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>
21 #include <config_fuzzers.h>
25 #include <cppuhelper/implbase.hxx>
26 #include <cppuhelper/weakref.hxx>
28 #include <com/sun/star/util/XCloseable.hpp>
29 #include <com/sun/star/frame/XComponentLoader.hpp>
30 #include <com/sun/star/frame/Desktop.hpp>
31 #include <com/sun/star/util/XCloseListener.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/frame/XTitle.hpp>
34 #include <osl/file.hxx>
35 #include <sal/log.hxx>
36 #include <vcl/weld.hxx>
37 #include <vcl/svapp.hxx>
38 #include <svl/eitem.hxx>
39 #include <basic/sbstar.hxx>
40 #include <svl/stritem.hxx>
41 #include <unotools/configmgr.hxx>
42 #include <unotools/eventcfg.hxx>
44 #include <sfx2/objsh.hxx>
45 #include <sfx2/signaturestate.hxx>
46 #include <sfx2/sfxmodelfactory.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/servicehelper.hxx>
51 #include <com/sun/star/document/XStorageBasedDocument.hpp>
52 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
53 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
54 #include <com/sun/star/document/XEmbeddedScripts.hpp>
55 #include <com/sun/star/document/XScriptInvocationContext.hpp>
56 #include <com/sun/star/ucb/ContentCreationException.hpp>
57 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
59 #include <unotools/ucbhelper.hxx>
60 #include <tools/diagnose_ex.h>
61 #include <tools/globname.hxx>
62 #include <tools/debug.hxx>
64 #include <sfx2/app.hxx>
65 #include <sfx2/bindings.hxx>
66 #include <sfx2/docfile.hxx>
67 #include <sfx2/event.hxx>
68 #include <sfx2/viewsh.hxx>
69 #include <sfx2/viewfrm.hxx>
70 #include <sfx2/sfxresid.hxx>
71 #include <objshimp.hxx>
72 #include <sfx2/strings.hrc>
73 #include <sfx2/sfxsids.hrc>
74 #include <basic/basmgr.hxx>
75 #include <sfx2/QuerySaveDocument.hxx>
76 #include <appbaslib.hxx>
77 #include <sfx2/sfxbasemodel.hxx>
78 #include <sfx2/sfxuno.hxx>
79 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
80 #include <sfx2/infobar.hxx>
82 #include <basic/basicmanagerrepository.hxx>
84 using namespace ::com::sun::star
;
85 using namespace ::com::sun::star::uno
;
86 using namespace ::com::sun::star::script
;
87 using namespace ::com::sun::star::frame
;
88 using namespace ::com::sun::star::document
;
90 using ::basic::BasicManagerRepository
;
94 WeakReference
< XInterface
> theCurrentComponent
;
96 #if HAVE_FEATURE_SCRIPTING
98 // remember all registered components for VBA compatibility, to be able to remove them on disposing the model
99 typedef ::std::map
< XInterface
*, OUString
> VBAConstantNameMap
;
100 VBAConstantNameMap s_aRegisteredVBAConstants
;
102 OUString
lclGetVBAGlobalConstName( const Reference
< XInterface
>& rxComponent
)
104 OSL_ENSURE( rxComponent
.is(), "lclGetVBAGlobalConstName - missing component" );
106 VBAConstantNameMap::iterator aIt
= s_aRegisteredVBAConstants
.find( rxComponent
.get() );
107 if( aIt
!= s_aRegisteredVBAConstants
.end() )
110 uno::Reference
< beans::XPropertySet
> xProps( rxComponent
, uno::UNO_QUERY
);
111 if( xProps
.is() ) try
114 xProps
->getPropertyValue("VBAGlobalConstantName") >>= aConstName
;
117 catch (const uno::Exception
&) // not supported
125 class SfxModelListener_Impl
: public ::cppu::WeakImplHelper
< css::util::XCloseListener
>
127 SfxObjectShell
* mpDoc
;
129 explicit SfxModelListener_Impl( SfxObjectShell
* pDoc
) : mpDoc(pDoc
) {};
130 virtual void SAL_CALL
queryClosing( const css::lang::EventObject
& aEvent
, sal_Bool bDeliverOwnership
) override
;
131 virtual void SAL_CALL
notifyClosing( const css::lang::EventObject
& aEvent
) override
;
132 virtual void SAL_CALL
disposing( const css::lang::EventObject
& aEvent
) override
;
138 void SAL_CALL
SfxModelListener_Impl::queryClosing( const css::lang::EventObject
& , sal_Bool
)
142 void SAL_CALL
SfxModelListener_Impl::notifyClosing( const css::lang::EventObject
& )
144 SolarMutexGuard aSolarGuard
;
145 mpDoc
->Broadcast( SfxHint(SfxHintId::Deinitializing
) );
148 void SAL_CALL
SfxModelListener_Impl::disposing( const css::lang::EventObject
& _rEvent
)
150 // am I ThisComponent in AppBasic?
151 SolarMutexGuard aSolarGuard
;
152 if ( SfxObjectShell::GetCurrentComponent() == _rEvent
.Source
)
154 // remove ThisComponent reference from AppBasic
155 SfxObjectShell::SetCurrentComponent( Reference
< XInterface
>() );
158 #if HAVE_FEATURE_SCRIPTING
159 /* Remove VBA component from AppBasic. As every application registers its
160 own current component, the disposed component may not be the "current
161 component" of the SfxObjectShell. */
162 if ( _rEvent
.Source
.is() )
164 VBAConstantNameMap::iterator aIt
= s_aRegisteredVBAConstants
.find( _rEvent
.Source
.get() );
165 if ( aIt
!= s_aRegisteredVBAConstants
.end() )
167 if ( BasicManager
* pAppMgr
= SfxApplication::GetBasicManager() )
168 pAppMgr
->SetGlobalUNOConstant( aIt
->second
, Any( Reference
< XInterface
>() ) );
169 s_aRegisteredVBAConstants
.erase( aIt
);
174 if ( !mpDoc
->Get_Impl()->bClosing
)
175 // GCC crashes when already in the destructor, so first query the Flag
180 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell
& _rDocShell
)
181 :rDocShell( _rDocShell
)
184 ,nTime( DateTime::SYSTEM
)
185 ,nVisualDocumentNumber( USHRT_MAX
)
186 ,nDocumentSignatureState( SignatureState::UNKNOWN
)
187 ,nScriptingSignatureState( SignatureState::UNKNOWN
)
190 ,bIsNamedVisible( false)
191 ,bIsAbortingImport ( false)
192 ,bInPrepareClose( false )
193 ,bPreparedForClose( false )
194 ,bForbidReload( false )
195 ,bBasicInitialized( false )
196 ,bIsPrintJobCancelable( true )
197 ,bOwnsStorage( true )
198 ,bInitialized( false )
199 ,bModelInitialized( false )
200 ,bPreserveVersions( true )
201 ,m_bMacroSignBroken( false )
202 ,m_bNoBasicCapabilities( false )
203 ,m_bDocRecoverySupport( true )
204 ,bQueryLoadTemplate( true )
205 ,bLoadReadonly( false )
206 ,bUseUserData( true )
207 ,bUseThumbnailSave( true )
208 ,bSaveVersionOnClose( false )
209 ,m_bSharedXMLFlag( false )
210 ,m_bAllowShareControlFileClean( true )
211 ,m_bConfigOptionsChecked( false )
212 ,m_bMacroCallsSeenWhileLoading( false )
214 ,nEventId ( SfxEventHintId::NONE
)
215 ,nLoadedFlags ( SfxLoadedFlags::ALL
)
216 ,nFlagsInProgress( SfxLoadedFlags::NONE
)
218 ,bRunningMacro( false )
219 ,bReadOnlyUI( false )
221 ,m_bEnableSetModified( true )
222 ,m_bIsModified( false )
223 ,m_nMapUnit( MapUnit::Map100thMM
)
224 ,m_bCreateTempStor( false )
226 ,m_bIncomplEncrWarnShown( false )
227 ,m_nModifyPasswordHash( 0 )
228 ,m_bModifyPasswordEntered( false )
229 ,m_bSavingForSigning( false )
230 ,m_bAllowModifiedBackAfterSigning( false )
232 SfxObjectShell
* pDoc
= &_rDocShell
;
233 std::vector
<SfxObjectShell
*> &rArr
= SfxGetpApp()->GetObjectShells_Impl();
234 rArr
.push_back( pDoc
);
238 SfxObjectShell_Impl::~SfxObjectShell_Impl()
243 SfxObjectShell::SfxObjectShell( const SfxModelFlags i_nCreationFlags
)
244 : pImpl(new SfxObjectShell_Impl(*this))
246 , eCreateMode(SfxObjectCreateMode::STANDARD
)
248 , bIsInGenerateThumbnail (false)
249 , mbAvoidRecentDocs(false)
251 if (i_nCreationFlags
& SfxModelFlags::EMBEDDED_OBJECT
)
252 eCreateMode
= SfxObjectCreateMode::EMBEDDED
;
253 else if (i_nCreationFlags
& SfxModelFlags::EXTERNAL_LINK
)
254 eCreateMode
= SfxObjectCreateMode::INTERNAL
;
256 const bool bScriptSupport
= ( i_nCreationFlags
& SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
) == SfxModelFlags::NONE
;
257 if ( !bScriptSupport
)
258 pImpl
->m_bNoBasicCapabilities
= true;
260 const bool bDocRecovery
= ( i_nCreationFlags
& SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
) == SfxModelFlags::NONE
;
262 pImpl
->m_bDocRecoverySupport
= false;
265 /** Constructor of the class SfxObjectShell.
267 @param eMode Purpose, to which the SfxObjectShell is created:
268 SfxObjectCreateMode::EMBEDDED (default) as SO-Server from within another Document
269 SfxObjectCreateMode::STANDARD, as a normal Document open stand-alone
270 SfxObjectCreateMode::ORGANIZER to be displayed in the Organizer, here nothing of the contents is used
272 SfxObjectShell::SfxObjectShell(SfxObjectCreateMode eMode
)
273 : pImpl(new SfxObjectShell_Impl(*this))
277 , bIsInGenerateThumbnail(false)
278 , mbAvoidRecentDocs(false)
282 SfxObjectShell::~SfxObjectShell()
285 if ( IsEnableSetModified() )
286 EnableSetModified( false );
288 SfxObjectShell::CloseInternal();
289 pImpl
->pBaseModel
.set( nullptr );
291 pImpl
->pReloadTimer
.reset();
293 SfxApplication
*pSfxApp
= SfxGetpApp();
294 if ( USHRT_MAX
!= pImpl
->nVisualDocumentNumber
&& pSfxApp
)
295 pSfxApp
->ReleaseIndex(pImpl
->nVisualDocumentNumber
);
297 // Destroy Basic-Manager
298 pImpl
->aBasicManager
.reset(nullptr);
300 if ( pSfxApp
&& pSfxApp
->GetDdeService() )
301 pSfxApp
->RemoveDdeTopic( this );
303 pImpl
->pBaseModel
.set( nullptr );
305 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
306 if ( pMedium
&& pMedium
->HasStorage_Impl() && pMedium
->GetStorage( false ) == pImpl
->m_xDocStorage
)
307 pMedium
->CanDisposeStorage_Impl( false );
309 if ( pImpl
->mxObjectContainer
)
311 pImpl
->mxObjectContainer
->CloseEmbeddedObjects();
312 pImpl
->mxObjectContainer
.reset();
315 if ( pImpl
->bOwnsStorage
&& pImpl
->m_xDocStorage
.is() )
316 pImpl
->m_xDocStorage
->dispose();
320 pMedium
->CloseAndReleaseStreams_Impl();
322 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
324 FreeSharedFile( pMedium
->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
330 // The removing of the temporary file must be done as the latest step in the document destruction
331 if ( !pImpl
->aTempName
.isEmpty() )
334 osl::FileBase::getFileURLFromSystemPath( pImpl
->aTempName
, aTmp
);
335 ::utl::UCBContentHelper::Kill( aTmp
);
340 void SfxObjectShell::Stamp_SetPrintCancelState(bool bState
)
342 pImpl
->bIsPrintJobCancelable
= bState
;
346 bool SfxObjectShell::Stamp_GetPrintCancelState() const
348 return pImpl
->bIsPrintJobCancelable
;
352 // closes the Object and all its views
354 bool SfxObjectShell::Close()
356 SfxObjectShellRef
xKeepAlive(this);
357 return CloseInternal();
360 // variant that does not take a reference to itself, so we can call it during object destruction
361 bool SfxObjectShell::CloseInternal()
363 if ( !pImpl
->bClosing
)
365 // Do not close if a progress is still running
369 pImpl
->bClosing
= true;
370 Reference
< util::XCloseable
> xCloseable( GetBaseModel(), UNO_QUERY
);
372 if ( xCloseable
.is() )
376 xCloseable
->close( true );
378 catch (const Exception
&)
380 pImpl
->bClosing
= false;
384 if ( pImpl
->bClosing
)
386 // remove from Document list
387 // If there is no App, there is no document to remove
388 // no need to call GetOrCreate here
389 SfxApplication
*pSfxApp
= SfxApplication::Get();
392 std::vector
<SfxObjectShell
*> &rDocs
= pSfxApp
->GetObjectShells_Impl();
393 auto it
= std::find( rDocs
.begin(), rDocs
.end(), this );
394 if ( it
!= rDocs
.end() )
403 OUString
SfxObjectShell::CreateShellID( const SfxObjectShell
* pShell
)
410 SfxMedium
* pMedium
= pShell
->GetMedium();
412 aShellID
= pMedium
->GetBaseURL();
414 if (!aShellID
.isEmpty())
417 sal_Int64 nShellID
= reinterpret_cast<sal_Int64
>(pShell
);
418 aShellID
= "0x" + OUString::number(nShellID
, 16);
422 // returns a pointer the first SfxDocument of specified type
424 SfxObjectShell
* SfxObjectShell::GetFirst
426 const std::function
<bool ( const SfxObjectShell
* )>& isObjectShell
,
430 std::vector
<SfxObjectShell
*> &rDocs
= SfxGetpApp()->GetObjectShells_Impl();
432 // search for a SfxDocument of the specified type
433 for (SfxObjectShell
* pSh
: rDocs
)
435 if ( bOnlyVisible
&& pSh
->IsPreview() && pSh
->IsReadOnly() )
438 if ( (!isObjectShell
|| isObjectShell( pSh
)) &&
439 ( !bOnlyVisible
|| SfxViewFrame::GetFirst( pSh
)))
447 // returns a pointer to the next SfxDocument of specified type behind *pDoc
449 SfxObjectShell
* SfxObjectShell::GetNext
451 const SfxObjectShell
& rPrev
,
452 const std::function
<bool ( const SfxObjectShell
* )>& isObjectShell
,
456 std::vector
<SfxObjectShell
*> &rDocs
= SfxGetpApp()->GetObjectShells_Impl();
458 // refind the specified predecessor
460 for ( nPos
= 0; nPos
< rDocs
.size(); ++nPos
)
461 if ( rDocs
[nPos
] == &rPrev
)
464 // search for the next SfxDocument of the specified type
465 for ( ++nPos
; nPos
< rDocs
.size(); ++nPos
)
467 SfxObjectShell
* pSh
= rDocs
[ nPos
];
468 if ( bOnlyVisible
&& pSh
->IsPreview() && pSh
->IsReadOnly() )
471 if ( (!isObjectShell
|| isObjectShell( pSh
)) &&
472 ( !bOnlyVisible
|| SfxViewFrame::GetFirst( pSh
)))
479 SfxObjectShell
* SfxObjectShell::Current()
481 SfxViewFrame
*pFrame
= SfxViewFrame::Current();
482 return pFrame
? pFrame
->GetObjectShell() : nullptr;
486 bool SfxObjectShell::IsInPrepareClose() const
488 return pImpl
->bInPrepareClose
;
495 SfxObjectShell_Impl
& rImpl
;
496 explicit BoolEnv_Impl( SfxObjectShell_Impl
& rImplP
) : rImpl( rImplP
)
497 { rImplP
.bInPrepareClose
= true; }
498 ~BoolEnv_Impl() { rImpl
.bInPrepareClose
= false; }
503 bool SfxObjectShell::PrepareClose
505 bool bUI
// true: Dialog and so on is allowed
506 // false: silent-mode
509 if( pImpl
->bInPrepareClose
|| pImpl
->bPreparedForClose
)
511 BoolEnv_Impl
aBoolEnv( *pImpl
);
514 if ( IsInModalMode() )
517 SfxViewFrame
* pFirst
= SfxViewFrame::GetFirst( this );
518 if( pFirst
&& !pFirst
->GetFrame().PrepareClose_Impl( bUI
) )
521 // prepare views for closing
522 for ( SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
523 pFrm
; pFrm
= SfxViewFrame::GetNext( *pFrm
, this ) )
525 DBG_ASSERT(pFrm
->GetViewShell(),"No Shell");
526 if ( pFrm
->GetViewShell() )
528 bool bRet
= pFrm
->GetViewShell()->PrepareClose( bUI
);
534 SfxApplication
*pSfxApp
= SfxGetpApp();
535 pSfxApp
->NotifyEvent( SfxEventHint(SfxEventHintId::PrepareCloseDoc
, GlobalEventConfig::GetEventName(GlobalEventId::PREPARECLOSEDOC
), this) );
537 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
539 pImpl
->bPreparedForClose
= true;
543 // Ask if possible if it should be saved
544 // only ask for the Document in the visible window
545 SfxViewFrame
*pFrame
= SfxObjectShell::Current() == this
546 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
548 if ( bUI
&& IsModified() && pFrame
)
551 SfxFrame
& rTop
= pFrame
->GetFrame();
552 SfxViewFrame::SetViewFrame( rTop
.GetCurrentViewFrame() );
553 pFrame
->GetFrame().Appear();
556 short nRet
= RET_YES
;
558 const Reference
<XTitle
> xTitle(*pImpl
->pBaseModel
, UNO_QUERY_THROW
);
559 const OUString sTitle
= xTitle
->getTitle ();
560 nRet
= ExecuteQuerySaveDocument(pFrame
->GetFrameWeld(), sTitle
);
562 /*HACK for plugin::destroy()*/
564 if ( RET_YES
== nRet
)
566 // Save by each Dispatcher
567 const SfxPoolItem
*pPoolItem
;
568 if ( IsSaveVersionOnClose() )
570 SfxStringItem
aItem( SID_DOCINFO_COMMENTS
, SfxResId(STR_AUTOMATICVERSION
) );
571 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
572 const SfxPoolItem
* ppArgs
[] = { &aItem
, &aWarnItem
, nullptr };
573 pPoolItem
= pFrame
->GetBindings().ExecuteSynchron( SID_SAVEDOC
, ppArgs
);
577 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
578 const SfxPoolItem
* ppArgs
[] = { &aWarnItem
, nullptr };
579 pPoolItem
= pFrame
->GetBindings().ExecuteSynchron( SID_SAVEDOC
, ppArgs
);
582 if ( !pPoolItem
|| pPoolItem
->IsVoidItem() )
584 if ( auto pBoolItem
= dynamic_cast< const SfxBoolItem
*>( pPoolItem
) )
585 if ( !pBoolItem
->GetValue() )
588 else if ( RET_CANCEL
== nRet
)
594 sfx2::SfxNotebookBar::CloseMethod(pFrame
->GetBindings());
595 pImpl
->bPreparedForClose
= true;
600 #if HAVE_FEATURE_SCRIPTING
603 BasicManager
* lcl_getBasicManagerForDocument( const SfxObjectShell
& _rDocument
)
605 if ( !_rDocument
.Get_Impl()->m_bNoBasicCapabilities
)
607 if ( !_rDocument
.Get_Impl()->bBasicInitialized
)
608 const_cast< SfxObjectShell
& >( _rDocument
).InitBasicManager_Impl();
609 return _rDocument
.Get_Impl()->aBasicManager
.get();
612 // assume we do not have Basic ourself, but we can refer to another
613 // document which does (by our model's XScriptInvocationContext::getScriptContainer).
614 // In this case, we return the BasicManager of this other document.
616 OSL_ENSURE( !Reference
< XEmbeddedScripts
>( _rDocument
.GetModel(), UNO_QUERY
).is(),
617 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
618 Reference
< XModel
> xForeignDocument
;
619 Reference
< XScriptInvocationContext
> xContext( _rDocument
.GetModel(), UNO_QUERY
);
622 xForeignDocument
.set( xContext
->getScriptContainer(), UNO_QUERY
);
623 OSL_ENSURE( xForeignDocument
.is() && xForeignDocument
!= _rDocument
.GetModel(),
624 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
627 BasicManager
* pBasMgr
= nullptr;
628 if ( xForeignDocument
.is() )
629 pBasMgr
= ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument
);
636 BasicManager
* SfxObjectShell::GetBasicManager() const
638 BasicManager
* pBasMgr
= nullptr;
639 #if HAVE_FEATURE_SCRIPTING
642 pBasMgr
= lcl_getBasicManagerForDocument( *this );
644 pBasMgr
= SfxApplication::GetBasicManager();
646 catch (const css::ucb::ContentCreationException
&)
648 TOOLS_WARN_EXCEPTION("sfx.doc", "");
654 bool SfxObjectShell::HasBasic() const
656 #if !HAVE_FEATURE_SCRIPTING
659 if ( pImpl
->m_bNoBasicCapabilities
)
662 if ( !pImpl
->bBasicInitialized
)
663 const_cast< SfxObjectShell
* >( this )->InitBasicManager_Impl();
665 return pImpl
->aBasicManager
.isValid();
670 #if HAVE_FEATURE_SCRIPTING
673 const Reference
< XLibraryContainer
>&
674 lcl_getOrCreateLibraryContainer( bool _bScript
, Reference
< XLibraryContainer
>& _rxContainer
,
675 const Reference
< XModel
>& _rxDocument
)
677 if ( !_rxContainer
.is() )
681 Reference
< XStorageBasedDocument
> xStorageDoc( _rxDocument
, UNO_QUERY
);
682 const Reference
< XComponentContext
> xContext(
683 ::comphelper::getProcessComponentContext() );
684 _rxContainer
.set ( _bScript
685 ? DocumentScriptLibraryContainer::create(
686 xContext
, xStorageDoc
)
687 : DocumentDialogLibraryContainer::create(
688 xContext
, xStorageDoc
)
691 catch (const Exception
&)
693 DBG_UNHANDLED_EXCEPTION("sfx.doc");
701 Reference
< XLibraryContainer
> SfxObjectShell::GetDialogContainer()
703 #if HAVE_FEATURE_SCRIPTING
706 if ( !pImpl
->m_bNoBasicCapabilities
)
707 return lcl_getOrCreateLibraryContainer( false, pImpl
->xDialogLibraries
, GetModel() );
709 BasicManager
* pBasMgr
= lcl_getBasicManagerForDocument( *this );
711 return pBasMgr
->GetDialogLibraryContainer();
713 catch (const css::ucb::ContentCreationException
&)
715 TOOLS_WARN_EXCEPTION("sfx.doc", "");
718 SAL_WARN("sfx.doc", "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?");
720 return SfxGetpApp()->GetDialogContainer();
723 Reference
< XLibraryContainer
> SfxObjectShell::GetBasicContainer()
725 #if HAVE_FEATURE_SCRIPTING
726 if (!utl::ConfigManager::IsFuzzing())
730 if ( !pImpl
->m_bNoBasicCapabilities
)
731 return lcl_getOrCreateLibraryContainer( true, pImpl
->xBasicLibraries
, GetModel() );
733 BasicManager
* pBasMgr
= lcl_getBasicManagerForDocument( *this );
735 return pBasMgr
->GetScriptLibraryContainer();
737 catch (const css::ucb::ContentCreationException
&)
739 TOOLS_WARN_EXCEPTION("sfx.doc", "");
742 SAL_WARN("sfx.doc", "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?");
744 return SfxGetpApp()->GetBasicContainer();
747 StarBASIC
* SfxObjectShell::GetBasic() const
749 #if !HAVE_FEATURE_SCRIPTING
752 BasicManager
* pMan
= GetBasicManager();
753 return pMan
? pMan
->GetLib(0) : nullptr;
757 void SfxObjectShell::InitBasicManager_Impl()
760 Creates a document's BasicManager and loads it, if we are already based on
765 This method has to be called by implementations of <SvPersist::Load()>
766 (with its pStor parameter) and by implementations of <SvPersist::InitNew()>
771 /* #163556# (DR) - Handling of recursive calls while creating the Basic
774 It is possible that (while creating the Basic manager) the code that
775 imports the Basic storage wants to access the Basic manager again.
776 Especially in VBA compatibility mode, there is code that wants to
777 access the "VBA Globals" object which is stored as global UNO constant
778 in the Basic manager.
780 To achieve correct handling of the recursive calls of this function
781 from lcl_getBasicManagerForDocument(), the implementation of the
782 function BasicManagerRepository::getDocumentBasicManager() has been
783 changed to return the Basic manager currently under construction, when
786 The variable pImpl->bBasicInitialized will be set to sal_True after
787 construction now, to ensure that the recursive call of the function
788 lcl_getBasicManagerForDocument() will be routed into this function too.
790 Calling BasicManagerHolder::reset() twice is not a big problem, as it
791 does not take ownership but stores only the raw pointer. Owner of all
792 Basic managers is the global BasicManagerRepository instance.
794 #if HAVE_FEATURE_SCRIPTING
795 DBG_ASSERT( !pImpl
->bBasicInitialized
&& !pImpl
->aBasicManager
.isValid(), "Local BasicManager already exists");
798 pImpl
->aBasicManager
.reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
800 catch (const css::ucb::ContentCreationException
&)
802 TOOLS_WARN_EXCEPTION("sfx.doc", "");
804 DBG_ASSERT( pImpl
->aBasicManager
.isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
805 pImpl
->bBasicInitialized
= true;
810 bool SfxObjectShell::DoClose()
816 SfxObjectShell
* SfxObjectShell::GetObjectShell()
822 uno::Sequence
< OUString
> SfxObjectShell::GetEventNames()
824 static uno::Sequence
< OUString
> s_EventNameContainer(rtl::Reference
<GlobalEventConfig
>(new GlobalEventConfig
)->getElementNames());
826 return s_EventNameContainer
;
830 css::uno::Reference
< css::frame::XModel3
> SfxObjectShell::GetModel() const
832 return GetBaseModel();
835 void SfxObjectShell::SetBaseModel( SfxBaseModel
* pModel
)
837 OSL_ENSURE( !pImpl
->pBaseModel
.is() || pModel
== nullptr, "Model already set!" );
838 pImpl
->pBaseModel
.set( pModel
);
839 if ( pImpl
->pBaseModel
.is() )
841 pImpl
->pBaseModel
->addCloseListener( new SfxModelListener_Impl(this) );
846 css::uno::Reference
< css::frame::XModel3
> SfxObjectShell::GetBaseModel() const
848 return pImpl
->pBaseModel
;
851 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet
)
853 pImpl
->nStyleFilter
= nSet
;
856 sal_uInt16
SfxObjectShell::GetAutoStyleFilterIndex() const
858 return pImpl
->nStyleFilter
;
862 void SfxObjectShell::SetCurrentComponent( const Reference
< XInterface
>& _rxComponent
)
864 WeakReference
< XInterface
>& rTheCurrentComponent
= theCurrentComponent
;
866 Reference
< XInterface
> xOldCurrentComp(rTheCurrentComponent
);
867 if ( _rxComponent
== xOldCurrentComp
)
870 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
871 // /required/ for "_rxComponent == s_xCurrentComponent.get()".
872 // In other words, it's still possible that we here do something which is not necessary,
873 // but we should have filtered quite some unnecessary calls already.
875 #if HAVE_FEATURE_SCRIPTING
876 BasicManager
* pAppMgr
= SfxApplication::GetBasicManager();
877 rTheCurrentComponent
= _rxComponent
;
881 // set "ThisComponent" for Basic
882 pAppMgr
->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent
) );
884 // set new current component for VBA compatibility
885 if ( _rxComponent
.is() )
887 OUString aVBAConstName
= lclGetVBAGlobalConstName( _rxComponent
);
888 if ( !aVBAConstName
.isEmpty() )
890 pAppMgr
->SetGlobalUNOConstant( aVBAConstName
, Any( _rxComponent
) );
891 s_aRegisteredVBAConstants
[ _rxComponent
.get() ] = aVBAConstName
;
894 // no new component passed -> remove last registered VBA component
895 else if ( xOldCurrentComp
.is() )
897 OUString aVBAConstName
= lclGetVBAGlobalConstName( xOldCurrentComp
);
898 if ( !aVBAConstName
.isEmpty() )
900 pAppMgr
->SetGlobalUNOConstant( aVBAConstName
, Any( Reference
< XInterface
>() ) );
901 s_aRegisteredVBAConstants
.erase( xOldCurrentComp
.get() );
907 Reference
< XInterface
> SfxObjectShell::GetCurrentComponent()
909 return theCurrentComponent
;
913 OUString
SfxObjectShell::GetServiceNameFromFactory( const OUString
& rFact
)
915 //! Remove everything behind name!
916 OUString
aFact( rFact
);
917 OUString
aPrefix("private:factory/");
918 if ( aFact
.startsWith( aPrefix
) )
919 aFact
= aFact
.copy( aPrefix
.getLength() );
920 sal_Int32 nPos
= aFact
.indexOf( '?' );
923 aFact
= aFact
.copy( 0, nPos
);
925 aFact
= aFact
.replaceAll("4", "");
926 aFact
= aFact
.toAsciiLowerCase();
928 // HACK: sometimes a real document service name is given here instead of
929 // a factory short name. Set return value directly to this service name as fallback
930 // in case next lines of code does nothing ...
931 // use rFact instead of normed aFact value !
932 OUString aServiceName
= rFact
;
934 if ( aFact
== "swriter" )
936 aServiceName
= "com.sun.star.text.TextDocument";
938 else if ( aFact
== "sweb" || aFact
== "swriter/web" )
940 aServiceName
= "com.sun.star.text.WebDocument";
942 else if ( aFact
== "sglobal" || aFact
== "swriter/globaldocument" )
944 aServiceName
= "com.sun.star.text.GlobalDocument";
946 else if ( aFact
== "scalc" )
948 aServiceName
= "com.sun.star.sheet.SpreadsheetDocument";
950 else if ( aFact
== "sdraw" )
952 aServiceName
= "com.sun.star.drawing.DrawingDocument";
954 else if ( aFact
== "simpress" )
956 aServiceName
= "com.sun.star.presentation.PresentationDocument";
958 else if ( aFact
== "schart" )
960 aServiceName
= "com.sun.star.chart.ChartDocument";
962 else if ( aFact
== "smath" )
964 aServiceName
= "com.sun.star.formula.FormulaProperties";
966 #if HAVE_FEATURE_SCRIPTING
967 else if ( aFact
== "sbasic" )
969 aServiceName
= "com.sun.star.script.BasicIDE";
972 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
973 else if ( aFact
== "sdatabase" )
975 aServiceName
= "com.sun.star.sdb.OfficeDatabaseDocument";
982 SfxObjectShell
* SfxObjectShell::CreateObjectByFactoryName( const OUString
& rFact
, SfxObjectCreateMode eMode
)
984 return CreateObject( GetServiceNameFromFactory( rFact
), eMode
);
988 SfxObjectShell
* SfxObjectShell::CreateObject( const OUString
& rServiceName
, SfxObjectCreateMode eCreateMode
)
990 if ( !rServiceName
.isEmpty() )
992 uno::Reference
< frame::XModel
> xDoc( ::comphelper::getProcessServiceFactory()->createInstance( rServiceName
), UNO_QUERY
);
993 if (SfxObjectShell
* pRet
= SfxObjectShell::GetShellFromComponent(xDoc
))
995 pRet
->SetCreateMode_Impl(eCreateMode
);
1003 Reference
<lang::XComponent
> SfxObjectShell::CreateAndLoadComponent( const SfxItemSet
& rSet
)
1005 uno::Sequence
< beans::PropertyValue
> aProps
;
1006 TransformItems( SID_OPENDOC
, rSet
, aProps
);
1007 const SfxStringItem
* pFileNameItem
= rSet
.GetItem
<SfxStringItem
>(SID_FILE_NAME
, false);
1008 const SfxStringItem
* pTargetItem
= rSet
.GetItem
<SfxStringItem
>(SID_TARGETNAME
, false);
1010 OUString
aTarget("_blank");
1011 if ( pFileNameItem
)
1012 aURL
= pFileNameItem
->GetValue();
1014 aTarget
= pTargetItem
->GetValue();
1016 uno::Reference
< frame::XComponentLoader
> xLoader
=
1017 frame::Desktop::create(comphelper::getProcessComponentContext());
1019 Reference
<lang::XComponent
> xComp
;
1022 xComp
= xLoader
->loadComponentFromURL(aURL
, aTarget
, 0, aProps
);
1024 catch (const uno::Exception
&)
1031 SfxObjectShell
* SfxObjectShell::GetShellFromComponent(const Reference
<uno::XInterface
>& xComp
)
1035 Reference
<lang::XUnoTunnel
> xTunnel(xComp
, UNO_QUERY_THROW
);
1036 Sequence
<sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
1037 return comphelper::getSomething_cast
<SfxObjectShell
>(xTunnel
->getSomething(aSeq
));
1039 catch (const Exception
&)
1046 SfxObjectShell
* SfxObjectShell::GetParentShell(const css::uno::Reference
<css::uno::XInterface
>& xChild
)
1048 SfxObjectShell
* pResult
= nullptr;
1052 if (css::uno::Reference
<css::container::XChild
> xChildModel
{ xChild
, css::uno::UNO_QUERY
})
1053 pResult
= GetShellFromComponent(xChildModel
->getParent());
1055 catch (const Exception
&)
1062 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew
)
1064 pImpl
->bInitialized
= true;
1065 if (utl::ConfigManager::IsFuzzing())
1067 if ( i_fromInitNew
)
1069 SetActivateEvent_Impl( SfxEventHintId::CreateDoc
);
1070 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::DocCreated
, GlobalEventConfig::GetEventName(GlobalEventId::DOCCREATED
), this ) );
1074 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::LoadFinished
, GlobalEventConfig::GetEventName(GlobalEventId::LOADFINISHED
), this ) );
1079 bool SfxObjectShell::IsChangeRecording() const
1081 // currently this function needs to be overwritten by Writer and Calc only
1082 SAL_WARN( "sfx.doc", "function not implemented" );
1087 bool SfxObjectShell::HasChangeRecordProtection() const
1089 // currently this function needs to be overwritten by Writer and Calc only
1090 SAL_WARN( "sfx.doc", "function not implemented" );
1095 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/, bool /*bLockAllViews*/ )
1097 // currently this function needs to be overwritten by Writer and Calc only
1098 SAL_WARN( "sfx.doc", "function not implemented" );
1102 void SfxObjectShell::SetProtectionPassword( const OUString
& /*rPassword*/ )
1104 // currently this function needs to be overwritten by Writer and Calc only
1105 SAL_WARN( "sfx.doc", "function not implemented" );
1109 bool SfxObjectShell::GetProtectionHash( /*out*/ css::uno::Sequence
< sal_Int8
> & /*rPasswordHash*/ )
1111 // currently this function needs to be overwritten by Writer and Calc only
1112 SAL_WARN( "sfx.doc", "function not implemented" );
1116 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */