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/CloseVetoException.hpp>
32 #include <com/sun/star/util/XCloseListener.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/frame/XTitle.hpp>
35 #include <osl/file.hxx>
36 #include <sal/log.hxx>
37 #include <vcl/weld.hxx>
38 #include <vcl/svapp.hxx>
39 #include <svl/eitem.hxx>
40 #include <basic/sbstar.hxx>
41 #include <svl/stritem.hxx>
42 #include <unotools/configmgr.hxx>
43 #include <unotools/eventcfg.hxx>
45 #include <sfx2/objsh.hxx>
46 #include <sfx2/signaturestate.hxx>
47 #include <sfx2/sfxmodelfactory.hxx>
49 #include <comphelper/configuration.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/servicehelper.hxx>
53 #include <com/sun/star/document/XStorageBasedDocument.hpp>
54 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
55 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
56 #include <com/sun/star/document/XEmbeddedScripts.hpp>
57 #include <com/sun/star/document/XScriptInvocationContext.hpp>
58 #include <com/sun/star/ucb/ContentCreationException.hpp>
59 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
61 #include <unotools/ucbhelper.hxx>
62 #include <comphelper/diagnose_ex.hxx>
63 #include <tools/globname.hxx>
64 #include <tools/debug.hxx>
66 #include <sfx2/app.hxx>
67 #include <sfx2/bindings.hxx>
68 #include <sfx2/docfile.hxx>
69 #include <sfx2/event.hxx>
70 #include <sfx2/viewsh.hxx>
71 #include <sfx2/viewfrm.hxx>
72 #include <sfx2/sfxresid.hxx>
73 #include <objshimp.hxx>
74 #include <sfx2/strings.hrc>
75 #include <sfx2/sfxsids.hrc>
76 #include <basic/basmgr.hxx>
77 #include <sfx2/QuerySaveDocument.hxx>
78 #include <appbaslib.hxx>
79 #include <sfx2/sfxbasemodel.hxx>
80 #include <sfx2/sfxuno.hxx>
81 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
82 #include <sfx2/infobar.hxx>
83 #include <svtools/svparser.hxx>
85 #include <basic/basicmanagerrepository.hxx>
87 using namespace ::com::sun::star
;
88 using namespace ::com::sun::star::uno
;
89 using namespace ::com::sun::star::script
;
90 using namespace ::com::sun::star::frame
;
91 using namespace ::com::sun::star::document
;
93 using ::basic::BasicManagerRepository
;
97 WeakReference
< XInterface
> theCurrentComponent
;
99 #if HAVE_FEATURE_SCRIPTING
101 // remember all registered components for VBA compatibility, to be able to remove them on disposing the model
102 typedef ::std::map
< XInterface
*, OUString
> VBAConstantNameMap
;
103 VBAConstantNameMap s_aRegisteredVBAConstants
;
105 OUString
lclGetVBAGlobalConstName( const Reference
< XInterface
>& rxComponent
)
107 OSL_ENSURE( rxComponent
.is(), "lclGetVBAGlobalConstName - missing component" );
109 VBAConstantNameMap::iterator aIt
= s_aRegisteredVBAConstants
.find( rxComponent
.get() );
110 if( aIt
!= s_aRegisteredVBAConstants
.end() )
113 uno::Reference
< beans::XPropertySet
> xProps( rxComponent
, uno::UNO_QUERY
);
114 if( xProps
.is() ) try
117 xProps
->getPropertyValue(u
"VBAGlobalConstantName"_ustr
) >>= aConstName
;
120 catch (const uno::Exception
&) // not supported
128 class SfxModelListener_Impl
: public ::cppu::WeakImplHelper
< css::util::XCloseListener
>
130 SfxObjectShell
* mpDoc
;
132 explicit SfxModelListener_Impl( SfxObjectShell
* pDoc
) : mpDoc(pDoc
) {};
133 virtual void SAL_CALL
queryClosing( const css::lang::EventObject
& aEvent
, sal_Bool bDeliverOwnership
) override
;
134 virtual void SAL_CALL
notifyClosing( const css::lang::EventObject
& aEvent
) override
;
135 virtual void SAL_CALL
disposing( const css::lang::EventObject
& aEvent
) override
;
141 void SAL_CALL
SfxModelListener_Impl::queryClosing( const css::lang::EventObject
& , sal_Bool bDeliverOwnership
)
143 if (mpDoc
->Get_Impl()->m_nClosingLockLevel
)
145 if (bDeliverOwnership
)
146 mpDoc
->Get_Impl()->m_bCloseModelScheduled
= true;
147 throw util::CloseVetoException(u
"Closing document is blocked"_ustr
, getXWeak());
151 void SAL_CALL
SfxModelListener_Impl::notifyClosing( const css::lang::EventObject
& )
153 SolarMutexGuard aSolarGuard
;
154 mpDoc
->Broadcast( SfxHint(SfxHintId::Deinitializing
) );
157 void SAL_CALL
SfxModelListener_Impl::disposing( const css::lang::EventObject
& _rEvent
)
159 // am I ThisComponent in AppBasic?
160 SolarMutexGuard aSolarGuard
;
161 if ( SfxObjectShell::GetCurrentComponent() == _rEvent
.Source
)
163 // remove ThisComponent reference from AppBasic
164 SfxObjectShell::SetCurrentComponent( Reference
< XInterface
>() );
167 #if HAVE_FEATURE_SCRIPTING
168 /* Remove VBA component from AppBasic. As every application registers its
169 own current component, the disposed component may not be the "current
170 component" of the SfxObjectShell. */
171 if ( _rEvent
.Source
.is() )
173 VBAConstantNameMap::iterator aIt
= s_aRegisteredVBAConstants
.find( _rEvent
.Source
.get() );
174 if ( aIt
!= s_aRegisteredVBAConstants
.end() )
176 if ( BasicManager
* pAppMgr
= SfxApplication::GetBasicManager() )
177 pAppMgr
->SetGlobalUNOConstant( aIt
->second
, Any( Reference
< XInterface
>() ) );
178 s_aRegisteredVBAConstants
.erase( aIt
);
183 if ( !mpDoc
->Get_Impl()->bClosing
)
184 // GCC crashes when already in the destructor, so first query the Flag
189 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell
& _rDocShell
)
190 :rDocShell( _rDocShell
)
193 ,nTime( DateTime::SYSTEM
)
194 ,nVisualDocumentNumber( USHRT_MAX
)
195 ,nDocumentSignatureState( SignatureState::UNKNOWN
)
196 ,nScriptingSignatureState( SignatureState::UNKNOWN
)
199 ,bIsNamedVisible( false)
200 ,bIsAbortingImport ( false)
201 ,bInPrepareClose( false )
202 ,bPreparedForClose( false )
203 ,bForbidReload( false )
204 ,bBasicInitialized( false )
205 ,bIsPrintJobCancelable( true )
206 ,bOwnsStorage( true )
207 ,bInitialized( false )
208 ,bModelInitialized( false )
209 ,bPreserveVersions( true )
210 ,m_bMacroSignBroken( false )
211 ,m_bNoBasicCapabilities( false )
212 ,m_bDocRecoverySupport( true )
213 ,bQueryLoadTemplate( true )
214 ,bLoadReadonly( false )
215 ,bUseUserData( true )
216 ,bUseThumbnailSave( true )
217 ,bSaveVersionOnClose( false )
218 ,m_bSharedXMLFlag( false )
219 ,m_bAllowShareControlFileClean( true )
220 ,m_bConfigOptionsChecked( false )
221 ,m_bMacroCallsSeenWhileLoading( false )
222 ,m_bHadCheckedMacrosOnLoad( false )
224 ,nEventId ( SfxEventHintId::NONE
)
225 ,nLoadedFlags ( SfxLoadedFlags::ALL
)
226 ,nFlagsInProgress( SfxLoadedFlags::NONE
)
228 ,bRunningMacro( false )
229 ,bReadOnlyUI( false )
231 ,m_bEnableSetModified( true )
232 ,m_bIsModified( false )
233 ,m_nMapUnit( MapUnit::Map100thMM
)
234 ,m_bCreateTempStor( false )
236 ,m_bIncomplEncrWarnShown( false )
237 ,m_nModifyPasswordHash( 0 )
238 ,m_bModifyPasswordEntered( false )
239 ,m_bSavingForSigning( false )
240 ,m_bAllowModifiedBackAfterSigning( false )
242 SfxObjectShell
* pDoc
= &_rDocShell
;
243 std::vector
<SfxObjectShell
*> &rArr
= SfxGetpApp()->GetObjectShells_Impl();
244 rArr
.push_back( pDoc
);
248 SfxObjectShell_Impl::~SfxObjectShell_Impl()
253 SfxObjectShell::SfxObjectShell( const SfxModelFlags i_nCreationFlags
)
254 : pImpl(new SfxObjectShell_Impl(*this))
256 , eCreateMode(SfxObjectCreateMode::STANDARD
)
258 , bIsInGenerateThumbnail (false)
259 , mbAvoidRecentDocs(false)
260 , bRememberSignature(false)
262 if (i_nCreationFlags
& SfxModelFlags::EMBEDDED_OBJECT
)
263 eCreateMode
= SfxObjectCreateMode::EMBEDDED
;
264 else if (i_nCreationFlags
& SfxModelFlags::EXTERNAL_LINK
)
265 eCreateMode
= SfxObjectCreateMode::INTERNAL
;
267 const bool bScriptSupport
= ( i_nCreationFlags
& SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
) == SfxModelFlags::NONE
;
268 if ( !bScriptSupport
)
269 pImpl
->m_bNoBasicCapabilities
= true;
271 const bool bDocRecovery
= ( i_nCreationFlags
& SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
) == SfxModelFlags::NONE
;
273 pImpl
->m_bDocRecoverySupport
= false;
276 /** Constructor of the class SfxObjectShell.
278 @param eMode Purpose, to which the SfxObjectShell is created:
279 SfxObjectCreateMode::EMBEDDED (default) as SO-Server from within another Document
280 SfxObjectCreateMode::STANDARD, as a normal Document open stand-alone
281 SfxObjectCreateMode::ORGANIZER to be displayed in the Organizer, here nothing of the contents is used
283 SfxObjectShell::SfxObjectShell(SfxObjectCreateMode eMode
)
284 : pImpl(new SfxObjectShell_Impl(*this))
288 , bIsInGenerateThumbnail(false)
289 , mbAvoidRecentDocs(false)
290 , bRememberSignature(false)
294 SfxObjectShell::~SfxObjectShell()
297 if ( IsEnableSetModified() )
298 EnableSetModified( false );
300 SfxObjectShell::CloseInternal();
301 pImpl
->pBaseModel
.clear();
303 pImpl
->pReloadTimer
.reset();
305 SfxApplication
*pSfxApp
= SfxGetpApp();
306 if ( USHRT_MAX
!= pImpl
->nVisualDocumentNumber
&& pSfxApp
)
307 pSfxApp
->ReleaseIndex(pImpl
->nVisualDocumentNumber
);
309 // Destroy Basic-Manager
310 pImpl
->aBasicManager
.reset(nullptr);
312 if ( pSfxApp
&& pSfxApp
->GetDdeService() )
313 pSfxApp
->RemoveDdeTopic( this );
315 InternalCloseAndRemoveFiles();
318 void SfxObjectShell::InternalCloseAndRemoveFiles()
320 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
321 if ( pMedium
&& pMedium
->HasStorage_Impl() && pMedium
->GetStorage( false ) == pImpl
->m_xDocStorage
)
322 pMedium
->CanDisposeStorage_Impl( false );
324 if ( pImpl
->mxObjectContainer
)
326 pImpl
->mxObjectContainer
->CloseEmbeddedObjects();
327 pImpl
->mxObjectContainer
.reset();
330 if ( pImpl
->bOwnsStorage
&& pImpl
->m_xDocStorage
.is() )
331 pImpl
->m_xDocStorage
->dispose();
335 pMedium
->CloseAndReleaseStreams_Impl();
337 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
339 FreeSharedFile( pMedium
->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
345 // The removing of the temporary file must be done as the latest step in the document destruction
346 if ( !pImpl
->aTempName
.isEmpty() )
349 osl::FileBase::getFileURLFromSystemPath( pImpl
->aTempName
, aTmp
);
350 ::utl::UCBContentHelper::Kill( aTmp
);
354 SfxCloseVetoLock::SfxCloseVetoLock(const SfxObjectShell
* pDocShell
)
355 : mpDocShell(pDocShell
)
358 osl_atomic_increment(&mpDocShell
->Get_Impl()->m_nClosingLockLevel
);
361 SfxCloseVetoLock::~SfxCloseVetoLock()
363 if (mpDocShell
&& osl_atomic_decrement(&mpDocShell
->Get_Impl()->m_nClosingLockLevel
) == 0)
365 if (mpDocShell
->Get_Impl()->m_bCloseModelScheduled
)
367 mpDocShell
->Get_Impl()->m_bCloseModelScheduled
= false; // pass ownership
368 if (rtl::Reference model
= static_cast<SfxBaseModel
*>(mpDocShell
->GetBaseModel().get()))
374 catch (const util::CloseVetoException
&)
376 DBG_UNHANDLED_EXCEPTION("sfx.doc");
383 void SfxObjectShell::Stamp_SetPrintCancelState(bool bState
)
385 pImpl
->bIsPrintJobCancelable
= bState
;
389 bool SfxObjectShell::Stamp_GetPrintCancelState() const
391 return pImpl
->bIsPrintJobCancelable
;
395 // closes the Object and all its views
397 bool SfxObjectShell::Close()
399 SfxObjectShellRef
xKeepAlive(this);
400 return CloseInternal();
403 // variant that does not take a reference to itself, so we can call it during object destruction
404 bool SfxObjectShell::CloseInternal()
406 if ( !pImpl
->bClosing
)
408 // Do not close if a progress is still running
412 pImpl
->bClosing
= true;
413 Reference
< util::XCloseable
> xCloseable( GetBaseModel(), UNO_QUERY
);
415 if ( xCloseable
.is() )
419 xCloseable
->close( true );
421 catch (const Exception
&)
423 pImpl
->bClosing
= false;
427 if ( pImpl
->bClosing
)
429 // remove from Document list
430 // If there is no App, there is no document to remove
431 // no need to call GetOrCreate here
432 SfxApplication
*pSfxApp
= SfxApplication::Get();
435 std::vector
<SfxObjectShell
*> &rDocs
= pSfxApp
->GetObjectShells_Impl();
436 auto it
= std::find( rDocs
.begin(), rDocs
.end(), this );
437 if ( it
!= rDocs
.end() )
446 OUString
SfxObjectShell::CreateShellID( const SfxObjectShell
* pShell
)
453 SfxMedium
* pMedium
= pShell
->GetMedium();
455 aShellID
= pMedium
->GetBaseURL();
457 if (!aShellID
.isEmpty())
460 sal_Int64 nShellID
= reinterpret_cast<sal_Int64
>(pShell
);
461 aShellID
= "0x" + OUString::number(nShellID
, 16);
465 // returns a pointer the first SfxDocument of specified type
467 SfxObjectShell
* SfxObjectShell::GetFirst
469 const std::function
<bool ( const SfxObjectShell
* )>& isObjectShell
,
473 std::vector
<SfxObjectShell
*> &rDocs
= SfxGetpApp()->GetObjectShells_Impl();
475 // search for a SfxDocument of the specified type
476 for (SfxObjectShell
* pSh
: rDocs
)
478 if ( bOnlyVisible
&& pSh
->IsPreview() && pSh
->IsReadOnly() )
481 if ( (!isObjectShell
|| isObjectShell( pSh
)) &&
482 ( !bOnlyVisible
|| SfxViewFrame::GetFirst( pSh
)))
490 // returns a pointer to the next SfxDocument of specified type behind *pDoc
492 SfxObjectShell
* SfxObjectShell::GetNext
494 const SfxObjectShell
& rPrev
,
495 const std::function
<bool ( const SfxObjectShell
* )>& isObjectShell
,
499 std::vector
<SfxObjectShell
*> &rDocs
= SfxGetpApp()->GetObjectShells_Impl();
501 // refind the specified predecessor
503 for ( nPos
= 0; nPos
< rDocs
.size(); ++nPos
)
504 if ( rDocs
[nPos
] == &rPrev
)
507 // search for the next SfxDocument of the specified type
508 for ( ++nPos
; nPos
< rDocs
.size(); ++nPos
)
510 SfxObjectShell
* pSh
= rDocs
[ nPos
];
511 if ( bOnlyVisible
&& pSh
->IsPreview() && pSh
->IsReadOnly() )
514 if ( (!isObjectShell
|| isObjectShell( pSh
)) &&
515 ( !bOnlyVisible
|| SfxViewFrame::GetFirst( pSh
)))
521 SfxObjectShell
* SfxObjectShell::Current()
523 SfxViewFrame
*pFrame
= SfxViewFrame::Current();
524 return pFrame
? pFrame
->GetObjectShell() : nullptr;
527 bool SfxObjectShell::IsInPrepareClose() const
529 return pImpl
->bInPrepareClose
;
536 SfxObjectShell_Impl
& rImpl
;
537 explicit BoolEnv_Impl( SfxObjectShell_Impl
& rImplP
) : rImpl( rImplP
)
538 { rImplP
.bInPrepareClose
= true; }
539 ~BoolEnv_Impl() { rImpl
.bInPrepareClose
= false; }
544 bool SfxObjectShell::PrepareClose
546 bool bUI
// true: Dialog and so on is allowed
547 // false: silent-mode
550 if( pImpl
->bInPrepareClose
|| pImpl
->bPreparedForClose
)
552 BoolEnv_Impl
aBoolEnv( *pImpl
);
555 if ( IsInModalMode() )
558 SfxViewFrame
* pFirst
= SfxViewFrame::GetFirst( this );
559 if( pFirst
&& !pFirst
->GetFrame().PrepareClose_Impl( bUI
) )
562 // prepare views for closing
563 for ( SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
564 pFrm
; pFrm
= SfxViewFrame::GetNext( *pFrm
, this ) )
566 DBG_ASSERT(pFrm
->GetViewShell(),"No Shell");
567 if ( pFrm
->GetViewShell() )
569 bool bRet
= pFrm
->GetViewShell()->PrepareClose( bUI
);
575 SfxApplication
*pSfxApp
= SfxGetpApp();
576 pSfxApp
->NotifyEvent( SfxEventHint(SfxEventHintId::PrepareCloseDoc
, GlobalEventConfig::GetEventName(GlobalEventId::PREPARECLOSEDOC
), this) );
578 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
580 pImpl
->bPreparedForClose
= true;
584 // Ask if possible if it should be saved
585 // only ask for the Document in the visible window
586 SfxViewFrame
*pFrame
= SfxObjectShell::Current() == this
587 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
589 if ( bUI
&& IsModified() && pFrame
)
592 SfxFrame
& rTop
= pFrame
->GetFrame();
593 SfxViewFrame::SetViewFrame( rTop
.GetCurrentViewFrame() );
594 pFrame
->GetFrame().Appear();
597 short nRet
= RET_YES
;
599 const Reference
<XTitle
> xTitle(*pImpl
->pBaseModel
, UNO_QUERY_THROW
);
600 const OUString sTitle
= xTitle
->getTitle ();
601 nRet
= ExecuteQuerySaveDocument(pFrame
->GetFrameWeld(), sTitle
);
603 /*HACK for plugin::destroy()*/
605 if ( RET_YES
== nRet
)
607 // Save by each Dispatcher
608 SfxPoolItemHolder aPoolItem
;
611 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
612 const SfxPoolItem
* ppArgs
[] = { &aWarnItem
, nullptr };
613 aPoolItem
= pFrame
->GetBindings().ExecuteSynchron(SID_SAVEASDOC
, ppArgs
);
615 else if (IsSaveVersionOnClose())
617 SfxStringItem
aItem( SID_DOCINFO_COMMENTS
, SfxResId(STR_AUTOMATICVERSION
) );
618 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
619 const SfxPoolItem
* ppArgs
[] = { &aItem
, &aWarnItem
, nullptr };
620 aPoolItem
= pFrame
->GetBindings().ExecuteSynchron( SID_SAVEDOC
, ppArgs
);
624 SfxBoolItem
aWarnItem( SID_FAIL_ON_WARNING
, bUI
);
625 const SfxPoolItem
* ppArgs
[] = { &aWarnItem
, nullptr };
626 aPoolItem
= pFrame
->GetBindings().ExecuteSynchron( SID_SAVEDOC
, ppArgs
);
629 if (!aPoolItem
|| IsDisabledItem(aPoolItem
.getItem()) )
631 if ( auto pBoolItem
= dynamic_cast< const SfxBoolItem
*>( aPoolItem
.getItem() ) )
632 if ( !pBoolItem
->GetValue() )
635 else if ( RET_CANCEL
== nRet
)
641 sfx2::SfxNotebookBar::CloseMethod(pFrame
->GetBindings());
642 pImpl
->bPreparedForClose
= true;
647 #if HAVE_FEATURE_SCRIPTING
650 BasicManager
* lcl_getBasicManagerForDocument( const SfxObjectShell
& _rDocument
)
652 if ( !_rDocument
.Get_Impl()->m_bNoBasicCapabilities
)
654 if ( !_rDocument
.Get_Impl()->bBasicInitialized
)
655 const_cast< SfxObjectShell
& >( _rDocument
).InitBasicManager_Impl();
656 return _rDocument
.Get_Impl()->aBasicManager
.get();
659 // assume we do not have Basic ourself, but we can refer to another
660 // document which does (by our model's XScriptInvocationContext::getScriptContainer).
661 // In this case, we return the BasicManager of this other document.
663 OSL_ENSURE( !Reference
< XEmbeddedScripts
>( _rDocument
.GetModel(), UNO_QUERY
).is(),
664 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
665 Reference
< XModel
> xForeignDocument
;
666 Reference
< XScriptInvocationContext
> xContext( _rDocument
.GetModel(), UNO_QUERY
);
669 xForeignDocument
.set( xContext
->getScriptContainer(), UNO_QUERY
);
670 OSL_ENSURE( xForeignDocument
.is() && xForeignDocument
!= _rDocument
.GetModel(),
671 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
674 BasicManager
* pBasMgr
= nullptr;
675 if ( xForeignDocument
.is() )
676 pBasMgr
= ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument
);
683 BasicManager
* SfxObjectShell::GetBasicManager() const
685 BasicManager
* pBasMgr
= nullptr;
686 #if HAVE_FEATURE_SCRIPTING
689 pBasMgr
= lcl_getBasicManagerForDocument( *this );
691 pBasMgr
= SfxApplication::GetBasicManager();
693 catch (const css::ucb::ContentCreationException
&)
695 TOOLS_WARN_EXCEPTION("sfx.doc", "");
701 bool SfxObjectShell::HasBasic() const
703 #if !HAVE_FEATURE_SCRIPTING
706 if ( pImpl
->m_bNoBasicCapabilities
)
709 if ( !pImpl
->bBasicInitialized
)
710 const_cast< SfxObjectShell
* >( this )->InitBasicManager_Impl();
712 return pImpl
->aBasicManager
.isValid();
717 #if HAVE_FEATURE_SCRIPTING
720 const Reference
< XLibraryContainer
>&
721 lcl_getOrCreateLibraryContainer( bool _bScript
, Reference
< XLibraryContainer
>& _rxContainer
,
722 const Reference
< XModel
>& _rxDocument
)
724 if ( !_rxContainer
.is() )
728 Reference
< XStorageBasedDocument
> xStorageDoc( _rxDocument
, UNO_QUERY
);
729 const Reference
< XComponentContext
>& xContext(
730 ::comphelper::getProcessComponentContext() );
731 _rxContainer
.set ( _bScript
732 ? DocumentScriptLibraryContainer::create(
733 xContext
, xStorageDoc
)
734 : DocumentDialogLibraryContainer::create(
735 xContext
, xStorageDoc
)
738 catch (const Exception
&)
740 DBG_UNHANDLED_EXCEPTION("sfx.doc");
748 Reference
< XLibraryContainer
> SfxObjectShell::GetDialogContainer()
750 #if HAVE_FEATURE_SCRIPTING
753 if ( !pImpl
->m_bNoBasicCapabilities
)
754 return lcl_getOrCreateLibraryContainer( false, pImpl
->xDialogLibraries
, GetModel() );
756 BasicManager
* pBasMgr
= lcl_getBasicManagerForDocument( *this );
758 return pBasMgr
->GetDialogLibraryContainer();
760 catch (const css::ucb::ContentCreationException
&)
762 TOOLS_WARN_EXCEPTION("sfx.doc", "");
765 SAL_WARN("sfx.doc", "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?");
767 return SfxGetpApp()->GetDialogContainer();
770 Reference
< XLibraryContainer
> SfxObjectShell::GetBasicContainer()
772 #if HAVE_FEATURE_SCRIPTING
773 if (!comphelper::IsFuzzing())
777 if ( !pImpl
->m_bNoBasicCapabilities
)
778 return lcl_getOrCreateLibraryContainer( true, pImpl
->xBasicLibraries
, GetModel() );
780 BasicManager
* pBasMgr
= lcl_getBasicManagerForDocument( *this );
782 return pBasMgr
->GetScriptLibraryContainer();
784 catch (const css::ucb::ContentCreationException
&)
786 TOOLS_WARN_EXCEPTION("sfx.doc", "");
789 SAL_WARN("sfx.doc", "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?");
791 return SfxGetpApp()->GetBasicContainer();
794 StarBASIC
* SfxObjectShell::GetBasic() const
796 #if !HAVE_FEATURE_SCRIPTING
799 BasicManager
* pMan
= GetBasicManager();
800 return pMan
? pMan
->GetLib(0) : nullptr;
804 void SfxObjectShell::InitBasicManager_Impl()
807 Creates a document's BasicManager and loads it, if we are already based on
812 This method has to be called by implementations of <SvPersist::Load()>
813 (with its pStor parameter) and by implementations of <SvPersist::InitNew()>
818 /* #163556# (DR) - Handling of recursive calls while creating the Basic
821 It is possible that (while creating the Basic manager) the code that
822 imports the Basic storage wants to access the Basic manager again.
823 Especially in VBA compatibility mode, there is code that wants to
824 access the "VBA Globals" object which is stored as global UNO constant
825 in the Basic manager.
827 To achieve correct handling of the recursive calls of this function
828 from lcl_getBasicManagerForDocument(), the implementation of the
829 function BasicManagerRepository::getDocumentBasicManager() has been
830 changed to return the Basic manager currently under construction, when
833 The variable pImpl->bBasicInitialized will be set to sal_True after
834 construction now, to ensure that the recursive call of the function
835 lcl_getBasicManagerForDocument() will be routed into this function too.
837 Calling BasicManagerHolder::reset() twice is not a big problem, as it
838 does not take ownership but stores only the raw pointer. Owner of all
839 Basic managers is the global BasicManagerRepository instance.
841 #if HAVE_FEATURE_SCRIPTING
842 DBG_ASSERT( !pImpl
->bBasicInitialized
&& !pImpl
->aBasicManager
.isValid(), "Local BasicManager already exists");
845 pImpl
->aBasicManager
.reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
847 catch (const css::ucb::ContentCreationException
&)
849 TOOLS_WARN_EXCEPTION("sfx.doc", "");
851 DBG_ASSERT( pImpl
->aBasicManager
.isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
852 pImpl
->bBasicInitialized
= true;
857 bool SfxObjectShell::DoClose()
863 SfxObjectShell
* SfxObjectShell::GetObjectShell()
869 uno::Sequence
< OUString
> SfxObjectShell::GetEventNames()
871 static uno::Sequence
< OUString
> s_EventNameContainer(rtl::Reference
<GlobalEventConfig
>(new GlobalEventConfig
)->getElementNames());
873 return s_EventNameContainer
;
877 css::uno::Reference
< css::frame::XModel3
> SfxObjectShell::GetModel() const
879 return GetBaseModel();
882 void SfxObjectShell::SetBaseModel( SfxBaseModel
* pModel
)
884 OSL_ENSURE( !pImpl
->pBaseModel
.is() || pModel
== nullptr, "Model already set!" );
885 pImpl
->pBaseModel
.set( pModel
);
886 if ( pImpl
->pBaseModel
.is() )
888 pImpl
->pBaseModel
->addCloseListener( new SfxModelListener_Impl(this) );
893 css::uno::Reference
< css::frame::XModel3
> SfxObjectShell::GetBaseModel() const
895 return pImpl
->pBaseModel
;
898 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet
)
900 pImpl
->nStyleFilter
= nSet
;
903 sal_uInt16
SfxObjectShell::GetAutoStyleFilterIndex() const
905 return pImpl
->nStyleFilter
;
909 void SfxObjectShell::SetCurrentComponent( const Reference
< XInterface
>& _rxComponent
)
911 WeakReference
< XInterface
>& rTheCurrentComponent
= theCurrentComponent
;
913 Reference
< XInterface
> xOldCurrentComp(rTheCurrentComponent
);
914 if ( _rxComponent
== xOldCurrentComp
)
917 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
918 // /required/ for "_rxComponent == s_xCurrentComponent.get()".
919 // In other words, it's still possible that we here do something which is not necessary,
920 // but we should have filtered quite some unnecessary calls already.
922 #if HAVE_FEATURE_SCRIPTING
923 BasicManager
* pAppMgr
= SfxApplication::GetBasicManager();
924 rTheCurrentComponent
= _rxComponent
;
928 // set "ThisComponent" for Basic
929 pAppMgr
->SetGlobalUNOConstant( u
"ThisComponent"_ustr
, Any( _rxComponent
) );
931 // set new current component for VBA compatibility
932 if ( _rxComponent
.is() )
934 OUString aVBAConstName
= lclGetVBAGlobalConstName( _rxComponent
);
935 if ( !aVBAConstName
.isEmpty() )
937 pAppMgr
->SetGlobalUNOConstant( aVBAConstName
, Any( _rxComponent
) );
938 s_aRegisteredVBAConstants
[ _rxComponent
.get() ] = aVBAConstName
;
941 // no new component passed -> remove last registered VBA component
942 else if ( xOldCurrentComp
.is() )
944 OUString aVBAConstName
= lclGetVBAGlobalConstName( xOldCurrentComp
);
945 if ( !aVBAConstName
.isEmpty() )
947 pAppMgr
->SetGlobalUNOConstant( aVBAConstName
, Any( Reference
< XInterface
>() ) );
948 s_aRegisteredVBAConstants
.erase( xOldCurrentComp
.get() );
954 Reference
< XInterface
> SfxObjectShell::GetCurrentComponent()
956 return theCurrentComponent
;
960 OUString
SfxObjectShell::GetServiceNameFromFactory( const OUString
& rFact
)
962 //! Remove everything behind name!
963 OUString
aFact( rFact
);
964 OUString
aPrefix(u
"private:factory/"_ustr
);
965 if ( aFact
.startsWith( aPrefix
) )
966 aFact
= aFact
.copy( aPrefix
.getLength() );
967 sal_Int32 nPos
= aFact
.indexOf( '?' );
970 aFact
= aFact
.copy( 0, nPos
);
972 aFact
= aFact
.replaceAll("4", "");
973 aFact
= aFact
.toAsciiLowerCase();
975 // HACK: sometimes a real document service name is given here instead of
976 // a factory short name. Set return value directly to this service name as fallback
977 // in case next lines of code does nothing ...
978 // use rFact instead of normed aFact value !
979 OUString aServiceName
= rFact
;
981 if ( aFact
== "swriter" )
983 aServiceName
= "com.sun.star.text.TextDocument";
985 else if ( aFact
== "sweb" || aFact
== "swriter/web" )
987 aServiceName
= "com.sun.star.text.WebDocument";
989 else if ( aFact
== "sglobal" || aFact
== "swriter/globaldocument" )
991 aServiceName
= "com.sun.star.text.GlobalDocument";
993 else if ( aFact
== "scalc" )
995 aServiceName
= "com.sun.star.sheet.SpreadsheetDocument";
997 else if ( aFact
== "sdraw" )
999 aServiceName
= "com.sun.star.drawing.DrawingDocument";
1001 else if ( aFact
== "simpress" )
1003 aServiceName
= "com.sun.star.presentation.PresentationDocument";
1005 else if ( aFact
== "schart" )
1007 aServiceName
= "com.sun.star.chart.ChartDocument";
1009 else if ( aFact
== "smath" )
1011 aServiceName
= "com.sun.star.formula.FormulaProperties";
1013 #if HAVE_FEATURE_SCRIPTING
1014 else if ( aFact
== "sbasic" )
1016 aServiceName
= "com.sun.star.script.BasicIDE";
1019 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1020 else if ( aFact
== "sdatabase" )
1022 aServiceName
= "com.sun.star.sdb.OfficeDatabaseDocument";
1026 return aServiceName
;
1029 SfxObjectShell
* SfxObjectShell::CreateObjectByFactoryName( const OUString
& rFact
, SfxObjectCreateMode eMode
)
1031 return CreateObject( GetServiceNameFromFactory( rFact
), eMode
);
1035 SfxObjectShell
* SfxObjectShell::CreateObject( const OUString
& rServiceName
, SfxObjectCreateMode eCreateMode
)
1037 if ( !rServiceName
.isEmpty() )
1039 uno::Reference
< frame::XModel
> xDoc( ::comphelper::getProcessServiceFactory()->createInstance( rServiceName
), UNO_QUERY
);
1040 if (SfxObjectShell
* pRet
= SfxObjectShell::GetShellFromComponent(xDoc
))
1042 pRet
->SetCreateMode_Impl(eCreateMode
);
1050 Reference
<lang::XComponent
> SfxObjectShell::CreateAndLoadComponent( const SfxItemSet
& rSet
)
1052 uno::Sequence
< beans::PropertyValue
> aProps
;
1053 TransformItems( SID_OPENDOC
, rSet
, aProps
);
1054 const SfxStringItem
* pFileNameItem
= rSet
.GetItem
<SfxStringItem
>(SID_FILE_NAME
, false);
1055 const SfxStringItem
* pTargetItem
= rSet
.GetItem
<SfxStringItem
>(SID_TARGETNAME
, false);
1057 OUString
aTarget(u
"_blank"_ustr
);
1058 if ( pFileNameItem
)
1059 aURL
= pFileNameItem
->GetValue();
1061 aTarget
= pTargetItem
->GetValue();
1063 uno::Reference
< frame::XComponentLoader
> xLoader
=
1064 frame::Desktop::create(comphelper::getProcessComponentContext());
1066 Reference
<lang::XComponent
> xComp
;
1069 xComp
= xLoader
->loadComponentFromURL(aURL
, aTarget
, 0, aProps
);
1071 catch (const uno::Exception
&)
1078 SfxObjectShell
* SfxObjectShell::GetShellFromComponent(const Reference
<uno::XInterface
>& xComp
)
1082 Reference
<lang::XUnoTunnel
> xTunnel(xComp
, UNO_QUERY
);
1085 static const Sequence
<sal_Int8
> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence() );
1086 return comphelper::getSomething_cast
<SfxObjectShell
>(xTunnel
->getSomething(aSeq
));
1088 catch (const Exception
&)
1095 SfxObjectShell
* SfxObjectShell::GetParentShell(const css::uno::Reference
<css::uno::XInterface
>& xChild
)
1097 SfxObjectShell
* pResult
= nullptr;
1101 if (css::uno::Reference
<css::container::XChild
> xChildModel
{ xChild
, css::uno::UNO_QUERY
})
1102 pResult
= GetShellFromComponent(xChildModel
->getParent());
1104 catch (const Exception
&)
1111 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew
)
1113 pImpl
->bInitialized
= true;
1114 if (comphelper::IsFuzzing())
1116 if ( i_fromInitNew
)
1118 SetActivateEvent_Impl( SfxEventHintId::CreateDoc
);
1119 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::DocCreated
, GlobalEventConfig::GetEventName(GlobalEventId::DOCCREATED
), this ) );
1123 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::LoadFinished
, GlobalEventConfig::GetEventName(GlobalEventId::LOADFINISHED
), this ) );
1128 bool SfxObjectShell::IsChangeRecording() const
1130 // currently this function needs to be overwritten by Writer and Calc only
1131 SAL_WARN( "sfx.doc", "function not implemented" );
1136 bool SfxObjectShell::HasChangeRecordProtection() const
1138 // currently this function needs to be overwritten by Writer and Calc only
1139 SAL_WARN( "sfx.doc", "function not implemented" );
1144 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/, bool /*bLockAllViews*/ )
1146 // currently this function needs to be overwritten by Writer and Calc only
1147 SAL_WARN( "sfx.doc", "function not implemented" );
1151 void SfxObjectShell::SetProtectionPassword( const OUString
& /*rPassword*/ )
1153 // currently this function needs to be overwritten by Writer and Calc only
1154 SAL_WARN( "sfx.doc", "function not implemented" );
1158 bool SfxObjectShell::GetProtectionHash( /*out*/ css::uno::Sequence
< sal_Int8
> & /*rPasswordHash*/ )
1160 // currently this function needs to be overwritten by Writer and Calc only
1161 SAL_WARN( "sfx.doc", "function not implemented" );
1165 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */