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