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