1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include "arrdecl.hxx"
25 #include <cppuhelper/implbase1.hxx>
27 #include <com/sun/star/util/XCloseable.hpp>
28 #include <com/sun/star/frame/XComponentLoader.hpp>
29 #include <com/sun/star/frame/Desktop.hpp>
30 #include <com/sun/star/util/XCloseBroadcaster.hpp>
31 #include <com/sun/star/util/XCloseListener.hpp>
32 #include <com/sun/star/util/XModifyBroadcaster.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/frame/XTitle.hpp>
35 #include <osl/mutex.hxx>
36 #include <rtl/instance.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <vcl/wrkwin.hxx>
39 #include <vcl/svapp.hxx>
40 #include <svl/eitem.hxx>
41 #include <tools/rtti.hxx>
42 #include <svl/lstner.hxx>
43 #include <sfx2/sfxhelp.hxx>
44 #include <basic/sbstar.hxx>
45 #include <svl/stritem.hxx>
46 #include <basic/sbx.hxx>
47 #include <unotools/eventcfg.hxx>
49 #include <sfx2/objsh.hxx>
50 #include <sfx2/signaturestate.hxx>
51 #include <sfx2/sfxmodelfactory.hxx>
53 #include <basic/sbuno.hxx>
54 #include <svtools/sfxecode.hxx>
55 #include <svtools/ehdl.hxx>
56 #include <unotools/printwarningoptions.hxx>
57 #include <comphelper/processfactory.hxx>
58 #include <comphelper/string.hxx>
60 #include <com/sun/star/document/XStorageBasedDocument.hpp>
61 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
62 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
63 #include <com/sun/star/document/XEmbeddedScripts.hpp>
64 #include <com/sun/star/document/XScriptInvocationContext.hpp>
66 #include <svl/urihelper.hxx>
67 #include <unotools/pathoptions.hxx>
68 #include <svl/sharecontrolfile.hxx>
69 #include <unotools/localfilehelper.hxx>
70 #include <unotools/ucbhelper.hxx>
71 #include <svtools/asynclink.hxx>
72 #include <tools/diagnose_ex.h>
73 #include <comphelper/classids.hxx>
75 #include <sfx2/app.hxx>
76 #include <sfx2/docfac.hxx>
77 #include <sfx2/docfile.hxx>
78 #include <sfx2/event.hxx>
79 #include <sfx2/dispatch.hxx>
80 #include <sfx2/viewsh.hxx>
81 #include <sfx2/viewfrm.hxx>
82 #include <sfx2/sfxresid.hxx>
83 #include "objshimp.hxx"
84 #include "sfxtypes.hxx"
85 #include <sfx2/evntconf.hxx>
86 #include <sfx2/request.hxx>
88 #include "sfxlocal.hrc"
89 #include "appdata.hxx"
90 #include <sfx2/sfxsids.hrc>
91 #include <basic/basmgr.hxx>
92 #include <svtools/svtools.hrc>
93 #include <sfx2/QuerySaveDocument.hxx>
95 #include <sfx2/msg.hxx>
96 #include "appbaslib.hxx"
97 #include <sfx2/sfxbasemodel.hxx>
98 #include <shellimpl.hxx>
100 #include <basic/basicmanagerrepository.hxx>
102 using namespace ::com::sun::star
;
103 using namespace ::com::sun::star::uno
;
104 using namespace ::com::sun::star::script
;
105 using namespace ::com::sun::star::frame
;
106 using namespace ::com::sun::star::document
;
108 using ::basic::BasicManagerRepository
;
109 #include <uno/mapping.hxx>
111 #include "sfxslots.hxx"
115 class theCurrentComponent
: public rtl::Static
< WeakReference
< XInterface
>, theCurrentComponent
> {};
117 #if HAVE_FEATURE_SCRIPTING
119 // remember all registered components for VBA compatibility, to be able to remove them on disposing the model
120 typedef ::std::map
< XInterface
*, OString
> VBAConstantNameMap
;
121 static VBAConstantNameMap s_aRegisteredVBAConstants
;
123 OString
lclGetVBAGlobalConstName( const Reference
< XInterface
>& rxComponent
)
125 OSL_ENSURE( rxComponent
.is(), "lclGetVBAGlobalConstName - missing component" );
127 VBAConstantNameMap::iterator aIt
= s_aRegisteredVBAConstants
.find( rxComponent
.get() );
128 if( aIt
!= s_aRegisteredVBAConstants
.end() )
131 uno::Reference
< beans::XPropertySet
> xProps( rxComponent
, uno::UNO_QUERY
);
132 if( xProps
.is() ) try
135 xProps
->getPropertyValue("VBAGlobalConstantName") >>= aConstName
;
136 return OUStringToOString( aConstName
, RTL_TEXTENCODING_ASCII_US
);
138 catch (const uno::Exception
&) // not supported
150 class SfxModelListener_Impl
: public ::cppu::WeakImplHelper1
< ::com::sun::star::util::XCloseListener
>
152 SfxObjectShell
* mpDoc
;
154 explicit SfxModelListener_Impl( SfxObjectShell
* pDoc
) : mpDoc(pDoc
) {};
155 virtual void SAL_CALL
queryClosing( const com::sun::star::lang::EventObject
& aEvent
, sal_Bool bDeliverOwnership
)
156 throw ( com::sun::star::uno::RuntimeException
, com::sun::star::util::CloseVetoException
, std::exception
) SAL_OVERRIDE
;
157 virtual void SAL_CALL
notifyClosing( const com::sun::star::lang::EventObject
& aEvent
) throw ( com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
158 virtual void SAL_CALL
disposing( const com::sun::star::lang::EventObject
& aEvent
) throw ( com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
162 void SAL_CALL
SfxModelListener_Impl::queryClosing( const com::sun::star::lang::EventObject
& , sal_Bool
)
163 throw ( com::sun::star::uno::RuntimeException
, com::sun::star::util::CloseVetoException
, std::exception
)
167 void SAL_CALL
SfxModelListener_Impl::notifyClosing( const com::sun::star::lang::EventObject
& ) throw ( com::sun::star::uno::RuntimeException
, std::exception
)
169 SolarMutexGuard aSolarGuard
;
170 mpDoc
->Broadcast( SfxSimpleHint(SFX_HINT_DEINITIALIZING
) );
173 void SAL_CALL
SfxModelListener_Impl::disposing( const com::sun::star::lang::EventObject
& _rEvent
) throw ( com::sun::star::uno::RuntimeException
, std::exception
)
175 // am I ThisComponent in AppBasic?
176 SolarMutexGuard aSolarGuard
;
177 if ( SfxObjectShell::GetCurrentComponent() == _rEvent
.Source
)
179 // remove ThisComponent reference from AppBasic
180 SfxObjectShell::SetCurrentComponent( Reference
< XInterface
>() );
183 #if HAVE_FEATURE_SCRIPTING
184 /* Remove VBA component from AppBasic. As every application registers its
185 own current component, the disposed component may not be the "current
186 component" of the SfxObjectShell. */
187 if ( _rEvent
.Source
.is() )
189 VBAConstantNameMap::iterator aIt
= s_aRegisteredVBAConstants
.find( _rEvent
.Source
.get() );
190 if ( aIt
!= s_aRegisteredVBAConstants
.end() )
192 if ( BasicManager
* pAppMgr
= SfxApplication::GetBasicManager() )
193 pAppMgr
->SetGlobalUNOConstant( aIt
->second
.getStr(), Any( Reference
< XInterface
>() ) );
194 s_aRegisteredVBAConstants
.erase( aIt
);
199 if ( !mpDoc
->Get_Impl()->bClosing
)
200 // GCC crashes when already in the destructor, so first query the Flag
204 TYPEINIT1(SfxObjectShell
, SfxShell
);
207 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell
& _rDocShell
)
208 :mpObjectContainer(0)
209 ,rDocShell( _rDocShell
)
212 ,nTime( DateTime::SYSTEM
)
213 ,nVisualDocumentNumber( USHRT_MAX
)
214 ,nDocumentSignatureState( SignatureState::UNKNOWN
)
215 ,nScriptingSignatureState( SignatureState::UNKNOWN
)
220 ,bIsNamedVisible( false)
222 ,bIsAbortingImport ( false)
223 ,bImportDone ( false)
224 ,bInPrepareClose( false )
225 ,bPreparedForClose( false )
226 ,bForbidReload( false )
227 ,bBasicInitialized( false )
228 ,bIsPrintJobCancelable( true )
229 ,bOwnsStorage( true )
231 ,bInitialized( false )
232 ,bSignatureErrorIsShown( false )
233 ,bModelInitialized( false )
234 ,bPreserveVersions( true )
235 ,m_bMacroSignBroken( false )
236 ,m_bNoBasicCapabilities( false )
237 ,m_bDocRecoverySupport( true )
238 ,bQueryLoadTemplate( true )
239 ,bLoadReadonly( false )
240 ,bUseUserData( true )
241 ,bSaveVersionOnClose( false )
242 ,m_bSharedXMLFlag( false )
243 ,m_bAllowShareControlFileClean( true )
244 ,m_bConfigOptionsChecked( false )
249 ,nLoadedFlags ( SfxLoadedFlags::ALL
)
250 ,nFlagsInProgress( SfxLoadedFlags::NONE
)
252 ,bRunningMacro( false )
253 ,bReloadAvailable( false )
256 ,eFlags( SfxObjectShellFlags::UNDEFINED
)
257 ,bReadOnlyUI( false )
260 ,m_bEnableSetModified( true )
261 ,m_bIsModified( false )
262 ,m_nMapUnit( MAP_100TH_MM
)
263 ,m_bCreateTempStor( false )
265 ,m_bIncomplEncrWarnShown( false )
266 ,m_nModifyPasswordHash( 0 )
267 ,m_bModifyPasswordEntered( false )
269 SfxObjectShell
* pDoc
= &_rDocShell
;
270 SfxObjectShellArr_Impl
&rArr
= SfxGetpApp()->GetObjectShells_Impl();
271 rArr
.push_back( pDoc
);
277 SfxObjectShell_Impl::~SfxObjectShell_Impl()
283 SfxObjectShell::SfxObjectShell( const SfxModelFlags i_nCreationFlags
)
284 : pImp( new SfxObjectShell_Impl( *this ) )
287 , eCreateMode(SfxObjectCreateMode::STANDARD
)
289 , bIsInGenerateThumbnail ( false )
291 if (i_nCreationFlags
& SfxModelFlags::EMBEDDED_OBJECT
)
292 eCreateMode
= SfxObjectCreateMode::EMBEDDED
;
293 else if (i_nCreationFlags
& SfxModelFlags::EXTERNAL_LINK
)
294 eCreateMode
= SfxObjectCreateMode::INTERNAL
;
296 const bool bScriptSupport
= ( i_nCreationFlags
& SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
) == SfxModelFlags::NONE
;
297 if ( !bScriptSupport
)
300 const bool bDocRecovery
= ( i_nCreationFlags
& SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
) == SfxModelFlags::NONE
;
302 pImp
->m_bDocRecoverySupport
= false;
307 // initializes a document from a file-description
309 SfxObjectShell::SfxObjectShell
311 SfxObjectCreateMode eMode
/* Purpose, io which the SfxObjectShell
314 SfxObjectCreateMode::EMBEDDED (default)
315 as SO-Server from within another
318 SfxObjectCreateMode::STANDARD,
319 as a normal Document open stand-alone
321 SfxObjectCreateMode::PREVIEW
322 to enable a Preview, if possible are
323 only little information is needed
325 SfxObjectCreateMode::ORGANIZER
326 to be displayed in the Organizer, here
327 notning of the contents is used */
332 Constructor of the class SfxObjectShell.
335 : pImp( new SfxObjectShell_Impl( *this ) ),
340 bIsInGenerateThumbnail ( false )
346 // virtual destructor of typical base-class SfxObjectShell
348 SfxObjectShell::~SfxObjectShell()
351 if ( IsEnableSetModified() )
352 EnableSetModified( false );
354 // Never call GetInPlaceObject(), the access to the derivative branch
355 // SfxInternObject is not allowed because of a compiler bug
356 SfxObjectShell::CloseInternal();
357 pImp
->pBaseModel
.set( NULL
);
359 DELETEX(AutoReloadTimer_Impl
, pImp
->pReloadTimer
);
361 SfxApplication
*pSfxApp
= SfxGetpApp();
362 if ( USHRT_MAX
!= pImp
->nVisualDocumentNumber
)
363 pSfxApp
->ReleaseIndex(pImp
->nVisualDocumentNumber
);
365 // Destroy Basic-Manager
366 pImp
->aBasicManager
.reset( NULL
);
368 if ( pSfxApp
->GetDdeService() )
369 pSfxApp
->RemoveDdeTopic( this );
371 pImp
->pBaseModel
.set( NULL
);
373 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
374 if ( pMedium
&& pMedium
->HasStorage_Impl() && pMedium
->GetStorage( false ) == pImp
->m_xDocStorage
)
375 pMedium
->CanDisposeStorage_Impl( false );
377 if ( pImp
->mpObjectContainer
)
379 pImp
->mpObjectContainer
->CloseEmbeddedObjects();
380 delete pImp
->mpObjectContainer
;
383 if ( pImp
->bOwnsStorage
&& pImp
->m_xDocStorage
.is() )
384 pImp
->m_xDocStorage
->dispose();
388 pMedium
->CloseAndReleaseStreams_Impl();
390 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
394 DELETEX( SfxMedium
, pMedium
);
397 // The removing of the temporary file must be done as the latest step in the document destruction
398 if ( !pImp
->aTempName
.isEmpty() )
401 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp
->aTempName
, aTmp
);
402 ::utl::UCBContentHelper::Kill( aTmp
);
410 void SfxObjectShell::Stamp_SetPrintCancelState(bool bState
)
412 pImp
->bIsPrintJobCancelable
= bState
;
417 bool SfxObjectShell::Stamp_GetPrintCancelState() const
419 return pImp
->bIsPrintJobCancelable
;
424 // closes the Object and all its views
426 bool SfxObjectShell::Close()
428 SfxObjectShellRef
aRef(this);
429 return CloseInternal();
432 // variant that does not take a reference to itself, so we can call it during object destruction
433 bool SfxObjectShell::CloseInternal()
435 if ( !pImp
->bClosing
)
437 // Do not close if a progress is still running
438 if ( !pImp
->bDisposing
&& GetProgress() )
441 pImp
->bClosing
= true;
442 Reference
< util::XCloseable
> xCloseable( GetBaseModel(), UNO_QUERY
);
444 if ( xCloseable
.is() )
448 xCloseable
->close( sal_True
);
450 catch (const Exception
&)
452 pImp
->bClosing
= false;
456 if ( pImp
->bClosing
)
458 // remove from Document list
459 // If there is no App, there is no document to remove
460 // no need to call GetOrCreate here
461 SfxApplication
*pSfxApp
= SfxApplication::Get();
464 SfxObjectShellArr_Impl
&rDocs
= pSfxApp
->GetObjectShells_Impl();
465 SfxObjectShellArr_Impl::iterator it
= std::find( rDocs
.begin(), rDocs
.end(), this );
466 if ( it
!= rDocs
.end() )
468 pImp
->bInList
= false;
476 OUString
SfxObjectShell::CreateShellID( const SfxObjectShell
* pShell
)
483 SfxMedium
* pMedium
= pShell
->GetMedium();
485 aShellID
= pMedium
->GetBaseURL();
487 if (!aShellID
.isEmpty())
490 sal_Int64 nShellID
= reinterpret_cast<sal_Int64
>(pShell
);
491 aShellID
= "0x" + OUString::number(nShellID
, 16);
495 // returns a pointer the first SfxDocument of specified type
497 SfxObjectShell
* SfxObjectShell::GetFirst
499 const TypeId
* pType
,
503 SfxObjectShellArr_Impl
&rDocs
= SfxGetpApp()->GetObjectShells_Impl();
505 // search for a SfxDocument of the specified type
506 for ( sal_uInt16 nPos
= 0; nPos
< rDocs
.size(); ++nPos
)
508 SfxObjectShell
* pSh
= rDocs
[ nPos
];
509 if ( bOnlyVisible
&& pSh
->IsPreview() && pSh
->IsReadOnly() )
512 if ( ( !pType
|| pSh
->IsA(*pType
) ) &&
513 ( !bOnlyVisible
|| SfxViewFrame::GetFirst( pSh
, true )))
521 // returns a pointer to the next SfxDocument of specified type behind *pDoc
523 SfxObjectShell
* SfxObjectShell::GetNext
525 const SfxObjectShell
& rPrev
,
530 SfxObjectShellArr_Impl
&rDocs
= SfxGetpApp()->GetObjectShells_Impl();
532 // refind the specified predecessor
534 for ( nPos
= 0; nPos
< rDocs
.size(); ++nPos
)
535 if ( rDocs
[nPos
] == &rPrev
)
538 // search for the next SfxDocument of the specified type
539 for ( ++nPos
; nPos
< rDocs
.size(); ++nPos
)
541 SfxObjectShell
* pSh
= rDocs
[ nPos
];
542 if ( bOnlyVisible
&& pSh
->IsPreview() && pSh
->IsReadOnly() )
545 if ( ( !pType
|| pSh
->IsA(*pType
) ) &&
546 ( !bOnlyVisible
|| SfxViewFrame::GetFirst( pSh
, true )))
554 SfxObjectShell
* SfxObjectShell::Current()
556 SfxViewFrame
*pFrame
= SfxViewFrame::Current();
557 return pFrame
? pFrame
->GetObjectShell() : 0;
562 bool SfxObjectShell::IsInPrepareClose() const
564 return pImp
->bInPrepareClose
;
571 SfxObjectShell_Impl
* pImp
;
572 explicit BoolEnv_Impl( SfxObjectShell_Impl
* pImpP
) : pImp( pImpP
)
573 { pImpP
->bInPrepareClose
= true; }
574 ~BoolEnv_Impl() { pImp
->bInPrepareClose
= false; }
578 bool SfxObjectShell::PrepareClose
580 bool bUI
// true: Dialog and so on is allowed
581 // false: silent-mode
584 if( pImp
->bInPrepareClose
|| pImp
->bPreparedForClose
)
586 BoolEnv_Impl
aBoolEnv( pImp
);
589 if ( IsInModalMode() )
592 SfxViewFrame
* pFirst
= SfxViewFrame::GetFirst( this );
593 if( pFirst
&& !pFirst
->GetFrame().PrepareClose_Impl( bUI
) )
596 // prepare views for closing
597 for ( SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
598 pFrm
; pFrm
= SfxViewFrame::GetNext( *pFrm
, this ) )
600 DBG_ASSERT(pFrm
->GetViewShell(),"No Shell");
601 if ( pFrm
->GetViewShell() )
603 bool nRet
= pFrm
->GetViewShell()->PrepareClose( bUI
);
609 SfxApplication
*pSfxApp
= SfxGetpApp();
610 pSfxApp
->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC
, GlobalEventConfig::GetEventName(GlobalEventId::PREPARECLOSEDOC
), this) );
612 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
614 pImp
->bPreparedForClose
= true;
618 // Ask if possible if it should be saved
619 // only ask for the Document in the visible window
620 SfxViewFrame
*pFrame
= SfxObjectShell::Current() == this
621 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
623 if ( bUI
&& IsModified() && pFrame
)
626 SfxFrame
& rTop
= pFrame
->GetTopFrame();
627 SfxViewFrame::SetViewFrame( rTop
.GetCurrentViewFrame() );
628 pFrame
->GetFrame().Appear();
631 short nRet
= RET_YES
;
633 const Reference
< XTitle
> xTitle( *pImp
->pBaseModel
.get(), UNO_QUERY_THROW
);
634 const OUString sTitle
= xTitle
->getTitle ();
635 nRet
= ExecuteQuerySaveDocument(&pFrame
->GetWindow(),sTitle
);
637 /*HACK for plugin::destroy()*/
639 if ( RET_YES
== nRet
)
641 // Save by each Dispatcher
642 const SfxPoolItem
*pPoolItem
;
643 if ( IsSaveVersionOnClose() )
645 SfxStringItem
aItem( SID_DOCINFO_COMMENTS
, SfxResId(STR_AUTOMATICVERSION
).toString() );
646 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
647 const SfxPoolItem
* ppArgs
[] = { &aItem
, &aWarnItem
, 0 };
648 pPoolItem
= pFrame
->GetBindings().ExecuteSynchron( SID_SAVEDOC
, ppArgs
);
652 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
653 const SfxPoolItem
* ppArgs
[] = { &aWarnItem
, 0 };
654 pPoolItem
= pFrame
->GetBindings().ExecuteSynchron( IsReadOnlyMedium() ? SID_SAVEASDOC
: SID_SAVEDOC
, ppArgs
);
657 if ( !pPoolItem
|| pPoolItem
->ISA(SfxVoidItem
) || ( pPoolItem
->ISA(SfxBoolItem
) && !static_cast<const SfxBoolItem
*>( pPoolItem
)->GetValue() ) )
660 else if ( RET_CANCEL
== nRet
)
665 pImp
->bPreparedForClose
= true;
670 #if HAVE_FEATURE_SCRIPTING
673 static BasicManager
* lcl_getBasicManagerForDocument( const SfxObjectShell
& _rDocument
)
675 if ( !_rDocument
.Get_Impl()->m_bNoBasicCapabilities
)
677 if ( !_rDocument
.Get_Impl()->bBasicInitialized
)
678 const_cast< SfxObjectShell
& >( _rDocument
).InitBasicManager_Impl();
679 return _rDocument
.Get_Impl()->aBasicManager
.get();
682 // assume we do not have Basic ourself, but we can refer to another
683 // document which does (by our model's XScriptInvocationContext::getScriptContainer).
684 // In this case, we return the BasicManager of this other document.
686 OSL_ENSURE( !Reference
< XEmbeddedScripts
>( _rDocument
.GetModel(), UNO_QUERY
).is(),
687 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
688 Reference
< XModel
> xForeignDocument
;
689 Reference
< XScriptInvocationContext
> xContext( _rDocument
.GetModel(), UNO_QUERY
);
692 xForeignDocument
.set( xContext
->getScriptContainer(), UNO_QUERY
);
693 OSL_ENSURE( xForeignDocument
.is() && xForeignDocument
!= _rDocument
.GetModel(),
694 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
697 BasicManager
* pBasMgr
= NULL
;
698 if ( xForeignDocument
.is() )
699 pBasMgr
= ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument
);
706 BasicManager
* SfxObjectShell::GetBasicManager() const
708 BasicManager
* pBasMgr
= NULL
;
709 #if HAVE_FEATURE_SCRIPTING
712 pBasMgr
= lcl_getBasicManagerForDocument( *this );
714 pBasMgr
= SfxApplication::GetBasicManager();
716 catch (const css::ucb::ContentCreationException
& e
)
718 SAL_WARN("sfx.doc", "caught exception " << e
.Message
);
724 void SfxObjectShell::SetHasNoBasic()
726 pImp
->m_bNoBasicCapabilities
= true;
729 bool SfxObjectShell::HasBasic() const
731 #if !HAVE_FEATURE_SCRIPTING
734 if ( pImp
->m_bNoBasicCapabilities
)
737 if ( !pImp
->bBasicInitialized
)
738 const_cast< SfxObjectShell
* >( this )->InitBasicManager_Impl();
740 return pImp
->aBasicManager
.isValid();
745 #if HAVE_FEATURE_SCRIPTING
748 const Reference
< XLibraryContainer
>&
749 lcl_getOrCreateLibraryContainer( bool _bScript
, Reference
< XLibraryContainer
>& _rxContainer
,
750 const Reference
< XModel
>& _rxDocument
)
752 if ( !_rxContainer
.is() )
756 Reference
< XStorageBasedDocument
> xStorageDoc( _rxDocument
, UNO_QUERY
);
757 const Reference
< XComponentContext
> xContext(
758 ::comphelper::getProcessComponentContext() );
759 _rxContainer
.set ( _bScript
760 ? DocumentScriptLibraryContainer::create(
761 xContext
, xStorageDoc
)
762 : DocumentDialogLibraryContainer::create(
763 xContext
, xStorageDoc
)
766 catch (const Exception
&)
768 DBG_UNHANDLED_EXCEPTION();
776 Reference
< XLibraryContainer
> SfxObjectShell::GetDialogContainer()
778 #if HAVE_FEATURE_SCRIPTING
781 if ( !pImp
->m_bNoBasicCapabilities
)
782 return lcl_getOrCreateLibraryContainer( false, pImp
->xDialogLibraries
, GetModel() );
784 BasicManager
* pBasMgr
= lcl_getBasicManagerForDocument( *this );
786 return pBasMgr
->GetDialogLibraryContainer().get();
788 catch (const css::ucb::ContentCreationException
& e
)
790 SAL_WARN("sfx.doc", "caught exception " << e
.Message
);
793 SAL_WARN("sfx.doc", "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?");
795 return SfxGetpApp()->GetDialogContainer();
798 Reference
< XLibraryContainer
> SfxObjectShell::GetBasicContainer()
800 #if HAVE_FEATURE_SCRIPTING
803 if ( !pImp
->m_bNoBasicCapabilities
)
804 return lcl_getOrCreateLibraryContainer( true, pImp
->xBasicLibraries
, GetModel() );
806 BasicManager
* pBasMgr
= lcl_getBasicManagerForDocument( *this );
808 return pBasMgr
->GetScriptLibraryContainer().get();
810 catch (const css::ucb::ContentCreationException
& e
)
812 SAL_WARN("sfx.doc", "caught exception " << e
.Message
);
814 SAL_WARN("sfx.doc", "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?");
816 return SfxGetpApp()->GetBasicContainer();
819 StarBASIC
* SfxObjectShell::GetBasic() const
821 #if !HAVE_FEATURE_SCRIPTING
824 BasicManager
* pMan
= GetBasicManager();
825 return pMan
? pMan
->GetLib(0) : NULL
;
829 void SfxObjectShell::InitBasicManager_Impl()
832 Creates a document's BasicManager and loads it, if we are already based on
837 This method has to be called by implementations of <SvPersist::Load()>
838 (with its pStor parameter) and by implementations of <SvPersist::InitNew()>
843 /* #163556# (DR) - Handling of recursive calls while creating the Bacic
846 It is possible that (while creating the Basic manager) the code that
847 imports the Basic storage wants to access the Basic manager again.
848 Especially in VBA compatibility mode, there is code that wants to
849 access the "VBA Globals" object which is stored as global UNO constant
850 in the Basic manager.
852 To achieve correct handling of the recursive calls of this function
853 from lcl_getBasicManagerForDocument(), the implementation of the
854 function BasicManagerRepository::getDocumentBasicManager() has been
855 changed to return the Basic manager currently under construction, when
858 The variable pImp->bBasicInitialized will be set to sal_True after
859 construction now, to ensure that the recursive call of the function
860 lcl_getBasicManagerForDocument() will be routed into this function too.
862 Calling BasicManagerHolder::reset() twice is not a big problem, as it
863 does not take ownership but stores only the raw pointer. Owner of all
864 Basic managers is the global BasicManagerRepository instance.
866 #if HAVE_FEATURE_SCRIPTING
867 DBG_ASSERT( !pImp
->bBasicInitialized
&& !pImp
->aBasicManager
.isValid(), "Lokaler BasicManager bereits vorhanden");
870 pImp
->aBasicManager
.reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
872 catch (const css::ucb::ContentCreationException
& e
)
874 SAL_WARN("sfx.doc", "caught exception " << e
.Message
);
876 DBG_ASSERT( pImp
->aBasicManager
.isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
877 pImp
->bBasicInitialized
= true;
883 bool SfxObjectShell::DoClose()
890 SfxObjectShell
* SfxObjectShell::GetObjectShell()
897 uno::Sequence
< OUString
> SfxObjectShell::GetEventNames()
899 static uno::Sequence
< OUString
>* pEventNameContainer
= NULL
;
901 if ( !pEventNameContainer
)
903 SolarMutexGuard aGuard
;
904 if ( !pEventNameContainer
)
906 static uno::Sequence
< OUString
> aEventNameContainer
= GlobalEventConfig().getElementNames();
907 pEventNameContainer
= &aEventNameContainer
;
911 return *pEventNameContainer
;
916 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XModel
> SfxObjectShell::GetModel() const
918 return GetBaseModel();
921 void SfxObjectShell::SetBaseModel( SfxBaseModel
* pModel
)
923 OSL_ENSURE( !pImp
->pBaseModel
.is() || pModel
== NULL
, "Model already set!" );
924 pImp
->pBaseModel
.set( pModel
);
925 if ( pImp
->pBaseModel
.is() )
927 pImp
->pBaseModel
->addCloseListener( new SfxModelListener_Impl(this) );
933 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XModel
> SfxObjectShell::GetBaseModel() const
935 return pImp
->pBaseModel
.get();
938 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet
)
940 pImp
->nStyleFilter
= nSet
;
943 sal_uInt16
SfxObjectShell::GetAutoStyleFilterIndex()
945 return pImp
->nStyleFilter
;
949 void SfxObjectShell::SetCurrentComponent( const Reference
< XInterface
>& _rxComponent
)
951 WeakReference
< XInterface
>& rTheCurrentComponent
= theCurrentComponent::get();
953 Reference
< XInterface
> xOldCurrentComp(rTheCurrentComponent
);
954 if ( _rxComponent
== xOldCurrentComp
)
957 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
958 // /required/ for "_rxComponent == s_xCurrentComponent.get()".
959 // In other words, it's still possible that we here do something which is not necessary,
960 // but we should have filtered quite some unnecessary calls already.
962 #if HAVE_FEATURE_SCRIPTING
963 BasicManager
* pAppMgr
= SfxApplication::GetBasicManager();
964 rTheCurrentComponent
= _rxComponent
;
967 // set "ThisComponent" for Basic
968 pAppMgr
->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent
) );
970 // set new current component for VBA compatibility
971 if ( _rxComponent
.is() )
973 OString aVBAConstName
= lclGetVBAGlobalConstName( _rxComponent
);
974 if ( !aVBAConstName
.isEmpty() )
976 pAppMgr
->SetGlobalUNOConstant( aVBAConstName
.getStr(), Any( _rxComponent
) );
977 s_aRegisteredVBAConstants
[ _rxComponent
.get() ] = aVBAConstName
;
980 // no new component passed -> remove last registered VBA component
981 else if ( xOldCurrentComp
.is() )
983 OString aVBAConstName
= lclGetVBAGlobalConstName( xOldCurrentComp
);
984 if ( !aVBAConstName
.isEmpty() )
986 pAppMgr
->SetGlobalUNOConstant( aVBAConstName
.getStr(), Any( Reference
< XInterface
>() ) );
987 s_aRegisteredVBAConstants
.erase( xOldCurrentComp
.get() );
994 Reference
< XInterface
> SfxObjectShell::GetCurrentComponent()
996 return theCurrentComponent::get();
1000 OUString
SfxObjectShell::GetServiceNameFromFactory( const OUString
& rFact
)
1002 //! Remove everything behind name!
1003 OUString
aFact( rFact
);
1004 OUString
aPrefix("private:factory/");
1005 if ( aFact
.startsWith( aPrefix
) )
1006 aFact
= aFact
.copy( aPrefix
.getLength() );
1007 sal_Int32 nPos
= aFact
.indexOf( '?' );
1011 aParam
= aFact
.copy( nPos
);
1012 aFact
= aFact
.copy( 0, nPos
);
1013 aParam
= aParam
.copy(1);
1015 aFact
= comphelper::string::remove(aFact
, '4');
1016 aFact
= aFact
.toAsciiLowerCase();
1018 // HACK: sometimes a real document service name is given here instead of
1019 // a factory short name. Set return value directly to this service name as fallback
1020 // in case next lines of code does nothing ...
1021 // use rFact instead of normed aFact value !
1022 OUString aServiceName
= rFact
;
1024 if ( aFact
== "swriter" )
1026 aServiceName
= "com.sun.star.text.TextDocument";
1028 else if ( aFact
== "sweb" || aFact
== "swriter/web" )
1030 aServiceName
= "com.sun.star.text.WebDocument";
1032 else if ( aFact
== "sglobal" || aFact
== "swriter/globaldocument" )
1034 aServiceName
= "com.sun.star.text.GlobalDocument";
1036 else if ( aFact
== "scalc" )
1038 aServiceName
= "com.sun.star.sheet.SpreadsheetDocument";
1040 else if ( aFact
== "sdraw" )
1042 aServiceName
= "com.sun.star.drawing.DrawingDocument";
1044 else if ( aFact
== "simpress" )
1046 aServiceName
= "com.sun.star.presentation.PresentationDocument";
1048 else if ( aFact
== "schart" )
1050 aServiceName
= "com.sun.star.chart.ChartDocument";
1052 else if ( aFact
== "smath" )
1054 aServiceName
= "com.sun.star.formula.FormulaProperties";
1056 #if HAVE_FEATURE_SCRIPTING
1057 else if ( aFact
== "sbasic" )
1059 aServiceName
= "com.sun.star.script.BasicIDE";
1062 #if HAVE_FEATURE_DBCONNECTIVITY
1063 else if ( aFact
== "sdatabase" )
1065 aServiceName
= "com.sun.star.sdb.OfficeDatabaseDocument";
1069 return aServiceName
;
1072 SfxObjectShell
* SfxObjectShell::CreateObjectByFactoryName( const OUString
& rFact
, SfxObjectCreateMode eMode
)
1074 return CreateObject( GetServiceNameFromFactory( rFact
), eMode
);
1078 SfxObjectShell
* SfxObjectShell::CreateObject( const OUString
& rServiceName
, SfxObjectCreateMode eCreateMode
)
1080 if ( !rServiceName
.isEmpty() )
1082 uno::Reference
< frame::XModel
> xDoc( ::comphelper::getProcessServiceFactory()->createInstance( rServiceName
), UNO_QUERY
);
1085 uno::Reference
< lang::XUnoTunnel
> xObj( xDoc
, UNO_QUERY
);
1086 uno::Sequence
< sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
1087 sal_Int64 nHandle
= xObj
->getSomething( aSeq
);
1090 SfxObjectShell
* pRet
= reinterpret_cast< SfxObjectShell
* >( sal::static_int_cast
< sal_IntPtr
>( nHandle
));
1091 pRet
->SetCreateMode_Impl( eCreateMode
);
1100 Reference
<lang::XComponent
> SfxObjectShell::CreateAndLoadComponent( const SfxItemSet
& rSet
, SfxFrame
* pFrame
)
1102 uno::Sequence
< beans::PropertyValue
> aProps
;
1103 TransformItems( SID_OPENDOC
, rSet
, aProps
);
1104 SFX_ITEMSET_ARG(&rSet
, pFileNameItem
, SfxStringItem
, SID_FILE_NAME
, false);
1105 SFX_ITEMSET_ARG(&rSet
, pTargetItem
, SfxStringItem
, SID_TARGETNAME
, false);
1107 OUString
aTarget("_blank");
1108 if ( pFileNameItem
)
1109 aURL
= pFileNameItem
->GetValue();
1111 aTarget
= pTargetItem
->GetValue();
1113 uno::Reference
< frame::XComponentLoader
> xLoader
;
1116 xLoader
= uno::Reference
< frame::XComponentLoader
>( pFrame
->GetFrameInterface(), uno::UNO_QUERY
);
1119 xLoader
= uno::Reference
< frame::XComponentLoader
>( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY
);
1121 Reference
<lang::XComponent
> xComp
;
1124 xComp
= xLoader
->loadComponentFromURL(aURL
, aTarget
, 0, aProps
);
1126 catch (const uno::Exception
&)
1133 SfxObjectShell
* SfxObjectShell::GetShellFromComponent( const Reference
<lang::XComponent
>& xComp
)
1137 Reference
<lang::XUnoTunnel
> xTunnel(xComp
, UNO_QUERY_THROW
);
1138 Sequence
<sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
1139 sal_Int64 nHandle
= xTunnel
->getSomething( aSeq
);
1143 return reinterpret_cast< SfxObjectShell
* >(sal::static_int_cast
< sal_IntPtr
>( nHandle
));
1145 catch (const Exception
&)
1152 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew
)
1154 pImp
->bInitialized
= true;
1155 if ( i_fromInitNew
)
1157 SetActivateEvent_Impl( SFX_EVENT_CREATEDOC
);
1158 SfxGetpApp()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED
, GlobalEventConfig::GetEventName(GlobalEventId::DOCCREATED
), this ) );
1162 SfxGetpApp()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED
, GlobalEventConfig::GetEventName(GlobalEventId::LOADFINISHED
), this ) );
1167 bool SfxObjectShell::IsChangeRecording() const
1169 // currently this function needs to be overwritten by Writer and Calc only
1170 DBG_ASSERT( false, "function not implemented" );
1175 bool SfxObjectShell::HasChangeRecordProtection() const
1177 // currently this function needs to be overwritten by Writer and Calc only
1178 DBG_ASSERT( false, "function not implemented" );
1183 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ )
1185 // currently this function needs to be overwritten by Writer and Calc only
1186 DBG_ASSERT( false, "function not implemented" );
1190 bool SfxObjectShell::SetProtectionPassword( const OUString
& /*rPassword*/ )
1192 // currently this function needs to be overwritten by Writer and Calc only
1193 DBG_ASSERT( false, "function not implemented" );
1198 bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence
< sal_Int8
> & /*rPasswordHash*/ )
1200 // currently this function needs to be overwritten by Writer and Calc only
1201 DBG_ASSERT( false, "function not implemented" );
1205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */