xref: /aoo41x/main/basic/source/basmgr/basmgr.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 #include <tools/stream.hxx>
31 #include <sot/storage.hxx>
32 #include <tools/urlobj.hxx>
33 #include <svl/smplhint.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/window.hxx>
36 #include <vcl/wrkwin.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <basic/sbx.hxx>
39 #include <sot/storinfo.hxx>
40 #include <unotools/pathoptions.hxx>
41 #include <tools/debug.hxx>
42 #include <tools/diagnose_ex.h>
43 #include <basic/sbmod.hxx>
44 #include <basic/sbobjmod.hxx>
45 #include <unotools/intlwrapper.hxx>
46 #include <comphelper/processfactory.hxx>
47 
48 #include <basic/sbuno.hxx>
49 #include <basic/basmgr.hxx>
50 #include <sbunoobj.hxx>
51 #include "basrid.hxx"
52 #include "sbintern.hxx"
53 #include <sb.hrc>
54 
55 
56 #define LIB_SEP			0x01
57 #define LIBINFO_SEP		0x02
58 #define LIBINFO_ID		0x1491
59 #define PASSWORD_MARKER	0x31452134
60 
61 
62 // Library API, implemented for XML import/export
63 
64 #include <com/sun/star/container/XNameContainer.hpp>
65 #include <com/sun/star/container/XContainer.hpp>
66 #include <com/sun/star/script/XStarBasicAccess.hpp>
67 #include <com/sun/star/script/XStarBasicModuleInfo.hpp>
68 #include <com/sun/star/script/XStarBasicDialogInfo.hpp>
69 #include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
70 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
71 #include <com/sun/star/script/ModuleInfo.hpp>
72 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
73 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
74 
75 #include <cppuhelper/implbase1.hxx>
76 
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;
83 
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;
89 
90 
91 
92 #define CURR_VER		2
93 
94 // Version 1
95 //	  sal_uIntPtr 	nEndPos
96 //	  sal_uInt16 	nId
97 //	  sal_uInt16	nVer
98 //	  sal_Bool		bDoLoad
99 //	  String	LibName
100 //	  String	AbsStorageName
101 //	  String	RelStorageName
102 // Version 2
103 //	+ sal_Bool		bReference
104 
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";
112 
113 TYPEINIT1( BasicManager, SfxBroadcaster );
114 DBG_NAME( BasicManager );
115 
116 StreamMode eStreamReadMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL;
117 StreamMode eStorageReadMode = STREAM_READ | STREAM_SHARE_DENYWRITE;
118 
119 DECLARE_LIST( BasErrorLst, BasicError* )
120 
121 //----------------------------------------------------------------------------
122 // BasicManager impl data
123 struct BasicManagerImpl
124 {
125     LibraryContainerInfo    maContainerInfo;
126 
127     // Save stream data
128     SvMemoryStream*  mpManagerStream;
129     SvMemoryStream** mppLibStreams;
130     sal_Int32        mnLibStreamCount;
131     sal_Bool         mbModifiedByLibraryContainer;
132     sal_Bool         mbError;
133 
134 	BasicManagerImpl( void )
135         : mpManagerStream( NULL )
136         , mppLibStreams( NULL )
137         , mnLibStreamCount( 0 )
138         , mbModifiedByLibraryContainer( sal_False )
139         , mbError( sal_False )
140 	{}
141     ~BasicManagerImpl();
142 };
143 
144 BasicManagerImpl::~BasicManagerImpl()
145 {
146     delete mpManagerStream;
147     if( mppLibStreams )
148     {
149         for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ )
150             delete mppLibStreams[i];
151         delete[] mppLibStreams;
152     }
153 }
154 
155 //============================================================================
156 // BasMgrContainerListenerImpl
157 //============================================================================
158 
159 typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper;
160 
161 class BasMgrContainerListenerImpl: public ContainerListenerHelper
162 {
163 	BasicManager* mpMgr;
164 	::rtl::OUString maLibName;		// empty -> no lib, but lib container
165 
166 public:
167 	BasMgrContainerListenerImpl( BasicManager* pMgr, ::rtl::OUString aLibName )
168         : mpMgr( pMgr )
169         , maLibName( aLibName ) {}
170 
171 	static void insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr,
172 		Any aLibAny, ::rtl::OUString aLibName );
173 	static void addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess,
174 		::rtl::OUString aLibName );
175 
176 
177 	// XEventListener
178 	virtual void SAL_CALL disposing( const  ::com::sun::star::lang::EventObject& Source )
179 		throw(::com::sun::star::uno::RuntimeException);
180 
181 	// XContainerListener
182 	virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event )
183 		throw(::com::sun::star::uno::RuntimeException);
184 	virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event )
185 		throw(::com::sun::star::uno::RuntimeException);
186 	virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event )
187 		throw(::com::sun::star::uno::RuntimeException);
188 };
189 
190 
191 //============================================================================
192 // BasMgrContainerListenerImpl
193 //============================================================================
194 
195 void BasMgrContainerListenerImpl::insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont,
196 	BasicManager* pMgr, Any aLibAny, ::rtl::OUString aLibName )
197 {
198 	Reference< XNameAccess > xLibNameAccess;
199 	aLibAny >>= xLibNameAccess;
200 
201 	if( !pMgr->GetLib( aLibName ) )
202 	{
203         BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr );
204 #ifdef DBG_UTIL
205 		StarBASIC* pLib =
206 #endif
207 		pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont );
208 		DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
209 	}
210 
211 	Reference< XContainer> xLibContainer( xLibNameAccess, UNO_QUERY );
212 	if( xLibContainer.is() )
213 	{
214 		// Register listener for library
215 		Reference< XContainerListener > xLibraryListener
216 			= static_cast< XContainerListener* >
217 				( new BasMgrContainerListenerImpl( pMgr, aLibName ) );
218 		xLibContainer->addContainerListener( xLibraryListener );
219 	}
220 
221 	if( xScriptCont->isLibraryLoaded( aLibName ) )
222 	{
223 		addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
224 	}
225 }
226 
227 
228 void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr,
229 	Reference< XNameAccess > xLibNameAccess, ::rtl::OUString aLibName )
230 {
231 	Sequence< ::rtl::OUString > aModuleNames = xLibNameAccess->getElementNames();
232 	sal_Int32 nModuleCount = aModuleNames.getLength();
233 
234 	StarBASIC* pLib = pMgr->GetLib( aLibName );
235 	DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
236 	if( pLib )
237 	{
238 		const ::rtl::OUString* pNames = aModuleNames.getConstArray();
239 		for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
240 		{
241 			::rtl::OUString aModuleName = pNames[ j ];
242 			Any aElement = xLibNameAccess->getByName( aModuleName );
243             ::rtl::OUString aMod;
244             aElement >>= aMod;
245             Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY );
246             if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) )
247 			{
248                 ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName );
249 				OSL_TRACE("#addLibraryModulesImpl - aMod");
250                 pLib->MakeModule32( aModuleName, mInfo, aMod );
251 			}
252 			else
253 		pLib->MakeModule32( aModuleName, aMod );
254 		}
255 	}
256 
257 	pLib->SetModified( sal_False );
258 }
259 
260 
261 
262 // XEventListener
263 //----------------------------------------------------------------------------
264 
265 void SAL_CALL BasMgrContainerListenerImpl::disposing( const  EventObject& Source )
266 	throw( RuntimeException )
267 {
268     (void)Source;
269 }
270 
271 // XContainerListener
272 //----------------------------------------------------------------------------
273 
274 void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent& Event )
275 	throw( RuntimeException )
276 {
277 	sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
278 	::rtl::OUString aName;
279 	Event.Accessor >>= aName;
280 
281     mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
282 
283 	if( bLibContainer )
284 	{
285         Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY );
286 		insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName );
287         StarBASIC* pLib = mpMgr->GetLib( aName );
288         if ( pLib )
289         {
290             Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, UNO_QUERY );
291             if ( xVBACompat.is() )
292                 pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() );
293         }
294 	}
295 	else
296 	{
297 
298 		StarBASIC* pLib = mpMgr->GetLib( maLibName );
299 		DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
300 		if( pLib )
301 		{
302     		SbModule* pMod = pLib->FindModule( aName );
303             if( !pMod )
304             {
305         	::rtl::OUString aMod;
306         	Event.Element >>= aMod;
307                 Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY );
308                 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) )
309                 {
310                     ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName );
311                     pLib->MakeModule32( aName, mInfo, aMod );
312                 }
313                 else
314 			        pLib->MakeModule32( aName, aMod );
315 			    pLib->SetModified( sal_False );
316             }
317 		}
318 	}
319 }
320 
321 //----------------------------------------------------------------------------
322 
323 void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent& Event )
324 	throw( RuntimeException )
325 {
326 	::rtl::OUString aName;
327 	Event.Accessor >>= aName;
328 
329     mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
330 
331 	// Replace not possible for library container
332 #ifdef DBG_UTIL
333 	sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
334 #endif
335     DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()");
336 
337 	StarBASIC* pLib = mpMgr->GetLib( maLibName );
338 	if( pLib )
339 	{
340 		SbModule* pMod = pLib->FindModule( aName );
341 		::rtl::OUString aMod;
342         Event.Element >>= aMod;
343 
344 		if( pMod )
345                 pMod->SetSource32( aMod );
346 		else
347 				pLib->MakeModule32( aName, aMod );
348 
349 		pLib->SetModified( sal_False );
350 	}
351 }
352 
353 //----------------------------------------------------------------------------
354 
355 void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const ContainerEvent& Event )
356 	throw( RuntimeException )
357 {
358 	::rtl::OUString aName;
359 	Event.Accessor >>= aName;
360 
361     mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
362 
363 	sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
364 	if( bLibContainer )
365 	{
366 		StarBASIC* pLib = mpMgr->GetLib( aName );
367 		if( pLib )
368 		{
369 			sal_uInt16 nLibId = mpMgr->GetLibId( aName );
370 			mpMgr->RemoveLib( nLibId, sal_False );
371 		}
372 	}
373 	else
374 	{
375 		StarBASIC* pLib = mpMgr->GetLib( maLibName );
376 		SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL;
377 		if( pMod )
378 		{
379 			pLib->Remove( pMod );
380 			pLib->SetModified( sal_False );
381 		}
382 	}
383 }
384 
385 
386 //=====================================================================
387 
388 class BasicErrorManager
389 {
390 private:
391 	BasErrorLst	aErrorList;
392 
393 public:
394 				~BasicErrorManager();
395 
396 	void		Reset();
397 	void		InsertError( const BasicError& rError );
398 
399 	sal_Bool		HasErrors()			{ return (sal_Bool)aErrorList.Count(); }
400 	BasicError*	GetFirstError()		{ return aErrorList.First(); }
401 	BasicError*	GetNextError()		{ return aErrorList.Next(); }
402 };
403 
404 
405 BasicErrorManager::~BasicErrorManager()
406 {
407 	Reset();
408 }
409 
410 void BasicErrorManager::Reset()
411 {
412 	BasicError* pError = (BasicError*)aErrorList.First();
413 	while ( pError )
414 	{
415 		delete pError;
416 		pError = (BasicError*)aErrorList.Next();
417 	}
418 	aErrorList.Clear();
419 }
420 
421 void BasicErrorManager::InsertError( const BasicError& rError )
422 {
423 	aErrorList.Insert( new BasicError( rError ), LIST_APPEND );
424 }
425 
426 
427 BasicError::BasicError()
428 {
429 	nErrorId	= 0;
430 	nReason 	= 0;
431 }
432 
433 BasicError::BasicError( sal_uIntPtr nId, sal_uInt16 nR, const String& rErrStr ) :
434 	aErrStr( rErrStr )
435 {
436 	nErrorId 	= nId;
437 	nReason 	= nR;
438 }
439 
440 BasicError::BasicError( const BasicError& rErr ) :
441 	aErrStr( rErr.aErrStr )
442 {
443 	nErrorId 	= rErr.nErrorId;
444 	nReason		= rErr.nReason;
445 }
446 
447 
448 class BasicLibInfo
449 {
450 private:
451 	StarBASICRef	xLib;
452 	String			aLibName;
453 	String			aStorageName;	// String is sufficient, unique at runtime
454 	String			aRelStorageName;
455 	String			aPassword;
456 
457 	sal_Bool			bDoLoad;
458 	sal_Bool			bReference;
459 	sal_Bool			bPasswordVerified;
460 	sal_Bool			bFoundInPath;	// Must not relativated again!
461 
462     // Lib represents library in new UNO library container
463     Reference< XLibraryContainer > mxScriptCont;
464 
465 public:
466 	BasicLibInfo();
467 	BasicLibInfo( const String& rStorageName );
468 
469 	sal_Bool			IsReference() const		{ return bReference; }
470 	sal_Bool&			IsReference()			{ return bReference; }
471 
472 	sal_Bool			IsExtern() const 		{ return ! aStorageName.EqualsAscii(szImbedded); }
473 
474 	void			SetStorageName( const String& rName )	{ aStorageName = rName; }
475 	const String&	GetStorageName() const					{ return aStorageName; }
476 
477 	void			SetRelStorageName( const String& rN )	{ aRelStorageName = rN; }
478 	const String&	GetRelStorageName()	const				{ return aRelStorageName; }
479 	void			CalcRelStorageName( const String& rMgrStorageName );
480 
481 	StarBASICRef	GetLib() const
482     {
483         if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
484             !mxScriptCont->isLibraryLoaded( aLibName ) )
485                 return StarBASICRef();
486         return xLib;
487     }
488 	StarBASICRef&	GetLibRef()							{ return xLib; }
489 	void			SetLib( StarBASIC* pBasic )			{ xLib = pBasic; }
490 
491 	const String&	GetLibName() const					{ return aLibName; }
492 	void			SetLibName( const String& rName )	{ aLibName = rName; }
493 
494 	// Only temporary for Load/Save
495 	sal_Bool			DoLoad()							{ return bDoLoad; }
496 
497 	sal_Bool			HasPassword() const 				{ return aPassword.Len() != 0; }
498 	const String&	GetPassword() const					{ return aPassword; }
499 	void			SetPassword( const String& rNewPassword )
500 														{ aPassword = rNewPassword;	}
501 	sal_Bool			IsPasswordVerified() const			{ return bPasswordVerified; }
502 	void			SetPasswordVerified()				{ bPasswordVerified = sal_True; }
503 
504 	sal_Bool			IsFoundInPath() const				{ return bFoundInPath; }
505 	void			SetFoundInPath( sal_Bool bInPath )		{ bFoundInPath = bInPath; }
506 
507 	void 					Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, sal_Bool bUseOldReloadInfo );
508 	static BasicLibInfo*	Create( SotStorageStream& rSStream );
509 
510     Reference< XLibraryContainer > GetLibraryContainer( void )
511         { return mxScriptCont; }
512     void SetLibraryContainer( const Reference< XLibraryContainer >& xScriptCont )
513         { mxScriptCont = xScriptCont; }
514 };
515 
516 DECLARE_LIST( BasicLibsBase, BasicLibInfo* )
517 
518 class BasicLibs : public BasicLibsBase
519 {
520 public:
521 	String	aBasicLibPath; // TODO: Should be member of manager, but currently not incompatible
522 };
523 
524 BasicLibInfo::BasicLibInfo()
525 {
526 	bReference 			= sal_False;
527 	bPasswordVerified 	= sal_False;
528 	bDoLoad 			= sal_False;
529 	bFoundInPath		= sal_False;
530     mxScriptCont    	= NULL;
531 	aStorageName 		= String::CreateFromAscii(szImbedded);
532 	aRelStorageName 	= String::CreateFromAscii(szImbedded);
533 }
534 
535 BasicLibInfo::BasicLibInfo( const String& rStorageName )
536 {
537 	bReference 			= sal_True;
538 	bPasswordVerified 	= sal_False;
539 	bDoLoad 			= sal_False;
540     mxScriptCont    	= NULL;
541 	aStorageName 		= rStorageName;
542 }
543 
544 void BasicLibInfo::Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, sal_Bool bUseOldReloadInfo )
545 {
546 	sal_uIntPtr nStartPos = rSStream.Tell();
547 	sal_uInt32 nEndPos = 0;
548 
549 	sal_uInt16 nId = LIBINFO_ID;
550 	sal_uInt16 nVer = CURR_VER;
551 
552 	rSStream << nEndPos;
553 	rSStream << nId;
554 	rSStream << nVer;
555 
556     String aCurStorageName = INetURLObject(rBasMgrStorageName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
557     DBG_ASSERT(aCurStorageName.Len() != 0, "Bad storage name");
558 
559     // If not set initialize StorageName
560     if ( aStorageName.Len() == 0 )
561         aStorageName = aCurStorageName;
562 
563     // Load again?
564     sal_Bool bDoLoad_ = xLib.Is();
565     if ( bUseOldReloadInfo )
566         bDoLoad_ = DoLoad();
567     rSStream << bDoLoad_;
568 
569     // The name of the lib...
570     rSStream.WriteByteString(GetLibName());
571 
572     // Absolute path...
573     if ( ! GetStorageName().EqualsAscii(szImbedded) )
574     {
575         String aSName = INetURLObject( GetStorageName(), INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
576         DBG_ASSERT(aSName.Len() != 0, "Bad storage name");
577         rSStream.WriteByteString( aSName );
578     }
579     else
580         rSStream.WriteByteString( szImbedded );
581 
582     // Relative path...
583     if ( ( aStorageName == aCurStorageName ) || ( aStorageName.EqualsAscii(szImbedded) ) )
584         rSStream.WriteByteString( szImbedded );
585     else
586     {
587         // Do not determine the relative path if the file was only found in path:
588         // because the relative path would change and after moving the lib the
589         // the file cannot be found.
590         if ( !IsFoundInPath() )
591             CalcRelStorageName( aCurStorageName );
592         rSStream.WriteByteString(aRelStorageName);
593     }
594 
595 	// ------------------------------
596 	// Version 2
597 	// ------------------------------
598 
599     // reference...
600     rSStream << bReference;
601 
602 	// ------------------------------
603 	// End
604 	// ------------------------------
605 
606 	nEndPos = rSStream.Tell();
607 	rSStream.Seek( nStartPos );
608 	rSStream << nEndPos;
609 	rSStream.Seek( nEndPos );
610 }
611 
612 BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
613 {
614 	BasicLibInfo* pInfo = new BasicLibInfo;
615 
616 	sal_uInt32 nEndPos;
617 	sal_uInt16 nId;
618 	sal_uInt16 nVer;
619 
620 	rSStream >> nEndPos;
621 	rSStream >> nId;
622 	rSStream >> nVer;
623 
624 	DBG_ASSERT( nId == LIBINFO_ID, "Keine BasicLibInfo !?" );
625     if( nId == LIBINFO_ID )
626     {
627         // Reload?
628         sal_Bool bDoLoad;
629         rSStream >> bDoLoad;
630         pInfo->bDoLoad = bDoLoad;
631 
632         // The name of the lib...
633         String aName;
634         rSStream.ReadByteString(aName);
635         pInfo->SetLibName( aName );
636 
637         // Absolute path...
638         String aStorageName;
639         rSStream.ReadByteString(aStorageName);
640         pInfo->SetStorageName( aStorageName );
641 
642         // Relative path...
643         String aRelStorageName;
644         rSStream.ReadByteString(aRelStorageName);
645         pInfo->SetRelStorageName( aRelStorageName );
646 
647         if ( nVer >= 2 )
648         {
649             sal_Bool bReferenz;
650             rSStream >> bReferenz;
651             pInfo->IsReference() = bReferenz;
652         }
653 
654         rSStream.Seek( nEndPos );
655     }
656     return pInfo;
657 }
658 
659 void BasicLibInfo::CalcRelStorageName( const String& rMgrStorageName )
660 {
661 	if ( rMgrStorageName.Len() )
662 	{
663         INetURLObject aAbsURLObj( rMgrStorageName );
664 		aAbsURLObj.removeSegment();
665 		String aPath = aAbsURLObj.GetMainURL( INetURLObject::NO_DECODE );
666 		UniString aRelURL = INetURLObject::GetRelURL( aPath, GetStorageName() );
667         SetRelStorageName( aRelURL );
668 	}
669 	else
670 		SetRelStorageName( String() );
671 }
672 BasicManager::BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib, String* pLibPath, sal_Bool bDocMgr ) : mbDocMgr( bDocMgr )
673 {
674 	DBG_CTOR( BasicManager, 0 );
675 
676 	Init();
677 
678 	if( pLibPath )
679 		pLibs->aBasicLibPath = *pLibPath;
680 
681     String aStorName( rStorage.GetName() );
682     maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
683 
684     // #91251: Storage name not longer available for documents < 5.0
685     // Should be no real problem, because only relative storage names
686     // (links) can be affected.
687     // DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
688     // DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
689 
690     // If there is no Manager Stream, no further actions are necessary
691     if ( rStorage.IsStream( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)) ) )
692     {
693         LoadBasicManager( rStorage, rBaseURL );
694         // StdLib contains Parent:
695         StarBASIC* pStdLib = GetStdLib();
696         DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" );
697         if ( !pStdLib )
698         {
699             // Should never happen, but if it happens we wont crash...
700             pStdLib = new StarBASIC( NULL, mbDocMgr );
701 			BasicLibInfo* pStdLibInfo = pLibs->GetObject( 0 );
702 			if ( !pStdLibInfo )
703 				pStdLibInfo = CreateLibInfo();
704 			pStdLibInfo->SetLib( pStdLib );
705             StarBASICRef xStdLib = pStdLibInfo->GetLib();
706 			xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
707 			pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
708 			xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
709 			xStdLib->SetModified( sal_False );
710         }
711         else
712         {
713 			pStdLib->SetParent( pParentFromStdLib );
714             // The other get StdLib as parent:
715             for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ )
716 			{
717 				StarBASIC* pBasic = GetLib( nBasic );
718 				if ( pBasic )
719 				{
720 //					pBasic->SetParent( pStdLib );
721 					pStdLib->Insert( pBasic );
722 					pBasic->SetFlag( SBX_EXTSEARCH );
723 				}
724 			}
725             // Modified through insert
726             pStdLib->SetModified( sal_False );
727         }
728 
729         // #91626 Save all stream data to save it unmodified if basic isn't modified
730         // in an 6.0+ office. So also the old basic dialogs can be saved.
731 	    SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
732 		    ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode );
733         mpImpl->mpManagerStream = new SvMemoryStream();
734         *static_cast<SvStream*>(&xManagerStream) >> *mpImpl->mpManagerStream;
735 
736 	    SotStorageRef xBasicStorage = rStorage.OpenSotStorage
737 							    ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, sal_False );
738 	    if( xBasicStorage.Is() && !xBasicStorage->GetError() )
739 	    {
740 	        sal_uInt16 nLibs = GetLibCount();
741             mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ];
742             for( sal_uInt16 nL = 0; nL < nLibs; nL++ )
743 	        {
744 		        BasicLibInfo* pInfo = pLibs->GetObject( nL );
745 		        DBG_ASSERT( pInfo, "pInfo?!" );
746     		    SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), eStreamReadMode );
747                 mpImpl->mppLibStreams[nL] = new SvMemoryStream();
748                 *static_cast<SvStream*>(&xBasicStream) >> *( mpImpl->mppLibStreams[nL] );
749             }
750         }
751         else
752             mpImpl->mbError = sal_True;
753 	}
754 	else
755 	{
756 		ImpCreateStdLib( pParentFromStdLib );
757 		if ( rStorage.IsStream( String::CreateFromAscii(szOldManagerStream) ) )
758             LoadOldBasicManager( rStorage );
759 	}
760 
761 	bBasMgrModified = sal_False;
762 }
763 
764 void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
765 {
766     Reference< XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
767     if ( !xScriptCont.is() )
768         return;
769 
770     String aLibName = pBasic->GetName();
771 	if( !xScriptCont->hasByName( aLibName ) )
772 		xScriptCont->createLibrary( aLibName );
773 
774 	Any aLibAny = xScriptCont->getByName( aLibName );
775 	Reference< XNameContainer > xLib;
776 	aLibAny >>= xLib;
777     if ( !xLib.is() )
778         return;
779 
780     sal_uInt16 nModCount = pBasic->GetModules()->Count();
781 	for ( sal_uInt16 nMod = 0 ; nMod < nModCount ; nMod++ )
782 	{
783 		SbModule* pModule = (SbModule*)pBasic->GetModules()->Get( nMod );
784 		DBG_ASSERT( pModule, "Modul nicht erhalten!" );
785 
786 		String aModName = pModule->GetName();
787 		if( !xLib->hasByName( aModName ) )
788 		{
789 			::rtl::OUString aSource = pModule->GetSource32();
790 			Any aSourceAny;
791 			aSourceAny <<= aSource;
792 			xLib->insertByName( aModName, aSourceAny );
793 		}
794 	}
795 }
796 
797 const Reference< XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer()  const
798 {
799     return mpImpl->maContainerInfo.mxDialogCont;
800 }
801 
802 const Reference< XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer()  const
803 {
804     return mpImpl->maContainerInfo.mxScriptCont;
805 }
806 
807 void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
808 {
809 	mpImpl->maContainerInfo = rInfo;
810 
811 	Reference< XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
812 	StarBASIC* pStdLib = GetStdLib();
813 	String aLibName = pStdLib->GetName();
814 	if( xScriptCont.is() )
815 	{
816 		// Register listener for lib container
817 		::rtl::OUString aEmptyLibName;
818 		Reference< XContainerListener > xLibContainerListener
819 			= static_cast< XContainerListener* >
820 				( new BasMgrContainerListenerImpl( this, aEmptyLibName ) );
821 
822     	Reference< XContainer> xLibContainer( xScriptCont, UNO_QUERY );
823 		xLibContainer->addContainerListener( xLibContainerListener );
824 
825 		Sequence< ::rtl::OUString > aScriptLibNames = xScriptCont->getElementNames();
826 		const ::rtl::OUString* pScriptLibName = aScriptLibNames.getConstArray();
827 		sal_Int32 i, nNameCount = aScriptLibNames.getLength();
828 
829         if( nNameCount )
830         {
831 		    for( i = 0 ; i < nNameCount ; ++i, ++pScriptLibName )
832 		    {
833 			    Any aLibAny = xScriptCont->getByName( *pScriptLibName );
834 
835                 if ( pScriptLibName->equalsAscii( "Standard" ) )
836 				    xScriptCont->loadLibrary( *pScriptLibName );
837 
838 			    BasMgrContainerListenerImpl::insertLibraryImpl
839 				    ( xScriptCont, this, aLibAny, *pScriptLibName );
840 		    }
841         }
842         else
843         {
844             // No libs? Maybe an 5.2 document already loaded
845 	        sal_uInt16 nLibs = GetLibCount();
846 		    for( sal_uInt16 nL = 0; nL < nLibs; nL++ )
847 		    {
848 			    BasicLibInfo* pBasLibInfo = pLibs->GetObject( nL );
849 			    StarBASIC* pLib = pBasLibInfo->GetLib();
850 			    if( !pLib )
851                 {
852                     sal_Bool bLoaded = ImpLoadLibary( pBasLibInfo, NULL, sal_False );
853                     if( bLoaded )
854                         pLib = pBasLibInfo->GetLib();
855                 }
856 			    if( pLib )
857                 {
858                     copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
859                     if( pBasLibInfo->HasPassword() )
860                     {
861                         OldBasicPassword* pOldBasicPassword =
862                             mpImpl->maContainerInfo.mpOldBasicPassword;
863                         if( pOldBasicPassword )
864                         {
865                             pOldBasicPassword->setLibraryPassword
866                                 ( pLib->GetName(), pBasLibInfo->GetPassword() );
867                             pBasLibInfo->SetPasswordVerified();
868                         }
869                     }
870                 }
871 		    }
872 
873             mpImpl->mbModifiedByLibraryContainer = sal_False;
874         }
875 	}
876 
877     SetGlobalUNOConstant( "BasicLibraries", makeAny( mpImpl->maContainerInfo.mxScriptCont ) );
878     SetGlobalUNOConstant( "DialogLibraries", makeAny( mpImpl->maContainerInfo.mxDialogCont ) );
879 }
880 
881 BasicManager::BasicManager( StarBASIC* pSLib, String* pLibPath, sal_Bool bDocMgr ) : mbDocMgr( bDocMgr )
882 {
883 	DBG_CTOR( BasicManager, 0 );
884 	Init();
885     DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" );
886 
887 	if( pLibPath )
888 		pLibs->aBasicLibPath = *pLibPath;
889 
890 	BasicLibInfo* pStdLibInfo = CreateLibInfo();
891 	pStdLibInfo->SetLib( pSLib );
892     StarBASICRef xStdLib = pStdLibInfo->GetLib();
893 	xStdLib->SetName( String::CreateFromAscii(szStdLibName));
894 	pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
895 	pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
896 
897     // Save is only necessary if basic has changed
898 	xStdLib->SetModified( sal_False );
899 	bBasMgrModified = sal_False;
900 }
901 
902 BasicManager::BasicManager()
903 {
904     DBG_CTOR( BasicManager, 0 );
905     // This ctor may only be used to adapt relative paths for 'Save As'.
906     // There is no AppBasic so libs must not be loaded...
907     Init();
908 }
909 
910 void BasicManager::ImpMgrNotLoaded( const String& rStorageName )
911 {
912     // pErrInf is only destroyed if the error os processed by an
913     // ErrorHandler
914     StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK );
915     pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, rStorageName ) );
916 
917     // Create a stdlib otherwise we crash!
918     BasicLibInfo* pStdLibInfo = CreateLibInfo();
919     pStdLibInfo->SetLib( new StarBASIC( NULL, mbDocMgr ) );
920     StarBASICRef xStdLib = pStdLibInfo->GetLib();
921     xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
922     pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
923     xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
924     xStdLib->SetModified( sal_False );
925 }
926 
927 
928 void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
929 {
930 	BasicLibInfo* pStdLibInfo = CreateLibInfo();
931 	StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
932 	pStdLibInfo->SetLib( pStdLib );
933 	pStdLib->SetName( String::CreateFromAscii(szStdLibName) );
934 	pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
935 	pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
936 }
937 
938 
939 void BasicManager::LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, sal_Bool bLoadLibs )
940 {
941 	DBG_CHKTHIS( BasicManager, 0 );
942 
943 //	StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
944 
945 	SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
946 		( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode );
947 
948     String aStorName( rStorage.GetName() );
949     // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
950 
951 	if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
952 	{
953         ImpMgrNotLoaded( aStorName );
954 		return;
955 	}
956 
957     maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
958     // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
959 
960     String aRealStorageName = maStorageName;  // for relative paths, can be modified through BaseURL
961 
962     // If loaded from template, only BaseURL is used:
963     //String aBaseURL = INetURLObject::GetBaseURL();
964     if ( rBaseURL.Len() )
965 	{
966         INetURLObject aObj( rBaseURL );
967 		if ( aObj.GetProtocol() == INET_PROT_FILE )
968 			aRealStorageName = aObj.PathToFileName();
969 	}
970 
971 	xManagerStream->SetBufferSize( 1024 );
972 	xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
973 
974 	sal_uInt32 nEndPos;
975 	*xManagerStream >> nEndPos;
976 
977 	sal_uInt16 nLibs;
978 	*xManagerStream >> nLibs;
979 	// Plausi!
980 	if( nLibs & 0xF000 )
981 	{
982 		DBG_ASSERT( !this, "BasicManager-Stream defect!" );
983 		return;
984 	}
985 	for ( sal_uInt16 nL = 0; nL < nLibs; nL++ )
986 	{
987 		BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
988 
989         // Correct absolute pathname if relative is existing.
990         // Always try relative first if there are two stands on disk
991         if ( pInfo->GetRelStorageName().Len() && ( ! pInfo->GetRelStorageName().EqualsAscii(szImbedded) ) )
992 		{
993             INetURLObject aObj( aRealStorageName, INET_PROT_FILE );
994             aObj.removeSegment();
995             bool bWasAbsolute = sal_False;
996             aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
997 
998             //*** TODO: Replace if still necessary
999             /* if ( SfxContentHelper::Exists( aObj.GetMainURL() ) )
1000                 pInfo->SetStorageName( aObj.GetMainURL() );
1001 			else */
1002             //*** TODO-End
1003             if ( pLibs->aBasicLibPath.Len() )
1004 			{
1005                 // Search lib in path
1006 				String aSearchFile = pInfo->GetRelStorageName();
1007 				SvtPathOptions aPathCFG;
1008 				if( aPathCFG.SearchFile( aSearchFile, SvtPathOptions::PATH_BASIC ) )
1009 				{
1010                     pInfo->SetStorageName( aSearchFile );
1011 					pInfo->SetFoundInPath( sal_True );
1012 				}
1013 			}
1014 		}
1015 
1016 		pLibs->Insert( pInfo, LIST_APPEND );
1017 		// Libs from external files should be loaded only when necessary.
1018 		// But references are loaded at once, otherwise some big customers get into trouble
1019 		if ( bLoadLibs && pInfo->DoLoad() &&
1020 			( ( !pInfo->IsExtern() ) || ( pInfo->IsReference() ) ) )
1021 		{
1022             ImpLoadLibary( pInfo, &rStorage );
1023 		}
1024 	}
1025 
1026 	xManagerStream->Seek( nEndPos );
1027 	xManagerStream->SetBufferSize( 0 );
1028 	xManagerStream.Clear();
1029 }
1030 
1031 void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
1032 {
1033 	DBG_CHKTHIS( BasicManager, 0 );
1034 
1035 //	StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
1036 
1037 	SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
1038 		( String::CreateFromAscii(szOldManagerStream), eStreamReadMode );
1039 
1040     String aStorName( rStorage.GetName() );
1041     DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1042 
1043 	if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
1044 	{
1045         ImpMgrNotLoaded( aStorName );
1046 		return;
1047 	}
1048 
1049 	xManagerStream->SetBufferSize( 1024 );
1050 	xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
1051 	sal_uInt32 nBasicStartOff, nBasicEndOff;
1052 	*xManagerStream >> nBasicStartOff;
1053 	*xManagerStream >> nBasicEndOff;
1054 
1055 	DBG_ASSERT( !xManagerStream->GetError(), "Ungueltiger Manager-Stream!" );
1056 
1057 	xManagerStream->Seek( nBasicStartOff );
1058 	if( !ImplLoadBasic( *xManagerStream, pLibs->GetObject(0)->GetLibRef() ) )
1059 	{
1060 //		String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) );
1061 //      aErrorText.SearchAndReplace( "XX", aStorName );
1062         StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK );
1063         pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) );
1064 		// und es geht weiter...
1065 	}
1066 	xManagerStream->Seek( nBasicEndOff+1 );	// +1: 0x00 as separator
1067 	String aLibs;
1068 	xManagerStream->ReadByteString(aLibs);
1069 	xManagerStream->SetBufferSize( 0 );
1070 	xManagerStream.Clear();	// Close stream
1071 
1072 	if ( aLibs.Len() )
1073 	{
1074         String aCurStorageName( aStorName );
1075         INetURLObject aCurStorage( aCurStorageName, INET_PROT_FILE );
1076 		sal_uInt16 nLibs = aLibs.GetTokenCount( LIB_SEP );
1077 		for ( sal_uInt16 nLib = 0; nLib < nLibs; nLib++ )
1078 		{
1079 			String aLibInfo( aLibs.GetToken( nLib, LIB_SEP ) );
1080 			// TODO: Remove == 2
1081 			DBG_ASSERT( ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 2 ) || ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 3 ), "Ungueltige Lib-Info!" );
1082 			String aLibName( aLibInfo.GetToken( 0, LIBINFO_SEP ) );
1083 			String aLibAbsStorageName( aLibInfo.GetToken( 1, LIBINFO_SEP ) );
1084 			String aLibRelStorageName( aLibInfo.GetToken( 2, LIBINFO_SEP ) );
1085             INetURLObject aLibAbsStorage( aLibAbsStorageName, INET_PROT_FILE );
1086 
1087             INetURLObject aLibRelStorage( aStorName );
1088             aLibRelStorage.removeSegment();
1089             bool bWasAbsolute = sal_False;
1090             aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
1091             DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
1092 
1093 			SotStorageRef xStorageRef;
1094 			if ( ( aLibAbsStorage == aCurStorage ) || ( aLibRelStorageName.EqualsAscii(szImbedded) ) )
1095 				xStorageRef = &rStorage;
1096 			else
1097 			{
1098                 xStorageRef = new SotStorage( sal_False, aLibAbsStorage.GetMainURL
1099                     ( INetURLObject::NO_DECODE ), eStorageReadMode, sal_True );
1100                 if ( xStorageRef->GetError() != ERRCODE_NONE )
1101                     xStorageRef = new SotStorage( sal_False, aLibRelStorage.
1102                     GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode, sal_True );
1103 			}
1104 			if ( xStorageRef.Is() )
1105                 AddLib( *xStorageRef, aLibName, sal_False );
1106 			else
1107 			{
1108 //				String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
1109 //				aErrorText.SearchAndReplace( "XX", aLibName );
1110                 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK );
1111                 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STORAGENOTFOUND, aStorName ) );
1112 			}
1113 		}
1114 	}
1115 }
1116 
1117 BasicManager::~BasicManager()
1118 {
1119 	DBG_DTOR( BasicManager, 0 );
1120 
1121     // Notify listener if something needs to be saved
1122 	Broadcast( SfxSimpleHint( SFX_HINT_DYING) );
1123 
1124     // Destroy Basic-Infos...
1125     // In reverse order
1126 	BasicLibInfo* pInf = pLibs->Last();
1127 	while ( pInf )
1128 	{
1129 		delete pInf;
1130 		pInf = pLibs->Prev();
1131 	}
1132 	pLibs->Clear();
1133 	delete pLibs;
1134 	delete pErrorMgr;
1135 	delete mpImpl;
1136 }
1137 
1138 void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
1139 {
1140     delete _rpManager;
1141     _rpManager = NULL;
1142 }
1143 
1144 void BasicManager::Init()
1145 {
1146 	DBG_CHKTHIS( BasicManager, 0 );
1147 
1148 	bBasMgrModified = sal_False;
1149 	pErrorMgr = new BasicErrorManager;
1150 	pLibs = new BasicLibs;
1151 	mpImpl = new BasicManagerImpl();
1152 }
1153 
1154 BasicLibInfo* BasicManager::CreateLibInfo()
1155 {
1156 	DBG_CHKTHIS( BasicManager, 0 );
1157 
1158 	BasicLibInfo* pInf = new BasicLibInfo;
1159 	pLibs->Insert( pInf, LIST_APPEND );
1160 	return pInf;
1161 }
1162 
1163 sal_Bool BasicManager::ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, sal_Bool bInfosOnly ) const
1164 {
1165 	DBG_CHKTHIS( BasicManager, 0 );
1166 
1167 	DBG_ASSERT( pLibInfo, "LibInfo!?" );
1168 
1169 	String aStorageName( pLibInfo->GetStorageName() );
1170 	if ( !aStorageName.Len() || ( aStorageName.EqualsAscii(szImbedded) ) )
1171 		aStorageName = GetStorageName();
1172 
1173 	SotStorageRef xStorage;
1174 	// The current must not be opened again...
1175 	if ( pCurStorage )
1176 	{
1177         String aStorName( pCurStorage->GetName() );
1178         // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1179 
1180         INetURLObject aCurStorageEntry(aStorName, INET_PROT_FILE);
1181         // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
1182 
1183         INetURLObject aStorageEntry(aStorageName, INET_PROT_FILE);
1184         // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
1185 
1186 		if ( aCurStorageEntry == aStorageEntry )
1187 			xStorage = pCurStorage;
1188 	}
1189 
1190 	if ( !xStorage.Is() )
1191 		xStorage = new SotStorage( sal_False, aStorageName, eStorageReadMode );
1192 
1193 	SotStorageRef xBasicStorage = xStorage->OpenSotStorage
1194 							( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, sal_False );
1195 
1196 	if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1197 	{
1198 		StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN,	xStorage->GetName(), ERRCODE_BUTTON_OK );
1199 		pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
1200 	}
1201 	else
1202 	{
1203 		// In the Basic-Storage every lib is in a Stream...
1204 		SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
1205 		if ( !xBasicStream.Is() || xBasicStream->GetError() )
1206 		{
1207 			StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1208 			pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLibInfo->GetLibName() ) );
1209 		}
1210 		else
1211 		{
1212 			sal_Bool bLoaded = sal_False;
1213 			if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 )
1214 			{
1215 				if ( !bInfosOnly )
1216 				{
1217 					if ( !pLibInfo->GetLib().Is() )
1218 						pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
1219 					xBasicStream->SetBufferSize( 1024 );
1220 					xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1221 					bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
1222 					xBasicStream->SetBufferSize( 0 );
1223                     StarBASICRef xStdLib = pLibInfo->GetLib();
1224 					xStdLib->SetName( pLibInfo->GetLibName() );
1225 					xStdLib->SetModified( sal_False );
1226 					xStdLib->SetFlag( SBX_DONTSTORE );
1227 				}
1228 				else
1229 				{
1230 					// Skip Basic...
1231 					xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1232 					ImplEncryptStream( *xBasicStream );
1233 					SbxBase::Skip( *xBasicStream );
1234 					bLoaded = sal_True;
1235 				}
1236 			}
1237 			if ( !bLoaded )
1238 			{
1239 				StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD,	pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1240 				pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_BASICLOADERROR, pLibInfo->GetLibName() ) );
1241 			}
1242 			else
1243 			{
1244 				// Perhaps there are additional information in the stream...
1245 				xBasicStream->SetKey( szCryptingKey );
1246 				xBasicStream->RefreshBuffer();
1247 				sal_uInt32 nPasswordMarker = 0;
1248 				*xBasicStream >> nPasswordMarker;
1249 				if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() )
1250 				{
1251 					String aPassword;
1252 					xBasicStream->ReadByteString(aPassword);
1253 					pLibInfo->SetPassword( aPassword );
1254 				}
1255 				xBasicStream->SetKey( ByteString() );
1256 				CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() );
1257 			}
1258 			return bLoaded;
1259 		}
1260 	}
1261 	return sal_False;
1262 }
1263 
1264 sal_Bool BasicManager::ImplEncryptStream( SvStream& rStrm ) const
1265 {
1266 	sal_uIntPtr nPos = rStrm.Tell();
1267 	sal_uInt32 nCreator;
1268 	rStrm >> nCreator;
1269 	rStrm.Seek( nPos );
1270 	sal_Bool bProtected = sal_False;
1271 	if ( nCreator != SBXCR_SBX )
1272 	{
1273 		// Should only be the case for encrypted Streams
1274 		bProtected = sal_True;
1275 		rStrm.SetKey( szCryptingKey );
1276 		rStrm.RefreshBuffer();
1277 	}
1278 	return bProtected;
1279 }
1280 
1281 // This code is necessary to load the BASIC of Beta 1
1282 // TODO: Which Beta 1?
1283 sal_Bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
1284 {
1285 	sal_Bool bProtected = ImplEncryptStream( rStrm );
1286 	SbxBaseRef xNew = SbxBase::Load( rStrm );
1287 	sal_Bool bLoaded = sal_False;
1288 	if( xNew.Is() )
1289 	{
1290 		if( xNew->IsA( TYPE(StarBASIC) ) )
1291 		{
1292 			StarBASIC* pNew = (StarBASIC*)(SbxBase*) xNew;
1293 			// Use the Parent of the old BASICs
1294 			if( rOldBasic.Is() )
1295 			{
1296 				pNew->SetParent( rOldBasic->GetParent() );
1297 				if( pNew->GetParent() )
1298 					pNew->GetParent()->Insert( pNew );
1299 				pNew->SetFlag( SBX_EXTSEARCH );
1300 			}
1301 			rOldBasic = pNew;
1302 
1303 			// Fill new libray container (5.2 -> 6.0)
1304             copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
1305 
1306 /*
1307 			if( rOldBasic->GetParent() )
1308 			{
1309 				rOldBasic->GetParent()->Insert( rOldBasic );
1310 				rOldBasic->SetFlag( SBX_EXTSEARCH );
1311 			}
1312 */
1313 			pNew->SetModified( sal_False );
1314 			bLoaded = sal_True;
1315 		}
1316 	}
1317 	if ( bProtected )
1318 		rStrm.SetKey( ByteString() );
1319 	return bLoaded;
1320 }
1321 
1322 void BasicManager::CheckModules( StarBASIC* pLib, sal_Bool bReference ) const
1323 {
1324 	if ( !pLib )
1325 		return;
1326 
1327 	sal_Bool bModified = pLib->IsModified();
1328 
1329 	for ( sal_uInt16 nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ )
1330 	{
1331 		SbModule* pModule = (SbModule*)pLib->GetModules()->Get( nMod );
1332 		DBG_ASSERT( pModule, "Modul nicht erhalten!" );
1333 		if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
1334 			pLib->Compile( pModule );
1335 	}
1336 
1337 	// #67477, AB 8.12.99 On demand compile in referenced libs should not
1338 	// cause modified
1339 	if( !bModified && bReference )
1340 	{
1341 		DBG_ERROR( "Per Reference eingebundene Basic-Library ist nicht compiliert!" );
1342 		pLib->SetModified( sal_False );
1343 	}
1344 }
1345 
1346 StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const String& rLibName, sal_Bool bReference )
1347 {
1348 	DBG_CHKTHIS( BasicManager, 0 );
1349 
1350     String aStorName( rStorage.GetName() );
1351     DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1352 
1353     String aStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
1354     DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
1355 
1356 	String aNewLibName( rLibName );
1357 	while ( HasLib( aNewLibName ) )
1358 		aNewLibName += '_';
1359 
1360 	BasicLibInfo* pLibInfo = CreateLibInfo();
1361 	// Use original name otherwise ImpLoadLibary failes...
1362 	pLibInfo->SetLibName( rLibName );
1363 	// Funktioniert so aber nicht, wenn Name doppelt
1364 //	sal_uInt16 nLibId = GetLibId( rLibName );
1365 	sal_uInt16 nLibId = (sal_uInt16) pLibs->GetPos( pLibInfo );
1366 
1367 	// Set StorageName before load because it is compared with pCurStorage
1368 	pLibInfo->SetStorageName( aStorageName );
1369     sal_Bool bLoaded = ImpLoadLibary( pLibInfo, &rStorage );
1370 
1371 	if ( bLoaded )
1372 	{
1373 		if ( aNewLibName != rLibName )
1374 			SetLibName( nLibId, aNewLibName );
1375 
1376 		if ( bReference )
1377 		{
1378 			pLibInfo->GetLib()->SetModified( sal_False );	// Don't save in this case
1379 			pLibInfo->SetRelStorageName( String() );
1380 //			pLibInfo->CalcRelStorageName( GetStorageName() );
1381 			pLibInfo->IsReference() = sal_True;
1382 		}
1383 		else
1384 		{
1385 			pLibInfo->GetLib()->SetModified( sal_True ); // Must be saved after Add!
1386 			pLibInfo->SetStorageName( String::CreateFromAscii(szImbedded) ); // Save in BasicManager-Storage
1387 		}
1388 		bBasMgrModified = sal_True;
1389 	}
1390 	else
1391 	{
1392 		RemoveLib( nLibId, sal_False );
1393 		pLibInfo = 0;
1394 	}
1395 
1396 	if( pLibInfo )
1397 		return &*pLibInfo->GetLib() ;
1398 	else
1399 		return 0;
1400 }
1401 
1402 sal_Bool BasicManager::IsReference( sal_uInt16 nLib )
1403 {
1404 	DBG_CHKTHIS( BasicManager, 0 );
1405 
1406 	BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1407 	DBG_ASSERT( pLibInfo, "Lib?!" );
1408 	if ( pLibInfo )
1409 		return pLibInfo->IsReference();
1410 
1411 	return sal_False;
1412 }
1413 
1414 sal_Bool BasicManager::RemoveLib( sal_uInt16 nLib )
1415 {
1416 	// Only pyhsical deletion if no reference
1417 	return RemoveLib( nLib, !IsReference( nLib ) );
1418 }
1419 
1420 sal_Bool BasicManager::RemoveLib( sal_uInt16 nLib, sal_Bool bDelBasicFromStorage )
1421 {
1422 	DBG_CHKTHIS( BasicManager, 0 );
1423 	DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" );
1424 
1425 	BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1426 	DBG_ASSERT( pLibInfo, "Lib not found!" );
1427 
1428 	if ( !pLibInfo || !nLib )
1429 	{
1430 //		String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
1431 		StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
1432 		pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STDLIB, pLibInfo->GetLibName() ) );
1433 		return sal_False;
1434 	}
1435 
1436     // If one of the streams cannot be opened, this is not an error,
1437     // because BASIC was never written before...
1438 	if ( bDelBasicFromStorage && !pLibInfo->IsReference() &&
1439 			( !pLibInfo->IsExtern() || SotStorage::IsStorageFile( pLibInfo->GetStorageName() ) ) )
1440 	{
1441 		SotStorageRef xStorage;
1442 		if ( !pLibInfo->IsExtern() )
1443 			xStorage = new SotStorage( sal_False, GetStorageName() );
1444 		else
1445 			xStorage = new SotStorage( sal_False, pLibInfo->GetStorageName() );
1446 
1447 		if ( xStorage->IsStorage( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) ) )
1448 		{
1449 			SotStorageRef xBasicStorage = xStorage->OpenSotStorage
1450 							( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), STREAM_STD_READWRITE, sal_False );
1451 
1452 			if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1453 			{
1454 //				String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
1455 				StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
1456 				pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
1457 			}
1458 			else if ( xBasicStorage->IsStream( pLibInfo->GetLibName() ) )
1459 			{
1460 				xBasicStorage->Remove( pLibInfo->GetLibName() );
1461 				xBasicStorage->Commit();
1462 
1463 				// If no further stream available,
1464 				// delete the SubStorage.
1465 				SvStorageInfoList aInfoList( 0, 4 );
1466 				xBasicStorage->FillInfoList( &aInfoList );
1467 				if ( !aInfoList.Count() )
1468 				{
1469 					xBasicStorage.Clear();
1470 					xStorage->Remove( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) );
1471 					xStorage->Commit();
1472 					// If no further Streams or SubStorages available,
1473 					// delete the Storage, too.
1474 					aInfoList.Clear();
1475 					xStorage->FillInfoList( &aInfoList );
1476 					if ( !aInfoList.Count() )
1477 					{
1478                         String aName_( xStorage->GetName() );
1479 						xStorage.Clear();
1480                         //*** TODO: Replace if still necessary
1481                         //SfxContentHelper::Kill( aName );
1482                         //*** TODO-End
1483 					}
1484 				}
1485 			}
1486 		}
1487 	}
1488 	bBasMgrModified = sal_True;
1489 	if ( pLibInfo->GetLib().Is() )
1490 		GetStdLib()->Remove( pLibInfo->GetLib() );
1491 	delete pLibs->Remove( pLibInfo );
1492 	return sal_True;	// Remove was successful, del unimportant
1493 }
1494 
1495 sal_uInt16 BasicManager::GetLibCount() const
1496 {
1497 	DBG_CHKTHIS( BasicManager, 0 );
1498 	return (sal_uInt16)pLibs->Count();
1499 }
1500 
1501 StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const
1502 {
1503 	DBG_CHKTHIS( BasicManager, 0 );
1504 	BasicLibInfo* pInf = pLibs->GetObject( nLib );
1505 	DBG_ASSERT( pInf, "Lib existiert nicht!" );
1506 	if ( pInf )
1507 		return pInf->GetLib();
1508 	return 0;
1509 }
1510 
1511 StarBASIC* BasicManager::GetStdLib() const
1512 {
1513 	DBG_CHKTHIS( BasicManager, 0 );
1514 	StarBASIC* pLib = GetLib( 0 );
1515 	return pLib;
1516 }
1517 
1518 StarBASIC* BasicManager::GetLib( const String& rName ) const
1519 {
1520 	DBG_CHKTHIS( BasicManager, 0 );
1521 
1522 	BasicLibInfo* pInf = pLibs->First();
1523 	while ( pInf )
1524 	{
1525 		if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )// Check if available...
1526 			return pInf->GetLib();
1527 
1528 		pInf = pLibs->Next();
1529 	}
1530 	return 0;
1531 }
1532 
1533 sal_uInt16 BasicManager::GetLibId( const String& rName ) const
1534 {
1535 	DBG_CHKTHIS( BasicManager, 0 );
1536 
1537 	BasicLibInfo* pInf = pLibs->First();
1538 	while ( pInf )
1539 	{
1540 		if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
1541 			return (sal_uInt16)pLibs->GetCurPos();
1542 
1543 		pInf = pLibs->Next();
1544 	}
1545 	return LIB_NOTFOUND;
1546 }
1547 
1548 sal_Bool BasicManager::HasLib( const String& rName ) const
1549 {
1550 	DBG_CHKTHIS( BasicManager, 0 );
1551 
1552 	BasicLibInfo* pInf = pLibs->First();
1553 	while ( pInf )
1554 	{
1555 		if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
1556 			return sal_True;
1557 
1558 		pInf = pLibs->Next();
1559 	}
1560 	return sal_False;
1561 }
1562 
1563 sal_Bool BasicManager::SetLibName( sal_uInt16 nLib, const String& rName )
1564 {
1565 	DBG_CHKTHIS( BasicManager, 0 );
1566 
1567 	BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1568 	DBG_ASSERT( pLibInfo, "Lib?!" );
1569 	if ( pLibInfo )
1570 	{
1571 		pLibInfo->SetLibName( rName );
1572 		if ( pLibInfo->GetLib().Is() )
1573 		{
1574             StarBASICRef xStdLib = pLibInfo->GetLib();
1575 			xStdLib->SetName( rName );
1576 			xStdLib->SetModified( sal_True );
1577 		}
1578 		bBasMgrModified = sal_True;
1579 		return sal_True;
1580 	}
1581 	return sal_False;
1582 }
1583 
1584 String BasicManager::GetLibName( sal_uInt16 nLib )
1585 {
1586 	DBG_CHKTHIS( BasicManager, 0 );
1587 
1588 	BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1589 	DBG_ASSERT( pLibInfo, "Lib?!" );
1590 	if ( pLibInfo )
1591 		return pLibInfo->GetLibName();
1592 	return String();
1593 }
1594 
1595 sal_Bool BasicManager::LoadLib( sal_uInt16 nLib )
1596 {
1597 	DBG_CHKTHIS( BasicManager, 0 );
1598 
1599 	sal_Bool bDone = sal_False;
1600 	BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1601 	DBG_ASSERT( pLibInfo, "Lib?!" );
1602 	if ( pLibInfo )
1603 	{
1604         Reference< XLibraryContainer > xLibContainer = pLibInfo->GetLibraryContainer();
1605         if( xLibContainer.is() )
1606         {
1607             String aLibName = pLibInfo->GetLibName();
1608             xLibContainer->loadLibrary( aLibName );
1609             bDone = xLibContainer->isLibraryLoaded( aLibName );;
1610         }
1611         else
1612         {
1613             bDone = ImpLoadLibary( pLibInfo, NULL, sal_False );
1614 		    StarBASIC* pLib = GetLib( nLib );
1615 		    if ( pLib )
1616 		    {
1617     //			pLib->SetParent( GetStdLib() );
1618 			    GetStdLib()->Insert( pLib );
1619 			    pLib->SetFlag( SBX_EXTSEARCH );
1620 		    }
1621         }
1622 	}
1623 	else
1624 	{
1625 //		String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
1626 //		aErrorText.SearchAndReplace( "XX", "" );
1627 		StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD,	String(), ERRCODE_BUTTON_OK );
1628 		pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_LIBNOTFOUND, String::CreateFromInt32(nLib) ) );
1629 	}
1630 	return bDone;
1631 }
1632 
1633 StarBASIC* BasicManager::CreateLib( const String& rLibName )
1634 {
1635 	DBG_CHKTHIS( BasicManager, 0 );
1636 	if ( GetLib( rLibName ) )
1637 		return 0;
1638 
1639 	BasicLibInfo* pLibInfo = CreateLibInfo();
1640 	StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1641 	GetStdLib()->Insert( pNew );
1642 	pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1643 	pLibInfo->SetLib( pNew );
1644 	pLibInfo->SetLibName( rLibName );
1645 	pLibInfo->GetLib()->SetName( rLibName );
1646 	return pLibInfo->GetLib();
1647 }
1648 
1649 // For XML import/export:
1650 StarBASIC* BasicManager::CreateLib
1651     ( const String& rLibName, const String& Password, const String& LinkTargetURL )
1652 {
1653 	// Ask if lib exists because standard lib is always there
1654 	StarBASIC* pLib = GetLib( rLibName );
1655 	if( !pLib )
1656 	{
1657 	    if( LinkTargetURL.Len() != 0 )
1658 		{
1659 			SotStorageRef xStorage = new SotStorage( sal_False, LinkTargetURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
1660 			if( !xStorage->GetError() )
1661 			{
1662 				pLib = AddLib( *xStorage, rLibName, sal_True );
1663 
1664 				//if( !pLibInfo )
1665 					//pLibInfo = FindLibInfo( pLib );
1666 				//pLibInfo->SetStorageName( LinkTargetURL );
1667 				//pLibInfo->GetLib()->SetModified( sal_False );	// Dann nicht speichern
1668 				//pLibInfo->SetRelStorageName( String() );
1669 				//pLibInfo->IsReference() = sal_True;
1670 			}
1671 			//else
1672 				//Message?
1673 
1674 			DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
1675 		}
1676 		else
1677 		{
1678 			pLib = CreateLib( rLibName );
1679 			if( Password.Len() != 0 )
1680 			{
1681 				BasicLibInfo* pLibInfo = FindLibInfo( pLib );
1682 				pLibInfo ->SetPassword( Password );
1683 			}
1684 		}
1685 		//ExternalSourceURL ?
1686 	}
1687 	return pLib;
1688 }
1689 
1690 StarBASIC* BasicManager::CreateLibForLibContainer( const String& rLibName,
1691     const Reference< XLibraryContainer >& xScriptCont )
1692 {
1693 	DBG_CHKTHIS( BasicManager, 0 );
1694 	if ( GetLib( rLibName ) )
1695 		return 0;
1696 
1697 	BasicLibInfo* pLibInfo = CreateLibInfo();
1698 	StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1699 	GetStdLib()->Insert( pNew );
1700 	pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1701 	pLibInfo->SetLib( pNew );
1702 	pLibInfo->SetLibName( rLibName );
1703 	pLibInfo->GetLib()->SetName( rLibName );
1704     pLibInfo->SetLibraryContainer( xScriptCont );
1705 	return pNew;
1706 }
1707 
1708 
1709 BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic ) const
1710 {
1711 	DBG_CHKTHIS( BasicManager, 0 );
1712 
1713 	BasicLibInfo* pInf = ((BasicManager*)this)->pLibs->First();
1714 	while ( pInf )
1715 	{
1716 		if ( pInf->GetLib() == pBasic )
1717 			return pInf;
1718 
1719 		pInf = ((BasicManager*)this)->pLibs->Next();
1720 	}
1721 	return 0;
1722 }
1723 
1724 
1725 sal_Bool BasicManager::IsModified() const
1726 {
1727 	DBG_CHKTHIS( BasicManager, 0 );
1728 
1729 	if ( bBasMgrModified )
1730 		return sal_True;
1731 	return IsBasicModified();
1732 }
1733 
1734 sal_Bool BasicManager::IsBasicModified() const
1735 {
1736 	DBG_CHKTHIS( BasicManager, 0 );
1737 
1738 	BasicLibInfo* pInf = pLibs->First();
1739 	while ( pInf )
1740 	{
1741 		if ( pInf->GetLib().Is() && pInf->GetLib()->IsModified() )
1742 			return sal_True;
1743 
1744 		pInf = pLibs->Next();
1745 	}
1746 	return sal_False;
1747 }
1748 
1749 void BasicManager::SetFlagToAllLibs( short nFlag, sal_Bool bSet ) const
1750 {
1751 	sal_uInt16 nLibs = GetLibCount();
1752 	for ( sal_uInt16 nL = 0; nL < nLibs; nL++ )
1753 	{
1754 		BasicLibInfo* pInfo = pLibs->GetObject( nL );
1755 		DBG_ASSERT( pInfo, "Info?!" );
1756 		StarBASIC* pLib = pInfo->GetLib();
1757 		if ( pLib )
1758 		{
1759 			if ( bSet )
1760 				pLib->SetFlag( nFlag );
1761 			else
1762 				pLib->ResetFlag( nFlag );
1763 		}
1764 	}
1765 }
1766 
1767 sal_Bool BasicManager::HasErrors()
1768 {
1769 	DBG_CHKTHIS( BasicManager, 0 );
1770 	return pErrorMgr->HasErrors();
1771 }
1772 
1773 void BasicManager::ClearErrors()
1774 {
1775 	DBG_CHKTHIS( BasicManager, 0 );
1776 	pErrorMgr->Reset();
1777 }
1778 
1779 BasicError* BasicManager::GetFirstError()
1780 {
1781 	DBG_CHKTHIS( BasicManager, 0 );
1782 	return pErrorMgr->GetFirstError();
1783 }
1784 
1785 BasicError* BasicManager::GetNextError()
1786 {
1787 	DBG_CHKTHIS( BasicManager, 0 );
1788 	return pErrorMgr->GetNextError();
1789 }
1790 bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
1791 {
1792     bool bRes = false;
1793     StarBASIC* pStandardLib = GetStdLib();
1794     OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" );
1795     if ( pStandardLib )
1796         bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut );
1797     return bRes;
1798 }
1799 
1800 Any BasicManager::SetGlobalUNOConstant( const sal_Char* _pAsciiName, const Any& _rValue )
1801 {
1802     Any aOldValue;
1803 
1804     StarBASIC* pStandardLib = GetStdLib();
1805     OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
1806     if ( !pStandardLib )
1807         return aOldValue;
1808 
1809     ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
1810 
1811     // obtain the old value
1812     SbxVariable* pVariable = pStandardLib->Find( sVarName, SbxCLASS_OBJECT );
1813     if ( pVariable )
1814         aOldValue = sbxToUnoValue( pVariable );
1815 
1816     SbxObjectRef xUnoObj = GetSbUnoObject( sVarName, _rValue );
1817     xUnoObj->SetFlag( SBX_DONTSTORE );
1818     pStandardLib->Insert( xUnoObj );
1819 
1820     return aOldValue;
1821 }
1822 
1823 bool BasicManager::LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames )
1824 {
1825     try
1826     {
1827         Reference< XNameAccess > xScripts( GetScriptLibraryContainer(), UNO_QUERY_THROW );
1828         Reference< XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), UNO_QUERY_THROW );
1829 
1830         Sequence< ::rtl::OUString > aNames( xScripts->getElementNames() );
1831         const ::rtl::OUString* pNames = aNames.getConstArray();
1832         const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
1833         for ( ; pNames != pNamesEnd; ++pNames )
1834         {
1835             if( /*pLib->mbSharedIndexFile ||*/ !xPassword->isLibraryPasswordProtected( *pNames ) )
1836                 continue;
1837 
1838             StarBASIC* pBasicLib = GetLib( *pNames );
1839             if ( !pBasicLib )
1840                 continue;
1841 
1842             Reference< XNameAccess > xScriptLibrary( xScripts->getByName( *pNames ), UNO_QUERY_THROW );
1843             Sequence< ::rtl::OUString > aElementNames( xScriptLibrary->getElementNames() );
1844             sal_Int32 nLen = aElementNames.getLength();
1845 
1846             Sequence< ::rtl::OUString > aBigModules( nLen );
1847             sal_Int32 nBigModules = 0;
1848 
1849             const ::rtl::OUString* pElementNames = aElementNames.getConstArray();
1850             const ::rtl::OUString* pElementNamesEnd = aElementNames.getConstArray() + aElementNames.getLength();
1851             for ( ; pElementNames != pElementNamesEnd; ++pElementNames )
1852             {
1853                 SbModule* pMod = pBasicLib->FindModule( *pElementNames );
1854                 if ( pMod && pMod->ExceedsLegacyModuleSize() )
1855                     aBigModules[ nBigModules++ ] = *pElementNames;
1856             }
1857 
1858             if ( nBigModules )
1859             {
1860                 aBigModules.realloc( nBigModules );
1861                 _out_rModuleNames = aBigModules;
1862                 return true;
1863             }
1864         }
1865     }
1866     catch( const Exception& )
1867     {
1868     	DBG_UNHANDLED_EXCEPTION();
1869     }
1870     return false;
1871 }
1872 
1873 
1874 namespace
1875 {
1876     SbMethod* lcl_queryMacro( BasicManager* i_manager, String const& i_fullyQualifiedName )
1877     {
1878         sal_uInt16 nLast = 0;
1879         String sMacro = i_fullyQualifiedName;
1880         String sLibName = sMacro.GetToken( 0, '.', nLast );
1881         String sModule = sMacro.GetToken( 0, '.', nLast );
1882         sMacro.Erase( 0, nLast );
1883 
1884 	    IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
1885 	    const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
1886 	    sal_uInt16 nLibCount = i_manager->GetLibCount();
1887 	    for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib )
1888 	    {
1889 		    if ( COMPARE_EQUAL == pCollator->compareString( i_manager->GetLibName( nLib ), sLibName ) )
1890 		    {
1891 			    StarBASIC* pLib = i_manager->GetLib( nLib );
1892 			    if( !pLib )
1893 			    {
1894 				    i_manager->LoadLib( nLib );
1895 				    pLib = i_manager->GetLib( nLib );
1896 			    }
1897 
1898 			    if( pLib )
1899 			    {
1900 				    sal_uInt16 nModCount = pLib->GetModules()->Count();
1901 				    for( sal_uInt16 nMod = 0; nMod < nModCount; ++nMod )
1902 				    {
1903 					    SbModule* pMod = (SbModule*)pLib->GetModules()->Get( nMod );
1904 					    if ( pMod && COMPARE_EQUAL == pCollator->compareString( pMod->GetName(), sModule ) )
1905 					    {
1906 						    SbMethod* pMethod = (SbMethod*)pMod->Find( sMacro, SbxCLASS_METHOD );
1907 						    if( pMethod )
1908 							    return pMethod;
1909 					    }
1910 				    }
1911 			    }
1912 		    }
1913 	    }
1914 	    return 0;
1915     }
1916 }
1917 
1918 bool BasicManager::HasMacro( String const& i_fullyQualifiedName ) const
1919 {
1920     return ( NULL != lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) );
1921 }
1922 
1923 ErrCode BasicManager::ExecuteMacro( String const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue )
1924 {
1925     SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1926     ErrCode nError = 0;
1927     if ( pMethod )
1928     {
1929         if ( i_arguments )
1930             pMethod->SetParameters( i_arguments );
1931         nError = pMethod->Call( i_retValue );
1932     }
1933     else
1934         nError = ERRCODE_BASIC_PROC_UNDEFINED;
1935     return nError;
1936 }
1937 
1938 ErrCode BasicManager::ExecuteMacro( String const& i_fullyQualifiedName, String const& i_commaSeparatedArgs, SbxValue* i_retValue )
1939 {
1940     SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1941     if ( !pMethod )
1942         return ERRCODE_BASIC_PROC_UNDEFINED;
1943 
1944     // arguments must be quoted
1945     String sQuotedArgs;
1946     String sArgs( i_commaSeparatedArgs );
1947     if ( sArgs.Len()<2 || sArgs.GetBuffer()[1] == '\"')
1948         // no args or already quoted args
1949         sQuotedArgs = sArgs;
1950     else
1951     {
1952         // quote parameters
1953         sArgs.Erase( 0, 1 );
1954         sArgs.Erase( sArgs.Len()-1, 1 );
1955 
1956         sQuotedArgs = '(';
1957 
1958         sal_uInt16 nCount = sArgs.GetTokenCount(',');
1959         for ( sal_uInt16 n=0; n<nCount; ++n )
1960         {
1961             sQuotedArgs += '\"';
1962             sQuotedArgs += sArgs.GetToken( n, ',' );
1963             sQuotedArgs += '\"';
1964             if ( n<nCount-1 )
1965                 sQuotedArgs += ',';
1966         }
1967 
1968         sQuotedArgs += ')';
1969     }
1970 
1971     // add quoted arguments and do the call
1972     String sCall( '[' );
1973     sCall += pMethod->GetName();
1974     sCall += sQuotedArgs;
1975     sCall += ']';
1976 
1977 	SbxVariable* pRet = pMethod->GetParent()->Execute( sCall );
1978     if ( pRet && ( pRet != pMethod ) )
1979         *i_retValue = *pRet;
1980     return SbxBase::GetError();
1981 }
1982 
1983 //=====================================================================
1984 
1985 class ModuleInfo_Impl : public ModuleInfoHelper
1986 {
1987 	::rtl::OUString maName;
1988 	::rtl::OUString maLanguage;
1989 	::rtl::OUString maSource;
1990 
1991 public:
1992 	ModuleInfo_Impl( const ::rtl::OUString& aName, const ::rtl::OUString& aLanguage, const ::rtl::OUString& aSource )
1993 		: maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
1994 
1995     // Methods XStarBasicModuleInfo
1996     virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
1997 		{ return maName; }
1998     virtual ::rtl::OUString SAL_CALL getLanguage() throw(RuntimeException)
1999 		{ return maLanguage; }
2000     virtual ::rtl::OUString SAL_CALL getSource() throw(RuntimeException)
2001 		{ return maSource; }
2002 };
2003 
2004 
2005 //=====================================================================
2006 
2007 class DialogInfo_Impl : public DialogInfoHelper
2008 {
2009 	::rtl::OUString maName;
2010 	Sequence< sal_Int8 > mData;
2011 
2012 public:
2013 	DialogInfo_Impl( const ::rtl::OUString& aName, Sequence< sal_Int8 > Data )
2014 		: maName( aName ), mData( Data ) {}
2015 
2016     // Methods XStarBasicDialogInfo
2017     virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
2018 		{ return maName; }
2019     virtual Sequence< sal_Int8 > SAL_CALL getData() throw(RuntimeException)
2020 		{ return mData; }
2021 };
2022 
2023 
2024 //=====================================================================
2025 
2026 class LibraryInfo_Impl : public LibraryInfoHelper
2027 {
2028 	::rtl::OUString maName;
2029 	Reference< XNameContainer > mxModuleContainer;
2030 	Reference< XNameContainer > mxDialogContainer;
2031 	::rtl::OUString maPassword;
2032 	::rtl::OUString maExternaleSourceURL;
2033 	::rtl::OUString maLinkTargetURL;
2034 
2035 public:
2036 	LibraryInfo_Impl
2037 	(
2038 		const ::rtl::OUString& aName,
2039 		Reference< XNameContainer > xModuleContainer,
2040 		Reference< XNameContainer > xDialogContainer,
2041 		const ::rtl::OUString& aPassword,
2042 		const ::rtl::OUString& aExternaleSourceURL,
2043 		const ::rtl::OUString& aLinkTargetURL
2044 	)
2045 		: maName( aName )
2046 		, mxModuleContainer( xModuleContainer )
2047 		, mxDialogContainer( xDialogContainer )
2048 		, maPassword( aPassword )
2049 		, maExternaleSourceURL( aExternaleSourceURL )
2050 		, maLinkTargetURL( aLinkTargetURL )
2051 	{}
2052 
2053     // Methods XStarBasicLibraryInfo
2054     virtual ::rtl::OUString SAL_CALL getName() throw(RuntimeException)
2055 		{ return maName; }
2056     virtual Reference< XNameContainer > SAL_CALL getModuleContainer() throw(RuntimeException)
2057 		{ return mxModuleContainer; }
2058     virtual Reference< XNameContainer > SAL_CALL getDialogContainer() throw(RuntimeException)
2059 		{ return mxDialogContainer; }
2060     virtual ::rtl::OUString SAL_CALL getPassword() throw(RuntimeException)
2061 		{ return maPassword; }
2062     virtual ::rtl::OUString SAL_CALL getExternalSourceURL() throw(RuntimeException)
2063 		{ return maExternaleSourceURL; }
2064     virtual ::rtl::OUString SAL_CALL getLinkTargetURL() throw(RuntimeException)
2065 		{ return maLinkTargetURL; }
2066 };
2067 
2068 //=====================================================================
2069 
2070 class ModuleContainer_Impl : public NameContainerHelper
2071 {
2072 	StarBASIC* mpLib;
2073 
2074 public:
2075 	ModuleContainer_Impl( StarBASIC* pLib )
2076 		:mpLib( pLib ) {}
2077 
2078     // Methods XElementAccess
2079     virtual Type SAL_CALL getElementType()
2080 		throw(RuntimeException);
2081     virtual sal_Bool SAL_CALL hasElements()
2082 		throw(RuntimeException);
2083 
2084     // Methods XNameAccess
2085     virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
2086 		throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2087     virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
2088 		throw(RuntimeException);
2089     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
2090 		throw(RuntimeException);
2091 
2092     // Methods XNameReplace
2093     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2094 		throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
2095 
2096     // Methods XNameContainer
2097     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
2098 		throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
2099     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
2100 		throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2101 };
2102 
2103 // Methods XElementAccess
2104 Type ModuleContainer_Impl::getElementType()
2105 	throw(RuntimeException)
2106 {
2107 	Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
2108 	return aModuleType;
2109 }
2110 
2111 sal_Bool ModuleContainer_Impl::hasElements()
2112 	throw(RuntimeException)
2113 {
2114     SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
2115     return pMods && pMods->Count() > 0;
2116 }
2117 
2118 // Methods XNameAccess
2119 Any ModuleContainer_Impl::getByName( const ::rtl::OUString& aName )
2120 	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2121 {
2122     SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
2123 	if( !pMod )
2124 		throw NoSuchElementException();
2125 	Reference< XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl
2126 		( aName, ::rtl::OUString::createFromAscii( szScriptLanguage ), pMod->GetSource32() );
2127 	Any aRetAny;
2128 	aRetAny <<= xMod;
2129 	return aRetAny;
2130 }
2131 
2132 Sequence< ::rtl::OUString > ModuleContainer_Impl::getElementNames()
2133 	throw(RuntimeException)
2134 {
2135     SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
2136     sal_uInt16 nMods = pMods ? pMods->Count() : 0;
2137 	Sequence< ::rtl::OUString > aRetSeq( nMods );
2138 	::rtl::OUString* pRetSeq = aRetSeq.getArray();
2139 	for( sal_uInt16 i = 0 ; i < nMods ; i++ )
2140 	{
2141 		SbxVariable* pMod = pMods->Get( i );
2142 		pRetSeq[i] = ::rtl::OUString( pMod->GetName() );
2143 	}
2144 	return aRetSeq;
2145 }
2146 
2147 sal_Bool ModuleContainer_Impl::hasByName( const ::rtl::OUString& aName )
2148 	throw(RuntimeException)
2149 {
2150     SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
2151 	sal_Bool bRet = (pMod != NULL);
2152 	return bRet;
2153 }
2154 
2155 
2156 // Methods XNameReplace
2157 void ModuleContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2158 	throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2159 {
2160 	removeByName( aName );
2161 	insertByName( aName, aElement );
2162 }
2163 
2164 
2165 // Methods XNameContainer
2166 void ModuleContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2167 	throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2168 {
2169 	Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
2170 	Type aAnyType = aElement.getValueType();
2171 	if( aModuleType != aAnyType )
2172 		throw IllegalArgumentException();
2173 	Reference< XStarBasicModuleInfo > xMod;
2174 	aElement >>= xMod;
2175 	mpLib->MakeModule32( aName, xMod->getSource() );
2176 }
2177 
2178 void ModuleContainer_Impl::removeByName( const ::rtl::OUString& Name )
2179 	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2180 {
2181     SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL;
2182 	if( !pMod )
2183 		throw NoSuchElementException();
2184 	mpLib->Remove( pMod );
2185 }
2186 
2187 
2188 //=====================================================================
2189 
2190 Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
2191 {
2192 	SvMemoryStream aMemStream;
2193 	pDialog->Store( aMemStream );
2194 	sal_Int32 nLen = aMemStream.Tell();
2195 	Sequence< sal_Int8 > aData( nLen );
2196 	sal_Int8* pDestData = aData.getArray();
2197 	const sal_Int8* pSrcData = (const sal_Int8*)aMemStream.GetData();
2198 	rtl_copyMemory( pDestData, pSrcData, nLen );
2199 	return aData;
2200 }
2201 
2202 SbxObject* implCreateDialog( Sequence< sal_Int8 > aData )
2203 {
2204 	sal_Int8* pData = aData.getArray();
2205 	SvMemoryStream aMemStream( pData, aData.getLength(), STREAM_READ );
2206 	SbxObject* pDialog = (SbxObject*)SbxBase::Load( aMemStream );
2207 	return pDialog;
2208 }
2209 
2210 // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
2211 // which we can't include here, we have to use the value directly
2212 #define SBXID_DIALOG		101
2213 
2214 
2215 class DialogContainer_Impl : public NameContainerHelper
2216 {
2217 	StarBASIC* mpLib;
2218 
2219 public:
2220 	DialogContainer_Impl( StarBASIC* pLib )
2221 		:mpLib( pLib ) {}
2222 
2223     // Methods XElementAccess
2224     virtual Type SAL_CALL getElementType()
2225 		throw(RuntimeException);
2226     virtual sal_Bool SAL_CALL hasElements()
2227 		throw(RuntimeException);
2228 
2229     // Methods XNameAccess
2230     virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
2231 		throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2232     virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
2233 		throw(RuntimeException);
2234     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
2235 		throw(RuntimeException);
2236 
2237     // Methods XNameReplace
2238     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2239 		throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
2240 
2241     // Methods XNameContainer
2242     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
2243 		throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
2244     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
2245 		throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2246 };
2247 
2248 // Methods XElementAccess
2249 Type DialogContainer_Impl::getElementType()
2250 	throw(RuntimeException)
2251 {
2252 	Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
2253 	return aModuleType;
2254 }
2255 
2256 sal_Bool DialogContainer_Impl::hasElements()
2257 	throw(RuntimeException)
2258 {
2259 	sal_Bool bRet = sal_False;
2260 
2261 	mpLib->GetAll( SbxCLASS_OBJECT );
2262 	sal_Int16 nCount = mpLib->GetObjects()->Count();
2263 	for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2264 	{
2265 		SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2266 		if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2267 		{
2268 			bRet = sal_True;
2269 			break;
2270 		}
2271 	}
2272 	return bRet;
2273 }
2274 
2275 // Methods XNameAccess
2276 Any DialogContainer_Impl::getByName( const ::rtl::OUString& aName )
2277 	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2278 {
2279 	SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2280 	if( !( pVar && pVar->ISA( SbxObject ) &&
2281 		   ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2282 	{
2283 		throw NoSuchElementException();
2284 	}
2285 
2286 	Reference< XStarBasicDialogInfo > xDialog =
2287 		(XStarBasicDialogInfo*)new DialogInfo_Impl
2288 			( aName, implGetDialogData( (SbxObject*)pVar ) );
2289 
2290 	Any aRetAny;
2291 	aRetAny <<= xDialog;
2292 	return aRetAny;
2293 }
2294 
2295 Sequence< ::rtl::OUString > DialogContainer_Impl::getElementNames()
2296 	throw(RuntimeException)
2297 {
2298 	mpLib->GetAll( SbxCLASS_OBJECT );
2299 	sal_Int16 nCount = mpLib->GetObjects()->Count();
2300 	Sequence< ::rtl::OUString > aRetSeq( nCount );
2301 	::rtl::OUString* pRetSeq = aRetSeq.getArray();
2302 	sal_Int32 nDialogCounter = 0;
2303 
2304 	for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2305 	{
2306 		SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2307 		if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2308 		{
2309 			pRetSeq[ nDialogCounter ] = ::rtl::OUString( pVar->GetName() );
2310 			nDialogCounter++;
2311 		}
2312 	}
2313 	aRetSeq.realloc( nDialogCounter );
2314 	return aRetSeq;
2315 }
2316 
2317 sal_Bool DialogContainer_Impl::hasByName( const ::rtl::OUString& aName )
2318 	throw(RuntimeException)
2319 {
2320 	sal_Bool bRet = sal_False;
2321 	SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2322 	if( pVar && pVar->ISA( SbxObject ) &&
2323 		   ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2324 	{
2325 		bRet = sal_True;
2326 	}
2327 	return bRet;
2328 }
2329 
2330 
2331 // Methods XNameReplace
2332 void DialogContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2333 	throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2334 {
2335 	removeByName( aName );
2336 	insertByName( aName, aElement );
2337 }
2338 
2339 
2340 // Methods XNameContainer
2341 void DialogContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2342 	throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2343 {
2344     (void)aName;
2345 	Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
2346 	Type aAnyType = aElement.getValueType();
2347 	if( aModuleType != aAnyType )
2348 		throw IllegalArgumentException();
2349 	Reference< XStarBasicDialogInfo > xMod;
2350 	aElement >>= xMod;
2351 	SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
2352 	mpLib->Insert( xDialog );
2353 }
2354 
2355 void DialogContainer_Impl::removeByName( const ::rtl::OUString& Name )
2356 	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2357 {
2358     (void)Name;
2359 	SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE );
2360 	if( !( pVar && pVar->ISA( SbxObject ) &&
2361 		   ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2362 	{
2363 		throw NoSuchElementException();
2364 	}
2365 	mpLib->Remove( pVar );
2366 }
2367 
2368 
2369 //=====================================================================
2370 
2371 
2372 class LibraryContainer_Impl : public NameContainerHelper
2373 {
2374 	BasicManager* mpMgr;
2375 
2376 public:
2377 	LibraryContainer_Impl( BasicManager* pMgr )
2378 		:mpMgr( pMgr ) {}
2379 
2380     // Methods XElementAccess
2381     virtual Type SAL_CALL getElementType()
2382 		throw(RuntimeException);
2383     virtual sal_Bool SAL_CALL hasElements()
2384 		throw(RuntimeException);
2385 
2386     // Methods XNameAccess
2387     virtual Any SAL_CALL getByName( const ::rtl::OUString& aName )
2388 		throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2389     virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames()
2390 		throw(RuntimeException);
2391     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
2392 		throw(RuntimeException);
2393 
2394     // Methods XNameReplace
2395     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2396 		throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
2397 
2398     // Methods XNameContainer
2399     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement )
2400 		throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
2401     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
2402 		throw(NoSuchElementException, WrappedTargetException, RuntimeException);
2403 };
2404 
2405 
2406 // Methods XElementAccess
2407 Type LibraryContainer_Impl::getElementType()
2408 	throw(RuntimeException)
2409 {
2410 	Type aType = ::getCppuType( (const Reference< XStarBasicLibraryInfo > *)0 );
2411 	return aType;
2412 }
2413 
2414 sal_Bool LibraryContainer_Impl::hasElements()
2415 	throw(RuntimeException)
2416 {
2417 	sal_Int32 nLibs = mpMgr->GetLibCount();
2418 	sal_Bool bRet = (nLibs > 0);
2419 	return bRet;
2420 }
2421 
2422 // Methods XNameAccess
2423 Any LibraryContainer_Impl::getByName( const ::rtl::OUString& aName )
2424 	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2425 {
2426 	Any aRetAny;
2427 	if( !mpMgr->HasLib( aName ) )
2428 		throw NoSuchElementException();
2429 	StarBASIC* pLib = mpMgr->GetLib( aName );
2430 
2431 	Reference< XNameContainer > xModuleContainer =
2432 		(XNameContainer*)new ModuleContainer_Impl( pLib );
2433 
2434 	Reference< XNameContainer > xDialogContainer;
2435 		(XNameContainer*)new DialogContainer_Impl( pLib );
2436 
2437 	BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
2438 
2439 	::rtl::OUString aPassword = pLibInfo->GetPassword();
2440 
2441 	// TODO Only provide extern info!
2442 	::rtl::OUString aExternaleSourceURL;
2443 	::rtl::OUString aLinkTargetURL;
2444 	if( pLibInfo->IsReference() )
2445 		aLinkTargetURL = pLibInfo->GetStorageName();
2446 	else if( pLibInfo->IsExtern() )
2447 		aExternaleSourceURL = pLibInfo->GetStorageName();
2448 
2449 	Reference< XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
2450 	(
2451 		aName,
2452 		xModuleContainer,
2453 		xDialogContainer,
2454 		aPassword,
2455 		aExternaleSourceURL,
2456 		aLinkTargetURL
2457 	);
2458 
2459 	aRetAny <<= xLibInfo;
2460 	return aRetAny;
2461 }
2462 
2463 Sequence< ::rtl::OUString > LibraryContainer_Impl::getElementNames()
2464 	throw(RuntimeException)
2465 {
2466 	sal_uInt16 nLibs = mpMgr->GetLibCount();
2467 	Sequence< ::rtl::OUString > aRetSeq( nLibs );
2468 	::rtl::OUString* pRetSeq = aRetSeq.getArray();
2469 	for( sal_uInt16 i = 0 ; i < nLibs ; i++ )
2470 	{
2471 		pRetSeq[i] = ::rtl::OUString( mpMgr->GetLibName( i ) );
2472 	}
2473 	return aRetSeq;
2474 }
2475 
2476 sal_Bool LibraryContainer_Impl::hasByName( const ::rtl::OUString& aName )
2477 	throw(RuntimeException)
2478 {
2479 	sal_Bool bRet = mpMgr->HasLib( aName );
2480 	return bRet;
2481 }
2482 
2483 // Methods XNameReplace
2484 void LibraryContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2485 	throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2486 {
2487 	removeByName( aName );
2488 	insertByName( aName, aElement );
2489 }
2490 
2491 // Methods XNameContainer
2492 void LibraryContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2493 	throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2494 {
2495     (void)aName;
2496     (void)aElement;
2497 	// TODO: Insert a complete Library?!
2498 }
2499 
2500 void LibraryContainer_Impl::removeByName( const ::rtl::OUString& Name )
2501 	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2502 {
2503 	StarBASIC* pLib = mpMgr->GetLib( Name );
2504 	if( !pLib )
2505 		throw NoSuchElementException();
2506 	sal_uInt16 nLibId = mpMgr->GetLibId( Name );
2507 	mpMgr->RemoveLib( nLibId );
2508 }
2509 
2510 //=====================================================================
2511 
2512 typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
2513 
2514 
2515 class StarBasicAccess_Impl : public StarBasicAccessHelper
2516 {
2517 	BasicManager* mpMgr;
2518 	Reference< XNameContainer > mxLibContainer;
2519 
2520 public:
2521 	StarBasicAccess_Impl( BasicManager* pMgr )
2522 		:mpMgr( pMgr ) {}
2523 
2524 public:
2525 
2526     // Methods
2527     virtual Reference< XNameContainer > SAL_CALL getLibraryContainer()
2528 		throw(RuntimeException);
2529     virtual void SAL_CALL createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password,
2530 		const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL )
2531 			throw(ElementExistException, RuntimeException);
2532     virtual void SAL_CALL addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName,
2533 		const ::rtl::OUString& Language, const ::rtl::OUString& Source )
2534 			throw(NoSuchElementException, RuntimeException);
2535     virtual void SAL_CALL addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName,
2536 		const Sequence< sal_Int8 >& Data )
2537 			throw(NoSuchElementException, RuntimeException);
2538 
2539 };
2540 
2541 Reference< XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
2542 	throw(RuntimeException)
2543 {
2544 	if( !mxLibContainer.is() )
2545 		mxLibContainer = (XNameContainer*)new LibraryContainer_Impl( mpMgr );
2546 	return mxLibContainer;
2547 }
2548 
2549 void SAL_CALL StarBasicAccess_Impl::createLibrary
2550 (
2551 	const ::rtl::OUString& LibName,
2552 	const ::rtl::OUString& Password,
2553 	const ::rtl::OUString& ExternalSourceURL,
2554 	const ::rtl::OUString& LinkTargetURL
2555 )
2556 	throw(ElementExistException, RuntimeException)
2557 {
2558     (void)ExternalSourceURL;
2559 #ifdef DBG_UTIL
2560 	StarBASIC* pLib =
2561 #endif
2562 	mpMgr->CreateLib( LibName, Password, LinkTargetURL );
2563 	DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
2564 }
2565 
2566 void SAL_CALL StarBasicAccess_Impl::addModule
2567 (
2568 	const ::rtl::OUString& LibraryName,
2569 	const ::rtl::OUString& ModuleName,
2570 	const ::rtl::OUString& Language,
2571 	const ::rtl::OUString& Source
2572 )
2573 	throw(NoSuchElementException, RuntimeException)
2574 {
2575     (void)Language;
2576 	StarBASIC* pLib = mpMgr->GetLib( LibraryName );
2577 	DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
2578 	if( pLib )
2579 		pLib->MakeModule32( ModuleName, Source );
2580 }
2581 
2582 void SAL_CALL StarBasicAccess_Impl::addDialog
2583 (
2584 	const ::rtl::OUString& LibraryName,
2585 	const ::rtl::OUString& DialogName,
2586 	const Sequence< sal_Int8 >& Data
2587 )
2588 	throw(NoSuchElementException, RuntimeException)
2589 {
2590 	(void)LibraryName;
2591 	(void)DialogName;
2592 	(void)Data;
2593 }
2594 
2595 // Basic XML Import/Export
2596 Reference< XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
2597 {
2598 	Reference< XStarBasicAccess > xRet =
2599 		new StarBasicAccess_Impl( (BasicManager*)pMgr );
2600 	return xRet;
2601 }
2602 
2603