merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / doc / objserv.cxx
blobf4fbc00c970a741e557e9fd1e1c5a5deb6e3e319
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: objserv.cxx,v $
10 * $Revision: 1.106 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <sot/storage.hxx>
35 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
36 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
38 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
39 #include <com/sun/star/ui/dialogs/XControlAccess.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/beans/XPropertyAccess.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/beans/PropertyValue.hpp>
44 #include <com/sun/star/container/XNameAccess.hpp>
45 #include <com/sun/star/document/XExporter.hpp>
46 #include <com/sun/star/task/XInteractionHandler.hpp>
47 #include <com/sun/star/task/XStatusIndicator.hpp>
48 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
49 #include <com/sun/star/frame/XDocumentTemplates.hpp>
50 #include <com/sun/star/frame/XStorable.hpp>
51 #include <comphelper/processfactory.hxx>
52 #include <com/sun/star/security/CertificateValidity.hpp>
54 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
55 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
56 #include <tools/urlobj.hxx>
57 #include <svtools/whiter.hxx>
58 #include <vcl/msgbox.hxx>
59 #include <svtools/intitem.hxx>
60 #include <svtools/eitem.hxx>
61 #include <vcl/wrkwin.hxx>
62 #include <svtools/sfxecode.hxx>
63 #include <svtools/ehdl.hxx>
65 #include <comphelper/string.hxx>
66 #include <basic/sbx.hxx>
67 #include <svtools/pathoptions.hxx>
68 #include <svtools/useroptions.hxx>
69 #include <svtools/asynclink.hxx>
70 #include <svtools/saveopt.hxx>
71 #include <comphelper/documentconstants.hxx>
73 #include <sfx2/app.hxx>
74 #include <sfx2/signaturestate.hxx>
75 #include "sfxresid.hxx"
76 #include <sfx2/event.hxx>
77 #include <sfx2/request.hxx>
78 #include <sfx2/printer.hxx>
79 #include <sfx2/viewsh.hxx>
80 #include <sfx2/doctdlg.hxx>
81 #include <sfx2/docfilt.hxx>
82 #include <sfx2/docfile.hxx>
83 #include <sfx2/dispatch.hxx>
84 #include <sfx2/dinfdlg.hxx>
85 #include <sfx2/objitem.hxx>
86 #include <sfx2/objsh.hxx>
87 #include "objshimp.hxx"
88 #include "sfxtypes.hxx"
89 //#include "interno.hxx"
90 #include <sfx2/module.hxx>
91 #include <sfx2/topfrm.hxx>
92 #include "versdlg.hxx"
93 #include "doc.hrc"
94 #include <sfx2/docfac.hxx>
95 #include <sfx2/fcontnr.hxx>
96 #include <sfx2/filedlghelper.hxx>
97 #include "sfxhelp.hxx"
98 #include <sfx2/msgpool.hxx>
99 #include <sfx2/objface.hxx>
101 #include "../appl/app.hrc"
102 #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
103 #include <com/sun/star/embed/XTransactedObject.hpp>
104 #include <com/sun/star/util/XCloneable.hpp>
105 #include <com/sun/star/document/XDocumentProperties.hpp>
106 #include <com/sun/star/document/XDocumentEventCompatibleHelper.hpp>
108 #include "helpid.hrc"
110 #include "guisaveas.hxx"
112 using namespace ::com::sun::star;
113 using namespace ::com::sun::star::lang;
114 using namespace ::com::sun::star::uno;
115 using namespace ::com::sun::star::ui::dialogs;
116 using namespace ::com::sun::star::awt;
117 using namespace ::com::sun::star::container;
118 using namespace ::com::sun::star::beans;
119 using namespace ::com::sun::star::document;
120 using namespace ::com::sun::star::task;
122 //====================================================================
124 class SfxSaveAsContext_Impl
126 String& _rNewNameVar;
127 String _aNewName;
129 public:
130 SfxSaveAsContext_Impl( String &rNewNameVar,
131 const String &rNewName )
132 : _rNewNameVar( rNewNameVar ),
133 _aNewName( rNewName )
134 { rNewNameVar = rNewName; }
135 ~SfxSaveAsContext_Impl()
136 { _rNewNameVar.Erase(); }
139 //====================================================================
141 #define SfxObjectShell
142 #include "sfxslots.hxx"
144 svtools::AsynchronLink* pPendingCloser = 0;
146 //=========================================================================
150 SFX_IMPL_INTERFACE(SfxObjectShell,SfxShell,SfxResId(0))
154 //=========================================================================
156 class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
158 sal_Bool m_bGotOwnership;
159 sal_Bool m_bPreventClose;
161 public:
162 SfxClosePreventer_Impl();
164 sal_Bool HasOwnership() { return m_bGotOwnership; }
166 void SetPreventClose( sal_Bool bPrevent ) { m_bPreventClose = bPrevent; }
168 virtual void SAL_CALL queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
169 throw ( uno::RuntimeException, util::CloseVetoException );
171 virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException ) ;
173 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException ) ;
177 SfxClosePreventer_Impl::SfxClosePreventer_Impl()
178 : m_bGotOwnership( sal_False )
179 , m_bPreventClose( sal_True )
183 void SAL_CALL SfxClosePreventer_Impl::queryClosing( const lang::EventObject&, sal_Bool bDeliverOwnership )
184 throw ( uno::RuntimeException, util::CloseVetoException )
186 if ( m_bPreventClose )
188 if ( !m_bGotOwnership )
189 m_bGotOwnership = bDeliverOwnership;
191 throw util::CloseVetoException();
195 void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& ) throw ( uno::RuntimeException )
198 void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException )
201 //=========================================================================
202 class SfxInstanceCloseGuard_Impl
204 SfxClosePreventer_Impl* m_pPreventer;
205 uno::Reference< util::XCloseListener > m_xPreventer;
206 uno::Reference< util::XCloseable > m_xCloseable;
208 public:
209 SfxInstanceCloseGuard_Impl()
210 : m_pPreventer( NULL )
213 ~SfxInstanceCloseGuard_Impl();
215 sal_Bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable );
218 sal_Bool SfxInstanceCloseGuard_Impl::Init_Impl( const uno::Reference< util::XCloseable >& xCloseable )
220 sal_Bool bResult = sal_False;
222 // do not allow reinit after the successful init
223 if ( xCloseable.is() && !m_xCloseable.is() )
227 m_pPreventer = new SfxClosePreventer_Impl();
228 m_xPreventer = uno::Reference< util::XCloseListener >( m_pPreventer );
229 xCloseable->addCloseListener( m_xPreventer );
230 m_xCloseable = xCloseable;
231 bResult = sal_True;
233 catch( uno::Exception& )
235 OSL_ENSURE( sal_False, "Could not register close listener!\n" );
239 return bResult;
242 SfxInstanceCloseGuard_Impl::~SfxInstanceCloseGuard_Impl()
244 if ( m_xCloseable.is() && m_xPreventer.is() )
248 m_xCloseable->removeCloseListener( m_xPreventer );
250 catch( uno::Exception& )
256 if ( m_pPreventer )
258 m_pPreventer->SetPreventClose( sal_False );
260 if ( m_pPreventer->HasOwnership() )
261 m_xCloseable->close( sal_True ); // TODO: do it asynchronously
264 catch( uno::Exception& )
270 //=========================================================================
272 void SfxObjectShell::PrintExec_Impl(SfxRequest &rReq)
274 SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this);
275 if ( pFrame )
277 rReq.SetSlot( SID_PRINTDOC );
278 pFrame->GetViewShell()->ExecuteSlot(rReq);
282 //--------------------------------------------------------------------
284 void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet)
286 bool bPrinting = false;
287 SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this, TYPE(SfxTopViewFrame));
288 if ( pFrame )
290 SfxPrinter *pPrinter = pFrame->GetViewShell()->GetPrinter();
291 bPrinting = pPrinter && pPrinter->IsPrinting();
293 rSet.Put( SfxBoolItem( SID_PRINTOUT, bPrinting ) );
296 //--------------------------------------------------------------------
298 sal_Bool SfxObjectShell::APISaveAs_Impl
300 const String& aFileName,
301 SfxItemSet* aParams
304 BOOL bOk = sal_False;
306 {DBG_CHKTHIS(SfxObjectShell, 0);}
308 if ( GetMedium() )
310 String aFilterName;
311 SFX_ITEMSET_ARG( aParams, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
312 if( pFilterNameItem )
314 aFilterName = pFilterNameItem->GetValue();
316 else
318 SFX_ITEMSET_ARG( aParams, pContentTypeItem, SfxStringItem, SID_CONTENTTYPE, sal_False );
319 if ( pContentTypeItem )
321 const SfxFilter* pFilter = SfxFilterMatcher( String::CreateFromAscii(GetFactory().GetShortName()) ).GetFilter4Mime( pContentTypeItem->GetValue(), SFX_FILTER_EXPORT );
322 if ( pFilter )
323 aFilterName = pFilter->GetName();
327 // in case no filter defined use default one
328 if( !aFilterName.Len() )
330 const SfxFilter* pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName());
332 DBG_ASSERT( pFilt, "No default filter!\n" );
333 if( pFilt )
334 aFilterName = pFilt->GetFilterName();
336 aParams->Put(SfxStringItem( SID_FILTER_NAME, aFilterName));
341 SfxObjectShellRef xLock( this ); // ???
343 // use the title that is provided in the media descriptor
344 SFX_ITEMSET_ARG( aParams, pDocTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
345 if ( pDocTitleItem )
346 getDocProperties()->setTitle( pDocTitleItem->GetValue() );
348 bOk = CommonSaveAs_Impl( INetURLObject(aFileName), aFilterName,
349 aParams );
353 // prevent picklist-entry
354 GetMedium()->SetUpdatePickList( FALSE );
357 return bOk;
360 //--------------------------------------------------------------------
362 void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
364 {DBG_CHKTHIS(SfxObjectShell, 0);}
366 USHORT nId = rReq.GetSlot();
368 if( SID_SIGNATURE == nId || SID_MACRO_SIGNATURE == nId )
370 if ( QueryHiddenInformation( WhenSigning, NULL ) == RET_YES )
371 ( SID_SIGNATURE == nId ) ? SignDocumentContent() : SignScriptingContent();
372 return;
375 if ( !GetMedium() && nId != SID_CLOSEDOC )
377 rReq.Ignore();
378 return;
381 // this guard is created here to have it destruction at the end of the method
382 SfxInstanceCloseGuard_Impl aModelGuard;
384 sal_Bool bIsPDFExport = sal_False;
385 switch(nId)
387 case SID_VERSION:
389 SfxViewFrame* pFrame = GetFrame();
390 if ( !pFrame )
391 pFrame = SfxViewFrame::GetFirst( this );
392 if ( !pFrame )
393 return;
395 if ( pFrame->GetFrame()->GetParentFrame() )
397 pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
398 return;
401 if ( !IsOwnStorageFormat_Impl( *GetMedium() ) )
402 return;
404 SfxVersionDialog *pDlg = new SfxVersionDialog( pFrame, IsSaveVersionOnClose() );
405 pDlg->Execute();
406 SetSaveVersionOnClose( pDlg->IsSaveVersionOnClose() );
407 delete pDlg;
408 rReq.Done();
409 return;
412 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
413 case SID_DOCINFO:
415 SFX_REQUEST_ARG(rReq, pDocInfItem, SfxDocumentInfoItem, SID_DOCINFO, FALSE);
416 if ( pDocInfItem )
418 // parameter, e.g. from replayed macro
419 pDocInfItem->UpdateDocumentInfo(getDocProperties(), true);
420 SetUseUserData( pDocInfItem->IsUseUserData() );
422 else
424 // no argument containing DocInfo; check optional arguments
425 BOOL bReadOnly = IsReadOnly();
426 SFX_REQUEST_ARG(rReq, pROItem, SfxBoolItem, SID_DOC_READONLY, FALSE);
427 if ( pROItem )
428 // override readonly attribute of document
429 // e.g. if a readonly document is saved elsewhere and user asks for editing DocInfo before
430 bReadOnly = pROItem->GetValue();
432 // collect data for dialog
433 String aURL, aTitle;
434 if ( HasName() && !pImp->aNewName.Len() )
436 aURL = GetMedium()->GetName();
437 aTitle = GetTitle();
439 else
441 if ( !pImp->aNewName.Len() )
443 aURL = DEFINE_CONST_UNICODE( "private:factory/" );
444 aURL += String::CreateFromAscii( GetFactory().GetShortName() );
445 // aTitle = String( SfxResId( STR_NONAME ) );
447 else
449 aURL = DEFINE_CONST_UNICODE( "[private:factory/" );
450 aURL += String::CreateFromAscii( GetFactory().GetShortName() );
451 aURL += DEFINE_CONST_UNICODE( "]" );
452 INetURLObject aURLObj( pImp->aNewName );
453 aURL += String(aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI ));
454 // aTitle = aURLObj.GetBase();
457 aTitle = GetTitle();
460 SfxDocumentInfoItem aDocInfoItem( aURL, getDocProperties(),
461 IsUseUserData() );
462 if ( !GetSlotState( SID_DOCTEMPLATE ) )
463 // templates not supported
464 aDocInfoItem.SetTemplate(FALSE);
466 SfxItemSet aSet(GetPool(), SID_DOCINFO, SID_DOCINFO, SID_DOC_READONLY, SID_DOC_READONLY,
467 SID_EXPLORER_PROPS_START, SID_EXPLORER_PROPS_START, SID_BASEURL, SID_BASEURL,
468 0L );
469 aSet.Put( aDocInfoItem );
470 aSet.Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
471 aSet.Put( SfxStringItem( SID_EXPLORER_PROPS_START, aTitle ) );
472 aSet.Put( SfxStringItem( SID_BASEURL, GetMedium()->GetBaseURL() ) );
474 // creating dialog is done via virtual method; application will add its own statistics page
475 SfxDocumentInfoDialog *pDlg = CreateDocumentInfoDialog(0, aSet);
476 if ( RET_OK == pDlg->Execute() )
478 SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pDocInfoItem, SfxDocumentInfoItem, SID_DOCINFO, FALSE);
479 if ( pDocInfoItem )
481 // user has done some changes to DocumentInfo
482 pDocInfoItem->UpdateDocumentInfo(getDocProperties());
483 SetUseUserData( ((const SfxDocumentInfoItem *)pDocInfoItem)->IsUseUserData() );
485 // add data from dialog for possible recording purposes
486 rReq.AppendItem( SfxDocumentInfoItem( GetTitle(),
487 getDocProperties(), IsUseUserData() ) );
490 rReq.Done();
492 else
493 // nothing done; no recording
494 rReq.Ignore();
496 delete pDlg;
499 return;
502 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
504 case SID_EXPORTDOCASPDF:
505 case SID_DIRECTEXPORTDOCASPDF:
506 bIsPDFExport = sal_True;
507 case SID_EXPORTDOC:
508 case SID_SAVEASDOC:
509 case SID_SAVEDOC:
511 if( nId == SID_SAVEDOC || nId == SID_SAVEASDOC )
513 uno::Reference< document::XDocumentEventCompatibleHelper > xVbaEventHelper( GetModel(), uno::UNO_QUERY );
514 if( xVbaEventHelper.is() )
516 if( xVbaEventHelper->processCompatibleEvent( nId ) )
518 rReq.SetReturnValue( SfxBoolItem( 0, sal_True ) );
519 return;
523 //!! detaillierte Auswertung eines Fehlercodes
524 SfxObjectShellRef xLock( this );
526 // the model can not be closed till the end of this method
527 // if somebody tries to close it during this time the model will be closed
528 // at the end of the method
529 aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) );
531 sal_Bool bDialogUsed = sal_False;
532 sal_uInt32 nErrorCode = ERRCODE_NONE;
534 // by default versions should be preserved always except in case of an explicit
535 // SaveAs via GUI, so the flag must be set accordingly
536 pImp->bPreserveVersions = (nId == SID_SAVEDOC);
539 SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ???
541 if ( nId == SID_SAVEASDOC )
543 // in case of plugin mode the SaveAs operation means SaveTo
544 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, FALSE );
545 if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
546 rReq.AppendItem( SfxBoolItem( SID_SAVETO, sal_True ) );
549 // TODO/LATER: do the following GUI related actions in standalown method
550 // ========================================================================================================
551 // Introduce a status indicator for GUI operation
552 SFX_REQUEST_ARG( rReq, pStatusIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, FALSE );
553 if ( !pStatusIndicatorItem )
555 // get statusindicator
556 uno::Reference< task::XStatusIndicator > xStatusIndicator;
557 SfxViewFrame *pFrame = GetFrame();
558 if ( pFrame && pFrame->GetFrame() )
560 uno::Reference< task::XStatusIndicatorFactory > xStatFactory(
561 pFrame->GetFrame()->GetFrameInterface(),
562 uno::UNO_QUERY );
563 if( xStatFactory.is() )
564 xStatusIndicator = xStatFactory->createStatusIndicator();
568 OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!\n" );
569 if ( xStatusIndicator.is() )
571 SfxUnoAnyItem aStatIndItem( SID_PROGRESS_STATUSBAR_CONTROL, uno::makeAny( xStatusIndicator ) );
573 if ( nId == SID_SAVEDOC )
575 // in case of saving it is not possible to transport the parameters from here
576 // but it is not clear here whether the saving will be done or saveAs operation
577 GetMedium()->GetItemSet()->Put( aStatIndItem );
580 rReq.AppendItem( aStatIndItem );
583 else if ( nId == SID_SAVEDOC )
585 // in case of saving it is not possible to transport the parameters from here
586 // but it is not clear here whether the saving will be done or saveAs operation
587 GetMedium()->GetItemSet()->Put( *pStatusIndicatorItem );
590 // Introduce an interaction handler for GUI operation
591 SFX_REQUEST_ARG( rReq, pInteractionHandlerItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, FALSE );
592 if ( !pInteractionHandlerItem )
594 uno::Reference< task::XInteractionHandler > xInteract;
595 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
596 if( xServiceManager.is() )
598 xInteract = Reference< XInteractionHandler >(
599 xServiceManager->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ),
600 UNO_QUERY );
603 OSL_ENSURE( xInteract.is(), "Can not retrieve default status indicator!\n" );
604 if ( xInteract.is() )
606 SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER, uno::makeAny( xInteract ) );
607 if ( nId == SID_SAVEDOC )
609 // in case of saving it is not possible to transport the parameters from here
610 // but it is not clear here whether the saving will be done or saveAs operation
611 GetMedium()->GetItemSet()->Put( aInteractionItem );
614 rReq.AppendItem( aInteractionItem );
617 else if ( nId == SID_SAVEDOC )
619 // in case of saving it is not possible to transport the parameters from here
620 // but it is not clear here whether the saving will be done or saveAs operation
621 GetMedium()->GetItemSet()->Put( *pInteractionHandlerItem );
623 // ========================================================================================================
625 sal_Bool bPreselectPassword = sal_False;
626 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldPasswordItem, SfxStringItem, SID_PASSWORD, FALSE );
627 if ( pOldPasswordItem )
628 bPreselectPassword = sal_True;
630 uno::Sequence< beans::PropertyValue > aDispatchArgs;
631 if ( rReq.GetArgs() )
632 TransformItems( nId,
633 *rReq.GetArgs(),
634 aDispatchArgs,
635 NULL );
637 const SfxSlot* pSlot = GetModule()->GetSlotPool()->GetSlot( nId );
638 if ( !pSlot )
639 throw uno::Exception();
641 uno::Reference< lang::XMultiServiceFactory > xEmptyFactory;
642 SfxStoringHelper aHelper( xEmptyFactory );
644 if ( QueryHiddenInformation( bIsPDFExport ? WhenCreatingPDF : WhenSaving, NULL ) == RET_YES )
646 bDialogUsed = aHelper.GUIStoreModel( GetModel(),
647 ::rtl::OUString::createFromAscii( pSlot->GetUnoName() ),
648 aDispatchArgs,
649 bPreselectPassword,
650 GetSharedFileURL(),
651 GetDocumentSignatureState() );
653 else
655 // the user has decided not to store the document
656 throw task::ErrorCodeIOException( ::rtl::OUString(),
657 uno::Reference< uno::XInterface >(),
658 ERRCODE_IO_ABORT );
661 // merge aDispatchArgs to the request
662 SfxAllItemSet aResultParams( GetPool() );
663 TransformParameters( nId,
664 aDispatchArgs,
665 aResultParams,
666 NULL );
667 rReq.SetArgs( aResultParams );
669 SFX_REQUEST_ARG( rReq, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, FALSE );
670 ::rtl::OUString aFilterName = pFilterNameItem ? ::rtl::OUString( pFilterNameItem->GetValue() )
671 : ::rtl::OUString();
672 const SfxFilter* pFilt = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
674 OSL_ENSURE( nId == SID_SAVEDOC || pFilt, "The filter can not be zero since it was used for storing!\n" );
675 if ( bDialogUsed && pFilt
676 && pFilt->IsOwnFormat()
677 && pFilt->UsesStorage()
678 && pFilt->GetVersion() >= SOFFICE_FILEFORMAT_60 )
680 SfxViewFrame* pDocViewFrame = SfxViewFrame::GetFirst( this );
681 SfxFrame* pDocFrame = pDocViewFrame ? pDocViewFrame->GetFrame() : NULL;
682 if ( pDocFrame )
683 SfxHelp::OpenHelpAgent( pDocFrame, HID_DID_SAVE_PACKED_XML );
686 // the StoreAsURL/StoreToURL method have called this method with false
687 // so it has to be restored to true here since it is a call from GUI
688 GetMedium()->SetUpdatePickList( sal_True );
690 // TODO: in future it must be done in followind way
691 // if document is opened from GUI it is immediatelly appeares in the picklist
692 // if the document is a new one then it appeares in the picklist immediatelly
693 // after SaveAs operation triggered from GUI
695 catch( task::ErrorCodeIOException& aErrorEx )
697 nErrorCode = (sal_uInt32)aErrorEx.ErrCode;
699 catch( Exception& )
701 nErrorCode = ERRCODE_IO_GENERAL;
704 // by default versions should be preserved always except in case of an explicit
705 // SaveAs via GUI, so the flag must be reset to guarantee this
706 pImp->bPreserveVersions = sal_True;
707 ULONG lErr=GetErrorCode();
709 if ( !lErr && nErrorCode )
710 lErr = nErrorCode;
712 if ( lErr && nErrorCode == ERRCODE_NONE )
714 SFX_REQUEST_ARG( rReq, pWarnItem, SfxBoolItem, SID_FAIL_ON_WARNING, FALSE );
715 if ( pWarnItem && pWarnItem->GetValue() )
716 nErrorCode = lErr;
719 // may be nErrorCode should be shown in future
720 if ( lErr != ERRCODE_IO_ABORT )
722 SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC,GetTitle());
723 ErrorHandler::HandleError( lErr );
726 if ( nId == SID_EXPORTDOCASPDF )
728 // This function is used by the SendMail function that needs information if a export
729 // file was written or not. This could be due to cancellation of the export
730 // or due to an error. So IO abort must be handled like an error!
731 nErrorCode = ( lErr != ERRCODE_IO_ABORT ) && ( nErrorCode == ERRCODE_NONE ) ? nErrorCode : lErr;
734 rReq.SetReturnValue( SfxBoolItem(0, nErrorCode == ERRCODE_NONE ) );
736 ResetError();
738 Invalidate();
739 break;
742 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
744 case SID_CLOSEDOC:
746 SfxViewFrame *pFrame = GetFrame();
747 if ( pFrame && pFrame->GetFrame()->GetParentFrame() )
749 // Wenn SID_CLOSEDOC "uber Menue etc. ausgef"uhrt wird, das
750 // aktuelle Dokument aber in einem Frame liegt, soll eigentlich
751 // das FrameSetDocument geclosed werden
752 pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
753 rReq.Done();
754 return;
757 BOOL bInFrameSet = FALSE;
758 USHORT nFrames=0;
759 pFrame = SfxViewFrame::GetFirst( this );
760 while ( pFrame )
762 if ( pFrame->GetFrame()->GetParentFrame() )
764 // Auf dieses Dokument existiert noch eine Sicht, die
765 // in einem FrameSet liegt; diese darf nat"urlich nicht
766 // geclosed werden
767 bInFrameSet = TRUE;
769 else
770 nFrames++;
772 pFrame = SfxViewFrame::GetNext( *pFrame, this );
775 if ( bInFrameSet )
777 // Alle Sichten, die nicht in einem FrameSet liegen, closen
778 pFrame = SfxViewFrame::GetFirst( this );
779 while ( pFrame )
781 if ( !pFrame->GetFrame()->GetParentFrame() )
782 pFrame->GetFrame()->DoClose();
783 pFrame = SfxViewFrame::GetNext( *pFrame, this );
787 // Parameter auswerten
788 SFX_REQUEST_ARG(rReq, pSaveItem, SfxBoolItem, SID_CLOSEDOC_SAVE, FALSE);
789 SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_CLOSEDOC_FILENAME, FALSE);
790 if ( pSaveItem )
792 if ( pSaveItem->GetValue() )
794 if ( !pNameItem )
796 SbxBase::SetError( SbxERR_WRONG_ARGS );
797 rReq.Ignore();
798 return;
800 SfxAllItemSet aArgs( GetPool() );
801 SfxStringItem aTmpItem( SID_FILE_NAME, pNameItem->GetValue() );
802 aArgs.Put( aTmpItem, aTmpItem.Which() );
803 SfxRequest aSaveAsReq( SID_SAVEASDOC, SFX_CALLMODE_API, aArgs );
804 ExecFile_Impl( aSaveAsReq );
805 if ( !aSaveAsReq.IsDone() )
807 rReq.Ignore();
808 return;
811 else
812 SetModified(FALSE);
815 // Benutzer bricht ab?
816 if ( !PrepareClose( 2 ) )
818 rReq.SetReturnValue( SfxBoolItem(0, FALSE) );
819 rReq.Done();
820 return;
823 SetModified( FALSE );
824 ULONG lErr = GetErrorCode();
825 ErrorHandler::HandleError(lErr);
827 rReq.SetReturnValue( SfxBoolItem(0, TRUE) );
828 rReq.Done();
829 rReq.ReleaseArgs(); // da der Pool in Close zerst"ort wird
830 DoClose();
831 return;
834 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
835 case SID_DOCTEMPLATE:
837 // speichern als Dokumentvorlagen
838 SfxDocumentTemplateDlg *pDlg = 0;
839 SfxErrorContext aEc(ERRCTX_SFX_DOCTEMPLATE,GetTitle());
840 SfxDocumentTemplates *pTemplates = new SfxDocumentTemplates;
842 if ( !rReq.GetArgs() )
844 pDlg = new SfxDocumentTemplateDlg(0, pTemplates);
845 if ( RET_OK == pDlg->Execute() && pDlg->GetTemplateName().Len())
847 rReq.AppendItem(SfxStringItem(
848 SID_TEMPLATE_NAME, pDlg->GetTemplateName()));
849 rReq.AppendItem(SfxStringItem(
850 SID_TEMPLATE_REGIONNAME, pDlg->GetRegionName()));
852 else
854 delete pDlg;
855 rReq.Ignore();
856 return;
860 SFX_REQUEST_ARG(rReq, pRegionItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, FALSE);
861 SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_TEMPLATE_NAME, FALSE);
862 SFX_REQUEST_ARG(rReq, pRegionNrItem, SfxUInt16Item, SID_TEMPLATE_REGION, FALSE);
863 if ( (!pRegionItem && !pRegionNrItem ) || !pNameItem )
865 DBG_ASSERT( rReq.IsAPI(), "non-API call without Arguments" );
866 SbxBase::SetError( SbxERR_WRONG_ARGS );
867 rReq.Ignore();
868 return;
871 ::rtl::OUString aTemplateName = pNameItem->GetValue();
872 ::rtl::OUString aTemplateGroup;
873 if ( pRegionItem )
874 aTemplateGroup = pRegionItem->GetValue();
875 else
876 // pRegionNrItem must not be NULL, it was just checked
877 aTemplateGroup = pTemplates->GetFullRegionName( pRegionNrItem->GetValue() );
878 // check Group and Name
879 delete pTemplates;
881 sal_Bool bOk = sal_False;
884 uno::Reference< frame::XStorable > xStorable( GetModel(), uno::UNO_QUERY_THROW );
885 ::rtl::OUString aService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DocumentTemplates" ) );
886 uno::Reference< frame::XDocumentTemplates > xTemplates(
887 comphelper::getProcessServiceFactory()->createInstance( aService ),
888 uno::UNO_QUERY_THROW );
890 bOk = xTemplates->storeTemplate( aTemplateGroup, aTemplateName, xStorable );
892 catch( uno::Exception& )
896 DELETEX(pDlg);
898 rReq.SetReturnValue( SfxBoolItem( 0, bOk ) );
899 if ( bOk )
901 // update the Organizer runtime cache from the template component if the cache has already been created
902 // TODO/LATER: get rid of this cache duplication
903 SfxDocumentTemplates aTemplates;
904 aTemplates.ReInitFromComponent();
906 else
908 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
909 return;
912 break;
916 // Picklisten-Eintrag verhindern
917 if ( rReq.IsAPI() )
918 GetMedium()->SetUpdatePickList( FALSE );
919 else if ( rReq.GetArgs() )
921 SFX_ITEMSET_GET( *rReq.GetArgs(), pPicklistItem, SfxBoolItem, SID_PICKLIST, FALSE );
922 if ( pPicklistItem )
923 GetMedium()->SetUpdatePickList( pPicklistItem->GetValue() );
926 // Ignore()-Zweige haben schon returnt
927 rReq.Done();
930 //--------------------------------------------------------------------
932 void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
934 DBG_CHKTHIS(SfxObjectShell, 0);
935 SfxWhichIter aIter( rSet );
937 for ( USHORT nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() )
939 switch ( nWhich )
941 case SID_DOCTEMPLATE :
943 if ( !GetFactory().GetTemplateFilter() )
944 rSet.DisableItem( nWhich );
945 break;
948 case SID_VERSION:
950 SfxObjectShell *pDoc = this;
951 SfxViewFrame* pFrame = GetFrame();
952 if ( !pFrame )
953 pFrame = SfxViewFrame::GetFirst( this );
954 if ( pFrame )
956 if ( pFrame->GetFrame()->GetParentFrame() )
958 pFrame = pFrame->GetTopViewFrame();
959 pDoc = pFrame->GetObjectShell();
963 if ( !pFrame || !pDoc->HasName() ||
964 !IsOwnStorageFormat_Impl( *pDoc->GetMedium() ) )
965 //REMOVE || pDoc->GetMedium()->GetStorage()->GetVersion() < SOFFICE_FILEFORMAT_50 )
966 rSet.DisableItem( nWhich );
967 break;
969 case SID_SAVEDOC:
971 bool bAllowSave = (GetApplicationFlag(SFX_APPFLAG_ALWAYS_ALLOW_SAVE) || IsModified());
972 bool bMediumRO = IsReadOnlyMedium();
973 if ( !bMediumRO && GetMedium() && bAllowSave )
974 rSet.Put(SfxStringItem(
975 nWhich, String(SfxResId(STR_SAVEDOC))));
976 else
977 rSet.DisableItem(nWhich);
979 break;
981 case SID_DOCINFO:
982 if ( 0 != ( pImp->eFlags & SFXOBJECTSHELL_NODOCINFO ) )
983 rSet.DisableItem( nWhich );
984 break;
986 case SID_CLOSEDOC:
988 SfxObjectShell *pDoc = this;
989 SfxViewFrame *pFrame = GetFrame();
990 if ( pFrame && pFrame->GetFrame()->GetParentFrame() )
992 // Wenn SID_CLOSEDOC "uber Menue etc. ausgef"uhrt wird, das
993 // aktuelle Dokument aber in einem Frame liegt, soll eigentlich
994 // das FrameSetDocument geclosed werden
995 pDoc = pFrame->GetTopViewFrame()->GetObjectShell();
998 if ( pDoc->GetFlags() & SFXOBJECTSHELL_DONTCLOSE )
999 rSet.DisableItem(nWhich);
1000 else
1001 rSet.Put(SfxStringItem(nWhich, String(SfxResId(STR_CLOSEDOC))));
1002 break;
1005 case SID_SAVEASDOC:
1007 if( ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) != SFX_LOADED_MAINDOCUMENT )
1009 rSet.DisableItem( nWhich );
1010 break;
1013 const SfxFilter* pCombinedFilters = NULL;
1014 SfxFilterContainer* pFilterContainer = GetFactory().GetFilterContainer();
1016 if ( pFilterContainer )
1018 SfxFilterFlags nMust = SFX_FILTER_IMPORT | SFX_FILTER_EXPORT;
1019 SfxFilterFlags nDont = SFX_FILTER_NOTINSTALLED | SFX_FILTER_INTERNAL;
1021 pCombinedFilters = pFilterContainer->GetAnyFilter( nMust, nDont );
1024 if ( /*!pCombinedFilters ||*/ !GetMedium() )
1025 rSet.DisableItem( nWhich );
1026 else
1027 rSet.Put( SfxStringItem( nWhich, String( SfxResId( STR_SAVEASDOC ) ) ) );
1028 break;
1031 case SID_EXPORTDOCASPDF:
1032 case SID_DIRECTEXPORTDOCASPDF:
1036 search for filter cant work correctly ...
1037 Because it's not clear, which export filter for which office module
1038 must be searched. On the other side it can be very expensive doing so.
1039 The best solution would be: on installation time we should know if pdf feature
1040 was installed or not!!! (e.g. by writing a bool inside cfg)
1042 SfxFilterContainer* pFilterContainer = GetFactory().GetFilterContainer();
1043 if ( pFilterContainer )
1045 String aPDFExtension = String::CreateFromAscii( "pdf" );
1046 const SfxFilter* pFilter = pFilterContainer->GetFilter4Extension( aPDFExtension, SFX_FILTER_EXPORT );
1047 if ( pFilter != NULL )
1048 break;
1051 rSet.DisableItem( nWhich );
1053 break;
1056 case SID_DOC_MODIFIED:
1058 rSet.Put( SfxBoolItem( SID_DOC_MODIFIED, IsModified() ) );
1059 break;
1062 case SID_MODIFIED:
1064 rSet.Put( SfxBoolItem( SID_MODIFIED, IsModified() ) );
1065 break;
1068 case SID_DOCINFO_TITLE:
1070 rSet.Put( SfxStringItem(
1071 SID_DOCINFO_TITLE, getDocProperties()->getTitle() ) );
1072 break;
1074 case SID_FILE_NAME:
1076 if( GetMedium() && HasName() )
1077 rSet.Put( SfxStringItem(
1078 SID_FILE_NAME, GetMedium()->GetName() ) );
1079 break;
1081 case SID_SIGNATURE:
1083 rSet.Put( SfxUInt16Item( SID_SIGNATURE, GetDocumentSignatureState() ) );
1084 break;
1086 case SID_MACRO_SIGNATURE:
1088 // the slot makes sense only if there is a macro in the document
1089 if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() )
1090 rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) );
1091 else
1092 rSet.DisableItem( nWhich );
1093 break;
1099 //--------------------------------------------------------------------
1101 void SfxObjectShell::ExecProps_Impl(SfxRequest &rReq)
1103 switch ( rReq.GetSlot() )
1105 case SID_MODIFIED:
1107 SetModified( ( (SfxBoolItem&) rReq.GetArgs()->Get(SID_MODIFIED)).GetValue() );
1108 rReq.Done();
1109 break;
1112 case SID_DOCTITLE:
1113 SetTitle( ( (SfxStringItem&) rReq.GetArgs()->Get(SID_DOCTITLE)).GetValue() );
1114 rReq.Done();
1115 break;
1117 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1118 case SID_PLAYMACRO:
1120 SFX_APP()->PlayMacro_Impl( rReq, GetBasic() );
1121 break;
1124 case SID_DOCINFO_AUTHOR :
1126 ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1127 getDocProperties()->setAuthor( aStr );
1128 break;
1131 case SID_DOCINFO_COMMENTS :
1133 ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1134 getDocProperties()->setDescription( aStr );
1135 break;
1138 case SID_DOCINFO_KEYWORDS :
1140 ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1141 getDocProperties()->setKeywords(
1142 ::comphelper::string::convertCommaSeparated(aStr) );
1143 break;
1148 //--------------------------------------------------------------------
1150 void SfxObjectShell::StateProps_Impl(SfxItemSet &rSet)
1152 SfxWhichIter aIter(rSet);
1153 for ( USHORT nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
1155 switch ( nSID )
1157 case SID_DOCINFO_AUTHOR :
1159 rSet.Put( SfxStringItem( nSID,
1160 getDocProperties()->getAuthor() ) );
1161 break;
1164 case SID_DOCINFO_COMMENTS :
1166 rSet.Put( SfxStringItem( nSID,
1167 getDocProperties()->getDescription()) );
1168 break;
1171 case SID_DOCINFO_KEYWORDS :
1173 rSet.Put( SfxStringItem( nSID, ::comphelper::string::
1174 convertCommaSeparated(getDocProperties()->getKeywords())) );
1175 break;
1178 case SID_DOCPATH:
1180 DBG_ERROR( "Not supported anymore!" );
1181 break;
1184 case SID_DOCFULLNAME:
1186 rSet.Put( SfxStringItem( SID_DOCFULLNAME, GetTitle(SFX_TITLE_FULLNAME) ) );
1187 break;
1190 case SID_DOCTITLE:
1192 rSet.Put( SfxStringItem( SID_DOCTITLE, GetTitle() ) );
1193 break;
1196 case SID_DOC_READONLY:
1198 rSet.Put( SfxBoolItem( SID_DOC_READONLY, IsReadOnly() ) );
1199 break;
1202 case SID_DOC_SAVED:
1204 rSet.Put( SfxBoolItem( SID_DOC_SAVED, !IsModified() ) );
1205 break;
1208 case SID_CLOSING:
1210 rSet.Put( SfxBoolItem( SID_CLOSING, Get_Impl()->bInCloseEvent ) );
1211 break;
1214 case SID_DOC_LOADING:
1215 rSet.Put( SfxBoolItem( nSID, SFX_LOADED_MAINDOCUMENT !=
1216 ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) ) );
1217 break;
1219 case SID_IMG_LOADING:
1220 rSet.Put( SfxBoolItem( nSID, SFX_LOADED_IMAGES !=
1221 ( pImp->nLoadedFlags & SFX_LOADED_IMAGES ) ) );
1222 break;
1227 //--------------------------------------------------------------------
1229 void SfxObjectShell::ExecView_Impl(SfxRequest &rReq)
1231 switch ( rReq.GetSlot() )
1233 case SID_ACTIVATE:
1235 SfxViewFrame *pFrame =
1236 SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame), TRUE );
1237 if ( pFrame )
1238 pFrame->GetFrame()->Appear();
1239 rReq.SetReturnValue( SfxObjectItem( 0, pFrame ) );
1240 rReq.Done();
1241 break;
1243 case SID_NEWWINDOWFOREDIT:
1245 SfxViewFrame* pFrame = SfxViewFrame::Current();
1246 if( pFrame->GetObjectShell() == this &&
1247 ( pFrame->GetFrameType() & SFXFRAME_HASTITLE ) )
1248 pFrame->ExecuteSlot( rReq );
1249 else
1251 String aFileName( GetObjectShell()->GetMedium()->GetName() );
1252 if ( aFileName.Len() )
1254 SfxStringItem aName( SID_FILE_NAME, aFileName );
1255 SfxBoolItem aCreateView( SID_OPEN_NEW_VIEW, TRUE );
1256 SFX_APP()->GetAppDispatcher_Impl()->Execute(
1257 SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aName,
1258 &aCreateView, 0L);
1265 //--------------------------------------------------------------------
1267 void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/)
1271 sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< security::DocumentSignatureInformation >& aInfos )
1273 sal_Bool bCertValid = sal_True;
1274 sal_uInt16 nResult = SIGNATURESTATE_NOSIGNATURES;
1275 int nInfos = aInfos.getLength();
1276 bool bCompleteSignature = true;
1277 if( nInfos )
1279 //These errors of certificates are allowed
1280 sal_Int32 nNonErrors = security::CertificateValidity::VALID |
1281 security::CertificateValidity::UNKNOWN_REVOKATION;
1282 //Build a mask to filter out the allowed errors
1283 sal_Int32 nMask = ~nNonErrors;
1285 nResult = SIGNATURESTATE_SIGNATURES_OK;
1286 for ( int n = 0; n < nInfos; n++ )
1288 if ( bCertValid )
1290 sal_Int32 nCertStat = aInfos[n].CertificateStatus;
1291 // "subtract" the allowed error flags from the result
1292 sal_Int32 nErrors = ( nCertStat & nMask );
1293 bCertValid = nErrors > 0 ? sal_False : sal_True;
1296 if ( !aInfos[n].SignatureIsValid )
1298 nResult = SIGNATURESTATE_SIGNATURES_BROKEN;
1299 break; // we know enough
1301 bCompleteSignature &= !aInfos[n].PartialDocumentSignature;
1305 if ( nResult == SIGNATURESTATE_SIGNATURES_OK && !bCertValid )
1306 nResult = SIGNATURESTATE_SIGNATURES_NOTVALIDATED;
1307 else if ( nResult == SIGNATURESTATE_SIGNATURES_OK && bCertValid && !bCompleteSignature)
1308 nResult = SIGNATURESTATE_SIGNATURES_PARTIAL_OK;
1310 // this code must not check whether the document is modified
1311 // it should only check the provided info
1313 return nResult;
1316 uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( sal_Bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner )
1318 uno::Sequence< security::DocumentSignatureInformation > aResult;
1319 uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner;
1321 if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() )
1325 if ( !xLocSigner.is() )
1327 uno::Sequence< uno::Any > aArgs( 1 );
1328 aArgs[0] <<= ::rtl::OUString();
1331 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1332 aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) );
1334 catch( uno::Exception& )
1338 xLocSigner.set( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW );
1342 if ( bScriptingContent )
1343 aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1344 uno::Reference< io::XInputStream >() );
1345 else
1346 aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1347 uno::Reference< io::XInputStream >() );
1349 catch( com::sun::star::uno::Exception& )
1354 return aResult;
1357 sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent )
1359 sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState;
1361 if ( *pState == SIGNATURESTATE_UNKNOWN )
1363 *pState = SIGNATURESTATE_NOSIGNATURES;
1365 uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent );
1366 *pState = ImplCheckSignaturesInformation( aInfos );
1369 if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
1370 || *pState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK)
1372 if ( IsModified() )
1373 *pState = SIGNATURESTATE_SIGNATURES_INVALID;
1376 return (sal_uInt16)*pState;
1379 void SfxObjectShell::ImplSign( sal_Bool bScriptingContent )
1381 // Check if it is stored in OASIS format...
1382 if ( GetMedium() && GetMedium()->GetFilter()
1383 && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl() ) )
1385 // Only OASIS and OOo6.x formats will be handled further
1386 InfoBox( NULL, SfxResId( RID_XMLSEC_INFO_WRONGDOCFORMAT ) ).Execute();
1387 return;
1390 // check whether the document is signed
1391 ImplGetSignatureState( sal_False ); // document signature
1392 ImplGetSignatureState( sal_True ); // script signature
1393 sal_Bool bHasSign = ( pImp->nScriptingSignatureState != SIGNATURESTATE_NOSIGNATURES || pImp->nDocumentSignatureState != SIGNATURESTATE_NOSIGNATURES );
1395 // the target ODF version on saving
1396 SvtSaveOptions aSaveOpt;
1397 SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion();
1399 // the document is not new and is not modified
1400 ::rtl::OUString aODFVersion;
1403 // check the version of the document
1404 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1405 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aODFVersion;
1407 catch( uno::Exception& )
1410 bool bNoSig = false;
1412 if ( IsModified() || !GetMedium() || !GetMedium()->GetName().Len()
1413 || (!aODFVersion.equals( ODFVER_012_TEXT ) && !bHasSign) )
1415 // the document might need saving ( new, modified or in ODF1.1 format without signature )
1417 if ( nVersion >= SvtSaveOptions::ODFVER_012 )
1420 if ( (bHasSign && QueryBox( NULL, SfxResId( MSG_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN ) ).Execute() == RET_YES)
1421 || (!bHasSign && QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_SAVEBEFORESIGN ) ).Execute() == RET_YES) )
1423 USHORT nId = SID_SAVEDOC;
1424 if ( !GetMedium() || !GetMedium()->GetName().Len() )
1425 nId = SID_SAVEASDOC;
1426 SfxRequest aSaveRequest( nId, 0, GetPool() );
1427 //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved.
1428 SetModified(sal_True);
1429 ExecFile_Impl( aSaveRequest );
1431 // Check if it is stored in OASIS format...
1432 if ( GetMedium() && GetMedium()->GetFilter()
1433 && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl()
1434 || SotStorage::GetVersion( GetMedium()->GetStorage() ) <= SOFFICE_FILEFORMAT_60 ) )
1436 // Only OASIS format will be handled further
1437 InfoBox( NULL, SfxResId( RID_XMLSEC_INFO_WRONGDOCFORMAT ) ).Execute();
1438 return;
1441 else
1443 //When the document is modified then we must not show the digital signatures dialog
1444 //If we have come here then the user denied to save.
1445 if (!bHasSign)
1446 bNoSig = true;
1449 else
1451 ErrorBox( NULL, WB_OK, SfxResId( STR_XMLSEC_ODF12_EXPECTED ) ).Execute();
1452 return;
1455 if ( IsModified() || !GetMedium() || !GetMedium()->GetName().Len() )
1456 return;
1459 // the document is not modified currently, so it can not become modified after signing
1460 sal_Bool bAllowModifiedBack = sal_False;
1461 if ( IsEnableSetModified() )
1463 EnableSetModified( sal_False );
1464 bAllowModifiedBack = sal_True;
1467 // we have to store to the original document, the original medium should be closed for this time
1468 if ( !bNoSig
1469 && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1471 GetMedium()->CloseAndRelease();
1473 // We sign only ODF1.2, that means that if this point has been reached,
1474 // the ODF1.2 signing process should be used.
1475 // This code still might be called to show the signature of ODF1.1 document.
1476 sal_Bool bSigned = GetMedium()->SignContents_Impl(
1477 bScriptingContent,
1478 aODFVersion,
1479 pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_OK
1480 || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
1481 || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK);
1483 DoSaveCompleted( GetMedium() );
1485 if ( bSigned )
1487 if ( bScriptingContent )
1489 pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
1491 // adding of scripting signature removes existing document signature
1492 pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
1494 else
1495 pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
1497 pImp->bSignatureErrorIsShown = sal_False;
1499 Invalidate( SID_SIGNATURE );
1500 Invalidate( SID_MACRO_SIGNATURE );
1501 Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
1505 if ( bAllowModifiedBack )
1506 EnableSetModified( sal_True );
1509 sal_uInt16 SfxObjectShell::GetDocumentSignatureState()
1511 return ImplGetSignatureState( FALSE );
1514 void SfxObjectShell::SignDocumentContent()
1516 ImplSign( FALSE );
1519 sal_uInt16 SfxObjectShell::GetScriptingSignatureState()
1521 return ImplGetSignatureState( TRUE );
1524 void SfxObjectShell::SignScriptingContent()
1526 ImplSign( TRUE );
1529 // static
1530 const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId()
1532 static uno::Sequence<sal_Int8> * pSeq = 0;
1533 if( !pSeq )
1535 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
1536 if( !pSeq )
1538 static uno::Sequence< sal_Int8 > aSeq( 16 );
1539 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
1540 pSeq = &aSeq;
1543 return *pSeq;