xref: /aoo41x/main/sfx2/source/doc/objmisc.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 
31 #ifndef _INETMSG_HXX //autogen
32 #include <svl/inetmsg.hxx>
33 #endif
34 #include <tools/diagnose_ex.h>
35 #include <svl/eitem.hxx>
36 #include <svl/stritem.hxx>
37 #include <svl/intitem.hxx>
38 #include <svtools/svparser.hxx> // SvKeyValue
39 #include <vos/mutex.hxx>
40 #include <cppuhelper/exc_hlp.hxx>
41 
42 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
43 #include <com/sun/star/document/XDocumentProperties.hpp>
44 #include <com/sun/star/document/UpdateDocMode.hpp>
45 #include <com/sun/star/script/XTypeConverter.hpp>
46 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
47 #include <com/sun/star/script/FinishEngineEvent.hpp>
48 #include <com/sun/star/script/InterruptReason.hpp>
49 #include <com/sun/star/script/XEngineListener.hpp>
50 #include <com/sun/star/script/XDebugging.hpp>
51 #ifndef _COM_SUN_STAR_SCRIPT_XINVOKATION_HPP_
52 #include <com/sun/star/script/XInvocation.hpp>
53 #endif
54 #include <com/sun/star/script/ContextInformation.hpp>
55 #include <com/sun/star/script/FinishReason.hpp>
56 #include <com/sun/star/script/XEngine.hpp>
57 #include <com/sun/star/script/InterruptEngineEvent.hpp>
58 #include <com/sun/star/script/XLibraryAccess.hpp>
59 #include <com/sun/star/document/MacroExecMode.hpp>
60 #include <com/sun/star/document/XScriptInvocationContext.hpp>
61 #include <com/sun/star/embed/EmbedStates.hpp>
62 #include <com/sun/star/embed/XEmbedPersist.hpp>
63 #include <com/sun/star/util/XModifiable.hpp>
64 #include <com/sun/star/container/XChild.hpp>
65 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
66 
67 
68 #include <com/sun/star/script/provider/XScript.hpp>
69 #include <com/sun/star/script/provider/XScriptProvider.hpp>
70 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
71 
72 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
73 #include <toolkit/unohlp.hxx>
74 #endif
75 
76 #include <com/sun/star/uno/Reference.h>
77 #include <com/sun/star/uno/Any.h>
78 #include <com/sun/star/ucb/XContent.hpp>
79 #include <com/sun/star/task/ErrorCodeRequest.hpp>
80 #include <unotools/securityoptions.hxx>
81 
82 #include <comphelper/processfactory.hxx>
83 #include <comphelper/componentcontext.hxx>
84 #include <comphelper/configurationhelper.hxx>
85 
86 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
87 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
88 #include <com/sun/star/task/InteractionClassification.hpp>
89 #include <com/sun/star/frame/XModel.hpp>
90 
91 using namespace ::com::sun::star;
92 using namespace ::com::sun::star::uno;
93 using namespace ::com::sun::star::ucb;
94 using namespace ::com::sun::star::document;
95 using namespace ::com::sun::star::frame;
96 using namespace ::com::sun::star::script;
97 using namespace ::com::sun::star::script::provider;
98 using namespace ::com::sun::star::container;
99 #include <basic/sbuno.hxx>
100 #include <basic/sbstar.hxx>
101 #ifndef _SB_BASMGR_HXX
102 #include <basic/basmgr.hxx>
103 #endif
104 #ifndef _VCL_MSGBOX_HXX
105 #include <vcl/msgbox.hxx>
106 #endif
107 #include <basic/sbx.hxx>
108 #include <svtools/sfxecode.hxx>
109 #include <svtools/ehdl.hxx>
110 
111 #include <unotools/pathoptions.hxx>
112 #include <unotools/ucbhelper.hxx>
113 #include <tools/inetmime.hxx>
114 #include <tools/urlobj.hxx>
115 #include <svl/inettype.hxx>
116 #include <svl/sharecontrolfile.hxx>
117 #include <osl/file.hxx>
118 #include <rtl/bootstrap.hxx>
119 #include <vcl/svapp.hxx>
120 #include <framework/interaction.hxx>
121 #include <framework/documentundoguard.hxx>
122 #include <comphelper/interaction.hxx>
123 #include <comphelper/storagehelper.hxx>
124 #include <comphelper/documentconstants.hxx>
125 
126 #include <sfx2/signaturestate.hxx>
127 #include <sfx2/app.hxx>
128 #include "appdata.hxx"
129 #include <sfx2/request.hxx>
130 #include <sfx2/bindings.hxx>
131 #include "sfx2/sfxresid.hxx"
132 #include <sfx2/docfile.hxx>
133 #include <sfx2/docfilt.hxx>
134 #include <sfx2/objsh.hxx>
135 #include "objshimp.hxx"
136 #include <sfx2/event.hxx>
137 #include "fltfnc.hxx"
138 #include <sfx2/sfx.hrc>
139 #include <sfx2/dispatch.hxx>
140 #include <sfx2/viewfrm.hxx>
141 #include <sfx2/viewsh.hxx>
142 #include <sfx2/ctrlitem.hxx>
143 #include "arrdecl.hxx"
144 #include <sfx2/module.hxx>
145 #include <sfx2/docfac.hxx>
146 #include "helper.hxx"
147 #include "doc.hrc"
148 #include "workwin.hxx"
149 #include "helpid.hrc"
150 #include "../appl/app.hrc"
151 #include <sfx2/sfxdlg.hxx>
152 #include "appbaslib.hxx"
153 #include <openflag.hxx>                 // SFX_STREAM_READWRITE
154 
155 using namespace ::com::sun::star;
156 
157 // class SfxHeaderAttributes_Impl ----------------------------------------
158 
159 class SfxHeaderAttributes_Impl : public SvKeyValueIterator
160 {
161 private:
162 	SfxObjectShell* pDoc;
163 	SvKeyValueIteratorRef xIter;
164 	sal_Bool bAlert;
165 
166 public:
167 	SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
168 		SvKeyValueIterator(), pDoc( pSh ),
169 		xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
170 		bAlert( sal_False ) {}
171 
172 	virtual sal_Bool GetFirst( SvKeyValue& rKV ) { return xIter->GetFirst( rKV ); }
173 	virtual sal_Bool GetNext( SvKeyValue& rKV ) { return xIter->GetNext( rKV ); }
174 	virtual void Append( const SvKeyValue& rKV );
175 
176 	void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = sal_False; }
177 	void SetAttributes();
178 	void SetAttribute( const SvKeyValue& rKV );
179 };
180 
181 //=========================================================================
182 
183 sal_uInt16 __READONLY_DATA aTitleMap_Impl[3][2] =
184 {
185 								//	local				remote
186 	/*	SFX_TITLE_CAPTION	*/	{ 	SFX_TITLE_FILENAME, SFX_TITLE_TITLE },
187 	/*	SFX_TITLE_PICKLIST  */	{ 	32,					SFX_TITLE_FULLNAME },
188 	/*	SFX_TITLE_HISTORY	*/	{ 	32,					SFX_TITLE_FULLNAME }
189 };
190 
191 //=========================================================================
192 
193 void SfxObjectShell::AbortImport()
194 {
195 	pImp->bIsAbortingImport = sal_True;
196 }
197 
198 //-------------------------------------------------------------------------
199 
200 sal_Bool SfxObjectShell::IsAbortingImport() const
201 {
202 	return pImp->bIsAbortingImport;
203 }
204 
205 //-------------------------------------------------------------------------
206 
207 uno::Reference<document::XDocumentProperties>
208 SfxObjectShell::getDocProperties()
209 {
210     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
211         GetModel(), uno::UNO_QUERY_THROW);
212     uno::Reference<document::XDocumentProperties> xDocProps(
213         xDPS->getDocumentProperties());
214     DBG_ASSERT(xDocProps.is(),
215         "SfxObjectShell: model has no DocumentProperties");
216     return xDocProps;
217 }
218 
219 //-------------------------------------------------------------------------
220 
221 void SfxObjectShell::DoFlushDocInfo()
222 {
223 }
224 
225 //-------------------------------------------------------------------------
226 
227 // Note: the only thing that calls this is the modification event handler
228 // that is installed at the XDocumentProperties
229 void SfxObjectShell::FlushDocInfo()
230 {
231     if ( IsLoading() )
232         return;
233 
234 	SetModified(sal_True);
235     uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
236     DoFlushDocInfo(); // call template method
237     ::rtl::OUString url(xDocProps->getAutoloadURL());
238     sal_Int32 delay(xDocProps->getAutoloadSecs());
239     SetAutoLoad( INetURLObject(url), delay * 1000,
240                  (delay > 0) || url.getLength() );
241 /*
242 	// bitte beachten:
243 	// 1. Titel in DocInfo aber nicht am Doc (nach HTML-Import)
244 	// 	=> auch am Doc setzen
245 	// 2. Titel in DocInfo leer (Briefumschlagsdruck)
246 	//	=> nicht am Doc setzen, da sonst "unbenanntX" daraus wird
247 	String aDocInfoTitle = GetDocInfo().GetTitle();
248 	if ( aDocInfoTitle.Len() )
249 		SetTitle( aDocInfoTitle );
250 	else
251 	{
252 		pImp->aTitle.Erase();
253 		SetNamedVisibility_Impl();
254     	if ( GetMedium() )
255     	{
256         	SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
257         	Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
258     	}
259     }*/
260 }
261 
262 //-------------------------------------------------------------------------
263 
264 void SfxObjectShell::SetError( sal_uInt32 lErr, const ::rtl::OUString& aLogMessage )
265 {
266 	if(pImp->lErr==ERRCODE_NONE)
267     {
268 		pImp->lErr=lErr;
269 
270         if( lErr != ERRCODE_NONE && aLogMessage.getLength() )
271             AddLog( aLogMessage );
272     }
273 }
274 
275 //-------------------------------------------------------------------------
276 
277 sal_uInt32 SfxObjectShell::GetError() const
278 {
279 	return ERRCODE_TOERROR(GetErrorCode());
280 }
281 
282 //-------------------------------------------------------------------------
283 
284 sal_uInt32 SfxObjectShell::GetErrorCode() const
285 {
286 	sal_uInt32 lError=pImp->lErr;
287 	if(!lError && GetMedium())
288 		lError=GetMedium()->GetErrorCode();
289 	return lError;
290 }
291 
292 //-------------------------------------------------------------------------
293 
294 void SfxObjectShell::ResetError()
295 {
296     if( pImp->lErr != ERRCODE_NONE )
297         AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Resetting Error." ) ) );
298 
299 	pImp->lErr=0;
300 	SfxMedium * pMed = GetMedium();
301 	if( pMed )
302 		pMed->ResetError();
303 }
304 
305 //-------------------------------------------------------------------------
306 
307 sal_Bool SfxObjectShell::IsTemplate() const
308 {
309 	return pImp->bIsTemplate;
310 }
311 
312 //-------------------------------------------------------------------------
313 
314 void SfxObjectShell::SetTemplate(sal_Bool bIs)
315 {
316 	pImp->bIsTemplate=bIs;
317 	SfxFilterMatcher aMatcher( GetFactory().GetFactoryName() );
318 	SfxFilterMatcherIter aIter( &aMatcher, SFX_FILTER_TEMPLATEPATH );
319 	SfxMedium* pMed = GetMedium();
320 	if( pMed ) pMed->SetFilter( aIter.First() );
321 }
322 
323 //-------------------------------------------------------------------------
324 
325 void SfxObjectShell::EnableSetModified( sal_Bool bEnable )
326 {
327 #ifdef DBG_UTIL
328     if ( bEnable == pImp->m_bEnableSetModified )
329         DBG_WARNING( "SFX_PERSIST: EnableSetModified 2x mit dem gleichen Wert gerufen" );
330 #endif
331 	pImp->m_bEnableSetModified = bEnable;
332 }
333 
334 //-------------------------------------------------------------------------
335 
336 sal_Bool SfxObjectShell::IsEnableSetModified() const
337 {
338     return pImp->m_bEnableSetModified && !IsReadOnly();
339 }
340 
341 //-------------------------------------------------------------------------
342 
343 sal_Bool SfxObjectShell::IsModified()
344 {
345     if ( pImp->m_bIsModified )
346         return sal_True;
347 
348     if ( !pImp->m_xDocStorage.is() || IsReadOnly() )
349     {
350         // if the document still has no storage and is not set to be modified explicitly it is not modified
351         // a readonly document is also not modified
352 
353         return sal_False;
354     }
355 
356     uno::Sequence < ::rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
357     for ( sal_Int32 n=0; n<aNames.getLength(); n++ )
358     {
359         uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( aNames[n] );
360         OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
361         if ( xObj.is() )
362         {
363             try
364             {
365                 sal_Int32 nState = xObj->getCurrentState();
366                 if ( nState != embed::EmbedStates::LOADED )
367                 {
368                     uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
369                     if ( xModifiable.is() && xModifiable->isModified() )
370                         return sal_True;
371                 }
372             }
373             catch( uno::Exception& )
374             {}
375         }
376     }
377 
378     return sal_False;
379 }
380 
381 //-------------------------------------------------------------------------
382 
383 void SfxObjectShell::SetModified( sal_Bool bModifiedP )
384 {
385 #ifdef DBG_UTIL
386     if ( !bModifiedP && !IsEnableSetModified() )
387         DBG_WARNING( "SFX_PERSIST: SetModified( sal_False ), obwohl IsEnableSetModified() == sal_False" );
388 #endif
389 
390 	if( !IsEnableSetModified() )
391 		return;
392 
393 	if( pImp->m_bIsModified != bModifiedP )
394 	{
395 		pImp->m_bIsModified = bModifiedP;
396 		ModifyChanged();
397 	}
398 }
399 
400 //-------------------------------------------------------------------------
401 
402 void SfxObjectShell::ModifyChanged()
403 {
404 	if ( pImp->bClosing )
405 		// SetModified aus dem dispose des Models!
406 		return;
407 
408 	{DBG_CHKTHIS(SfxObjectShell, 0);}
409 
410     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
411     if ( pViewFrame )
412         pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS );
413 
414     Invalidate( SID_SIGNATURE );
415     Invalidate( SID_MACRO_SIGNATURE );
416 	Broadcast( SfxSimpleHint( SFX_HINT_TITLECHANGED ) );	// xmlsec05, signed state might change in title...
417 
418     SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_MODIFYCHANGED, GlobalEventConfig::GetEventName(STR_EVENT_MODIFYCHANGED), this ) );
419 }
420 
421 //-------------------------------------------------------------------------
422 
423 sal_Bool SfxObjectShell::IsReadOnlyUI() const
424 
425 /* 	[Beschreibung]
426 
427 	Liefert sal_True, wenn das Dokument fuer die UI wie r/o behandelt werden
428 	soll. Dieses ist unabhaengig vom tatsaechlichen r/o, welches per
429 	<IsReadOnly()> erfragbar ist.
430 */
431 
432 {
433 	return pImp->bReadOnlyUI;
434 }
435 
436 //-------------------------------------------------------------------------
437 
438 sal_Bool SfxObjectShell::IsReadOnlyMedium() const
439 
440 /* 	[Beschreibung]
441 
442 	Liefert sal_True, wenn das Medium r/o ist bzw. r/o geoeffnet wurde.
443 */
444 
445 {
446 	if ( !pMedium )
447 		return sal_True;
448 	return pMedium->IsReadOnly();
449 }
450 
451 //-------------------------------------------------------------------------
452 
453 void SfxObjectShell::SetReadOnlyUI( sal_Bool bReadOnly )
454 
455 /* 	[Beschreibung]
456 
457 	Schaltet das Dokument in einen r/o bzw. r/w Zustand ohne es neu
458 	zu laden und ohne die Open-Modi des Mediums zu aendern.
459 */
460 
461 {
462 	sal_Bool bWasRO = IsReadOnly();
463 	pImp->bReadOnlyUI = bReadOnly;
464 	if ( bWasRO != IsReadOnly() )
465 	{
466 		Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
467 		//if ( pImp->pDocInfo )
468 		//	pImp->pDocInfo->SetReadOnly( IsReadOnly() );
469 	}
470 }
471 
472 //-------------------------------------------------------------------------
473 
474 void SfxObjectShell::SetReadOnly()
475 {
476     // Let the document be completely readonly, means that the
477     // medium open mode is adjusted accordingly, and the write lock
478     // on the file is removed.
479 
480  	if ( pMedium && !IsReadOnlyMedium() )
481     {
482         sal_Bool bWasROUI = IsReadOnly();
483 
484         pMedium->UnlockFile( sal_False );
485 
486         // the storage-based mediums are already based on the temporary file
487         // so UnlockFile has already closed the locking stream
488         if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
489             pMedium->CloseInStream();
490 
491         pMedium->SetOpenMode( SFX_STREAM_READONLY, pMedium->IsDirect(), sal_True );
492         pMedium->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
493 
494         if ( !bWasROUI )
495             Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
496     }
497 }
498 //-------------------------------------------------------------------------
499 
500 sal_Bool SfxObjectShell::IsReadOnly() const
501 {
502 	return pImp->bReadOnlyUI || IsReadOnlyMedium();
503 }
504 
505 //-------------------------------------------------------------------------
506 
507 sal_Bool SfxObjectShell::IsInModalMode() const
508 {
509     return pImp->bModalMode || pImp->bRunningMacro;
510 }
511 
512 //<!--Added by PengYunQuan for Validity Cell Range Picker
513 sal_Bool SfxObjectShell::AcceptStateUpdate() const
514 {
515 	return !IsInModalMode();
516 }
517 //-->Added by PengYunQuan for Validity Cell Range Picker
518 
519 //-------------------------------------------------------------------------
520 
521 sal_Bool SfxObjectShell::HasModalViews() const
522 {
523 	SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
524 	while( pFrame )
525 	{
526 		if ( pFrame->IsInModalMode() )
527 			return sal_True;
528 
529 		pFrame = SfxViewFrame::GetNext( *pFrame, this );
530 	}
531 
532 	return sal_False;
533 }
534 
535 //-------------------------------------------------------------------------
536 
537 void SfxObjectShell::SetMacroMode_Impl( sal_Bool bModal )
538 {
539     if ( !pImp->bRunningMacro != !bModal )
540 	{
541         pImp->bRunningMacro = bModal;
542 		Broadcast( SfxSimpleHint( SFX_HINT_MODECHANGED ) );
543 	}
544 }
545 
546 //-------------------------------------------------------------------------
547 
548 void SfxObjectShell::SetModalMode_Impl( sal_Bool bModal )
549 {
550 	// nur Broadcasten wenn modifiziert, sonst ggf. Endlosrekursion
551 	if ( !pImp->bModalMode != !bModal )
552 	{
553 		// zentral mitz"ahlen
554 		sal_uInt16 &rDocModalCount = SFX_APP()->Get_Impl()->nDocModalMode;
555 		if ( bModal )
556 			++rDocModalCount;
557 		else
558 			--rDocModalCount;
559 
560 		// umschalten
561 		pImp->bModalMode = bModal;
562 		Broadcast( SfxSimpleHint( SFX_HINT_MODECHANGED ) );
563 	}
564 }
565 
566 //--------------------------------------------------------------------
567 sal_Bool SfxObjectShell::SwitchToShared( sal_Bool bShared, sal_Bool bSave )
568 {
569     sal_Bool bResult = sal_True;
570 
571     if ( bShared != IsDocShared() )
572     {
573         ::rtl::OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
574 
575         if ( !aOrigURL.getLength() && bSave )
576         {
577             // this is a new document, let it be stored before switching to the shared mode;
578             // the storing should be done without shared flag, since it is possible that the
579             // target location does not allow to create sharing control file;
580             // the shared flag will be set later after creation of sharing control file
581             SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
582 
583             if ( pViewFrame )
584             {
585                 // TODO/LATER: currently the application guards against the reentrance problem
586 				const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
587                 SfxBoolItem* pResult = PTR_CAST( SfxBoolItem, pItem );
588                 bResult = ( pResult && pResult->GetValue() );
589                 if ( bResult )
590                     aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
591             }
592         }
593 
594         sal_Bool bOldValue = HasSharedXMLFlagSet();
595         SetSharedXMLFlag( bShared );
596 
597         sal_Bool bRemoveEntryOnError = sal_False;
598         if ( bResult && bShared )
599         {
600             try
601             {
602                 ::svt::ShareControlFile aControlFile( aOrigURL );
603                 aControlFile.InsertOwnEntry();
604                 bRemoveEntryOnError = sal_True;
605             }
606             catch( uno::Exception& )
607             {
608                 bResult = sal_False;
609             }
610         }
611 
612         if ( bResult && bSave )
613         {
614             SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
615 
616             if ( pViewFrame )
617             {
618                 // TODO/LATER: currently the application guards against the reentrance problem
619                 SetModified( sal_True ); // the modified flag has to be set to let the document be stored with the shared flag
620 				const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
621                 SfxBoolItem* pResult = PTR_CAST( SfxBoolItem, pItem );
622                 bResult = ( pResult && pResult->GetValue() );
623             }
624         }
625 
626         if ( bResult )
627         {
628             // TODO/LATER: Is it possible that the following calls fail?
629             if ( bShared )
630             {
631                 pImp->m_aSharedFileURL = aOrigURL;
632                 GetMedium()->SwitchDocumentToTempFile();
633             }
634             else
635             {
636                 ::rtl::OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
637                 GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
638                 pImp->m_aSharedFileURL = ::rtl::OUString();
639 
640                 // now remove the temporary file the document was based on
641                 ::utl::UCBContentHelper::Kill( aTempFileURL );
642 
643                 try
644                 {
645                     // aOrigURL can not be used since it contains an old value
646                     ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
647                     aControlFile.RemoveFile();
648                 }
649                 catch( uno::Exception& )
650                 {
651                 }
652             }
653         }
654         else
655         {
656             // the saving has failed!
657             if ( bRemoveEntryOnError )
658             {
659                 try
660                 {
661                     ::svt::ShareControlFile aControlFile( aOrigURL );
662                     aControlFile.RemoveEntry();
663                 }
664                 catch( uno::Exception& )
665                 {}
666             }
667 
668             SetSharedXMLFlag( bOldValue );
669         }
670     }
671     else
672         bResult = sal_False; // the second switch to the same mode
673 
674     if ( bResult )
675         SetTitle( String() );
676 
677     return bResult;
678 }
679 
680 //--------------------------------------------------------------------
681 
682 void SfxObjectShell::DisconnectFromShared()
683 {
684     if ( IsDocShared() )
685     {
686         if ( pMedium && pMedium->GetStorage().is() )
687         {
688             // set medium to noname
689             pMedium->SetName( String(), sal_True );
690             pMedium->Init_Impl();
691 
692             // drop resource
693             SetNoName();
694             InvalidateName();
695 
696             // untitled document must be based on temporary storage
697             // the medium should not dispose the storage in this case
698             if ( pMedium->GetStorage() == GetStorage() )
699                 ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium );
700 
701             pMedium->Close();
702             FreeSharedFile();
703 
704             SfxMedium* pTmpMedium = pMedium;
705             ForgetMedium();
706             if( !DoSaveCompleted( pTmpMedium ) )
707                 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
708             else
709             {
710                 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
711                 pMedium->CanDisposeStorage_Impl( sal_False );
712             }
713 
714             pMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
715             pMedium->SetOpenMode( SFX_STREAM_READWRITE, sal_True, sal_True );
716 
717             SetTitle( String() );
718         }
719     }
720 }
721 
722 //--------------------------------------------------------------------
723 
724 void SfxObjectShell::FreeSharedFile()
725 {
726     if ( pMedium )
727         FreeSharedFile( pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
728 }
729 
730 //--------------------------------------------------------------------
731 void SfxObjectShell::FreeSharedFile( const ::rtl::OUString& aTempFileURL )
732 {
733     SetSharedXMLFlag( sal_False );
734 
735     if ( IsDocShared() && aTempFileURL.getLength()
736       && !::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
737     {
738         if ( pImp->m_bAllowShareControlFileClean )
739         {
740             try
741             {
742                 ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
743                 aControlFile.RemoveEntry();
744             }
745             catch( uno::Exception& )
746             {
747             }
748         }
749 
750         // the cleaning is forbidden only once
751         pImp->m_bAllowShareControlFileClean = sal_True;
752 
753         // now remove the temporary file the document is based currently on
754         ::utl::UCBContentHelper::Kill( aTempFileURL );
755 
756         pImp->m_aSharedFileURL = ::rtl::OUString();
757     }
758 }
759 
760 //--------------------------------------------------------------------
761 void SfxObjectShell::DoNotCleanShareControlFile()
762 {
763     pImp->m_bAllowShareControlFileClean = sal_False;
764 }
765 
766 //--------------------------------------------------------------------
767 void SfxObjectShell::SetSharedXMLFlag( sal_Bool bFlag ) const
768 {
769     pImp->m_bSharedXMLFlag = bFlag;
770 }
771 
772 //--------------------------------------------------------------------
773 sal_Bool SfxObjectShell::HasSharedXMLFlagSet() const
774 {
775     return pImp->m_bSharedXMLFlag;
776 }
777 
778 //--------------------------------------------------------------------
779 
780 sal_Bool SfxObjectShell::IsDocShared() const
781 {
782     return ( pImp->m_aSharedFileURL.getLength() > 0 );
783 }
784 
785 //--------------------------------------------------------------------
786 
787 ::rtl::OUString SfxObjectShell::GetSharedFileURL() const
788 {
789     return pImp->m_aSharedFileURL;
790 }
791 
792 //--------------------------------------------------------------------
793 
794 Size SfxObjectShell::GetFirstPageSize()
795 {
796     return GetVisArea(ASPECT_THUMBNAIL).GetSize();
797 }
798 
799 
800 //--------------------------------------------------------------------
801 
802 IndexBitSet& SfxObjectShell::GetNoSet_Impl()
803 {
804 	return pImp->aBitSet;
805 }
806 
807 //--------------------------------------------------------------------
808 // changes the title of the document
809 
810 void SfxObjectShell::SetTitle
811 (
812 	const String& rTitle		// der neue Titel des Dokuments
813 )
814 
815 /*	[Beschreibung]
816 
817 	Mit dieser Methode kann der Titel des Dokuments gesetzt werden.
818 	Dieser entspricht initial dem kompletten Dateinamen. Ein Setzen
819 	des Titels wirkt jedoch nicht zu"uck auf den Dateinamen; er wird
820 	jedoch in den Caption-Bars der MDI-Fenster angezeigt.
821 */
822 
823 {
824 	DBG_CHKTHIS(SfxObjectShell, 0);
825 
826 	// nix zu tun?
827 	if ( ( ( HasName() && pImp->aTitle == rTitle )
828 		|| ( !HasName() && GetTitle() == rTitle ) )
829 	  && !IsDocShared() )
830 		return;
831 
832 	SfxApplication *pSfxApp = SFX_APP();
833 #if 0
834 	// wird 'unbenannt#' als Titel gesetzt
835 	String aNoName(SfxResId(STR_NONAME));
836 	if ( rTitle.Match(aNoName) <= aNoName.Len() )
837 	{
838 		// er ist es selbst => ignorieren
839 		pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
840 		pImp->bIsNamedVisible=0;
841 	}
842 #endif
843 
844 	// ggf. die unbenannt-Nummer freigeben
845 	if ( pImp->bIsNamedVisible && USHRT_MAX != pImp->nVisualDocumentNumber )
846 	{
847 		pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
848 		pImp->bIsNamedVisible = 0;
849 	}
850 
851 	// Title setzen
852 	pImp->aTitle = rTitle;
853 //  Wieso denn in der DocInfo?
854 //	GetDocInfo().SetTitle( rTitle );
855 //	FlushDocInfo();
856 
857 	// Benachrichtigungen
858     if ( GetMedium() )
859     {
860         SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
861         Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
862     }
863 }
864 
865 //--------------------------------------------------------------------
866 
867 #if OSL_DEBUG_LEVEL > 1
868 String X(const String &rRet)
869 {
870 	if ( !rRet.Len() )
871 		return DEFINE_CONST_UNICODE( "-empty-" );
872 	return rRet;
873 }
874 #else
875 #define X(ret) ret
876 #endif
877 
878 //--------------------------------------------------------------------
879 //--------------------------------------------------------------------
880 String SfxObjectShell::GetTitle
881 (
882 	sal_uInt16	nMaxLength 		/*	0 (default)
883 								der Titel selbst, so wie er ist
884 
885 								1 (==SFX_TITLE_FILENAME)
886 								liefert den logischen Dateinamen ohne Pfad
887 								(unter WNT je nach Systemeinstellung ohne
888 								Extension)
889 
890 								2 (==SFX_TITLE_FULLNAME)
891 								liefert den mit komplettem logischen Dateinamen
892 								mit Pfad (remote => ::com::sun::star::util::URL)
893 
894 								3 (==SFX_TITLE_APINAME)
895 								liefert den logischen Dateinamen ohne Pfad
896 								und Extension
897 
898 								4 (==SFX_TITLE_DETECT)
899 								liefert den kompletten Titel, falls noch
900 								nicht gesetzt wird aber aus DocInfo oder
901 								dem Namen des Medium erzeugt
902 
903 								5 (==SFX_TITLE_CAPTION)
904 								liefert den Titel so, wie MB ihn heute in
905 								der CaptionBar anzeigen m"ochte
906 
907 								6 (==SFX_TITLE_PICKLIST)
908 								liefert den Titel so, wie MB ihn heute in
909 								der PickList anzeigen m"ochte
910 
911 								7 (==SFX_TITLE_HISTORY)
912 								liefert den Titel so, wie MB ihn heute in
913 								der History anzeigen m"ochte
914 
915 								10 bis USHRT_MAX
916 								liefert maximal 'nMaxLength' Zeichen vom logischen
917 								Dateinamen inkl. Pfad (remote => ::com::sun::star::util::URL)
918 								*/
919 ) const
920 
921 /*	[Beschreibung]
922 
923 	Liefert den Titel bzw. logischen Dateinamen des Dokuments, je nach
924 	'nMaxLength'.
925 
926 	Falls der Dateiname mit Pfad verwendet wird, wird die Namensk"urzung durch
927 	Ersetzung eines oder mehrerer Directory-Namen durch "..." durchgef"uhrt,
928 	URLs werden z.Zt. immer komplett geliefert.
929 */
930 
931 {
932 //    if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
933 //        return String();
934     SfxMedium *pMed = GetMedium();
935     if ( IsLoading() )
936         return String();
937 
938 /*    if ( !nMaxLength && pImp->pDocInfo )
939     {
940         String aTitle = pImp->pDocInfo->GetTitle();
941         if ( aTitle.Len() )
942             return aTitle;
943     } */
944 
945 	// Titel erzeugen?
946 	if ( SFX_TITLE_DETECT == nMaxLength && !pImp->aTitle.Len() )
947 	{
948 		static sal_Bool bRecur = sal_False;
949 		if ( bRecur )
950 			return DEFINE_CONST_UNICODE( "-not available-" );
951 		bRecur = sal_True;
952 
953 		String aTitle;
954 		SfxObjectShell *pThis = (SfxObjectShell*) this;
955 
956 		if ( pMed )
957 		{
958 			SFX_ITEMSET_ARG( pMed->GetItemSet(), pNameItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
959 			if ( pNameItem )
960 				aTitle = pNameItem->GetValue();
961 		}
962 
963 		if ( !aTitle.Len() )
964 			aTitle = GetTitle( SFX_TITLE_FILENAME );
965 
966 		if ( IsTemplate() )
967 			pThis->SetTitle( aTitle );
968 		bRecur = sal_False;
969 		return X(aTitle);
970 	}
971 	else if (SFX_TITLE_APINAME == nMaxLength )
972 		return X(GetAPIName());
973 
974 	// Sonderfall Vorlagen:
975 	if( IsTemplate() && pImp->aTitle.Len() &&
976 		 ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
977 		return X(pImp->aTitle);
978 
979 	// Picklist/Caption wird gemappt
980 	if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
981 	{
982 		// Wenn ein spezieller Titel beim "Offnen mitgegeben wurde;
983 		// wichtig bei URLs, die INET_PROT_FILE verwenden, denn bei denen
984 		// wird der gesetzte Titel nicht beachtet.
985 		// (s.u., Auswertung von aTitleMap_Impl)
986 		SFX_ITEMSET_ARG( pMed->GetItemSet(), pNameItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
987 		if ( pNameItem )
988 			return X( pNameItem->GetValue() );
989 	}
990 
991 	// noch unbenannt?
992 	DBG_ASSERT( !HasName() || pMed, "HasName() aber kein Medium?!?" );
993 	if ( !HasName() || !pMed )
994 	{
995 		// schon Titel gesezt?
996 		if ( pImp->aTitle.Len() )
997 			return X(pImp->aTitle);
998 
999 		// mu\s es durchnumeriert werden?
1000 		String aNoName( SfxResId( STR_NONAME ) );
1001 		if ( pImp->bIsNamedVisible )
1002 			// Nummer hintenanh"angen
1003 			aNoName += String::CreateFromInt32( pImp->nVisualDocumentNumber );
1004 
1005 		// Dokument hei\st vorerst 'unbenannt#'
1006 		return X(aNoName);
1007 	}
1008 
1009 	const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : ::rtl::OUString( GetMedium()->GetName() ) );
1010 	if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY )
1011 	{
1012 		sal_uInt16 nRemote;
1013 		if( !pMed || aURL.GetProtocol() == INET_PROT_FILE )
1014 			nRemote = 0;
1015 		else
1016 			nRemote = 1;
1017 		nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote];
1018 	}
1019 
1020 	// lokale Datei?
1021 	if ( aURL.GetProtocol() == INET_PROT_FILE )
1022 	{
1023         String aName( aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName() );
1024 		if ( nMaxLength == SFX_TITLE_FULLNAME )
1025 			return X( aName );
1026 		else if ( nMaxLength == SFX_TITLE_FILENAME )
1027             return X( aURL.getName( INetURLObject::LAST_SEGMENT,
1028 				true, INetURLObject::DECODE_WITH_CHARSET ) );
1029 		else if ( !pImp->aTitle.Len() )
1030             pImp->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT,
1031 										 true, INetURLObject::DECODE_WITH_CHARSET );
1032 	}
1033 	else
1034 	{
1035 		// ::com::sun::star::util::URL-Versionen
1036 		if ( nMaxLength >= SFX_TITLE_MAXLEN )
1037 		{
1038             String aComplete( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
1039 			if( aComplete.Len() > nMaxLength )
1040 			{
1041 				String aRet( DEFINE_CONST_UNICODE( "..." ) );
1042 				aRet += aComplete.Copy( aComplete.Len() - nMaxLength + 3, nMaxLength - 3 );
1043 				return X( aRet );
1044 			}
1045 			else
1046                 return X( aComplete );
1047 		}
1048 		else if ( nMaxLength == SFX_TITLE_FILENAME )
1049 		{
1050             String aName( aURL.GetBase() );
1051 			aName = INetURLObject::decode( aName, INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET );
1052 			if( !aName.Len() )
1053 				aName = aURL.GetURLNoPass();
1054 			return X(aName);
1055 		}
1056 		else if ( nMaxLength == SFX_TITLE_FULLNAME )
1057 			return X(aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ));
1058 
1059 		// ggf. Titel aus Dateiname generieren
1060 		if ( !pImp->aTitle.Len() )
1061 			pImp->aTitle = aURL.GetBase();
1062 
1063 		// workaround for the case when the name can not be retrieved from URL by INetURLObject
1064 		if ( !pImp->aTitle.Len() )
1065 			pImp->aTitle = aURL.GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
1066 	}
1067 
1068 	// ganzer Titel
1069 	return X(pImp->aTitle);
1070 }
1071 
1072 //--------------------------------------------------------------------
1073 
1074 void SfxObjectShell::InvalidateName()
1075 
1076 /*	[Beschreibung]
1077 
1078 	Ermittelt den Titel des Dokuments neu aus 'unbenannt', DocInfo-Titel
1079 	bzw. Dateinamen. Wird nach Laden aus Template oder SaveAs ben"otigt.
1080 */
1081 
1082 {
1083 	// Title neu erzeugen
1084 	pImp->aTitle.Erase();
1085 //	pImp->nVisualDocumentNumber = USHRT_MAX;
1086 	//GetTitle( SFX_TITLE_DETECT );
1087 	SetName( GetTitle( SFX_TITLE_APINAME ) );
1088 
1089 	// Benachrichtigungen
1090 	Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
1091 }
1092 
1093 //--------------------------------------------------------------------
1094 
1095 void SfxObjectShell::SetNamedVisibility_Impl()
1096 {
1097 	if ( !pImp->bIsNamedVisible )
1098 	{
1099 		// Nummer verpassen
1100 		pImp->bIsNamedVisible = sal_True;
1101 		// ggf. neue Nummer verpassen
1102 		if ( !HasName() && USHRT_MAX == pImp->nVisualDocumentNumber && !pImp->aTitle.Len() )
1103 		{
1104 			pImp->nVisualDocumentNumber = SFX_APP()->GetFreeIndex();
1105 			Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
1106 		}
1107 	}
1108 
1109 	SetName( GetTitle(SFX_TITLE_APINAME) );
1110 }
1111 
1112 void SfxObjectShell::SetNoName()
1113 {
1114     bHasName = 0;
1115     bIsTmp = sal_True;
1116     GetModel()->attachResource( ::rtl::OUString(), GetModel()->getArgs() );
1117 }
1118 
1119 //--------------------------------------------------------------------
1120 
1121 void SfxObjectShell::MemoryError()
1122 {
1123 }
1124 
1125 //--------------------------------------------------------------------
1126 
1127 SfxProgress* SfxObjectShell::GetProgress() const
1128 {
1129 	return pImp->pProgress;
1130 }
1131 
1132 //--------------------------------------------------------------------
1133 
1134 void SfxObjectShell::SetProgress_Impl
1135 (
1136 	SfxProgress *pProgress	/*	zu startender <SfxProgress> oder 0, falls
1137 								der Progress zur"uckgesetzt werden soll */
1138 )
1139 
1140 /*	[Beschreibung]
1141 
1142 	Interne Methode zum setzen oder zur"ucksetzen des Progress-Modes
1143 	f"ur diese SfxObjectShell.
1144 */
1145 
1146 {
1147 	DBG_ASSERT( ( !pImp->pProgress && pProgress ) ||
1148 				( pImp->pProgress && !pProgress ),
1149 				"Progress activation/deacitivation mismatch" );
1150 	pImp->pProgress = pProgress;
1151 }
1152 
1153 //--------------------------------------------------------------------
1154 
1155 void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame* pFrame )
1156 {
1157 	SfxApplication* pSfxApp = SFX_APP();
1158     if ( !pSfxApp->IsDowning() && !IsLoading() && pFrame && !pFrame->GetFrame().IsClosing_Impl() )
1159 	{
1160         SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
1161         if ( !pHiddenItem || !pHiddenItem->GetValue() )
1162         {
1163             sal_uInt16 nId = pImp->nEventId;
1164             pImp->nEventId = 0;
1165             if ( nId == SFX_EVENT_OPENDOC )
1166                 pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(STR_EVENT_OPENDOC), this, pFrame->GetFrame().GetController() ), sal_False);
1167 			else if (nId == SFX_EVENT_CREATEDOC )
1168                 pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(STR_EVENT_CREATEDOC), this, pFrame->GetFrame().GetController() ), sal_False);
1169         }
1170 	}
1171 }
1172 
1173 //--------------------------------------------------------------------
1174 
1175 void SfxObjectShell::SetActivateEvent_Impl(sal_uInt16 nId )
1176 {
1177 	if ( GetFactory().GetFlags() & SFXOBJECTSHELL_HASOPENDOC )
1178 		pImp->nEventId = nId;
1179 }
1180 
1181 //--------------------------------------------------------------------
1182 
1183 void SfxObjectShell::RegisterTransfer( SfxMedium& rMedium )
1184 /*  [Beschreibung ]
1185 	Alle Medien, die aufgesetzt werden, um Teile eines Dokumentes zu
1186 	laden, muessen an der zugehoerigen SfxObjectShell angemeldet
1187 	werden. So kann dokumentweise abgebrochen werden.  */
1188 {
1189 	rMedium.SetReferer( GetMedium()->GetName() );
1190 }
1191 
1192 //-------------------------------------------------------------------------
1193 
1194 void SfxObjectShell::PrepareReload( )
1195 /*  [Beschreibung ]
1196 	Wird vor dem Reload gerufen und gibt die Moeglichkeit,
1197 	etwaige Caches zu leeren. */
1198 {
1199 }
1200 
1201 //-------------------------------------------------------------------------
1202 
1203 void SfxObjectShell::LockAutoLoad( sal_Bool bLock )
1204 
1205 /* 	Verhindert ein evtl. eintreffendes AutoLoad. Wird auch vor AutoLoad
1206 	eines umgebenden FrameSet beruecksichtigt.
1207 */
1208 
1209 {
1210 	if ( bLock )
1211 		++pImp->nAutoLoadLocks;
1212 	else
1213 		--pImp->nAutoLoadLocks;
1214 }
1215 
1216 //-------------------------------------------------------------------------
1217 
1218 // kann nach frame.cxx gemoved werden, wenn 358+36x-Stand gemerged sind
1219 
1220 sal_Bool SfxFrame::IsAutoLoadLocked_Impl() const
1221 {
1222 	// sein einges Doc gelockt?
1223 	const SfxObjectShell* pObjSh = GetCurrentDocument();
1224 	if ( !pObjSh || !pObjSh->IsAutoLoadLocked() )
1225 		return sal_False;
1226 
1227 	// seine Childs gelockt?
1228 	for ( sal_uInt16 n = GetChildFrameCount(); n--; )
1229 		if ( !GetChildFrame(n)->IsAutoLoadLocked_Impl() )
1230 			return sal_False;
1231 
1232 	// sonst ist AutoLoad erlaubt
1233 	return sal_True;
1234 }
1235 
1236 //-------------------------------------------------------------------------
1237 
1238 sal_Bool SfxObjectShell::IsAutoLoadLocked() const
1239 
1240 /* 	Liefert, ob ein eintreffendes AutoLoad ausgefuehrt werden darf. Wird auch
1241 	vor AutoLoad eines umgebenden FrameSet beruecksichtigt.
1242 */
1243 
1244 {
1245 	return !IsReadOnly() || pImp->nAutoLoadLocks > 0;
1246 }
1247 
1248 //-------------------------------------------------------------------------
1249 void SfxObjectShell::BreakMacroSign_Impl( sal_Bool bBreakMacroSign )
1250 {
1251 	pImp->m_bMacroSignBroken = bBreakMacroSign;
1252 }
1253 
1254 //-------------------------------------------------------------------------
1255 void SfxObjectShell::CheckSecurityOnLoading_Impl()
1256 {
1257     uno::Reference< task::XInteractionHandler > xInteraction;
1258     if ( GetMedium() )
1259         xInteraction = GetMedium()->GetInteractionHandler();
1260 
1261 	// check if there is a broken signature...
1262     CheckForBrokenDocSignatures_Impl( xInteraction );
1263 
1264     CheckEncryption_Impl( xInteraction );
1265 
1266     // check macro security
1267     pImp->aMacroMode.checkMacrosOnLoading( xInteraction );
1268 }
1269 
1270 //-------------------------------------------------------------------------
1271 void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
1272 {
1273     ::rtl::OUString aVersion;
1274     sal_Bool bIsEncrypted = sal_False;
1275     sal_Bool bHasNonEncrypted = sal_False;
1276 
1277     try
1278     {
1279         uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1280         xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion;
1281         xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasEncryptedEntries" ) ) ) >>= bIsEncrypted;
1282         xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasNonEncryptedEntries" ) ) ) >>= bHasNonEncrypted;
1283     }
1284     catch( uno::Exception& )
1285     {
1286     }
1287 
1288     if ( aVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
1289     {
1290         // this is ODF1.2 or later
1291         if ( bIsEncrypted && bHasNonEncrypted )
1292         {
1293             if ( !pImp->m_bIncomplEncrWarnShown )
1294             {
1295                 // this is an encrypted document with nonencrypted streams inside, show the warning
1296                 ::com::sun::star::task::ErrorCodeRequest aErrorCode;
1297                 aErrorCode.ErrCode = ERRCODE_SFX_INCOMPLETE_ENCRYPTION;
1298 
1299                 SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False );
1300                 pImp->m_bIncomplEncrWarnShown = sal_True;
1301             }
1302 
1303             // broken signatures imply no macro execution at all
1304             pImp->aMacroMode.disallowMacroExecution();
1305         }
1306     }
1307 }
1308 
1309 //-------------------------------------------------------------------------
1310 void SfxObjectShell::CheckForBrokenDocSignatures_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
1311 {
1312     sal_Int16 nSignatureState = GetDocumentSignatureState();
1313     bool bSignatureBroken = ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN );
1314     if ( !bSignatureBroken )
1315         return;
1316 
1317     pImp->showBrokenSignatureWarning( xHandler );
1318 
1319     // broken signatures imply no macro execution at all
1320     pImp->aMacroMode.disallowMacroExecution();
1321 }
1322 
1323 //-------------------------------------------------------------------------
1324 void SfxObjectShell::SetAutoLoad(
1325 	const INetURLObject& rUrl, sal_uInt32 nTime, sal_Bool bReload )
1326 {
1327 	if ( pImp->pReloadTimer )
1328 		DELETEZ(pImp->pReloadTimer);
1329 	if ( bReload )
1330 	{
1331 		pImp->pReloadTimer = new AutoReloadTimer_Impl(
1332 								rUrl.GetMainURL( INetURLObject::DECODE_TO_IURI ),
1333 								nTime, bReload, this );
1334 		pImp->pReloadTimer->Start();
1335 	}
1336 }
1337 
1338 sal_Bool SfxObjectShell::IsLoadingFinished() const
1339 {
1340 	return ( pImp->nLoadedFlags == SFX_LOADED_ALL );
1341 }
1342 
1343 void impl_addToModelCollection(const com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel);
1344 void SfxObjectShell::InitOwnModel_Impl()
1345 {
1346 	if ( !pImp->bModelInitialized )
1347 	{
1348 		SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
1349 		if ( pSalvageItem )
1350 		{
1351             pImp->aTempName = pMedium->GetPhysicalName();
1352 			pMedium->GetItemSet()->ClearItem( SID_DOC_SALVAGE );
1353 			pMedium->GetItemSet()->ClearItem( SID_FILE_NAME );
1354 			pMedium->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetOrigURL() ) );
1355 		}
1356 		else
1357 		{
1358 			pMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
1359 			pMedium->GetItemSet()->ClearItem( SID_DOCUMENT );
1360 		}
1361 
1362 		pMedium->GetItemSet()->ClearItem( SID_REFERER );
1363 		uno::Reference< frame::XModel >  xModel ( GetModel(), uno::UNO_QUERY );
1364 		if ( xModel.is() )
1365 		{
1366 			::rtl::OUString aURL = GetMedium()->GetOrigURL();
1367 			SfxItemSet *pSet = GetMedium()->GetItemSet();
1368             if ( !GetMedium()->IsReadOnly() )
1369                 pSet->ClearItem( SID_INPUTSTREAM );
1370 			uno::Sequence< beans::PropertyValue > aArgs;
1371 			TransformItems( SID_OPENDOC, *pSet, aArgs );
1372 			xModel->attachResource( aURL, aArgs );
1373             impl_addToModelCollection(xModel);
1374 		}
1375 
1376 		pImp->bModelInitialized = sal_True;
1377 	}
1378 }
1379 
1380 void SfxObjectShell::FinishedLoading( sal_uInt16 nFlags )
1381 {
1382 	sal_Bool bSetModifiedTRUE = sal_False;
1383 	SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
1384     if( ( nFlags & SFX_LOADED_MAINDOCUMENT ) && !(pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT )
1385 	    && !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ))
1386 	{
1387 		pImp->nFlagsInProgress |= SFX_LOADED_MAINDOCUMENT;
1388 		((SfxHeaderAttributes_Impl*)GetHeaderAttributes())->SetAttributes();
1389 		pImp->bImportDone = sal_True;
1390 		if( !IsAbortingImport() )
1391 			PositionView_Impl();
1392 
1393         if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().getLength() ) && !IsModifyPasswordEntered() )
1394             SetReadOnly();
1395 
1396 		// Salvage
1397 		if ( pSalvageItem )
1398 			bSetModifiedTRUE = sal_True;
1399 
1400 		if ( !IsEnableSetModified() )
1401 			EnableSetModified( sal_True );
1402 
1403 		if( !bSetModifiedTRUE && IsEnableSetModified() )
1404 			SetModified( sal_False );
1405 
1406         CheckSecurityOnLoading_Impl();
1407 
1408 		bHasName = sal_True; // the document is loaded, so the name should already available
1409 		GetTitle( SFX_TITLE_DETECT );
1410 		InitOwnModel_Impl();
1411 		pImp->nFlagsInProgress &= ~SFX_LOADED_MAINDOCUMENT;
1412 	}
1413 
1414     if( ( nFlags & SFX_LOADED_IMAGES ) && !(pImp->nLoadedFlags & SFX_LOADED_IMAGES )
1415 	    && !(pImp->nFlagsInProgress & SFX_LOADED_IMAGES ))
1416 	{
1417 		pImp->nFlagsInProgress |= SFX_LOADED_IMAGES;
1418         uno::Reference<document::XDocumentProperties> xDocProps(
1419             getDocProperties());
1420         ::rtl::OUString url(xDocProps->getAutoloadURL());
1421         sal_Int32 delay(xDocProps->getAutoloadSecs());
1422         SetAutoLoad( INetURLObject(url), delay * 1000,
1423                      (delay > 0) || url.getLength() );
1424 		if( !bSetModifiedTRUE && IsEnableSetModified() )
1425 			SetModified( sal_False );
1426 		Invalidate( SID_SAVEASDOC );
1427 		pImp->nFlagsInProgress &= ~SFX_LOADED_IMAGES;
1428 	}
1429 
1430 	pImp->nLoadedFlags |= nFlags;
1431 
1432 	if ( !pImp->nFlagsInProgress )
1433 	{
1434 		// in case of reentrance calls the first called FinishedLoading() call on the stack
1435 		// should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1436 
1437 		if ( bSetModifiedTRUE )
1438 			SetModified( sal_True );
1439 		else
1440 			SetModified( sal_False );
1441 
1442 		if ( (pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) && (pImp->nLoadedFlags & SFX_LOADED_IMAGES ) )
1443 		{
1444             SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
1445             sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
1446 
1447 			// closing the streams on loading should be under control of SFX!
1448 			DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" );
1449 
1450             if ( bTemplate )
1451             {
1452                 TemplateDisconnectionAfterLoad();
1453             }
1454             else
1455             {
1456                 // if a readonly medium has storage then it's stream is already based on temporary file
1457                 if( !(pMedium->GetOpenMode() & STREAM_WRITE) && !pMedium->HasStorage_Impl() )
1458                     // don't lock file opened read only
1459                     pMedium->CloseInStream();
1460             }
1461 		}
1462 
1463         SetInitialized_Impl( false );
1464 
1465 		// Title is not available until loading has finished
1466 		Broadcast( SfxSimpleHint( SFX_HINT_TITLECHANGED ) );
1467 		if ( pImp->nEventId )
1468 			PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1469 	}
1470 }
1471 
1472 //-------------------------------------------------------------------------
1473 extern void SetTemplate_Impl( const String&, const String&, SfxObjectShell* );
1474 
1475 void SfxObjectShell::TemplateDisconnectionAfterLoad()
1476 {
1477     // document is created from a template
1478     //TODO/LATER: should the templates always be XML docs!
1479 
1480     SfxMedium* pTmpMedium = pMedium;
1481     if ( pTmpMedium )
1482     {
1483         String aName( pTmpMedium->GetName() );
1484         SFX_ITEMSET_ARG( pTmpMedium->GetItemSet(), pTemplNamItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False);
1485         String aTemplateName;
1486         if ( pTemplNamItem )
1487             aTemplateName = pTemplNamItem->GetValue();
1488         else
1489         {
1490             // !TODO/LATER: what's this?!
1491             // Interaktiv ( DClick, Contextmenu ) kommt kein Langname mit
1492             aTemplateName = getDocProperties()->getTitle();
1493             if ( !aTemplateName.Len() )
1494             {
1495                 INetURLObject aURL( aName );
1496                 aURL.CutExtension();
1497                 aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
1498             }
1499         }
1500 
1501         // set medium to noname
1502         pTmpMedium->SetName( String(), sal_True );
1503         pTmpMedium->Init_Impl();
1504 
1505         // drop resource
1506         SetNoName();
1507         InvalidateName();
1508 
1509         if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
1510         {
1511             // untitled document must be based on temporary storage
1512             // the medium should not dispose the storage in this case
1513             uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
1514             GetStorage()->copyToStorage( xTmpStor );
1515 
1516             // the medium should disconnect from the original location
1517             // the storage should not be disposed since the document is still
1518             // based on it, but in DoSaveCompleted it will be disposed
1519             pTmpMedium->CanDisposeStorage_Impl( sal_False );
1520             pTmpMedium->Close();
1521 
1522             // setting the new storage the medium will be based on
1523             pTmpMedium->SetStorage_Impl( xTmpStor );
1524 
1525             ForgetMedium();
1526             if( !DoSaveCompleted( pTmpMedium ) )
1527                 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1528             else
1529             {
1530                 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
1531                 sal_Bool bSalvage = pSalvageItem ? sal_True : sal_False;
1532 
1533                 if ( !bSalvage )
1534                 {
1535                     // some further initializations for templates
1536                     SetTemplate_Impl( aName, aTemplateName, this );
1537                 }
1538 
1539                 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1540                 pTmpMedium->CanDisposeStorage_Impl( sal_False );
1541             }
1542         }
1543         else
1544         {
1545             // some further initializations for templates
1546             SetTemplate_Impl( aName, aTemplateName, this );
1547             pTmpMedium->CreateTempFile( sal_True );
1548         }
1549 
1550         // templates are never readonly
1551         pTmpMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
1552         pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, sal_True, sal_True );
1553 
1554         // notifications about possible changes in readonly state and document info
1555         Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
1556 
1557         // created untitled document can't be modified
1558         SetModified( sal_False );
1559     }
1560 }
1561 
1562 //-------------------------------------------------------------------------
1563 
1564 void SfxObjectShell::PositionView_Impl()
1565 {
1566 	MarkData_Impl *pMark = Get_Impl()->pMarkData;
1567 	if( pMark )
1568 	{
1569 		SfxViewShell* pSh = pMark->pFrame->GetViewShell();
1570 		if( pMark->aUserData.Len() )
1571 			pSh->ReadUserData( pMark->aUserData, sal_True );
1572 		else if( pMark->aMark.Len() )
1573 			pSh->JumpToMark( pMark->aMark );
1574 		DELETEZ( Get_Impl()->pMarkData );
1575 	}
1576 }
1577 
1578 //-------------------------------------------------------------------------
1579 
1580 sal_Bool SfxObjectShell::IsLoading() const
1581 /*  [Beschreibung ]
1582 	Has FinishedLoading been called? */
1583 {
1584 	return !( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT );
1585 }
1586 
1587 //-------------------------------------------------------------------------
1588 
1589 void SfxObjectShell::CancelTransfers()
1590 /*  [Beschreibung ]
1591 	Hier koennen Transfers gecanceled werden, die nicht mit
1592 	RegisterTransfer registiert wurden */
1593 {
1594 	if( ( pImp->nLoadedFlags & SFX_LOADED_ALL ) != SFX_LOADED_ALL )
1595 	{
1596 		AbortImport();
1597 		if( IsLoading() )
1598 			FinishedLoading( SFX_LOADED_ALL );
1599 
1600 /*
1601 		SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1602 		while( pFrame )
1603 		{
1604 			pFrame->CancelTransfers();
1605 			pFrame = SfxViewFrame::GetNext( *pFrame, this );
1606 		}*/
1607 	}
1608 }
1609 
1610 //-------------------------------------------------------------------------
1611 
1612 AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1613 	const String& rURL, sal_uInt32 nTime, sal_Bool bReloadP, SfxObjectShell* pSh )
1614 	: aUrl( rURL ), bReload( bReloadP ), pObjSh( pSh )
1615 {
1616 	SetTimeout( nTime );
1617 }
1618 
1619 //-------------------------------------------------------------------------
1620 
1621 void AutoReloadTimer_Impl::Timeout()
1622 {
1623 	SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh );
1624 
1625 	if ( pFrame )
1626 	{
1627 		// momentan nicht m"oglich/sinnvoll?
1628         if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
1629 		{
1630 			// erneuten Versuch erlauben
1631 			Start();
1632 			return;
1633 		}
1634 
1635 		SfxAllItemSet aSet( SFX_APP()->GetPool() );
1636 		aSet.Put( SfxBoolItem( SID_AUTOLOAD, sal_True ) );
1637 		if ( aUrl.Len() )
1638 			aSet.Put(  SfxStringItem( SID_FILE_NAME, aUrl ) );
1639 		SfxRequest aReq( SID_RELOAD, 0, aSet );
1640 		pObjSh->Get_Impl()->pReloadTimer = 0;
1641 		delete this;
1642 		pFrame->ExecReload_Impl( aReq );
1643 		return;
1644 	}
1645 
1646 	pObjSh->Get_Impl()->pReloadTimer = 0;
1647 	delete this;
1648 }
1649 
1650 SfxModule* SfxObjectShell::GetModule() const
1651 {
1652 	return GetFactory().GetModule();
1653 }
1654 
1655 ErrCode SfxObjectShell::CallBasic( const String& rMacro,
1656 	const String& rBasic, SbxArray* pArgs,
1657 	SbxValue* pRet )
1658 {
1659     SfxApplication* pApp = SFX_APP();
1660     if( pApp->GetName() != rBasic )
1661     {
1662         if ( !AdjustMacroMode( String() ) )
1663             return ERRCODE_IO_ACCESSDENIED;
1664     }
1665 
1666     BasicManager *pMgr = GetBasicManager();
1667     if( pApp->GetName() == rBasic )
1668         pMgr = pApp->GetBasicManager();
1669     ErrCode nRet = SfxApplication::CallBasic( rMacro, pMgr, pArgs, pRet );
1670     return nRet;
1671 }
1672 
1673 namespace
1674 {
1675     static bool lcl_isScriptAccessAllowed_nothrow( const Reference< XInterface >& _rxScriptContext )
1676     {
1677         try
1678         {
1679             Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY );
1680             if ( !xScripts.is() )
1681             {
1682                 Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW );
1683                 xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW );
1684             }
1685 
1686             return xScripts->getAllowMacroExecution();
1687         }
1688         catch( const Exception& )
1689         {
1690         	DBG_UNHANDLED_EXCEPTION();
1691         }
1692         return false;
1693     }
1694 }
1695 
1696 ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const ::rtl::OUString& _rScriptURL,
1697     const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam, bool bRaiseError )
1698 {
1699     OSL_TRACE( "in CallXScript" );
1700 	ErrCode nErr = ERRCODE_NONE;
1701 
1702     bool bIsDocumentScript = ( _rScriptURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "location=document" ) ) >= 0 );
1703         // TODO: we should parse the URL, and check whether there is a parameter with this name.
1704         // Otherwise, we might find too much.
1705     if ( bIsDocumentScript && !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) )
1706         return ERRCODE_IO_ACCESSDENIED;
1707 
1708 	bool bCaughtException = false;
1709     Any aException;
1710     try
1711     {
1712         // obtain/create a script provider
1713         Reference< provider::XScriptProvider > xScriptProvider;
1714         Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY );
1715         if ( xSPS.is() )
1716             xScriptProvider.set( xSPS->getScriptProvider() );
1717 
1718         if ( !xScriptProvider.is() )
1719         {
1720             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
1721             Reference< provider::XScriptProviderFactory > xScriptProviderFactory(
1722                 aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), UNO_QUERY_THROW );
1723             xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( _rxScriptContext ) ), UNO_SET_THROW );
1724         }
1725 
1726         // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1727         ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext.get() );
1728 
1729         // obtain the script, and execute it
1730         Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_QUERY_THROW );
1731         aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
1732     }
1733     catch ( const uno::Exception& )
1734     {
1735         aException = ::cppu::getCaughtException();
1736 		bCaughtException = sal_True;
1737         nErr = ERRCODE_BASIC_INTERNAL_ERROR;
1738     }
1739 
1740 	if ( bCaughtException && bRaiseError )
1741 	{
1742         ::std::auto_ptr< VclAbstractDialog > pScriptErrDlg;
1743 		SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1744         if ( pFact )
1745             pScriptErrDlg.reset( pFact->CreateScriptErrorDialog( NULL, aException ) );
1746         OSL_ENSURE( pScriptErrDlg.get(), "SfxObjectShell::CallXScript: no script error dialog!" );
1747 
1748         if ( pScriptErrDlg.get() )
1749 			pScriptErrDlg->Execute();
1750 	}
1751 
1752     OSL_TRACE( "leaving CallXScript" );
1753     return nErr;
1754 }
1755 
1756 // perhaps rename to CallScript once we get rid of the existing CallScript
1757 // and Call, CallBasic, CallStarBasic methods
1758 ErrCode SfxObjectShell::CallXScript( const String& rScriptURL,
1759         const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >&
1760             aParams,
1761         ::com::sun::star::uno::Any& aRet,
1762         ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
1763         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam
1764         , bool bRaiseError )
1765 {
1766     return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, bRaiseError );
1767 }
1768 
1769 //-------------------------------------------------------------------------
1770 SfxFrame* SfxObjectShell::GetSmartSelf( SfxFrame* pSelf, SfxMedium& /*rMedium*/ )
1771 {
1772 	return pSelf;
1773 }
1774 
1775 SfxObjectShellFlags SfxObjectShell::GetFlags() const
1776 {
1777 	if( pImp->eFlags == SFXOBJECTSHELL_UNDEFINED )
1778 		pImp->eFlags = GetFactory().GetFlags();
1779 	return pImp->eFlags;
1780 }
1781 
1782 void SfxObjectShell::SetFlags( SfxObjectShellFlags eFlags )
1783 {
1784 	pImp->eFlags = eFlags;
1785 }
1786 
1787 void SfxHeaderAttributes_Impl::SetAttributes()
1788 {
1789 	bAlert = sal_True;
1790 	SvKeyValue aPair;
1791 	for( sal_Bool bCont = xIter->GetFirst( aPair ); bCont;
1792 		 bCont = xIter->GetNext( aPair ) )
1793 		SetAttribute( aPair );
1794 }
1795 
1796 void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue& rKV )
1797 {
1798 	String aValue = rKV.GetValue();
1799 	if( rKV.GetKey().CompareIgnoreCaseToAscii( "refresh" ) == COMPARE_EQUAL && rKV.GetValue().Len() )
1800 	{
1801 		sal_uInt32 nTime = aValue.GetToken(  0, ';' ).ToInt32() ;
1802 		String aURL = aValue.GetToken( 1, ';' );
1803 		aURL.EraseTrailingChars().EraseLeadingChars();
1804         uno::Reference<document::XDocumentProperties> xDocProps(
1805             pDoc->getDocProperties());
1806 		if( aURL.Copy(0, 4).CompareIgnoreCaseToAscii( "url=" ) == COMPARE_EQUAL )
1807 		{
1808 			INetURLObject aObj;
1809 			INetURLObject( pDoc->GetMedium()->GetName() ).GetNewAbsURL( aURL.Copy( 4 ), &aObj );
1810             xDocProps->setAutoloadURL(
1811                 aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1812 		}
1813         try
1814         {
1815             xDocProps->setAutoloadSecs( nTime );
1816         }
1817         catch (lang::IllegalArgumentException &)
1818         {
1819             // ignore
1820         }
1821 	}
1822 	else if( rKV.GetKey().CompareIgnoreCaseToAscii( "expires" ) == COMPARE_EQUAL )
1823 	{
1824 		DateTime aDateTime;
1825 		if( INetRFC822Message::ParseDateField( rKV.GetValue(), aDateTime ) )
1826 		{
1827 			aDateTime.ConvertToLocalTime();
1828 			pDoc->GetMedium()->SetExpired_Impl( aDateTime );
1829 		}
1830 		else
1831 		{
1832 //			DBG_ERROR( "Schlechtes ::com::sun::star::util::DateTime fuer Expired" );
1833 			pDoc->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1834 		}
1835 	}
1836 	else if( rKV.GetKey().CompareIgnoreCaseToAscii( "content-type" ) == COMPARE_EQUAL )
1837 	{
1838 		::rtl::OString sContent = ::rtl::OUStringToOString( aValue, RTL_TEXTENCODING_ASCII_US );
1839 		ByteString sType, sSubType;
1840 		INetContentTypeParameterList aParameters;
1841 
1842 		if( INetContentTypes::parse( sContent, sType, sSubType, &aParameters ) )
1843 		{
1844 			const INetContentTypeParameter * pCharset = aParameters.find("charset");
1845 			if (pCharset != 0)
1846 				pDoc->GetMedium()->SetCharset( pCharset->m_sValue );
1847 		}
1848 	}
1849 }
1850 
1851 void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV )
1852 {
1853 	xIter->Append( rKV );
1854 	if( bAlert ) SetAttribute( rKV );
1855 }
1856 
1857 SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes()
1858 {
1859 	if( !pImp->xHeaderAttributes.Is() )
1860 	{
1861 		DBG_ASSERT( pMedium, "Kein Medium" );
1862 		pImp->xHeaderAttributes = new SfxHeaderAttributes_Impl( this );
1863 	}
1864 	return ( SvKeyValueIterator*) &pImp->xHeaderAttributes;
1865 }
1866 
1867 void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1868 {
1869 	((SfxHeaderAttributes_Impl*)GetHeaderAttributes())
1870 		->ClearForSourceView();
1871 }
1872 
1873 
1874 void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1875 {
1876 	((SfxHeaderAttributes_Impl*)GetHeaderAttributes())
1877 		->SetAttributes();
1878 }
1879 
1880 sal_Bool SfxObjectShell::IsPreview() const
1881 {
1882 	if ( !pMedium )
1883 		return sal_False;
1884 
1885 	sal_Bool bPreview = sal_False;
1886 	SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
1887 	if ( pFlags )
1888 	{
1889 		// Werte auf einzelne Items verteilen
1890 		String aFileFlags = pFlags->GetValue();
1891 		aFileFlags.ToUpperAscii();
1892 		if ( STRING_NOTFOUND != aFileFlags.Search( 'B' ) )
1893 			bPreview = sal_True;
1894 	}
1895 
1896 	if ( !bPreview )
1897 	{
1898 		SFX_ITEMSET_ARG( pMedium->GetItemSet(), pItem, SfxBoolItem, SID_PREVIEW, sal_False);
1899 		if ( pItem )
1900 			bPreview = pItem->GetValue();
1901 	}
1902 
1903 	return bPreview;
1904 }
1905 
1906 sal_Bool SfxObjectShell::IsSecure()
1907 {
1908 	// Wenn globale Warnung an ist, nach Secure-Referer-Liste gehen
1909 	String aReferer = GetMedium()->GetName();
1910 	if ( !aReferer.Len() )
1911 	{
1912 		// bei neuen Dokumenten das Template als Referer nehmen
1913 		::rtl::OUString aTempl( getDocProperties()->getTemplateURL() );
1914 		if ( aTempl.getLength() )
1915             aReferer = INetURLObject( aTempl ).GetMainURL( INetURLObject::NO_DECODE );
1916 	}
1917 
1918 	INetURLObject aURL( "macro:" );
1919     if ( !aReferer.Len() )
1920         // empty new or embedded document
1921         return sal_True;
1922 
1923 		SvtSecurityOptions aOpt;
1924 
1925 	if( aOpt.GetBasicMode() == eALWAYS_EXECUTE )
1926     	return sal_True;
1927 
1928 	if( aOpt.GetBasicMode() == eNEVER_EXECUTE )
1929     	return sal_False;
1930 
1931 	if ( aOpt.IsSecureURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aReferer ) )
1932     //if ( SvtSecurityOptions().IsSecureURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aReferer ) )
1933 	{
1934         if ( GetMedium()->GetContent().is() )
1935         {
1936             Any aAny( ::utl::UCBContentHelper::GetProperty( aURL.GetMainURL( INetURLObject::NO_DECODE ), String( RTL_CONSTASCII_USTRINGPARAM("IsProtected")) ) );
1937             sal_Bool bIsProtected = sal_False;
1938             if ( ( aAny >>= bIsProtected ) && bIsProtected )
1939                 return sal_False;
1940             else
1941                 return sal_True;
1942 		}
1943 		else
1944 			return sal_True;
1945 	}
1946 	else
1947 		return sal_False;
1948 }
1949 
1950 void SfxObjectShell::SetWaitCursor( sal_Bool bSet ) const
1951 {
1952     for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1953     {
1954         if ( bSet )
1955             pFrame->GetFrame().GetWindow().EnterWait();
1956         else
1957             pFrame->GetFrame().GetWindow().LeaveWait();
1958     }
1959 }
1960 
1961 String SfxObjectShell::GetAPIName() const
1962 {
1963 	INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : ::rtl::OUString( GetMedium()->GetName() ) );
1964     String aName( aURL.GetBase() );
1965     if( !aName.Len() )
1966         aName = aURL.GetURLNoPass();
1967     if ( !aName.Len() )
1968         aName = GetTitle( SFX_TITLE_DETECT );
1969     return aName;
1970 }
1971 
1972 void SfxObjectShell::Invalidate( sal_uInt16 nId )
1973 {
1974     for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1975         Invalidate_Impl( pFrame->GetBindings(), nId );
1976 }
1977 
1978 bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool bSuppressUI )
1979 {
1980     uno::Reference< task::XInteractionHandler > xInteraction;
1981     if ( pMedium && !bSuppressUI )
1982         xInteraction = pMedium->GetInteractionHandler();
1983 
1984     CheckForBrokenDocSignatures_Impl( xInteraction );
1985 
1986     CheckEncryption_Impl( xInteraction );
1987 
1988     return pImp->aMacroMode.adjustMacroMode( xInteraction );
1989 }
1990 
1991 Window* SfxObjectShell::GetDialogParent( SfxMedium* pLoadingMedium )
1992 {
1993     Window* pWindow = 0;
1994     SfxItemSet* pSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet();
1995     SFX_ITEMSET_ARG( pSet, pUnoItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False );
1996     if ( pUnoItem )
1997     {
1998         uno::Reference < frame::XFrame > xFrame( pUnoItem->GetFrame() );
1999         pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
2000     }
2001 
2002     if ( !pWindow )
2003     {
2004         SfxFrame* pFrame = 0;
2005         SFX_ITEMSET_ARG( pSet, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False );
2006         if( pFrameItem && pFrameItem->GetFrame() )
2007             // get target frame from ItemSet
2008             pFrame = pFrameItem->GetFrame();
2009         else
2010         {
2011             // try the current frame
2012             SfxViewFrame* pView = SfxViewFrame::Current();
2013             if ( !pView || pView->GetObjectShell() != this )
2014                 // get any visible frame
2015                 pView = SfxViewFrame::GetFirst(this);
2016             if ( pView )
2017                 pFrame = &pView->GetFrame();
2018         }
2019 
2020         if ( pFrame )
2021             // get topmost window
2022             pWindow = VCLUnoHelper::GetWindow( pFrame->GetFrameInterface()->getContainerWindow() );
2023     }
2024 
2025     if ( pWindow )
2026     {
2027         // this frame may be invisible, show it if it is allowed
2028         SFX_ITEMSET_ARG( pSet, pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
2029         if ( !pHiddenItem || !pHiddenItem->GetValue() )
2030         {
2031             pWindow->Show();
2032             pWindow->ToTop();
2033         }
2034     }
2035 
2036     return pWindow;
2037 }
2038 
2039 String SfxObjectShell::UpdateTitle( SfxMedium* pMed, sal_uInt16 nDocViewNumber )
2040 {
2041     // Titel des Fensters
2042     String aTitle;
2043     if ( pMed )
2044 	{
2045 		INetURLObject aTmp( pMed->GetName() );
2046         aTitle = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2047 	}
2048     else
2049     {
2050 		pMed = GetMedium();
2051         aTitle = GetTitle(SFX_TITLE_CAPTION);
2052         String aName(aTitle);
2053         if ( nDocViewNumber )
2054         {
2055             aName += ':';
2056             aName += String::CreateFromInt32( nDocViewNumber );
2057         }
2058     }
2059 
2060 	if ( pMed )
2061 	{
2062 		SFX_ITEMSET_ARG( pMed->GetItemSet(), pRepairedDocItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False );
2063 		if ( pRepairedDocItem && pRepairedDocItem->GetValue() )
2064         	aTitle += String( SfxResId(STR_REPAIREDDOCUMENT) );
2065 	}
2066 
2067 	if ( IsReadOnlyUI() || (pMed && pMed->IsReadOnly()) )
2068         aTitle += String( SfxResId(STR_READONLY) );
2069     else if ( IsDocShared() )
2070         aTitle += String( SfxResId(STR_SHARED) );
2071 
2072     return aTitle;
2073 }
2074 
2075 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
2076 {
2077 	eCreateMode = nMode;
2078 }
2079 
2080 sal_Bool SfxObjectShell::IsInPlaceActive()
2081 {
2082 	if ( eCreateMode != SFX_CREATE_MODE_EMBEDDED )
2083 		return sal_False;
2084 
2085     SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
2086     return pFrame && pFrame->GetFrame().IsInPlace();
2087 }
2088 
2089 sal_Bool SfxObjectShell::IsUIActive()
2090 {
2091 	if ( eCreateMode != SFX_CREATE_MODE_EMBEDDED )
2092 		return sal_False;
2093 
2094     SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
2095     return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
2096 }
2097 
2098 void SfxObjectShell::UIActivate( sal_Bool )
2099 {
2100 }
2101 
2102 void SfxObjectShell::InPlaceActivate( sal_Bool )
2103 {
2104 }
2105 
2106 sal_Bool SfxObjectShell::UseInteractionToHandleError(
2107                     const uno::Reference< task::XInteractionHandler >& xHandler,
2108                     sal_uInt32 nError )
2109 {
2110     sal_Bool bResult = sal_False;
2111 
2112     if ( xHandler.is() )
2113     {
2114         try
2115         {
2116             uno::Any aInteraction;
2117             uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations(2);
2118             ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort();
2119             ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
2120             lContinuations[0] = uno::Reference< task::XInteractionContinuation >(
2121                                  static_cast< task::XInteractionContinuation* >( pAbort ), uno::UNO_QUERY );
2122             lContinuations[1] = uno::Reference< task::XInteractionContinuation >(
2123                                  static_cast< task::XInteractionContinuation* >( pApprove ), uno::UNO_QUERY );
2124 
2125             task::ErrorCodeRequest aErrorCode;
2126             aErrorCode.ErrCode = nError;
2127             aInteraction <<= aErrorCode;
2128             xHandler->handle(::framework::InteractionRequest::CreateRequest (aInteraction,lContinuations));
2129             bResult = pAbort->wasSelected();
2130         }
2131         catch( uno::Exception& )
2132         {}
2133     }
2134 
2135     return bResult;
2136 }
2137 
2138 sal_Bool SfxObjectShell_Impl::NeedsOfficeUpdateDialog()
2139 {
2140     // if the configuration is not available for any reason, the default behavior is to show the message
2141     sal_Bool bResult = sal_True;
2142 
2143     try
2144     {
2145     	uno::Reference< lang::XMultiServiceFactory > xServiceManager( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
2146 		uno::Reference< uno::XInterface > xCommonConfig(
2147                         ::comphelper::ConfigurationHelper::openConfig(
2148 							xServiceManager,
2149 							::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
2150 							::comphelper::ConfigurationHelper::E_STANDARD ),
2151                         uno::UNO_SET_THROW );
2152 
2153         ::comphelper::ConfigurationHelper::readRelativeKey(
2154                         xCommonConfig,
2155                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Load/" ) ),
2156                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowOfficeUpdateDialog" ) ) ) >>= bResult;
2157     }
2158     catch( uno::Exception& )
2159     {
2160     }
2161 
2162 	return bResult;
2163 }
2164 
2165 sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const
2166 {
2167     sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE );
2168 
2169     const SfxMedium* pMedium( rDocShell.GetMedium() );
2170     OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
2171     if ( pMedium )
2172     {
2173         SFX_ITEMSET_ARG( pMedium->GetItemSet(), pMacroModeItem, SfxUInt16Item, SID_MACROEXECMODE, sal_False);
2174         if ( pMacroModeItem )
2175             nImposedExecMode = pMacroModeItem->GetValue();
2176     }
2177     return nImposedExecMode;
2178 }
2179 
2180 sal_Bool SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
2181 {
2182     const SfxMedium* pMedium( rDocShell.GetMedium() );
2183     OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
2184     if ( pMedium )
2185     {
2186 		pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) );
2187         return sal_True;
2188     }
2189 
2190     return sal_False;
2191 }
2192 
2193 ::rtl::OUString SfxObjectShell_Impl::getDocumentLocation() const
2194 {
2195     ::rtl::OUString sLocation;
2196 
2197     const SfxMedium* pMedium( rDocShell.GetMedium() );
2198     OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
2199     if ( pMedium )
2200     {
2201         sLocation = pMedium->GetName();
2202         if ( !sLocation.getLength() )
2203         {
2204             // for documents made from a template: get the name of the template
2205             sLocation = rDocShell.getDocProperties()->getTemplateURL();
2206         }
2207     }
2208     return sLocation;
2209 }
2210 
2211 uno::Reference< embed::XStorage > SfxObjectShell_Impl::getZipStorageToSign()
2212 {
2213     Reference < embed::XStorage > xStore;
2214 
2215     SfxMedium* pMedium( rDocShell.GetMedium() );
2216     OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getLastCommitDocumentStorage: no medium!" );
2217     if ( pMedium )
2218         xStore = pMedium->GetZipStorageToSign_Impl();
2219 
2220     return xStore;
2221 }
2222 
2223 sal_Bool SfxObjectShell_Impl::documentStorageHasMacros() const
2224 {
2225     return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage );
2226 }
2227 
2228 Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
2229 {
2230     return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY );
2231 }
2232 
2233 sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState()
2234 {
2235     sal_Int16 nSignatureState( rDocShell.GetScriptingSignatureState() );
2236 
2237     if ( nSignatureState != SIGNATURESTATE_NOSIGNATURES && m_bMacroSignBroken )
2238     {
2239         // if there is a macro signature it must be handled as broken
2240         nSignatureState = SIGNATURESTATE_SIGNATURES_BROKEN;
2241     }
2242 
2243     return nSignatureState;
2244 }
2245 
2246 sal_Bool SfxObjectShell_Impl::hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor )
2247 {
2248     sal_Bool bResult = sal_False;
2249 
2250     try
2251     {
2252         ::rtl::OUString aVersion;
2253         try
2254         {
2255             uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW );
2256             xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion;
2257         }
2258         catch( uno::Exception& )
2259         {
2260         }
2261         uno::Sequence< uno::Any > aArgs( 1 );
2262         aArgs[0] <<= aVersion;
2263 
2264         uno::Reference< security::XDocumentDigitalSignatures > xSigner( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW );
2265 
2266         if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN
2267           || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
2268           || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
2269         {
2270             uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.ImplAnalyzeSignature( sal_True, xSigner );
2271 
2272             if ( aInfo.getLength() )
2273             {
2274                 if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN )
2275                     nScriptingSignatureState = rDocShell.ImplCheckSignaturesInformation( aInfo );
2276 
2277                 if ( nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
2278                   || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
2279                 {
2280                     for ( sal_Int32 nInd = 0; !bResult && nInd < aInfo.getLength(); nInd++ )
2281                     {
2282                         bResult = xSigner->isAuthorTrusted( aInfo[nInd].Signer );
2283                     }
2284 
2285                     if ( !bResult && bAllowUIToAddAuthor )
2286                     {
2287                         uno::Reference< task::XInteractionHandler > xInteraction;
2288                         if ( rDocShell.GetMedium() )
2289                             xInteraction = rDocShell.GetMedium()->GetInteractionHandler();
2290 
2291                         if ( xInteraction.is() )
2292                         {
2293                             task::DocumentMacroConfirmationRequest aRequest;
2294                             aRequest.DocumentURL = getDocumentLocation();
2295                             aRequest.DocumentStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl();
2296                             aRequest.DocumentSignatureInformation = aInfo;
2297                             aRequest.DocumentVersion = aVersion;
2298                             aRequest.Classification = task::InteractionClassification_QUERY;
2299                             bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), sal_True );
2300                         }
2301                     }
2302                 }
2303             }
2304         }
2305     }
2306     catch( uno::Exception& )
2307     {}
2308 
2309     return bResult;
2310 }
2311 
2312 void SfxObjectShell_Impl::showBrokenSignatureWarning( const uno::Reference< task::XInteractionHandler >& _rxInteraction ) const
2313 {
2314     if  ( !bSignatureErrorIsShown )
2315     {
2316         SfxObjectShell::UseInteractionToHandleError( _rxInteraction, ERRCODE_SFX_BROKENSIGNATURE );
2317 	    const_cast< SfxObjectShell_Impl* >( this )->bSignatureErrorIsShown = sal_True;
2318     }
2319 }
2320 
2321 void SfxObjectShell::AddLog( const ::rtl::OUString& aMessage )
2322 {
2323     if ( !pImp->m_xLogRing.is() )
2324     {
2325         try
2326         {
2327             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
2328             if ( aContext.is() )
2329                 pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
2330         }
2331         catch( uno::Exception& )
2332         {}
2333     }
2334 
2335     if ( pImp->m_xLogRing.is() )
2336         pImp->m_xLogRing->logString( aMessage );
2337 }
2338 
2339 namespace {
2340 
2341 void WriteStringInStream( const uno::Reference< io::XOutputStream >& xOutStream, const ::rtl::OUString& aString )
2342 {
2343     if ( xOutStream.is() )
2344     {
2345         ::rtl::OString aStrLog = ::rtl::OUStringToOString( aString, RTL_TEXTENCODING_UTF8 );
2346         uno::Sequence< sal_Int8 > aLogData( (const sal_Int8*)aStrLog.getStr(), aStrLog.getLength() );
2347         xOutStream->writeBytes( aLogData );
2348 
2349         aLogData.realloc( 1 );
2350         aLogData[0] = '\n';
2351         xOutStream->writeBytes( aLogData );
2352     }
2353 }
2354 
2355 }
2356 
2357 void SfxObjectShell::StoreLog()
2358 {
2359     if ( !pImp->m_xLogRing.is() )
2360     {
2361         try
2362         {
2363             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
2364             if ( aContext.is() )
2365                 pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
2366         }
2367         catch( uno::Exception& )
2368         {}
2369     }
2370 
2371     if ( pImp->m_xLogRing.is() )
2372     {
2373 #ifdef WNT
2374         ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}" ) );
2375 #else
2376         ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}" ) );
2377 #endif
2378 
2379         ::rtl::Bootstrap::expandMacros( aFileURL );
2380 
2381 #ifdef WNT
2382         ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/setup.ini:buildid}" ) );
2383 #else
2384         ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/setuprc:buildid}" ) );
2385 #endif
2386 
2387         ::rtl::Bootstrap::expandMacros( aBuildID );
2388 
2389         if ( aFileURL.getLength() )
2390         {
2391             aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/temp/document_io_logring.txt" ) );
2392             try
2393             {
2394                 uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
2395                 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( xFactory->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW );
2396                 uno::Reference< io::XStream > xStream( xSimpleFileAccess->openFileReadWrite( aFileURL ), uno::UNO_SET_THROW );
2397                 uno::Reference< io::XOutputStream > xOutStream( xStream->getOutputStream(), uno::UNO_SET_THROW );
2398                 uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY_THROW );
2399                 xTruncate->truncate();
2400 
2401                 if ( aBuildID.getLength() )
2402                     WriteStringInStream( xOutStream, aBuildID );
2403 
2404                 uno::Sequence< ::rtl::OUString > aLogSeq = pImp->m_xLogRing->getCollectedLog();
2405                 for ( sal_Int32 nInd = 0; nInd < aLogSeq.getLength(); nInd++ )
2406                     WriteStringInStream( xOutStream, aLogSeq[nInd] );
2407             }
2408             catch( uno::Exception& )
2409             {}
2410         }
2411     }
2412 }
2413 
2414