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