1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
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"
37 #include <tools/rcid.h>
38 #include <tools/config.hxx>
39 #include <tools/stream.hxx>
40 #ifndef __RSC //autogen
41 #include <tools/errinf.hxx>
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"
53 #include "runtime.hxx"
54 #include <basic/sbuno.hxx>
55 #include <basic/sbobjmod.hxx>
57 #include "filefmt.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"
75 const static String
aThisComponent( RTL_CONSTASCII_USTRINGPARAM("ThisComponent") );
76 const static String
aVBAHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
78 SbxObject
* StarBASIC::getVBAGlobals( )
81 pVBAGlobals
= (SbUnoObject
*)Find( aVBAHook
, SbxCLASS_DONTCARE
);
86 SbxVariable
* StarBASIC::VBAFind( const String
& rName
, SbxClassType t
)
88 if( rName
== aThisComponent
)
90 // rename to init globals
91 if ( getVBAGlobals( ) )
92 return pVBAGlobals
->Find( rName
, t
);
97 //========================================================================
98 // Array zur Umrechnung SFX <-> VB-Fehlercodes anlegen
100 struct SFX_VB_ErrorItem
106 const SFX_VB_ErrorItem __FAR_DATA SFX_VB_ErrorTab
[] =
108 { 1, SbERR_BASIC_EXCEPTION
}, // #87844 Map exception to error code 1
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
)
250 return new StarBASIC( NULL
);
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
);
266 SbxObject
* SbiFactory::CreateObject( const String
& rClass
)
268 if( rClass
.EqualsIgnoreCaseAscii( "StarBASIC" ) )
269 return new StarBASIC( NULL
);
271 if( rClass
.EqualsIgnoreCaseAscii( "StarBASICModule" ) )
274 return new SbModule( aEmpty
);
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
);
289 // Factory class to create OLE objects
290 class SbOLEFactory
: public SbxFactory
293 virtual SbxBase
* Create( UINT16 nSbxId
, UINT32
= SBXCR_SBX
);
294 virtual SbxObject
* CreateObject( const String
& );
297 SbxBase
* SbOLEFactory::Create( UINT16
, UINT32
)
303 SbUnoObject
* createOLEObject_Impl( const String
& aType
); // sbunoobj.cxx
305 SbxObject
* SbOLEFactory::CreateObject( const String
& rClassName
)
307 SbxObject
* pRet
= createOLEObject_Impl( rClassName
);
312 // Factory class to create user defined objects (type command)
313 class SbTypeFactory
: public SbxFactory
315 SbxObject
* cloneTypeObjectImpl( const SbxObject
& rTypeObj
);
318 virtual SbxBase
* Create( UINT16 nSbxId
, UINT32
= SBXCR_SBX
);
319 virtual SbxObject
* CreateObject( const String
& );
322 SbxBase
* SbTypeFactory::Create( UINT16
, UINT32
)
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
);
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() );
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
);
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
);
375 SbxObject
* SbTypeFactory::CreateObject( const String
& rClassName
)
377 SbxObject
* pRet
= NULL
;
378 SbModule
* pMod
= pMOD
;
381 const SbxObject
* pObj
= pMod
->FindType( rClassName
);
383 pRet
= cloneTypeObjectImpl( *pObj
);
388 SbxObject
* createUserTypeImpl( const String
& rClassName
)
390 SbxObject
* pRetObj
= pTYPEFAC
->CreateObject( rClassName
);
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();
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
);
423 SbMethod
* pMethod
= PTR_CAST(SbMethod
, pVar
);
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
);
448 SbMethod
* pImplMethod
= pIfaceMethod
->getImplMethod();
451 DBG_ERROR( "No ImplMethod" );
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" );
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
);
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
);
492 SbxProperty
* pProp
= PTR_CAST( SbxProperty
, pVar
);
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
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
);
529 triggerInitializeEvent();
531 SbIfaceMapperMethod
* pIfaceMapperMethod
= PTR_CAST(SbIfaceMapperMethod
,pRes
);
532 if( pIfaceMapperMethod
)
534 pRes
= pIfaceMapperMethod
->getImplMethod();
535 pRes
->SetFlag( SBX_EXTFOUND
);
541 void SbClassModuleObject::triggerInitializeEvent( void )
543 static String
aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Initialize") );
545 if( mbInitializeEventDone
)
548 mbInitializeEventDone
= true;
551 SbxVariable
* pMeth
= SbxObject::Find( aInitMethodName
, SbxCLASS_METHOD
);
559 void SbClassModuleObject::triggerTerminateEvent( void )
561 static String
aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Terminate") );
563 if( !mbInitializeEventDone
|| GetSbData()->bRunInit
)
567 SbxVariable
* pMeth
= SbxObject::Find( aTermMethodName
, SbxCLASS_METHOD
);
576 SbClassData::SbClassData( void )
578 mxIfaces
= new SbxArray();
581 void SbClassData::clear( void )
586 SbClassFactory::SbClassFactory( void )
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
)
613 SbxObject
* SbClassFactory::CreateObject( const String
& rClassName
)
615 SbxVariable
* pVar
= xClassModules
->Find( rClassName
, SbxCLASS_DONTCARE
);
616 SbxObject
* pRet
= NULL
;
619 SbModule
* pMod
= (SbModule
*)pVar
;
620 pRet
= new SbClassModuleObject( pMod
);
625 SbModule
* SbClassFactory::FindClass( const String
& rClassName
)
627 SbxVariable
* pVar
= xClassModules
->Find( rClassName
, SbxCLASS_DONTCARE
);
628 SbModule
* pMod
= pVar
? (SbModule
*)pVar
: NULL
;
633 ////////////////////////////////////////////////////////////////////////////
635 StarBASIC::StarBASIC( StarBASIC
* p
, BOOL bIsDocBasic
)
636 : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASIC") ) ), bDocBasic( bIsDocBasic
)
640 bNoRtl
= bBreak
= 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
);
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
);
673 StarBASIC::~StarBASIC()
675 if( !--GetSbData()->nInst
)
677 RemoveFactory( pSBFAC
);
679 RemoveFactory( pUNOFAC
);
681 RemoveFactory( pTYPEFAC
);
683 RemoveFactory( pCLASSFAC
);
685 RemoveFactory( pOLEFAC
);
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
);
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
)
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
);
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() );
765 case ModuleType::Class
:
766 p
= new SbModule( mInfo
.ModuleName
, isVBAEnabled() );
767 p
->SetModuleType( com::sun::star::script::ModuleType::Class
);
769 case ModuleType::Form
:
770 p
= new SbUserFormModule( mInfo
, isVBAEnabled() );
773 p
= new SbModule( mInfo
.ModuleName
, isVBAEnabled() );
776 p
->SetSource32( mInfo
.ModuleSource
);
777 p
->SetParent( this );
778 pModules
->Insert( p
, pModules
->Count() );
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
);
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() );
811 SbxObject::Remove( pVar
);
814 BOOL
StarBASIC::Compile( SbModule
* pMod
)
816 return pMod
? pMod
->Compile() : FALSE
;
819 BOOL
StarBASIC::Disassemble( SbModule
* pMod
, String
& rText
)
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
) )
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() )
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
);
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
);
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
);
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
927 if( t
== SbxCLASS_DONTCARE
|| t
== SbxCLASS_OBJECT
)
929 if( rName
.EqualsIgnoreCaseAscii( RTLNAME
) )
933 pRes
= ((SbiStdObject
*) (SbxObject
*) pRtl
)->Find( rName
, t
);
935 pRes
->SetFlag( SBX_EXTFOUND
);
937 // Module durchsuchen
939 for( USHORT i
= 0; i
< pModules
->Count(); i
++ )
941 SbModule
* p
= (SbModule
*) pModules
->Get( i
);
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
)
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
)
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
);
969 if( !pRes
&& pNamed
&& ( t
== SbxCLASS_METHOD
|| t
== SbxCLASS_DONTCARE
) &&
970 !pNamed
->GetName().EqualsIgnoreCaseAscii( aMainStr
) )
971 pRes
= pNamed
->Find( aMainStr
, SbxCLASS_METHOD
);
973 pRes
= SbxObject::Find( rName
, t
);
977 BOOL
StarBASIC::Call( const String
& rName
, SbxArray
* pParam
)
979 BOOL bRes
= SbxObject::Call( rName
, pParam
);
982 SbxError eErr
= SbxBase::GetError();
983 SbxBase::ResetError();
984 if( eErr
!= SbxERR_OK
)
985 RTError( (SbError
)eErr
, 0, 0, 0 );
990 // Find-Funktion ueber Name (z.B. Abfrage aus BASIC-IDE)
991 SbxBase
* StarBASIC::FindSBXInCurrentScope( const String
& rName
)
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
);
1009 if( !pSbx
->ISA(SbxMethod
) && !pSbx
->ISA(SbxObject
) )
1010 pVar
= PTR_CAST(SbxVariable
,pSbx
);
1013 rStatus
= 0; // doch gefunden
1017 void StarBASIC::QuitAndExitApplication()
1023 void StarBASIC::Stop()
1025 SbiInstance
* p
= pINST
;
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
)
1052 SbxObject
* p
= (SbxObject
*) SbxObject::Find( *pName
, SbxCLASS_OBJECT
);
1056 p
->SetFlag( SBX_EXTSEARCH
);
1058 p
->ResetFlag( SBX_EXTSEARCH
);
1063 for( USHORT i
= 0; i
< GetObjects()->Count(); i
++ )
1065 SbxObject
* p
= (SbxObject
*) GetObjects()->Get( i
);
1067 p
->SetFlag( SBX_EXTSEARCH
);
1069 p
->ResetFlag( SBX_EXTSEARCH
);
1074 /**************************************************************************
1076 * Debugging und Fehlerbehandlung
1078 **************************************************************************/
1080 SbMethod
* StarBASIC::GetActiveMethod( USHORT nLevel
)
1083 return pINST
->GetCaller( nLevel
);
1088 SbModule
* StarBASIC::GetActiveModule()
1090 if( pINST
&& !IsCompilerError() )
1091 return pINST
->GetActiveModule();
1096 USHORT
StarBASIC::BreakPoint( USHORT l
, USHORT c1
, USHORT c2
)
1098 SetErrorData( 0, l
, c1
, c2
);
1100 if( GetSbData()->aBreakHdl
.IsSet() )
1101 return (USHORT
) GetSbData()->aBreakHdl
.Call( this );
1106 USHORT
StarBASIC::StepPoint( USHORT l
, USHORT c1
, USHORT c2
)
1108 SetErrorData( 0, l
, c1
, c2
);
1110 if( GetSbData()->aBreakHdl
.IsSet() )
1111 return (USHORT
) GetSbData()->aBreakHdl
.Call( this );
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
;
1146 return eLanguageMode
;
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
)
1161 if( SbiRuntime::isVBAEnabled() )
1165 case SbERR_BASIC_ARRAY_FIX
:
1167 case SbERR_BASIC_STRING_OVERFLOW
:
1169 case SbERR_BASIC_EXPR_TOO_COMPLEX
:
1171 case SbERR_BASIC_OPER_NOT_PERFORM
:
1173 case SbERR_BASIC_TOO_MANY_DLL
:
1175 case SbERR_BASIC_LOOP_NOT_INIT
:
1183 const SFX_VB_ErrorItem
* pErrItem
;
1187 pErrItem
= SFX_VB_ErrorTab
+ nIndex
;
1188 if( pErrItem
->nErrorSFX
== nError
)
1190 nRet
= pErrItem
->nErrorVB
;
1195 while( pErrItem
->nErrorVB
!= 0xFFFF ); // bis End-Marke
1199 SbError
StarBASIC::GetSfxFromVBError( USHORT nError
)
1203 if( SbiRuntime::isVBAEnabled() )
1215 return SbERR_BASIC_ARRAY_FIX
;
1217 return SbERR_BASIC_STRING_OVERFLOW
;
1219 return SbERR_BASIC_EXPR_TOO_COMPLEX
;
1221 return SbERR_BASIC_OPER_NOT_PERFORM
;
1223 return SbERR_BASIC_TOO_MANY_DLL
;
1225 return SbERR_BASIC_LOOP_NOT_INIT
;
1230 const SFX_VB_ErrorItem
* pErrItem
;
1234 pErrItem
= SFX_VB_ErrorTab
+ nIndex
;
1235 if( pErrItem
->nErrorVB
== nError
)
1237 nRet
= pErrItem
->nErrorSFX
;
1240 else if( pErrItem
->nErrorVB
> nError
)
1241 break; // kann nicht mehr gefunden werden
1245 while( pErrItem
->nErrorVB
!= 0xFFFF ); // bis End-Marke
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
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") );
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
;
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
1342 // #109018 Check if running Basic is affected
1343 StarBASIC
* pStartedBasic
= pINST
->GetBasic();
1344 if( pStartedBasic
!= this )
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
1358 code
= (ULONG
)*new StringErrorInfo( code
, String(rMsg
) );
1360 SetErrorData( code
, l
, c1
, c2
);
1361 GetSbData()->bCompiler
= TRUE
;
1363 if( GetSbData()->aErrHdl
.IsSet() )
1364 bRet
= (BOOL
) GetSbData()->aErrHdl
.Call( this );
1367 GetSbData()->bCompiler
= FALSE
; // nur TRUE fuer Error-Handler
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() );
1382 if( (c
& ERRCODE_CLASS_MASK
) == ERRCODE_CLASS_COMPILER
)
1384 MakeErrorText( c
, rMsg
);
1386 // Umsetzung des Codes fuer String-Transport in SFX-Error
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 );
1397 void StarBASIC::Error( SbError n
)
1399 Error( n
, String() );
1402 void StarBASIC::Error( SbError n
, const String
& rMsg
)
1405 pINST
->Error( n
, rMsg
);
1408 void StarBASIC::FatalError( SbError n
)
1411 pINST
->FatalError( n
);
1414 SbError
StarBASIC::GetErrBasic()
1417 return pINST
->GetErr();
1422 // #66536 Zusatz-Message fuer RTL-Funktion Error zugreifbar machen
1423 String
StarBASIC::GetErrorMsg()
1426 return pINST
->GetErrorMsg();
1431 USHORT
StarBASIC::GetErl()
1434 return pINST
->GetErl();
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
) )
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
];
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
];
1501 pObjs
->Remove( pVar
);
1503 delete[] ppDeleteTab
;
1508 for( USHORT i
= 0; i
< nMod
; i
++ )
1510 SbModule
* pMod
= (SbModule
*) SbxBase::Load( r
);
1513 else if( pMod
->ISA(SbJScriptModule
) )
1515 // Ref zuweisen, damit pMod deleted wird
1516 SbModuleRef xRef
= pMod
;
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
);
1528 p
= Find( String( RTL_CONSTASCII_USTRINGPARAM("TRUE") ), SbxCLASS_PROPERTY
);
1532 // Suche ueber StarBASIC ist immer global
1533 DBG_ASSERT( IsSet( SBX_GBLSEARCH
), "Basic ohne GBLSEARCH geladen" );
1534 SetFlag( SBX_GBLSEARCH
);
1538 BOOL
StarBASIC::StoreData( SvStream
& r
) const
1540 if( !SbxObject::StoreData( r
) )
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
) )
1552 BOOL
StarBASIC::LoadOldModules( SvStream
& )
1557 bool StarBASIC::GetUNOConstant( const sal_Char
* _pAsciiName
, ::com::sun::star::uno::Any
& aOut
)
1560 ::rtl::OUString
sVarName( ::rtl::OUString::createFromAscii( _pAsciiName
) );
1561 SbUnoObject
* pGlobs
= dynamic_cast<SbUnoObject
*>( Find( sVarName
, SbxCLASS_DONTCARE
) );
1564 aOut
= pGlobs
->getUnoAny();
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
)
1589 nCountHash
= MakeHashCode( String::CreateFromAscii( pCountStr
) );
1590 nAddHash
= MakeHashCode( String::CreateFromAscii( pAddStr
) );
1591 nItemHash
= MakeHashCode( String::CreateFromAscii( pItemStr
) );
1592 nRemoveHash
= MakeHashCode( String::CreateFromAscii( pRemoveStr
) );
1598 BasicCollection::~BasicCollection()
1601 void BasicCollection::Clear()
1607 void BasicCollection::Initialize()
1609 xItemArray
= new SbxArray();
1610 SetType( SbxOBJECT
);
1611 SetFlag( SBX_FIXED
);
1612 ResetFlag( SBX_WRITE
);
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
);
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
);
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
) )
1665 else if( pVar
->GetHashCode() == nItemHash
1666 && aVarName
.EqualsIgnoreCaseAscii( pItemStr
) )
1668 else if( pVar
->GetHashCode() == nRemoveHash
1669 && aVarName
.EqualsIgnoreCaseAscii( pRemoveStr
) )
1672 SbxObject::SFX_NOTIFY( rCst
, rId1
, rHint
, rId2
);
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
)
1691 if( pIndexVar
->GetType() == SbxSTRING
)
1692 nIndex
= implGetIndexForName( pIndexVar
->GetString() );
1694 nIndex
= pIndexVar
->GetLong() - 1;
1698 INT32
BasicCollection::implGetIndexForName( const String
& rName
)
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
) )
1716 void BasicCollection::CollAdd( SbxArray
* pPar_
)
1718 USHORT nCount
= pPar_
->Count();
1719 if( nCount
< 2 || nCount
> 5 )
1721 SetError( SbxERR_WRONG_ARGS
);
1725 SbxVariable
* pItem
= pPar_
->Get(1);
1731 nNextIndex
= xItemArray
->Count();
1735 SbxVariable
* pBefore
= pPar_
->Get(3);
1738 if( !( pBefore
->IsErr() || ( pBefore
->GetType() == SbxEMPTY
) ) )
1740 SetError( SbERR_BAD_ARGUMENT
);
1743 SbxVariable
* pAfter
= pPar_
->Get(4);
1744 INT32 nAfterIndex
= implGetIndex( pAfter
);
1745 if( nAfterIndex
== -1 )
1747 SetError( SbERR_BAD_ARGUMENT
);
1750 nNextIndex
= nAfterIndex
+ 1;
1752 else // if( nCount == 4 )
1754 INT32 nBeforeIndex
= implGetIndex( pBefore
);
1755 if( nBeforeIndex
== -1 )
1757 SetError( SbERR_BAD_ARGUMENT
);
1760 nNextIndex
= nBeforeIndex
;
1764 SbxVariableRef pNewItem
= new SbxVariable( *pItem
);
1767 SbxVariable
* pKey
= pPar_
->Get(2);
1768 if( !( pKey
->IsErr() || ( pKey
->GetType() == SbxEMPTY
) ) )
1770 if( pKey
->GetType() != SbxSTRING
)
1772 SetError( SbERR_BAD_ARGUMENT
);
1775 String aKey
= pKey
->GetString();
1776 if( implGetIndexForName( aKey
) != -1 )
1778 SetError( SbERR_BAD_ARGUMENT
);
1781 pNewItem
->SetName( aKey
);
1784 pNewItem
->SetFlag( SBX_READWRITE
);
1785 xItemArray
->Insert32( pNewItem
, nNextIndex
);
1789 SetError( SbERR_BAD_ARGUMENT
);
1794 void BasicCollection::CollItem( SbxArray
* pPar_
)
1796 if( pPar_
->Count() != 2 )
1798 SetError( SbxERR_WRONG_ARGS
);
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
);
1807 SetError( SbxERR_BAD_INDEX
);
1809 *(pPar_
->Get(0)) = *pRes
;
1812 void BasicCollection::CollRemove( SbxArray
* pPar_
)
1814 if( pPar_
== NULL
|| pPar_
->Count() != 2 )
1816 SetError( SbxERR_WRONG_ARGS
);
1820 SbxVariable
* p
= pPar_
->Get( 1 );
1821 INT32 nIndex
= implGetIndex( p
);
1822 if( nIndex
>= 0 && nIndex
< (INT32
)xItemArray
->Count32() )
1823 xItemArray
->Remove32( nIndex
);
1825 SetError( SbxERR_BAD_INDEX
);