merge the formfield patch from ooo-build
[ooovba.git] / basic / source / basmgr / basmgr.cxx
blobbde0711f25806f673b80e6d060cd27d180af6acf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: basmgr.cxx,v $
10 * $Revision: 1.45 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 #include <tools/stream.hxx>
34 #include <sot/storage.hxx>
35 #include <tools/urlobj.hxx>
36 #include <svtools/smplhint.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/window.hxx>
39 #include <vcl/wrkwin.hxx>
40 #include <vcl/msgbox.hxx>
41 #include <basic/sbx.hxx>
42 #include <sot/storinfo.hxx>
43 #include <svtools/pathoptions.hxx>
44 #include <tools/debug.hxx>
45 #include <tools/diagnose_ex.h>
46 #include <basic/sbmod.hxx>
47 #include <basic/sbobjmod.hxx>
49 #include <basic/sbuno.hxx>
50 #include <basic/basmgr.hxx>
51 #include <sbunoobj.hxx>
52 #include "basrid.hxx"
53 #include "sbintern.hxx"
54 #include <sb.hrc>
57 #define LIB_SEP 0x01
58 #define LIBINFO_SEP 0x02
59 #define LIBINFO_ID 0x1491
60 #define PASSWORD_MARKER 0x31452134
63 // Library API, implemented for XML import/export
65 #include <com/sun/star/container/XNameContainer.hpp>
66 #include <com/sun/star/container/XContainer.hpp>
67 #include <com/sun/star/script/XStarBasicAccess.hpp>
68 #include <com/sun/star/script/XStarBasicModuleInfo.hpp>
69 #include <com/sun/star/script/XStarBasicDialogInfo.hpp>
70 #include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
71 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
72 #include <com/sun/star/script/ModuleInfo.hpp>
73 #include <com/sun/star/script/ModuleType.hpp>
75 #include <cppuhelper/implbase1.hxx>
77 using com::sun::star::uno::Reference;
78 using namespace com::sun::star::container;
79 using namespace com::sun::star::uno;
80 using namespace com::sun::star::lang;
81 using namespace com::sun::star::script;
82 using namespace cppu;
84 typedef WeakImplHelper1< XNameContainer > NameContainerHelper;
85 typedef WeakImplHelper1< XStarBasicModuleInfo > ModuleInfoHelper;
86 typedef WeakImplHelper1< XStarBasicDialogInfo > DialogInfoHelper;
87 typedef WeakImplHelper1< XStarBasicLibraryInfo > LibraryInfoHelper;
88 typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
92 #define CURR_VER 2
94 // Version 1
95 // ULONG nEndPos
96 // USHORT nId
97 // USHORT nVer
98 // BOOL bDoLoad
99 // String LibName
100 // String AbsStorageName
101 // String RelStorageName
102 // Version 2
103 // + BOOL bReference
105 static const char* szStdLibName = "Standard";
106 static const char* szBasicStorage = "StarBASIC";
107 static const char* szOldManagerStream = "BasicManager";
108 static const char* szManagerStream = "BasicManager2";
109 static const char* szImbedded = "LIBIMBEDDED";
110 static const char* szCryptingKey = "CryptedBasic";
111 static const char* szScriptLanguage = "StarBasic";
113 static const String BasicStreamName( String::CreateFromAscii(szBasicStorage) );
114 static const String ManagerStreamName( String::CreateFromAscii(szManagerStream) );
117 #define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
120 TYPEINIT1( BasicManager, SfxBroadcaster );
121 DBG_NAME( BasicManager );
123 StreamMode eStreamReadMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL;
124 StreamMode eStorageReadMode = STREAM_READ | STREAM_SHARE_DENYWRITE;
126 DECLARE_LIST( BasErrorLst, BasicError* )
128 //----------------------------------------------------------------------------
129 // BasicManager impl data
130 struct BasicManagerImpl
132 LibraryContainerInfo maContainerInfo;
134 // Save stream data
135 SvMemoryStream* mpManagerStream;
136 SvMemoryStream** mppLibStreams;
137 sal_Int32 mnLibStreamCount;
138 sal_Bool mbModifiedByLibraryContainer;
139 sal_Bool mbError;
141 BasicManagerImpl( void )
142 : mpManagerStream( NULL )
143 , mppLibStreams( NULL )
144 , mnLibStreamCount( 0 )
145 , mbModifiedByLibraryContainer( sal_False )
146 , mbError( sal_False )
148 ~BasicManagerImpl();
151 BasicManagerImpl::~BasicManagerImpl()
153 delete mpManagerStream;
154 if( mppLibStreams )
156 for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ )
157 delete mppLibStreams[i];
158 delete[] mppLibStreams;
162 //============================================================================
163 // BasMgrContainerListenerImpl
164 //============================================================================
166 typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper;
168 class BasMgrContainerListenerImpl: public ContainerListenerHelper
170 BasicManager* mpMgr;
171 ::rtl::OUString maLibName; // empty -> no lib, but lib container
173 public:
174 BasMgrContainerListenerImpl( BasicManager* pMgr, ::rtl::OUString aLibName )
175 : mpMgr( pMgr )
176 , maLibName( aLibName ) {}
178 static void insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr,
179 Any aLibAny, ::rtl::OUString aLibName );
180 static void addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess,
181 ::rtl::OUString aLibName );
184 // XEventListener
185 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
186 throw(::com::sun::star::uno::RuntimeException);
188 // XContainerListener
189 virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event )
190 throw(::com::sun::star::uno::RuntimeException);
191 virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event )
192 throw(::com::sun::star::uno::RuntimeException);
193 virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event )
194 throw(::com::sun::star::uno::RuntimeException);
198 //============================================================================
199 // BasMgrContainerListenerImpl
200 //============================================================================
202 void BasMgrContainerListenerImpl::insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont,
203 BasicManager* pMgr, Any aLibAny, ::rtl::OUString aLibName )
205 Reference< XNameAccess > xLibNameAccess;
206 aLibAny >>= xLibNameAccess;
208 if( !pMgr->GetLib( aLibName ) )
210 BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr );
211 #ifdef DBG_UTIL
212 StarBASIC* pLib =
213 #endif
214 pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont );
215 DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
218 Reference< XContainer> xLibContainer( xLibNameAccess, UNO_QUERY );
219 if( xLibContainer.is() )
221 // Register listener for library
222 Reference< XContainerListener > xLibraryListener
223 = static_cast< XContainerListener* >
224 ( new BasMgrContainerListenerImpl( pMgr, aLibName ) );
225 xLibContainer->addContainerListener( xLibraryListener );
228 if( xScriptCont->isLibraryLoaded( aLibName ) )
230 addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
235 void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr,
236 Reference< XNameAccess > xLibNameAccess, ::rtl::OUString aLibName )
238 Sequence< ::rtl::OUString > aModuleNames = xLibNameAccess->getElementNames();
239 sal_Int32 nModuleCount = aModuleNames.getLength();
241 StarBASIC* pLib = pMgr->GetLib( aLibName );
242 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
243 if( pLib )
245 const ::rtl::OUString* pNames = aModuleNames.getConstArray();
246 for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
248 ::rtl::OUString aModuleName = pNames[ j ];
249 Any aElement = xLibNameAccess->getByName( aModuleName );
250 ModuleInfo mInfo;
251 if ( aElement >>= mInfo )
253 OSL_TRACE("#addLibraryModulesImpl - aMod");
254 pLib->MakeModule32( mInfo );
256 else
258 ::rtl::OUString aMod;
259 aElement >>= aMod;
260 pLib->MakeModule32( aModuleName, aMod );
265 pLib->SetModified( FALSE );
270 // XEventListener
271 //----------------------------------------------------------------------------
273 void SAL_CALL BasMgrContainerListenerImpl::disposing( const EventObject& Source )
274 throw( RuntimeException )
276 (void)Source;
279 // XContainerListener
280 //----------------------------------------------------------------------------
282 void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent& Event )
283 throw( RuntimeException )
285 sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
286 ::rtl::OUString aName;
287 Event.Accessor >>= aName;
289 mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
291 if( bLibContainer )
293 Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY );
294 insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName );
296 else
299 StarBASIC* pLib = mpMgr->GetLib( maLibName );
300 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
301 if( pLib )
303 SbModule* pMod = pLib->FindModule( aName );
304 if( !pMod )
306 ModuleInfo mInfo;
307 if( Event.Element >>= mInfo )
309 pLib->MakeModule32( mInfo );
311 else
313 ::rtl::OUString aMod;
314 Event.Element >>= aMod;
315 pLib->MakeModule32( aName, aMod );
317 pLib->SetModified( FALSE );
323 //----------------------------------------------------------------------------
325 void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent& Event )
326 throw( RuntimeException )
328 ::rtl::OUString aName;
329 Event.Accessor >>= aName;
331 mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
333 // Replace not possible for library container
334 #ifdef DBG_UTIL
335 sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
336 #endif
337 DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()");
339 StarBASIC* pLib = mpMgr->GetLib( maLibName );
341 if( pLib )
343 SbModule* pMod = pLib->FindModule( aName );
344 ::rtl::OUString aMod;
345 ModuleInfo mInfo;
346 if( Event.Element >>= mInfo )
347 aMod = mInfo.ModuleSource;
348 else
349 Event.Element >>= aMod;
350 if( pMod )
352 pMod->SetSource32( aMod );
353 if ( mInfo.ModuleType == ModuleType::Document )
355 SbObjModule* pObjModule = dynamic_cast< SbObjModule* >( pMod );
356 if ( pObjModule )
357 pObjModule->SetUnoObject( makeAny( mInfo.ModuleObject ) );
360 else
361 // Probably we should have an assert for
362 // unknow module type, e.g. either we are using
363 // the ModuleInfo structure ( vba ) for *all* modules
364 // or not ( normal )
365 if ( mInfo.ModuleType == ModuleType::Unknown )
366 pLib->MakeModule32( aName, aMod );
367 else
368 pLib->MakeModule32( mInfo );
370 pLib->SetModified( FALSE );
374 //----------------------------------------------------------------------------
376 void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const ContainerEvent& Event )
377 throw( RuntimeException )
379 ::rtl::OUString aName;
380 Event.Accessor >>= aName;
382 mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
384 sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
385 if( bLibContainer )
387 StarBASIC* pLib = mpMgr->GetLib( aName );
388 if( pLib )
390 USHORT nLibId = mpMgr->GetLibId( aName );
391 mpMgr->RemoveLib( nLibId, FALSE );
394 else
396 StarBASIC* pLib = mpMgr->GetLib( maLibName );
397 SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL;
398 if( pMod )
400 pLib->Remove( pMod );
401 pLib->SetModified( FALSE );
407 //=====================================================================
409 class BasicErrorManager
411 private:
412 BasErrorLst aErrorList;
414 public:
415 ~BasicErrorManager();
417 void Reset();
418 void InsertError( const BasicError& rError );
420 BOOL HasErrors() { return (BOOL)aErrorList.Count(); }
421 BasicError* GetFirstError() { return aErrorList.First(); }
422 BasicError* GetNextError() { return aErrorList.Next(); }
426 BasicErrorManager::~BasicErrorManager()
428 Reset();
431 void BasicErrorManager::Reset()
433 BasicError* pError = (BasicError*)aErrorList.First();
434 while ( pError )
436 delete pError;
437 pError = (BasicError*)aErrorList.Next();
439 aErrorList.Clear();
442 void BasicErrorManager::InsertError( const BasicError& rError )
444 aErrorList.Insert( new BasicError( rError ), LIST_APPEND );
448 BasicError::BasicError()
450 nErrorId = 0;
451 nReason = 0;
454 BasicError::BasicError( ULONG nId, USHORT nR, const String& rErrStr ) :
455 aErrStr( rErrStr )
457 nErrorId = nId;
458 nReason = nR;
461 BasicError::BasicError( const BasicError& rErr ) :
462 aErrStr( rErr.aErrStr )
464 nErrorId = rErr.nErrorId;
465 nReason = rErr.nReason;
469 class BasicLibInfo
471 private:
472 StarBASICRef xLib;
473 String aLibName;
474 String aStorageName; // String is sufficient, unique at runtime
475 String aRelStorageName;
476 String aPassword;
478 BOOL bDoLoad;
479 BOOL bReference;
480 BOOL bPasswordVerified;
481 BOOL bFoundInPath; // Must not relativated again!
483 // Lib represents library in new UNO library container
484 Reference< XLibraryContainer > mxScriptCont;
486 public:
487 BasicLibInfo();
488 BasicLibInfo( const String& rStorageName );
490 BOOL IsReference() const { return bReference; }
491 BOOL& IsReference() { return bReference; }
493 BOOL IsExtern() const { return ! aStorageName.EqualsAscii(szImbedded); }
495 void SetStorageName( const String& rName ) { aStorageName = rName; }
496 const String& GetStorageName() const { return aStorageName; }
498 void SetRelStorageName( const String& rN ) { aRelStorageName = rN; }
499 const String& GetRelStorageName() const { return aRelStorageName; }
500 void CalcRelStorageName( const String& rMgrStorageName );
502 StarBASICRef GetLib() const
504 if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
505 !mxScriptCont->isLibraryLoaded( aLibName ) )
506 return StarBASICRef();
507 return xLib;
509 StarBASICRef& GetLibRef() { return xLib; }
510 void SetLib( StarBASIC* pBasic ) { xLib = pBasic; }
512 const String& GetLibName() const { return aLibName; }
513 void SetLibName( const String& rName ) { aLibName = rName; }
515 // Only temporary for Load/Save
516 BOOL DoLoad() { return bDoLoad; }
518 BOOL HasPassword() const { return aPassword.Len() != 0; }
519 const String& GetPassword() const { return aPassword; }
520 void SetPassword( const String& rNewPassword )
521 { aPassword = rNewPassword; }
522 BOOL IsPasswordVerified() const { return bPasswordVerified; }
523 void SetPasswordVerified() { bPasswordVerified = TRUE; }
525 BOOL IsFoundInPath() const { return bFoundInPath; }
526 void SetFoundInPath( BOOL bInPath ) { bFoundInPath = bInPath; }
528 void Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, BOOL bUseOldReloadInfo );
529 static BasicLibInfo* Create( SotStorageStream& rSStream );
531 Reference< XLibraryContainer > GetLibraryContainer( void )
532 { return mxScriptCont; }
533 void SetLibraryContainer( const Reference< XLibraryContainer >& xScriptCont )
534 { mxScriptCont = xScriptCont; }
537 DECLARE_LIST( BasicLibsBase, BasicLibInfo* )
539 class BasicLibs : public BasicLibsBase
541 public:
542 String aBasicLibPath; // TODO: Should be member of manager, but currently not incompatible
545 BasicLibInfo::BasicLibInfo()
547 bReference = FALSE;
548 bPasswordVerified = FALSE;
549 bDoLoad = FALSE;
550 bFoundInPath = FALSE;
551 mxScriptCont = NULL;
552 aStorageName = String::CreateFromAscii(szImbedded);
553 aRelStorageName = String::CreateFromAscii(szImbedded);
556 BasicLibInfo::BasicLibInfo( const String& rStorageName )
558 bReference = TRUE;
559 bPasswordVerified = FALSE;
560 bDoLoad = FALSE;
561 mxScriptCont = NULL;
562 aStorageName = rStorageName;
565 void BasicLibInfo::Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, BOOL bUseOldReloadInfo )
567 ULONG nStartPos = rSStream.Tell();
568 sal_uInt32 nEndPos = 0;
570 USHORT nId = LIBINFO_ID;
571 USHORT nVer = CURR_VER;
573 rSStream << nEndPos;
574 rSStream << nId;
575 rSStream << nVer;
577 String aCurStorageName = INetURLObject(rBasMgrStorageName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
578 DBG_ASSERT(aCurStorageName.Len() != 0, "Bad storage name");
580 // If not set initialize StorageName
581 if ( aStorageName.Len() == 0 )
582 aStorageName = aCurStorageName;
584 // Load again?
585 BOOL bDoLoad_ = xLib.Is();
586 if ( bUseOldReloadInfo )
587 bDoLoad_ = DoLoad();
588 rSStream << bDoLoad_;
590 // The name of the lib...
591 rSStream.WriteByteString(GetLibName());
593 // Absolute path...
594 if ( ! GetStorageName().EqualsAscii(szImbedded) )
596 String aSName = INetURLObject( GetStorageName(), INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
597 DBG_ASSERT(aSName.Len() != 0, "Bad storage name");
598 rSStream.WriteByteString( aSName );
600 else
601 rSStream.WriteByteString( szImbedded );
603 // Relative path...
604 if ( ( aStorageName == aCurStorageName ) || ( aStorageName.EqualsAscii(szImbedded) ) )
605 rSStream.WriteByteString( szImbedded );
606 else
608 // Do not determine the relative path if the file was only found in path:
609 // because the relative path would change and after moving the lib the
610 // the file cannot be found.
611 if ( !IsFoundInPath() )
612 CalcRelStorageName( aCurStorageName );
613 rSStream.WriteByteString(aRelStorageName);
616 // ------------------------------
617 // Version 2
618 // ------------------------------
620 // reference...
621 rSStream << bReference;
623 // ------------------------------
624 // End
625 // ------------------------------
627 nEndPos = rSStream.Tell();
628 rSStream.Seek( nStartPos );
629 rSStream << nEndPos;
630 rSStream.Seek( nEndPos );
633 BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
635 BasicLibInfo* pInfo = new BasicLibInfo;
637 sal_uInt32 nEndPos;
638 USHORT nId;
639 USHORT nVer;
641 rSStream >> nEndPos;
642 rSStream >> nId;
643 rSStream >> nVer;
645 DBG_ASSERT( nId == LIBINFO_ID, "Keine BasicLibInfo !?" );
646 if( nId == LIBINFO_ID )
648 // Reload?
649 BOOL bDoLoad;
650 rSStream >> bDoLoad;
651 pInfo->bDoLoad = bDoLoad;
653 // The name of the lib...
654 String aName;
655 rSStream.ReadByteString(aName);
656 pInfo->SetLibName( aName );
658 // Absolute path...
659 String aStorageName;
660 rSStream.ReadByteString(aStorageName);
661 pInfo->SetStorageName( aStorageName );
663 // Relative path...
664 String aRelStorageName;
665 rSStream.ReadByteString(aRelStorageName);
666 pInfo->SetRelStorageName( aRelStorageName );
668 if ( nVer >= 2 )
670 BOOL bReferenz;
671 rSStream >> bReferenz;
672 pInfo->IsReference() = bReferenz;
675 rSStream.Seek( nEndPos );
677 return pInfo;
680 void BasicLibInfo::CalcRelStorageName( const String& rMgrStorageName )
682 if ( rMgrStorageName.Len() )
684 INetURLObject aAbsURLObj( rMgrStorageName );
685 aAbsURLObj.removeSegment();
686 String aPath = aAbsURLObj.GetMainURL( INetURLObject::NO_DECODE );
687 UniString aRelURL = INetURLObject::GetRelURL( aPath, GetStorageName() );
688 SetRelStorageName( aRelURL );
690 else
691 SetRelStorageName( String() );
693 BasicManager::BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib, String* pLibPath, BOOL bDocMgr ) : mbDocMgr( bDocMgr )
695 DBG_CTOR( BasicManager, 0 );
697 Init();
699 if( pLibPath )
700 pLibs->aBasicLibPath = *pLibPath;
702 String aStorName( rStorage.GetName() );
703 maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
705 // #91251: Storage name not longer available for documents < 5.0
706 // Should be no real problem, because only relative storage names
707 // (links) can be affected.
708 // DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
709 // DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
711 // If there is no Manager Stream, no further actions are necessary
712 if ( rStorage.IsStream( ManagerStreamName ) )
714 LoadBasicManager( rStorage, rBaseURL );
715 // StdLib contains Parent:
716 StarBASIC* pStdLib = GetStdLib();
717 DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" );
718 if ( !pStdLib )
720 // Should never happen, but if it happens we wont crash...
721 pStdLib = new StarBASIC( NULL, mbDocMgr );
722 BasicLibInfo* pStdLibInfo = pLibs->GetObject( 0 );
723 if ( !pStdLibInfo )
724 pStdLibInfo = CreateLibInfo();
725 pStdLibInfo->SetLib( pStdLib );
726 StarBASICRef xStdLib = pStdLibInfo->GetLib();
727 xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
728 pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
729 xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
730 xStdLib->SetModified( FALSE );
732 else
734 pStdLib->SetParent( pParentFromStdLib );
735 // The other get StdLib as parent:
736 for ( USHORT nBasic = 1; nBasic < GetLibCount(); nBasic++ )
738 StarBASIC* pBasic = GetLib( nBasic );
739 if ( pBasic )
741 // pBasic->SetParent( pStdLib );
742 pStdLib->Insert( pBasic );
743 pBasic->SetFlag( SBX_EXTSEARCH );
746 // Modified through insert
747 pStdLib->SetModified( FALSE );
750 // #91626 Save all stream data to save it unmodified if basic isn't modified
751 // in an 6.0+ office. So also the old basic dialogs can be saved.
752 SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
753 ( ManagerStreamName, eStreamReadMode );
754 mpImpl->mpManagerStream = new SvMemoryStream();
755 *static_cast<SvStream*>(&xManagerStream) >> *mpImpl->mpManagerStream;
757 SotStorageRef xBasicStorage = rStorage.OpenSotStorage
758 ( BasicStreamName, eStorageReadMode, FALSE );
759 if( xBasicStorage.Is() && !xBasicStorage->GetError() )
761 USHORT nLibs = GetLibCount();
762 mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ];
763 for( USHORT nL = 0; nL < nLibs; nL++ )
765 BasicLibInfo* pInfo = pLibs->GetObject( nL );
766 DBG_ASSERT( pInfo, "pInfo?!" );
767 SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), eStreamReadMode );
768 mpImpl->mppLibStreams[nL] = new SvMemoryStream();
769 *static_cast<SvStream*>(&xBasicStream) >> *( mpImpl->mppLibStreams[nL] );
772 else
773 mpImpl->mbError = sal_True;
775 else
777 ImpCreateStdLib( pParentFromStdLib );
778 if ( rStorage.IsStream( String::CreateFromAscii(szOldManagerStream) ) )
779 LoadOldBasicManager( rStorage );
782 bBasMgrModified = FALSE;
785 void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
787 Reference< XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
788 if ( !xScriptCont.is() )
789 return;
791 String aLibName = pBasic->GetName();
792 if( !xScriptCont->hasByName( aLibName ) )
793 xScriptCont->createLibrary( aLibName );
795 Any aLibAny = xScriptCont->getByName( aLibName );
796 Reference< XNameContainer > xLib;
797 aLibAny >>= xLib;
798 if ( !xLib.is() )
799 return;
801 USHORT nModCount = pBasic->GetModules()->Count();
802 for ( USHORT nMod = 0 ; nMod < nModCount ; nMod++ )
804 SbModule* pModule = (SbModule*)pBasic->GetModules()->Get( nMod );
805 DBG_ASSERT( pModule, "Modul nicht erhalten!" );
807 String aModName = pModule->GetName();
808 if( !xLib->hasByName( aModName ) )
810 ::rtl::OUString aSource = pModule->GetSource32();
811 Any aSourceAny;
812 aSourceAny <<= aSource;
813 xLib->insertByName( aModName, aSourceAny );
818 const Reference< XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const
820 return mpImpl->maContainerInfo.mxDialogCont;
823 const Reference< XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const
825 return mpImpl->maContainerInfo.mxScriptCont;
828 void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
830 mpImpl->maContainerInfo = rInfo;
832 Reference< XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
833 StarBASIC* pStdLib = GetStdLib();
834 String aLibName = pStdLib->GetName();
835 if( xScriptCont.is() )
837 // Register listener for lib container
838 ::rtl::OUString aEmptyLibName;
839 Reference< XContainerListener > xLibContainerListener
840 = static_cast< XContainerListener* >
841 ( new BasMgrContainerListenerImpl( this, aEmptyLibName ) );
843 Reference< XContainer> xLibContainer( xScriptCont, UNO_QUERY );
844 xLibContainer->addContainerListener( xLibContainerListener );
846 Sequence< ::rtl::OUString > aScriptLibNames = xScriptCont->getElementNames();
847 const ::rtl::OUString* pScriptLibName = aScriptLibNames.getConstArray();
848 sal_Int32 i, nNameCount = aScriptLibNames.getLength();
850 if( nNameCount )
852 for( i = 0 ; i < nNameCount ; ++i, ++pScriptLibName )
854 Any aLibAny = xScriptCont->getByName( *pScriptLibName );
856 if ( pScriptLibName->equalsAscii( "Standard" ) )
857 xScriptCont->loadLibrary( *pScriptLibName );
859 BasMgrContainerListenerImpl::insertLibraryImpl
860 ( xScriptCont, this, aLibAny, *pScriptLibName );
863 else
865 // No libs? Maybe an 5.2 document already loaded
866 USHORT nLibs = GetLibCount();
867 for( USHORT nL = 0; nL < nLibs; nL++ )
869 BasicLibInfo* pBasLibInfo = pLibs->GetObject( nL );
870 StarBASIC* pLib = pBasLibInfo->GetLib();
871 if( !pLib )
873 BOOL bLoaded = ImpLoadLibary( pBasLibInfo, NULL, FALSE );
874 if( bLoaded )
875 pLib = pBasLibInfo->GetLib();
877 if( pLib )
879 copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
880 if( pBasLibInfo->HasPassword() )
882 OldBasicPassword* pOldBasicPassword =
883 mpImpl->maContainerInfo.mpOldBasicPassword;
884 if( pOldBasicPassword )
886 pOldBasicPassword->setLibraryPassword
887 ( pLib->GetName(), pBasLibInfo->GetPassword() );
888 pBasLibInfo->SetPasswordVerified();
894 mpImpl->mbModifiedByLibraryContainer = sal_False;
898 SetGlobalUNOConstant( "BasicLibraries", makeAny( mpImpl->maContainerInfo.mxScriptCont ) );
899 SetGlobalUNOConstant( "DialogLibraries", makeAny( mpImpl->maContainerInfo.mxDialogCont ) );
902 BasicManager::BasicManager( StarBASIC* pSLib, String* pLibPath, BOOL bDocMgr ) : mbDocMgr( bDocMgr )
904 DBG_CTOR( BasicManager, 0 );
905 Init();
906 DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" );
908 if( pLibPath )
909 pLibs->aBasicLibPath = *pLibPath;
911 BasicLibInfo* pStdLibInfo = CreateLibInfo();
912 pStdLibInfo->SetLib( pSLib );
913 StarBASICRef xStdLib = pStdLibInfo->GetLib();
914 xStdLib->SetName( String::CreateFromAscii(szStdLibName));
915 pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
916 pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
918 // Save is only necessary if basic has changed
919 xStdLib->SetModified( FALSE );
920 bBasMgrModified = FALSE;
923 BasicManager::BasicManager()
925 DBG_CTOR( BasicManager, 0 );
926 // This ctor may only be used to adapt relative paths for 'Save As'.
927 // There is no AppBasic so libs must not be loaded...
928 Init();
931 void BasicManager::ImpMgrNotLoaded( const String& rStorageName )
933 // pErrInf is only destroyed if the error os processed by an
934 // ErrorHandler
935 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK );
936 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, rStorageName ) );
938 // Create a stdlib otherwise we crash!
939 BasicLibInfo* pStdLibInfo = CreateLibInfo();
940 pStdLibInfo->SetLib( new StarBASIC( NULL, mbDocMgr ) );
941 StarBASICRef xStdLib = pStdLibInfo->GetLib();
942 xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
943 pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
944 xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
945 xStdLib->SetModified( FALSE );
949 void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
951 BasicLibInfo* pStdLibInfo = CreateLibInfo();
952 StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
953 pStdLibInfo->SetLib( pStdLib );
954 pStdLib->SetName( String::CreateFromAscii(szStdLibName) );
955 pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
956 pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
960 void BasicManager::LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, BOOL bLoadLibs )
962 DBG_CHKTHIS( BasicManager, 0 );
964 // StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
966 SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
967 ( ManagerStreamName, eStreamReadMode );
969 String aStorName( rStorage.GetName() );
970 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
972 if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
974 ImpMgrNotLoaded( aStorName );
975 return;
978 maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
979 // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
981 String aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL
983 // If loaded from template, only BaseURL is used:
984 //String aBaseURL = INetURLObject::GetBaseURL();
985 if ( rBaseURL.Len() )
987 INetURLObject aObj( rBaseURL );
988 if ( aObj.GetProtocol() == INET_PROT_FILE )
989 aRealStorageName = aObj.PathToFileName();
992 xManagerStream->SetBufferSize( 1024 );
993 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
995 sal_uInt32 nEndPos;
996 *xManagerStream >> nEndPos;
998 USHORT nLibs;
999 *xManagerStream >> nLibs;
1000 // Plausi!
1001 if( nLibs & 0xF000 )
1003 DBG_ASSERT( !this, "BasicManager-Stream defect!" );
1004 return;
1006 for ( USHORT nL = 0; nL < nLibs; nL++ )
1008 BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
1010 // Correct absolute pathname if relative is existing.
1011 // Always try relative first if there are two stands on disk
1012 if ( pInfo->GetRelStorageName().Len() && ( ! pInfo->GetRelStorageName().EqualsAscii(szImbedded) ) )
1014 INetURLObject aObj( aRealStorageName, INET_PROT_FILE );
1015 aObj.removeSegment();
1016 bool bWasAbsolute = FALSE;
1017 aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
1019 //*** TODO: Replace if still necessary
1020 /* if ( SfxContentHelper::Exists( aObj.GetMainURL() ) )
1021 pInfo->SetStorageName( aObj.GetMainURL() );
1022 else */
1023 //*** TODO-End
1024 if ( pLibs->aBasicLibPath.Len() )
1026 // Search lib in path
1027 String aSearchFile = pInfo->GetRelStorageName();
1028 SvtPathOptions aPathCFG;
1029 if( aPathCFG.SearchFile( aSearchFile, SvtPathOptions::PATH_BASIC ) )
1031 pInfo->SetStorageName( aSearchFile );
1032 pInfo->SetFoundInPath( TRUE );
1037 pLibs->Insert( pInfo, LIST_APPEND );
1038 // Libs from external files should be loaded only when necessary.
1039 // But references are loaded at once, otherwise some big customers get into trouble
1040 if ( bLoadLibs && pInfo->DoLoad() &&
1041 ( ( !pInfo->IsExtern() ) || ( pInfo->IsReference() ) ) )
1043 ImpLoadLibary( pInfo, &rStorage );
1047 xManagerStream->Seek( nEndPos );
1048 xManagerStream->SetBufferSize( 0 );
1049 xManagerStream.Clear();
1052 void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
1054 DBG_CHKTHIS( BasicManager, 0 );
1056 // StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
1058 SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
1059 ( String::CreateFromAscii(szOldManagerStream), eStreamReadMode );
1061 String aStorName( rStorage.GetName() );
1062 DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1064 if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
1066 ImpMgrNotLoaded( aStorName );
1067 return;
1070 xManagerStream->SetBufferSize( 1024 );
1071 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
1072 sal_uInt32 nBasicStartOff, nBasicEndOff;
1073 *xManagerStream >> nBasicStartOff;
1074 *xManagerStream >> nBasicEndOff;
1076 DBG_ASSERT( !xManagerStream->GetError(), "Ungueltiger Manager-Stream!" );
1078 xManagerStream->Seek( nBasicStartOff );
1079 if( !ImplLoadBasic( *xManagerStream, pLibs->GetObject(0)->GetLibRef() ) )
1081 // String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) );
1082 // aErrorText.SearchAndReplace( "XX", aStorName );
1083 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK );
1084 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) );
1085 // und es geht weiter...
1087 xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator
1088 String aLibs;
1089 xManagerStream->ReadByteString(aLibs);
1090 xManagerStream->SetBufferSize( 0 );
1091 xManagerStream.Clear(); // Close stream
1093 if ( aLibs.Len() )
1095 String aCurStorageName( aStorName );
1096 INetURLObject aCurStorage( aCurStorageName, INET_PROT_FILE );
1097 USHORT nLibs = aLibs.GetTokenCount( LIB_SEP );
1098 for ( USHORT nLib = 0; nLib < nLibs; nLib++ )
1100 String aLibInfo( aLibs.GetToken( nLib, LIB_SEP ) );
1101 // TODO: Remove == 2
1102 DBG_ASSERT( ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 2 ) || ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 3 ), "Ungueltige Lib-Info!" );
1103 String aLibName( aLibInfo.GetToken( 0, LIBINFO_SEP ) );
1104 String aLibAbsStorageName( aLibInfo.GetToken( 1, LIBINFO_SEP ) );
1105 String aLibRelStorageName( aLibInfo.GetToken( 2, LIBINFO_SEP ) );
1106 INetURLObject aLibAbsStorage( aLibAbsStorageName, INET_PROT_FILE );
1108 INetURLObject aLibRelStorage( aStorName );
1109 aLibRelStorage.removeSegment();
1110 bool bWasAbsolute = FALSE;
1111 aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
1112 DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
1114 SotStorageRef xStorageRef;
1115 if ( ( aLibAbsStorage == aCurStorage ) || ( aLibRelStorageName.EqualsAscii(szImbedded) ) )
1116 xStorageRef = &rStorage;
1117 else
1119 xStorageRef = new SotStorage( FALSE, aLibAbsStorage.GetMainURL
1120 ( INetURLObject::NO_DECODE ), eStorageReadMode, TRUE );
1121 if ( xStorageRef->GetError() != ERRCODE_NONE )
1122 xStorageRef = new SotStorage( FALSE, aLibRelStorage.
1123 GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode, TRUE );
1125 if ( xStorageRef.Is() )
1126 AddLib( *xStorageRef, aLibName, FALSE );
1127 else
1129 // String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
1130 // aErrorText.SearchAndReplace( "XX", aLibName );
1131 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK );
1132 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STORAGENOTFOUND, aStorName ) );
1138 BasicManager::~BasicManager()
1140 DBG_DTOR( BasicManager, 0 );
1142 // Notify listener if something needs to be saved
1143 Broadcast( SfxSimpleHint( SFX_HINT_DYING) );
1145 // Destroy Basic-Infos...
1146 // In reverse order
1147 BasicLibInfo* pInf = pLibs->Last();
1148 while ( pInf )
1150 delete pInf;
1151 pInf = pLibs->Prev();
1153 pLibs->Clear();
1154 delete pLibs;
1155 delete pErrorMgr;
1156 delete mpImpl;
1159 void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
1161 delete _rpManager;
1162 _rpManager = NULL;
1166 bool BasicManager::HasExeCode( const String& sLib )
1168 StarBASIC* pLib = GetLib(sLib);
1169 if ( pLib )
1171 SbxArray* pMods = pLib->GetModules();
1172 USHORT nMods = pMods ? pMods->Count() : 0;
1173 for( USHORT i = 0; i < nMods; i++ )
1175 SbModule* p = (SbModule*) pMods->Get( i );
1176 if ( p )
1177 if ( p->HasExeCode() )
1178 return true;
1181 return false;
1184 void BasicManager::Init()
1186 DBG_CHKTHIS( BasicManager, 0 );
1188 bBasMgrModified = FALSE;
1189 pErrorMgr = new BasicErrorManager;
1190 pLibs = new BasicLibs;
1191 mpImpl = new BasicManagerImpl();
1194 BasicLibInfo* BasicManager::CreateLibInfo()
1196 DBG_CHKTHIS( BasicManager, 0 );
1198 BasicLibInfo* pInf = new BasicLibInfo;
1199 pLibs->Insert( pInf, LIST_APPEND );
1200 return pInf;
1203 BOOL BasicManager::ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, BOOL bInfosOnly ) const
1205 DBG_CHKTHIS( BasicManager, 0 );
1207 DBG_ASSERT( pLibInfo, "LibInfo!?" );
1209 String aStorageName( pLibInfo->GetStorageName() );
1210 if ( !aStorageName.Len() || ( aStorageName.EqualsAscii(szImbedded) ) )
1211 aStorageName = GetStorageName();
1213 SotStorageRef xStorage;
1214 // The current must not be opened again...
1215 if ( pCurStorage )
1217 String aStorName( pCurStorage->GetName() );
1218 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1220 INetURLObject aCurStorageEntry(aStorName, INET_PROT_FILE);
1221 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
1223 INetURLObject aStorageEntry(aStorageName, INET_PROT_FILE);
1224 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
1226 if ( aCurStorageEntry == aStorageEntry )
1227 xStorage = pCurStorage;
1230 if ( !xStorage.Is() )
1231 xStorage = new SotStorage( FALSE, aStorageName, eStorageReadMode );
1233 SotStorageRef xBasicStorage = xStorage->OpenSotStorage
1234 ( BasicStreamName, eStorageReadMode, FALSE );
1236 if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1238 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), ERRCODE_BUTTON_OK );
1239 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
1241 else
1243 // In the Basic-Storage every lib is in a Stream...
1244 SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
1245 if ( !xBasicStream.Is() || xBasicStream->GetError() )
1247 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1248 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLibInfo->GetLibName() ) );
1250 else
1252 BOOL bLoaded = FALSE;
1253 if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 )
1255 if ( !bInfosOnly )
1257 if ( !pLibInfo->GetLib().Is() )
1258 pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
1259 xBasicStream->SetBufferSize( 1024 );
1260 xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1261 bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
1262 xBasicStream->SetBufferSize( 0 );
1263 StarBASICRef xStdLib = pLibInfo->GetLib();
1264 xStdLib->SetName( pLibInfo->GetLibName() );
1265 xStdLib->SetModified( FALSE );
1266 xStdLib->SetFlag( SBX_DONTSTORE );
1268 else
1270 // Skip Basic...
1271 xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1272 ImplEncryptStream( *xBasicStream );
1273 SbxBase::Skip( *xBasicStream );
1274 bLoaded = TRUE;
1277 if ( !bLoaded )
1279 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1280 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_BASICLOADERROR, pLibInfo->GetLibName() ) );
1282 else
1284 // Perhaps there are additional information in the stream...
1285 xBasicStream->SetKey( szCryptingKey );
1286 xBasicStream->RefreshBuffer();
1287 sal_uInt32 nPasswordMarker = 0;
1288 *xBasicStream >> nPasswordMarker;
1289 if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() )
1291 String aPassword;
1292 xBasicStream->ReadByteString(aPassword);
1293 pLibInfo->SetPassword( aPassword );
1295 xBasicStream->SetKey( ByteString() );
1296 CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() );
1298 return bLoaded;
1301 return FALSE;
1304 BOOL BasicManager::ImplEncryptStream( SvStream& rStrm ) const
1306 ULONG nPos = rStrm.Tell();
1307 UINT32 nCreator;
1308 rStrm >> nCreator;
1309 rStrm.Seek( nPos );
1310 BOOL bProtected = FALSE;
1311 if ( nCreator != SBXCR_SBX )
1313 // Should only be the case for encrypted Streams
1314 bProtected = TRUE;
1315 rStrm.SetKey( szCryptingKey );
1316 rStrm.RefreshBuffer();
1318 return bProtected;
1321 // This code is necessary to load the BASIC of Beta 1
1322 // TODO: Which Beta 1?
1323 BOOL BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
1325 BOOL bProtected = ImplEncryptStream( rStrm );
1326 SbxBaseRef xNew = SbxBase::Load( rStrm );
1327 BOOL bLoaded = FALSE;
1328 if( xNew.Is() )
1330 if( xNew->IsA( TYPE(StarBASIC) ) )
1332 StarBASIC* pNew = (StarBASIC*)(SbxBase*) xNew;
1333 // Use the Parent of the old BASICs
1334 if( rOldBasic.Is() )
1336 pNew->SetParent( rOldBasic->GetParent() );
1337 if( pNew->GetParent() )
1338 pNew->GetParent()->Insert( pNew );
1339 pNew->SetFlag( SBX_EXTSEARCH );
1341 rOldBasic = pNew;
1343 // Fill new libray container (5.2 -> 6.0)
1344 copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
1347 if( rOldBasic->GetParent() )
1349 rOldBasic->GetParent()->Insert( rOldBasic );
1350 rOldBasic->SetFlag( SBX_EXTSEARCH );
1353 pNew->SetModified( FALSE );
1354 bLoaded = TRUE;
1357 if ( bProtected )
1358 rStrm.SetKey( ByteString() );
1359 return bLoaded;
1362 void BasicManager::CheckModules( StarBASIC* pLib, BOOL bReference ) const
1364 if ( !pLib )
1365 return;
1367 BOOL bModified = pLib->IsModified();
1369 for ( USHORT nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ )
1371 SbModule* pModule = (SbModule*)pLib->GetModules()->Get( nMod );
1372 DBG_ASSERT( pModule, "Modul nicht erhalten!" );
1373 if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
1374 pLib->Compile( pModule );
1377 // #67477, AB 8.12.99 On demand compile in referenced libs should not
1378 // cause modified
1379 if( !bModified && bReference )
1381 DBG_ERROR( "Per Reference eingebundene Basic-Library ist nicht compiliert!" );
1382 pLib->SetModified( FALSE );
1386 StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const String& rLibName, BOOL bReference )
1388 DBG_CHKTHIS( BasicManager, 0 );
1390 String aStorName( rStorage.GetName() );
1391 DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1393 String aStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
1394 DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
1396 String aNewLibName( rLibName );
1397 while ( HasLib( aNewLibName ) )
1398 aNewLibName += '_';
1400 BasicLibInfo* pLibInfo = CreateLibInfo();
1401 // Use original name otherwise ImpLoadLibary failes...
1402 pLibInfo->SetLibName( rLibName );
1403 // Funktioniert so aber nicht, wenn Name doppelt
1404 // USHORT nLibId = GetLibId( rLibName );
1405 USHORT nLibId = (USHORT) pLibs->GetPos( pLibInfo );
1407 // Set StorageName before load because it is compared with pCurStorage
1408 pLibInfo->SetStorageName( aStorageName );
1409 BOOL bLoaded = ImpLoadLibary( pLibInfo, &rStorage );
1411 if ( bLoaded )
1413 if ( aNewLibName != rLibName )
1414 SetLibName( nLibId, aNewLibName );
1416 if ( bReference )
1418 pLibInfo->GetLib()->SetModified( FALSE ); // Don't save in this case
1419 pLibInfo->SetRelStorageName( String() );
1420 // pLibInfo->CalcRelStorageName( GetStorageName() );
1421 pLibInfo->IsReference() = TRUE;
1423 else
1425 pLibInfo->GetLib()->SetModified( TRUE ); // Must be saved after Add!
1426 pLibInfo->SetStorageName( String::CreateFromAscii(szImbedded) ); // Save in BasicManager-Storage
1428 bBasMgrModified = TRUE;
1430 else
1432 RemoveLib( nLibId, FALSE );
1433 pLibInfo = 0;
1436 if( pLibInfo )
1437 return &*pLibInfo->GetLib() ;
1438 else
1439 return 0;
1442 BOOL BasicManager::IsReference( USHORT nLib )
1444 DBG_CHKTHIS( BasicManager, 0 );
1446 BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1447 DBG_ASSERT( pLibInfo, "Lib?!" );
1448 if ( pLibInfo )
1449 return pLibInfo->IsReference();
1451 return FALSE;
1454 BOOL BasicManager::RemoveLib( USHORT nLib )
1456 // Only pyhsical deletion if no reference
1457 return RemoveLib( nLib, !IsReference( nLib ) );
1460 BOOL BasicManager::RemoveLib( USHORT nLib, BOOL bDelBasicFromStorage )
1462 DBG_CHKTHIS( BasicManager, 0 );
1463 DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" );
1465 BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1466 DBG_ASSERT( pLibInfo, "Lib not found!" );
1468 if ( !pLibInfo || !nLib )
1470 // String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
1471 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
1472 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STDLIB, pLibInfo->GetLibName() ) );
1473 return FALSE;
1476 // If one of the streams cannot be opened, this is not an error,
1477 // because BASIC was never written before...
1478 if ( bDelBasicFromStorage && !pLibInfo->IsReference() &&
1479 ( !pLibInfo->IsExtern() || SotStorage::IsStorageFile( pLibInfo->GetStorageName() ) ) )
1481 SotStorageRef xStorage;
1482 if ( !pLibInfo->IsExtern() )
1483 xStorage = new SotStorage( FALSE, GetStorageName() );
1484 else
1485 xStorage = new SotStorage( FALSE, pLibInfo->GetStorageName() );
1487 if ( xStorage->IsStorage( BasicStreamName ) )
1489 SotStorageRef xBasicStorage = xStorage->OpenSotStorage
1490 ( BasicStreamName, STREAM_STD_READWRITE, FALSE );
1492 if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1494 // String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
1495 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
1496 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
1498 else if ( xBasicStorage->IsStream( pLibInfo->GetLibName() ) )
1500 xBasicStorage->Remove( pLibInfo->GetLibName() );
1501 xBasicStorage->Commit();
1503 // If no further stream available,
1504 // delete the SubStorage.
1505 SvStorageInfoList aInfoList( 0, 4 );
1506 xBasicStorage->FillInfoList( &aInfoList );
1507 if ( !aInfoList.Count() )
1509 xBasicStorage.Clear();
1510 xStorage->Remove( BasicStreamName );
1511 xStorage->Commit();
1512 // If no further Streams or SubStorages available,
1513 // delete the Storage, too.
1514 aInfoList.Clear();
1515 xStorage->FillInfoList( &aInfoList );
1516 if ( !aInfoList.Count() )
1518 String aName_( xStorage->GetName() );
1519 xStorage.Clear();
1520 //*** TODO: Replace if still necessary
1521 //SfxContentHelper::Kill( aName );
1522 //*** TODO-End
1528 bBasMgrModified = TRUE;
1529 if ( pLibInfo->GetLib().Is() )
1530 GetStdLib()->Remove( pLibInfo->GetLib() );
1531 delete pLibs->Remove( pLibInfo );
1532 return TRUE; // Remove was successful, del unimportant
1535 USHORT BasicManager::GetLibCount() const
1537 DBG_CHKTHIS( BasicManager, 0 );
1538 return (USHORT)pLibs->Count();
1541 StarBASIC* BasicManager::GetLib( USHORT nLib ) const
1543 DBG_CHKTHIS( BasicManager, 0 );
1544 BasicLibInfo* pInf = pLibs->GetObject( nLib );
1545 DBG_ASSERT( pInf, "Lib existiert nicht!" );
1546 if ( pInf )
1547 return pInf->GetLib();
1548 return 0;
1551 StarBASIC* BasicManager::GetStdLib() const
1553 DBG_CHKTHIS( BasicManager, 0 );
1554 StarBASIC* pLib = GetLib( 0 );
1555 return pLib;
1558 StarBASIC* BasicManager::GetLib( const String& rName ) const
1560 DBG_CHKTHIS( BasicManager, 0 );
1562 BasicLibInfo* pInf = pLibs->First();
1563 while ( pInf )
1565 if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )// Check if available...
1566 return pInf->GetLib();
1568 pInf = pLibs->Next();
1570 return 0;
1573 USHORT BasicManager::GetLibId( const String& rName ) const
1575 DBG_CHKTHIS( BasicManager, 0 );
1577 BasicLibInfo* pInf = pLibs->First();
1578 while ( pInf )
1580 if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
1581 return (USHORT)pLibs->GetCurPos();
1583 pInf = pLibs->Next();
1585 return LIB_NOTFOUND;
1588 BOOL BasicManager::HasLib( const String& rName ) const
1590 DBG_CHKTHIS( BasicManager, 0 );
1592 BasicLibInfo* pInf = pLibs->First();
1593 while ( pInf )
1595 if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
1596 return TRUE;
1598 pInf = pLibs->Next();
1600 return FALSE;
1603 BOOL BasicManager::SetLibName( USHORT nLib, const String& rName )
1605 DBG_CHKTHIS( BasicManager, 0 );
1607 BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1608 DBG_ASSERT( pLibInfo, "Lib?!" );
1609 if ( pLibInfo )
1611 pLibInfo->SetLibName( rName );
1612 if ( pLibInfo->GetLib().Is() )
1614 StarBASICRef xStdLib = pLibInfo->GetLib();
1615 xStdLib->SetName( rName );
1616 xStdLib->SetModified( TRUE );
1618 bBasMgrModified = TRUE;
1619 return TRUE;
1621 return FALSE;
1624 String BasicManager::GetLibName( USHORT nLib )
1626 DBG_CHKTHIS( BasicManager, 0 );
1628 BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1629 DBG_ASSERT( pLibInfo, "Lib?!" );
1630 if ( pLibInfo )
1631 return pLibInfo->GetLibName();
1632 return String();
1635 BOOL BasicManager::LoadLib( USHORT nLib )
1637 DBG_CHKTHIS( BasicManager, 0 );
1639 BOOL bDone = FALSE;
1640 BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1641 DBG_ASSERT( pLibInfo, "Lib?!" );
1642 if ( pLibInfo )
1644 Reference< XLibraryContainer > xLibContainer = pLibInfo->GetLibraryContainer();
1645 if( xLibContainer.is() )
1647 String aLibName = pLibInfo->GetLibName();
1648 xLibContainer->loadLibrary( aLibName );
1649 bDone = xLibContainer->isLibraryLoaded( aLibName );;
1651 else
1653 bDone = ImpLoadLibary( pLibInfo, NULL, FALSE );
1654 StarBASIC* pLib = GetLib( nLib );
1655 if ( pLib )
1657 // pLib->SetParent( GetStdLib() );
1658 GetStdLib()->Insert( pLib );
1659 pLib->SetFlag( SBX_EXTSEARCH );
1663 else
1665 // String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
1666 // aErrorText.SearchAndReplace( "XX", "" );
1667 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, String(), ERRCODE_BUTTON_OK );
1668 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_LIBNOTFOUND, String::CreateFromInt32(nLib) ) );
1670 return bDone;
1673 StarBASIC* BasicManager::CreateLib( const String& rLibName )
1675 DBG_CHKTHIS( BasicManager, 0 );
1676 if ( GetLib( rLibName ) )
1677 return 0;
1679 BasicLibInfo* pLibInfo = CreateLibInfo();
1680 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1681 GetStdLib()->Insert( pNew );
1682 pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1683 pLibInfo->SetLib( pNew );
1684 pLibInfo->SetLibName( rLibName );
1685 pLibInfo->GetLib()->SetName( rLibName );
1686 return pLibInfo->GetLib();
1689 // For XML import/export:
1690 StarBASIC* BasicManager::CreateLib
1691 ( const String& rLibName, const String& Password, const String& LinkTargetURL )
1693 // Ask if lib exists because standard lib is always there
1694 StarBASIC* pLib = GetLib( rLibName );
1695 if( !pLib )
1697 if( LinkTargetURL.Len() != 0 )
1699 SotStorageRef xStorage = new SotStorage( FALSE, LinkTargetURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
1700 if( !xStorage->GetError() )
1702 pLib = AddLib( *xStorage, rLibName, TRUE );
1704 //if( !pLibInfo )
1705 //pLibInfo = FindLibInfo( pLib );
1706 //pLibInfo->SetStorageName( LinkTargetURL );
1707 //pLibInfo->GetLib()->SetModified( FALSE ); // Dann nicht speichern
1708 //pLibInfo->SetRelStorageName( String() );
1709 //pLibInfo->IsReference() = TRUE;
1711 //else
1712 //Message?
1714 DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
1716 else
1718 pLib = CreateLib( rLibName );
1719 if( Password.Len() != 0 )
1721 BasicLibInfo* pLibInfo = FindLibInfo( pLib );
1722 pLibInfo ->SetPassword( Password );
1725 //ExternalSourceURL ?
1727 return pLib;
1730 StarBASIC* BasicManager::CreateLibForLibContainer( const String& rLibName,
1731 const Reference< XLibraryContainer >& xScriptCont )
1733 DBG_CHKTHIS( BasicManager, 0 );
1734 if ( GetLib( rLibName ) )
1735 return 0;
1737 BasicLibInfo* pLibInfo = CreateLibInfo();
1738 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1739 GetStdLib()->Insert( pNew );
1740 pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1741 pLibInfo->SetLib( pNew );
1742 pLibInfo->SetLibName( rLibName );
1743 pLibInfo->GetLib()->SetName( rLibName );
1744 pLibInfo->SetLibraryContainer( xScriptCont );
1745 return pNew;
1749 BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic ) const
1751 DBG_CHKTHIS( BasicManager, 0 );
1753 BasicLibInfo* pInf = ((BasicManager*)this)->pLibs->First();
1754 while ( pInf )
1756 if ( pInf->GetLib() == pBasic )
1757 return pInf;
1759 pInf = ((BasicManager*)this)->pLibs->Next();
1761 return 0;
1765 BOOL BasicManager::IsModified() const
1767 DBG_CHKTHIS( BasicManager, 0 );
1769 if ( bBasMgrModified )
1770 return TRUE;
1771 return IsBasicModified();
1774 BOOL BasicManager::IsBasicModified() const
1776 DBG_CHKTHIS( BasicManager, 0 );
1778 BasicLibInfo* pInf = pLibs->First();
1779 while ( pInf )
1781 if ( pInf->GetLib().Is() && pInf->GetLib()->IsModified() )
1782 return TRUE;
1784 pInf = pLibs->Next();
1786 return FALSE;
1789 void BasicManager::SetFlagToAllLibs( short nFlag, BOOL bSet ) const
1791 USHORT nLibs = GetLibCount();
1792 for ( USHORT nL = 0; nL < nLibs; nL++ )
1794 BasicLibInfo* pInfo = pLibs->GetObject( nL );
1795 DBG_ASSERT( pInfo, "Info?!" );
1796 StarBASIC* pLib = pInfo->GetLib();
1797 if ( pLib )
1799 if ( bSet )
1800 pLib->SetFlag( nFlag );
1801 else
1802 pLib->ResetFlag( nFlag );
1807 BOOL BasicManager::HasErrors()
1809 DBG_CHKTHIS( BasicManager, 0 );
1810 return pErrorMgr->HasErrors();
1813 void BasicManager::ClearErrors()
1815 DBG_CHKTHIS( BasicManager, 0 );
1816 pErrorMgr->Reset();
1819 BasicError* BasicManager::GetFirstError()
1821 DBG_CHKTHIS( BasicManager, 0 );
1822 return pErrorMgr->GetFirstError();
1825 BasicError* BasicManager::GetNextError()
1827 DBG_CHKTHIS( BasicManager, 0 );
1828 return pErrorMgr->GetNextError();
1830 bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
1832 bool bRes = false;
1833 StarBASIC* pStandardLib = GetStdLib();
1834 OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
1835 if ( pStandardLib )
1836 bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut );
1837 return bRes;
1840 Any BasicManager::SetGlobalUNOConstant( const sal_Char* _pAsciiName, const Any& _rValue )
1842 Any aOldValue;
1844 StarBASIC* pStandardLib = GetStdLib();
1845 OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
1846 if ( !pStandardLib )
1847 return aOldValue;
1849 ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
1851 // obtain the old value
1852 SbxVariable* pVariable = pStandardLib->Find( sVarName, SbxCLASS_OBJECT );
1853 if ( pVariable )
1854 aOldValue = sbxToUnoValue( pVariable );
1856 SbxObjectRef xUnoObj = GetSbUnoObject( sVarName, _rValue );
1857 xUnoObj->SetFlag( SBX_DONTSTORE );
1858 pStandardLib->Insert( xUnoObj );
1860 return aOldValue;
1863 bool BasicManager::LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames )
1867 Reference< XNameAccess > xScripts( GetScriptLibraryContainer(), UNO_QUERY_THROW );
1868 Reference< XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), UNO_QUERY_THROW );
1870 Sequence< ::rtl::OUString > aNames( xScripts->getElementNames() );
1871 const ::rtl::OUString* pNames = aNames.getConstArray();
1872 const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
1873 for ( ; pNames != pNamesEnd; ++pNames )
1875 if( /*pLib->mbSharedIndexFile ||*/ !xPassword->isLibraryPasswordProtected( *pNames ) )
1876 continue;
1878 StarBASIC* pBasicLib = GetLib( *pNames );
1879 if ( !pBasicLib )
1880 continue;
1882 Reference< XNameAccess > xScriptLibrary( xScripts->getByName( *pNames ), UNO_QUERY_THROW );
1883 Sequence< ::rtl::OUString > aElementNames( xScriptLibrary->getElementNames() );
1884 sal_Int32 nLen = aElementNames.getLength();
1886 Sequence< ::rtl::OUString > aBigModules( nLen );
1887 sal_Int32 nBigModules = 0;
1889 const ::rtl::OUString* pElementNames = aElementNames.getConstArray();
1890 const ::rtl::OUString* pElementNamesEnd = aElementNames.getConstArray() + aElementNames.getLength();
1891 for ( ; pElementNames != pElementNamesEnd; ++pElementNames )
1893 SbModule* pMod = pBasicLib->FindModule( *pElementNames );
1894 if ( pMod && pMod->ExceedsLegacyModuleSize() )
1895 aBigModules[ nBigModules++ ] = *pElementNames;
1898 if ( nBigModules )
1900 aBigModules.realloc( nBigModules );
1901 _out_rModuleNames = aBigModules;
1902 return true;
1906 catch( const Exception& )
1908 DBG_UNHANDLED_EXCEPTION();
1910 return false;
1913 //=====================================================================
1915 class ModuleInfo_Impl : public ModuleInfoHelper
1917 ::rtl::OUString maName;
1918 ::rtl::OUString maLanguage;
1919 ::rtl::OUString maSource;
1921 public:
1922 ModuleInfo_Impl( const ::rtl::OUString& aName, const ::rtl::OUString& aLanguage, const ::rtl::OUString& aSource )
1923 : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
1925 // Methods XStarBasicModuleInfo
1926 virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
1927 { return maName; }
1928 virtual ::rtl::OUString SAL_CALL getLanguage() throw(RuntimeException)
1929 { return maLanguage; }
1930 virtual ::rtl::OUString SAL_CALL getSource() throw(RuntimeException)
1931 { return maSource; }
1935 //=====================================================================
1937 class DialogInfo_Impl : public DialogInfoHelper
1939 ::rtl::OUString maName;
1940 Sequence< sal_Int8 > mData;
1942 public:
1943 DialogInfo_Impl( const ::rtl::OUString& aName, Sequence< sal_Int8 > Data )
1944 : maName( aName ), mData( Data ) {}
1946 // Methods XStarBasicDialogInfo
1947 virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
1948 { return maName; }
1949 virtual Sequence< sal_Int8 > SAL_CALL getData() throw(RuntimeException)
1950 { return mData; }
1954 //=====================================================================
1956 class LibraryInfo_Impl : public LibraryInfoHelper
1958 ::rtl::OUString maName;
1959 Reference< XNameContainer > mxModuleContainer;
1960 Reference< XNameContainer > mxDialogContainer;
1961 ::rtl::OUString maPassword;
1962 ::rtl::OUString maExternaleSourceURL;
1963 ::rtl::OUString maLinkTargetURL;
1965 public:
1966 LibraryInfo_Impl
1968 const ::rtl::OUString& aName,
1969 Reference< XNameContainer > xModuleContainer,
1970 Reference< XNameContainer > xDialogContainer,
1971 const ::rtl::OUString& aPassword,
1972 const ::rtl::OUString& aExternaleSourceURL,
1973 const ::rtl::OUString& aLinkTargetURL
1975 : maName( aName )
1976 , mxModuleContainer( xModuleContainer )
1977 , mxDialogContainer( xDialogContainer )
1978 , maPassword( aPassword )
1979 , maExternaleSourceURL( aExternaleSourceURL )
1980 , maLinkTargetURL( aLinkTargetURL )
1983 // Methods XStarBasicLibraryInfo
1984 virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
1985 { return maName; }
1986 virtual Reference< XNameContainer > SAL_CALL getModuleContainer() throw(RuntimeException)
1987 { return mxModuleContainer; }
1988 virtual Reference< XNameContainer > SAL_CALL getDialogContainer() throw(RuntimeException)
1989 { return mxDialogContainer; }
1990 virtual ::rtl::OUString SAL_CALL getPassword() throw(RuntimeException)
1991 { return maPassword; }
1992 virtual ::rtl::OUString SAL_CALL getExternalSourceURL() throw(RuntimeException)
1993 { return maExternaleSourceURL; }
1994 virtual ::rtl::OUString SAL_CALL getLinkTargetURL() throw(RuntimeException)
1995 { return maLinkTargetURL; }
1998 //=====================================================================
2000 class ModuleContainer_Impl : public NameContainerHelper
2002 StarBASIC* mpLib;
2004 public:
2005 ModuleContainer_Impl( StarBASIC* pLib )
2006 :mpLib( pLib ) {}
2008 // Methods XElementAccess
2009 virtual Type SAL_CALL getElementType()
2010 throw(RuntimeException);
2011 virtual sal_Bool SAL_CALL hasElements()
2012 throw(RuntimeException);
2014 // Methods XNameAccess
2015 virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
2016 throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2017 virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
2018 throw(RuntimeException);
2019 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
2020 throw(RuntimeException);
2022 // Methods XNameReplace
2023 virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2024 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
2026 // Methods XNameContainer
2027 virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
2028 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
2029 virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
2030 throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2033 // Methods XElementAccess
2034 Type ModuleContainer_Impl::getElementType()
2035 throw(RuntimeException)
2037 Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
2038 return aModuleType;
2041 sal_Bool ModuleContainer_Impl::hasElements()
2042 throw(RuntimeException)
2044 SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
2045 return pMods && pMods->Count() > 0;
2048 // Methods XNameAccess
2049 Any ModuleContainer_Impl::getByName( const ::rtl::OUString& aName )
2050 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2052 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
2053 if( !pMod )
2054 throw NoSuchElementException();
2055 Reference< XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl
2056 ( aName, ::rtl::OUString::createFromAscii( szScriptLanguage ), pMod->GetSource32() );
2057 Any aRetAny;
2058 aRetAny <<= xMod;
2059 return aRetAny;
2062 Sequence< ::rtl::OUString > ModuleContainer_Impl::getElementNames()
2063 throw(RuntimeException)
2065 SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
2066 USHORT nMods = pMods ? pMods->Count() : 0;
2067 Sequence< ::rtl::OUString > aRetSeq( nMods );
2068 ::rtl::OUString* pRetSeq = aRetSeq.getArray();
2069 for( USHORT i = 0 ; i < nMods ; i++ )
2071 SbxVariable* pMod = pMods->Get( i );
2072 pRetSeq[i] = ::rtl::OUString( pMod->GetName() );
2074 return aRetSeq;
2077 sal_Bool ModuleContainer_Impl::hasByName( const ::rtl::OUString& aName )
2078 throw(RuntimeException)
2080 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
2081 sal_Bool bRet = (pMod != NULL);
2082 return bRet;
2086 // Methods XNameReplace
2087 void ModuleContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2088 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2090 removeByName( aName );
2091 insertByName( aName, aElement );
2095 // Methods XNameContainer
2096 void ModuleContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2097 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2099 Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
2100 Type aAnyType = aElement.getValueType();
2101 if( aModuleType != aAnyType )
2102 throw IllegalArgumentException();
2103 Reference< XStarBasicModuleInfo > xMod;
2104 aElement >>= xMod;
2105 mpLib->MakeModule32( aName, xMod->getSource() );
2108 void ModuleContainer_Impl::removeByName( const ::rtl::OUString& Name )
2109 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2111 SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL;
2112 if( !pMod )
2113 throw NoSuchElementException();
2114 mpLib->Remove( pMod );
2118 //=====================================================================
2120 Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
2122 SvMemoryStream aMemStream;
2123 pDialog->Store( aMemStream );
2124 sal_Int32 nLen = aMemStream.Tell();
2125 Sequence< sal_Int8 > aData( nLen );
2126 sal_Int8* pDestData = aData.getArray();
2127 const sal_Int8* pSrcData = (const sal_Int8*)aMemStream.GetData();
2128 rtl_copyMemory( pDestData, pSrcData, nLen );
2129 return aData;
2132 SbxObject* implCreateDialog( Sequence< sal_Int8 > aData )
2134 sal_Int8* pData = aData.getArray();
2135 SvMemoryStream aMemStream( pData, aData.getLength(), STREAM_READ );
2136 SbxObject* pDialog = (SbxObject*)SbxBase::Load( aMemStream );
2137 return pDialog;
2140 // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
2141 // which we can't include here, we have to use the value directly
2142 #define SBXID_DIALOG 101
2145 class DialogContainer_Impl : public NameContainerHelper
2147 StarBASIC* mpLib;
2149 public:
2150 DialogContainer_Impl( StarBASIC* pLib )
2151 :mpLib( pLib ) {}
2153 // Methods XElementAccess
2154 virtual Type SAL_CALL getElementType()
2155 throw(RuntimeException);
2156 virtual sal_Bool SAL_CALL hasElements()
2157 throw(RuntimeException);
2159 // Methods XNameAccess
2160 virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
2161 throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2162 virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
2163 throw(RuntimeException);
2164 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
2165 throw(RuntimeException);
2167 // Methods XNameReplace
2168 virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2169 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
2171 // Methods XNameContainer
2172 virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
2173 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
2174 virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
2175 throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2178 // Methods XElementAccess
2179 Type DialogContainer_Impl::getElementType()
2180 throw(RuntimeException)
2182 Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
2183 return aModuleType;
2186 sal_Bool DialogContainer_Impl::hasElements()
2187 throw(RuntimeException)
2189 sal_Bool bRet = sal_False;
2191 mpLib->GetAll( SbxCLASS_OBJECT );
2192 sal_Int16 nCount = mpLib->GetObjects()->Count();
2193 for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2195 SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2196 if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2198 bRet = sal_True;
2199 break;
2202 return bRet;
2205 // Methods XNameAccess
2206 Any DialogContainer_Impl::getByName( const ::rtl::OUString& aName )
2207 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2209 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2210 if( !( pVar && pVar->ISA( SbxObject ) &&
2211 ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2213 throw NoSuchElementException();
2216 Reference< XStarBasicDialogInfo > xDialog =
2217 (XStarBasicDialogInfo*)new DialogInfo_Impl
2218 ( aName, implGetDialogData( (SbxObject*)pVar ) );
2220 Any aRetAny;
2221 aRetAny <<= xDialog;
2222 return aRetAny;
2225 Sequence< ::rtl::OUString > DialogContainer_Impl::getElementNames()
2226 throw(RuntimeException)
2228 mpLib->GetAll( SbxCLASS_OBJECT );
2229 sal_Int16 nCount = mpLib->GetObjects()->Count();
2230 Sequence< ::rtl::OUString > aRetSeq( nCount );
2231 ::rtl::OUString* pRetSeq = aRetSeq.getArray();
2232 sal_Int32 nDialogCounter = 0;
2234 for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2236 SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2237 if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2239 pRetSeq[ nDialogCounter ] = ::rtl::OUString( pVar->GetName() );
2240 nDialogCounter++;
2243 aRetSeq.realloc( nDialogCounter );
2244 return aRetSeq;
2247 sal_Bool DialogContainer_Impl::hasByName( const ::rtl::OUString& aName )
2248 throw(RuntimeException)
2250 sal_Bool bRet = sal_False;
2251 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2252 if( pVar && pVar->ISA( SbxObject ) &&
2253 ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2255 bRet = sal_True;
2257 return bRet;
2261 // Methods XNameReplace
2262 void DialogContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2263 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2265 removeByName( aName );
2266 insertByName( aName, aElement );
2270 // Methods XNameContainer
2271 void DialogContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2272 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2274 (void)aName;
2275 Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
2276 Type aAnyType = aElement.getValueType();
2277 if( aModuleType != aAnyType )
2278 throw IllegalArgumentException();
2279 Reference< XStarBasicDialogInfo > xMod;
2280 aElement >>= xMod;
2281 SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
2282 mpLib->Insert( xDialog );
2285 void DialogContainer_Impl::removeByName( const ::rtl::OUString& Name )
2286 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2288 (void)Name;
2289 SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE );
2290 if( !( pVar && pVar->ISA( SbxObject ) &&
2291 ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2293 throw NoSuchElementException();
2295 mpLib->Remove( pVar );
2299 //=====================================================================
2302 class LibraryContainer_Impl : public NameContainerHelper
2304 BasicManager* mpMgr;
2306 public:
2307 LibraryContainer_Impl( BasicManager* pMgr )
2308 :mpMgr( pMgr ) {}
2310 // Methods XElementAccess
2311 virtual Type SAL_CALL getElementType()
2312 throw(RuntimeException);
2313 virtual sal_Bool SAL_CALL hasElements()
2314 throw(RuntimeException);
2316 // Methods XNameAccess
2317 virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
2318 throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2319 virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
2320 throw(RuntimeException);
2321 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
2322 throw(RuntimeException);
2324 // Methods XNameReplace
2325 virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2326 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
2328 // Methods XNameContainer
2329 virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
2330 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
2331 virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
2332 throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2336 // Methods XElementAccess
2337 Type LibraryContainer_Impl::getElementType()
2338 throw(RuntimeException)
2340 Type aType = ::getCppuType( (const Reference< XStarBasicLibraryInfo > *)0 );
2341 return aType;
2344 sal_Bool LibraryContainer_Impl::hasElements()
2345 throw(RuntimeException)
2347 sal_Int32 nLibs = mpMgr->GetLibCount();
2348 sal_Bool bRet = (nLibs > 0);
2349 return bRet;
2352 // Methods XNameAccess
2353 Any LibraryContainer_Impl::getByName( const ::rtl::OUString& aName )
2354 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2356 Any aRetAny;
2357 if( !mpMgr->HasLib( aName ) )
2358 throw NoSuchElementException();
2359 StarBASIC* pLib = mpMgr->GetLib( aName );
2361 Reference< XNameContainer > xModuleContainer =
2362 (XNameContainer*)new ModuleContainer_Impl( pLib );
2364 Reference< XNameContainer > xDialogContainer;
2365 (XNameContainer*)new DialogContainer_Impl( pLib );
2367 BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
2369 ::rtl::OUString aPassword = pLibInfo->GetPassword();
2371 // TODO Only provide extern info!
2372 ::rtl::OUString aExternaleSourceURL;
2373 ::rtl::OUString aLinkTargetURL;
2374 if( pLibInfo->IsReference() )
2375 aLinkTargetURL = pLibInfo->GetStorageName();
2376 else if( pLibInfo->IsExtern() )
2377 aExternaleSourceURL = pLibInfo->GetStorageName();
2379 Reference< XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
2381 aName,
2382 xModuleContainer,
2383 xDialogContainer,
2384 aPassword,
2385 aExternaleSourceURL,
2386 aLinkTargetURL
2389 aRetAny <<= xLibInfo;
2390 return aRetAny;
2393 Sequence< ::rtl::OUString > LibraryContainer_Impl::getElementNames()
2394 throw(RuntimeException)
2396 USHORT nLibs = mpMgr->GetLibCount();
2397 Sequence< ::rtl::OUString > aRetSeq( nLibs );
2398 ::rtl::OUString* pRetSeq = aRetSeq.getArray();
2399 for( USHORT i = 0 ; i < nLibs ; i++ )
2401 pRetSeq[i] = ::rtl::OUString( mpMgr->GetLibName( i ) );
2403 return aRetSeq;
2406 sal_Bool LibraryContainer_Impl::hasByName( const ::rtl::OUString& aName )
2407 throw(RuntimeException)
2409 sal_Bool bRet = mpMgr->HasLib( aName );
2410 return bRet;
2413 // Methods XNameReplace
2414 void LibraryContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2415 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2417 removeByName( aName );
2418 insertByName( aName, aElement );
2421 // Methods XNameContainer
2422 void LibraryContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2423 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2425 (void)aName;
2426 (void)aElement;
2427 // TODO: Insert a complete Library?!
2430 void LibraryContainer_Impl::removeByName( const ::rtl::OUString& Name )
2431 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2433 StarBASIC* pLib = mpMgr->GetLib( Name );
2434 if( !pLib )
2435 throw NoSuchElementException();
2436 USHORT nLibId = mpMgr->GetLibId( Name );
2437 mpMgr->RemoveLib( nLibId );
2440 //=====================================================================
2442 typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
2445 class StarBasicAccess_Impl : public StarBasicAccessHelper
2447 BasicManager* mpMgr;
2448 Reference< XNameContainer > mxLibContainer;
2450 public:
2451 StarBasicAccess_Impl( BasicManager* pMgr )
2452 :mpMgr( pMgr ) {}
2454 public:
2456 // Methods
2457 virtual Reference< XNameContainer > SAL_CALL getLibraryContainer()
2458 throw(RuntimeException);
2459 virtual void SAL_CALL createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password,
2460 const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL )
2461 throw(ElementExistException, RuntimeException);
2462 virtual void SAL_CALL addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName,
2463 const ::rtl::OUString& Language, const ::rtl::OUString& Source )
2464 throw(NoSuchElementException, RuntimeException);
2465 virtual void SAL_CALL addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName,
2466 const Sequence< sal_Int8 >& Data )
2467 throw(NoSuchElementException, RuntimeException);
2471 Reference< XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
2472 throw(RuntimeException)
2474 if( !mxLibContainer.is() )
2475 mxLibContainer = (XNameContainer*)new LibraryContainer_Impl( mpMgr );
2476 return mxLibContainer;
2479 void SAL_CALL StarBasicAccess_Impl::createLibrary
2481 const ::rtl::OUString& LibName,
2482 const ::rtl::OUString& Password,
2483 const ::rtl::OUString& ExternalSourceURL,
2484 const ::rtl::OUString& LinkTargetURL
2486 throw(ElementExistException, RuntimeException)
2488 (void)ExternalSourceURL;
2489 #ifdef DBG_UTIL
2490 StarBASIC* pLib =
2491 #endif
2492 mpMgr->CreateLib( LibName, Password, LinkTargetURL );
2493 DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
2496 void SAL_CALL StarBasicAccess_Impl::addModule
2498 const ::rtl::OUString& LibraryName,
2499 const ::rtl::OUString& ModuleName,
2500 const ::rtl::OUString& Language,
2501 const ::rtl::OUString& Source
2503 throw(NoSuchElementException, RuntimeException)
2505 (void)Language;
2506 StarBASIC* pLib = mpMgr->GetLib( LibraryName );
2507 DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
2508 if( pLib )
2509 pLib->MakeModule32( ModuleName, Source );
2512 void SAL_CALL StarBasicAccess_Impl::addDialog
2514 const ::rtl::OUString& LibraryName,
2515 const ::rtl::OUString& DialogName,
2516 const Sequence< sal_Int8 >& Data
2518 throw(NoSuchElementException, RuntimeException)
2520 (void)LibraryName;
2521 (void)DialogName;
2522 (void)Data;
2525 // Basic XML Import/Export
2526 Reference< XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
2528 Reference< XStarBasicAccess > xRet =
2529 new StarBasicAccess_Impl( (BasicManager*)pMgr );
2530 return xRet;