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