/* -*- 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 .
*/
namespace basic
{ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::XComponentContext; using ::com::sun::star::frame::XModel; using ::com::sun::star::frame::Desktop; using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::embed::XStorage; using ::com::sun::star::script::XStorageBasedLibraryContainer; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::document::XStorageBasedDocument; using ::com::sun::star::document::XEmbeddedScripts;
/** creates a new BasicManager instance for the given model
@param _out_rpBasicManager reference to the pointer variable that will hold the new BasicManager.
@param _rxDocumentModel the model whose BasicManager will be created. Must not be <NULL/>.
*/ bool impl_createManagerForModel(
BasicManagerStore::iterator location, const Reference< XModel >& _rxDocumentModel );
/** creates the application-wide BasicManager
*/
BasicManager* impl_createApplicationBasicManager();
/** notifies all listeners which expressed interest in the creation of BasicManager instances.
*/ void impl_notifyCreationListeners( const Reference< XModel >& _rxDocumentModel,
BasicManager& _rManager
);
/** retrieves the current storage of a given document
@param _rxDocument the document whose storage is to be retrieved.
@param _out_rStorage takes the storage upon successful return. Note that this might be <NULL/> even if <TRUE/> is returned. In this case, the document has not yet been saved.
@return <TRUE/> if the storage could be successfully retrieved (in which case <arg>_out_rStorage</arg> might or might not be <NULL/>), <FALSE/> otherwise. In the latter case, processing this document should stop.
*/ staticbool impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage );
/** retrieves the containers for Basic and Dialog libraries for a given document
@param _rxDocument the document whose containers are to be retrieved.
@param _out_rxBasicLibraries takes the basic library container upon successful return
@param _out_rxDialogLibraries takes the dialog library container upon successful return
@return <TRUE/> if and only if both containers exist, and could successfully be retrieved
*/ staticbool impl_getDocumentLibraryContainers_nothrow( const Reference< XModel >& _rxDocument,
Reference<XStorageBasedLibraryContainer>& _out_rxBasicLibraries,
Reference<XStorageBasedLibraryContainer>& _out_rxDialogLibraries
);
/** initializes the given library containers, which belong to a document
*/ staticvoid impl_initDocLibraryContainers_nothrow( const Reference<XStorageBasedLibraryContainer>& _rxBasicLibraries, const Reference<XStorageBasedLibraryContainer>& _rxDialogLibraries
);
ImplRepository::~ImplRepository()
{ // Avoid double-delete of managers when they are destroyed in our dtor, and start notify us for (auto& it : m_aStore)
EndListening(*it.second);
}
/* #163556# (DR) - This function may be called recursively while constructing the Basic manager and loading the Basic storage. By passing the map entry received from impl_getLocationForModel() to the function impl_createManagerForModel(), the new Basic manager will be put immediately into the map of existing Basic managers, thus a recursive call of this function will find and return it without creating another instance.
*/ autoconst loc = impl_getLocationForModel( _rxDocumentModel ); if (loc->second != nullptr) return loc->second.get(); if (impl_createManagerForModel(loc, _rxDocumentModel)) return loc->second.get(); return nullptr;
}
// Create basic and load it // AppBasicDir is now a PATH
INetURLObject aAppBasic( SvtPathOptions().SubstituteVariable(u"$(progurl)"_ustr) );
aAppBasic.insertName( Application::GetAppName() );
BasicManager* pBasicManager = new BasicManager( new StarBASIC, &aAppBasicDir );
setApplicationBasicManager( std::unique_ptr<BasicManager>(pBasicManager) );
// The first dir in the path as destination:
OUString aFileName( aAppBasic.getName() );
aAppBasic = INetURLObject( o3tl::getToken(aAppBasicDir, 1, ';') );
DBG_ASSERT(aAppBasic.GetProtocol() != INetProtocol::NotValid,
OString("Invalid URL: \"" +
OUStringToOString(aAppBasicDir, osl_getThreadTextEncoding()) + "\"").getStr());
aAppBasic.insertName( aFileName );
pBasicManager->SetStorageName( aAppBasic.PathToFileName() );
_out_rpBasicManager = nullptr;
Reference< XStorage > xStorage; if ( !impl_getDocumentStorage_nothrow( _rxDocumentModel, xStorage ) )
{
m_aStore.erase(location); // the document is not able to provide the storage it is based on. returnfalse;
}
Reference<XStorageBasedLibraryContainer> xBasicLibs;
Reference<XStorageBasedLibraryContainer> xDialogLibs; if ( !impl_getDocumentLibraryContainers_nothrow( _rxDocumentModel, xBasicLibs, xDialogLibs ) )
{
m_aStore.erase(location); // the document does not have BasicLibraries and DialogLibraries returnfalse;
}
// register as listener for this model being disposed/closed
OSL_ENSURE( _rxDocumentModel.is(), "ImplRepository::impl_createManagerForModel: the document must be an XComponent!" );
assert(impl_hasLocationForModel(_rxDocumentModel));
startComponentListening( _rxDocumentModel );
bool bOk = false; // startComponentListening may fail in a disposed _rxDocumentModel, in which case _out_rpBasicManager will be removed // from the map and destroyed if (impl_hasLocationForModel(_rxDocumentModel))
{
bOk = true; // register as listener for the BasicManager being destroyed
StartListening( *_out_rpBasicManager );
}
// #i104876: Library container must not be modified just after // creation. This happens as side effect when creating default // "Standard" libraries and needs to be corrected here
xBasicLibs->setModified( false );
xDialogLibs->setModified( false ); return bOk;
}
BasicManagerStore::iterator it = std::find_if(m_aStore.begin(), m_aStore.end(),
[&xNormalizedSource](BasicManagerStore::reference rEntry) { return rEntry.first.get() == xNormalizedSource.get(); }); if (it != m_aStore.end())
{
impl_removeFromRepository( it ); return;
}
OSL_FAIL( "ImplRepository::_disposing: where does this come from?" );
}
void ImplRepository::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint )
{ if ( _rHint.GetId() != SfxHintId::Dying ) // not interested in return;
BasicManager* pManager = dynamic_cast< BasicManager* >( &_rBC );
OSL_ENSURE( pManager, "ImplRepository::Notify: where does this come from?" );
BasicManagerStore::iterator it = std::find_if(m_aStore.begin(), m_aStore.end(),
[&pManager](BasicManagerStore::reference rEntry) { return rEntry.second.get() == pManager; }); if (it != m_aStore.end())
{ // a BasicManager which is still in our repository is being deleted. // That's bad, since by definition, we *own* all instances in our // repository.
OSL_FAIL( "ImplRepository::Notify: nobody should tamper with the managers, except ourself!" );
m_aStore.erase( it );
}
}
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 ist noch experimentell.