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