/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basic.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "basrid.hxx" #include "sbintern.hxx" #include #define LIB_SEP 0x01 #define LIBINFO_SEP 0x02 #define LIBINFO_ID 0x1491 #define PASSWORD_MARKER 0x31452134 // Library API, implemented for XML import/export #include #include #include #include #include #include #include #include #include #include #include using com::sun::star::uno::Reference; using namespace com::sun::star::container; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::script; using namespace cppu; typedef WeakImplHelper1< XNameContainer > NameContainerHelper; typedef WeakImplHelper1< XStarBasicModuleInfo > ModuleInfoHelper; typedef WeakImplHelper1< XStarBasicDialogInfo > DialogInfoHelper; typedef WeakImplHelper1< XStarBasicLibraryInfo > LibraryInfoHelper; typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper; #define CURR_VER 2 // Version 1 // sal_uIntPtr nEndPos // sal_uInt16 nId // sal_uInt16 nVer // sal_Bool bDoLoad // String LibName // String AbsStorageName // String RelStorageName // Version 2 // + sal_Bool bReference static const char* szStdLibName = "Standard"; static const char szBasicStorage[] = "StarBASIC"; static const char* szOldManagerStream = "BasicManager"; static const char szManagerStream[] = "BasicManager2"; static const char* szImbedded = "LIBIMBEDDED"; static const char* szCryptingKey = "CryptedBasic"; static const char* szScriptLanguage = "StarBasic"; TYPEINIT1( BasicManager, SfxBroadcaster ); DBG_NAME( BasicManager ); StreamMode eStreamReadMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL; StreamMode eStorageReadMode = STREAM_READ | STREAM_SHARE_DENYWRITE; DECLARE_LIST( BasErrorLst, BasicError* ) //---------------------------------------------------------------------------- // BasicManager impl data struct BasicManagerImpl { LibraryContainerInfo maContainerInfo; // Save stream data SvMemoryStream* mpManagerStream; SvMemoryStream** mppLibStreams; sal_Int32 mnLibStreamCount; sal_Bool mbModifiedByLibraryContainer; sal_Bool mbError; BasicManagerImpl( void ) : mpManagerStream( NULL ) , mppLibStreams( NULL ) , mnLibStreamCount( 0 ) , mbModifiedByLibraryContainer( sal_False ) , mbError( sal_False ) {} ~BasicManagerImpl(); }; BasicManagerImpl::~BasicManagerImpl() { delete mpManagerStream; if( mppLibStreams ) { for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ ) delete mppLibStreams[i]; delete[] mppLibStreams; } } //============================================================================ // BasMgrContainerListenerImpl //============================================================================ typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper; class BasMgrContainerListenerImpl: public ContainerListenerHelper { BasicManager* mpMgr; ::rtl::OUString maLibName; // empty -> no lib, but lib container public: BasMgrContainerListenerImpl( BasicManager* pMgr, ::rtl::OUString aLibName ) : mpMgr( pMgr ) , maLibName( aLibName ) {} static void insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr, Any aLibAny, ::rtl::OUString aLibName ); static void addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess, ::rtl::OUString aLibName ); // XEventListener virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); // XContainerListener virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw(::com::sun::star::uno::RuntimeException); }; //============================================================================ // BasMgrContainerListenerImpl //============================================================================ void BasMgrContainerListenerImpl::insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr, Any aLibAny, ::rtl::OUString aLibName ) { Reference< XNameAccess > xLibNameAccess; aLibAny >>= xLibNameAccess; if( !pMgr->GetLib( aLibName ) ) { BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr ); #ifdef DBG_UTIL StarBASIC* pLib = #endif pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont ); DBG_ASSERT( pLib, "XML Import: Basic library could not be created"); } Reference< XContainer> xLibContainer( xLibNameAccess, UNO_QUERY ); if( xLibContainer.is() ) { // Register listener for library Reference< XContainerListener > xLibraryListener = static_cast< XContainerListener* > ( new BasMgrContainerListenerImpl( pMgr, aLibName ) ); xLibContainer->addContainerListener( xLibraryListener ); } if( xScriptCont->isLibraryLoaded( aLibName ) ) { addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName ); } } void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess, ::rtl::OUString aLibName ) { Sequence< ::rtl::OUString > aModuleNames = xLibNameAccess->getElementNames(); sal_Int32 nModuleCount = aModuleNames.getLength(); StarBASIC* pLib = pMgr->GetLib( aLibName ); DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!"); if( pLib ) { const ::rtl::OUString* pNames = aModuleNames.getConstArray(); for( sal_Int32 j = 0 ; j < nModuleCount ; j++ ) { ::rtl::OUString aModuleName = pNames[ j ]; Any aElement = xLibNameAccess->getByName( aModuleName ); ::rtl::OUString aMod; aElement >>= aMod; Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY ); if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) ) { ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName ); OSL_TRACE("#addLibraryModulesImpl - aMod"); pLib->MakeModule32( aModuleName, mInfo, aMod ); } else pLib->MakeModule32( aModuleName, aMod ); } } pLib->SetModified( sal_False ); } // XEventListener //---------------------------------------------------------------------------- void SAL_CALL BasMgrContainerListenerImpl::disposing( const EventObject& Source ) throw( RuntimeException ) { (void)Source; } // XContainerListener //---------------------------------------------------------------------------- void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent& Event ) throw( RuntimeException ) { sal_Bool bLibContainer = maLibName.isEmpty(); ::rtl::OUString aName; Event.Accessor >>= aName; mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True; if( bLibContainer ) { Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY ); insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName ); StarBASIC* pLib = mpMgr->GetLib( aName ); if ( pLib ) { Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, UNO_QUERY ); if ( xVBACompat.is() ) pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() ); } } else { StarBASIC* pLib = mpMgr->GetLib( maLibName ); DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!"); if( pLib ) { SbModule* pMod = pLib->FindModule( aName ); if( !pMod ) { ::rtl::OUString aMod; Event.Element >>= aMod; Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY ); if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) ) { ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName ); pLib->MakeModule32( aName, mInfo, aMod ); } else pLib->MakeModule32( aName, aMod ); pLib->SetModified( sal_False ); } } } } //---------------------------------------------------------------------------- void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent& Event ) throw( RuntimeException ) { ::rtl::OUString aName; Event.Accessor >>= aName; mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True; // Replace not possible for library container #ifdef DBG_UTIL sal_Bool bLibContainer = maLibName.isEmpty(); #endif DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()"); StarBASIC* pLib = mpMgr->GetLib( maLibName ); if( pLib ) { SbModule* pMod = pLib->FindModule( aName ); ::rtl::OUString aMod; Event.Element >>= aMod; if( pMod ) pMod->SetSource32( aMod ); else pLib->MakeModule32( aName, aMod ); pLib->SetModified( sal_False ); } } //---------------------------------------------------------------------------- void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const ContainerEvent& Event ) throw( RuntimeException ) { ::rtl::OUString aName; Event.Accessor >>= aName; mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True; sal_Bool bLibContainer = maLibName.isEmpty(); if( bLibContainer ) { StarBASIC* pLib = mpMgr->GetLib( aName ); if( pLib ) { sal_uInt16 nLibId = mpMgr->GetLibId( aName ); mpMgr->RemoveLib( nLibId, sal_False ); } } else { StarBASIC* pLib = mpMgr->GetLib( maLibName ); SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL; if( pMod ) { pLib->Remove( pMod ); pLib->SetModified( sal_False ); } } } //===================================================================== class BasicErrorManager { private: BasErrorLst aErrorList; public: ~BasicErrorManager(); void Reset(); void InsertError( const BasicError& rError ); sal_Bool HasErrors() { return (sal_Bool)aErrorList.Count(); } BasicError* GetFirstError() { return aErrorList.First(); } BasicError* GetNextError() { return aErrorList.Next(); } }; BasicErrorManager::~BasicErrorManager() { Reset(); } void BasicErrorManager::Reset() { BasicError* pError = (BasicError*)aErrorList.First(); while ( pError ) { delete pError; pError = (BasicError*)aErrorList.Next(); } aErrorList.Clear(); } void BasicErrorManager::InsertError( const BasicError& rError ) { aErrorList.Insert( new BasicError( rError ), LIST_APPEND ); } BasicError::BasicError() { nErrorId = 0; nReason = 0; } BasicError::BasicError( sal_uIntPtr nId, sal_uInt16 nR, const String& rErrStr ) : aErrStr( rErrStr ) { nErrorId = nId; nReason = nR; } BasicError::BasicError( const BasicError& rErr ) : aErrStr( rErr.aErrStr ) { nErrorId = rErr.nErrorId; nReason = rErr.nReason; } class BasicLibInfo { private: StarBASICRef xLib; String aLibName; String aStorageName; // String is sufficient, unique at runtime String aRelStorageName; String aPassword; sal_Bool bDoLoad; sal_Bool bReference; sal_Bool bPasswordVerified; sal_Bool bFoundInPath; // Must not relativated again! // Lib represents library in new UNO library container Reference< XLibraryContainer > mxScriptCont; public: BasicLibInfo(); BasicLibInfo( const String& rStorageName ); sal_Bool IsReference() const { return bReference; } sal_Bool& IsReference() { return bReference; } sal_Bool IsExtern() const { return ! aStorageName.EqualsAscii(szImbedded); } void SetStorageName( const String& rName ) { aStorageName = rName; } const String& GetStorageName() const { return aStorageName; } void SetRelStorageName( const String& rN ) { aRelStorageName = rN; } const String& GetRelStorageName() const { return aRelStorageName; } void CalcRelStorageName( const String& rMgrStorageName ); StarBASICRef GetLib() const { if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) && !mxScriptCont->isLibraryLoaded( aLibName ) ) return StarBASICRef(); return xLib; } StarBASICRef& GetLibRef() { return xLib; } void SetLib( StarBASIC* pBasic ) { xLib = pBasic; } const String& GetLibName() const { return aLibName; } void SetLibName( const String& rName ) { aLibName = rName; } // Only temporary for Load/Save sal_Bool DoLoad() { return bDoLoad; } sal_Bool HasPassword() const { return aPassword.Len() != 0; } const String& GetPassword() const { return aPassword; } void SetPassword( const String& rNewPassword ) { aPassword = rNewPassword; } sal_Bool IsPasswordVerified() const { return bPasswordVerified; } void SetPasswordVerified() { bPasswordVerified = sal_True; } sal_Bool IsFoundInPath() const { return bFoundInPath; } void SetFoundInPath( sal_Bool bInPath ) { bFoundInPath = bInPath; } void Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, sal_Bool bUseOldReloadInfo ); static BasicLibInfo* Create( SotStorageStream& rSStream ); Reference< XLibraryContainer > GetLibraryContainer( void ) { return mxScriptCont; } void SetLibraryContainer( const Reference< XLibraryContainer >& xScriptCont ) { mxScriptCont = xScriptCont; } }; DECLARE_LIST( BasicLibsBase, BasicLibInfo* ) class BasicLibs : public BasicLibsBase { public: String aBasicLibPath; // TODO: Should be member of manager, but currently not incompatible }; BasicLibInfo::BasicLibInfo() { bReference = sal_False; bPasswordVerified = sal_False; bDoLoad = sal_False; bFoundInPath = sal_False; mxScriptCont = NULL; aStorageName = String::CreateFromAscii(szImbedded); aRelStorageName = String::CreateFromAscii(szImbedded); } BasicLibInfo::BasicLibInfo( const String& rStorageName ) { bReference = sal_True; bPasswordVerified = sal_False; bDoLoad = sal_False; mxScriptCont = NULL; aStorageName = rStorageName; } void BasicLibInfo::Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, sal_Bool bUseOldReloadInfo ) { sal_uIntPtr nStartPos = rSStream.Tell(); sal_uInt32 nEndPos = 0; sal_uInt16 nId = LIBINFO_ID; sal_uInt16 nVer = CURR_VER; rSStream << nEndPos; rSStream << nId; rSStream << nVer; String aCurStorageName = INetURLObject(rBasMgrStorageName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE ); DBG_ASSERT(aCurStorageName.Len() != 0, "Bad storage name"); // If not set initialize StorageName if ( aStorageName.Len() == 0 ) aStorageName = aCurStorageName; // Load again? sal_Bool bDoLoad_ = xLib.Is(); if ( bUseOldReloadInfo ) bDoLoad_ = DoLoad(); rSStream << bDoLoad_; // The name of the lib... rSStream.WriteByteString(GetLibName()); // Absolute path... if ( ! GetStorageName().EqualsAscii(szImbedded) ) { String aSName = INetURLObject( GetStorageName(), INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE ); DBG_ASSERT(aSName.Len() != 0, "Bad storage name"); rSStream.WriteByteString( aSName ); } else rSStream.WriteByteString( szImbedded ); // Relative path... if ( ( aStorageName == aCurStorageName ) || ( aStorageName.EqualsAscii(szImbedded) ) ) rSStream.WriteByteString( szImbedded ); else { // Do not determine the relative path if the file was only found in path: // because the relative path would change and after moving the lib the // the file cannot be found. if ( !IsFoundInPath() ) CalcRelStorageName( aCurStorageName ); rSStream.WriteByteString(aRelStorageName); } // ------------------------------ // Version 2 // ------------------------------ // reference... rSStream << bReference; // ------------------------------ // End // ------------------------------ nEndPos = rSStream.Tell(); rSStream.Seek( nStartPos ); rSStream << nEndPos; rSStream.Seek( nEndPos ); } BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream ) { BasicLibInfo* pInfo = new BasicLibInfo; sal_uInt32 nEndPos; sal_uInt16 nId; sal_uInt16 nVer; rSStream >> nEndPos; rSStream >> nId; rSStream >> nVer; DBG_ASSERT( nId == LIBINFO_ID, "Keine BasicLibInfo !?" ); if( nId == LIBINFO_ID ) { // Reload? sal_Bool bDoLoad; rSStream >> bDoLoad; pInfo->bDoLoad = bDoLoad; // The name of the lib... String aName; rSStream.ReadByteString(aName); pInfo->SetLibName( aName ); // Absolute path... String aStorageName; rSStream.ReadByteString(aStorageName); pInfo->SetStorageName( aStorageName ); // Relative path... String aRelStorageName; rSStream.ReadByteString(aRelStorageName); pInfo->SetRelStorageName( aRelStorageName ); if ( nVer >= 2 ) { sal_Bool bReferenz; rSStream >> bReferenz; pInfo->IsReference() = bReferenz; } rSStream.Seek( nEndPos ); } return pInfo; } void BasicLibInfo::CalcRelStorageName( const String& rMgrStorageName ) { if ( rMgrStorageName.Len() ) { INetURLObject aAbsURLObj( rMgrStorageName ); aAbsURLObj.removeSegment(); String aPath = aAbsURLObj.GetMainURL( INetURLObject::NO_DECODE ); UniString aRelURL = INetURLObject::GetRelURL( aPath, GetStorageName() ); SetRelStorageName( aRelURL ); } else SetRelStorageName( String() ); } BasicManager::BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib, String* pLibPath, sal_Bool bDocMgr ) : mbDocMgr( bDocMgr ) { DBG_CTOR( BasicManager, 0 ); Init(); if( pLibPath ) pLibs->aBasicLibPath = *pLibPath; String aStorName( rStorage.GetName() ); maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE ); // #91251: Storage name not longer available for documents < 5.0 // Should be no real problem, because only relative storage names // (links) can be affected. // DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); // DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name"); // If there is no Manager Stream, no further actions are necessary if ( rStorage.IsStream( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)) ) ) { LoadBasicManager( rStorage, rBaseURL ); // StdLib contains Parent: StarBASIC* pStdLib = GetStdLib(); DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" ); if ( !pStdLib ) { // Should never happen, but if it happens we won't crash... pStdLib = new StarBASIC( NULL, mbDocMgr ); BasicLibInfo* pStdLibInfo = pLibs->GetObject( 0 ); if ( !pStdLibInfo ) pStdLibInfo = CreateLibInfo(); pStdLibInfo->SetLib( pStdLib ); StarBASICRef xStdLib = pStdLibInfo->GetLib(); xStdLib->SetName( String::CreateFromAscii(szStdLibName) ); pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) ); xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH ); xStdLib->SetModified( sal_False ); } else { pStdLib->SetParent( pParentFromStdLib ); // The other get StdLib as parent: for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ ) { StarBASIC* pBasic = GetLib( nBasic ); if ( pBasic ) { // pBasic->SetParent( pStdLib ); pStdLib->Insert( pBasic ); pBasic->SetFlag( SBX_EXTSEARCH ); } } // Modified through insert pStdLib->SetModified( sal_False ); } // #91626 Save all stream data to save it unmodified if basic isn't modified // in an 6.0+ office. So also the old basic dialogs can be saved. SotStorageStreamRef xManagerStream = rStorage.OpenSotStream ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode ); mpImpl->mpManagerStream = new SvMemoryStream(); *static_cast(&xManagerStream) >> *mpImpl->mpManagerStream; SotStorageRef xBasicStorage = rStorage.OpenSotStorage ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, sal_False ); if( xBasicStorage.Is() && !xBasicStorage->GetError() ) { sal_uInt16 nLibs = GetLibCount(); mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ]; for( sal_uInt16 nL = 0; nL < nLibs; nL++ ) { BasicLibInfo* pInfo = pLibs->GetObject( nL ); DBG_ASSERT( pInfo, "pInfo?!" ); SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), eStreamReadMode ); mpImpl->mppLibStreams[nL] = new SvMemoryStream(); *static_cast(&xBasicStream) >> *( mpImpl->mppLibStreams[nL] ); } } else mpImpl->mbError = sal_True; } else { ImpCreateStdLib( pParentFromStdLib ); if ( rStorage.IsStream( String::CreateFromAscii(szOldManagerStream) ) ) LoadOldBasicManager( rStorage ); } bBasMgrModified = sal_False; } void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo ) { Reference< XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() ); if ( !xScriptCont.is() ) return; String aLibName = pBasic->GetName(); if( !xScriptCont->hasByName( aLibName ) ) xScriptCont->createLibrary( aLibName ); Any aLibAny = xScriptCont->getByName( aLibName ); Reference< XNameContainer > xLib; aLibAny >>= xLib; if ( !xLib.is() ) return; sal_uInt16 nModCount = pBasic->GetModules()->Count(); for ( sal_uInt16 nMod = 0 ; nMod < nModCount ; nMod++ ) { SbModule* pModule = (SbModule*)pBasic->GetModules()->Get( nMod ); DBG_ASSERT( pModule, "Modul nicht erhalten!" ); String aModName = pModule->GetName(); if( !xLib->hasByName( aModName ) ) { ::rtl::OUString aSource = pModule->GetSource32(); Any aSourceAny; aSourceAny <<= aSource; xLib->insertByName( aModName, aSourceAny ); } } } const Reference< XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const { return mpImpl->maContainerInfo.mxDialogCont; } const Reference< XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const { return mpImpl->maContainerInfo.mxScriptCont; } void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo ) { mpImpl->maContainerInfo = rInfo; Reference< XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() ); StarBASIC* pStdLib = GetStdLib(); String aLibName = pStdLib->GetName(); if( xScriptCont.is() ) { // Register listener for lib container ::rtl::OUString aEmptyLibName; Reference< XContainerListener > xLibContainerListener = static_cast< XContainerListener* > ( new BasMgrContainerListenerImpl( this, aEmptyLibName ) ); Reference< XContainer> xLibContainer( xScriptCont, UNO_QUERY ); xLibContainer->addContainerListener( xLibContainerListener ); Sequence< ::rtl::OUString > aScriptLibNames = xScriptCont->getElementNames(); const ::rtl::OUString* pScriptLibName = aScriptLibNames.getConstArray(); sal_Int32 i, nNameCount = aScriptLibNames.getLength(); if( nNameCount ) { for( i = 0 ; i < nNameCount ; ++i, ++pScriptLibName ) { Any aLibAny = xScriptCont->getByName( *pScriptLibName ); if ( pScriptLibName->equalsAscii( "Standard" ) ) xScriptCont->loadLibrary( *pScriptLibName ); BasMgrContainerListenerImpl::insertLibraryImpl ( xScriptCont, this, aLibAny, *pScriptLibName ); } } else { // No libs? Maybe an 5.2 document already loaded sal_uInt16 nLibs = GetLibCount(); for( sal_uInt16 nL = 0; nL < nLibs; nL++ ) { BasicLibInfo* pBasLibInfo = pLibs->GetObject( nL ); StarBASIC* pLib = pBasLibInfo->GetLib(); if( !pLib ) { sal_Bool bLoaded = ImpLoadLibary( pBasLibInfo, NULL, sal_False ); if( bLoaded ) pLib = pBasLibInfo->GetLib(); } if( pLib ) { copyToLibraryContainer( pLib, mpImpl->maContainerInfo ); if( pBasLibInfo->HasPassword() ) { OldBasicPassword* pOldBasicPassword = mpImpl->maContainerInfo.mpOldBasicPassword; if( pOldBasicPassword ) { pOldBasicPassword->setLibraryPassword ( pLib->GetName(), pBasLibInfo->GetPassword() ); pBasLibInfo->SetPasswordVerified(); } } } } mpImpl->mbModifiedByLibraryContainer = sal_False; } } SetGlobalUNOConstant( "BasicLibraries", makeAny( mpImpl->maContainerInfo.mxScriptCont ) ); SetGlobalUNOConstant( "DialogLibraries", makeAny( mpImpl->maContainerInfo.mxDialogCont ) ); } BasicManager::BasicManager( StarBASIC* pSLib, String* pLibPath, sal_Bool bDocMgr ) : mbDocMgr( bDocMgr ) { DBG_CTOR( BasicManager, 0 ); Init(); DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" ); if( pLibPath ) pLibs->aBasicLibPath = *pLibPath; BasicLibInfo* pStdLibInfo = CreateLibInfo(); pStdLibInfo->SetLib( pSLib ); StarBASICRef xStdLib = pStdLibInfo->GetLib(); xStdLib->SetName( String::CreateFromAscii(szStdLibName)); pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) ); pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH ); // Save is only necessary if basic has changed xStdLib->SetModified( sal_False ); bBasMgrModified = sal_False; } BasicManager::BasicManager() { DBG_CTOR( BasicManager, 0 ); // This ctor may only be used to adapt relative paths for 'Save As'. // There is no AppBasic so libs must not be loaded... Init(); } void BasicManager::ImpMgrNotLoaded( const String& rStorageName ) { // pErrInf is only destroyed if the error is processed by an // ErrorHandler StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, rStorageName ) ); // Create a stdlib otherwise we crash! BasicLibInfo* pStdLibInfo = CreateLibInfo(); pStdLibInfo->SetLib( new StarBASIC( NULL, mbDocMgr ) ); StarBASICRef xStdLib = pStdLibInfo->GetLib(); xStdLib->SetName( String::CreateFromAscii(szStdLibName) ); pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) ); xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH ); xStdLib->SetModified( sal_False ); } void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib ) { BasicLibInfo* pStdLibInfo = CreateLibInfo(); StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr ); pStdLibInfo->SetLib( pStdLib ); pStdLib->SetName( String::CreateFromAscii(szStdLibName) ); pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) ); pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH ); } void BasicManager::LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, sal_Bool bLoadLibs ) { DBG_CHKTHIS( BasicManager, 0 ); // StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE; SotStorageStreamRef xManagerStream = rStorage.OpenSotStream ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode ); String aStorName( rStorage.GetName() ); // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) ) { ImpMgrNotLoaded( aStorName ); return; } maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE ); // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name"); String aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL // If loaded from template, only BaseURL is used: //String aBaseURL = INetURLObject::GetBaseURL(); if ( rBaseURL.Len() ) { INetURLObject aObj( rBaseURL ); if ( aObj.GetProtocol() == INET_PROT_FILE ) aRealStorageName = aObj.PathToFileName(); } xManagerStream->SetBufferSize( 1024 ); xManagerStream->Seek( STREAM_SEEK_TO_BEGIN ); sal_uInt32 nEndPos; *xManagerStream >> nEndPos; sal_uInt16 nLibs; *xManagerStream >> nLibs; // Plausi! if( nLibs & 0xF000 ) { DBG_ASSERT( sal_False, "BasicManager-Stream defect!" ); return; } for ( sal_uInt16 nL = 0; nL < nLibs; nL++ ) { BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream ); // Correct absolute pathname if relative is existing. // Always try relative first if there are two stands on disk if ( pInfo->GetRelStorageName().Len() && ( ! pInfo->GetRelStorageName().EqualsAscii(szImbedded) ) ) { INetURLObject aObj( aRealStorageName, INET_PROT_FILE ); aObj.removeSegment(); bool bWasAbsolute = sal_False; aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute ); //*** TODO: Replace if still necessary /* if ( SfxContentHelper::Exists( aObj.GetMainURL() ) ) pInfo->SetStorageName( aObj.GetMainURL() ); else */ //*** TODO-End if ( pLibs->aBasicLibPath.Len() ) { // Search lib in path String aSearchFile = pInfo->GetRelStorageName(); SvtPathOptions aPathCFG; if( aPathCFG.SearchFile( aSearchFile, SvtPathOptions::PATH_BASIC ) ) { pInfo->SetStorageName( aSearchFile ); pInfo->SetFoundInPath( sal_True ); } } } pLibs->Insert( pInfo, LIST_APPEND ); // Libs from external files should be loaded only when necessary. // But references are loaded at once, otherwise some big customers get into trouble if ( bLoadLibs && pInfo->DoLoad() && ( ( !pInfo->IsExtern() ) || ( pInfo->IsReference() ) ) ) { ImpLoadLibary( pInfo, &rStorage ); } } xManagerStream->Seek( nEndPos ); xManagerStream->SetBufferSize( 0 ); xManagerStream.Clear(); } void BasicManager::LoadOldBasicManager( SotStorage& rStorage ) { DBG_CHKTHIS( BasicManager, 0 ); // StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE; SotStorageStreamRef xManagerStream = rStorage.OpenSotStream ( String::CreateFromAscii(szOldManagerStream), eStreamReadMode ); String aStorName( rStorage.GetName() ); DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) ) { ImpMgrNotLoaded( aStorName ); return; } xManagerStream->SetBufferSize( 1024 ); xManagerStream->Seek( STREAM_SEEK_TO_BEGIN ); sal_uInt32 nBasicStartOff, nBasicEndOff; *xManagerStream >> nBasicStartOff; *xManagerStream >> nBasicEndOff; DBG_ASSERT( !xManagerStream->GetError(), "Ungueltiger Manager-Stream!" ); xManagerStream->Seek( nBasicStartOff ); if( !ImplLoadBasic( *xManagerStream, pLibs->GetObject(0)->GetLibRef() ) ) { // String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) ); // aErrorText.SearchAndReplace( "XX", aStorName ); StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) ); // und es geht weiter... } xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator String aLibs; xManagerStream->ReadByteString(aLibs); xManagerStream->SetBufferSize( 0 ); xManagerStream.Clear(); // Close stream if ( aLibs.Len() ) { String aCurStorageName( aStorName ); INetURLObject aCurStorage( aCurStorageName, INET_PROT_FILE ); sal_uInt16 nLibs = aLibs.GetTokenCount( LIB_SEP ); for ( sal_uInt16 nLib = 0; nLib < nLibs; nLib++ ) { String aLibInfo( aLibs.GetToken( nLib, LIB_SEP ) ); // TODO: Remove == 2 DBG_ASSERT( ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 2 ) || ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 3 ), "Ungueltige Lib-Info!" ); String aLibName( aLibInfo.GetToken( 0, LIBINFO_SEP ) ); String aLibAbsStorageName( aLibInfo.GetToken( 1, LIBINFO_SEP ) ); String aLibRelStorageName( aLibInfo.GetToken( 2, LIBINFO_SEP ) ); INetURLObject aLibAbsStorage( aLibAbsStorageName, INET_PROT_FILE ); INetURLObject aLibRelStorage( aStorName ); aLibRelStorage.removeSegment(); bool bWasAbsolute = sal_False; aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute); DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" ); SotStorageRef xStorageRef; if ( ( aLibAbsStorage == aCurStorage ) || ( aLibRelStorageName.EqualsAscii(szImbedded) ) ) xStorageRef = &rStorage; else { xStorageRef = new SotStorage( sal_False, aLibAbsStorage.GetMainURL ( INetURLObject::NO_DECODE ), eStorageReadMode, sal_True ); if ( xStorageRef->GetError() != ERRCODE_NONE ) xStorageRef = new SotStorage( sal_False, aLibRelStorage. GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode, sal_True ); } if ( xStorageRef.Is() ) AddLib( *xStorageRef, aLibName, sal_False ); else { // String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) ); // aErrorText.SearchAndReplace( "XX", aLibName ); StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STORAGENOTFOUND, aStorName ) ); } } } } BasicManager::~BasicManager() { DBG_DTOR( BasicManager, 0 ); // Notify listener if something needs to be saved Broadcast( SfxSimpleHint( SFX_HINT_DYING) ); // Destroy Basic-Infos... // In reverse order BasicLibInfo* pInf = pLibs->Last(); while ( pInf ) { delete pInf; pInf = pLibs->Prev(); } pLibs->Clear(); delete pLibs; delete pErrorMgr; delete mpImpl; } void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager ) { delete _rpManager; _rpManager = NULL; } void BasicManager::Init() { DBG_CHKTHIS( BasicManager, 0 ); bBasMgrModified = sal_False; pErrorMgr = new BasicErrorManager; pLibs = new BasicLibs; mpImpl = new BasicManagerImpl(); } BasicLibInfo* BasicManager::CreateLibInfo() { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = new BasicLibInfo; pLibs->Insert( pInf, LIST_APPEND ); return pInf; } sal_Bool BasicManager::ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, sal_Bool bInfosOnly ) const { DBG_CHKTHIS( BasicManager, 0 ); DBG_ASSERT( pLibInfo, "LibInfo!?" ); String aStorageName( pLibInfo->GetStorageName() ); if ( !aStorageName.Len() || ( aStorageName.EqualsAscii(szImbedded) ) ) aStorageName = GetStorageName(); SotStorageRef xStorage; // The current must not be opened again... if ( pCurStorage ) { String aStorName( pCurStorage->GetName() ); // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); INetURLObject aCurStorageEntry(aStorName, INET_PROT_FILE); // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name"); INetURLObject aStorageEntry(aStorageName, INET_PROT_FILE); // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name"); if ( aCurStorageEntry == aStorageEntry ) xStorage = pCurStorage; } if ( !xStorage.Is() ) xStorage = new SotStorage( sal_False, aStorageName, eStorageReadMode ); SotStorageRef xBasicStorage = xStorage->OpenSotStorage ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, sal_False ); if ( !xBasicStorage.Is() || xBasicStorage->GetError() ) { StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) ); } else { // In the Basic-Storage every lib is in a Stream... SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode ); if ( !xBasicStream.Is() || xBasicStream->GetError() ) { StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLibInfo->GetLibName() ) ); } else { sal_Bool bLoaded = sal_False; if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 ) { if ( !bInfosOnly ) { if ( !pLibInfo->GetLib().Is() ) pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) ); xBasicStream->SetBufferSize( 1024 ); xBasicStream->Seek( STREAM_SEEK_TO_BEGIN ); bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() ); xBasicStream->SetBufferSize( 0 ); StarBASICRef xStdLib = pLibInfo->GetLib(); xStdLib->SetName( pLibInfo->GetLibName() ); xStdLib->SetModified( sal_False ); xStdLib->SetFlag( SBX_DONTSTORE ); } else { // Skip Basic... xBasicStream->Seek( STREAM_SEEK_TO_BEGIN ); ImplEncryptStream( *xBasicStream ); SbxBase::Skip( *xBasicStream ); bLoaded = sal_True; } } if ( !bLoaded ) { StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_BASICLOADERROR, pLibInfo->GetLibName() ) ); } else { // Perhaps there are additional information in the stream... xBasicStream->SetKey( szCryptingKey ); xBasicStream->RefreshBuffer(); sal_uInt32 nPasswordMarker = 0; *xBasicStream >> nPasswordMarker; if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() ) { String aPassword; xBasicStream->ReadByteString(aPassword); pLibInfo->SetPassword( aPassword ); } xBasicStream->SetKey( ByteString() ); CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() ); } return bLoaded; } } return sal_False; } sal_Bool BasicManager::ImplEncryptStream( SvStream& rStrm ) const { sal_uIntPtr nPos = rStrm.Tell(); sal_uInt32 nCreator; rStrm >> nCreator; rStrm.Seek( nPos ); sal_Bool bProtected = sal_False; if ( nCreator != SBXCR_SBX ) { // Should only be the case for encrypted Streams bProtected = sal_True; rStrm.SetKey( szCryptingKey ); rStrm.RefreshBuffer(); } return bProtected; } // This code is necessary to load the BASIC of Beta 1 // TODO: Which Beta 1? sal_Bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const { sal_Bool bProtected = ImplEncryptStream( rStrm ); SbxBaseRef xNew = SbxBase::Load( rStrm ); sal_Bool bLoaded = sal_False; if( xNew.Is() ) { if( xNew->IsA( TYPE(StarBASIC) ) ) { StarBASIC* pNew = (StarBASIC*)(SbxBase*) xNew; // Use the Parent of the old BASICs if( rOldBasic.Is() ) { pNew->SetParent( rOldBasic->GetParent() ); if( pNew->GetParent() ) pNew->GetParent()->Insert( pNew ); pNew->SetFlag( SBX_EXTSEARCH ); } rOldBasic = pNew; // Fill new libray container (5.2 -> 6.0) copyToLibraryContainer( pNew, mpImpl->maContainerInfo ); /* if( rOldBasic->GetParent() ) { rOldBasic->GetParent()->Insert( rOldBasic ); rOldBasic->SetFlag( SBX_EXTSEARCH ); } */ pNew->SetModified( sal_False ); bLoaded = sal_True; } } if ( bProtected ) rStrm.SetKey( ByteString() ); return bLoaded; } void BasicManager::CheckModules( StarBASIC* pLib, sal_Bool bReference ) const { if ( !pLib ) return; sal_Bool bModified = pLib->IsModified(); for ( sal_uInt16 nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ ) { SbModule* pModule = (SbModule*)pLib->GetModules()->Get( nMod ); DBG_ASSERT( pModule, "Modul nicht erhalten!" ); if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() ) pLib->Compile( pModule ); } // #67477, AB 8.12.99 On demand compile in referenced libs should not // cause modified if( !bModified && bReference ) { DBG_ERROR( "Per Reference eingebundene Basic-Library ist nicht compiliert!" ); pLib->SetModified( sal_False ); } } StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const String& rLibName, sal_Bool bReference ) { DBG_CHKTHIS( BasicManager, 0 ); String aStorName( rStorage.GetName() ); DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); String aStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE ); DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name"); String aNewLibName( rLibName ); while ( HasLib( aNewLibName ) ) aNewLibName += '_'; BasicLibInfo* pLibInfo = CreateLibInfo(); // Use original name otherwise ImpLoadLibary fails... pLibInfo->SetLibName( rLibName ); // Funktioniert so aber nicht, wenn Name doppelt // sal_uInt16 nLibId = GetLibId( rLibName ); sal_uInt16 nLibId = (sal_uInt16) pLibs->GetPos( pLibInfo ); // Set StorageName before load because it is compared with pCurStorage pLibInfo->SetStorageName( aStorageName ); sal_Bool bLoaded = ImpLoadLibary( pLibInfo, &rStorage ); if ( bLoaded ) { if ( aNewLibName != rLibName ) SetLibName( nLibId, aNewLibName ); if ( bReference ) { pLibInfo->GetLib()->SetModified( sal_False ); // Don't save in this case pLibInfo->SetRelStorageName( String() ); // pLibInfo->CalcRelStorageName( GetStorageName() ); pLibInfo->IsReference() = sal_True; } else { pLibInfo->GetLib()->SetModified( sal_True ); // Must be saved after Add! pLibInfo->SetStorageName( String::CreateFromAscii(szImbedded) ); // Save in BasicManager-Storage } bBasMgrModified = sal_True; } else { RemoveLib( nLibId, sal_False ); pLibInfo = 0; } if( pLibInfo ) return &*pLibInfo->GetLib() ; else return 0; } sal_Bool BasicManager::IsReference( sal_uInt16 nLib ) { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pLibInfo = pLibs->GetObject( nLib ); DBG_ASSERT( pLibInfo, "Lib?!" ); if ( pLibInfo ) return pLibInfo->IsReference(); return sal_False; } sal_Bool BasicManager::RemoveLib( sal_uInt16 nLib ) { // Only pyhsical deletion if no reference return RemoveLib( nLib, !IsReference( nLib ) ); } sal_Bool BasicManager::RemoveLib( sal_uInt16 nLib, sal_Bool bDelBasicFromStorage ) { DBG_CHKTHIS( BasicManager, 0 ); DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" ); BasicLibInfo* pLibInfo = pLibs->GetObject( nLib ); DBG_ASSERT( pLibInfo, "Lib not found!" ); if ( !pLibInfo || !nLib ) { // String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) ); StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STDLIB, pLibInfo->GetLibName() ) ); return sal_False; } // If one of the streams cannot be opened, this is not an error, // because BASIC was never written before... if ( bDelBasicFromStorage && !pLibInfo->IsReference() && ( !pLibInfo->IsExtern() || SotStorage::IsStorageFile( pLibInfo->GetStorageName() ) ) ) { SotStorageRef xStorage; if ( !pLibInfo->IsExtern() ) xStorage = new SotStorage( sal_False, GetStorageName() ); else xStorage = new SotStorage( sal_False, pLibInfo->GetStorageName() ); if ( xStorage->IsStorage( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) ) ) { SotStorageRef xBasicStorage = xStorage->OpenSotStorage ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), STREAM_STD_READWRITE, sal_False ); if ( !xBasicStorage.Is() || xBasicStorage->GetError() ) { // String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) ); StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) ); } else if ( xBasicStorage->IsStream( pLibInfo->GetLibName() ) ) { xBasicStorage->Remove( pLibInfo->GetLibName() ); xBasicStorage->Commit(); // If no further stream available, // delete the SubStorage. SvStorageInfoList aInfoList( 0, 4 ); xBasicStorage->FillInfoList( &aInfoList ); if ( !aInfoList.Count() ) { xBasicStorage.Clear(); xStorage->Remove( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) ); xStorage->Commit(); // If no further Streams or SubStorages available, // delete the Storage, too. aInfoList.Clear(); xStorage->FillInfoList( &aInfoList ); if ( !aInfoList.Count() ) { String aName_( xStorage->GetName() ); xStorage.Clear(); //*** TODO: Replace if still necessary //SfxContentHelper::Kill( aName ); //*** TODO-End } } } } } bBasMgrModified = sal_True; if ( pLibInfo->GetLib().Is() ) GetStdLib()->Remove( pLibInfo->GetLib() ); delete pLibs->Remove( pLibInfo ); return sal_True; // Remove was successful, del unimportant } sal_uInt16 BasicManager::GetLibCount() const { DBG_CHKTHIS( BasicManager, 0 ); return (sal_uInt16)pLibs->Count(); } StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = pLibs->GetObject( nLib ); DBG_ASSERT( pInf, "Lib existiert nicht!" ); if ( pInf ) return pInf->GetLib(); return 0; } StarBASIC* BasicManager::GetStdLib() const { DBG_CHKTHIS( BasicManager, 0 ); StarBASIC* pLib = GetLib( 0 ); return pLib; } StarBASIC* BasicManager::GetLib( const String& rName ) const { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = pLibs->First(); while ( pInf ) { if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )// Check if available... return pInf->GetLib(); pInf = pLibs->Next(); } return 0; } sal_uInt16 BasicManager::GetLibId( const String& rName ) const { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = pLibs->First(); while ( pInf ) { if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL ) return (sal_uInt16)pLibs->GetCurPos(); pInf = pLibs->Next(); } return LIB_NOTFOUND; } sal_Bool BasicManager::HasLib( const String& rName ) const { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = pLibs->First(); while ( pInf ) { if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL ) return sal_True; pInf = pLibs->Next(); } return sal_False; } sal_Bool BasicManager::SetLibName( sal_uInt16 nLib, const String& rName ) { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pLibInfo = pLibs->GetObject( nLib ); DBG_ASSERT( pLibInfo, "Lib?!" ); if ( pLibInfo ) { pLibInfo->SetLibName( rName ); if ( pLibInfo->GetLib().Is() ) { StarBASICRef xStdLib = pLibInfo->GetLib(); xStdLib->SetName( rName ); xStdLib->SetModified( sal_True ); } bBasMgrModified = sal_True; return sal_True; } return sal_False; } String BasicManager::GetLibName( sal_uInt16 nLib ) { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pLibInfo = pLibs->GetObject( nLib ); DBG_ASSERT( pLibInfo, "Lib?!" ); if ( pLibInfo ) return pLibInfo->GetLibName(); return String(); } sal_Bool BasicManager::LoadLib( sal_uInt16 nLib ) { DBG_CHKTHIS( BasicManager, 0 ); sal_Bool bDone = sal_False; BasicLibInfo* pLibInfo = pLibs->GetObject( nLib ); DBG_ASSERT( pLibInfo, "Lib?!" ); if ( pLibInfo ) { Reference< XLibraryContainer > xLibContainer = pLibInfo->GetLibraryContainer(); if( xLibContainer.is() ) { String aLibName = pLibInfo->GetLibName(); xLibContainer->loadLibrary( aLibName ); bDone = xLibContainer->isLibraryLoaded( aLibName );; } else { bDone = ImpLoadLibary( pLibInfo, NULL, sal_False ); StarBASIC* pLib = GetLib( nLib ); if ( pLib ) { // pLib->SetParent( GetStdLib() ); GetStdLib()->Insert( pLib ); pLib->SetFlag( SBX_EXTSEARCH ); } } } else { // String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) ); // aErrorText.SearchAndReplace( "XX", "" ); StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, String(), ERRCODE_BUTTON_OK ); pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_LIBNOTFOUND, String::CreateFromInt32(nLib) ) ); } return bDone; } StarBASIC* BasicManager::CreateLib( const String& rLibName ) { DBG_CHKTHIS( BasicManager, 0 ); if ( GetLib( rLibName ) ) return 0; BasicLibInfo* pLibInfo = CreateLibInfo(); StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr ); GetStdLib()->Insert( pNew ); pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE ); pLibInfo->SetLib( pNew ); pLibInfo->SetLibName( rLibName ); pLibInfo->GetLib()->SetName( rLibName ); return pLibInfo->GetLib(); } // For XML import/export: StarBASIC* BasicManager::CreateLib ( const String& rLibName, const String& Password, const String& LinkTargetURL ) { // Ask if lib exists because standard lib is always there StarBASIC* pLib = GetLib( rLibName ); if( !pLib ) { if( LinkTargetURL.Len() != 0 ) { SotStorageRef xStorage = new SotStorage( sal_False, LinkTargetURL, STREAM_READ | STREAM_SHARE_DENYWRITE ); if( !xStorage->GetError() ) { pLib = AddLib( *xStorage, rLibName, sal_True ); //if( !pLibInfo ) //pLibInfo = FindLibInfo( pLib ); //pLibInfo->SetStorageName( LinkTargetURL ); //pLibInfo->GetLib()->SetModified( sal_False ); // Dann nicht speichern //pLibInfo->SetRelStorageName( String() ); //pLibInfo->IsReference() = sal_True; } //else //Message? DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded"); } else { pLib = CreateLib( rLibName ); if( Password.Len() != 0 ) { BasicLibInfo* pLibInfo = FindLibInfo( pLib ); pLibInfo ->SetPassword( Password ); } } //ExternalSourceURL ? } return pLib; } StarBASIC* BasicManager::CreateLibForLibContainer( const String& rLibName, const Reference< XLibraryContainer >& xScriptCont ) { DBG_CHKTHIS( BasicManager, 0 ); if ( GetLib( rLibName ) ) return 0; BasicLibInfo* pLibInfo = CreateLibInfo(); StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr ); GetStdLib()->Insert( pNew ); pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE ); pLibInfo->SetLib( pNew ); pLibInfo->SetLibName( rLibName ); pLibInfo->GetLib()->SetName( rLibName ); pLibInfo->SetLibraryContainer( xScriptCont ); return pNew; } BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic ) const { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = ((BasicManager*)this)->pLibs->First(); while ( pInf ) { if ( pInf->GetLib() == pBasic ) return pInf; pInf = ((BasicManager*)this)->pLibs->Next(); } return 0; } sal_Bool BasicManager::IsModified() const { DBG_CHKTHIS( BasicManager, 0 ); if ( bBasMgrModified ) return sal_True; return IsBasicModified(); } sal_Bool BasicManager::IsBasicModified() const { DBG_CHKTHIS( BasicManager, 0 ); BasicLibInfo* pInf = pLibs->First(); while ( pInf ) { if ( pInf->GetLib().Is() && pInf->GetLib()->IsModified() ) return sal_True; pInf = pLibs->Next(); } return sal_False; } void BasicManager::SetFlagToAllLibs( short nFlag, sal_Bool bSet ) const { sal_uInt16 nLibs = GetLibCount(); for ( sal_uInt16 nL = 0; nL < nLibs; nL++ ) { BasicLibInfo* pInfo = pLibs->GetObject( nL ); DBG_ASSERT( pInfo, "Info?!" ); StarBASIC* pLib = pInfo->GetLib(); if ( pLib ) { if ( bSet ) pLib->SetFlag( nFlag ); else pLib->ResetFlag( nFlag ); } } } sal_Bool BasicManager::HasErrors() { DBG_CHKTHIS( BasicManager, 0 ); return pErrorMgr->HasErrors(); } void BasicManager::ClearErrors() { DBG_CHKTHIS( BasicManager, 0 ); pErrorMgr->Reset(); } BasicError* BasicManager::GetFirstError() { DBG_CHKTHIS( BasicManager, 0 ); return pErrorMgr->GetFirstError(); } BasicError* BasicManager::GetNextError() { DBG_CHKTHIS( BasicManager, 0 ); return pErrorMgr->GetNextError(); } bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut ) { bool bRes = false; StarBASIC* pStandardLib = GetStdLib(); OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" ); if ( pStandardLib ) bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut ); return bRes; } Any BasicManager::SetGlobalUNOConstant( const sal_Char* _pAsciiName, const Any& _rValue ) { Any aOldValue; StarBASIC* pStandardLib = GetStdLib(); OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" ); if ( !pStandardLib ) return aOldValue; ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) ); // obtain the old value SbxVariable* pVariable = pStandardLib->Find( sVarName, SbxCLASS_OBJECT ); if ( pVariable ) aOldValue = sbxToUnoValue( pVariable ); SbxObjectRef xUnoObj = GetSbUnoObject( sVarName, _rValue ); xUnoObj->SetFlag( SBX_DONTSTORE ); pStandardLib->Insert( xUnoObj ); return aOldValue; } bool BasicManager::LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames ) { try { Reference< XNameAccess > xScripts( GetScriptLibraryContainer(), UNO_QUERY_THROW ); Reference< XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), UNO_QUERY_THROW ); Sequence< ::rtl::OUString > aNames( xScripts->getElementNames() ); const ::rtl::OUString* pNames = aNames.getConstArray(); const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength(); for ( ; pNames != pNamesEnd; ++pNames ) { if( /*pLib->mbSharedIndexFile ||*/ !xPassword->isLibraryPasswordProtected( *pNames ) ) continue; StarBASIC* pBasicLib = GetLib( *pNames ); if ( !pBasicLib ) continue; Reference< XNameAccess > xScriptLibrary( xScripts->getByName( *pNames ), UNO_QUERY_THROW ); Sequence< ::rtl::OUString > aElementNames( xScriptLibrary->getElementNames() ); sal_Int32 nLen = aElementNames.getLength(); Sequence< ::rtl::OUString > aBigModules( nLen ); sal_Int32 nBigModules = 0; const ::rtl::OUString* pElementNames = aElementNames.getConstArray(); const ::rtl::OUString* pElementNamesEnd = aElementNames.getConstArray() + aElementNames.getLength(); for ( ; pElementNames != pElementNamesEnd; ++pElementNames ) { SbModule* pMod = pBasicLib->FindModule( *pElementNames ); if ( pMod && pMod->ExceedsLegacyModuleSize() ) aBigModules[ nBigModules++ ] = *pElementNames; } if ( nBigModules ) { aBigModules.realloc( nBigModules ); _out_rModuleNames = aBigModules; return true; } } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } return false; } namespace { SbMethod* lcl_queryMacro( BasicManager* i_manager, String const& i_fullyQualifiedName ) { sal_uInt16 nLast = 0; String sMacro = i_fullyQualifiedName; String sLibName = sMacro.GetToken( 0, '.', nLast ); String sModule = sMacro.GetToken( 0, '.', nLast ); sMacro.Erase( 0, nLast ); IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ); const CollatorWrapper* pCollator = aIntlWrapper.getCollator(); sal_uInt16 nLibCount = i_manager->GetLibCount(); for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib ) { if ( COMPARE_EQUAL == pCollator->compareString( i_manager->GetLibName( nLib ), sLibName ) ) { StarBASIC* pLib = i_manager->GetLib( nLib ); if( !pLib ) { i_manager->LoadLib( nLib ); pLib = i_manager->GetLib( nLib ); } if( pLib ) { sal_uInt16 nModCount = pLib->GetModules()->Count(); for( sal_uInt16 nMod = 0; nMod < nModCount; ++nMod ) { SbModule* pMod = (SbModule*)pLib->GetModules()->Get( nMod ); if ( pMod && COMPARE_EQUAL == pCollator->compareString( pMod->GetName(), sModule ) ) { SbMethod* pMethod = (SbMethod*)pMod->Find( sMacro, SbxCLASS_METHOD ); if( pMethod ) return pMethod; } } } } } return 0; } } bool BasicManager::HasMacro( String const& i_fullyQualifiedName ) const { return ( NULL != lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) ); } ErrCode BasicManager::ExecuteMacro( String const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue ) { SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName ); ErrCode nError = 0; if ( pMethod ) { if ( i_arguments ) pMethod->SetParameters( i_arguments ); nError = pMethod->Call( i_retValue ); } else nError = ERRCODE_BASIC_PROC_UNDEFINED; return nError; } ErrCode BasicManager::ExecuteMacro( String const& i_fullyQualifiedName, String const& i_commaSeparatedArgs, SbxValue* i_retValue ) { SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName ); if ( !pMethod ) return ERRCODE_BASIC_PROC_UNDEFINED; // arguments must be quoted String sQuotedArgs; String sArgs( i_commaSeparatedArgs ); if ( sArgs.Len()<2 || sArgs.GetBuffer()[1] == '\"') // no args or already quoted args sQuotedArgs = sArgs; else { // quote parameters sArgs.Erase( 0, 1 ); sArgs.Erase( sArgs.Len()-1, 1 ); sQuotedArgs = '('; sal_uInt16 nCount = sArgs.GetTokenCount(','); for ( sal_uInt16 n=0; nGetName(); sCall += sQuotedArgs; sCall += ']'; SbxVariable* pRet = pMethod->GetParent()->Execute( sCall ); if ( pRet && ( pRet != pMethod ) ) *i_retValue = *pRet; return SbxBase::GetError(); } //===================================================================== class ModuleInfo_Impl : public ModuleInfoHelper { ::rtl::OUString maName; ::rtl::OUString maLanguage; ::rtl::OUString maSource; public: ModuleInfo_Impl( const ::rtl::OUString& aName, const ::rtl::OUString& aLanguage, const ::rtl::OUString& aSource ) : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {} // Methods XStarBasicModuleInfo virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException) { return maName; } virtual ::rtl::OUString SAL_CALL getLanguage() throw(RuntimeException) { return maLanguage; } virtual ::rtl::OUString SAL_CALL getSource() throw(RuntimeException) { return maSource; } }; //===================================================================== class DialogInfo_Impl : public DialogInfoHelper { ::rtl::OUString maName; Sequence< sal_Int8 > mData; public: DialogInfo_Impl( const ::rtl::OUString& aName, Sequence< sal_Int8 > Data ) : maName( aName ), mData( Data ) {} // Methods XStarBasicDialogInfo virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException) { return maName; } virtual Sequence< sal_Int8 > SAL_CALL getData() throw(RuntimeException) { return mData; } }; //===================================================================== class LibraryInfo_Impl : public LibraryInfoHelper { ::rtl::OUString maName; Reference< XNameContainer > mxModuleContainer; Reference< XNameContainer > mxDialogContainer; ::rtl::OUString maPassword; ::rtl::OUString maExternaleSourceURL; ::rtl::OUString maLinkTargetURL; public: LibraryInfo_Impl ( const ::rtl::OUString& aName, Reference< XNameContainer > xModuleContainer, Reference< XNameContainer > xDialogContainer, const ::rtl::OUString& aPassword, const ::rtl::OUString& aExternaleSourceURL, const ::rtl::OUString& aLinkTargetURL ) : maName( aName ) , mxModuleContainer( xModuleContainer ) , mxDialogContainer( xDialogContainer ) , maPassword( aPassword ) , maExternaleSourceURL( aExternaleSourceURL ) , maLinkTargetURL( aLinkTargetURL ) {} // Methods XStarBasicLibraryInfo virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException) { return maName; } virtual Reference< XNameContainer > SAL_CALL getModuleContainer() throw(RuntimeException) { return mxModuleContainer; } virtual Reference< XNameContainer > SAL_CALL getDialogContainer() throw(RuntimeException) { return mxDialogContainer; } virtual ::rtl::OUString SAL_CALL getPassword() throw(RuntimeException) { return maPassword; } virtual ::rtl::OUString SAL_CALL getExternalSourceURL() throw(RuntimeException) { return maExternaleSourceURL; } virtual ::rtl::OUString SAL_CALL getLinkTargetURL() throw(RuntimeException) { return maLinkTargetURL; } }; //===================================================================== class ModuleContainer_Impl : public NameContainerHelper { StarBASIC* mpLib; public: ModuleContainer_Impl( StarBASIC* pLib ) :mpLib( pLib ) {} // Methods XElementAccess virtual Type SAL_CALL getElementType() throw(RuntimeException); virtual sal_Bool SAL_CALL hasElements() throw(RuntimeException); // Methods XNameAccess virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException); virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw(RuntimeException); virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(RuntimeException); // Methods XNameReplace virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException); // Methods XNameContainer virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException); virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException); }; // Methods XElementAccess Type ModuleContainer_Impl::getElementType() throw(RuntimeException) { Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 ); return aModuleType; } sal_Bool ModuleContainer_Impl::hasElements() throw(RuntimeException) { SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL; return pMods && pMods->Count() > 0; } // Methods XNameAccess Any ModuleContainer_Impl::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) { SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL; if( !pMod ) throw NoSuchElementException(); Reference< XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl ( aName, ::rtl::OUString::createFromAscii( szScriptLanguage ), pMod->GetSource32() ); Any aRetAny; aRetAny <<= xMod; return aRetAny; } Sequence< ::rtl::OUString > ModuleContainer_Impl::getElementNames() throw(RuntimeException) { SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL; sal_uInt16 nMods = pMods ? pMods->Count() : 0; Sequence< ::rtl::OUString > aRetSeq( nMods ); ::rtl::OUString* pRetSeq = aRetSeq.getArray(); for( sal_uInt16 i = 0 ; i < nMods ; i++ ) { SbxVariable* pMod = pMods->Get( i ); pRetSeq[i] = ::rtl::OUString( pMod->GetName() ); } return aRetSeq; } sal_Bool ModuleContainer_Impl::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) { SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL; sal_Bool bRet = (pMod != NULL); return bRet; } // Methods XNameReplace void ModuleContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) { removeByName( aName ); insertByName( aName, aElement ); } // Methods XNameContainer void ModuleContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) { Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 ); Type aAnyType = aElement.getValueType(); if( aModuleType != aAnyType ) throw IllegalArgumentException(); Reference< XStarBasicModuleInfo > xMod; aElement >>= xMod; mpLib->MakeModule32( aName, xMod->getSource() ); } void ModuleContainer_Impl::removeByName( const ::rtl::OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) { SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL; if( !pMod ) throw NoSuchElementException(); mpLib->Remove( pMod ); } //===================================================================== Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog ) { SvMemoryStream aMemStream; pDialog->Store( aMemStream ); sal_Int32 nLen = aMemStream.Tell(); Sequence< sal_Int8 > aData( nLen ); sal_Int8* pDestData = aData.getArray(); const sal_Int8* pSrcData = (const sal_Int8*)aMemStream.GetData(); rtl_copyMemory( pDestData, pSrcData, nLen ); return aData; } SbxObject* implCreateDialog( Sequence< sal_Int8 > aData ) { sal_Int8* pData = aData.getArray(); SvMemoryStream aMemStream( pData, aData.getLength(), STREAM_READ ); SbxObject* pDialog = (SbxObject*)SbxBase::Load( aMemStream ); return pDialog; } // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx // which we can't include here, we have to use the value directly #define SBXID_DIALOG 101 class DialogContainer_Impl : public NameContainerHelper { StarBASIC* mpLib; public: DialogContainer_Impl( StarBASIC* pLib ) :mpLib( pLib ) {} // Methods XElementAccess virtual Type SAL_CALL getElementType() throw(RuntimeException); virtual sal_Bool SAL_CALL hasElements() throw(RuntimeException); // Methods XNameAccess virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException); virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw(RuntimeException); virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(RuntimeException); // Methods XNameReplace virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException); // Methods XNameContainer virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException); virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException); }; // Methods XElementAccess Type DialogContainer_Impl::getElementType() throw(RuntimeException) { Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 ); return aModuleType; } sal_Bool DialogContainer_Impl::hasElements() throw(RuntimeException) { sal_Bool bRet = sal_False; mpLib->GetAll( SbxCLASS_OBJECT ); sal_Int16 nCount = mpLib->GetObjects()->Count(); for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ ) { SbxVariable* pVar = mpLib->GetObjects()->Get( nObj ); if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) { bRet = sal_True; break; } } return bRet; } // Methods XNameAccess Any DialogContainer_Impl::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) { SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE ); if( !( pVar && pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) ) { throw NoSuchElementException(); } Reference< XStarBasicDialogInfo > xDialog = (XStarBasicDialogInfo*)new DialogInfo_Impl ( aName, implGetDialogData( (SbxObject*)pVar ) ); Any aRetAny; aRetAny <<= xDialog; return aRetAny; } Sequence< ::rtl::OUString > DialogContainer_Impl::getElementNames() throw(RuntimeException) { mpLib->GetAll( SbxCLASS_OBJECT ); sal_Int16 nCount = mpLib->GetObjects()->Count(); Sequence< ::rtl::OUString > aRetSeq( nCount ); ::rtl::OUString* pRetSeq = aRetSeq.getArray(); sal_Int32 nDialogCounter = 0; for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ ) { SbxVariable* pVar = mpLib->GetObjects()->Get( nObj ); if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) { pRetSeq[ nDialogCounter ] = ::rtl::OUString( pVar->GetName() ); nDialogCounter++; } } aRetSeq.realloc( nDialogCounter ); return aRetSeq; } sal_Bool DialogContainer_Impl::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) { sal_Bool bRet = sal_False; SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE ); if( pVar && pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) { bRet = sal_True; } return bRet; } // Methods XNameReplace void DialogContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) { removeByName( aName ); insertByName( aName, aElement ); } // Methods XNameContainer void DialogContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) { (void)aName; Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 ); Type aAnyType = aElement.getValueType(); if( aModuleType != aAnyType ) throw IllegalArgumentException(); Reference< XStarBasicDialogInfo > xMod; aElement >>= xMod; SbxObjectRef xDialog = implCreateDialog( xMod->getData() ); mpLib->Insert( xDialog ); } void DialogContainer_Impl::removeByName( const ::rtl::OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) { (void)Name; SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE ); if( !( pVar && pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) ) { throw NoSuchElementException(); } mpLib->Remove( pVar ); } //===================================================================== class LibraryContainer_Impl : public NameContainerHelper { BasicManager* mpMgr; public: LibraryContainer_Impl( BasicManager* pMgr ) :mpMgr( pMgr ) {} // Methods XElementAccess virtual Type SAL_CALL getElementType() throw(RuntimeException); virtual sal_Bool SAL_CALL hasElements() throw(RuntimeException); // Methods XNameAccess virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException); virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw(RuntimeException); virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw(RuntimeException); // Methods XNameReplace virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException); // Methods XNameContainer virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException); virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException); }; // Methods XElementAccess Type LibraryContainer_Impl::getElementType() throw(RuntimeException) { Type aType = ::getCppuType( (const Reference< XStarBasicLibraryInfo > *)0 ); return aType; } sal_Bool LibraryContainer_Impl::hasElements() throw(RuntimeException) { sal_Int32 nLibs = mpMgr->GetLibCount(); sal_Bool bRet = (nLibs > 0); return bRet; } // Methods XNameAccess Any LibraryContainer_Impl::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) { Any aRetAny; if( !mpMgr->HasLib( aName ) ) throw NoSuchElementException(); StarBASIC* pLib = mpMgr->GetLib( aName ); Reference< XNameContainer > xModuleContainer = (XNameContainer*)new ModuleContainer_Impl( pLib ); Reference< XNameContainer > xDialogContainer; (XNameContainer*)new DialogContainer_Impl( pLib ); BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib ); ::rtl::OUString aPassword = pLibInfo->GetPassword(); // TODO Only provide external info! ::rtl::OUString aExternaleSourceURL; ::rtl::OUString aLinkTargetURL; if( pLibInfo->IsReference() ) aLinkTargetURL = pLibInfo->GetStorageName(); else if( pLibInfo->IsExtern() ) aExternaleSourceURL = pLibInfo->GetStorageName(); Reference< XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl ( aName, xModuleContainer, xDialogContainer, aPassword, aExternaleSourceURL, aLinkTargetURL ); aRetAny <<= xLibInfo; return aRetAny; } Sequence< ::rtl::OUString > LibraryContainer_Impl::getElementNames() throw(RuntimeException) { sal_uInt16 nLibs = mpMgr->GetLibCount(); Sequence< ::rtl::OUString > aRetSeq( nLibs ); ::rtl::OUString* pRetSeq = aRetSeq.getArray(); for( sal_uInt16 i = 0 ; i < nLibs ; i++ ) { pRetSeq[i] = ::rtl::OUString( mpMgr->GetLibName( i ) ); } return aRetSeq; } sal_Bool LibraryContainer_Impl::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException) { sal_Bool bRet = mpMgr->HasLib( aName ); return bRet; } // Methods XNameReplace void LibraryContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) { removeByName( aName ); insertByName( aName, aElement ); } // Methods XNameContainer void LibraryContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) { (void)aName; (void)aElement; // TODO: Insert a complete Library?! } void LibraryContainer_Impl::removeByName( const ::rtl::OUString& Name ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) { StarBASIC* pLib = mpMgr->GetLib( Name ); if( !pLib ) throw NoSuchElementException(); sal_uInt16 nLibId = mpMgr->GetLibId( Name ); mpMgr->RemoveLib( nLibId ); } //===================================================================== typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper; class StarBasicAccess_Impl : public StarBasicAccessHelper { BasicManager* mpMgr; Reference< XNameContainer > mxLibContainer; public: StarBasicAccess_Impl( BasicManager* pMgr ) :mpMgr( pMgr ) {} public: // Methods virtual Reference< XNameContainer > SAL_CALL getLibraryContainer() throw(RuntimeException); virtual void SAL_CALL createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password, const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL ) throw(ElementExistException, RuntimeException); virtual void SAL_CALL addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName, const ::rtl::OUString& Language, const ::rtl::OUString& Source ) throw(NoSuchElementException, RuntimeException); virtual void SAL_CALL addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName, const Sequence< sal_Int8 >& Data ) throw(NoSuchElementException, RuntimeException); }; Reference< XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer() throw(RuntimeException) { if( !mxLibContainer.is() ) mxLibContainer = (XNameContainer*)new LibraryContainer_Impl( mpMgr ); return mxLibContainer; } void SAL_CALL StarBasicAccess_Impl::createLibrary ( const ::rtl::OUString& LibName, const ::rtl::OUString& Password, const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL ) throw(ElementExistException, RuntimeException) { (void)ExternalSourceURL; #ifdef DBG_UTIL StarBASIC* pLib = #endif mpMgr->CreateLib( LibName, Password, LinkTargetURL ); DBG_ASSERT( pLib, "XML Import: Basic library could not be created"); } void SAL_CALL StarBasicAccess_Impl::addModule ( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName, const ::rtl::OUString& Language, const ::rtl::OUString& Source ) throw(NoSuchElementException, RuntimeException) { (void)Language; StarBASIC* pLib = mpMgr->GetLib( LibraryName ); DBG_ASSERT( pLib, "XML Import: Lib for module unknown"); if( pLib ) pLib->MakeModule32( ModuleName, Source ); } void SAL_CALL StarBasicAccess_Impl::addDialog ( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName, const Sequence< sal_Int8 >& Data ) throw(NoSuchElementException, RuntimeException) { (void)LibraryName; (void)DialogName; (void)Data; } // Basic XML Import/Export Reference< XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr ) { Reference< XStarBasicAccess > xRet = new StarBasicAccess_Impl( (BasicManager*)pMgr ); return xRet; }