bump product version to 5.0.4.1
[LibreOffice.git] / basic / source / basmgr / basmgr.cxx
blob158f0d280a6ee0d73282164c318741fbf16304b6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/stream.hxx>
21 #include <sot/storage.hxx>
22 #include <tools/urlobj.hxx>
23 #include <svl/smplhint.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/window.hxx>
26 #include <vcl/wrkwin.hxx>
27 #include <vcl/msgbox.hxx>
28 #include <basic/sbx.hxx>
29 #include <sot/storinfo.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <tools/debug.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <basic/sbmod.hxx>
34 #include <unotools/intlwrapper.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/string.hxx>
38 #include <basic/sbuno.hxx>
39 #include <basic/basmgr.hxx>
40 #include "global.hxx"
41 #include <sbunoobj.hxx>
42 #include "basrid.hxx"
43 #include "sbintern.hxx"
44 #include <sb.hrc>
46 #include <vector>
47 #include <boost/ptr_container/ptr_vector.hpp>
49 #define LIB_SEP 0x01
50 #define LIBINFO_SEP 0x02
51 #define LIBINFO_ID 0x1491
52 #define PASSWORD_MARKER 0x31452134
55 // Library API, implemented for XML import/export
57 #include <com/sun/star/container/XNameContainer.hpp>
58 #include <com/sun/star/container/XContainer.hpp>
59 #include <com/sun/star/script/XStarBasicAccess.hpp>
60 #include <com/sun/star/script/XStarBasicModuleInfo.hpp>
61 #include <com/sun/star/script/XStarBasicDialogInfo.hpp>
62 #include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
63 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
64 #include <com/sun/star/script/ModuleInfo.hpp>
65 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
66 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
67 #include <com/sun/star/ucb/ContentCreationException.hpp>
69 #include <cppuhelper/implbase1.hxx>
71 using com::sun::star::uno::Reference;
72 using namespace com::sun::star;
73 using namespace com::sun::star::script;
74 using namespace cppu;
76 typedef WeakImplHelper1< container::XNameContainer > NameContainerHelper;
77 typedef WeakImplHelper1< script::XStarBasicModuleInfo > ModuleInfoHelper;
78 typedef WeakImplHelper1< script::XStarBasicDialogInfo > DialogInfoHelper;
79 typedef WeakImplHelper1< script::XStarBasicLibraryInfo > LibraryInfoHelper;
80 typedef WeakImplHelper1< script::XStarBasicAccess > StarBasicAccessHelper;
82 // Version 1
83 // sal_uIntPtr nEndPos
84 // sal_uInt16 nId
85 // sal_uInt16 nVer
86 // bool bDoLoad
87 // String LibName
88 // String AbsStorageName
89 // String RelStorageName
90 // Version 2
91 // + bool bReference
93 static const char szStdLibName[] = "Standard";
94 static const char szBasicStorage[] = "StarBASIC";
95 static const char szOldManagerStream[] = "BasicManager";
96 static const char szManagerStream[] = "BasicManager2";
97 static const char szImbedded[] = "LIBIMBEDDED";
98 static const char szCryptingKey[] = "CryptedBasic";
100 TYPEINIT1( BasicManager, SfxBroadcaster );
102 const StreamMode eStreamReadMode = StreamMode::READ | StreamMode::NOCREATE | StreamMode::SHARE_DENYALL;
103 const StreamMode eStorageReadMode = StreamMode::READ | StreamMode::SHARE_DENYWRITE;
106 // BasicManager impl data
107 struct BasicManagerImpl
109 LibraryContainerInfo maContainerInfo;
111 // Save stream data
112 SvMemoryStream* mpManagerStream;
113 SvMemoryStream** mppLibStreams;
114 sal_Int32 mnLibStreamCount;
116 boost::ptr_vector<BasicLibInfo> aLibs;
117 OUString aBasicLibPath;
119 BasicManagerImpl()
120 : mpManagerStream( NULL )
121 , mppLibStreams( NULL )
122 , mnLibStreamCount( 0 )
124 ~BasicManagerImpl();
127 BasicManagerImpl::~BasicManagerImpl()
129 delete mpManagerStream;
130 if( mppLibStreams )
132 for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ )
133 delete mppLibStreams[i];
134 delete[] mppLibStreams;
139 // BasMgrContainerListenerImpl
142 typedef ::cppu::WeakImplHelper1< container::XContainerListener > ContainerListenerHelper;
144 class BasMgrContainerListenerImpl: public ContainerListenerHelper
146 BasicManager* mpMgr;
147 OUString maLibName; // empty -> no lib, but lib container
149 public:
150 BasMgrContainerListenerImpl( BasicManager* pMgr, const OUString& aLibName )
151 : mpMgr( pMgr )
152 , maLibName( aLibName ) {}
154 static void insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, BasicManager* pMgr,
155 uno::Any aLibAny, const OUString& aLibName );
156 static void addLibraryModulesImpl( BasicManager* pMgr, uno::Reference< container::XNameAccess > xLibNameAccess,
157 const OUString& aLibName );
160 // XEventListener
161 virtual void SAL_CALL disposing( const lang::EventObject& Source )
162 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
164 // XContainerListener
165 virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event )
166 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
167 virtual void SAL_CALL elementReplaced( const container::ContainerEvent& Event )
168 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
169 virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event )
170 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
175 // BasMgrContainerListenerImpl
178 void BasMgrContainerListenerImpl::insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont,
179 BasicManager* pMgr, uno::Any aLibAny, const OUString& aLibName )
181 Reference< container::XNameAccess > xLibNameAccess;
182 aLibAny >>= xLibNameAccess;
184 if( !pMgr->GetLib( aLibName ) )
186 BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr );
187 #ifdef DBG_UTIL
188 StarBASIC* pLib =
189 #endif
190 pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont );
191 DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
194 uno::Reference< container::XContainer> xLibContainer( xLibNameAccess, uno::UNO_QUERY );
195 if( xLibContainer.is() )
197 // Register listener for library
198 Reference< container::XContainerListener > xLibraryListener
199 = static_cast< container::XContainerListener* >
200 ( new BasMgrContainerListenerImpl( pMgr, aLibName ) );
201 xLibContainer->addContainerListener( xLibraryListener );
204 if( xScriptCont->isLibraryLoaded( aLibName ) )
206 addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
211 void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr,
212 uno::Reference< container::XNameAccess > xLibNameAccess, const OUString& aLibName )
214 uno::Sequence< OUString > aModuleNames = xLibNameAccess->getElementNames();
215 sal_Int32 nModuleCount = aModuleNames.getLength();
217 StarBASIC* pLib = pMgr->GetLib( aLibName );
218 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
219 if( pLib )
221 const OUString* pNames = aModuleNames.getConstArray();
222 for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
224 OUString aModuleName = pNames[ j ];
225 uno::Any aElement = xLibNameAccess->getByName( aModuleName );
226 OUString aMod;
227 aElement >>= aMod;
228 uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, uno::UNO_QUERY );
229 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) )
231 ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName );
232 OSL_TRACE("#addLibraryModulesImpl - aMod");
233 pLib->MakeModule32( aModuleName, mInfo, aMod );
235 else
236 pLib->MakeModule32( aModuleName, aMod );
239 pLib->SetModified( false );
245 // XEventListener
248 void SAL_CALL BasMgrContainerListenerImpl::disposing( const lang::EventObject& Source )
249 throw( uno::RuntimeException, std::exception )
251 (void)Source;
254 // XContainerListener
257 void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const container::ContainerEvent& Event )
258 throw( uno::RuntimeException, std::exception )
260 bool bLibContainer = maLibName.isEmpty();
261 OUString aName;
262 Event.Accessor >>= aName;
264 if( bLibContainer )
266 uno::Reference< script::XLibraryContainer > xScriptCont( Event.Source, uno::UNO_QUERY );
267 insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName );
268 StarBASIC* pLib = mpMgr->GetLib( aName );
269 if ( pLib )
271 uno::Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, uno::UNO_QUERY );
272 if ( xVBACompat.is() )
273 pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() );
276 else
279 StarBASIC* pLib = mpMgr->GetLib( maLibName );
280 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
281 if( pLib )
283 SbModule* pMod = pLib->FindModule( aName );
284 if( !pMod )
286 OUString aMod;
287 Event.Element >>= aMod;
288 uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, uno::UNO_QUERY );
289 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) )
291 ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName );
292 pLib->MakeModule32( aName, mInfo, aMod );
294 else
295 pLib->MakeModule32( aName, aMod );
296 pLib->SetModified( false );
304 void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const container::ContainerEvent& Event )
305 throw( uno::RuntimeException, std::exception )
307 OUString aName;
308 Event.Accessor >>= aName;
310 // Replace not possible for library container
311 #ifdef DBG_UTIL
312 bool bLibContainer = maLibName.isEmpty();
313 #endif
314 DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()");
316 StarBASIC* pLib = mpMgr->GetLib( maLibName );
317 if( pLib )
319 SbModule* pMod = pLib->FindModule( aName );
320 OUString aMod;
321 Event.Element >>= aMod;
323 if( pMod )
324 pMod->SetSource32( aMod );
325 else
326 pLib->MakeModule32( aName, aMod );
328 pLib->SetModified( false );
334 void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const container::ContainerEvent& Event )
335 throw( uno::RuntimeException, std::exception )
337 OUString aName;
338 Event.Accessor >>= aName;
340 bool bLibContainer = maLibName.isEmpty();
341 if( bLibContainer )
343 StarBASIC* pLib = mpMgr->GetLib( aName );
344 if( pLib )
346 sal_uInt16 nLibId = mpMgr->GetLibId( aName );
347 mpMgr->RemoveLib( nLibId, false );
350 else
352 StarBASIC* pLib = mpMgr->GetLib( maLibName );
353 SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL;
354 if( pMod )
356 pLib->Remove( pMod );
357 pLib->SetModified( false );
362 BasicError::BasicError( sal_uInt64 nId, BasicErrorReason nR, const OUString& rErrStr ) :
363 aErrStr( rErrStr )
365 nErrorId = nId;
366 nReason = nR;
369 BasicError::BasicError( const BasicError& rErr ) :
370 aErrStr( rErr.aErrStr )
372 nErrorId = rErr.nErrorId;
373 nReason = rErr.nReason;
379 class BasicLibInfo
381 private:
382 StarBASICRef xLib;
383 OUString aLibName;
384 OUString aStorageName; // string is sufficient, unique at runtime
385 OUString aRelStorageName;
386 OUString aPassword;
388 bool bDoLoad;
389 bool bReference;
390 bool bPasswordVerified;
392 // Lib represents library in new UNO library container
393 uno::Reference< script::XLibraryContainer > mxScriptCont;
395 public:
396 BasicLibInfo();
398 bool& IsReference() { return bReference; }
400 bool IsExtern() const { return aStorageName != szImbedded; }
402 void SetStorageName( const OUString& rName ) { aStorageName = rName; }
403 const OUString& GetStorageName() const { return aStorageName; }
405 void SetRelStorageName( const OUString& rN ) { aRelStorageName = rN; }
406 const OUString& GetRelStorageName() const { return aRelStorageName; }
408 StarBASICRef GetLib() const
410 if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
411 !mxScriptCont->isLibraryLoaded( aLibName ) )
412 return StarBASICRef();
413 return xLib;
415 StarBASICRef& GetLibRef() { return xLib; }
416 void SetLib( StarBASIC* pBasic ) { xLib = pBasic; }
418 const OUString& GetLibName() const { return aLibName; }
419 void SetLibName( const OUString& rName ) { aLibName = rName; }
421 // Only temporary for Load/Save
422 bool DoLoad() { return bDoLoad; }
424 bool HasPassword() const { return !aPassword.isEmpty(); }
425 const OUString& GetPassword() const { return aPassword; }
426 void SetPassword( const OUString& rNewPassword )
427 { aPassword = rNewPassword; }
428 void SetPasswordVerified() { bPasswordVerified = true; }
430 static BasicLibInfo* Create( SotStorageStream& rSStream );
432 uno::Reference< script::XLibraryContainer > GetLibraryContainer()
433 { return mxScriptCont; }
434 void SetLibraryContainer( const uno::Reference< script::XLibraryContainer >& xScriptCont )
435 { mxScriptCont = xScriptCont; }
439 BasicLibInfo::BasicLibInfo()
441 bReference = false;
442 bPasswordVerified = false;
443 bDoLoad = false;
444 mxScriptCont = NULL;
445 aStorageName = szImbedded;
446 aRelStorageName = szImbedded;
449 BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
451 BasicLibInfo* pInfo = new BasicLibInfo;
453 sal_uInt32 nEndPos;
454 sal_uInt16 nId;
455 sal_uInt16 nVer;
457 rSStream.ReadUInt32( nEndPos );
458 rSStream.ReadUInt16( nId );
459 rSStream.ReadUInt16( nVer );
461 DBG_ASSERT( nId == LIBINFO_ID, "No BasicLibInfo?!" );
462 if( nId == LIBINFO_ID )
464 // Reload?
465 bool bDoLoad;
466 rSStream.ReadCharAsBool( bDoLoad );
467 pInfo->bDoLoad = bDoLoad;
469 // The name of the lib...
470 OUString aName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
471 pInfo->SetLibName( aName );
473 // Absolute path...
474 OUString aStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
475 pInfo->SetStorageName( aStorageName );
477 // Relative path...
478 OUString aRelStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
479 pInfo->SetRelStorageName( aRelStorageName );
481 if ( nVer >= 2 )
483 bool bReferenz;
484 rSStream.ReadCharAsBool( bReferenz );
485 pInfo->IsReference() = bReferenz;
488 rSStream.Seek( nEndPos );
490 return pInfo;
493 BasicManager::BasicManager( SotStorage& rStorage, const OUString& rBaseURL, StarBASIC* pParentFromStdLib, OUString* pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr )
495 Init();
497 if( pLibPath )
499 mpImpl->aBasicLibPath = *pLibPath;
501 OUString aStorName( rStorage.GetName() );
502 maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::NO_DECODE );
505 // If there is no Manager Stream, no further actions are necessary
506 if ( rStorage.IsStream( OUString(szManagerStream) ) )
508 LoadBasicManager( rStorage, rBaseURL );
509 // StdLib contains Parent:
510 StarBASIC* pStdLib = GetStdLib();
511 DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" );
512 if ( !pStdLib )
514 // Should never happen, but if it happens we wont crash...
515 pStdLib = new StarBASIC( NULL, mbDocMgr );
517 if (mpImpl->aLibs.empty())
518 CreateLibInfo();
520 BasicLibInfo& rStdLibInfo = mpImpl->aLibs.front();
522 rStdLibInfo.SetLib( pStdLib );
523 StarBASICRef xStdLib = rStdLibInfo.GetLib();
524 xStdLib->SetName( OUString(szStdLibName) );
525 rStdLibInfo.SetLibName( OUString(szStdLibName) );
526 xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
527 xStdLib->SetModified( false );
529 else
531 pStdLib->SetParent( pParentFromStdLib );
532 // The other get StdLib as parent:
534 for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ )
536 StarBASIC* pBasic = GetLib( nBasic );
537 if ( pBasic )
539 pStdLib->Insert( pBasic );
540 pBasic->SetFlag( SBX_EXTSEARCH );
543 // Modified through insert
544 pStdLib->SetModified( false );
547 // #91626 Save all stream data to save it unmodified if basic isn't modified
548 // in an 6.0+ office. So also the old basic dialogs can be saved.
549 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( OUString(szManagerStream), eStreamReadMode );
550 mpImpl->mpManagerStream = new SvMemoryStream();
551 static_cast<SvStream*>(&xManagerStream)->ReadStream( *mpImpl->mpManagerStream );
553 tools::SvRef<SotStorage> xBasicStorage = rStorage.OpenSotStorage( OUString(szBasicStorage), eStorageReadMode, false );
554 if( xBasicStorage.Is() && !xBasicStorage->GetError() )
556 sal_uInt16 nLibs = GetLibCount();
557 mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ];
558 for( sal_uInt16 nL = 0; nL < nLibs; nL++ )
560 BasicLibInfo& rInfo = mpImpl->aLibs[nL];
561 tools::SvRef<SotStorageStream> xBasicStream = xBasicStorage->OpenSotStream( rInfo.GetLibName(), eStreamReadMode );
562 mpImpl->mppLibStreams[nL] = new SvMemoryStream();
563 static_cast<SvStream*>(&xBasicStream)->ReadStream( *( mpImpl->mppLibStreams[nL] ) );
567 else
569 ImpCreateStdLib( pParentFromStdLib );
570 if ( rStorage.IsStream( OUString(szOldManagerStream) ) )
571 LoadOldBasicManager( rStorage );
575 void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
577 uno::Reference< script::XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
578 if ( !xScriptCont.is() )
579 return;
581 OUString aLibName = pBasic->GetName();
582 if( !xScriptCont->hasByName( aLibName ) )
583 xScriptCont->createLibrary( aLibName );
585 uno::Any aLibAny = xScriptCont->getByName( aLibName );
586 uno::Reference< container::XNameContainer > xLib;
587 aLibAny >>= xLib;
588 if ( !xLib.is() )
589 return;
591 sal_uInt16 nModCount = pBasic->GetModules()->Count();
592 for ( sal_uInt16 nMod = 0 ; nMod < nModCount ; nMod++ )
594 SbModule* pModule = static_cast<SbModule*>(pBasic->GetModules()->Get( nMod ));
595 DBG_ASSERT( pModule, "Module not received!" );
597 OUString aModName = pModule->GetName();
598 if( !xLib->hasByName( aModName ) )
600 OUString aSource = pModule->GetSource32();
601 uno::Any aSourceAny;
602 aSourceAny <<= aSource;
603 xLib->insertByName( aModName, aSourceAny );
608 const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const
610 return mpImpl->maContainerInfo.mxDialogCont;
613 const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const
615 return mpImpl->maContainerInfo.mxScriptCont;
618 void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
620 mpImpl->maContainerInfo = rInfo;
622 uno::Reference< script::XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
623 if( xScriptCont.is() )
625 // Register listener for lib container
626 OUString aEmptyLibName;
627 uno::Reference< container::XContainerListener > xLibContainerListener
628 = static_cast< container::XContainerListener* >
629 ( new BasMgrContainerListenerImpl( this, aEmptyLibName ) );
631 uno::Reference< container::XContainer> xLibContainer( xScriptCont, uno::UNO_QUERY );
632 xLibContainer->addContainerListener( xLibContainerListener );
634 uno::Sequence< OUString > aScriptLibNames = xScriptCont->getElementNames();
635 const OUString* pScriptLibName = aScriptLibNames.getConstArray();
636 sal_Int32 i, nNameCount = aScriptLibNames.getLength();
638 if( nNameCount )
640 for( i = 0 ; i < nNameCount ; ++i, ++pScriptLibName )
642 uno::Any aLibAny = xScriptCont->getByName( *pScriptLibName );
644 if ( *pScriptLibName == "Standard" )
645 xScriptCont->loadLibrary( *pScriptLibName );
647 BasMgrContainerListenerImpl::insertLibraryImpl
648 ( xScriptCont, this, aLibAny, *pScriptLibName );
651 else
653 // No libs? Maybe an 5.2 document already loaded
654 for( BasicLibInfo& rBasLibInfo: mpImpl->aLibs )
656 StarBASIC* pLib = rBasLibInfo.GetLib();
657 if( !pLib )
659 bool bLoaded = ImpLoadLibrary( &rBasLibInfo, NULL, false );
660 if( bLoaded )
661 pLib = rBasLibInfo.GetLib();
663 if( pLib )
665 copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
666 if( rBasLibInfo.HasPassword() )
668 OldBasicPassword* pOldBasicPassword =
669 mpImpl->maContainerInfo.mpOldBasicPassword;
670 if( pOldBasicPassword )
672 pOldBasicPassword->setLibraryPassword
673 ( pLib->GetName(), rBasLibInfo.GetPassword() );
674 rBasLibInfo.SetPasswordVerified();
682 SetGlobalUNOConstant( "BasicLibraries", makeAny( mpImpl->maContainerInfo.mxScriptCont ) );
683 SetGlobalUNOConstant( "DialogLibraries", makeAny( mpImpl->maContainerInfo.mxDialogCont ) );
686 BasicManager::BasicManager( StarBASIC* pSLib, OUString* pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr )
688 Init();
689 DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" );
691 if( pLibPath )
693 mpImpl->aBasicLibPath = *pLibPath;
695 BasicLibInfo* pStdLibInfo = CreateLibInfo();
696 pStdLibInfo->SetLib( pSLib );
697 StarBASICRef xStdLib = pStdLibInfo->GetLib();
698 xStdLib->SetName(OUString(szStdLibName));
699 pStdLibInfo->SetLibName(OUString(szStdLibName) );
700 pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
702 // Save is only necessary if basic has changed
703 xStdLib->SetModified( false );
706 void BasicManager::ImpMgrNotLoaded( const OUString& rStorageName )
708 // pErrInf is only destroyed if the error os processed by an
709 // ErrorHandler
710 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK );
711 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::OPENMGRSTREAM, rStorageName));
713 // Create a stdlib otherwise we crash!
714 BasicLibInfo* pStdLibInfo = CreateLibInfo();
715 pStdLibInfo->SetLib( new StarBASIC( NULL, mbDocMgr ) );
716 StarBASICRef xStdLib = pStdLibInfo->GetLib();
717 xStdLib->SetName( OUString(szStdLibName) );
718 pStdLibInfo->SetLibName( OUString(szStdLibName) );
719 xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
720 xStdLib->SetModified( false );
724 void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
726 BasicLibInfo* pStdLibInfo = CreateLibInfo();
727 StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
728 pStdLibInfo->SetLib( pStdLib );
729 pStdLib->SetName( OUString(szStdLibName) );
730 pStdLibInfo->SetLibName( OUString(szStdLibName) );
731 pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
734 void BasicManager::LoadBasicManager( SotStorage& rStorage, const OUString& rBaseURL, bool bLoadLibs )
736 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( OUString(szManagerStream), eStreamReadMode );
738 OUString aStorName( rStorage.GetName() );
739 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
741 if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
743 ImpMgrNotLoaded( aStorName );
744 return;
747 maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::NO_DECODE );
748 // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
750 OUString aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL
752 if ( !rBaseURL.isEmpty() )
754 INetURLObject aObj( rBaseURL );
755 if ( aObj.GetProtocol() == INetProtocol::File )
757 aRealStorageName = aObj.PathToFileName();
761 xManagerStream->SetBufferSize( 1024 );
762 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
764 sal_uInt32 nEndPos;
765 xManagerStream->ReadUInt32( nEndPos );
767 sal_uInt16 nLibs;
768 xManagerStream->ReadUInt16( nLibs );
769 // Plausibility!
770 if( nLibs & 0xF000 )
772 DBG_ASSERT( false, "BasicManager-Stream defect!" );
773 return;
775 const size_t nMinBasicLibSize(8);
776 const size_t nMaxPossibleLibs = xManagerStream->remainingSize() / nMinBasicLibSize;
777 if (nLibs > nMaxPossibleLibs)
779 SAL_WARN("basic", "Parsing error: " << nMaxPossibleLibs <<
780 " max possible entries, but " << nLibs << " claimed, truncating");
781 nLibs = nMaxPossibleLibs;
783 for (sal_uInt16 nL = 0; nL < nLibs; ++nL)
785 BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
787 // Correct absolute pathname if relative is existing.
788 // Always try relative first if there are two stands on disk
789 if ( !pInfo->GetRelStorageName().isEmpty() && pInfo->GetRelStorageName() != szImbedded )
791 INetURLObject aObj( aRealStorageName, INetProtocol::File );
792 aObj.removeSegment();
793 bool bWasAbsolute = false;
794 aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
796 //*** TODO: Replace if still necessary
797 //*** TODO-End
798 if ( ! mpImpl->aBasicLibPath.isEmpty() )
800 // Search lib in path
801 OUString aSearchFile = pInfo->GetRelStorageName();
802 OUString aSearchFileOldFormat(aSearchFile);
803 SvtPathOptions aPathCFG;
804 if( aPathCFG.SearchFile( aSearchFileOldFormat, SvtPathOptions::PATH_BASIC ) )
806 pInfo->SetStorageName( aSearchFile );
811 mpImpl->aLibs.push_back( pInfo );
812 // Libs from external files should be loaded only when necessary.
813 // But references are loaded at once, otherwise some big customers get into trouble
814 if ( bLoadLibs && pInfo->DoLoad() &&
815 ( !pInfo->IsExtern() || pInfo->IsReference()))
817 ImpLoadLibrary( pInfo, &rStorage );
821 xManagerStream->Seek( nEndPos );
822 xManagerStream->SetBufferSize( 0 );
823 xManagerStream.Clear();
826 void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
828 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( OUString(szOldManagerStream), eStreamReadMode );
830 OUString aStorName( rStorage.GetName() );
831 DBG_ASSERT( aStorName.getLength(), "No Storage Name!" );
833 if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
835 ImpMgrNotLoaded( aStorName );
836 return;
839 xManagerStream->SetBufferSize( 1024 );
840 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
841 sal_uInt32 nBasicStartOff, nBasicEndOff;
842 xManagerStream->ReadUInt32( nBasicStartOff );
843 xManagerStream->ReadUInt32( nBasicEndOff );
845 DBG_ASSERT( !xManagerStream->GetError(), "Invalid Manager-Stream!" );
847 xManagerStream->Seek( nBasicStartOff );
848 if( !ImplLoadBasic( *xManagerStream, mpImpl->aLibs.front().GetLibRef() ) )
850 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK );
851 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::OPENMGRSTREAM, aStorName));
852 // and it proceeds ...
854 xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator
855 OUString aLibs = xManagerStream->ReadUniOrByteString(xManagerStream->GetStreamCharSet());
856 xManagerStream->SetBufferSize( 0 );
857 xManagerStream.Clear(); // Close stream
859 if ( !aLibs.isEmpty() )
861 OUString aCurStorageName( aStorName );
862 INetURLObject aCurStorage( aCurStorageName, INetProtocol::File );
863 sal_Int32 nLibs = comphelper::string::getTokenCount(aLibs, LIB_SEP);
864 for ( sal_Int32 nLib = 0; nLib < nLibs; nLib++ )
866 OUString aLibInfo(aLibs.getToken(nLib, LIB_SEP));
867 // TODO: Remove == 2
868 DBG_ASSERT( ( comphelper::string::getTokenCount(aLibInfo, LIBINFO_SEP) == 2 ) || ( comphelper::string::getTokenCount(aLibInfo, LIBINFO_SEP) == 3 ), "Invalid Lib-Info!" );
869 OUString aLibName( aLibInfo.getToken( 0, LIBINFO_SEP ) );
870 OUString aLibAbsStorageName( aLibInfo.getToken( 1, LIBINFO_SEP ) );
871 OUString aLibRelStorageName( aLibInfo.getToken( 2, LIBINFO_SEP ) );
872 INetURLObject aLibAbsStorage( aLibAbsStorageName, INetProtocol::File );
874 INetURLObject aLibRelStorage( aStorName );
875 aLibRelStorage.removeSegment();
876 bool bWasAbsolute = false;
877 aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
878 DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
880 tools::SvRef<SotStorage> xStorageRef;
881 if ( aLibAbsStorage == aCurStorage || aLibRelStorageName == szImbedded )
883 xStorageRef = &rStorage;
885 else
887 xStorageRef = new SotStorage( false, aLibAbsStorage.GetMainURL
888 ( INetURLObject::NO_DECODE ), eStorageReadMode );
889 if ( xStorageRef->GetError() != ERRCODE_NONE )
890 xStorageRef = new SotStorage( false, aLibRelStorage.
891 GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode );
893 if ( xStorageRef.Is() )
895 AddLib( *xStorageRef, aLibName, false );
897 else
899 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK );
900 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::STORAGENOTFOUND, aStorName));
906 BasicManager::~BasicManager()
908 // Notify listener if something needs to be saved
909 Broadcast( SfxSimpleHint( SFX_HINT_DYING) );
911 // Destroy Basic-Infos...
912 // In reverse order
913 delete mpImpl;
916 void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
918 delete _rpManager;
919 _rpManager = NULL;
923 bool BasicManager::HasExeCode( const OUString& sLib )
925 StarBASIC* pLib = GetLib(sLib);
926 if ( pLib )
928 SbxArray* pMods = pLib->GetModules();
929 sal_uInt16 nMods = pMods ? pMods->Count() : 0;
930 for( sal_uInt16 i = 0; i < nMods; i++ )
932 SbModule* p = static_cast<SbModule*>( pMods->Get( i ) );
933 if ( p )
934 if ( p->HasExeCode() )
935 return true;
938 return false;
941 void BasicManager::Init()
943 mpImpl = new BasicManagerImpl();
946 BasicLibInfo* BasicManager::CreateLibInfo()
948 BasicLibInfo* pInf = new BasicLibInfo;
949 mpImpl->aLibs.push_back( pInf );
950 return pInf;
953 bool BasicManager::ImpLoadLibrary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, bool bInfosOnly )
955 try {
956 DBG_ASSERT( pLibInfo, "LibInfo!?" );
958 OUString aStorageName( pLibInfo->GetStorageName() );
959 if ( aStorageName.isEmpty() || aStorageName == szImbedded )
961 aStorageName = GetStorageName();
963 tools::SvRef<SotStorage> xStorage;
964 // The current must not be opened again...
965 if ( pCurStorage )
967 OUString aStorName( pCurStorage->GetName() );
968 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
970 INetURLObject aCurStorageEntry(aStorName, INetProtocol::File);
971 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
973 INetURLObject aStorageEntry(aStorageName, INetProtocol::File);
974 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
976 if ( aCurStorageEntry == aStorageEntry )
978 xStorage = pCurStorage;
982 if ( !xStorage.Is() )
984 xStorage = new SotStorage( false, aStorageName, eStorageReadMode );
986 tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage( OUString(szBasicStorage), eStorageReadMode, false );
988 if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
990 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), ERRCODE_BUTTON_OK );
991 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::OPENLIBSTORAGE, pLibInfo->GetLibName()));
993 else
995 // In the Basic-Storage every lib is in a Stream...
996 tools::SvRef<SotStorageStream> xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
997 if ( !xBasicStream.Is() || xBasicStream->GetError() )
999 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1000 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::OPENLIBSTREAM, pLibInfo->GetLibName()));
1002 else
1004 bool bLoaded = false;
1005 if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 )
1007 if ( !bInfosOnly )
1009 if ( !pLibInfo->GetLib().Is() )
1011 pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
1013 xBasicStream->SetBufferSize( 1024 );
1014 xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1015 bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
1016 xBasicStream->SetBufferSize( 0 );
1017 StarBASICRef xStdLib = pLibInfo->GetLib();
1018 xStdLib->SetName( pLibInfo->GetLibName() );
1019 xStdLib->SetModified( false );
1020 xStdLib->SetFlag( SBX_DONTSTORE );
1022 else
1024 // Skip Basic...
1025 xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1026 ImplEncryptStream( *xBasicStream );
1027 SbxBase::Skip( *xBasicStream );
1028 bLoaded = true;
1031 if ( !bLoaded )
1033 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1034 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::BASICLOADERROR, pLibInfo->GetLibName()));
1036 else
1038 // Perhaps there are additional information in the stream...
1039 xBasicStream->SetCryptMaskKey(szCryptingKey);
1040 xBasicStream->RefreshBuffer();
1041 sal_uInt32 nPasswordMarker = 0;
1042 xBasicStream->ReadUInt32( nPasswordMarker );
1043 if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() )
1045 OUString aPassword = xBasicStream->ReadUniOrByteString(
1046 xBasicStream->GetStreamCharSet());
1047 pLibInfo->SetPassword( aPassword );
1049 xBasicStream->SetCryptMaskKey(OString());
1050 CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() );
1052 return bLoaded;
1056 catch (const css::ucb::ContentCreationException&)
1059 return false;
1062 bool BasicManager::ImplEncryptStream( SvStream& rStrm )
1064 sal_Size nPos = rStrm.Tell();
1065 sal_uInt32 nCreator;
1066 rStrm.ReadUInt32( nCreator );
1067 rStrm.Seek( nPos );
1068 bool bProtected = false;
1069 if ( nCreator != SBXCR_SBX )
1071 // Should only be the case for encrypted Streams
1072 bProtected = true;
1073 rStrm.SetCryptMaskKey(szCryptingKey);
1074 rStrm.RefreshBuffer();
1076 return bProtected;
1079 // This code is necessary to load the BASIC of Beta 1
1080 // TODO: Which Beta 1?
1081 bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
1083 bool bProtected = ImplEncryptStream( rStrm );
1084 SbxBaseRef xNew = SbxBase::Load( rStrm );
1085 bool bLoaded = false;
1086 if( xNew.Is() )
1088 if( xNew->IsA( TYPE(StarBASIC) ) )
1090 StarBASIC* pNew = static_cast<StarBASIC*>((SbxBase*) xNew);
1091 // Use the Parent of the old BASICs
1092 if( rOldBasic.Is() )
1094 pNew->SetParent( rOldBasic->GetParent() );
1095 if( pNew->GetParent() )
1097 pNew->GetParent()->Insert( pNew );
1099 pNew->SetFlag( SBX_EXTSEARCH );
1101 rOldBasic = pNew;
1103 // Fill new libray container (5.2 -> 6.0)
1104 copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
1106 pNew->SetModified( false );
1107 bLoaded = true;
1110 if ( bProtected )
1112 rStrm.SetCryptMaskKey(OString());
1114 return bLoaded;
1117 void BasicManager::CheckModules( StarBASIC* pLib, bool bReference )
1119 if ( !pLib )
1121 return;
1123 bool bModified = pLib->IsModified();
1125 for ( sal_uInt16 nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ )
1127 SbModule* pModule = static_cast<SbModule*>(pLib->GetModules()->Get( nMod ));
1128 DBG_ASSERT( pModule, "Module not received!" );
1129 if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
1131 StarBASIC::Compile( pModule );
1135 // #67477, AB 8.12.99 On demand compile in referenced libs should not
1136 // cause modified
1137 if( !bModified && bReference )
1139 OSL_FAIL( "Referenced basic library is not compiled!" );
1140 pLib->SetModified( false );
1144 StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const OUString& rLibName, bool bReference )
1146 OUString aStorName( rStorage.GetName() );
1147 DBG_ASSERT( !aStorName.isEmpty(), "No Storage Name!" );
1149 OUString aStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::NO_DECODE );
1150 DBG_ASSERT(!aStorageName.isEmpty(), "Bad storage name");
1152 OUString aNewLibName( rLibName );
1153 while ( HasLib( aNewLibName ) )
1155 aNewLibName += "_";
1157 BasicLibInfo* pLibInfo = CreateLibInfo();
1158 // Use original name otherwise ImpLoadLibrary failes...
1159 pLibInfo->SetLibName( rLibName );
1160 // but doesn't work this way if name exists twice
1161 sal_uInt16 nLibId = (sal_uInt16) mpImpl->aLibs.size() - 1;
1163 // Set StorageName before load because it is compared with pCurStorage
1164 pLibInfo->SetStorageName( aStorageName );
1165 bool bLoaded = ImpLoadLibrary( pLibInfo, &rStorage );
1167 if ( bLoaded )
1169 if ( aNewLibName != rLibName )
1171 pLibInfo->SetLibName(aNewLibName);
1173 if ( bReference )
1175 pLibInfo->GetLib()->SetModified( false ); // Don't save in this case
1176 pLibInfo->SetRelStorageName( OUString() );
1177 pLibInfo->IsReference() = true;
1179 else
1181 pLibInfo->GetLib()->SetModified( true ); // Must be saved after Add!
1182 pLibInfo->SetStorageName( OUString(szImbedded) ); // Save in BasicManager-Storage
1185 else
1187 RemoveLib( nLibId, false );
1188 pLibInfo = 0;
1191 return pLibInfo ? &*pLibInfo->GetLib() : 0;
1195 bool BasicManager::IsReference( sal_uInt16 nLib )
1197 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" );
1198 if ( nLib < mpImpl->aLibs.size() )
1200 return mpImpl->aLibs[nLib].IsReference();
1202 return false;
1205 bool BasicManager::RemoveLib( sal_uInt16 nLib )
1207 // Only pyhsical deletion if no reference
1208 return RemoveLib( nLib, !IsReference( nLib ) );
1211 bool BasicManager::RemoveLib( sal_uInt16 nLib, bool bDelBasicFromStorage )
1213 DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" );
1215 DBG_ASSERT( !nLib || nLib < mpImpl->aLibs.size(), "Lib not found!" );
1217 if( !nLib || nLib < mpImpl->aLibs.size() )
1219 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, OUString(), ERRCODE_BUTTON_OK );
1220 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::STDLIB, OUString()));
1221 return false;
1224 boost::ptr_vector<BasicLibInfo>::iterator itLibInfo = mpImpl->aLibs.begin() + nLib;
1226 // If one of the streams cannot be opened, this is not an error,
1227 // because BASIC was never written before...
1228 if ( bDelBasicFromStorage && !itLibInfo->IsReference() &&
1229 ( !itLibInfo->IsExtern() || SotStorage::IsStorageFile( itLibInfo->GetStorageName() ) ) )
1231 tools::SvRef<SotStorage> xStorage;
1234 if (!itLibInfo->IsExtern())
1236 xStorage = new SotStorage(false, GetStorageName());
1238 else
1240 xStorage = new SotStorage(false, itLibInfo->GetStorageName());
1243 catch (const css::ucb::ContentCreationException& e)
1245 SAL_WARN("basic", "BasicManager::RemoveLib: Caught exception: " << e.Message);
1248 if (xStorage.Is() && xStorage->IsStorage(OUString(szBasicStorage)))
1250 tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage
1251 ( OUString(szBasicStorage), STREAM_STD_READWRITE, false );
1253 if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1255 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, OUString(), ERRCODE_BUTTON_OK );
1256 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::OPENLIBSTORAGE, itLibInfo->GetLibName()));
1258 else if ( xBasicStorage->IsStream( itLibInfo->GetLibName() ) )
1260 xBasicStorage->Remove( itLibInfo->GetLibName() );
1261 xBasicStorage->Commit();
1263 // If no further stream available,
1264 // delete the SubStorage.
1265 SvStorageInfoList aInfoList;
1266 xBasicStorage->FillInfoList( &aInfoList );
1267 if ( aInfoList.empty() )
1269 xBasicStorage.Clear();
1270 xStorage->Remove( OUString(szBasicStorage) );
1271 xStorage->Commit();
1272 // If no further Streams or SubStorages available,
1273 // delete the Storage, too.
1274 aInfoList.clear();
1275 xStorage->FillInfoList( &aInfoList );
1276 if ( aInfoList.empty() )
1278 //OUString aName_( xStorage->GetName() );
1279 xStorage.Clear();
1280 //*** TODO: Replace if still necessary
1281 //SfxContentHelper::Kill( aName );
1282 //*** TODO-End
1288 if ( itLibInfo->GetLib().Is() )
1290 GetStdLib()->Remove( itLibInfo->GetLib() );
1292 mpImpl->aLibs.erase(itLibInfo);
1293 return true; // Remove was successful, del unimportant
1296 sal_uInt16 BasicManager::GetLibCount() const
1298 return (sal_uInt16)mpImpl->aLibs.size();
1301 StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const
1303 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" );
1304 if ( nLib < mpImpl->aLibs.size() )
1306 return mpImpl->aLibs[nLib].GetLib();
1308 return 0;
1311 StarBASIC* BasicManager::GetStdLib() const
1313 StarBASIC* pLib = GetLib( 0 );
1314 return pLib;
1317 StarBASIC* BasicManager::GetLib( const OUString& rName ) const
1319 for(const BasicLibInfo& rLib: mpImpl->aLibs)
1321 if ( rLib.GetLibName().equalsIgnoreAsciiCase( rName ))// Check if available...
1323 return rLib.GetLib();
1326 return 0;
1329 sal_uInt16 BasicManager::GetLibId( const OUString& rName ) const
1331 for (size_t i = 0; i < mpImpl->aLibs.size(); i++)
1333 if ( mpImpl->aLibs[i].GetLibName().equalsIgnoreAsciiCase( rName ))
1335 return (sal_uInt16)i;
1338 return LIB_NOTFOUND;
1341 bool BasicManager::HasLib( const OUString& rName ) const
1343 for(const BasicLibInfo& rLib: mpImpl->aLibs)
1345 if ( rLib.GetLibName().equalsIgnoreAsciiCase( rName ))// Check if available...
1347 return true;
1350 return false;
1353 OUString BasicManager::GetLibName( sal_uInt16 nLib )
1355 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib?!" );
1356 if ( nLib < mpImpl->aLibs.size() )
1358 return mpImpl->aLibs[nLib].GetLibName();
1360 return OUString();
1363 bool BasicManager::LoadLib( sal_uInt16 nLib )
1365 bool bDone = false;
1366 DBG_ASSERT( nLib < mpImpl->aLibs.size() , "Lib?!" );
1367 if ( nLib < mpImpl->aLibs.size() )
1369 BasicLibInfo& rLibInfo = mpImpl->aLibs[nLib];
1370 uno::Reference< script::XLibraryContainer > xLibContainer = rLibInfo.GetLibraryContainer();
1371 if( xLibContainer.is() )
1373 OUString aLibName = rLibInfo.GetLibName();
1374 xLibContainer->loadLibrary( aLibName );
1375 bDone = xLibContainer->isLibraryLoaded( aLibName );;
1377 else
1379 bDone = ImpLoadLibrary( &rLibInfo, NULL, false );
1380 StarBASIC* pLib = GetLib( nLib );
1381 if ( pLib )
1383 GetStdLib()->Insert( pLib );
1384 pLib->SetFlag( SBX_EXTSEARCH );
1388 else
1390 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, OUString(), ERRCODE_BUTTON_OK );
1391 aErrors.push_back(BasicError(*pErrInf, BasicErrorReason::LIBNOTFOUND, OUString::number(nLib)));
1393 return bDone;
1396 StarBASIC* BasicManager::CreateLib( const OUString& rLibName )
1398 if ( GetLib( rLibName ) )
1400 return 0;
1402 BasicLibInfo* pLibInfo = CreateLibInfo();
1403 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1404 GetStdLib()->Insert( pNew );
1405 pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1406 pLibInfo->SetLib( pNew );
1407 pLibInfo->SetLibName( rLibName );
1408 pLibInfo->GetLib()->SetName( rLibName );
1409 return pLibInfo->GetLib();
1412 // For XML import/export:
1413 StarBASIC* BasicManager::CreateLib( const OUString& rLibName, const OUString& Password,
1414 const OUString& LinkTargetURL )
1416 // Ask if lib exists because standard lib is always there
1417 StarBASIC* pLib = GetLib( rLibName );
1418 if( !pLib )
1420 if( !LinkTargetURL.isEmpty())
1424 tools::SvRef<SotStorage> xStorage = new SotStorage(false, LinkTargetURL, StreamMode::READ | StreamMode::SHARE_DENYWRITE);
1425 if (!xStorage->GetError())
1427 pLib = AddLib(*xStorage, rLibName, true);
1430 catch (const css::ucb::ContentCreationException& e)
1432 SAL_WARN("basic", "BasicManager::RemoveLib: Caught exception: " << e.Message);
1434 DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
1436 else
1438 pLib = CreateLib( rLibName );
1439 if( Password.isEmpty())
1441 BasicLibInfo* pLibInfo = FindLibInfo( pLib );
1442 pLibInfo ->SetPassword( Password );
1445 //ExternalSourceURL ?
1447 return pLib;
1450 StarBASIC* BasicManager::CreateLibForLibContainer( const OUString& rLibName,
1451 const uno::Reference< script::XLibraryContainer >& xScriptCont )
1453 if ( GetLib( rLibName ) )
1455 return 0;
1457 BasicLibInfo* pLibInfo = CreateLibInfo();
1458 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1459 GetStdLib()->Insert( pNew );
1460 pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1461 pLibInfo->SetLib( pNew );
1462 pLibInfo->SetLibName( rLibName );
1463 pLibInfo->GetLib()->SetName( rLibName );
1464 pLibInfo->SetLibraryContainer( xScriptCont );
1465 return pNew;
1469 BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic )
1471 for(BasicLibInfo& rLib: mpImpl->aLibs)
1473 if ( rLib.GetLib() == pBasic )
1475 return &rLib;
1478 return NULL;
1482 bool BasicManager::IsBasicModified() const
1484 for(const BasicLibInfo& rLib: mpImpl->aLibs)
1486 if ( rLib.GetLib().Is() && rLib.GetLib()->IsModified() )
1488 return true;
1491 return false;
1495 bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, uno::Any& aOut )
1497 bool bRes = false;
1498 StarBASIC* pStandardLib = GetStdLib();
1499 OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" );
1500 if ( pStandardLib )
1501 bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut );
1502 return bRes;
1505 uno::Any BasicManager::SetGlobalUNOConstant( const sal_Char* _pAsciiName, const uno::Any& _rValue )
1507 uno::Any aOldValue;
1509 StarBASIC* pStandardLib = GetStdLib();
1510 OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
1511 if ( !pStandardLib )
1512 return aOldValue;
1514 OUString sVarName( OUString::createFromAscii( _pAsciiName ) );
1516 // obtain the old value
1517 SbxVariable* pVariable = pStandardLib->Find( sVarName, SbxCLASS_OBJECT );
1518 if ( pVariable )
1519 aOldValue = sbxToUnoValue( pVariable );
1521 SbxObjectRef xUnoObj = GetSbUnoObject( sVarName, _rValue );
1522 xUnoObj->SetFlag( SBX_DONTSTORE );
1523 pStandardLib->Insert( xUnoObj );
1525 return aOldValue;
1528 bool BasicManager::LegacyPsswdBinaryLimitExceeded( uno::Sequence< OUString >& _out_rModuleNames )
1532 uno::Reference< container::XNameAccess > xScripts( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW );
1533 uno::Reference< script::XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW );
1535 uno::Sequence< OUString > aNames( xScripts->getElementNames() );
1536 const OUString* pNames = aNames.getConstArray();
1537 const OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
1538 for ( ; pNames != pNamesEnd; ++pNames )
1540 if( !xPassword->isLibraryPasswordProtected( *pNames ) )
1541 continue;
1543 StarBASIC* pBasicLib = GetLib( *pNames );
1544 if ( !pBasicLib )
1545 continue;
1547 uno::Reference< container::XNameAccess > xScriptLibrary( xScripts->getByName( *pNames ), uno::UNO_QUERY_THROW );
1548 uno::Sequence< OUString > aElementNames( xScriptLibrary->getElementNames() );
1549 sal_Int32 nLen = aElementNames.getLength();
1551 uno::Sequence< OUString > aBigModules( nLen );
1552 sal_Int32 nBigModules = 0;
1554 const OUString* pElementNames = aElementNames.getConstArray();
1555 const OUString* pElementNamesEnd = aElementNames.getConstArray() + aElementNames.getLength();
1556 for ( ; pElementNames != pElementNamesEnd; ++pElementNames )
1558 SbModule* pMod = pBasicLib->FindModule( *pElementNames );
1559 if ( pMod && pMod->ExceedsLegacyModuleSize() )
1560 aBigModules[ nBigModules++ ] = *pElementNames;
1563 if ( nBigModules )
1565 aBigModules.realloc( nBigModules );
1566 _out_rModuleNames = aBigModules;
1567 return true;
1571 catch( const uno::Exception& )
1573 DBG_UNHANDLED_EXCEPTION();
1575 return false;
1579 namespace
1581 SbMethod* lcl_queryMacro( BasicManager* i_manager, OUString const& i_fullyQualifiedName )
1583 sal_Int32 nLast = 0;
1584 const OUString sParse = i_fullyQualifiedName;
1585 OUString sLibName = sParse.getToken( (sal_Int32)0, (sal_Unicode)'.', nLast );
1586 OUString sModule = sParse.getToken( (sal_Int32)0, (sal_Unicode)'.', nLast );
1587 OUString sMacro;
1588 if(nLast >= 0)
1590 sMacro = OUString(sParse.getStr() + nLast, sParse.getLength() - nLast );
1592 else
1594 sMacro = sParse;
1597 utl::TransliterationWrapper& rTransliteration = SbGlobal::GetTransliteration();
1598 sal_uInt16 nLibCount = i_manager->GetLibCount();
1599 for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib )
1601 if ( rTransliteration.isEqual( i_manager->GetLibName( nLib ), sLibName ) )
1603 StarBASIC* pLib = i_manager->GetLib( nLib );
1604 if( !pLib )
1606 i_manager->LoadLib( nLib );
1607 pLib = i_manager->GetLib( nLib );
1610 if( pLib )
1612 sal_uInt16 nModCount = pLib->GetModules()->Count();
1613 for( sal_uInt16 nMod = 0; nMod < nModCount; ++nMod )
1615 SbModule* pMod = static_cast<SbModule*>(pLib->GetModules()->Get( nMod ));
1616 if ( pMod && rTransliteration.isEqual( pMod->GetName(), sModule ) )
1618 SbMethod* pMethod = static_cast<SbMethod*>(pMod->Find( sMacro, SbxCLASS_METHOD ));
1619 if( pMethod )
1621 return pMethod;
1628 return 0;
1632 bool BasicManager::HasMacro( OUString const& i_fullyQualifiedName ) const
1634 return ( NULL != lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) );
1637 ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue )
1639 SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1640 ErrCode nError = 0;
1641 if ( pMethod )
1643 if ( i_arguments )
1644 pMethod->SetParameters( i_arguments );
1645 nError = pMethod->Call( i_retValue );
1647 else
1648 nError = ERRCODE_BASIC_PROC_UNDEFINED;
1649 return nError;
1652 ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, OUString const& i_commaSeparatedArgs, SbxValue* i_retValue )
1654 SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1655 if ( !pMethod )
1657 return ERRCODE_BASIC_PROC_UNDEFINED;
1659 // arguments must be quoted
1660 OUString sQuotedArgs;
1661 OUStringBuffer sArgs( i_commaSeparatedArgs );
1662 if ( sArgs.getLength()<2 || sArgs[1] == '\"')
1664 // no args or already quoted args
1665 sQuotedArgs = sArgs.makeStringAndClear();
1667 else
1669 // quote parameters
1670 sArgs.remove( 0, 1 );
1671 sArgs.remove( sArgs.getLength() - 1, 1 );
1673 sQuotedArgs = "(";
1674 OUString sArgs2 = sArgs.makeStringAndClear();
1675 sal_Int32 nCount = comphelper::string::getTokenCount(sArgs2, ',');
1676 for (sal_Int32 n = 0; n < nCount; ++n)
1678 sQuotedArgs += "\"";
1679 sQuotedArgs += sArgs2.getToken(n, ',');
1680 sQuotedArgs += "\"";
1681 if ( n < nCount - 1 )
1683 sQuotedArgs += ",";
1687 sQuotedArgs += ")";
1690 // add quoted arguments and do the call
1691 OUString sCall;
1692 sCall += "[";
1693 sCall += pMethod->GetName();
1694 sCall += sQuotedArgs;
1695 sCall += "]";
1697 SbxVariable* pRet = pMethod->GetParent()->Execute( sCall );
1698 if ( pRet && ( pRet != pMethod ) )
1700 *i_retValue = *pRet;
1702 return SbxBase::GetError();
1707 class ModuleInfo_Impl : public ModuleInfoHelper
1709 OUString maName;
1710 OUString maLanguage;
1711 OUString maSource;
1713 public:
1714 ModuleInfo_Impl( const OUString& aName, const OUString& aLanguage, const OUString& aSource )
1715 : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
1717 // Methods XStarBasicModuleInfo
1718 virtual OUString SAL_CALL getName() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1719 { return maName; }
1720 virtual OUString SAL_CALL getLanguage() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1721 { return maLanguage; }
1722 virtual OUString SAL_CALL getSource() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1723 { return maSource; }
1729 class DialogInfo_Impl : public DialogInfoHelper
1731 OUString maName;
1732 uno::Sequence< sal_Int8 > mData;
1734 public:
1735 DialogInfo_Impl( const OUString& aName, const uno::Sequence< sal_Int8 >& Data )
1736 : maName( aName ), mData( Data ) {}
1738 // Methods XStarBasicDialogInfo
1739 virtual OUString SAL_CALL getName() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1740 { return maName; }
1741 virtual uno::Sequence< sal_Int8 > SAL_CALL getData() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1742 { return mData; }
1748 class LibraryInfo_Impl : public LibraryInfoHelper
1750 OUString maName;
1751 uno::Reference< container::XNameContainer > mxModuleContainer;
1752 uno::Reference< container::XNameContainer > mxDialogContainer;
1753 OUString maPassword;
1754 OUString maExternaleSourceURL;
1755 OUString maLinkTargetURL;
1757 public:
1758 LibraryInfo_Impl
1760 const OUString& aName,
1761 uno::Reference< container::XNameContainer > xModuleContainer,
1762 uno::Reference< container::XNameContainer > xDialogContainer,
1763 const OUString& aPassword,
1764 const OUString& aExternaleSourceURL,
1765 const OUString& aLinkTargetURL
1767 : maName( aName )
1768 , mxModuleContainer( xModuleContainer )
1769 , mxDialogContainer( xDialogContainer )
1770 , maPassword( aPassword )
1771 , maExternaleSourceURL( aExternaleSourceURL )
1772 , maLinkTargetURL( aLinkTargetURL )
1775 // Methods XStarBasicLibraryInfo
1776 virtual OUString SAL_CALL getName() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1777 { return maName; }
1778 virtual uno::Reference< container::XNameContainer > SAL_CALL getModuleContainer() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1779 { return mxModuleContainer; }
1780 virtual uno::Reference< container::XNameContainer > SAL_CALL getDialogContainer() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1781 { return mxDialogContainer; }
1782 virtual OUString SAL_CALL getPassword() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1783 { return maPassword; }
1784 virtual OUString SAL_CALL getExternalSourceURL() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1785 { return maExternaleSourceURL; }
1786 virtual OUString SAL_CALL getLinkTargetURL() throw(uno::RuntimeException, std::exception) SAL_OVERRIDE
1787 { return maLinkTargetURL; }
1792 class ModuleContainer_Impl : public NameContainerHelper
1794 StarBASIC* mpLib;
1796 public:
1797 ModuleContainer_Impl( StarBASIC* pLib )
1798 :mpLib( pLib ) {}
1800 // Methods XElementAccess
1801 virtual uno::Type SAL_CALL getElementType()
1802 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1803 virtual sal_Bool SAL_CALL hasElements()
1804 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1806 // Methods XNameAccess
1807 virtual uno::Any SAL_CALL getByName( const OUString& aName )
1808 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1809 virtual uno::Sequence< OUString > SAL_CALL getElementNames()
1810 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1811 virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
1812 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1814 // Methods XNameReplace
1815 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement )
1816 throw(lang::IllegalArgumentException, container::NoSuchElementException,
1817 lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1819 // Methods XNameContainer
1820 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement )
1821 throw(lang::IllegalArgumentException, container::ElementExistException,
1822 lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1823 virtual void SAL_CALL removeByName( const OUString& Name )
1824 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1827 // Methods XElementAccess
1828 uno::Type ModuleContainer_Impl::getElementType()
1829 throw(uno::RuntimeException, std::exception)
1831 uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get();
1832 return aModuleType;
1835 sal_Bool ModuleContainer_Impl::hasElements()
1836 throw(uno::RuntimeException, std::exception)
1838 SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
1839 return pMods && pMods->Count() > 0;
1842 // Methods XNameAccess
1843 uno::Any ModuleContainer_Impl::getByName( const OUString& aName )
1844 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
1846 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
1847 if( !pMod )
1848 throw container::NoSuchElementException();
1849 uno::Reference< script::XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl
1850 ( aName, "StarBasic", pMod->GetSource32() );
1851 uno::Any aRetAny;
1852 aRetAny <<= xMod;
1853 return aRetAny;
1856 uno::Sequence< OUString > ModuleContainer_Impl::getElementNames()
1857 throw(uno::RuntimeException, std::exception)
1859 SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
1860 sal_uInt16 nMods = pMods ? pMods->Count() : 0;
1861 uno::Sequence< OUString > aRetSeq( nMods );
1862 OUString* pRetSeq = aRetSeq.getArray();
1863 for( sal_uInt16 i = 0 ; i < nMods ; i++ )
1865 SbxVariable* pMod = pMods->Get( i );
1866 pRetSeq[i] = OUString( pMod->GetName() );
1868 return aRetSeq;
1871 sal_Bool ModuleContainer_Impl::hasByName( const OUString& aName )
1872 throw(uno::RuntimeException, std::exception)
1874 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
1875 bool bRet = (pMod != NULL);
1876 return bRet;
1880 // Methods XNameReplace
1881 void ModuleContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
1882 throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
1884 removeByName( aName );
1885 insertByName( aName, aElement );
1889 // Methods XNameContainer
1890 void ModuleContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement )
1891 throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
1893 uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get();
1894 uno::Type aAnyType = aElement.getValueType();
1895 if( aModuleType != aAnyType )
1897 throw lang::IllegalArgumentException();
1899 uno::Reference< script::XStarBasicModuleInfo > xMod;
1900 aElement >>= xMod;
1901 mpLib->MakeModule32( aName, xMod->getSource() );
1904 void ModuleContainer_Impl::removeByName( const OUString& Name )
1905 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
1907 SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL;
1908 if( !pMod )
1910 throw container::NoSuchElementException();
1912 mpLib->Remove( pMod );
1918 uno::Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
1920 SvMemoryStream aMemStream;
1921 pDialog->Store( aMemStream );
1922 sal_Size nLen = aMemStream.Tell();
1923 uno::Sequence< sal_Int8 > aData( nLen );
1924 sal_Int8* pDestData = aData.getArray();
1925 const sal_Int8* pSrcData = static_cast<const sal_Int8*>(aMemStream.GetData());
1926 memcpy( pDestData, pSrcData, nLen );
1927 return aData;
1930 SbxObject* implCreateDialog( const uno::Sequence< sal_Int8 >& aData )
1932 sal_Int8* pData = const_cast< uno::Sequence< sal_Int8 >& >(aData).getArray();
1933 SvMemoryStream aMemStream( pData, aData.getLength(), StreamMode::READ );
1934 SbxBase* pBase = SbxBase::Load( aMemStream );
1935 return dynamic_cast<SbxObject*>(pBase);
1938 // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
1939 // which we can't include here, we have to use the value directly
1940 #define SBXID_DIALOG 101
1943 class DialogContainer_Impl : public NameContainerHelper
1945 StarBASIC* mpLib;
1947 public:
1948 DialogContainer_Impl( StarBASIC* pLib )
1949 :mpLib( pLib ) {}
1951 // Methods XElementAccess
1952 virtual uno::Type SAL_CALL getElementType()
1953 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1954 virtual sal_Bool SAL_CALL hasElements()
1955 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1957 // Methods XNameAccess
1958 virtual uno::Any SAL_CALL getByName( const OUString& aName )
1959 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1960 virtual uno::Sequence< OUString > SAL_CALL getElementNames()
1961 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1962 virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
1963 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
1965 // Methods XNameReplace
1966 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement )
1967 throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1969 // Methods XNameContainer
1970 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement )
1971 throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1972 virtual void SAL_CALL removeByName( const OUString& Name )
1973 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
1976 // Methods XElementAccess
1977 uno::Type DialogContainer_Impl::getElementType()
1978 throw(uno::RuntimeException, std::exception)
1980 uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get();
1981 return aModuleType;
1984 sal_Bool DialogContainer_Impl::hasElements()
1985 throw(uno::RuntimeException, std::exception)
1987 bool bRet = false;
1989 sal_Int16 nCount = mpLib->GetObjects()->Count();
1990 for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
1992 SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
1993 if ( pVar->ISA( SbxObject ) && ( static_cast<SbxObject*>(pVar)->GetSbxId() == SBXID_DIALOG ) )
1995 bRet = true;
1996 break;
1999 return bRet;
2002 // Methods XNameAccess
2003 uno::Any DialogContainer_Impl::getByName( const OUString& aName )
2004 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2006 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2007 if( !( pVar && pVar->ISA( SbxObject ) &&
2008 ( static_cast<SbxObject*>(pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2010 throw container::NoSuchElementException();
2013 uno::Reference< script::XStarBasicDialogInfo > xDialog =
2014 (XStarBasicDialogInfo*)new DialogInfo_Impl
2015 ( aName, implGetDialogData( static_cast<SbxObject*>(pVar) ) );
2017 uno::Any aRetAny;
2018 aRetAny <<= xDialog;
2019 return aRetAny;
2022 uno::Sequence< OUString > DialogContainer_Impl::getElementNames()
2023 throw(uno::RuntimeException, std::exception)
2025 sal_Int16 nCount = mpLib->GetObjects()->Count();
2026 uno::Sequence< OUString > aRetSeq( nCount );
2027 OUString* pRetSeq = aRetSeq.getArray();
2028 sal_Int32 nDialogCounter = 0;
2030 for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2032 SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2033 if ( pVar->ISA( SbxObject ) && ( static_cast<SbxObject*>(pVar)->GetSbxId() == SBXID_DIALOG ) )
2035 pRetSeq[ nDialogCounter ] = OUString( pVar->GetName() );
2036 nDialogCounter++;
2039 aRetSeq.realloc( nDialogCounter );
2040 return aRetSeq;
2043 sal_Bool DialogContainer_Impl::hasByName( const OUString& aName )
2044 throw(uno::RuntimeException, std::exception)
2046 bool bRet = false;
2047 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2048 if( pVar && pVar->ISA( SbxObject ) &&
2049 ( static_cast<SbxObject*>(pVar)->GetSbxId() == SBXID_DIALOG ) )
2051 bRet = true;
2053 return bRet;
2057 // Methods XNameReplace
2058 void DialogContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
2059 throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2061 removeByName( aName );
2062 insertByName( aName, aElement );
2066 // Methods XNameContainer
2067 void DialogContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement )
2068 throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2070 (void)aName;
2071 uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get();
2072 uno::Type aAnyType = aElement.getValueType();
2073 if( aModuleType != aAnyType )
2075 throw lang::IllegalArgumentException();
2077 uno::Reference< script::XStarBasicDialogInfo > xMod;
2078 aElement >>= xMod;
2079 SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
2080 mpLib->Insert( xDialog );
2083 void DialogContainer_Impl::removeByName( const OUString& Name )
2084 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2086 (void)Name;
2087 SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE );
2088 if( !( pVar && pVar->ISA( SbxObject ) &&
2089 ( static_cast<SbxObject*>(pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2091 throw container::NoSuchElementException();
2093 mpLib->Remove( pVar );
2100 class LibraryContainer_Impl : public NameContainerHelper
2102 BasicManager* mpMgr;
2104 public:
2105 LibraryContainer_Impl( BasicManager* pMgr )
2106 :mpMgr( pMgr ) {}
2108 // Methods XElementAccess
2109 virtual uno::Type SAL_CALL getElementType()
2110 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
2111 virtual sal_Bool SAL_CALL hasElements()
2112 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
2114 // Methods XNameAccess
2115 virtual uno::Any SAL_CALL getByName( const OUString& aName )
2116 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2117 virtual uno::Sequence< OUString > SAL_CALL getElementNames()
2118 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
2119 virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
2120 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
2122 // Methods XNameReplace
2123 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement )
2124 throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2126 // Methods XNameContainer
2127 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement )
2128 throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2129 virtual void SAL_CALL removeByName( const OUString& Name )
2130 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2134 // Methods XElementAccess
2135 uno::Type LibraryContainer_Impl::getElementType()
2136 throw(uno::RuntimeException, std::exception)
2138 uno::Type aType = cppu::UnoType<script::XStarBasicLibraryInfo>::get();
2139 return aType;
2142 sal_Bool LibraryContainer_Impl::hasElements()
2143 throw(uno::RuntimeException, std::exception)
2145 sal_Int32 nLibs = mpMgr->GetLibCount();
2146 bool bRet = (nLibs > 0);
2147 return bRet;
2150 // Methods XNameAccess
2151 uno::Any LibraryContainer_Impl::getByName( const OUString& aName )
2152 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2154 uno::Any aRetAny;
2155 if( !mpMgr->HasLib( aName ) )
2156 throw container::NoSuchElementException();
2157 StarBASIC* pLib = mpMgr->GetLib( aName );
2159 uno::Reference< container::XNameContainer > xModuleContainer =
2160 (container::XNameContainer*)new ModuleContainer_Impl( pLib );
2162 uno::Reference< container::XNameContainer > xDialogContainer =
2163 (container::XNameContainer*)new DialogContainer_Impl( pLib );
2165 BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
2167 OUString aPassword = pLibInfo->GetPassword();
2169 // TODO Only provide extern info!
2170 OUString aExternaleSourceURL;
2171 OUString aLinkTargetURL;
2172 if( pLibInfo->IsReference() )
2174 aLinkTargetURL = pLibInfo->GetStorageName();
2176 else if( pLibInfo->IsExtern() )
2178 aExternaleSourceURL = pLibInfo->GetStorageName();
2180 uno::Reference< script::XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
2182 aName,
2183 xModuleContainer,
2184 xDialogContainer,
2185 aPassword,
2186 aExternaleSourceURL,
2187 aLinkTargetURL
2190 aRetAny <<= xLibInfo;
2191 return aRetAny;
2194 uno::Sequence< OUString > LibraryContainer_Impl::getElementNames()
2195 throw(uno::RuntimeException, std::exception)
2197 sal_uInt16 nLibs = mpMgr->GetLibCount();
2198 uno::Sequence< OUString > aRetSeq( nLibs );
2199 OUString* pRetSeq = aRetSeq.getArray();
2200 for( sal_uInt16 i = 0 ; i < nLibs ; i++ )
2202 pRetSeq[i] = OUString( mpMgr->GetLibName( i ) );
2204 return aRetSeq;
2207 sal_Bool LibraryContainer_Impl::hasByName( const OUString& aName )
2208 throw(uno::RuntimeException, std::exception)
2210 bool bRet = mpMgr->HasLib( aName );
2211 return bRet;
2214 // Methods XNameReplace
2215 void LibraryContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
2216 throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2218 removeByName( aName );
2219 insertByName( aName, aElement );
2222 // Methods XNameContainer
2223 void LibraryContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement )
2224 throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2226 (void)aName;
2227 (void)aElement;
2228 // TODO: Insert a complete Library?!
2231 void LibraryContainer_Impl::removeByName( const OUString& Name )
2232 throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
2234 StarBASIC* pLib = mpMgr->GetLib( Name );
2235 if( !pLib )
2237 throw container::NoSuchElementException();
2239 sal_uInt16 nLibId = mpMgr->GetLibId( Name );
2240 mpMgr->RemoveLib( nLibId );
2245 typedef WeakImplHelper1< script::XStarBasicAccess > StarBasicAccessHelper;
2248 class StarBasicAccess_Impl : public StarBasicAccessHelper
2250 BasicManager* mpMgr;
2251 uno::Reference< container::XNameContainer > mxLibContainer;
2253 public:
2254 StarBasicAccess_Impl( BasicManager* pMgr )
2255 :mpMgr( pMgr ) {}
2257 public:
2258 // Methods
2259 virtual uno::Reference< container::XNameContainer > SAL_CALL getLibraryContainer()
2260 throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
2261 virtual void SAL_CALL createLibrary( const OUString& LibName, const OUString& Password,
2262 const OUString& ExternalSourceURL, const OUString& LinkTargetURL )
2263 throw(container::ElementExistException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2264 virtual void SAL_CALL addModule( const OUString& LibraryName, const OUString& ModuleName,
2265 const OUString& Language, const OUString& Source )
2266 throw(container::NoSuchElementException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2267 virtual void SAL_CALL addDialog( const OUString& LibraryName, const OUString& DialogName,
2268 const uno::Sequence< sal_Int8 >& Data )
2269 throw(container::NoSuchElementException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
2272 uno::Reference< container::XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
2273 throw(uno::RuntimeException, std::exception)
2275 if( !mxLibContainer.is() )
2276 mxLibContainer = (container::XNameContainer*)new LibraryContainer_Impl( mpMgr );
2277 return mxLibContainer;
2280 void SAL_CALL StarBasicAccess_Impl::createLibrary
2282 const OUString& LibName,
2283 const OUString& Password,
2284 const OUString& ExternalSourceURL,
2285 const OUString& LinkTargetURL
2287 throw(container::ElementExistException, uno::RuntimeException, std::exception)
2289 (void)ExternalSourceURL;
2290 #ifdef DBG_UTIL
2291 StarBASIC* pLib =
2292 #endif
2293 mpMgr->CreateLib( LibName, Password, LinkTargetURL );
2294 DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
2297 void SAL_CALL StarBasicAccess_Impl::addModule
2299 const OUString& LibraryName,
2300 const OUString& ModuleName,
2301 const OUString& Language,
2302 const OUString& Source
2304 throw(container::NoSuchElementException, uno::RuntimeException, std::exception)
2306 (void)Language;
2307 StarBASIC* pLib = mpMgr->GetLib( LibraryName );
2308 DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
2309 if( pLib )
2311 pLib->MakeModule32( ModuleName, Source );
2315 void SAL_CALL StarBasicAccess_Impl::addDialog
2317 const OUString& LibraryName,
2318 const OUString& DialogName,
2319 const uno::Sequence< sal_Int8 >& Data
2321 throw(container::NoSuchElementException, uno::RuntimeException, std::exception)
2323 (void)LibraryName;
2324 (void)DialogName;
2325 (void)Data;
2328 // Basic XML Import/Export
2329 uno::Reference< script::XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
2331 uno::Reference< script::XStarBasicAccess > xRet =
2332 new StarBasicAccess_Impl( pMgr );
2333 return xRet;
2336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */