Update to m13
[ooovba.git] / basic / source / classes / sb.cxx
blob6b96c4f96955911f7ea7c4f13e1e94493cb38ae0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sb.cxx,v $
10 * $Revision: 1.34 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
34 #include <stdio.h>
36 #include "sb.hxx"
37 #include <tools/rcid.h>
38 #include <tools/config.hxx>
39 #include <tools/stream.hxx>
40 #ifndef __RSC //autogen
41 #include <tools/errinf.hxx>
42 #endif
43 #include <basic/sbx.hxx>
44 #include <tools/list.hxx>
45 #include <tools/shl.hxx>
46 #include <tools/rc.hxx>
47 #include <vcl/svapp.hxx>
48 #include "sbunoobj.hxx"
49 #include "sbjsmeth.hxx"
50 #include "sbjsmod.hxx"
51 #include "sbintern.hxx"
52 #include "disas.hxx"
53 #include "runtime.hxx"
54 #include <basic/sbuno.hxx>
55 #include <basic/sbobjmod.hxx>
56 #include "stdobj.hxx"
57 #include "filefmt.hxx"
58 #include "sb.hrc"
59 #include <basrid.hxx>
60 #include <vos/mutex.hxx>
62 #include <com/sun/star/script/ModuleType.hpp>
63 #include <com/sun/star/script/ModuleInfo.hpp>
64 using namespace ::com::sun::star::script;
66 // #pragma SW_SEGMENT_CLASS( SBASIC, SBASIC_CODE )
68 SV_IMPL_VARARR(SbTextPortions,SbTextPortion)
70 TYPEINIT1(StarBASIC,SbxObject)
72 #define RTLNAME "@SBRTL"
73 // i#i68894#
75 const static String aThisComponent( RTL_CONSTASCII_USTRINGPARAM("ThisComponent") );
76 const static String aVBAHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
78 SbxObject* StarBASIC::getVBAGlobals( )
80 if ( !pVBAGlobals )
81 pVBAGlobals = (SbUnoObject*)Find( aVBAHook , SbxCLASS_DONTCARE );
82 return pVBAGlobals;
85 // i#i68894#
86 SbxVariable* StarBASIC::VBAFind( const String& rName, SbxClassType t )
88 if( rName == aThisComponent )
89 return NULL;
90 // rename to init globals
91 if ( getVBAGlobals( ) )
92 return pVBAGlobals->Find( rName, t );
93 return NULL;
97 //========================================================================
98 // Array zur Umrechnung SFX <-> VB-Fehlercodes anlegen
100 struct SFX_VB_ErrorItem
102 USHORT nErrorVB;
103 SbError nErrorSFX;
106 const SFX_VB_ErrorItem __FAR_DATA SFX_VB_ErrorTab[] =
108 { 1, SbERR_BASIC_EXCEPTION }, // #87844 Map exception to error code 1
109 { 2, SbERR_SYNTAX },
110 { 3, SbERR_NO_GOSUB },
111 { 4, SbERR_REDO_FROM_START },
112 { 5, SbERR_BAD_ARGUMENT },
113 { 6, SbERR_MATH_OVERFLOW },
114 { 7, SbERR_NO_MEMORY },
115 { 8, SbERR_ALREADY_DIM },
116 { 9, SbERR_OUT_OF_RANGE },
117 { 10, SbERR_DUPLICATE_DEF },
118 { 11, SbERR_ZERODIV },
119 { 12, SbERR_VAR_UNDEFINED },
120 { 13, SbERR_CONVERSION },
121 { 14, SbERR_BAD_PARAMETER },
122 { 18, SbERR_USER_ABORT },
123 { 20, SbERR_BAD_RESUME },
124 { 28, SbERR_STACK_OVERFLOW },
125 { 35, SbERR_PROC_UNDEFINED },
126 { 48, SbERR_BAD_DLL_LOAD },
127 { 49, SbERR_BAD_DLL_CALL },
128 { 51, SbERR_INTERNAL_ERROR },
129 { 52, SbERR_BAD_CHANNEL },
130 { 53, SbERR_FILE_NOT_FOUND },
131 { 54, SbERR_BAD_FILE_MODE },
132 { 55, SbERR_FILE_ALREADY_OPEN },
133 { 57, SbERR_IO_ERROR },
134 { 58, SbERR_FILE_EXISTS },
135 { 59, SbERR_BAD_RECORD_LENGTH },
136 { 61, SbERR_DISK_FULL },
137 { 62, SbERR_READ_PAST_EOF },
138 { 63, SbERR_BAD_RECORD_NUMBER },
139 { 67, SbERR_TOO_MANY_FILES },
140 { 68, SbERR_NO_DEVICE },
141 { 70, SbERR_ACCESS_DENIED },
142 { 71, SbERR_NOT_READY },
143 { 73, SbERR_NOT_IMPLEMENTED },
144 { 74, SbERR_DIFFERENT_DRIVE },
145 { 75, SbERR_ACCESS_ERROR },
146 { 76, SbERR_PATH_NOT_FOUND },
147 { 91, SbERR_NO_OBJECT },
148 { 93, SbERR_BAD_PATTERN },
149 { 94, SBERR_IS_NULL },
150 { 250, SbERR_DDE_ERROR },
151 { 280, SbERR_DDE_WAITINGACK },
152 { 281, SbERR_DDE_OUTOFCHANNELS },
153 { 282, SbERR_DDE_NO_RESPONSE },
154 { 283, SbERR_DDE_MULT_RESPONSES },
155 { 284, SbERR_DDE_CHANNEL_LOCKED },
156 { 285, SbERR_DDE_NOTPROCESSED },
157 { 286, SbERR_DDE_TIMEOUT },
158 { 287, SbERR_DDE_USER_INTERRUPT },
159 { 288, SbERR_DDE_BUSY },
160 { 289, SbERR_DDE_NO_DATA },
161 { 290, SbERR_DDE_WRONG_DATA_FORMAT },
162 { 291, SbERR_DDE_PARTNER_QUIT },
163 { 292, SbERR_DDE_CONV_CLOSED },
164 { 293, SbERR_DDE_NO_CHANNEL },
165 { 294, SbERR_DDE_INVALID_LINK },
166 { 295, SbERR_DDE_QUEUE_OVERFLOW },
167 { 296, SbERR_DDE_LINK_ALREADY_EST },
168 { 297, SbERR_DDE_LINK_INV_TOPIC },
169 { 298, SbERR_DDE_DLL_NOT_FOUND },
170 { 323, SbERR_CANNOT_LOAD },
171 { 341, SbERR_BAD_INDEX },
172 { 366, SbERR_NO_ACTIVE_OBJECT },
173 { 380, SbERR_BAD_PROP_VALUE },
174 { 382, SbERR_PROP_READONLY },
175 { 394, SbERR_PROP_WRITEONLY },
176 { 420, SbERR_INVALID_OBJECT },
177 { 423, SbERR_NO_METHOD },
178 { 424, SbERR_NEEDS_OBJECT },
179 { 425, SbERR_INVALID_USAGE_OBJECT },
180 { 430, SbERR_NO_OLE },
181 { 438, SbERR_BAD_METHOD },
182 { 440, SbERR_OLE_ERROR },
183 { 445, SbERR_BAD_ACTION },
184 { 446, SbERR_NO_NAMED_ARGS },
185 { 447, SbERR_BAD_LOCALE },
186 { 448, SbERR_NAMED_NOT_FOUND },
187 { 449, SbERR_NOT_OPTIONAL },
188 { 450, SbERR_WRONG_ARGS },
189 { 451, SbERR_NOT_A_COLL },
190 { 452, SbERR_BAD_ORDINAL },
191 { 453, SbERR_DLLPROC_NOT_FOUND },
192 { 460, SbERR_BAD_CLIPBD_FORMAT },
193 { 951, SbERR_UNEXPECTED },
194 { 952, SbERR_EXPECTED },
195 { 953, SbERR_SYMBOL_EXPECTED },
196 { 954, SbERR_VAR_EXPECTED },
197 { 955, SbERR_LABEL_EXPECTED },
198 { 956, SbERR_LVALUE_EXPECTED },
199 { 957, SbERR_VAR_DEFINED },
200 { 958, SbERR_PROC_DEFINED },
201 { 959, SbERR_LABEL_DEFINED },
202 { 960, SbERR_UNDEF_VAR },
203 { 961, SbERR_UNDEF_ARRAY },
204 { 962, SbERR_UNDEF_PROC },
205 { 963, SbERR_UNDEF_LABEL },
206 { 964, SbERR_UNDEF_TYPE },
207 { 965, SbERR_BAD_EXIT },
208 { 966, SbERR_BAD_BLOCK },
209 { 967, SbERR_BAD_BRACKETS },
210 { 968, SbERR_BAD_DECLARATION },
211 { 969, SbERR_BAD_PARAMETERS },
212 { 970, SbERR_BAD_CHAR_IN_NUMBER },
213 { 971, SbERR_MUST_HAVE_DIMS },
214 { 972, SbERR_NO_IF },
215 { 973, SbERR_NOT_IN_SUBR },
216 { 974, SbERR_NOT_IN_MAIN },
217 { 975, SbERR_WRONG_DIMS },
218 { 976, SbERR_BAD_OPTION },
219 { 977, SbERR_CONSTANT_REDECLARED },
220 { 978, SbERR_PROG_TOO_LARGE },
221 { 979, SbERR_NO_STRINGS_ARRAYS },
222 { 1000, SbERR_PROPERTY_NOT_FOUND },
223 { 1001, SbERR_METHOD_NOT_FOUND },
224 { 1002, SbERR_ARG_MISSING },
225 { 1003, SbERR_BAD_NUMBER_OF_ARGS },
226 { 1004, SbERR_METHOD_FAILED },
227 { 1005, SbERR_SETPROP_FAILED },
228 { 1006, SbERR_GETPROP_FAILED },
229 { 1007, SbERR_BASIC_COMPAT },
230 { 0xFFFF, 0xFFFFFFFFL } // End-Marke
234 ////////////////////////////////////////////////////////////////////////////
236 // Die StarBASIC-Factory hat einen Hack. Wenn ein SbModule eingerichtet wird,
237 // wird der Pointer gespeichert und an nachfolgende SbProperties/SbMethods
238 // uebergeben. Dadurch wird die Modul-Relationship wiederhergestellt. Das
239 // klappt aber nur, wenn ein Modul geladen wird. Fuer getrennt geladene
240 // Properties kann es Probleme geben!
242 SbxBase* SbiFactory::Create( UINT16 nSbxId, UINT32 nCreator )
244 if( nCreator == SBXCR_SBX )
246 String aEmpty;
247 switch( nSbxId )
249 case SBXID_BASIC:
250 return new StarBASIC( NULL );
251 case SBXID_BASICMOD:
252 return new SbModule( aEmpty );
253 case SBXID_BASICPROP:
254 return new SbProperty( aEmpty, SbxVARIANT, NULL );
255 case SBXID_BASICMETHOD:
256 return new SbMethod( aEmpty, SbxVARIANT, NULL );
257 case SBXID_JSCRIPTMOD:
258 return new SbJScriptModule( aEmpty );
259 case SBXID_JSCRIPTMETH:
260 return new SbJScriptMethod( aEmpty, SbxVARIANT, NULL );
263 return NULL;
266 SbxObject* SbiFactory::CreateObject( const String& rClass )
268 if( rClass.EqualsIgnoreCaseAscii( "StarBASIC" ) )
269 return new StarBASIC( NULL );
270 else
271 if( rClass.EqualsIgnoreCaseAscii( "StarBASICModule" ) )
273 String aEmpty;
274 return new SbModule( aEmpty );
276 else
277 if( rClass.EqualsIgnoreCaseAscii( "Collection" ) )
279 // Only variables qualified by the Module Name e.g. Sheet1.foo
280 // should work for Documant && Class type Modules
281 String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
282 return new BasicCollection( aCollectionName );
284 else
285 return NULL;
289 // Factory class to create OLE objects
290 class SbOLEFactory : public SbxFactory
292 public:
293 virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
294 virtual SbxObject* CreateObject( const String& );
297 SbxBase* SbOLEFactory::Create( UINT16, UINT32 )
299 // Not supported
300 return NULL;
303 SbUnoObject* createOLEObject_Impl( const String& aType ); // sbunoobj.cxx
305 SbxObject* SbOLEFactory::CreateObject( const String& rClassName )
307 SbxObject* pRet = createOLEObject_Impl( rClassName );
308 return pRet;
312 // Factory class to create user defined objects (type command)
313 class SbTypeFactory : public SbxFactory
315 SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
317 public:
318 virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
319 virtual SbxObject* CreateObject( const String& );
322 SbxBase* SbTypeFactory::Create( UINT16, UINT32 )
324 // Not supported
325 return NULL;
328 SbxObject* SbTypeFactory::cloneTypeObjectImpl( const SbxObject& rTypeObj )
330 SbxObject* pRet = new SbxObject( rTypeObj );
331 pRet->PutObject( pRet );
333 // Copy the properties, not only the reference to them
334 SbxArray* pProps = pRet->GetProperties();
335 UINT32 nCount = pProps->Count32();
336 for( UINT32 i = 0 ; i < nCount ; i++ )
338 SbxVariable* pVar = pProps->Get32( i );
339 SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
340 if( pProp )
342 SbxProperty* pNewProp = new SbxProperty( *pProp );
343 if( pVar->GetType() & SbxARRAY )
345 SbxBase* pParObj = pVar->GetObject();
346 SbxDimArray* pSource = PTR_CAST(SbxDimArray,pParObj);
347 SbxDimArray* pDest = new SbxDimArray( pVar->GetType() );
348 INT32 lb = 0;
349 INT32 ub = 0;
351 pDest->setHasFixedSize( pSource->hasFixedSize() );
352 if ( pSource->GetDims() && pSource->hasFixedSize() )
354 for ( INT32 i=1; i <= pSource->GetDims(); ++i )
356 pSource->GetDim32( (INT32)i, lb, ub );
357 pDest->AddDim32( lb, ub );
360 else
361 pDest->unoAddDim( 0, -1 ); // variant array
362 USHORT nSavFlags = pVar->GetFlags();
363 pNewProp->ResetFlag( SBX_FIXED );
364 // need to reset the FIXED flag
365 // when calling PutObject ( because the type will not match Object )
366 pNewProp->PutObject( pDest );
367 pNewProp->SetFlags( nSavFlags );
369 pProps->PutDirect( pNewProp, i );
372 return pRet;
375 SbxObject* SbTypeFactory::CreateObject( const String& rClassName )
377 SbxObject* pRet = NULL;
378 SbModule* pMod = pMOD;
379 if( pMod )
381 const SbxObject* pObj = pMod->FindType( rClassName );
382 if( pObj )
383 pRet = cloneTypeObjectImpl( *pObj );
385 return pRet;
388 SbxObject* createUserTypeImpl( const String& rClassName )
390 SbxObject* pRetObj = pTYPEFAC->CreateObject( rClassName );
391 return pRetObj;
394 TYPEINIT1(SbClassModuleObject,SbModule)
396 SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule )
397 : SbModule( pClassModule->GetName() )
398 , mpClassModule( pClassModule )
399 , mbInitializeEventDone( false )
401 aOUSource = pClassModule->aOUSource;
402 aComment = pClassModule->aComment;
403 pImage = pClassModule->pImage;
404 pBreaks = pClassModule->pBreaks;
406 SetClassName( pClassModule->GetName() );
408 // Allow search only internally
409 ResetFlag( SBX_GBLSEARCH );
411 // Copy the methods from original class module
412 SbxArray* pClassMethods = pClassModule->GetMethods();
413 UINT32 nMethodCount = pClassMethods->Count32();
414 UINT32 i;
415 for( i = 0 ; i < nMethodCount ; i++ )
417 SbxVariable* pVar = pClassMethods->Get32( i );
419 // Exclude SbIfaceMapperMethod to copy them in a second step
420 SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
421 if( !pIfaceMethod )
423 SbMethod* pMethod = PTR_CAST(SbMethod, pVar );
424 if( pMethod )
426 USHORT nFlags_ = pMethod->GetFlags();
427 pMethod->SetFlag( SBX_NO_BROADCAST );
428 SbMethod* pNewMethod = new SbMethod( *pMethod );
429 pNewMethod->ResetFlag( SBX_NO_BROADCAST );
430 pMethod->SetFlags( nFlags_ );
431 pNewMethod->pMod = this;
432 pNewMethod->SetParent( this );
433 pMethods->PutDirect( pNewMethod, i );
434 StartListening( pNewMethod->GetBroadcaster(), TRUE );
439 // Copy SbIfaceMapperMethod in a second step to ensure that
440 // the corresponding base methods have already been copied
441 for( i = 0 ; i < nMethodCount ; i++ )
443 SbxVariable* pVar = pClassMethods->Get32( i );
445 SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
446 if( pIfaceMethod )
448 SbMethod* pImplMethod = pIfaceMethod->getImplMethod();
449 if( !pImplMethod )
451 DBG_ERROR( "No ImplMethod" );
452 continue;
455 // Search for own copy of ImplMethod
456 String aImplMethodName = pImplMethod->GetName();
457 SbxVariable* p = pMethods->Find( aImplMethodName, SbxCLASS_METHOD );
458 SbMethod* pImplMethodCopy = p ? PTR_CAST(SbMethod,p) : NULL;
459 if( !pImplMethodCopy )
461 DBG_ERROR( "Found no ImplMethod copy" );
462 continue;
464 SbIfaceMapperMethod* pNewIfaceMethod =
465 new SbIfaceMapperMethod( pIfaceMethod->GetName(), pImplMethodCopy );
466 pMethods->PutDirect( pNewIfaceMethod, i );
470 // Copy the properties from original class module
471 SbxArray* pClassProps = pClassModule->GetProperties();
472 UINT32 nPropertyCount = pClassProps->Count32();
473 for( i = 0 ; i < nPropertyCount ; i++ )
475 SbxVariable* pVar = pClassProps->Get32( i );
476 SbProcedureProperty* pProcedureProp = PTR_CAST( SbProcedureProperty, pVar );
477 if( pProcedureProp )
479 USHORT nFlags_ = pProcedureProp->GetFlags();
480 pProcedureProp->SetFlag( SBX_NO_BROADCAST );
481 SbProcedureProperty* pNewProp = new SbProcedureProperty
482 ( pProcedureProp->GetName(), pProcedureProp->GetType() );
483 // ( pProcedureProp->GetName(), pProcedureProp->GetType(), this );
484 pNewProp->SetFlags( nFlags_ ); // Copy flags
485 pNewProp->ResetFlag( SBX_NO_BROADCAST ); // except the Broadcast if it was set
486 pProcedureProp->SetFlags( nFlags_ );
487 pProps->PutDirect( pNewProp, i );
488 StartListening( pNewProp->GetBroadcaster(), TRUE );
490 else
492 SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
493 if( pProp )
495 USHORT nFlags_ = pProp->GetFlags();
496 pProp->SetFlag( SBX_NO_BROADCAST );
497 SbxProperty* pNewProp = new SbxProperty( *pProp );
498 pNewProp->ResetFlag( SBX_NO_BROADCAST );
499 pNewProp->SetParent( this );
500 pProps->PutDirect( pNewProp, i );
501 pProp->SetFlags( nFlags_ );
505 SetModuleType( com::sun::star::script::ModuleType::Class );
508 SbClassModuleObject::~SbClassModuleObject()
510 triggerTerminateEvent();
512 // Must be deleted by base class dtor because this data
513 // is not owned by the SbClassModuleObject object
514 pImage = NULL;
515 pBreaks = NULL;
518 void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
519 const SfxHint& rHint, const TypeId& rHintType )
521 SbModule::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
524 SbxVariable* SbClassModuleObject::Find( const XubString& rName, SbxClassType t )
526 SbxVariable* pRes = SbxObject::Find( rName, t );
527 if( pRes )
529 triggerInitializeEvent();
531 SbIfaceMapperMethod* pIfaceMapperMethod = PTR_CAST(SbIfaceMapperMethod,pRes);
532 if( pIfaceMapperMethod )
534 pRes = pIfaceMapperMethod->getImplMethod();
535 pRes->SetFlag( SBX_EXTFOUND );
538 return pRes;
541 void SbClassModuleObject::triggerInitializeEvent( void )
543 static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Initialize") );
545 if( mbInitializeEventDone )
546 return;
548 mbInitializeEventDone = true;
550 // Search method
551 SbxVariable* pMeth = SbxObject::Find( aInitMethodName, SbxCLASS_METHOD );
552 if( pMeth )
554 SbxValues aVals;
555 pMeth->Get( aVals );
559 void SbClassModuleObject::triggerTerminateEvent( void )
561 static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Terminate") );
563 if( !mbInitializeEventDone || GetSbData()->bRunInit )
564 return;
566 // Search method
567 SbxVariable* pMeth = SbxObject::Find( aTermMethodName, SbxCLASS_METHOD );
568 if( pMeth )
570 SbxValues aVals;
571 pMeth->Get( aVals );
576 SbClassData::SbClassData( void )
578 mxIfaces = new SbxArray();
581 void SbClassData::clear( void )
583 mxIfaces->Clear();
586 SbClassFactory::SbClassFactory( void )
588 String aDummyName;
589 xClassModules = new SbxObject( aDummyName );
592 SbClassFactory::~SbClassFactory()
595 void SbClassFactory::AddClassModule( SbModule* pClassModule )
597 SbxObject* pParent = pClassModule->GetParent();
598 xClassModules->Insert( pClassModule );
599 pClassModule->SetParent( pParent );
602 void SbClassFactory::RemoveClassModule( SbModule* pClassModule )
604 xClassModules->Remove( pClassModule );
607 SbxBase* SbClassFactory::Create( UINT16, UINT32 )
609 // Not supported
610 return NULL;
613 SbxObject* SbClassFactory::CreateObject( const String& rClassName )
615 SbxVariable* pVar = xClassModules->Find( rClassName, SbxCLASS_DONTCARE );
616 SbxObject* pRet = NULL;
617 if( pVar )
619 SbModule* pMod = (SbModule*)pVar;
620 pRet = new SbClassModuleObject( pMod );
622 return pRet;
625 SbModule* SbClassFactory::FindClass( const String& rClassName )
627 SbxVariable* pVar = xClassModules->Find( rClassName, SbxCLASS_DONTCARE );
628 SbModule* pMod = pVar ? (SbModule*)pVar : NULL;
629 return pMod;
633 ////////////////////////////////////////////////////////////////////////////
635 StarBASIC::StarBASIC( StarBASIC* p, BOOL bIsDocBasic )
636 : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASIC") ) ), bDocBasic( bIsDocBasic )
638 SetParent( p );
639 pLibInfo = NULL;
640 bNoRtl = bBreak = FALSE;
641 bVBAEnabled = FALSE;
642 pModules = new SbxArray;
644 if( !GetSbData()->nInst++ )
646 pSBFAC = new SbiFactory;
647 AddFactory( pSBFAC );
648 pUNOFAC = new SbUnoFactory;
649 AddFactory( pUNOFAC );
650 pTYPEFAC = new SbTypeFactory;
651 AddFactory( pTYPEFAC );
652 pCLASSFAC = new SbClassFactory;
653 AddFactory( pCLASSFAC );
654 pOLEFAC = new SbOLEFactory;
655 AddFactory( pOLEFAC );
657 pRtl = new SbiStdObject( String( RTL_CONSTASCII_USTRINGPARAM(RTLNAME) ), this );
658 // Suche ueber StarBASIC ist immer global
659 SetFlag( SBX_GBLSEARCH );
660 pVBAGlobals = NULL;
661 bQuit = FALSE;
664 // #51727 SetModified ueberladen, damit der Modified-
665 // Zustand nicht an den Parent weitergegeben wird.
666 void StarBASIC::SetModified( BOOL b )
668 SbxBase::SetModified( b );
671 //***
673 StarBASIC::~StarBASIC()
675 if( !--GetSbData()->nInst )
677 RemoveFactory( pSBFAC );
678 pSBFAC = NULL;
679 RemoveFactory( pUNOFAC );
680 pUNOFAC = NULL;
681 RemoveFactory( pTYPEFAC );
682 pTYPEFAC = NULL;
683 RemoveFactory( pCLASSFAC );
684 pCLASSFAC = NULL;
685 RemoveFactory( pOLEFAC );
686 pOLEFAC = NULL;
688 #ifdef DBG_UTIL
689 // SbiData braucht am Programm-Ende nicht abgeraeumt werden,
690 // aber wir wollen keine MLK's beim Purify
691 // Wo sollte es sonst geschehen???
692 SbiGlobals** pp = (SbiGlobals**) ::GetAppData( SHL_SBC );
693 SbiGlobals* p = *pp;
694 if( p )
696 delete p;
697 *pp = 0;
699 #endif
702 // #100326 Set Parent NULL in registered listeners
703 if( xUnoListeners.Is() )
705 USHORT uCount = xUnoListeners->Count();
706 for( USHORT i = 0 ; i < uCount ; i++ )
708 SbxVariable* pListenerObj = xUnoListeners->Get( i );
709 pListenerObj->SetParent( NULL );
711 xUnoListeners = NULL;
715 // operator new() wird hier versenkt, damit jeder eine Instanz
716 // anlegen kann, ohne neu zu bilden.
718 void* StarBASIC::operator new( size_t n )
720 if( n < sizeof( StarBASIC ) )
722 // DBG_ASSERT( FALSE, "Warnung: inkompatibler BASIC-Stand!" );
723 n = sizeof( StarBASIC );
725 return ::operator new( n );
728 void StarBASIC::operator delete( void* p )
730 ::operator delete( p );
733 /**************************************************************************
735 * Erzeugen/Verwalten von Modulen
737 **************************************************************************/
739 SbModule* StarBASIC::MakeModule( const String& rName, const String& rSrc )
741 return MakeModule32( rName, rSrc );
744 SbModule* StarBASIC::MakeModule32( const String& rName, const ::rtl::OUString& rSrc )
746 ModuleInfo mInfo;
747 mInfo.ModuleSource = rSrc;
748 mInfo.ModuleType = ModuleType::Normal;
749 mInfo.ModuleName = rName;
750 return MakeModule32( mInfo );
752 SbModule* StarBASIC::MakeModule32( const ModuleInfo& mInfo )
755 OSL_TRACE("create module %s type mInfo %d", rtl::OUStringToOString( mInfo.ModuleName, RTL_TEXTENCODING_UTF8 ).getStr(), mInfo.ModuleType );
756 SbModule* p = NULL;
757 switch ( mInfo.ModuleType )
759 case ModuleType::Document:
760 // In theory we should be able to create Object modules
761 // in ordinary basic ( in vba mode thought these are create
762 // by the application/basic and not by the user )
763 p = new SbObjModule( mInfo, isVBAEnabled() );
764 break;
765 case ModuleType::Class:
766 p = new SbModule( mInfo.ModuleName, isVBAEnabled() );
767 p->SetModuleType( com::sun::star::script::ModuleType::Class );
768 break;
769 case ModuleType::Form:
770 p = new SbUserFormModule( mInfo, isVBAEnabled() );
771 break;
772 default:
773 p = new SbModule( mInfo.ModuleName, isVBAEnabled() );
776 p->SetSource32( mInfo.ModuleSource );
777 p->SetParent( this );
778 pModules->Insert( p, pModules->Count() );
779 SetModified( TRUE );
780 return p;
783 void StarBASIC::Insert( SbxVariable* pVar )
785 if( pVar->IsA( TYPE(SbModule) ) )
787 pModules->Insert( pVar, pModules->Count() );
788 pVar->SetParent( this );
789 StartListening( pVar->GetBroadcaster(), TRUE );
791 else
793 BOOL bWasModified = IsModified();
794 SbxObject::Insert( pVar );
795 if( !bWasModified && pVar->IsSet( SBX_DONTSTORE ) )
796 SetModified( FALSE );
800 void StarBASIC::Remove( SbxVariable* pVar )
802 if( pVar->IsA( TYPE(SbModule) ) )
804 // #87540 Can be last reference!
805 SbxVariableRef xVar = pVar;
806 pModules->Remove( pVar );
807 pVar->SetParent( 0 );
808 EndListening( pVar->GetBroadcaster() );
810 else
811 SbxObject::Remove( pVar );
814 BOOL StarBASIC::Compile( SbModule* pMod )
816 return pMod ? pMod->Compile() : FALSE;
819 BOOL StarBASIC::Disassemble( SbModule* pMod, String& rText )
821 rText.Erase();
822 if( pMod )
823 pMod->Disassemble( rText );
824 return BOOL( rText.Len() != 0 );
827 void StarBASIC::Clear()
829 while( pModules->Count() )
830 pModules->Remove( pModules->Count() - 1 );
833 SbModule* StarBASIC::FindModule( const String& rName )
835 for( USHORT i = 0; i < pModules->Count(); i++ )
837 SbModule* p = (SbModule*) pModules->Get( i );
838 if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
839 return p;
841 return NULL;
844 // Init-Code aller Module ausfuehren (auch in inserteten Bibliotheken)
845 void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit )
847 // Eigene Module initialisieren
848 for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
850 SbModule* pModule = (SbModule*)pModules->Get( nMod );
851 if( !pModule->IsCompiled() )
852 pModule->Compile();
854 // compile modules first then RunInit ( otherwise there is
855 // can be order dependency, e.g. classmodule A has a member
856 // of of type classmodule B and classmodule B hasn't been compiled yet )
857 for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
859 SbModule* pModule = (SbModule*)pModules->Get( nMod );
860 pModule->RunInit();
863 // Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
864 // Wenn ja, auch dort initialisieren
865 for ( USHORT nObj = 0; nObj < pObjs->Count(); nObj++ )
867 SbxVariable* pVar = pObjs->Get( nObj );
868 StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
869 if( pBasic && pBasic != pBasicNotToInit )
870 pBasic->InitAllModules();
874 // #88329 Put modules back to not initialised state to
875 // force reinitialisation at next start
876 void StarBASIC::DeInitAllModules( void )
878 // Eigene Module initialisieren
879 for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
881 SbModule* pModule = (SbModule*)pModules->Get( nMod );
882 if( pModule->pImage )
883 pModule->pImage->bInit = false;
885 // Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
886 // Wenn ja, auch dort initialisieren
887 for ( USHORT nObj = 0; nObj < pObjs->Count(); nObj++ )
889 SbxVariable* pVar = pObjs->Get( nObj );
890 StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
891 if( pBasic )
892 pBasic->DeInitAllModules();
896 // #43011 Fuer das TestTool, um globale Variablen loeschen zu koennen
897 void StarBASIC::ClearGlobalVars( void )
899 SbxArrayRef xProps( GetProperties() );
900 USHORT nPropCount = xProps->Count();
901 for ( USHORT nProp = 0 ; nProp < nPropCount ; ++nProp )
903 SbxBase* pVar = xProps->Get( nProp );
904 pVar->Clear();
906 SetModified( TRUE );
910 // Diese Implementation sucht erst innerhalb der Runtime-Library, dann
911 // nach einem Element innerhalb eines Moduls. Dieses Element kann eine
912 // Public-Variable oder ein Entrypoint sein. Wenn nicht gefunden, wird,
913 // falls nach einer Methode gesucht wird und ein Modul mit dem angege-
914 // benen Namen gefunden wurde, der Entrypoint "Main" gesucht. Wenn das
915 // auch nicht klappt, laeuft die traditionelle Suche ueber Objekte an.
917 SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t )
919 static String aMainStr( RTL_CONSTASCII_USTRINGPARAM("Main") );
921 SbxVariable* pRes = NULL;
922 SbModule* pNamed = NULL;
923 // "Extended" search in Runtime Lib
924 // aber nur, wenn SbiRuntime nicht das Flag gesetzt hat
925 if( !bNoRtl )
927 if( t == SbxCLASS_DONTCARE || t == SbxCLASS_OBJECT )
929 if( rName.EqualsIgnoreCaseAscii( RTLNAME ) )
930 pRes = pRtl;
932 if( !pRes )
933 pRes = ((SbiStdObject*) (SbxObject*) pRtl)->Find( rName, t );
934 if( pRes )
935 pRes->SetFlag( SBX_EXTFOUND );
937 // Module durchsuchen
938 if( !pRes )
939 for( USHORT i = 0; i < pModules->Count(); i++ )
941 SbModule* p = (SbModule*) pModules->Get( i );
942 if( p->IsVisible() )
944 // Modul merken fuer Main()-Aufruf
945 // oder stimmt etwa der Name ueberein?!?
946 if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
948 if( t == SbxCLASS_OBJECT || t == SbxCLASS_DONTCARE )
950 pRes = p; break;
952 pNamed = p;
954 // Only variables qualified by the Module Name e.g. Sheet1.foo
955 // should work for Documant && Class type Modules
956 INT32 nType = p->GetModuleType();
957 if ( nType == com::sun::star::script::ModuleType::Document || nType == com::sun::star::script::ModuleType::Form )
958 continue;
959 // Sonst testen, ob das Element vorhanden ist
960 // GBLSEARCH-Flag rausnehmen (wg. Rekursion)
961 USHORT nGblFlag = p->GetFlags() & SBX_GBLSEARCH;
962 p->ResetFlag( SBX_GBLSEARCH );
963 pRes = p->Find( rName, t );
964 p->SetFlag( nGblFlag );
965 if( pRes )
966 break;
969 if( !pRes && pNamed && ( t == SbxCLASS_METHOD || t == SbxCLASS_DONTCARE ) &&
970 !pNamed->GetName().EqualsIgnoreCaseAscii( aMainStr ) )
971 pRes = pNamed->Find( aMainStr, SbxCLASS_METHOD );
972 if( !pRes )
973 pRes = SbxObject::Find( rName, t );
974 return pRes;
977 BOOL StarBASIC::Call( const String& rName, SbxArray* pParam )
979 BOOL bRes = SbxObject::Call( rName, pParam );
980 if( !bRes )
982 SbxError eErr = SbxBase::GetError();
983 SbxBase::ResetError();
984 if( eErr != SbxERR_OK )
985 RTError( (SbError)eErr, 0, 0, 0 );
987 return bRes;
990 // Find-Funktion ueber Name (z.B. Abfrage aus BASIC-IDE)
991 SbxBase* StarBASIC::FindSBXInCurrentScope( const String& rName )
993 if( !pINST )
994 return NULL;
995 if( !pINST->pRun )
996 return NULL;
997 return pINST->pRun->FindElementExtern( rName );
1000 // Alte Schnittstelle vorerst erhalten
1001 SbxVariable* StarBASIC::FindVarInCurrentScopy
1002 ( const String& rName, USHORT& rStatus )
1004 rStatus = 1; // Annahme: Nichts gefunden
1005 SbxVariable* pVar = NULL;
1006 SbxBase* pSbx = FindSBXInCurrentScope( rName );
1007 if( pSbx )
1009 if( !pSbx->ISA(SbxMethod) && !pSbx->ISA(SbxObject) )
1010 pVar = PTR_CAST(SbxVariable,pSbx);
1012 if( pVar )
1013 rStatus = 0; // doch gefunden
1014 return pVar;
1017 void StarBASIC::QuitAndExitApplication()
1019 Stop();
1020 bQuit = TRUE;
1023 void StarBASIC::Stop()
1025 SbiInstance* p = pINST;
1026 while( p )
1028 p->Stop();
1029 p = p->pNext;
1033 BOOL StarBASIC::IsRunning()
1035 return BOOL( pINST != NULL );
1038 /**************************************************************************
1040 * Objekt-Factories etc.
1042 **************************************************************************/
1044 // Aktivierung eines Objekts. Aktive Objekte muessen nicht mehr
1045 // von BASIC aus ueber den Namen angesprochen werden. Ist
1046 // NULL angegeben, wird alles aktiviert.
1048 void StarBASIC::ActivateObject( const String* pName, BOOL bActivate )
1050 if( pName )
1052 SbxObject* p = (SbxObject*) SbxObject::Find( *pName, SbxCLASS_OBJECT );
1053 if( p )
1055 if( bActivate )
1056 p->SetFlag( SBX_EXTSEARCH );
1057 else
1058 p->ResetFlag( SBX_EXTSEARCH );
1061 else
1063 for( USHORT i = 0; i < GetObjects()->Count(); i++ )
1065 SbxObject* p = (SbxObject*) GetObjects()->Get( i );
1066 if( bActivate )
1067 p->SetFlag( SBX_EXTSEARCH );
1068 else
1069 p->ResetFlag( SBX_EXTSEARCH );
1074 /**************************************************************************
1076 * Debugging und Fehlerbehandlung
1078 **************************************************************************/
1080 SbMethod* StarBASIC::GetActiveMethod( USHORT nLevel )
1082 if( pINST )
1083 return pINST->GetCaller( nLevel );
1084 else
1085 return NULL;
1088 SbModule* StarBASIC::GetActiveModule()
1090 if( pINST && !IsCompilerError() )
1091 return pINST->GetActiveModule();
1092 else
1093 return pCMOD;
1096 USHORT StarBASIC::BreakPoint( USHORT l, USHORT c1, USHORT c2 )
1098 SetErrorData( 0, l, c1, c2 );
1099 bBreak = TRUE;
1100 if( GetSbData()->aBreakHdl.IsSet() )
1101 return (USHORT) GetSbData()->aBreakHdl.Call( this );
1102 else
1103 return BreakHdl();
1106 USHORT StarBASIC::StepPoint( USHORT l, USHORT c1, USHORT c2 )
1108 SetErrorData( 0, l, c1, c2 );
1109 bBreak = FALSE;
1110 if( GetSbData()->aBreakHdl.IsSet() )
1111 return (USHORT) GetSbData()->aBreakHdl.Call( this );
1112 else
1113 return BreakHdl();
1116 USHORT __EXPORT StarBASIC::BreakHdl()
1118 return (USHORT) ( aBreakHdl.IsSet()
1119 ? aBreakHdl.Call( this ) : SbDEBUG_CONTINUE );
1122 // Abfragen fuer den Error-Handler und den Break-Handler:
1123 USHORT StarBASIC::GetLine() { return GetSbData()->nLine; }
1124 USHORT StarBASIC::GetCol1() { return GetSbData()->nCol1; }
1125 USHORT StarBASIC::GetCol2() { return GetSbData()->nCol2; }
1127 // Spezifisch fuer den Error-Handler:
1128 SbError StarBASIC::GetErrorCode() { return GetSbData()->nCode; }
1129 const String& StarBASIC::GetErrorText() { return GetSbData()->aErrMsg; }
1130 BOOL StarBASIC::IsCompilerError() { return GetSbData()->bCompiler; }
1131 void StarBASIC::SetGlobalLanguageMode( SbLanguageMode eLanguageMode )
1133 GetSbData()->eLanguageMode = eLanguageMode;
1135 SbLanguageMode StarBASIC::GetGlobalLanguageMode()
1137 return GetSbData()->eLanguageMode;
1139 // Lokale Einstellung
1140 SbLanguageMode StarBASIC::GetLanguageMode()
1142 // Globale Einstellung nehmen?
1143 if( eLanguageMode == SB_LANG_GLOBAL )
1144 return GetSbData()->eLanguageMode;
1145 else
1146 return eLanguageMode;
1149 // AB: 29.3.96
1150 // Das Mapping zwischen alten und neuen Fehlercodes erfolgt, indem die Tabelle
1151 // SFX_VB_ErrorTab[] durchsucht wird. Dies ist zwar nicht besonders performant,
1152 // verbraucht aber viel weniger Speicher als entsprechende switch-Bloecke.
1153 // Die Umrechnung von Fehlercodes muss nicht schnell sein, daher auch keine
1154 // binaere Suche bei VB-Error -> SFX-Error.
1156 // Neue Fehler-Codes auf alte, Sbx-Kompatible zurueckmappen
1157 USHORT StarBASIC::GetVBErrorCode( SbError nError )
1159 USHORT nRet = 0;
1161 if( SbiRuntime::isVBAEnabled() )
1163 switch( nError )
1165 case SbERR_BASIC_ARRAY_FIX:
1166 return 10;
1167 case SbERR_BASIC_STRING_OVERFLOW:
1168 return 14;
1169 case SbERR_BASIC_EXPR_TOO_COMPLEX:
1170 return 16;
1171 case SbERR_BASIC_OPER_NOT_PERFORM:
1172 return 17;
1173 case SbERR_BASIC_TOO_MANY_DLL:
1174 return 47;
1175 case SbERR_BASIC_LOOP_NOT_INIT:
1176 return 92;
1177 default:
1178 nRet = 0;
1182 // Suchschleife
1183 const SFX_VB_ErrorItem* pErrItem;
1184 USHORT nIndex = 0;
1187 pErrItem = SFX_VB_ErrorTab + nIndex;
1188 if( pErrItem->nErrorSFX == nError )
1190 nRet = pErrItem->nErrorVB;
1191 break;
1193 nIndex++;
1195 while( pErrItem->nErrorVB != 0xFFFF ); // bis End-Marke
1196 return nRet;
1199 SbError StarBASIC::GetSfxFromVBError( USHORT nError )
1201 SbError nRet = 0L;
1203 if( SbiRuntime::isVBAEnabled() )
1205 switch( nError )
1207 case 1:
1208 case 2:
1209 case 4:
1210 case 8:
1211 case 12:
1212 case 73:
1213 return 0L;
1214 case 10:
1215 return SbERR_BASIC_ARRAY_FIX;
1216 case 14:
1217 return SbERR_BASIC_STRING_OVERFLOW;
1218 case 16:
1219 return SbERR_BASIC_EXPR_TOO_COMPLEX;
1220 case 17:
1221 return SbERR_BASIC_OPER_NOT_PERFORM;
1222 case 47:
1223 return SbERR_BASIC_TOO_MANY_DLL;
1224 case 92:
1225 return SbERR_BASIC_LOOP_NOT_INIT;
1226 default:
1227 nRet = 0L;
1230 const SFX_VB_ErrorItem* pErrItem;
1231 USHORT nIndex = 0;
1234 pErrItem = SFX_VB_ErrorTab + nIndex;
1235 if( pErrItem->nErrorVB == nError )
1237 nRet = pErrItem->nErrorSFX;
1238 break;
1240 else if( pErrItem->nErrorVB > nError )
1241 break; // kann nicht mehr gefunden werden
1243 nIndex++;
1245 while( pErrItem->nErrorVB != 0xFFFF ); // bis End-Marke
1246 return nRet;
1249 // Error- / Break-Daten setzen
1250 void StarBASIC::SetErrorData
1251 ( SbError nCode, USHORT nLine, USHORT nCol1, USHORT nCol2 )
1253 SbiGlobals& aGlobals = *GetSbData();
1254 aGlobals.nCode = nCode;
1255 aGlobals.nLine = nLine;
1256 aGlobals.nCol1 = nCol1;
1257 aGlobals.nCol2 = nCol2;
1260 //----------------------------------------------------------------
1261 // Hilfsklasse zum Zugriff auf String SubResourcen einer Resource.
1262 // Quelle: sfx2\source\doc\docfile.cxx (TLX)
1263 struct BasicStringList_Impl : private Resource
1265 ResId aResId;
1267 BasicStringList_Impl( ResId& rErrIdP, USHORT nId)
1268 : Resource( rErrIdP ),aResId(nId, *rErrIdP.GetResMgr() ){}
1269 ~BasicStringList_Impl() { FreeResource(); }
1271 String GetString(){ return String( aResId ); }
1272 BOOL IsErrorTextAvailable( void )
1273 { return IsAvailableRes(aResId.SetRT(RSC_STRING)); }
1275 //----------------------------------------------------------------
1277 // #60175 Flag, das bei Basic-Fehlern das Anziehen der SFX-Resourcen verhindert
1278 static BOOL bStaticSuppressSfxResource = FALSE;
1280 void StarBASIC::StaticSuppressSfxResource( BOOL bSuppress )
1282 bStaticSuppressSfxResource = bSuppress;
1285 // Hack for #83750, use bStaticSuppressSfxResource as setup flag
1286 BOOL runsInSetup( void )
1288 return bStaticSuppressSfxResource;
1292 void StarBASIC::MakeErrorText( SbError nId, const String& aMsg )
1294 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1296 if( bStaticSuppressSfxResource )
1298 GetSbData()->aErrMsg = String( RTL_CONSTASCII_USTRINGPARAM("No resource: Error message not available") );
1299 return;
1302 USHORT nOldID = GetVBErrorCode( nId );
1304 // Hilfsklasse instanzieren
1305 BasResId aId( RID_BASIC_START );
1306 BasicStringList_Impl aMyStringList( aId, USHORT(nId & ERRCODE_RES_MASK) );
1308 if( aMyStringList.IsErrorTextAvailable() )
1310 // Merge Message mit Zusatztext
1311 String aMsg1 = aMyStringList.GetString();
1312 // Argument-Platzhalter durch %s ersetzen
1313 String aSrgStr( RTL_CONSTASCII_USTRINGPARAM("$(ARG1)") );
1314 USHORT nResult = aMsg1.Search( aSrgStr );
1316 if( nResult != STRING_NOTFOUND )
1318 aMsg1.Erase( nResult, aSrgStr.Len() );
1319 aMsg1.Insert( aMsg, nResult );
1321 GetSbData()->aErrMsg = aMsg1;
1323 else if( nOldID != 0 )
1325 String aStdMsg( RTL_CONSTASCII_USTRINGPARAM("Fehler ") );
1326 aStdMsg += String::CreateFromInt32( nOldID);
1327 aStdMsg += String( RTL_CONSTASCII_USTRINGPARAM(": Kein Fehlertext verfuegbar!") );
1328 GetSbData()->aErrMsg = aStdMsg;
1330 else
1331 GetSbData()->aErrMsg = String::EmptyString();
1334 BOOL StarBASIC::CError
1335 ( SbError code, const String& rMsg, USHORT l, USHORT c1, USHORT c2 )
1337 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1339 // Compiler-Fehler waehrend der Laufzeit -> Programm anhalten
1340 if( IsRunning() )
1342 // #109018 Check if running Basic is affected
1343 StarBASIC* pStartedBasic = pINST->GetBasic();
1344 if( pStartedBasic != this )
1345 return FALSE;
1347 Stop();
1350 // Flag setzen, damit GlobalRunInit den Fehler mitbekommt
1351 GetSbData()->bGlobalInitErr = TRUE;
1353 // Fehlertext basteln
1354 MakeErrorText( code, rMsg );
1356 // Umsetzung des Codes fuer String-Transport in SFX-Error
1357 if( rMsg.Len() )
1358 code = (ULONG)*new StringErrorInfo( code, String(rMsg) );
1360 SetErrorData( code, l, c1, c2 );
1361 GetSbData()->bCompiler = TRUE;
1362 BOOL bRet;
1363 if( GetSbData()->aErrHdl.IsSet() )
1364 bRet = (BOOL) GetSbData()->aErrHdl.Call( this );
1365 else
1366 bRet = ErrorHdl();
1367 GetSbData()->bCompiler = FALSE; // nur TRUE fuer Error-Handler
1368 return bRet;
1371 BOOL StarBASIC::RTError
1372 ( SbError code, USHORT l, USHORT c1, USHORT c2 )
1374 return RTError( code, String(), l, c1, c2 );
1377 BOOL StarBASIC::RTError( SbError code, const String& rMsg, USHORT l, USHORT c1, USHORT c2 )
1379 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1381 SbError c = code;
1382 if( (c & ERRCODE_CLASS_MASK) == ERRCODE_CLASS_COMPILER )
1383 c = 0;
1384 MakeErrorText( c, rMsg );
1386 // Umsetzung des Codes fuer String-Transport in SFX-Error
1387 if( rMsg.Len() )
1388 code = (ULONG)*new StringErrorInfo( code, String(rMsg) );
1390 SetErrorData( code, l, c1, c2 );
1391 if( GetSbData()->aErrHdl.IsSet() )
1392 return (BOOL) GetSbData()->aErrHdl.Call( this );
1393 else
1394 return ErrorHdl();
1397 void StarBASIC::Error( SbError n )
1399 Error( n, String() );
1402 void StarBASIC::Error( SbError n, const String& rMsg )
1404 if( pINST )
1405 pINST->Error( n, rMsg );
1408 void StarBASIC::FatalError( SbError n )
1410 if( pINST )
1411 pINST->FatalError( n );
1414 SbError StarBASIC::GetErrBasic()
1416 if( pINST )
1417 return pINST->GetErr();
1418 else
1419 return 0;
1422 // #66536 Zusatz-Message fuer RTL-Funktion Error zugreifbar machen
1423 String StarBASIC::GetErrorMsg()
1425 if( pINST )
1426 return pINST->GetErrorMsg();
1427 else
1428 return String();
1431 USHORT StarBASIC::GetErl()
1433 if( pINST )
1434 return pINST->GetErl();
1435 else
1436 return 0;
1439 BOOL __EXPORT StarBASIC::ErrorHdl()
1441 return (BOOL) ( aErrorHdl.IsSet()
1442 ? aErrorHdl.Call( this ) : FALSE );
1445 Link StarBASIC::GetGlobalErrorHdl()
1447 return GetSbData()->aErrHdl;
1450 void StarBASIC::SetGlobalErrorHdl( const Link& rLink )
1452 GetSbData()->aErrHdl = rLink;
1456 Link StarBASIC::GetGlobalBreakHdl()
1458 return GetSbData()->aBreakHdl;
1461 void StarBASIC::SetGlobalBreakHdl( const Link& rLink )
1463 GetSbData()->aBreakHdl = rLink;
1466 SbxArrayRef StarBASIC::getUnoListeners( void )
1468 if( !xUnoListeners.Is() )
1469 xUnoListeners = new SbxArray();
1470 return xUnoListeners;
1474 /**************************************************************************
1476 * Laden und Speichern
1478 **************************************************************************/
1480 BOOL StarBASIC::LoadData( SvStream& r, USHORT nVer )
1482 if( !SbxObject::LoadData( r, nVer ) )
1483 return FALSE;
1485 // #95459 Delete dialogs, otherwise endless recursion
1486 // in SbxVarable::GetType() if dialogs are accessed
1487 USHORT nObjCount = pObjs->Count();
1488 SbxVariable** ppDeleteTab = new SbxVariable*[ nObjCount ];
1489 USHORT nObj;
1491 for( nObj = 0 ; nObj < nObjCount ; nObj++ )
1493 SbxVariable* pVar = pObjs->Get( nObj );
1494 StarBASIC* pBasic = PTR_CAST( StarBASIC, pVar );
1495 ppDeleteTab[nObj] = pBasic ? NULL : pVar;
1497 for( nObj = 0 ; nObj < nObjCount ; nObj++ )
1499 SbxVariable* pVar = ppDeleteTab[nObj];
1500 if( pVar )
1501 pObjs->Remove( pVar );
1503 delete[] ppDeleteTab;
1505 UINT16 nMod;
1506 pModules->Clear();
1507 r >> nMod;
1508 for( USHORT i = 0; i < nMod; i++ )
1510 SbModule* pMod = (SbModule*) SbxBase::Load( r );
1511 if( !pMod )
1512 return FALSE;
1513 else if( pMod->ISA(SbJScriptModule) )
1515 // Ref zuweisen, damit pMod deleted wird
1516 SbModuleRef xRef = pMod;
1518 else
1520 pMod->SetParent( this );
1521 pModules->Put( pMod, i );
1524 // HACK fuer SFX-Mist!
1525 SbxVariable* p = Find( String( RTL_CONSTASCII_USTRINGPARAM("FALSE") ), SbxCLASS_PROPERTY );
1526 if( p )
1527 Remove( p );
1528 p = Find( String( RTL_CONSTASCII_USTRINGPARAM("TRUE") ), SbxCLASS_PROPERTY );
1529 if( p )
1530 Remove( p );
1531 // Ende des Hacks!
1532 // Suche ueber StarBASIC ist immer global
1533 DBG_ASSERT( IsSet( SBX_GBLSEARCH ), "Basic ohne GBLSEARCH geladen" );
1534 SetFlag( SBX_GBLSEARCH );
1535 return TRUE;
1538 BOOL StarBASIC::StoreData( SvStream& r ) const
1540 if( !SbxObject::StoreData( r ) )
1541 return FALSE;
1542 r << (UINT16) pModules->Count();
1543 for( USHORT i = 0; i < pModules->Count(); i++ )
1545 SbModule* p = (SbModule*) pModules->Get( i );
1546 if( !p->Store( r ) )
1547 return FALSE;
1549 return TRUE;
1552 BOOL StarBASIC::LoadOldModules( SvStream& )
1554 return FALSE;
1557 bool StarBASIC::GetUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
1559 bool bRes = false;
1560 ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
1561 SbUnoObject* pGlobs = dynamic_cast<SbUnoObject*>( Find( sVarName, SbxCLASS_DONTCARE ) );
1562 if ( pGlobs )
1564 aOut = pGlobs->getUnoAny();
1565 bRes = true;
1567 return bRes;
1570 //========================================================================
1571 // #118116 Implementation Collection object
1573 TYPEINIT1(BasicCollection,SbxObject)
1575 static const char pCountStr[] = "Count";
1576 static const char pAddStr[] = "Add";
1577 static const char pItemStr[] = "Item";
1578 static const char pRemoveStr[] = "Remove";
1579 static USHORT nCountHash = 0, nAddHash, nItemHash, nRemoveHash;
1581 SbxInfoRef BasicCollection::xAddInfo = NULL;
1582 SbxInfoRef BasicCollection::xItemInfo = NULL;
1584 BasicCollection::BasicCollection( const XubString& rClass )
1585 : SbxObject( rClass )
1587 if( !nCountHash )
1589 nCountHash = MakeHashCode( String::CreateFromAscii( pCountStr ) );
1590 nAddHash = MakeHashCode( String::CreateFromAscii( pAddStr ) );
1591 nItemHash = MakeHashCode( String::CreateFromAscii( pItemStr ) );
1592 nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemoveStr ) );
1594 Initialize();
1598 BasicCollection::~BasicCollection()
1601 void BasicCollection::Clear()
1603 SbxObject::Clear();
1604 Initialize();
1607 void BasicCollection::Initialize()
1609 xItemArray = new SbxArray();
1610 SetType( SbxOBJECT );
1611 SetFlag( SBX_FIXED );
1612 ResetFlag( SBX_WRITE );
1613 SbxVariable* p;
1614 p = Make( String::CreateFromAscii( pCountStr ), SbxCLASS_PROPERTY, SbxINTEGER );
1615 p->ResetFlag( SBX_WRITE );
1616 p->SetFlag( SBX_DONTSTORE );
1617 p = Make( String::CreateFromAscii( pAddStr ), SbxCLASS_METHOD, SbxEMPTY );
1618 p->SetFlag( SBX_DONTSTORE );
1619 p = Make( String::CreateFromAscii( pItemStr ), SbxCLASS_METHOD, SbxVARIANT );
1620 p->SetFlag( SBX_DONTSTORE );
1621 p = Make( String::CreateFromAscii( pRemoveStr ), SbxCLASS_METHOD, SbxEMPTY );
1622 p->SetFlag( SBX_DONTSTORE );
1623 if ( !xAddInfo.Is() )
1625 xAddInfo = new SbxInfo;
1626 xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Item") ), SbxVARIANT, SBX_READ );
1627 xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Key") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
1628 xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Before") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
1629 xAddInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("After") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
1631 if ( !xItemInfo.Is() )
1633 xItemInfo = new SbxInfo;
1634 xItemInfo->AddParam( String( RTL_CONSTASCII_USTRINGPARAM("Index") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL);
1638 SbxVariable* BasicCollection::Find( const XubString& rName, SbxClassType t )
1640 SbxVariable* pFind = SbxObject::Find( rName, t );
1641 return pFind;
1644 void BasicCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1,
1645 const SfxHint& rHint, const TypeId& rId2 )
1647 const SbxHint* p = PTR_CAST(SbxHint,&rHint);
1648 if( p )
1650 ULONG nId = p->GetId();
1651 BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
1652 BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
1653 BOOL bRequestInfo = BOOL( nId == SBX_HINT_INFOWANTED );
1654 SbxVariable* pVar = p->GetVar();
1655 SbxArray* pArg = pVar->GetParameters();
1656 XubString aVarName( pVar->GetName() );
1657 if( bRead || bWrite )
1659 if( pVar->GetHashCode() == nCountHash
1660 && aVarName.EqualsIgnoreCaseAscii( pCountStr ) )
1661 pVar->PutLong( xItemArray->Count32() );
1662 else if( pVar->GetHashCode() == nAddHash
1663 && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
1664 CollAdd( pArg );
1665 else if( pVar->GetHashCode() == nItemHash
1666 && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
1667 CollItem( pArg );
1668 else if( pVar->GetHashCode() == nRemoveHash
1669 && aVarName.EqualsIgnoreCaseAscii( pRemoveStr ) )
1670 CollRemove( pArg );
1671 else
1672 SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
1673 return;
1675 else if ( bRequestInfo )
1677 if( pVar->GetHashCode() == nAddHash
1678 && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
1679 pVar->SetInfo( xAddInfo );
1680 else if( pVar->GetHashCode() == nItemHash
1681 && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
1682 pVar->SetInfo( xItemInfo );
1685 SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
1688 INT32 BasicCollection::implGetIndex( SbxVariable* pIndexVar )
1690 INT32 nIndex = -1;
1691 if( pIndexVar->GetType() == SbxSTRING )
1692 nIndex = implGetIndexForName( pIndexVar->GetString() );
1693 else
1694 nIndex = pIndexVar->GetLong() - 1;
1695 return nIndex;
1698 INT32 BasicCollection::implGetIndexForName( const String& rName )
1700 INT32 nIndex = -1;
1701 INT32 nCount = xItemArray->Count32();
1702 INT32 nNameHash = MakeHashCode( rName );
1703 for( INT32 i = 0 ; i < nCount ; i++ )
1705 SbxVariable* pVar = xItemArray->Get32( i );
1706 if( pVar->GetHashCode() == nNameHash &&
1707 pVar->GetName().EqualsIgnoreCaseAscii( rName ) )
1709 nIndex = i;
1710 break;
1713 return nIndex;
1716 void BasicCollection::CollAdd( SbxArray* pPar_ )
1718 USHORT nCount = pPar_->Count();
1719 if( nCount < 2 || nCount > 5 )
1721 SetError( SbxERR_WRONG_ARGS );
1722 return;
1725 SbxVariable* pItem = pPar_->Get(1);
1726 if( pItem )
1728 int nNextIndex;
1729 if( nCount < 4 )
1731 nNextIndex = xItemArray->Count();
1733 else
1735 SbxVariable* pBefore = pPar_->Get(3);
1736 if( nCount == 5 )
1738 if( !( pBefore->IsErr() || ( pBefore->GetType() == SbxEMPTY ) ) )
1740 SetError( SbERR_BAD_ARGUMENT );
1741 return;
1743 SbxVariable* pAfter = pPar_->Get(4);
1744 INT32 nAfterIndex = implGetIndex( pAfter );
1745 if( nAfterIndex == -1 )
1747 SetError( SbERR_BAD_ARGUMENT );
1748 return;
1750 nNextIndex = nAfterIndex + 1;
1752 else // if( nCount == 4 )
1754 INT32 nBeforeIndex = implGetIndex( pBefore );
1755 if( nBeforeIndex == -1 )
1757 SetError( SbERR_BAD_ARGUMENT );
1758 return;
1760 nNextIndex = nBeforeIndex;
1764 SbxVariableRef pNewItem = new SbxVariable( *pItem );
1765 if( nCount >= 3 )
1767 SbxVariable* pKey = pPar_->Get(2);
1768 if( !( pKey->IsErr() || ( pKey->GetType() == SbxEMPTY ) ) )
1770 if( pKey->GetType() != SbxSTRING )
1772 SetError( SbERR_BAD_ARGUMENT );
1773 return;
1775 String aKey = pKey->GetString();
1776 if( implGetIndexForName( aKey ) != -1 )
1778 SetError( SbERR_BAD_ARGUMENT );
1779 return;
1781 pNewItem->SetName( aKey );
1784 pNewItem->SetFlag( SBX_READWRITE );
1785 xItemArray->Insert32( pNewItem, nNextIndex );
1787 else
1789 SetError( SbERR_BAD_ARGUMENT );
1790 return;
1794 void BasicCollection::CollItem( SbxArray* pPar_ )
1796 if( pPar_->Count() != 2 )
1798 SetError( SbxERR_WRONG_ARGS );
1799 return;
1801 SbxVariable* pRes = NULL;
1802 SbxVariable* p = pPar_->Get( 1 );
1803 INT32 nIndex = implGetIndex( p );
1804 if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() )
1805 pRes = xItemArray->Get32( nIndex );
1806 if( !pRes )
1807 SetError( SbxERR_BAD_INDEX );
1808 else
1809 *(pPar_->Get(0)) = *pRes;
1812 void BasicCollection::CollRemove( SbxArray* pPar_ )
1814 if( pPar_ == NULL || pPar_->Count() != 2 )
1816 SetError( SbxERR_WRONG_ARGS );
1817 return;
1820 SbxVariable* p = pPar_->Get( 1 );
1821 INT32 nIndex = implGetIndex( p );
1822 if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() )
1823 xItemArray->Remove32( nIndex );
1824 else
1825 SetError( SbxERR_BAD_INDEX );