blob: 6ae4615261b9af9453d393b43c4caddff50c1214 [file] [log] [blame]
/**************************************************************
*
* 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 <tools/stream.hxx>
#include <sot/storage.hxx>
#include <tools/urlobj.hxx>
#include <svl/smplhint.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/msgbox.hxx>
#include <basic/sbx.hxx>
#include <sot/storinfo.hxx>
#include <unotools/pathoptions.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <basic/sbmod.hxx>
#include <basic/sbobjmod.hxx>
#include <unotools/intlwrapper.hxx>
#include <comphelper/processfactory.hxx>
#include <basic/sbuno.hxx>
#include <basic/basmgr.hxx>
#include <sbunoobj.hxx>
#include "basrid.hxx"
#include "sbintern.hxx"
#include <sb.hrc>
#define LIB_SEP 0x01
#define LIBINFO_SEP 0x02
#define LIBINFO_ID 0x1491
#define PASSWORD_MARKER 0x31452134
// Library API, implemented for XML import/export
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/script/XStarBasicAccess.hpp>
#include <com/sun/star/script/XStarBasicModuleInfo.hpp>
#include <com/sun/star/script/XStarBasicDialogInfo.hpp>
#include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
#include <com/sun/star/script/ModuleInfo.hpp>
#include <com/sun/star/script/vba/XVBACompatibility.hpp>
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
#include <cppuhelper/implbase1.hxx>
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 wont 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<SvStream*>(&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<SvStream*>(&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 os 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( !this, "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 failes...
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; n<nCount; ++n )
{
sQuotedArgs += '\"';
sQuotedArgs += sArgs.GetToken( n, ',' );
sQuotedArgs += '\"';
if ( n<nCount-1 )
sQuotedArgs += ',';
}
sQuotedArgs += ')';
}
// add quoted arguments and do the call
String sCall( '[' );
sCall += pMethod->GetName();
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 extern 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;
}