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