1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sbxmod.cxx,v $
10 * $Revision: 1.44.10.1 $
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"
36 #include <vos/macros.hxx>
37 #include <vcl/svapp.hxx>
38 #include <tools/stream.hxx>
39 #include <svtools/brdcst.hxx>
40 #include <tools/shl.hxx>
41 #include <basic/sbx.hxx>
43 #include <sbjsmeth.hxx>
44 #include "sbjsmod.hxx"
45 #include "sbintern.hxx"
47 #include "opcodes.hxx"
48 #include "runtime.hxx"
50 #include "sbunoobj.hxx"
53 //#include <basic/hilight.hxx>
54 #include <svtools/syntaxhighlight.hxx>
56 #include <basic/basrdll.hxx>
57 #include <vos/mutex.hxx>
58 #include <basic/sbobjmod.hxx>
59 #include <com/sun/star/lang/XServiceInfo.hpp>
66 #if defined(UNX) || defined(OS2)
70 #include <sys/resource.h>
75 #include <comphelper/processfactory.hxx>
76 #include <com/sun/star/script/XLibraryContainer.hpp>
77 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
78 #include <com/sun/star/awt/XDialogProvider.hpp>
79 #include <com/sun/star/awt/XTopWindow.hpp>
80 #include <com/sun/star/awt/XControl.hpp>
81 #include <cppuhelper/implbase1.hxx>
82 #include <comphelper/anytostring.hxx>
83 #include <com/sun/star/document/XVbaMethodParameter.hpp> //liuchen 2009-7-21
84 extern void unoToSbxValue( SbxVariable
* pVar
, const ::com::sun::star::uno::Any
& aValue
); //liuchen 2009-7-21
85 extern ::com::sun::star::uno::Any
sbxToUnoValue( SbxVariable
* pVar
); //liuchen 2009-7-21
87 #include <com/sun/star/frame/XDesktop.hpp>
88 #include <vcl/svapp.hxx>
89 using namespace ::com::sun::star
;
91 TYPEINIT1(SbModule
,SbxObject
)
92 TYPEINIT1(SbMethod
,SbxMethod
)
93 TYPEINIT1(SbProperty
,SbxProperty
)
94 TYPEINIT1(SbProcedureProperty
,SbxProperty
)
95 TYPEINIT1(SbJScriptModule
,SbModule
)
96 TYPEINIT1(SbJScriptMethod
,SbMethod
)
97 TYPEINIT1(SbObjModule
,SbModule
)
98 TYPEINIT1(SbUserFormModule
,SbObjModule
)
100 SV_DECL_VARARR(SbiBreakpoints
,USHORT
,4,4)
101 SV_IMPL_VARARR(SbiBreakpoints
,USHORT
)
104 SV_IMPL_VARARR(HighlightPortions
, HighlightPortion
)
106 class AsyncQuitHandler
108 AsyncQuitHandler() {}
109 AsyncQuitHandler( const AsyncQuitHandler
&);
111 static AsyncQuitHandler
& instance()
113 static AsyncQuitHandler dInst
;
117 void QuitApplication()
119 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= comphelper::getProcessServiceFactory();
122 uno::Reference
< frame::XDesktop
> xDeskTop( xFactory
->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ) ), uno::UNO_QUERY
);
124 xDeskTop
->terminate();
127 DECL_LINK( OnAsyncQuit
, void* );
130 IMPL_LINK( AsyncQuitHandler
, OnAsyncQuit
, void*, /*pNull*/ )
136 bool UnlockControllerHack( StarBASIC
* pBasic
)
139 if ( pBasic
&& pBasic
->IsDocBasic() )
142 ::rtl::OUString
sVarName( ::rtl::OUString::createFromAscii( "ThisComponent" ) );
143 SbUnoObject
* pGlobs
= dynamic_cast<SbUnoObject
*>( pBasic
->Find( sVarName
, SbxCLASS_DONTCARE
) );
145 aUnoVar
= pGlobs
->getUnoAny();
146 uno::Reference
< frame::XModel
> xModel( aUnoVar
, uno::UNO_QUERY
);
151 xModel
->unlockControllers();
154 catch( uno::Exception
& )
161 /////////////////////////////////////////////////////////////////////////////
163 // Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
164 // Elemente von anderen Modulen aus gefunden werden koennen.
166 SbModule::SbModule( const String
& rName
, bool bVBACompat
)
167 : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ),
168 pImage( NULL
), pBreaks( NULL
), pClassData( NULL
), mbVBACompat( bVBACompat
), pDocObject( NULL
), bIsProxyModule( false )
171 SetFlag( SBX_EXTSEARCH
| SBX_GBLSEARCH
);
172 SetModuleType( com::sun::star::script::ModuleType::Normal
);
175 SbModule::~SbModule()
185 BOOL
SbModule::IsCompiled() const
187 return BOOL( pImage
!= 0 );
190 const SbxObject
* SbModule::FindType( String aTypeName
) const
192 return pImage
? pImage
->FindType( aTypeName
) : NULL
;
196 // Aus dem Codegenerator: Loeschen des Images und Invalidieren der Entries
198 void SbModule::StartDefinitions()
200 delete pImage
; pImage
= NULL
;
204 // Methoden und Properties bleiben erhalten, sind jedoch ungueltig
205 // schliesslich sind ja u.U. die Infos belegt
207 for( i
= 0; i
< pMethods
->Count(); i
++ )
209 SbMethod
* p
= PTR_CAST(SbMethod
,pMethods
->Get( i
) );
213 for( i
= 0; i
< pProps
->Count(); )
215 SbProperty
* p
= PTR_CAST(SbProperty
,pProps
->Get( i
) );
223 // Methode anfordern/anlegen
225 SbMethod
* SbModule::GetMethod( const String
& rName
, SbxDataType t
)
227 SbxVariable
* p
= pMethods
->Find( rName
, SbxCLASS_METHOD
);
228 SbMethod
* pMeth
= p
? PTR_CAST(SbMethod
,p
) : NULL
;
230 pMethods
->Remove( p
);
233 pMeth
= new SbMethod( rName
, t
, this );
234 pMeth
->SetParent( this );
235 pMeth
->SetFlags( SBX_READ
);
236 pMethods
->Put( pMeth
, pMethods
->Count() );
237 StartListening( pMeth
->GetBroadcaster(), TRUE
);
239 // Per Default ist die Methode GUELTIG, da sie auch vom Compiler
240 // (Codegenerator) erzeugt werden kann
241 pMeth
->bInvalid
= FALSE
;
242 pMeth
->ResetFlag( SBX_FIXED
);
243 pMeth
->SetFlag( SBX_WRITE
);
245 pMeth
->ResetFlag( SBX_WRITE
);
246 if( t
!= SbxVARIANT
)
247 pMeth
->SetFlag( SBX_FIXED
);
251 // Property anfordern/anlegen
253 SbProperty
* SbModule::GetProperty( const String
& rName
, SbxDataType t
)
255 SbxVariable
* p
= pProps
->Find( rName
, SbxCLASS_PROPERTY
);
256 SbProperty
* pProp
= p
? PTR_CAST(SbProperty
,p
) : NULL
;
261 pProp
= new SbProperty( rName
, t
, this );
262 pProp
->SetFlag( SBX_READWRITE
);
263 pProp
->SetParent( this );
264 pProps
->Put( pProp
, pProps
->Count() );
265 StartListening( pProp
->GetBroadcaster(), TRUE
);
270 SbProcedureProperty
* SbModule::GetProcedureProperty
271 ( const String
& rName
, SbxDataType t
)
273 SbxVariable
* p
= pProps
->Find( rName
, SbxCLASS_PROPERTY
);
274 SbProcedureProperty
* pProp
= p
? PTR_CAST(SbProcedureProperty
,p
) : NULL
;
279 pProp
= new SbProcedureProperty( rName
, t
);
280 pProp
->SetFlag( SBX_READWRITE
);
281 pProp
->SetParent( this );
282 pProps
->Put( pProp
, pProps
->Count() );
283 StartListening( pProp
->GetBroadcaster(), TRUE
);
288 SbIfaceMapperMethod
* SbModule::GetIfaceMapperMethod
289 ( const String
& rName
, SbMethod
* pImplMeth
)
291 SbxVariable
* p
= pMethods
->Find( rName
, SbxCLASS_METHOD
);
292 SbIfaceMapperMethod
* pMapperMethod
= p
? PTR_CAST(SbIfaceMapperMethod
,p
) : NULL
;
293 if( p
&& !pMapperMethod
)
294 pMethods
->Remove( p
);
297 pMapperMethod
= new SbIfaceMapperMethod( rName
, pImplMeth
);
298 pMapperMethod
->SetParent( this );
299 pMapperMethod
->SetFlags( SBX_READ
);
300 pMethods
->Put( pMapperMethod
, pMethods
->Count() );
302 pMapperMethod
->bInvalid
= FALSE
;
303 return pMapperMethod
;
306 SbIfaceMapperMethod::~SbIfaceMapperMethod()
310 TYPEINIT1(SbIfaceMapperMethod
,SbMethod
)
313 // Aus dem Codegenerator: Ungueltige Eintraege entfernen
315 void SbModule::EndDefinitions( BOOL bNewState
)
317 for( USHORT i
= 0; i
< pMethods
->Count(); )
319 SbMethod
* p
= PTR_CAST(SbMethod
,pMethods
->Get( i
) );
323 pMethods
->Remove( p
);
326 p
->bInvalid
= bNewState
;
336 void SbModule::Clear()
338 delete pImage
; pImage
= NULL
;
345 SbxVariable
* SbModule::Find( const XubString
& rName
, SbxClassType t
)
347 // make sure a search in an uninstatiated class module will fail
348 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
349 if ( bIsProxyModule
)
351 if( !pRes
&& pImage
)
353 SbiInstance
* pInst
= pINST
;
354 if( pInst
&& pInst
->IsCompatibility() )
356 // Put enum types as objects into module,
357 // allows MyEnum.First notation
358 SbxArrayRef xArray
= pImage
->GetEnums();
361 SbxVariable
* pEnumVar
= xArray
->Find( rName
, SbxCLASS_DONTCARE
);
362 SbxObject
* pEnumObject
= PTR_CAST( SbxObject
, pEnumVar
);
365 bool bPrivate
= pEnumObject
->IsSet( SBX_PRIVATE
);
366 String aEnumName
= pEnumObject
->GetName();
368 pRes
= new SbxVariable( SbxOBJECT
);
369 pRes
->SetName( aEnumName
);
370 pRes
->SetParent( this );
371 pRes
->SetFlag( SBX_READ
);
373 pRes
->SetFlag( SBX_PRIVATE
);
374 pRes
->PutObject( pEnumObject
);
382 const ::rtl::OUString
& SbModule::GetSource32() const
387 const String
& SbModule::GetSource() const
389 static String aRetStr
;
394 // Parent und BASIC sind eins!
396 void SbModule::SetParent( SbxObject
* p
)
398 // #118083: Assertion is not valid any more
399 // DBG_ASSERT( !p || p->IsA( TYPE(StarBASIC) ), "SbModules nur in BASIC eintragen" );
403 void SbModule::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
404 const SfxHint
& rHint
, const TypeId
& rHintType
)
406 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
409 SbxVariable
* pVar
= pHint
->GetVar();
410 SbProperty
* pProp
= PTR_CAST(SbProperty
,pVar
);
411 SbMethod
* pMeth
= PTR_CAST(SbMethod
,pVar
);
412 SbProcedureProperty
* pProcProperty
= PTR_CAST( SbProcedureProperty
, pVar
);
415 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
418 aProcName
.AppendAscii( "Property Get " );
419 aProcName
+= pProcProperty
->GetName();
421 SbxVariable
* pPropMeth
= Find( aProcName
, SbxCLASS_METHOD
);
425 pPropMeth
->SetParameters( pVar
->GetParameters() );
428 aVals
.eType
= SbxVARIANT
;
429 pPropMeth
->Get( aVals
);
433 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
435 SbxVariable
* pPropMeth
= NULL
;
437 bool bSet
= pProcProperty
->isSet();
440 pProcProperty
->setSet( false );
443 aProcName
.AppendAscii( "Property Set " );
444 aProcName
+= pProcProperty
->GetName();
445 pPropMeth
= Find( aProcName
, SbxCLASS_METHOD
);
447 if( !pPropMeth
) // Let
450 aProcName
.AppendAscii( "Property Let " );
451 aProcName
+= pProcProperty
->GetName();
452 pPropMeth
= Find( aProcName
, SbxCLASS_METHOD
);
458 SbxArrayRef xArray
= new SbxArray
;
459 xArray
->Put( pPropMeth
, 0 ); // Method as parameter 0
460 xArray
->Put( pVar
, 1 );
461 pPropMeth
->SetParameters( xArray
);
464 pPropMeth
->Get( aVals
);
465 pPropMeth
->SetParameters( NULL
);
472 if( pProp
->GetModule() != this )
473 SetError( SbxERR_BAD_ACTION
);
477 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
479 if( pMeth
->bInvalid
&& !Compile() )
480 // Auto-Compile hat nicht geklappt!
481 StarBASIC::Error( SbERR_BAD_PROP_VALUE
);
484 // Aufruf eines Unterprogramms
485 SbModule
* pOld
= pMOD
;
487 Run( (SbMethod
*) pVar
);
493 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
497 // Das Setzen der Source macht das Image ungueltig
498 // und scant die Methoden-Definitionen neu ein
500 void SbModule::SetSource( const String
& r
)
505 void SbModule::SetSource32( const ::rtl::OUString
& r
)
509 SbiTokenizer
aTok( r
);
510 aTok
.SetCompatible( IsVBACompat() );
511 while( !aTok
.IsEof() )
513 SbiToken eEndTok
= NIL
;
515 // Suchen nach SUB oder FUNCTION
516 SbiToken eLastTok
= NIL
;
517 while( !aTok
.IsEof() )
519 // #32385: Nicht bei declare
520 SbiToken eCurTok
= aTok
.Next();
521 if( eLastTok
!= DECLARE
)
525 eEndTok
= ENDSUB
; break;
527 if( eCurTok
== FUNCTION
)
529 eEndTok
= ENDFUNC
; break;
531 if( eCurTok
== PROPERTY
)
533 eEndTok
= ENDPROPERTY
; break;
538 // Definition der Methode
539 SbMethod
* pMeth
= NULL
;
542 USHORT nLine1
= aTok
.GetLine();
543 if( aTok
.Next() == SYMBOL
)
545 String
aName_( aTok
.GetSym() );
546 SbxDataType t
= aTok
.GetType();
547 if( t
== SbxVARIANT
&& eEndTok
== ENDSUB
)
549 pMeth
= GetMethod( aName_
, t
);
550 pMeth
->nLine1
= pMeth
->nLine2
= nLine1
;
551 // Die Methode ist erst mal GUELTIG
552 pMeth
->bInvalid
= FALSE
;
557 // Skip bis END SUB/END FUNCTION
560 while( !aTok
.IsEof() )
562 if( aTok
.Next() == eEndTok
)
564 pMeth
->nLine2
= aTok
.GetLine();
569 pMeth
->nLine2
= aTok
.GetLine();
572 EndDefinitions( TRUE
);
575 void SbModule::SetComment( const String
& r
)
581 SbMethod
* SbModule::GetFunctionForLine( USHORT nLine
)
583 for( USHORT i
= 0; i
< pMethods
->Count(); i
++ )
585 SbMethod
* p
= (SbMethod
*) pMethods
->Get( i
);
586 if( p
->GetSbxId() == SBXID_BASICMETHOD
)
588 if( nLine
>= p
->nLine1
&& nLine
<= p
->nLine2
)
595 // Ausstrahlen eines Hints an alle Basics
597 static void _SendHint( SbxObject
* pObj
, ULONG nId
, SbMethod
* p
)
600 if( pObj
->IsA( TYPE(StarBASIC
) ) && pObj
->IsBroadcaster() )
601 pObj
->GetBroadcaster().Broadcast( SbxHint( nId
, p
) );
602 // Dann die Unterobjekte fragen
603 SbxArray
* pObjs
= pObj
->GetObjects();
604 for( USHORT i
= 0; i
< pObjs
->Count(); i
++ )
606 SbxVariable
* pVar
= pObjs
->Get( i
);
607 if( pVar
->IsA( TYPE(SbxObject
) ) )
608 _SendHint( PTR_CAST(SbxObject
,pVar
), nId
, p
);
612 static void SendHint( SbxObject
* pObj
, ULONG nId
, SbMethod
* p
)
614 while( pObj
->GetParent() )
615 pObj
= pObj
->GetParent();
616 _SendHint( pObj
, nId
, p
);
619 // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
620 // beim Programm-Ende freigeben, damit nichts gehalten wird.
621 void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC
* pBasic
)
623 // return-Wert von CreateUnoService loeschen
624 static String
aName( RTL_CONSTASCII_USTRINGPARAM("CreateUnoService") );
625 SbxVariable
* pVar
= pBasic
->GetRtl()->Find( aName
, SbxCLASS_METHOD
);
627 pVar
->SbxValue::Clear();
629 // return-Wert von CreateUnoDialog loeschen
630 static String
aName2( RTL_CONSTASCII_USTRINGPARAM("CreateUnoDialog") );
631 pVar
= pBasic
->GetRtl()->Find( aName2
, SbxCLASS_METHOD
);
633 pVar
->SbxValue::Clear();
635 // return-Wert von CDec loeschen
636 static String
aName3( RTL_CONSTASCII_USTRINGPARAM("CDec") );
637 pVar
= pBasic
->GetRtl()->Find( aName3
, SbxCLASS_METHOD
);
639 pVar
->SbxValue::Clear();
641 // return-Wert von CreateObject loeschen
642 static String
aName4( RTL_CONSTASCII_USTRINGPARAM("CreateObject") );
643 pVar
= pBasic
->GetRtl()->Find( aName4
, SbxCLASS_METHOD
);
645 pVar
->SbxValue::Clear();
647 // Ueber alle Sub-Basics gehen
648 SbxArray
* pObjs
= pBasic
->GetObjects();
649 USHORT nCount
= pObjs
->Count();
650 for( USHORT i
= 0 ; i
< nCount
; i
++ )
652 SbxVariable
* pObjVar
= pObjs
->Get( i
);
653 StarBASIC
* pSubBasic
= PTR_CAST( StarBASIC
, pObjVar
);
655 ClearUnoObjectsInRTL_Impl_Rek( pSubBasic
);
659 void ClearUnoObjectsInRTL_Impl( StarBASIC
* pBasic
)
661 // #67781 Rueckgabewerte der Uno-Methoden loeschen
663 clearUnoServiceCtors();
665 ClearUnoObjectsInRTL_Impl_Rek( pBasic
);
667 // Oberstes Basic suchen
668 SbxObject
* p
= pBasic
;
669 while( p
->GetParent() )
671 if( ((StarBASIC
*)p
) != pBasic
)
672 ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC
*)p
);
674 bool SbModule::IsVBACompat()
679 void SbModule::SetVBACompat( bool bCompat
)
681 mbVBACompat
= bCompat
;
683 // Ausfuehren eines BASIC-Unterprogramms
684 USHORT
SbModule::Run( SbMethod
* pMeth
)
686 OSL_TRACE("About to run %s, vba compatmode is %d", rtl::OUStringToOString( pMeth
->GetName(), RTL_TEXTENCODING_UTF8
).getStr(), mbVBACompat
);
687 static USHORT nMaxCallLevel
= 0;
688 static String aMSOMacroRuntimeLibName
= String::CreateFromAscii( "Launcher" );
689 static String aMSOMacroRuntimeAppSymbol
= String::CreateFromAscii( "Application" );
692 BOOL bDelInst
= BOOL( pINST
== NULL
);
698 // #32779: Basic waehrend der Ausfuehrung festhalten
699 xBasic
= (StarBASIC
*) GetParent();
701 pINST
= new SbiInstance( (StarBASIC
*) GetParent() );
704 // i80726 The Find below will genarate an error in Testtool so we reset it unless there was one before already
705 BOOL bWasError
= SbxBase::GetError() != 0;
706 SbxVariable
* pMSOMacroRuntimeLibVar
= Find( aMSOMacroRuntimeLibName
, SbxCLASS_OBJECT
);
707 if ( !bWasError
&& (SbxBase::GetError() == SbxERR_PROC_UNDEFINED
) )
708 SbxBase::ResetError();
709 if( pMSOMacroRuntimeLibVar
)
711 StarBASIC
* pMSOMacroRuntimeLib
= PTR_CAST(StarBASIC
,pMSOMacroRuntimeLibVar
);
712 if( pMSOMacroRuntimeLib
)
714 USHORT nGblFlag
= pMSOMacroRuntimeLib
->GetFlags() & SBX_GBLSEARCH
;
715 pMSOMacroRuntimeLib
->ResetFlag( SBX_GBLSEARCH
);
716 SbxVariable
* pAppSymbol
= pMSOMacroRuntimeLib
->Find( aMSOMacroRuntimeAppSymbol
, SbxCLASS_METHOD
);
717 pMSOMacroRuntimeLib
->SetFlag( nGblFlag
);
720 pMSOMacroRuntimeLib
->SetFlag( SBX_EXTSEARCH
); // Could have been disabled before
721 GetSbData()->pMSOMacroRuntimLib
= pMSOMacroRuntimeLib
;
726 // Error-Stack loeschen
727 SbErrorStack
*& rErrStack
= GetSbData()->pErrStack
;
731 if( nMaxCallLevel
== 0 )
735 getrlimit ( RLIMIT_STACK
, &rl
);
736 // printf( "RLIMIT_STACK = %ld\n", rl.rlim_cur );
739 // Empiric value, 900 = needed bytes/Basic call level
740 // for Linux including 10% safety margin
741 nMaxCallLevel
= rl
.rlim_cur
/ 900;
742 #elif defined SOLARIS
743 // Empiric value, 1650 = needed bytes/Basic call level
744 // for Solaris including 10% safety margin
745 nMaxCallLevel
= rl
.rlim_cur
/ 1650;
747 nMaxCallLevel
= 5800;
749 nMaxCallLevel
= MAXRECURSION
;
754 // Rekursion zu tief?
755 if( ++pINST
->nCallLvl
<= nMaxCallLevel
)
757 // Globale Variable in allen Mods definieren
758 GlobalRunInit( /* bBasicStart = */ bDelInst
);
760 // Trat ein Compiler-Fehler auf? Dann starten wir nicht
761 if( GetSbData()->bGlobalInitErr
== FALSE
)
765 SendHint( GetParent(), SBX_HINT_BASICSTART
, pMeth
);
767 // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
768 // Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
769 // BreakCallLevel ermitteln
770 pINST
->CalcBreakCallLevel( pMeth
->GetDebugFlags() );
773 SbModule
* pOldMod
= pMOD
;
775 SbiRuntime
* pRt
= new SbiRuntime( this, pMeth
, pMeth
->nStart
);
776 pRt
->pNext
= pINST
->pRun
;
782 pINST
->EnableCompatibility( TRUE
);
783 //pRt->SetVBAEnabled( true ); // can we get rid of this
785 while( pRt
->Step() ) {}
787 pRt
->pNext
->unblock();
789 // #63710 Durch ein anderes Thread-Handling bei Events kann es passieren,
790 // dass show-Aufruf an einem Dialog zurueckkehrt (durch schliessen des
791 // Dialogs per UI), BEVOR ein per Event ausgeloester weitergehender Call,
792 // der in Basic weiter oben im Stack steht und auf einen Basic-Breakpoint
793 // gelaufen ist, zurueckkehrt. Dann wird unten die Instanz zerstoert und
794 // wenn das noch im Call stehende Basic weiterlaeuft, gibt es einen GPF.
795 // Daher muss hier gewartet werden, bis andere Call zurueckkehrt.
798 // Hier mit 1 statt 0 vergleichen, da vor nCallLvl--
799 while( pINST
->nCallLvl
!= 1 )
804 pINST
->pRun
= pRt
->pNext
;
805 pINST
->nCallLvl
--; // Call-Level wieder runter
807 // Gibt es eine uebergeordnete Runtime-Instanz?
808 // Dann SbDEBUG_BREAK uebernehmen, wenn gesetzt
809 SbiRuntime
* pRtNext
= pRt
->pNext
;
810 if( pRtNext
&& (pRt
->GetDebugFlags() & SbDEBUG_BREAK
) )
811 pRtNext
->SetDebugFlags( SbDEBUG_BREAK
);
815 if ( pINST
->nCallLvl
== 0 && IsVBACompat() )
817 // VBA always ensure screenupdating is enabled after completing
818 StarBASIC
* pBasic
= PTR_CAST(StarBASIC
,GetParent());
819 if ( pBasic
&& pBasic
->IsDocBasic() )
821 UnlockControllerHack( pBasic
);
826 // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
827 // beim Programm-Ende freigeben, damit nichts gehalten wird.
828 ClearUnoObjectsInRTL_Impl( xBasic
);
830 DBG_ASSERT(pINST
->nCallLvl
==0,"BASIC-Call-Level > 0");
831 delete pINST
, pINST
= NULL
, bDelInst
= FALSE
;
834 vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
835 SendHint( GetParent(), SBX_HINT_BASICSTOP
, pMeth
);
841 pINST
->nCallLvl
--; // Call-Level wieder runter
845 pINST
->nCallLvl
--; // Call-Level wieder runter
846 StarBASIC::FatalError( SbERR_STACK_OVERFLOW
);
849 // VBA always ensure screenupdating is enabled after completing
850 StarBASIC
* pBasic
= PTR_CAST(StarBASIC
,GetParent());
851 if ( pBasic
&& pBasic
->IsDocBasic() && !pINST
)
852 UnlockControllerHack( pBasic
);
855 // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
856 // beim Programm-Ende freigeben, damit nichts gehalten wird.
857 ClearUnoObjectsInRTL_Impl( xBasic
);
862 if ( pBasic
&& pBasic
->IsDocBasic() && pBasic
->IsQuitApplication() && !pINST
)
867 //QuitApplicationHack();
868 Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler
, OnAsyncQuit
), NULL
);
874 // Ausfuehren der Init-Methode eines Moduls nach dem Laden
875 // oder der Compilation
877 void SbModule::RunInit()
881 && pImage
->GetFlag( SBIMG_INITCODE
) )
883 // Flag setzen, dass RunInit aktiv ist (Testtool)
884 GetSbData()->bRunInit
= TRUE
;
886 // BOOL bDelInst = BOOL( pINST == NULL );
888 // pINST = new SbiInstance( (StarBASIC*) GetParent() );
889 SbModule
* pOldMod
= pMOD
;
891 // Der Init-Code beginnt immer hier
892 SbiRuntime
* pRt
= new SbiRuntime( this, NULL
, 0 );
893 pRt
->pNext
= pINST
->pRun
;
895 while( pRt
->Step() ) {}
896 pINST
->pRun
= pRt
->pNext
;
900 // delete pINST, pINST = NULL;
901 pImage
->bInit
= TRUE
;
902 pImage
->bFirstInit
= FALSE
;
904 // RunInit ist nicht mehr aktiv
905 GetSbData()->bRunInit
= FALSE
;
909 // Mit private/dim deklarierte Variablen loeschen
911 void SbModule::AddVarName( const String
& aName
)
913 // see if the name is added allready
914 std::vector
< String
>::iterator it_end
= mModuleVariableNames
.end();
915 for ( std::vector
< String
>::iterator it
= mModuleVariableNames
.begin(); it
!= it_end
; ++it
)
920 mModuleVariableNames
.push_back( aName
);
923 void SbModule::RemoveVars()
925 std::vector
< String
>::iterator it_end
= mModuleVariableNames
.end();
926 for ( std::vector
< String
>::iterator it
= mModuleVariableNames
.begin(); it
!= it_end
; ++it
)
928 // We don't want a Find being called in a derived class ( e.g.
929 // SbUserform because it could trigger say an initialise event
930 // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile )
931 SbxVariableRef p
= SbModule::Find( *it
, SbxCLASS_PROPERTY
);
937 void SbModule::ClearPrivateVars()
939 for( USHORT i
= 0 ; i
< pProps
->Count() ; i
++ )
941 SbProperty
* p
= PTR_CAST(SbProperty
,pProps
->Get( i
) );
944 // Arrays nicht loeschen, sondern nur deren Inhalt
945 if( p
->GetType() & SbxARRAY
)
947 SbxArray
* pArray
= PTR_CAST(SbxArray
,p
->GetObject());
950 for( USHORT j
= 0 ; j
< pArray
->Count() ; j
++ )
952 SbxVariable
* pj
= PTR_CAST(SbxVariable
,pArray
->Get( j
));
953 pj
->SbxValue::Clear();
955 USHORT nFlags = pj->GetFlags();
956 pj->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
958 pj->SetFlags( nFlags );
965 p
->SbxValue::Clear();
967 USHORT nFlags = p->GetFlags();
968 p->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
970 p->SetFlags( nFlags );
977 // Zunaechst in dieses Modul, um 358-faehig zu bleiben
978 // (Branch in sb.cxx vermeiden)
979 void StarBASIC::ClearAllModuleVars( void )
981 // Eigene Module initialisieren
982 for ( USHORT nMod
= 0; nMod
< pModules
->Count(); nMod
++ )
984 SbModule
* pModule
= (SbModule
*)pModules
->Get( nMod
);
985 // Nur initialisieren, wenn der Startcode schon ausgefuehrt wurde
986 if( pModule
->pImage
&& pModule
->pImage
->bInit
)
987 pModule
->ClearPrivateVars();
990 /* #88042 This code can delete already used public vars during runtime!
991 // Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
992 // Wenn ja, auch dort initialisieren
993 for ( USHORT nObj = 0; nObj < pObjs->Count(); nObj++ )
995 SbxVariable* pVar = pObjs->Get( nObj );
996 StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
998 pBasic->ClearAllModuleVars();
1003 // Ausfuehren des Init-Codes aller Module
1004 void SbModule::GlobalRunInit( BOOL bBasicStart
)
1006 // Wenn kein Basic-Start, nur initialisieren, wenn Modul uninitialisiert
1008 if( !(pImage
&& !pImage
->bInit
) )
1011 // GlobalInitErr-Flag fuer Compiler-Error initialisieren
1012 // Anhand dieses Flags kann in SbModule::Run() nach dem Aufruf
1013 // von GlobalRunInit festgestellt werden, ob beim initialisieren
1014 // der Module ein Fehler auftrat. Dann wird nicht gestartet.
1015 GetSbData()->bGlobalInitErr
= FALSE
;
1017 // Parent vom Modul ist ein Basic
1018 StarBASIC
*pBasic
= PTR_CAST(StarBASIC
,GetParent());
1021 pBasic
->InitAllModules();
1023 SbxObject
* pParent_
= pBasic
->GetParent();
1026 StarBASIC
* pParentBasic
= PTR_CAST(StarBASIC
,pParent_
);
1029 pParentBasic
->InitAllModules( pBasic
);
1031 // #109018 Parent can also have a parent (library in doc)
1032 SbxObject
* pParentParent
= pParentBasic
->GetParent();
1035 StarBASIC
* pParentParentBasic
= PTR_CAST(StarBASIC
,pParentParent
);
1036 if( pParentParentBasic
)
1037 pParentParentBasic
->InitAllModules( pParentBasic
);
1044 void SbModule::GlobalRunDeInit( void )
1046 StarBASIC
*pBasic
= PTR_CAST(StarBASIC
,GetParent());
1049 pBasic
->DeInitAllModules();
1051 SbxObject
* pParent_
= pBasic
->GetParent();
1053 pBasic
= PTR_CAST(StarBASIC
,pParent_
);
1055 pBasic
->DeInitAllModules();
1059 // Suche nach dem naechsten STMNT-Befehl im Code. Wird vom STMNT-
1060 // Opcode verwendet, um die Endspalte zu setzen.
1062 const BYTE
* SbModule::FindNextStmnt( const BYTE
* p
, USHORT
& nLine
, USHORT
& nCol
) const
1064 return FindNextStmnt( p
, nLine
, nCol
, FALSE
);
1067 const BYTE
* SbModule::FindNextStmnt( const BYTE
* p
, USHORT
& nLine
, USHORT
& nCol
,
1068 BOOL bFollowJumps
, const SbiImage
* pImg
) const
1070 UINT32 nPC
= (UINT32
) ( p
- (const BYTE
*) pImage
->GetCode() );
1071 while( nPC
< pImage
->GetCodeSize() )
1073 SbiOpcode eOp
= (SbiOpcode
) ( *p
++ );
1075 if( bFollowJumps
&& eOp
== _JUMP
&& pImg
)
1077 DBG_ASSERT( pImg
, "FindNextStmnt: pImg==NULL with FollowJumps option" );
1078 UINT32 nOp1
= *p
++; nOp1
|= *p
++ << 8;
1079 nOp1
|= *p
++ << 16; nOp1
|= *p
++ << 24;
1080 p
= (const BYTE
*) pImg
->GetCode() + nOp1
;
1082 else if( eOp
>= SbOP1_START
&& eOp
<= SbOP1_END
)
1084 else if( eOp
== _STMNT
)
1087 nl
= *p
++; nl
|= *p
++ << 8;
1088 nl
|= *p
++ << 16 ; nl
|= *p
++ << 24;
1089 nc
= *p
++; nc
|= *p
++ << 8;
1090 nc
|= *p
++ << 16 ; nc
|= *p
++ << 24;
1091 nLine
= (USHORT
)nl
; nCol
= (USHORT
)nc
;
1094 else if( eOp
>= SbOP2_START
&& eOp
<= SbOP2_END
)
1096 else if( !( eOp
>= SbOP0_START
&& eOp
<= SbOP0_END
) )
1098 StarBASIC::FatalError( SbERR_INTERNAL_ERROR
);
1105 // Testen, ob eine Zeile STMNT-Opcodes enthaelt
1107 BOOL
SbModule::IsBreakable( USHORT nLine
) const
1111 const BYTE
* p
= (const BYTE
* ) pImage
->GetCode();
1113 while( ( p
= FindNextStmnt( p
, nl
, nc
) ) != NULL
)
1119 USHORT
SbModule::GetBPCount() const
1121 return pBreaks
? pBreaks
->Count() : 0;
1124 USHORT
SbModule::GetBP( USHORT n
) const
1126 if( pBreaks
&& n
< pBreaks
->Count() )
1127 return pBreaks
->GetObject( n
);
1132 BOOL
SbModule::IsBP( USHORT nLine
) const
1136 const USHORT
* p
= pBreaks
->GetData();
1137 USHORT n
= pBreaks
->Count();
1138 for( USHORT i
= 0; i
< n
; i
++, p
++ )
1150 BOOL
SbModule::SetBP( USHORT nLine
)
1152 if( !IsBreakable( nLine
) )
1155 pBreaks
= new SbiBreakpoints
;
1156 const USHORT
* p
= pBreaks
->GetData();
1157 USHORT n
= pBreaks
->Count();
1159 for( i
= 0; i
< n
; i
++, p
++ )
1167 pBreaks
->Insert( &nLine
, 1, i
);
1169 // #38568: Zur Laufzeit auch hier SbDEBUG_BREAK setzen
1170 if( pINST
&& pINST
->pRun
)
1171 pINST
->pRun
->SetDebugFlags( SbDEBUG_BREAK
);
1173 return IsBreakable( nLine
);
1176 BOOL
SbModule::ClearBP( USHORT nLine
)
1181 const USHORT
* p
= pBreaks
->GetData();
1182 USHORT n
= pBreaks
->Count();
1183 for( USHORT i
= 0; i
< n
; i
++, p
++ )
1188 pBreaks
->Remove( i
, 1 ); bRes
= TRUE
; break;
1193 if( !pBreaks
->Count() )
1194 delete pBreaks
, pBreaks
= NULL
;
1199 void SbModule::ClearAllBP()
1201 delete pBreaks
; pBreaks
= NULL
;
1205 SbModule::fixUpMethodStart( bool bCvtToLegacy
, SbiImage
* pImg
) const
1209 for( UINT32 i
= 0; i
< pMethods
->Count(); i
++ )
1211 SbMethod
* pMeth
= PTR_CAST(SbMethod
,pMethods
->Get( (USHORT
)i
) );
1214 //fixup method start positions
1216 pMeth
->nStart
= pImg
->CalcLegacyOffset( pMeth
->nStart
);
1218 pMeth
->nStart
= pImg
->CalcNewOffset( (USHORT
)pMeth
->nStart
);
1224 BOOL
SbModule::LoadData( SvStream
& rStrm
, USHORT nVer
)
1227 if( !SbxObject::LoadData( rStrm
, 1 ) )
1229 // Sicherheitshalber...
1230 SetFlag( SBX_EXTSEARCH
| SBX_GBLSEARCH
);
1235 SbiImage
* p
= new SbiImage
;
1238 if( !p
->Load( rStrm
, nImgVer
) )
1243 // If the image is in old format, we fix up the method start offsets
1244 if ( nImgVer
< B_EXT_IMG_VERSION
)
1246 fixUpMethodStart( false, p
);
1247 p
->ReleaseLegacyBuffer();
1249 aComment
= p
->aComment
;
1250 SetName( p
->aName
);
1251 if( p
->GetCodeSize() )
1253 aOUSource
= p
->aOUSource
;
1254 // Alte Version: Image weg
1257 SetSource32( p
->aOUSource
);
1265 SetSource32( p
->aOUSource
);
1272 BOOL
SbModule::StoreData( SvStream
& rStrm
) const
1274 BOOL bFixup
= ( pImage
&& !pImage
->ExceedsLegacyLimits() );
1276 fixUpMethodStart( true );
1277 BOOL bRet
= SbxObject::StoreData( rStrm
);
1283 pImage
->aOUSource
= aOUSource
;
1284 pImage
->aComment
= aComment
;
1285 pImage
->aName
= GetName();
1287 // # PCode is saved only for legacy formats only
1288 // It should be noted that it probably isn't necessary
1289 // It would be better not to store the image ( more flexible with
1291 bool bRes
= pImage
->Save( rStrm
, B_LEGACYVERSION
);
1293 fixUpMethodStart( false ); // restore method starts
1300 aImg
.aOUSource
= aOUSource
;
1301 aImg
.aComment
= aComment
;
1302 aImg
.aName
= GetName();
1304 return aImg
.Save( rStrm
);
1308 BOOL
SbModule::ExceedsLegacyModuleSize()
1310 if ( !IsCompiled() )
1312 if ( pImage
&& pImage
->ExceedsLegacyLimits() )
1317 class ErrorHdlResetter
1322 ErrorHdlResetter() : mbError( false )
1324 // save error handler
1325 mErrHandler
= StarBASIC::GetGlobalErrorHdl();
1326 // set new error handler
1327 StarBASIC::SetGlobalErrorHdl( LINK( this, ErrorHdlResetter
, BasicErrorHdl
) );
1331 // restore error handler
1332 StarBASIC::SetGlobalErrorHdl(mErrHandler
);
1334 DECL_LINK( BasicErrorHdl
, StarBASIC
* );
1335 bool HasError() { return mbError
; }
1337 IMPL_LINK( ErrorHdlResetter
, BasicErrorHdl
, StarBASIC
*, /*pBasic*/)
1343 bool SbModule::HasExeCode()
1346 ErrorHdlResetter aGblErrHdl
;
1347 // And empty Image always has the Global Chain set up
1348 static const unsigned char pEmptyImage
[] = { 0x45, 0x0 , 0x0, 0x0, 0x0 };
1349 // lets be stricter for the moment than VBA
1352 if ( !IsCompiled() )
1354 if ( pImage
&& !( pImage
->GetCodeSize() == 5 && ( memcmp( pImage
->GetCode(), pEmptyImage
, pImage
->GetCodeSize() ) == 0 ) )
1355 || aGblErrHdl
.HasError() )
1360 // Store only image, no source
1361 BOOL
SbModule::StoreBinaryData( SvStream
& rStrm
)
1363 return StoreBinaryData( rStrm
, 0 );
1366 BOOL
SbModule::StoreBinaryData( SvStream
& rStrm
, USHORT nVer
)
1368 BOOL bRet
= Compile();
1371 BOOL bFixup
= ( !nVer
&& !pImage
->ExceedsLegacyLimits() );// save in old image format, fix up method starts
1373 if ( bFixup
) // save in old image format, fix up method starts
1374 fixUpMethodStart( true );
1375 bRet
= SbxObject::StoreData( rStrm
);
1378 pImage
->aOUSource
= ::rtl::OUString();
1379 pImage
->aComment
= aComment
;
1380 pImage
->aName
= GetName();
1384 bRet
= pImage
->Save( rStrm
, B_EXT_IMG_VERSION
);
1386 bRet
= pImage
->Save( rStrm
, B_LEGACYVERSION
);
1388 fixUpMethodStart( false ); // restore method starts
1390 pImage
->aOUSource
= aOUSource
;
1396 // Called for >= OO 1.0 passwd protected libraries only
1399 BOOL
SbModule::LoadBinaryData( SvStream
& rStrm
)
1401 ::rtl::OUString aKeepSource
= aOUSource
;
1402 bool bRet
= LoadData( rStrm
, 2 );
1404 aOUSource
= aKeepSource
;
1408 BOOL
SbModule::LoadCompleted()
1410 SbxArray
* p
= GetMethods();
1412 for( i
= 0; i
< p
->Count(); i
++ )
1414 SbMethod
* q
= PTR_CAST(SbMethod
,p
->Get( i
) );
1418 p
= GetProperties();
1419 for( i
= 0; i
< p
->Count(); i
++ )
1421 SbProperty
* q
= PTR_CAST(SbProperty
,p
->Get( i
) );
1428 /////////////////////////////////////////////////////////////////////////
1429 // Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
1430 SbJScriptModule::SbJScriptModule( const String
& rName
)
1435 BOOL
SbJScriptModule::LoadData( SvStream
& rStrm
, USHORT nVer
)
1440 if( !SbxObject::LoadData( rStrm
, 1 ) )
1443 // Source-String holen
1445 rStrm
.ReadByteString( aTmp
, gsl_getSystemTextEncoding() );
1451 BOOL
SbJScriptModule::StoreData( SvStream
& rStrm
) const
1453 if( !SbxObject::StoreData( rStrm
) )
1456 // Source-String schreiben
1457 String aTmp
= aOUSource
;
1458 rStrm
.WriteByteString( aTmp
, gsl_getSystemTextEncoding() );
1464 /////////////////////////////////////////////////////////////////////////
1466 SbMethod::SbMethod( const String
& r
, SbxDataType t
, SbModule
* p
)
1467 : SbxMethod( r
, t
), pMod( p
)
1474 refStatics
= new SbxArray
;
1476 // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
1477 SetFlag( SBX_NO_MODIFY
);
1480 SbMethod::SbMethod( const SbMethod
& r
)
1481 : SvRefBase( r
), SbxMethod( r
)
1484 bInvalid
= r
.bInvalid
;
1486 nDebugFlags
= r
.nDebugFlags
;
1489 refStatics
= r
.refStatics
;
1490 mCaller
= r
.mCaller
;
1491 SetFlag( SBX_NO_MODIFY
);
1494 SbMethod::~SbMethod()
1498 SbxArray
* SbMethod::GetLocals()
1501 return pINST
->GetLocals( this );
1506 void SbMethod::ClearStatics()
1508 refStatics
= new SbxArray
;
1511 SbxArray
* SbMethod::GetStatics()
1516 BOOL
SbMethod::LoadData( SvStream
& rStrm
, USHORT nVer
)
1518 if( !SbxMethod::LoadData( rStrm
, 1 ) )
1522 INT16 nTempStart
= (INT16
)nStart
;
1523 // nDebugFlags = n; // AB 16.1.96: Nicht mehr uebernehmen
1525 rStrm
>> nLine1
>> nLine2
>> nTempStart
>> bInvalid
;
1526 // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
1527 SetFlag( SBX_NO_MODIFY
);
1528 nStart
= nTempStart
;
1532 BOOL
SbMethod::StoreData( SvStream
& rStrm
) const
1534 if( !SbxMethod::StoreData( rStrm
) )
1536 rStrm
<< (INT16
) nDebugFlags
1544 void SbMethod::GetLineRange( USHORT
& l1
, USHORT
& l2
)
1546 l1
= nLine1
; l2
= nLine2
;
1549 // Kann spaeter mal weg
1551 SbxInfo
* SbMethod::GetInfo()
1556 // Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
1557 // #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
1558 // abgeschossen werden kann. Rueckgabewert wird als String geliefert.
1559 ErrCode
SbMethod::Call( SbxValue
* pRet
, SbxVariable
* pCaller
)
1563 OSL_TRACE("SbMethod::Call Have been passed a caller 0x%x", pCaller
);
1566 // RefCount vom Modul hochzaehlen
1567 SbModule
* pMod_
= (SbModule
*)GetParent();
1570 // RefCount vom Basic hochzaehlen
1571 StarBASIC
* pBasic
= (StarBASIC
*)pMod_
->GetParent();
1574 // Values anlegen, um Return-Wert zu erhalten
1576 aVals
.eType
= SbxVARIANT
;
1578 // #104083: Compile BEFORE get
1579 if( bInvalid
&& !pMod_
->Compile() )
1580 StarBASIC::Error( SbERR_BAD_PROP_VALUE
);
1586 // Gab es einen Error
1587 ErrCode nErr
= SbxBase::GetError();
1588 SbxBase::ResetError();
1590 // Objekte freigeben
1591 pMod_
->ReleaseRef();
1592 pBasic
->ReleaseRef();
1598 // #100883 Own Broadcast for SbMethod
1599 void SbMethod::Broadcast( ULONG nHintId
)
1601 if( pCst
&& !IsSet( SBX_NO_BROADCAST
) && StaticIsEnabledBroadcasting() )
1603 // Da die Methode von aussen aufrufbar ist, hier noch einmal
1604 // die Berechtigung testen
1605 if( nHintId
& SBX_HINT_DATAWANTED
)
1608 if( nHintId
& SBX_HINT_DATACHANGED
)
1612 if( pMod
&& !pMod
->IsCompiled() )
1615 // Block broadcasts while creating new method
1616 SfxBroadcaster
* pSave
= pCst
;
1618 SbMethod
* pThisCopy
= new SbMethod( *this );
1619 SbMethodRef xHolder
= pThisCopy
;
1622 // this, als Element 0 eintragen, aber den Parent nicht umsetzen!
1623 if( GetType() != SbxVOID
)
1624 mpPar
->PutDirect( pThisCopy
, 0 );
1625 SetParameters( NULL
);
1629 pSave
->Broadcast( SbxHint( nHintId
, pThisCopy
) );
1631 USHORT nSaveFlags
= GetFlags();
1632 SetFlag( SBX_READWRITE
);
1634 Put( pThisCopy
->GetValues_Impl() );
1636 SetFlags( nSaveFlags
);
1640 /////////////////////////////////////////////////////////////////////////
1642 // Implementation SbJScriptMethod (Method-Klasse als Wrapper fuer JavaScript-Funktionen)
1644 SbJScriptMethod::SbJScriptMethod( const String
& r
, SbxDataType t
, SbModule
* p
)
1645 : SbMethod( r
, t
, p
)
1649 SbJScriptMethod::~SbJScriptMethod()
1653 /////////////////////////////////////////////////////////////////////////
1654 SbObjModule::SbObjModule( const com::sun::star::script::ModuleInfo
& mInfo
, bool bIsVbaCompatible
)
1655 : SbModule( mInfo
.ModuleName
, bIsVbaCompatible
)
1657 SetModuleType( mInfo
.ModuleType
);
1658 if ( mInfo
.ModuleType
== script::ModuleType::Form
)
1660 SetClassName( rtl::OUString::createFromAscii( "Form" ) );
1662 else if ( mInfo
.ModuleObject
.is() )
1663 SetUnoObject( uno::makeAny( mInfo
.ModuleObject
) );
1666 SbObjModule::SetUnoObject( const uno::Any
& aObj
) throw ( uno::RuntimeException
)
1668 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,(SbxVariable
*)pDocObject
);
1669 if ( pUnoObj
&& pUnoObj
->getUnoAny() == aObj
) // object is equal, nothing to do
1671 pDocObject
= new SbUnoObject( GetName(), uno::makeAny( aObj
) );
1673 com::sun::star::uno::Reference
< com::sun::star::lang::XServiceInfo
> xServiceInfo( aObj
, com::sun::star::uno::UNO_QUERY_THROW
);
1674 if( xServiceInfo
->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Worksheet" ) ) )
1676 SetClassName( rtl::OUString::createFromAscii( "Worksheet" ) );
1678 else if( xServiceInfo
->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Workbook" ) ) )
1680 SetClassName( rtl::OUString::createFromAscii( "Workbook" ) );
1685 SbObjModule::GetObject()
1690 SbObjModule::Find( const XubString
& rName
, SbxClassType t
)
1692 //OSL_TRACE("SbObjectModule find for %s", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr() );
1693 SbxVariable
* pVar
= NULL
;
1694 if ( !pVar
&& pDocObject
)
1695 pVar
= pDocObject
->Find( rName
, t
);
1697 pVar
= SbModule::Find( rName
, t
);
1701 typedef ::cppu::WeakImplHelper1
< awt::XTopWindowListener
> EventListener_BASE
;
1703 class FormObjEventListenerImpl
: public EventListener_BASE
1705 SbUserFormModule
* mpUserForm
;
1706 uno::Reference
< lang::XComponent
> mxComponent
;
1709 sal_Bool mbActivated
;
1711 FormObjEventListenerImpl(); // not defined
1712 FormObjEventListenerImpl(const FormObjEventListenerImpl
&); // not defined
1714 FormObjEventListenerImpl( SbUserFormModule
* pUserForm
, const uno::Reference
< lang::XComponent
>& xComponent
) : mpUserForm( pUserForm
), mxComponent( xComponent
) , mbDisposed( false ), mbOpened( sal_False
), mbActivated( sal_False
), mbShowing( sal_False
)
1716 if ( mxComponent
.is() );
1718 uno::Reference
< awt::XTopWindow
> xList( mxComponent
, uno::UNO_QUERY_THROW
);;
1719 //uno::Reference< awt::XWindow > xList( mxComponent, uno::UNO_QUERY_THROW );;
1720 OSL_TRACE("*********** Registering the listener");
1721 xList
->addTopWindowListener( this );
1725 ~FormObjEventListenerImpl()
1729 sal_Bool
isShowing() { return mbShowing
; }
1730 void removeListener()
1734 if ( mxComponent
.is() && !mbDisposed
)
1736 uno::Reference
< awt::XTopWindow
> xList( mxComponent
, uno::UNO_QUERY_THROW
);;
1737 OSL_TRACE("*********** Removing the listener");
1738 xList
->removeTopWindowListener( this );
1742 catch( uno::Exception
& ) {}
1744 virtual void SAL_CALL
windowOpened( const lang::EventObject
& /*e*/ ) throw (uno::RuntimeException
)
1748 mbOpened
= sal_True
;
1749 mbShowing
= sal_True
;
1752 mbOpened
= mbActivated
= sal_False
;
1753 mpUserForm
->triggerActivateEvent();
1758 //liuchen 2009-7-21, support Excel VBA Form_QueryClose event
1759 virtual void SAL_CALL
windowClosing( const lang::EventObject
& e
) throw (uno::RuntimeException
)
1761 uno::Reference
< awt::XDialog
> xDialog( e
.Source
, uno::UNO_QUERY
);
1764 uno::Reference
< awt::XControl
> xControl( xDialog
, uno::UNO_QUERY
);
1765 if ( xControl
->getPeer().is() )
1767 uno::Reference
< document::XVbaMethodParameter
> xVbaMethodParameter( xControl
->getPeer(), uno::UNO_QUERY
);
1768 if ( xVbaMethodParameter
.is() )
1770 sal_Int8 nCancel
= 0;
1771 sal_Int8 nCloseMode
= 0;
1773 Sequence
< Any
> aParams
;
1775 aParams
[0] <<= nCancel
;
1776 aParams
[1] <<= nCloseMode
;
1778 mpUserForm
->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ),
1780 xVbaMethodParameter
->setVbaMethodParameter( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Cancel")), aParams
[0]);
1787 mpUserForm
->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ) );
1791 virtual void SAL_CALL
windowClosed( const lang::EventObject
& /*e*/ ) throw (uno::RuntimeException
) { mbOpened
= sal_False
; mbShowing
= sal_False
; }
1792 virtual void SAL_CALL
windowMinimized( const lang::EventObject
& /*e*/ ) throw (uno::RuntimeException
) {}
1793 virtual void SAL_CALL
windowNormalized( const lang::EventObject
& /*e*/ ) throw (uno::RuntimeException
){}
1794 virtual void SAL_CALL
windowActivated( const lang::EventObject
& /*e*/ ) throw (uno::RuntimeException
)
1798 mbActivated
= sal_True
;
1801 mbOpened
= mbActivated
= sal_False
;
1802 mpUserForm
->triggerActivateEvent();
1807 virtual void SAL_CALL
windowDeactivated( const lang::EventObject
& /*e*/ ) throw (uno::RuntimeException
)
1810 mpUserForm
->triggerDeActivateEvent();
1814 virtual void SAL_CALL
disposing( const lang::EventObject
& Source
) throw (uno::RuntimeException
)
1816 OSL_TRACE("** Userform/Dialog disposing");
1822 mpUserForm
->ResetApiObj();
1826 SbUserFormModule::SbUserFormModule( const com::sun::star::script::ModuleInfo
& mInfo
, bool bIsCompat
)
1827 :SbObjModule( mInfo
, bIsCompat
), mbInit( false )
1829 m_xModel
.set( mInfo
.ModuleObject
, uno::UNO_QUERY_THROW
);
1832 void SbUserFormModule::ResetApiObj()
1834 if ( m_xDialog
.is() ) // probably someone close the dialog window
1836 triggerTerminateEvent();
1842 void SbUserFormModule::triggerMethod( const String
& aMethodToRun
)
1844 Sequence
< Any
> aArguments
;
1845 triggerMethod( aMethodToRun
, aArguments
);
1847 void SbUserFormModule::triggerMethod( const String
& aMethodToRun
, Sequence
< Any
>& aArguments
)
1849 OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun
, RTL_TEXTENCODING_UTF8
).getStr() );
1851 SbxVariable
* pMeth
= SbObjModule::Find( aMethodToRun
, SbxCLASS_METHOD
);
1854 //liuchen 2009-7-21, support Excel VBA UserForm_QueryClose event with parameters
1855 if ( aArguments
.getLength() > 0 ) // Setup parameters
1857 SbxArrayRef xArray
= new SbxArray
;
1858 xArray
->Put( pMeth
, 0 ); // Method as parameter 0
1860 for ( sal_Int32 i
= 0; i
< aArguments
.getLength(); ++i
)
1862 SbxVariableRef xSbxVar
= new SbxVariable( SbxVARIANT
);
1863 unoToSbxValue( static_cast< SbxVariable
* >( xSbxVar
), aArguments
[i
] );
1864 xArray
->Put( xSbxVar
, static_cast< USHORT
>( i
) + 1 );
1866 // Enable passing by ref
1867 if ( xSbxVar
->GetType() != SbxVARIANT
)
1868 xSbxVar
->SetFlag( SBX_FIXED
);
1870 pMeth
->SetParameters( xArray
);
1873 pMeth
->Get( aVals
);
1875 for ( sal_Int32 i
= 0; i
< aArguments
.getLength(); ++i
)
1877 aArguments
[i
] = sbxToUnoValue( xArray
->Get( static_cast< USHORT
>(i
) + 1) );
1879 pMeth
->SetParameters( NULL
);
1885 pMeth
->Get( aVals
);
1890 void SbUserFormModule::triggerActivateEvent( void )
1892 OSL_TRACE("**** entering SbUserFormModule::triggerActivate");
1893 triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_activate") ) );
1894 OSL_TRACE("**** leaving SbUserFormModule::triggerActivate");
1897 void SbUserFormModule::triggerDeActivateEvent( void )
1899 OSL_TRACE("**** SbUserFormModule::triggerDeActivate");
1900 triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_DeActivate") ) );
1903 void SbUserFormModule::triggerInitializeEvent( void )
1908 OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent");
1909 static String
aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") );
1910 triggerMethod( aInitMethodName
);
1914 void SbUserFormModule::triggerTerminateEvent( void )
1916 OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent");
1917 static String
aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") );
1918 triggerMethod( aTermMethodName
);
1922 void SbUserFormModule::load()
1924 OSL_TRACE("** load() ");
1930 //liuchen 2009-7-21 change to accmordate VBA's beheavior
1931 void SbUserFormModule::Unload()
1933 OSL_TRACE("** Unload() ");
1935 sal_Int8 nCancel
= 0;
1936 sal_Int8 nCloseMode
= 1;
1938 Sequence
< Any
> aParams
;
1940 aParams
[0] <<= nCancel
;
1941 aParams
[1] <<= nCloseMode
;
1943 triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), aParams
);
1945 aParams
[0] >>= nCancel
;
1951 if ( m_xDialog
.is() )
1953 triggerTerminateEvent();
1956 SbxVariable
* pMeth
= SbObjModule::Find( String( RTL_CONSTASCII_USTRINGPARAM( "UnloadObject" ) ), SbxCLASS_METHOD
);
1959 OSL_TRACE("Attempting too run the UnloadObjectMethod");
1960 m_xDialog
= NULL
; //release ref to the uno object
1962 FormObjEventListenerImpl
* pFormListener
= dynamic_cast< FormObjEventListenerImpl
* >( m_DialogListener
.get() );
1963 bool bWaitForDispose
= true; // assume dialog is showing
1964 if ( pFormListener
)
1966 bWaitForDispose
= pFormListener
->isShowing();
1967 OSL_TRACE("Showing %d", bWaitForDispose
);
1970 if ( !bWaitForDispose
)
1972 // we've either already got a dispose or we'er never going to get one
1974 } // else wait for dispose
1975 OSL_TRACE("UnloadObject completed ( we hope )");
1980 void SbUserFormModule::InitObject()
1985 String
aHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
1986 SbUnoObject
* pGlobs
= (SbUnoObject
*)GetParent()->Find( aHook
, SbxCLASS_DONTCARE
);
1987 if ( m_xModel
.is() && pGlobs
)
1990 uno::Reference
< lang::XMultiServiceFactory
> xVBAFactory( pGlobs
->getUnoAny(), uno::UNO_QUERY_THROW
);
1991 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= comphelper::getProcessServiceFactory();
1992 uno::Sequence
< uno::Any
> aArgs(1);
1993 aArgs
[ 0 ] <<= m_xModel
;
1994 rtl::OUString
sDialogUrl( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:" ) );
1995 rtl::OUString
sProjectName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
1996 if ( this->GetParent()->GetName().Len() )
1997 sProjectName
= this->GetParent()->GetName();
1998 sDialogUrl
= sDialogUrl
.concat( sProjectName
).concat( rtl::OUString( '.') ).concat( GetName() ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) );
2000 uno::Reference
< awt::XDialogProvider
> xProvider( xFactory
->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")), aArgs
), uno::UNO_QUERY_THROW
);
2001 m_xDialog
= xProvider
->createDialog( sDialogUrl
);
2003 // create vba api object
2005 aArgs
[ 0 ] = uno::Any();
2006 aArgs
[ 1 ] <<= m_xDialog
;
2007 aArgs
[ 2 ] <<= m_xModel
;
2008 pDocObject
= new SbUnoObject( GetName(), uno::makeAny( xVBAFactory
->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs
) ) );
2009 uno::Reference
< lang::XComponent
> xComponent( aArgs
[ 1 ], uno::UNO_QUERY_THROW
);
2010 // remove old listener if it exists
2011 FormObjEventListenerImpl
* pFormListener
= dynamic_cast< FormObjEventListenerImpl
* >( m_DialogListener
.get() );
2012 if ( pFormListener
)
2013 pFormListener
->removeListener();
2014 m_DialogListener
= new FormObjEventListenerImpl( this, xComponent
);
2016 triggerInitializeEvent();
2019 catch( uno::Exception
& e
)
2026 SbUserFormModule::Find( const XubString
& rName
, SbxClassType t
)
2028 if ( !pDocObject
&& !GetSbData()->bRunInit
&& pINST
)
2030 return SbObjModule::Find( rName
, t
);
2032 /////////////////////////////////////////////////////////////////////////
2034 SbProperty::SbProperty( const String
& r
, SbxDataType t
, SbModule
* p
)
2035 : SbxProperty( r
, t
), pMod( p
)
2040 SbProperty::~SbProperty()
2043 /////////////////////////////////////////////////////////////////////////
2045 SbProcedureProperty::~SbProcedureProperty()