Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_features.h>
21 :
22 : #include <sot/storage.hxx>
23 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
24 : #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
25 : #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
26 : #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
27 : #include <com/sun/star/ui/dialogs/XControlAccess.hpp>
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/beans/XPropertyAccess.hpp>
30 : #include <com/sun/star/beans/XPropertySet.hpp>
31 : #include <com/sun/star/beans/PropertyValue.hpp>
32 : #include <com/sun/star/container/XNameAccess.hpp>
33 : #include <com/sun/star/document/XCmisDocument.hpp>
34 : #include <com/sun/star/document/XExporter.hpp>
35 : #include <com/sun/star/task/ErrorCodeIOException.hpp>
36 : #include <com/sun/star/task/InteractionHandler.hpp>
37 : #include <com/sun/star/task/XStatusIndicator.hpp>
38 : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
39 : #include <com/sun/star/frame/DocumentTemplates.hpp>
40 : #include <com/sun/star/frame/XController2.hpp>
41 : #include <com/sun/star/frame/XDocumentTemplates.hpp>
42 : #include <com/sun/star/frame/XStorable.hpp>
43 : #include <comphelper/processfactory.hxx>
44 : #include <comphelper/servicehelper.hxx>
45 : #include <com/sun/star/security/CertificateValidity.hpp>
46 :
47 : #include <com/sun/star/security/DocumentSignatureInformation.hpp>
48 : #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
49 : #include <tools/urlobj.hxx>
50 : #include <svl/whiter.hxx>
51 : #include <vcl/layout.hxx>
52 : #include <svl/intitem.hxx>
53 : #include <svl/eitem.hxx>
54 : #include <svl/visitem.hxx>
55 : #include <vcl/wrkwin.hxx>
56 : #include <svtools/sfxecode.hxx>
57 : #include <svtools/ehdl.hxx>
58 :
59 : #include <comphelper/string.hxx>
60 : #include <basic/sbx.hxx>
61 : #include <unotools/pathoptions.hxx>
62 : #include <unotools/useroptions.hxx>
63 : #include <unotools/saveopt.hxx>
64 : #include <svtools/asynclink.hxx>
65 : #include <svtools/miscopt.hxx>
66 : #include <comphelper/documentconstants.hxx>
67 :
68 : #include <sfx2/app.hxx>
69 : #include <sfx2/signaturestate.hxx>
70 : #include <sfx2/sfxresid.hxx>
71 : #include <sfx2/event.hxx>
72 : #include <sfx2/request.hxx>
73 : #include <sfx2/printer.hxx>
74 : #include <sfx2/viewsh.hxx>
75 : #include <sfx2/docfilt.hxx>
76 : #include <sfx2/docfile.hxx>
77 : #include <sfx2/dispatch.hxx>
78 : #include <sfx2/dinfdlg.hxx>
79 : #include <sfx2/objitem.hxx>
80 : #include <sfx2/objsh.hxx>
81 : #include "objshimp.hxx"
82 : #include "sfxtypes.hxx"
83 : #include <sfx2/module.hxx>
84 : #include <sfx2/viewfrm.hxx>
85 : #include "versdlg.hxx"
86 : #include "doc.hrc"
87 : #include <sfx2/docfac.hxx>
88 : #include <sfx2/fcontnr.hxx>
89 : #include <sfx2/sfxhelp.hxx>
90 : #include <sfx2/msgpool.hxx>
91 : #include <sfx2/objface.hxx>
92 : #include <sfx2/checkin.hxx>
93 :
94 : #include "../appl/app.hrc"
95 : #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
96 : #include <com/sun/star/embed/XTransactedObject.hpp>
97 : #include <com/sun/star/util/XCloneable.hpp>
98 : #include <com/sun/star/document/XDocumentProperties.hpp>
99 :
100 : #include "helpid.hrc"
101 :
102 : #include "guisaveas.hxx"
103 : #include <sfx2/templatedlg.hxx>
104 : #include <boost/scoped_ptr.hpp>
105 :
106 : using namespace ::com::sun::star;
107 : using namespace ::com::sun::star::lang;
108 : using namespace ::com::sun::star::uno;
109 : using namespace ::com::sun::star::ui::dialogs;
110 : using namespace ::com::sun::star::awt;
111 : using namespace ::com::sun::star::container;
112 : using namespace ::com::sun::star::beans;
113 : using namespace ::com::sun::star::document;
114 : using namespace ::com::sun::star::task;
115 :
116 : #define SfxObjectShell
117 : #include "sfxslots.hxx"
118 :
119 642 : SFX_IMPL_SUPERCLASS_INTERFACE(SfxObjectShell, SfxShell)
120 :
121 208 : void SfxObjectShell::InitInterface_Impl()
122 : {
123 208 : }
124 :
125 2 : class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
126 : {
127 : bool m_bGotOwnership;
128 : bool m_bPreventClose;
129 :
130 : public:
131 : SfxClosePreventer_Impl();
132 :
133 1 : bool HasOwnership() { return m_bGotOwnership; }
134 :
135 1 : void SetPreventClose( bool bPrevent ) { m_bPreventClose = bPrevent; }
136 :
137 : virtual void SAL_CALL queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
138 : throw ( uno::RuntimeException, util::CloseVetoException, std::exception ) SAL_OVERRIDE;
139 :
140 : virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE ;
141 :
142 : virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE ;
143 :
144 : } ;
145 :
146 1 : SfxClosePreventer_Impl::SfxClosePreventer_Impl()
147 : : m_bGotOwnership( false )
148 1 : , m_bPreventClose( true )
149 : {
150 1 : }
151 :
152 0 : void SAL_CALL SfxClosePreventer_Impl::queryClosing( const lang::EventObject&, sal_Bool bDeliverOwnership )
153 : throw ( uno::RuntimeException, util::CloseVetoException, std::exception )
154 : {
155 0 : if ( m_bPreventClose )
156 : {
157 0 : if ( !m_bGotOwnership )
158 0 : m_bGotOwnership = bDeliverOwnership;
159 :
160 0 : throw util::CloseVetoException();
161 : }
162 0 : }
163 :
164 0 : void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& ) throw ( uno::RuntimeException, std::exception )
165 0 : {}
166 :
167 0 : void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException, std::exception )
168 0 : {}
169 :
170 :
171 : class SfxInstanceCloseGuard_Impl
172 : {
173 : SfxClosePreventer_Impl* m_pPreventer;
174 : uno::Reference< util::XCloseListener > m_xPreventer;
175 : uno::Reference< util::XCloseable > m_xCloseable;
176 :
177 : public:
178 1 : SfxInstanceCloseGuard_Impl()
179 1 : : m_pPreventer( NULL )
180 1 : {}
181 :
182 : ~SfxInstanceCloseGuard_Impl();
183 :
184 : bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable );
185 : };
186 :
187 1 : bool SfxInstanceCloseGuard_Impl::Init_Impl( const uno::Reference< util::XCloseable >& xCloseable )
188 : {
189 1 : bool bResult = false;
190 :
191 : // do not allow reinit after the successful init
192 1 : if ( xCloseable.is() && !m_xCloseable.is() )
193 : {
194 : try
195 : {
196 1 : m_pPreventer = new SfxClosePreventer_Impl();
197 1 : m_xPreventer = uno::Reference< util::XCloseListener >( m_pPreventer );
198 1 : xCloseable->addCloseListener( m_xPreventer );
199 1 : m_xCloseable = xCloseable;
200 1 : bResult = true;
201 : }
202 0 : catch( uno::Exception& )
203 : {
204 : OSL_FAIL( "Could not register close listener!\n" );
205 : }
206 : }
207 :
208 1 : return bResult;
209 : }
210 :
211 2 : SfxInstanceCloseGuard_Impl::~SfxInstanceCloseGuard_Impl()
212 : {
213 1 : if ( m_xCloseable.is() && m_xPreventer.is() )
214 : {
215 : try
216 : {
217 1 : m_xCloseable->removeCloseListener( m_xPreventer );
218 : }
219 0 : catch( uno::Exception& )
220 : {
221 : }
222 :
223 : try
224 : {
225 1 : if ( m_pPreventer )
226 : {
227 1 : m_pPreventer->SetPreventClose( false );
228 :
229 1 : if ( m_pPreventer->HasOwnership() )
230 0 : m_xCloseable->close( sal_True ); // TODO: do it asynchronously
231 : }
232 : }
233 0 : catch( uno::Exception& )
234 : {
235 : }
236 : }
237 1 : }
238 :
239 :
240 :
241 0 : void SfxObjectShell::PrintExec_Impl(SfxRequest &rReq)
242 : {
243 0 : SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this);
244 0 : if ( pFrame )
245 : {
246 0 : rReq.SetSlot( SID_PRINTDOC );
247 0 : pFrame->GetViewShell()->ExecuteSlot(rReq);
248 : }
249 0 : }
250 :
251 :
252 :
253 0 : void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet)
254 : {
255 0 : bool bPrinting = false;
256 0 : SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
257 0 : if ( pFrame )
258 : {
259 0 : SfxPrinter *pPrinter = pFrame->GetViewShell()->GetPrinter();
260 0 : bPrinting = pPrinter && pPrinter->IsPrinting();
261 : }
262 0 : rSet.Put( SfxBoolItem( SID_PRINTOUT, bPrinting ) );
263 0 : }
264 :
265 :
266 :
267 700 : bool SfxObjectShell::APISaveAs_Impl
268 : (
269 : const OUString& aFileName,
270 : SfxItemSet* aParams
271 : )
272 : {
273 700 : bool bOk = false;
274 :
275 :
276 700 : if ( GetMedium() )
277 : {
278 700 : OUString aFilterName;
279 700 : SFX_ITEMSET_ARG( aParams, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, false );
280 700 : if( pFilterNameItem )
281 : {
282 687 : aFilterName = pFilterNameItem->GetValue();
283 : }
284 : else
285 : {
286 13 : SFX_ITEMSET_ARG( aParams, pContentTypeItem, SfxStringItem, SID_CONTENTTYPE, false );
287 13 : if ( pContentTypeItem )
288 : {
289 0 : const SfxFilter* pFilter = SfxFilterMatcher( OUString::createFromAscii(GetFactory().GetShortName()) ).GetFilter4Mime( pContentTypeItem->GetValue(), SfxFilterFlags::EXPORT );
290 0 : if ( pFilter )
291 0 : aFilterName = pFilter->GetName();
292 : }
293 : }
294 :
295 : // in case no filter defined use default one
296 700 : if( aFilterName.isEmpty() )
297 : {
298 13 : const SfxFilter* pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName());
299 :
300 : DBG_ASSERT( pFilt, "No default filter!\n" );
301 13 : if( pFilt )
302 13 : aFilterName = pFilt->GetFilterName();
303 :
304 13 : aParams->Put(SfxStringItem( SID_FILTER_NAME, aFilterName));
305 : }
306 :
307 :
308 : {
309 700 : SfxObjectShellRef xLock( this ); // ???
310 :
311 : // use the title that is provided in the media descriptor
312 700 : SFX_ITEMSET_ARG( aParams, pDocTitleItem, SfxStringItem, SID_DOCINFO_TITLE, false );
313 700 : if ( pDocTitleItem )
314 0 : getDocProperties()->setTitle( pDocTitleItem->GetValue() );
315 :
316 : bOk = CommonSaveAs_Impl( INetURLObject(aFileName), aFilterName,
317 700 : aParams );
318 :
319 700 : }
320 : }
321 :
322 700 : return bOk;
323 : }
324 :
325 0 : void SfxObjectShell::CheckOut( )
326 : {
327 : try
328 : {
329 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
330 0 : xCmisDoc->checkOut( );
331 :
332 : // Remove the info bar
333 0 : SfxViewFrame* pViewFrame = GetFrame();
334 0 : pViewFrame->RemoveInfoBar( "checkout" );
335 : }
336 0 : catch ( const uno::RuntimeException& e )
337 : {
338 0 : ScopedVclPtrInstance< MessageDialog > pErrorBox( &GetFrame()->GetWindow(), e.Message );
339 0 : pErrorBox->Execute( );
340 : }
341 0 : }
342 :
343 0 : void SfxObjectShell::CancelCheckOut( )
344 : {
345 : try
346 : {
347 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
348 0 : xCmisDoc->cancelCheckOut( );
349 :
350 0 : uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
351 0 : if ( xModifiable.is( ) )
352 0 : xModifiable->setModified( sal_False );
353 : }
354 0 : catch ( const uno::RuntimeException& e )
355 : {
356 0 : ScopedVclPtrInstance< MessageDialog > pErrorBox(&GetFrame()->GetWindow(), e.Message);
357 0 : pErrorBox->Execute( );
358 : }
359 0 : }
360 :
361 0 : void SfxObjectShell::CheckIn( )
362 : {
363 : try
364 : {
365 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
366 : // Pop up dialog to ask for comment and major
367 0 : ScopedVclPtrInstance< SfxCheckinDialog > checkinDlg(&GetFrame( )->GetWindow( ));
368 0 : if ( checkinDlg->Execute( ) == RET_OK )
369 : {
370 0 : OUString sComment = checkinDlg->GetComment( );
371 0 : bool bMajor = checkinDlg->IsMajor( );
372 0 : xCmisDoc->checkIn( bMajor, sComment );
373 0 : uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
374 0 : if ( xModifiable.is( ) )
375 0 : xModifiable->setModified( sal_False );
376 0 : }
377 : }
378 0 : catch ( const uno::RuntimeException& e )
379 : {
380 0 : ScopedVclPtrInstance< MessageDialog > pErrorBox(&GetFrame()->GetWindow(), e.Message);
381 0 : pErrorBox->Execute( );
382 : }
383 0 : }
384 :
385 0 : uno::Sequence< document::CmisVersion > SfxObjectShell::GetCmisVersions( )
386 : {
387 : try
388 : {
389 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
390 0 : return xCmisDoc->getAllVersions( );
391 : }
392 0 : catch ( const uno::RuntimeException& e )
393 : {
394 0 : ScopedVclPtrInstance< MessageDialog > pErrorBox(&GetFrame()->GetWindow(), e.Message);
395 0 : pErrorBox->Execute( );
396 : }
397 0 : return uno::Sequence< document::CmisVersion > ( );
398 : }
399 :
400 :
401 1 : void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
402 : {
403 :
404 1 : sal_uInt16 nId = rReq.GetSlot();
405 :
406 1 : if( SID_SIGNATURE == nId || SID_MACRO_SIGNATURE == nId )
407 : {
408 0 : if ( QueryHiddenInformation( HiddenWarningFact::WhenSigning, NULL ) == RET_YES )
409 0 : ( SID_SIGNATURE == nId ) ? SignDocumentContent() : SignScriptingContent();
410 0 : return;
411 : }
412 :
413 1 : if ( !GetMedium() && nId != SID_CLOSEDOC )
414 : {
415 0 : rReq.Ignore();
416 0 : return;
417 : }
418 :
419 : // this guard is created here to have it destruction at the end of the method
420 1 : SfxInstanceCloseGuard_Impl aModelGuard;
421 :
422 1 : bool bIsPDFExport = false;
423 1 : switch(nId)
424 : {
425 : case SID_VERSION:
426 : {
427 0 : SfxViewFrame* pFrame = GetFrame();
428 0 : if ( !pFrame )
429 0 : pFrame = SfxViewFrame::GetFirst( this );
430 0 : if ( !pFrame )
431 0 : return;
432 :
433 0 : if ( pFrame->GetFrame().GetParentFrame() )
434 : {
435 0 : pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
436 0 : return;
437 : }
438 :
439 0 : if ( !IsOwnStorageFormat_Impl( *GetMedium() ) )
440 0 : return;
441 :
442 0 : ScopedVclPtrInstance< SfxVersionDialog > pDlg( pFrame, IsSaveVersionOnClose() );
443 0 : pDlg->Execute();
444 0 : SetSaveVersionOnClose( pDlg->IsSaveVersionOnClose() );
445 0 : rReq.Done();
446 0 : return;
447 : }
448 :
449 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
450 : case SID_DOCINFO:
451 : {
452 0 : SFX_REQUEST_ARG(rReq, pDocInfItem, SfxDocumentInfoItem, SID_DOCINFO, false);
453 0 : if ( pDocInfItem )
454 : {
455 : // parameter, e.g. from replayed macro
456 0 : pDocInfItem->UpdateDocumentInfo(getDocProperties(), true);
457 0 : SetUseUserData( pDocInfItem->IsUseUserData() );
458 : }
459 : else
460 : {
461 : // no argument containing DocInfo; check optional arguments
462 0 : bool bReadOnly = IsReadOnly();
463 0 : SFX_REQUEST_ARG(rReq, pROItem, SfxBoolItem, SID_DOC_READONLY, false);
464 0 : if ( pROItem )
465 : // override readonly attribute of document
466 : // e.g. if a readonly document is saved elsewhere and user asks for editing DocInfo before
467 0 : bReadOnly = pROItem->GetValue();
468 :
469 : // collect data for dialog
470 0 : OUString aURL, aTitle;
471 0 : if ( HasName() )
472 : {
473 0 : aURL = GetMedium()->GetName();
474 0 : aTitle = GetTitle();
475 : }
476 : else
477 : {
478 0 : aURL = "private:factory/" + OUString::createFromAscii( GetFactory().GetShortName() );
479 :
480 0 : aTitle = GetTitle();
481 : }
482 :
483 0 : Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
484 0 : uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties();
485 :
486 : SfxDocumentInfoItem aDocInfoItem( aURL, getDocProperties(), aCmisProperties,
487 0 : IsUseUserData() );
488 0 : if ( !GetSlotState( SID_DOCTEMPLATE ) )
489 : // templates not supported
490 0 : aDocInfoItem.SetTemplate(false);
491 :
492 0 : SfxItemSet aSet(GetPool(), SID_DOCINFO, SID_DOCINFO, SID_DOC_READONLY, SID_DOC_READONLY,
493 : SID_EXPLORER_PROPS_START, SID_EXPLORER_PROPS_START, SID_BASEURL, SID_BASEURL,
494 0 : 0L );
495 0 : aSet.Put( aDocInfoItem );
496 0 : aSet.Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
497 0 : aSet.Put( SfxStringItem( SID_EXPLORER_PROPS_START, aTitle ) );
498 0 : aSet.Put( SfxStringItem( SID_BASEURL, GetMedium()->GetBaseURL() ) );
499 :
500 : // creating dialog is done via virtual method; application will
501 : // add its own statistics page
502 0 : ScopedVclPtr<SfxDocumentInfoDialog> pDlg(CreateDocumentInfoDialog(0, aSet));
503 0 : if ( RET_OK == pDlg->Execute() )
504 : {
505 0 : SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pDocInfoItem, SfxDocumentInfoItem, SID_DOCINFO, false);
506 0 : if ( pDocInfoItem )
507 : {
508 : // user has done some changes to DocumentInfo
509 0 : pDocInfoItem->UpdateDocumentInfo(getDocProperties());
510 : uno::Sequence< document::CmisProperty > aNewCmisProperties =
511 0 : pDocInfoItem->GetCmisProperties( );
512 0 : if ( aNewCmisProperties.getLength( ) > 0 )
513 0 : xCmisDoc->updateCmisProperties( aNewCmisProperties );
514 0 : SetUseUserData( pDocInfoItem->IsUseUserData() );
515 : // add data from dialog for possible recording purpose
516 : rReq.AppendItem( SfxDocumentInfoItem( GetTitle(),
517 0 : getDocProperties(), aNewCmisProperties, IsUseUserData() ) );
518 : }
519 :
520 0 : rReq.Done();
521 : }
522 : else
523 : // nothing done; no recording
524 0 : rReq.Ignore();
525 : }
526 :
527 0 : return;
528 : }
529 :
530 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
531 :
532 : case SID_EXPORTDOCASPDF:
533 : case SID_DIRECTEXPORTDOCASPDF:
534 0 : bIsPDFExport = true;
535 : //fall-through
536 : case SID_EXPORTDOC:
537 : case SID_SAVEASDOC:
538 : case SID_SAVEDOC:
539 : {
540 : // derived class may decide to abort this
541 1 : if( !QuerySlotExecutable( nId ) )
542 : {
543 0 : rReq.SetReturnValue( SfxBoolItem( 0, false ) );
544 0 : return;
545 : }
546 :
547 : //!! detailed analysis of an error code
548 1 : SfxObjectShellRef xLock( this );
549 :
550 : // the model can not be closed till the end of this method
551 : // if somebody tries to close it during this time the model will be closed
552 : // at the end of the method
553 1 : aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) );
554 :
555 1 : sal_uInt32 nErrorCode = ERRCODE_NONE;
556 :
557 : // by default versions should be preserved always except in case of an explicit
558 : // SaveAs via GUI, so the flag must be set accordingly
559 1 : pImp->bPreserveVersions = (nId == SID_SAVEDOC);
560 : try
561 : {
562 1 : SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ???
563 :
564 1 : if ( nId == SID_SAVEASDOC )
565 : {
566 : // in case of plugin mode the SaveAs operation means SaveTo
567 0 : SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, false );
568 0 : if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
569 0 : rReq.AppendItem( SfxBoolItem( SID_SAVETO, true ) );
570 : }
571 :
572 : // TODO/LATER: do the following GUI related actions in standalown method
573 :
574 : // Introduce a status indicator for GUI operation
575 1 : SFX_REQUEST_ARG( rReq, pStatusIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, false );
576 1 : if ( !pStatusIndicatorItem )
577 : {
578 : // get statusindicator
579 1 : uno::Reference< task::XStatusIndicator > xStatusIndicator;
580 2 : uno::Reference < frame::XController > xCtrl( GetModel()->getCurrentController() );
581 1 : if ( xCtrl.is() )
582 : {
583 1 : uno::Reference< task::XStatusIndicatorFactory > xStatFactory( xCtrl->getFrame(), uno::UNO_QUERY );
584 1 : if( xStatFactory.is() )
585 1 : xStatusIndicator = xStatFactory->createStatusIndicator();
586 : }
587 :
588 : OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!\n" );
589 :
590 1 : if ( xStatusIndicator.is() )
591 : {
592 1 : SfxUnoAnyItem aStatIndItem( SID_PROGRESS_STATUSBAR_CONTROL, uno::makeAny( xStatusIndicator ) );
593 :
594 1 : if ( nId == SID_SAVEDOC )
595 : {
596 : // in case of saving it is not possible to transport the parameters from here
597 : // but it is not clear here whether the saving will be done or saveAs operation
598 1 : GetMedium()->GetItemSet()->Put( aStatIndItem );
599 : }
600 :
601 1 : rReq.AppendItem( aStatIndItem );
602 1 : }
603 : }
604 0 : else if ( nId == SID_SAVEDOC )
605 : {
606 : // in case of saving it is not possible to transport the parameters from here
607 : // but it is not clear here whether the saving will be done or saveAs operation
608 0 : GetMedium()->GetItemSet()->Put( *pStatusIndicatorItem );
609 : }
610 :
611 : // Introduce an interaction handler for GUI operation
612 1 : SFX_REQUEST_ARG( rReq, pInteractionHandlerItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, false );
613 1 : if ( !pInteractionHandlerItem )
614 : {
615 1 : uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
616 : uno::Reference< task::XInteractionHandler2 > xInteract(
617 2 : task::InteractionHandler::createWithParent(xContext, 0) );
618 :
619 2 : SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER, uno::makeAny( xInteract ) );
620 1 : if ( nId == SID_SAVEDOC )
621 : {
622 : // in case of saving it is not possible to transport the parameters from here
623 : // but it is not clear here whether the saving will be done or saveAs operation
624 1 : GetMedium()->GetItemSet()->Put( aInteractionItem );
625 : }
626 :
627 2 : rReq.AppendItem( aInteractionItem );
628 : }
629 0 : else if ( nId == SID_SAVEDOC )
630 : {
631 : // in case of saving it is not possible to transport the parameters from here
632 : // but it is not clear here whether the saving will be done or saveAs operation
633 0 : GetMedium()->GetItemSet()->Put( *pInteractionHandlerItem );
634 : }
635 :
636 :
637 1 : bool bPreselectPassword = false;
638 1 : SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
639 1 : SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldPasswordItem, SfxStringItem, SID_PASSWORD, false );
640 1 : if ( pOldEncryptionDataItem || pOldPasswordItem )
641 0 : bPreselectPassword = true;
642 :
643 2 : uno::Sequence< beans::PropertyValue > aDispatchArgs;
644 1 : if ( rReq.GetArgs() )
645 : TransformItems( nId,
646 1 : *rReq.GetArgs(),
647 : aDispatchArgs,
648 1 : NULL );
649 :
650 1 : const SfxSlot* pSlot = GetModule()->GetSlotPool()->GetSlot( nId );
651 1 : if ( !pSlot )
652 0 : throw uno::Exception();
653 :
654 2 : SfxStoringHelper aHelper;
655 :
656 1 : if ( QueryHiddenInformation( bIsPDFExport ? HiddenWarningFact::WhenCreatingPDF : HiddenWarningFact::WhenSaving, NULL ) == RET_YES )
657 : {
658 : aHelper.GUIStoreModel( GetModel(),
659 : OUString::createFromAscii( pSlot->GetUnoName() ),
660 : aDispatchArgs,
661 : bPreselectPassword,
662 : GetSharedFileURL(),
663 1 : GetDocumentSignatureState() );
664 : }
665 : else
666 : {
667 : // the user has decided not to store the document
668 : throw task::ErrorCodeIOException(
669 : "SfxObjectShell::ExecFile_Impl: ERRCODE_IO_ABORT",
670 0 : uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT);
671 : }
672 :
673 : // merge aDispatchArgs to the request
674 2 : SfxAllItemSet aResultParams( GetPool() );
675 : TransformParameters( nId,
676 : aDispatchArgs,
677 : aResultParams,
678 1 : NULL );
679 1 : rReq.SetArgs( aResultParams );
680 :
681 : // the StoreAsURL/StoreToURL method have called this method with false
682 : // so it has to be restored to true here since it is a call from GUI
683 2 : GetMedium()->SetUpdatePickList( true );
684 :
685 : // TODO: in future it must be done in followind way
686 : // if document is opened from GUI it is immediatelly appears in the picklist
687 : // if the document is a new one then it appears in the picklist immediatelly
688 : // after SaveAs operation triggered from GUI
689 : }
690 0 : catch( const task::ErrorCodeIOException& aErrorEx )
691 : {
692 0 : nErrorCode = (sal_uInt32)aErrorEx.ErrCode;
693 : }
694 0 : catch( Exception& )
695 : {
696 0 : nErrorCode = ERRCODE_IO_GENERAL;
697 : }
698 :
699 : // by default versions should be preserved always except in case of an explicit
700 : // SaveAs via GUI, so the flag must be reset to guarantee this
701 1 : pImp->bPreserveVersions = true;
702 1 : sal_uIntPtr lErr=GetErrorCode();
703 :
704 1 : if ( !lErr && nErrorCode )
705 0 : lErr = nErrorCode;
706 :
707 1 : if ( lErr && nErrorCode == ERRCODE_NONE )
708 : {
709 0 : SFX_REQUEST_ARG( rReq, pWarnItem, SfxBoolItem, SID_FAIL_ON_WARNING, false );
710 0 : if ( pWarnItem && pWarnItem->GetValue() )
711 0 : nErrorCode = lErr;
712 : }
713 :
714 : // may be nErrorCode should be shown in future
715 1 : if ( lErr != ERRCODE_IO_ABORT )
716 : {
717 1 : SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC,GetTitle());
718 1 : ErrorHandler::HandleError( lErr );
719 : }
720 :
721 1 : if ( nId == SID_EXPORTDOCASPDF )
722 : {
723 : // This function is used by the SendMail function that needs information if a export
724 : // file was written or not. This could be due to cancellation of the export
725 : // or due to an error. So IO abort must be handled like an error!
726 0 : nErrorCode = ( lErr != ERRCODE_IO_ABORT ) && ( nErrorCode == ERRCODE_NONE ) ? nErrorCode : lErr;
727 : }
728 :
729 1 : if ( nId == SID_SAVEASDOC && nErrorCode == ERRCODE_NONE )
730 : {
731 : SfxBoolItem const * saveTo = static_cast<SfxBoolItem const *>(
732 0 : rReq.GetArg(SID_SAVETO, false, TYPE(SfxBoolItem)));
733 0 : if (saveTo == nullptr || !saveTo->GetValue())
734 : {
735 0 : GetFrame()->RemoveInfoBar("readonly");
736 0 : SetReadOnlyUI(false);
737 : }
738 : }
739 :
740 1 : rReq.SetReturnValue( SfxBoolItem(0, nErrorCode == ERRCODE_NONE ) );
741 :
742 1 : ResetError();
743 :
744 1 : Invalidate();
745 1 : break;
746 : }
747 :
748 : case SID_SAVEACOPY:
749 : {
750 0 : SfxAllItemSet aArgs( GetPool() );
751 0 : aArgs.Put( SfxBoolItem( SID_SAVEACOPYITEM, true ) );
752 0 : SfxRequest aSaveACopyReq( SID_EXPORTDOC, SfxCallMode::API, aArgs );
753 0 : ExecFile_Impl( aSaveACopyReq );
754 0 : if ( !aSaveACopyReq.IsDone() )
755 : {
756 0 : rReq.Ignore();
757 0 : return;
758 : }
759 0 : break;
760 : }
761 :
762 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
763 :
764 : case SID_CLOSEDOC:
765 : {
766 0 : SfxViewFrame *pFrame = GetFrame();
767 0 : if ( pFrame && pFrame->GetFrame().GetParentFrame() )
768 : {
769 : // If SID_CLOSEDOC is executed through menu and so on, but
770 : // the current document is in a frame, then the
771 : // FrameSetDocument should actually be closed.
772 0 : pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
773 0 : rReq.Done();
774 0 : return;
775 : }
776 :
777 0 : bool bInFrameSet = false;
778 0 : sal_uInt16 nFrames=0;
779 0 : pFrame = SfxViewFrame::GetFirst( this );
780 0 : while ( pFrame )
781 : {
782 0 : if ( pFrame->GetFrame().GetParentFrame() )
783 : {
784 : // In this document there still exists a view that is
785 : // in a FrameSet , which of course may not be closed
786 : // geclosed werden
787 0 : bInFrameSet = true;
788 : }
789 : else
790 0 : nFrames++;
791 :
792 0 : pFrame = SfxViewFrame::GetNext( *pFrame, this );
793 : }
794 :
795 0 : if ( bInFrameSet )
796 : {
797 : // Close all views that are not in a FrameSet.
798 0 : pFrame = SfxViewFrame::GetFirst( this );
799 0 : while ( pFrame )
800 : {
801 0 : if ( !pFrame->GetFrame().GetParentFrame() )
802 0 : pFrame->GetFrame().DoClose();
803 0 : pFrame = SfxViewFrame::GetNext( *pFrame, this );
804 : }
805 : }
806 :
807 : // Evaluate Parameter
808 0 : SFX_REQUEST_ARG(rReq, pSaveItem, SfxBoolItem, SID_CLOSEDOC_SAVE, false);
809 0 : SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_CLOSEDOC_FILENAME, false);
810 0 : if ( pSaveItem )
811 : {
812 0 : if ( pSaveItem->GetValue() )
813 : {
814 0 : if ( !pNameItem )
815 : {
816 : #if HAVE_FEATURE_SCRIPTING
817 0 : SbxBase::SetError( SbxERR_WRONG_ARGS );
818 : #endif
819 0 : rReq.Ignore();
820 0 : return;
821 : }
822 0 : SfxAllItemSet aArgs( GetPool() );
823 0 : SfxStringItem aTmpItem( SID_FILE_NAME, pNameItem->GetValue() );
824 0 : aArgs.Put( aTmpItem, aTmpItem.Which() );
825 0 : SfxRequest aSaveAsReq( SID_SAVEASDOC, SfxCallMode::API, aArgs );
826 0 : ExecFile_Impl( aSaveAsReq );
827 0 : if ( !aSaveAsReq.IsDone() )
828 : {
829 0 : rReq.Ignore();
830 0 : return;
831 0 : }
832 : }
833 : else
834 0 : SetModified(false);
835 : }
836 :
837 : // Cancelled by the user?
838 0 : if (!PrepareClose(true))
839 : {
840 0 : rReq.SetReturnValue( SfxBoolItem(0, false) );
841 0 : rReq.Done();
842 0 : return;
843 : }
844 :
845 0 : SetModified( false );
846 0 : sal_uIntPtr lErr = GetErrorCode();
847 0 : ErrorHandler::HandleError(lErr);
848 :
849 0 : rReq.SetReturnValue( SfxBoolItem(0, true) );
850 0 : rReq.Done();
851 0 : rReq.ReleaseArgs(); // because the pool is destroyed in Close
852 0 : DoClose();
853 0 : return;
854 : }
855 :
856 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
857 : case SID_DOCTEMPLATE:
858 : {
859 : // save as document templates
860 0 : ScopedVclPtrInstance< SfxTemplateManagerDlg > aDlg;
861 0 : aDlg->setDocumentModel(GetModel());
862 0 : aDlg->setSaveMode();
863 0 : aDlg->Execute();
864 :
865 0 : break;
866 : }
867 :
868 : case SID_CHECKOUT:
869 : {
870 0 : CheckOut( );
871 0 : break;
872 : }
873 : case SID_CANCELCHECKOUT:
874 : {
875 0 : if (ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_QUERY_CANCELCHECKOUT), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO)->Execute() == RET_YES)
876 : {
877 0 : CancelCheckOut( );
878 :
879 : // Reload the document as we may still have local changes
880 0 : SfxViewFrame *pFrame = GetFrame();
881 0 : if ( pFrame )
882 0 : pFrame->GetDispatcher()->Execute(SID_RELOAD);
883 : }
884 0 : break;
885 : }
886 : case SID_CHECKIN:
887 : {
888 0 : CheckIn( );
889 0 : break;
890 : }
891 : }
892 :
893 : // Prevent entry in the Pick-lists
894 1 : if ( rReq.IsAPI() )
895 0 : GetMedium()->SetUpdatePickList( false );
896 1 : else if ( rReq.GetArgs() )
897 : {
898 1 : SFX_ITEMSET_GET( *rReq.GetArgs(), pPicklistItem, SfxBoolItem, SID_PICKLIST, false );
899 1 : if ( pPicklistItem )
900 0 : GetMedium()->SetUpdatePickList( pPicklistItem->GetValue() );
901 : }
902 :
903 : // Ignore()-branches have already returned
904 1 : rReq.Done();
905 : }
906 :
907 :
908 :
909 4346 : void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
910 : {
911 4346 : SfxWhichIter aIter( rSet );
912 :
913 13115 : for ( sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() )
914 : {
915 8769 : switch ( nWhich )
916 : {
917 : case SID_DOCTEMPLATE :
918 : {
919 0 : if ( !GetFactory().GetTemplateFilter() )
920 0 : rSet.DisableItem( nWhich );
921 0 : break;
922 : }
923 :
924 : case SID_CHECKOUT:
925 : {
926 0 : bool bShow = false;
927 0 : Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
928 0 : uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties();
929 :
930 0 : if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
931 : {
932 : // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
933 0 : bool bIsGoogleFile = false;
934 0 : bool bCheckedOut = false;
935 0 : for ( sal_Int32 i = 0; i < aCmisProperties.getLength(); ++i )
936 : {
937 0 : if ( aCmisProperties[i].Id == "cmis:isVersionSeriesCheckedOut" )
938 : {
939 0 : uno::Sequence< sal_Bool > bTmp;
940 0 : aCmisProperties[i].Value >>= bTmp;
941 0 : bCheckedOut = bTmp[0];
942 : }
943 : // using title to know if it's a Google Drive file
944 : // maybe there's a safer way.
945 0 : if ( aCmisProperties[i].Name == "title" )
946 0 : bIsGoogleFile = true;
947 : }
948 0 : bShow = !bCheckedOut && !bIsGoogleFile;
949 : }
950 :
951 0 : if ( !bShow )
952 : {
953 0 : rSet.DisableItem( nWhich );
954 0 : rSet.Put( SfxVisibilityItem( nWhich, false ) );
955 0 : }
956 : }
957 0 : break;
958 :
959 : case SID_CANCELCHECKOUT:
960 : case SID_CHECKIN:
961 : {
962 0 : bool bShow = false;
963 0 : Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
964 0 : uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties( );
965 :
966 0 : if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
967 : {
968 : // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
969 0 : bool bFoundCheckedout = false;
970 0 : bool bCheckedOut = false;
971 0 : for ( sal_Int32 i = 0; i < aCmisProperties.getLength() && !bFoundCheckedout; ++i )
972 : {
973 0 : if ( aCmisProperties[i].Id == "cmis:isVersionSeriesCheckedOut" )
974 : {
975 0 : bFoundCheckedout = true;
976 0 : uno::Sequence< sal_Bool > bTmp;
977 0 : aCmisProperties[i].Value >>= bTmp;
978 0 : bCheckedOut = bTmp[0];
979 : }
980 : }
981 0 : bShow = bCheckedOut;
982 : }
983 :
984 0 : if ( !bShow )
985 : {
986 0 : rSet.DisableItem( nWhich );
987 0 : rSet.Put( SfxVisibilityItem( nWhich, false ) );
988 0 : }
989 : }
990 0 : break;
991 :
992 : case SID_VERSION:
993 : {
994 0 : SfxObjectShell *pDoc = this;
995 0 : SfxViewFrame* pFrame = GetFrame();
996 0 : if ( !pFrame )
997 0 : pFrame = SfxViewFrame::GetFirst( this );
998 0 : if ( pFrame )
999 : {
1000 0 : if ( pFrame->GetFrame().GetParentFrame() )
1001 : {
1002 0 : pFrame = pFrame->GetTopViewFrame();
1003 0 : pDoc = pFrame->GetObjectShell();
1004 : }
1005 : }
1006 :
1007 0 : if ( !pFrame || !pDoc->HasName() ||
1008 0 : !IsOwnStorageFormat_Impl( *pDoc->GetMedium() ) )
1009 0 : rSet.DisableItem( nWhich );
1010 0 : break;
1011 : }
1012 : case SID_SAVEDOC:
1013 : {
1014 1722 : SvtMiscOptions aMiscOptions;
1015 1722 : bool bAlwaysAllowSave = aMiscOptions.IsSaveAlwaysAllowed();
1016 1722 : bool bAllowSave = (bAlwaysAllowSave || IsModified());
1017 1722 : bool bMediumRO = IsReadOnlyMedium();
1018 1722 : if ( !bMediumRO && GetMedium() && bAllowSave )
1019 : rSet.Put(SfxStringItem(
1020 1038 : nWhich, SfxResId(STR_SAVEDOC).toString()));
1021 : else
1022 684 : rSet.DisableItem(nWhich);
1023 : }
1024 1722 : break;
1025 :
1026 : case SID_DOCINFO:
1027 1 : if ( pImp->eFlags & SfxObjectShellFlags::NODOCINFO )
1028 0 : rSet.DisableItem( nWhich );
1029 1 : break;
1030 :
1031 : case SID_CLOSEDOC:
1032 : {
1033 0 : SfxObjectShell *pDoc = this;
1034 0 : SfxViewFrame *pFrame = GetFrame();
1035 0 : if ( pFrame && pFrame->GetFrame().GetParentFrame() )
1036 : {
1037 :
1038 : // If SID_CLOSEDOC is executed through menu and so on, but
1039 : // the current document is in a frame, then the
1040 : // FrameSetDocument should actually be closed.
1041 0 : pDoc = pFrame->GetTopViewFrame()->GetObjectShell();
1042 : }
1043 :
1044 0 : if ( pDoc->GetFlags() & SfxObjectShellFlags::DONTCLOSE )
1045 0 : rSet.DisableItem(nWhich);
1046 : else
1047 0 : rSet.Put(SfxStringItem(nWhich, SfxResId(STR_CLOSEDOC).toString()));
1048 0 : break;
1049 : }
1050 :
1051 : case SID_SAVEASDOC:
1052 : {
1053 1707 : if( !( pImp->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) )
1054 : {
1055 0 : rSet.DisableItem( nWhich );
1056 0 : break;
1057 : }
1058 1707 : if ( /*!pCombinedFilters ||*/ !GetMedium() )
1059 0 : rSet.DisableItem( nWhich );
1060 : else
1061 1707 : rSet.Put( SfxStringItem( nWhich, SfxResId(STR_SAVEASDOC).toString() ) );
1062 1707 : break;
1063 : }
1064 :
1065 : case SID_SAVEACOPY:
1066 : {
1067 0 : if( !( pImp->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) )
1068 : {
1069 0 : rSet.DisableItem( nWhich );
1070 0 : break;
1071 : }
1072 0 : if ( /*!pCombinedFilters ||*/ !GetMedium() )
1073 0 : rSet.DisableItem( nWhich );
1074 : else
1075 0 : rSet.Put( SfxStringItem( nWhich, SfxResId(STR_SAVEACOPY).toString() ) );
1076 0 : break;
1077 : }
1078 :
1079 : case SID_EXPORTDOCASPDF:
1080 : case SID_DIRECTEXPORTDOCASPDF:
1081 : {
1082 1720 : break;
1083 : }
1084 :
1085 : case SID_DOC_MODIFIED:
1086 : {
1087 1762 : rSet.Put( SfxBoolItem( SID_DOC_MODIFIED, IsModified() ) );
1088 1762 : break;
1089 : }
1090 :
1091 : case SID_MODIFIED:
1092 : {
1093 0 : rSet.Put( SfxBoolItem( SID_MODIFIED, IsModified() ) );
1094 0 : break;
1095 : }
1096 :
1097 : case SID_DOCINFO_TITLE:
1098 : {
1099 : rSet.Put( SfxStringItem(
1100 0 : SID_DOCINFO_TITLE, getDocProperties()->getTitle() ) );
1101 0 : break;
1102 : }
1103 : case SID_FILE_NAME:
1104 : {
1105 0 : if( GetMedium() && HasName() )
1106 : rSet.Put( SfxStringItem(
1107 0 : SID_FILE_NAME, GetMedium()->GetName() ) );
1108 0 : break;
1109 : }
1110 : case SID_SIGNATURE:
1111 : {
1112 1761 : rSet.Put( SfxUInt16Item( SID_SIGNATURE, static_cast<sal_uInt16>(GetDocumentSignatureState()) ) );
1113 1761 : break;
1114 : }
1115 : case SID_MACRO_SIGNATURE:
1116 : {
1117 : // the slot makes sense only if there is a macro in the document
1118 0 : if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() )
1119 0 : rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, static_cast<sal_uInt16>(GetScriptingSignatureState()) ) );
1120 : else
1121 0 : rSet.DisableItem( nWhich );
1122 0 : break;
1123 : }
1124 : }
1125 4346 : }
1126 4346 : }
1127 :
1128 :
1129 :
1130 0 : void SfxObjectShell::ExecProps_Impl(SfxRequest &rReq)
1131 : {
1132 0 : switch ( rReq.GetSlot() )
1133 : {
1134 : case SID_MODIFIED:
1135 : {
1136 0 : SetModified( static_cast<const SfxBoolItem&>(rReq.GetArgs()->Get(SID_MODIFIED)).GetValue() );
1137 0 : rReq.Done();
1138 0 : break;
1139 : }
1140 :
1141 : case SID_DOCTITLE:
1142 0 : SetTitle( static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_DOCTITLE)).GetValue() );
1143 0 : rReq.Done();
1144 0 : break;
1145 :
1146 : case SID_DOCINFO_AUTHOR :
1147 : {
1148 0 : OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1149 0 : getDocProperties()->setAuthor( aStr );
1150 0 : break;
1151 : }
1152 :
1153 : case SID_DOCINFO_COMMENTS :
1154 : {
1155 0 : OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1156 0 : getDocProperties()->setDescription( aStr );
1157 0 : break;
1158 : }
1159 :
1160 : case SID_DOCINFO_KEYWORDS :
1161 : {
1162 0 : OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1163 0 : getDocProperties()->setKeywords(
1164 0 : ::comphelper::string::convertCommaSeparated(aStr) );
1165 0 : break;
1166 : }
1167 : }
1168 0 : }
1169 :
1170 :
1171 :
1172 9 : void SfxObjectShell::StateProps_Impl(SfxItemSet &rSet)
1173 : {
1174 9 : SfxWhichIter aIter(rSet);
1175 18 : for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
1176 : {
1177 9 : switch ( nSID )
1178 : {
1179 : case SID_DOCINFO_AUTHOR :
1180 : {
1181 : rSet.Put( SfxStringItem( nSID,
1182 0 : getDocProperties()->getAuthor() ) );
1183 0 : break;
1184 : }
1185 :
1186 : case SID_DOCINFO_COMMENTS :
1187 : {
1188 : rSet.Put( SfxStringItem( nSID,
1189 0 : getDocProperties()->getDescription()) );
1190 0 : break;
1191 : }
1192 :
1193 : case SID_DOCINFO_KEYWORDS :
1194 : {
1195 : rSet.Put( SfxStringItem( nSID, ::comphelper::string::
1196 0 : convertCommaSeparated(getDocProperties()->getKeywords())) );
1197 0 : break;
1198 : }
1199 :
1200 : case SID_DOCPATH:
1201 : {
1202 : OSL_FAIL( "Not supported anymore!" );
1203 0 : break;
1204 : }
1205 :
1206 : case SID_DOCFULLNAME:
1207 : {
1208 9 : rSet.Put( SfxStringItem( SID_DOCFULLNAME, GetTitle(SFX_TITLE_FULLNAME) ) );
1209 9 : break;
1210 : }
1211 :
1212 : case SID_DOCTITLE:
1213 : {
1214 0 : rSet.Put( SfxStringItem( SID_DOCTITLE, GetTitle() ) );
1215 0 : break;
1216 : }
1217 :
1218 : case SID_DOC_READONLY:
1219 : {
1220 0 : rSet.Put( SfxBoolItem( SID_DOC_READONLY, IsReadOnly() ) );
1221 0 : break;
1222 : }
1223 :
1224 : case SID_DOC_SAVED:
1225 : {
1226 0 : rSet.Put( SfxBoolItem( SID_DOC_SAVED, !IsModified() ) );
1227 0 : break;
1228 : }
1229 :
1230 : case SID_CLOSING:
1231 : {
1232 0 : rSet.Put( SfxBoolItem( SID_CLOSING, false ) );
1233 0 : break;
1234 : }
1235 :
1236 : case SID_DOC_LOADING:
1237 0 : rSet.Put( SfxBoolItem( nSID, ! ( pImp->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) ) );
1238 0 : break;
1239 :
1240 : case SID_IMG_LOADING:
1241 0 : rSet.Put( SfxBoolItem( nSID, ! ( pImp->nLoadedFlags & SfxLoadedFlags::IMAGES ) ) );
1242 0 : break;
1243 : }
1244 9 : }
1245 9 : }
1246 :
1247 :
1248 :
1249 0 : void SfxObjectShell::ExecView_Impl(SfxRequest &rReq)
1250 : {
1251 0 : switch ( rReq.GetSlot() )
1252 : {
1253 : case SID_ACTIVATE:
1254 : {
1255 0 : SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this, true );
1256 0 : if ( pFrame )
1257 0 : pFrame->GetFrame().Appear();
1258 0 : rReq.SetReturnValue( SfxObjectItem( 0, pFrame ) );
1259 0 : rReq.Done();
1260 0 : break;
1261 : }
1262 : case SID_NEWWINDOWFOREDIT:
1263 : {
1264 0 : SfxViewFrame* pFrame = SfxViewFrame::Current();
1265 0 : if( pFrame->GetObjectShell() == this &&
1266 0 : ( pFrame->GetFrameType() & SFXFRAME_HASTITLE ) )
1267 0 : pFrame->ExecuteSlot( rReq );
1268 : else
1269 : {
1270 0 : OUString aFileName( GetObjectShell()->GetMedium()->GetName() );
1271 0 : if ( !aFileName.isEmpty() )
1272 : {
1273 0 : SfxStringItem aName( SID_FILE_NAME, aFileName );
1274 0 : SfxBoolItem aCreateView( SID_OPEN_NEW_VIEW, true );
1275 : SfxGetpApp()->GetAppDispatcher_Impl()->Execute(
1276 : SID_OPENDOC, SfxCallMode::ASYNCHRON, &aName,
1277 0 : &aCreateView, 0L);
1278 0 : }
1279 : }
1280 : }
1281 : }
1282 0 : }
1283 :
1284 :
1285 :
1286 0 : void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/)
1287 : {
1288 0 : }
1289 :
1290 4019 : SignatureState SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< security::DocumentSignatureInformation >& aInfos )
1291 : {
1292 4019 : bool bCertValid = true;
1293 4019 : SignatureState nResult = SignatureState::NOSIGNATURES;
1294 4019 : int nInfos = aInfos.getLength();
1295 4019 : bool bCompleteSignature = true;
1296 4019 : if( nInfos )
1297 : {
1298 0 : nResult = SignatureState::OK;
1299 0 : for ( int n = 0; n < nInfos; n++ )
1300 : {
1301 0 : if ( bCertValid )
1302 : {
1303 0 : sal_Int32 nCertStat = aInfos[n].CertificateStatus;
1304 0 : bCertValid = nCertStat == security::CertificateValidity::VALID;
1305 : }
1306 :
1307 0 : if ( !aInfos[n].SignatureIsValid )
1308 : {
1309 0 : nResult = SignatureState::BROKEN;
1310 0 : break; // we know enough
1311 : }
1312 0 : bCompleteSignature &= !aInfos[n].PartialDocumentSignature;
1313 : }
1314 : }
1315 :
1316 4019 : if ( nResult == SignatureState::OK && !bCertValid )
1317 0 : nResult = SignatureState::NOTVALIDATED;
1318 4019 : else if ( nResult == SignatureState::OK && bCertValid && !bCompleteSignature)
1319 0 : nResult = SignatureState::PARTIAL_OK;
1320 :
1321 : // this code must not check whether the document is modified
1322 : // it should only check the provided info
1323 :
1324 4019 : return nResult;
1325 : }
1326 :
1327 4019 : uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner )
1328 : {
1329 4019 : uno::Sequence< security::DocumentSignatureInformation > aResult;
1330 8038 : uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner;
1331 :
1332 4019 : if ( GetMedium() && !GetMedium()->GetName().isEmpty() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() )
1333 : {
1334 : try
1335 : {
1336 491 : if ( !xLocSigner.is() )
1337 : {
1338 491 : OUString aVersion;
1339 : try
1340 : {
1341 491 : uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1342 491 : xPropSet->getPropertyValue("Version") >>= aVersion;
1343 : }
1344 0 : catch( uno::Exception& )
1345 : {
1346 : }
1347 :
1348 491 : xLocSigner.set( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) );
1349 :
1350 : }
1351 :
1352 214 : if ( bScriptingContent )
1353 0 : aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1354 0 : uno::Reference< io::XInputStream >() );
1355 : else
1356 642 : aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1357 428 : uno::Reference< io::XInputStream >() );
1358 : }
1359 277 : catch( com::sun::star::uno::Exception& )
1360 : {
1361 : }
1362 : }
1363 :
1364 8038 : return aResult;
1365 : }
1366 :
1367 22041 : SignatureState SfxObjectShell::ImplGetSignatureState( bool bScriptingContent )
1368 : {
1369 22041 : SignatureState* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState;
1370 :
1371 22041 : if ( *pState == SignatureState::UNKNOWN )
1372 : {
1373 4019 : *pState = SignatureState::NOSIGNATURES;
1374 :
1375 4019 : uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent );
1376 4019 : *pState = ImplCheckSignaturesInformation( aInfos );
1377 : }
1378 :
1379 22041 : if ( *pState == SignatureState::OK || *pState == SignatureState::NOTVALIDATED
1380 22041 : || *pState == SignatureState::PARTIAL_OK)
1381 : {
1382 0 : if ( IsModified() )
1383 0 : *pState = SignatureState::INVALID;
1384 : }
1385 :
1386 22041 : return *pState;
1387 : }
1388 :
1389 0 : void SfxObjectShell::ImplSign( bool bScriptingContent )
1390 : {
1391 : // Check if it is stored in OASIS format...
1392 0 : if ( GetMedium()
1393 0 : && GetMedium()->GetFilter()
1394 0 : && !GetMedium()->GetName().isEmpty()
1395 0 : && ( !GetMedium()->GetFilter()->IsOwnFormat()
1396 0 : || !GetMedium()->HasStorage_Impl()
1397 : )
1398 : )
1399 : {
1400 : // Only OASIS and OOo6.x formats will be handled further
1401 0 : ScopedVclPtrInstance<MessageDialog>::Create( nullptr, SfxResId( STR_INFO_WRONGDOCFORMAT ), VCL_MESSAGE_INFO )->Execute();
1402 0 : return;
1403 : }
1404 :
1405 : // check whether the document is signed
1406 0 : ImplGetSignatureState( false ); // document signature
1407 0 : ImplGetSignatureState( true ); // script signature
1408 0 : bool bHasSign = ( pImp->nScriptingSignatureState != SignatureState::NOSIGNATURES || pImp->nDocumentSignatureState != SignatureState::NOSIGNATURES );
1409 :
1410 : // the target ODF version on saving
1411 0 : SvtSaveOptions aSaveOpt;
1412 0 : SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion();
1413 :
1414 : // the document is not new and is not modified
1415 0 : OUString aODFVersion;
1416 : try
1417 : {
1418 : // check the version of the document
1419 0 : uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1420 0 : xPropSet->getPropertyValue("Version") >>= aODFVersion;
1421 : }
1422 0 : catch( uno::Exception& )
1423 : {}
1424 :
1425 0 : bool bNoSig = false;
1426 :
1427 0 : if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty()
1428 0 : || (aODFVersion != ODFVER_012_TEXT && !bHasSign) )
1429 : {
1430 : // the document might need saving ( new, modified or in ODF1.1 format without signature )
1431 :
1432 0 : if ( nVersion >= SvtSaveOptions::ODFVER_012 )
1433 : {
1434 :
1435 0 : if ( (bHasSign && ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO)->Execute() == RET_YES)
1436 0 : || (!bHasSign && ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(RID_SVXSTR_XMLSEC_QUERY_SAVEBEFORESIGN), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO)->Execute() == RET_YES) )
1437 : {
1438 0 : sal_uInt16 nId = SID_SAVEDOC;
1439 0 : if ( !GetMedium() || GetMedium()->GetName().isEmpty() )
1440 0 : nId = SID_SAVEASDOC;
1441 0 : SfxRequest aSaveRequest( nId, SfxCallMode::SLOT, GetPool() );
1442 : //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved.
1443 0 : SetModified(true);
1444 0 : ExecFile_Impl( aSaveRequest );
1445 :
1446 : // Check if it is stored in OASIS format...
1447 0 : if ( GetMedium() && GetMedium()->GetFilter()
1448 0 : && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl()
1449 0 : || SotStorage::GetVersion( GetMedium()->GetStorage() ) <= SOFFICE_FILEFORMAT_60 ) )
1450 : {
1451 : // Only OASIS format will be handled further
1452 0 : ScopedVclPtrInstance<MessageDialog>::Create( nullptr, SfxResId( STR_INFO_WRONGDOCFORMAT ), VCL_MESSAGE_INFO )->Execute();
1453 0 : return;
1454 0 : }
1455 : }
1456 : else
1457 : {
1458 : // When the document is modified then we must not show the
1459 : // digital signatures dialog
1460 : // If we have come here then the user denied to save.
1461 0 : if (!bHasSign)
1462 0 : bNoSig = true;
1463 : }
1464 : }
1465 : else
1466 : {
1467 0 : ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_XMLSEC_ODF12_EXPECTED))->Execute();
1468 0 : return;
1469 : }
1470 :
1471 0 : if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty() )
1472 0 : return;
1473 : }
1474 :
1475 : // the document is not modified currently, so it can not become modified after signing
1476 0 : bool bAllowModifiedBack = false;
1477 0 : if ( IsEnableSetModified() )
1478 : {
1479 0 : EnableSetModified( false );
1480 0 : bAllowModifiedBack = true;
1481 : }
1482 :
1483 : // we have to store to the original document, the original medium should be closed for this time
1484 0 : if ( !bNoSig
1485 0 : && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1486 : {
1487 0 : GetMedium()->CloseAndRelease();
1488 :
1489 : // We sign only ODF1.2, that means that if this point has been reached,
1490 : // the ODF1.2 signing process should be used.
1491 : // This code still might be called to show the signature of ODF1.1 document.
1492 : bool bSigned = GetMedium()->SignContents_Impl(
1493 : bScriptingContent,
1494 : aODFVersion,
1495 0 : pImp->nDocumentSignatureState == SignatureState::OK
1496 0 : || pImp->nDocumentSignatureState == SignatureState::NOTVALIDATED
1497 0 : || pImp->nDocumentSignatureState == SignatureState::PARTIAL_OK);
1498 :
1499 0 : DoSaveCompleted( GetMedium() );
1500 :
1501 0 : if ( bSigned )
1502 : {
1503 0 : if ( bScriptingContent )
1504 : {
1505 0 : pImp->nScriptingSignatureState = SignatureState::UNKNOWN;// Re-Check
1506 :
1507 : // adding of scripting signature removes existing document signature
1508 0 : pImp->nDocumentSignatureState = SignatureState::UNKNOWN;// Re-Check
1509 : }
1510 : else
1511 0 : pImp->nDocumentSignatureState = SignatureState::UNKNOWN;// Re-Check
1512 :
1513 0 : pImp->bSignatureErrorIsShown = false;
1514 :
1515 0 : Invalidate( SID_SIGNATURE );
1516 0 : Invalidate( SID_MACRO_SIGNATURE );
1517 0 : Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
1518 : }
1519 : }
1520 :
1521 0 : if ( bAllowModifiedBack )
1522 0 : EnableSetModified( true );
1523 : }
1524 :
1525 22041 : SignatureState SfxObjectShell::GetDocumentSignatureState()
1526 : {
1527 22041 : return ImplGetSignatureState( false );
1528 : }
1529 :
1530 0 : void SfxObjectShell::SignDocumentContent()
1531 : {
1532 0 : ImplSign( false );
1533 0 : }
1534 :
1535 0 : SignatureState SfxObjectShell::GetScriptingSignatureState()
1536 : {
1537 0 : return ImplGetSignatureState( true );
1538 : }
1539 :
1540 0 : void SfxObjectShell::SignScriptingContent()
1541 : {
1542 0 : ImplSign( true );
1543 0 : }
1544 :
1545 : namespace
1546 : {
1547 : class theSfxObjectShellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSfxObjectShellUnoTunnelId > {};
1548 : }
1549 :
1550 79783 : const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId()
1551 : {
1552 79783 : return theSfxObjectShellUnoTunnelId::get().getSeq();
1553 648 : }
1554 :
1555 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|