/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// remember all registered components for VBA compatibility, to be able to remove them on disposing the model typedef ::std::map< XInterface*, OUString > VBAConstantNameMap;
VBAConstantNameMap s_aRegisteredVBAConstants;
void SAL_CALL SfxModelListener_Impl::disposing( const css::lang::EventObject& _rEvent )
{ // am I ThisComponent in AppBasic?
SolarMutexGuard aSolarGuard; if ( SfxObjectShell::GetCurrentComponent() == _rEvent.Source )
{ // remove ThisComponent reference from AppBasic
SfxObjectShell::SetCurrentComponent( Reference< XInterface >() );
}
#if HAVE_FEATURE_SCRIPTING /* Remove VBA component from AppBasic. As every application registers its own current component, the disposed component may not be the "current
component" of the SfxObjectShell. */ if ( _rEvent.Source.is() )
{
VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( _rEvent.Source.get() ); if ( aIt != s_aRegisteredVBAConstants.end() )
{ if ( BasicManager* pAppMgr = SfxApplication::GetBasicManager() )
pAppMgr->SetGlobalUNOConstant( aIt->second, Any( Reference< XInterface >() ) );
s_aRegisteredVBAConstants.erase( aIt );
}
} #endif
if ( !mpDoc->Get_Impl()->bClosing ) // GCC crashes when already in the destructor, so first query the Flag
mpDoc->DoClose();
}
@param eMode Purpose, to which the SfxObjectShell is created: SfxObjectCreateMode::EMBEDDED (default) as SO-Server from within another Document SfxObjectCreateMode::STANDARD, as a normal Document open stand-alone SfxObjectCreateMode::ORGANIZER to be displayed in the Organizer, here nothing of the contents is used
*/
SfxObjectShell::SfxObjectShell(SfxObjectCreateMode eMode)
: pImpl(new SfxObjectShell_Impl(*this))
, pMedium(nullptr)
, eCreateMode(eMode)
, bHasName(false)
, bIsInGenerateThumbnail(false)
, mbAvoidRecentDocs(false)
, bRememberSignature(false)
{
}
SfxObjectShell::~SfxObjectShell()
{
if ( IsEnableSetModified() )
EnableSetModified( false );
if ( pSfxApp && pSfxApp->GetDdeService() )
pSfxApp->RemoveDdeTopic( this );
InternalCloseAndRemoveFiles();
}
void SfxObjectShell::InternalCloseAndRemoveFiles()
{ // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned! if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( false ) == pImpl->m_xDocStorage )
pMedium->CanDisposeStorage_Impl( false );
if ( pImpl->mxObjectContainer )
{
pImpl->mxObjectContainer->CloseEmbeddedObjects();
pImpl->mxObjectContainer.reset();
}
if ( pImpl->bOwnsStorage && pImpl->m_xDocStorage.is() )
pImpl->m_xDocStorage->dispose();
if ( pMedium )
{
pMedium->CloseAndReleaseStreams_Impl();
// The removing of the temporary file must be done as the latest step in the document destruction if ( !pImpl->aTempName.isEmpty() )
{
OUString aTmp;
osl::FileBase::getFileURLFromSystemPath( pImpl->aTempName, aTmp );
::utl::UCBContentHelper::Kill( aTmp );
}
}
SfxCloseVetoLock::SfxCloseVetoLock(const SfxObjectShell* pDocShell)
: mpDocShell(pDocShell)
{ if (mpDocShell)
osl_atomic_increment(&mpDocShell->Get_Impl()->m_nClosingLockLevel);
}
SfxCloseVetoLock::~SfxCloseVetoLock()
{ if (mpDocShell && osl_atomic_decrement(&mpDocShell->Get_Impl()->m_nClosingLockLevel) == 0)
{ if (mpDocShell->Get_Impl()->m_bCloseModelScheduled)
{
mpDocShell->Get_Impl()->m_bCloseModelScheduled = false; // pass ownership if (rtl::Reference model = static_cast<SfxBaseModel*>(mpDocShell->GetBaseModel().get()))
{ try
{
model->close(true);
} catch (const util::CloseVetoException&)
{
DBG_UNHANDLED_EXCEPTION("sfx.doc");
}
}
}
}
}
// variant that does not take a reference to itself, so we can call it during object destruction bool SfxObjectShell::CloseInternal()
{ if ( !pImpl->bClosing )
{ // Do not close if a progress is still running if ( GetProgress() ) returnfalse;
if ( pImpl->bClosing )
{ // remove from Document list // If there is no App, there is no document to remove // no need to call GetOrCreate here
SfxApplication *pSfxApp = SfxApplication::Get(); if(pSfxApp)
{
std::vector<SfxObjectShell*> &rDocs = pSfxApp->GetObjectShells_Impl(); auto it = std::find( rDocs.begin(), rDocs.end(), this ); if ( it != rDocs.end() )
rDocs.erase( it );
}
}
}
// search for a SfxDocument of the specified type for (SfxObjectShell* pSh : rDocs)
{ if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() ) continue;
// refind the specified predecessor
size_t nPos; for ( nPos = 0; nPos < rDocs.size(); ++nPos ) if ( rDocs[nPos] == &rPrev ) break;
// search for the next SfxDocument of the specified type for ( ++nPos; nPos < rDocs.size(); ++nPos )
{
SfxObjectShell* pSh = rDocs[ nPos ]; if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() ) continue;
// Ask if possible if it should be saved // only ask for the Document in the visible window
SfxViewFrame *pFrame = SfxObjectShell::Current() == this
? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
// assume we do not have Basic ourself, but we can refer to another // document which does (by our model's XScriptInvocationContext::getScriptContainer). // In this case, we return the BasicManager of this other document.
OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(), "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
Reference< XModel > xForeignDocument;
Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY ); if ( xContext.is() )
{
xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY );
OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(), "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
}
SAL_WARN("sfx.doc", "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?"); #endif return SfxGetpApp()->GetDialogContainer();
}
Creates a document's BasicManager and loads it, if we are already based on a storage.
[Note]
This method has to be called by implementations of <SvPersist::Load()> (with its pStor parameter) and by implementations of <SvPersist::InitNew()> (with pStor = 0).
*/
{ /* #163556# (DR) - Handling of recursive calls while creating the Basic manager.
It is possible that (while creating the Basic manager) the code that imports the Basic storage wants to access the Basic manager again. Especially in VBA compatibility mode, there is code that wants to access the "VBA Globals" object which is stored as global UNO constant in the Basic manager.
To achieve correct handling of the recursive calls of this function from lcl_getBasicManagerForDocument(), the implementation of the function BasicManagerRepository::getDocumentBasicManager() has been changed to return the Basic manager currently under construction, when called repeatedly.
The variable pImpl->bBasicInitialized will be set to sal_True after construction now, to ensure that the recursive call of the function lcl_getBasicManagerForDocument() will be routed into this function too.
Calling BasicManagerHolder::reset() twice is not a big problem, as it does not take ownership but stores only the raw pointer. Owner of all Basic managers is the global BasicManagerRepository instance.
*/ #if HAVE_FEATURE_SCRIPTING
DBG_ASSERT( !pImpl->bBasicInitialized && !pImpl->aBasicManager.isValid(), "Local BasicManager already exists"); try
{
pImpl->aBasicManager.reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
} catch (const css::ucb::ContentCreationException&)
{
TOOLS_WARN_EXCEPTION("sfx.doc", "");
}
DBG_ASSERT( pImpl->aBasicManager.isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
pImpl->bBasicInitialized = true; #endif
}
Reference< XInterface > xOldCurrentComp(rTheCurrentComponent); if ( _rxComponent == xOldCurrentComp ) // nothing to do return; // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not // /required/ for "_rxComponent == s_xCurrentComponent.get()". // In other words, it's still possible that we here do something which is not necessary, // but we should have filtered quite some unnecessary calls already.
// HACK: sometimes a real document service name is given here instead of // a factory short name. Set return value directly to this service name as fallback // in case next lines of code does nothing ... // use rFact instead of normed aFact value !
OUString aServiceName = rFact;
void SfxObjectShell::SetInitialized_Impl( constbool i_fromInitNew )
{
pImpl->bInitialized = true; if (comphelper::IsFuzzing()) return; if ( i_fromInitNew )
{
SetActivateEvent_Impl( SfxEventHintId::CreateDoc );
SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::DocCreated, GlobalEventConfig::GetEventName(GlobalEventId::DOCCREATED), this ) );
} else
{
SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::LoadFinished, GlobalEventConfig::GetEventName(GlobalEventId::LOADFINISHED), this ) );
}
}
bool SfxObjectShell::IsChangeRecording(SfxViewShell* /*pViewShell*/, bool /*bRecordAllViews*/) const
{ // currently this function needs to be overwritten by Writer and Calc only
SAL_WARN( "sfx.doc", "function not implemented" ); returnfalse;
}
bool SfxObjectShell::HasChangeRecordProtection() const
{ // currently this function needs to be overwritten by Writer and Calc only
SAL_WARN( "sfx.doc", "function not implemented" ); returnfalse;
}
void SfxObjectShell::SetChangeRecording( bool/*bActivate*/, bool /*bLockAllViews*/, SfxRedlineRecordingMode /*eRedlineRecordingMode*/)
{ // currently this function needs to be overwritten by Writer and Calc only
SAL_WARN( "sfx.doc", "function not implemented" );
}
void SfxObjectShell::SetProtectionPassword( const OUString & /*rPassword*/ )
{ // currently this function needs to be overwritten by Writer and Calc only
SAL_WARN( "sfx.doc", "function not implemented" );
}
bool SfxObjectShell::GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ )
{ // currently this function needs to be overwritten by Writer and Calc only
SAL_WARN( "sfx.doc", "function not implemented" ); returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.