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