xref: /AOO41X/main/basic/source/classes/sbxmod.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <list>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <vos/macros.hxx>
34*cdf0e10cSrcweir #include <vcl/svapp.hxx>
35*cdf0e10cSrcweir #include <tools/stream.hxx>
36*cdf0e10cSrcweir #include <svl/brdcst.hxx>
37*cdf0e10cSrcweir #include <tools/shl.hxx>
38*cdf0e10cSrcweir #include <basic/sbx.hxx>
39*cdf0e10cSrcweir #include "sbdiagnose.hxx"
40*cdf0e10cSrcweir #include "sb.hxx"
41*cdf0e10cSrcweir #include <sbjsmeth.hxx>
42*cdf0e10cSrcweir #include "sbjsmod.hxx"
43*cdf0e10cSrcweir #include "sbintern.hxx"
44*cdf0e10cSrcweir #include "image.hxx"
45*cdf0e10cSrcweir #include "opcodes.hxx"
46*cdf0e10cSrcweir #include "runtime.hxx"
47*cdf0e10cSrcweir #include "token.hxx"
48*cdf0e10cSrcweir #include "sbunoobj.hxx"
49*cdf0e10cSrcweir #include "sbtrace.hxx"
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir //#include <basic/hilight.hxx>
53*cdf0e10cSrcweir #include <svtools/syntaxhighlight.hxx>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #include <basic/basrdll.hxx>
56*cdf0e10cSrcweir #include <vos/mutex.hxx>
57*cdf0e10cSrcweir #include <basic/sbobjmod.hxx>
58*cdf0e10cSrcweir #include <basic/vbahelper.hxx>
59*cdf0e10cSrcweir #include <cppuhelper/implbase3.hxx>
60*cdf0e10cSrcweir #include <unotools/eventcfg.hxx>
61*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/script/ModuleType.hpp>
63*cdf0e10cSrcweir #include <com/sun/star/script/vba/XVBACompatibility.hpp>
64*cdf0e10cSrcweir #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
65*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
66*cdf0e10cSrcweir #include <com/sun/star/document/XEventBroadcaster.hpp>
67*cdf0e10cSrcweir #include <com/sun/star/document/XEventListener.hpp>
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir using namespace com::sun::star;
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir // for the bsearch
72*cdf0e10cSrcweir #ifdef WNT
73*cdf0e10cSrcweir #define CDECL _cdecl
74*cdf0e10cSrcweir #endif
75*cdf0e10cSrcweir #if defined(UNX) || defined(OS2)
76*cdf0e10cSrcweir #define CDECL
77*cdf0e10cSrcweir #endif
78*cdf0e10cSrcweir #ifdef UNX
79*cdf0e10cSrcweir #include <sys/resource.h>
80*cdf0e10cSrcweir #endif
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir #include <stdio.h>
83*cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp>
84*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
85*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
86*cdf0e10cSrcweir #include <vcl/svapp.hxx>
87*cdf0e10cSrcweir #include <map>
88*cdf0e10cSrcweir #include <com/sun/star/reflection/XProxyFactory.hpp>
89*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
90*cdf0e10cSrcweir #include <basic/sbobjmod.hxx>
91*cdf0e10cSrcweir #include <com/sun/star/uno/XAggregation.hpp>
92*cdf0e10cSrcweir #include <com/sun/star/script/XInvocation.hpp>
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir using namespace com::sun::star::lang;
95*cdf0e10cSrcweir using namespace com::sun::star::reflection;
96*cdf0e10cSrcweir using namespace com::sun::star::beans;
97*cdf0e10cSrcweir using namespace com::sun::star::script;
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir #include <com/sun/star/script/XLibraryContainer.hpp>
101*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
102*cdf0e10cSrcweir #include <com/sun/star/awt/XDialogProvider.hpp>
103*cdf0e10cSrcweir #include <com/sun/star/awt/XTopWindow.hpp>
104*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp>
105*cdf0e10cSrcweir #include <com/sun/star/awt/XControl.hpp>
106*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
107*cdf0e10cSrcweir #include <comphelper/anytostring.hxx>
108*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
109*cdf0e10cSrcweir #include <ooo/vba/VbQueryClose.hpp>
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1< XInvocation > DocObjectWrapper_BASE;
112*cdf0e10cSrcweir typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;
113*cdf0e10cSrcweir ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
114*cdf0e10cSrcweir void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir class DocObjectWrapper : public DocObjectWrapper_BASE
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir     Reference< XAggregation >  m_xAggProxy;
119*cdf0e10cSrcweir     Reference< XInvocation >  m_xAggInv;
120*cdf0e10cSrcweir     Reference< XTypeProvider > m_xAggregateTypeProv;
121*cdf0e10cSrcweir     Sequence< Type >           m_Types;
122*cdf0e10cSrcweir     SbModule*                m_pMod;
123*cdf0e10cSrcweir     SbMethodRef getMethod( const rtl::OUString& aName ) throw (RuntimeException);
124*cdf0e10cSrcweir     SbPropertyRef getProperty( const rtl::OUString& aName ) throw (RuntimeException);
125*cdf0e10cSrcweir     String mName; // for debugging
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir public:
128*cdf0e10cSrcweir     DocObjectWrapper( SbModule* pMod );
129*cdf0e10cSrcweir     virtual ~DocObjectWrapper();
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir     virtual void SAL_CALL acquire() throw();
132*cdf0e10cSrcweir     virtual void SAL_CALL release() throw();
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (RuntimeException)
135*cdf0e10cSrcweir     {
136*cdf0e10cSrcweir         if( !m_xAggregateTypeProv.is() )
137*cdf0e10cSrcweir             throw RuntimeException();
138*cdf0e10cSrcweir         return m_xAggregateTypeProv->getImplementationId();
139*cdf0e10cSrcweir     }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(  ) throw (RuntimeException);
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir     virtual Any SAL_CALL invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException);
144*cdf0e10cSrcweir     virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException);
145*cdf0e10cSrcweir     virtual Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException);
146*cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException);
147*cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException);
148*cdf0e10cSrcweir     virtual  Any SAL_CALL queryInterface( const Type& aType ) throw ( RuntimeException );
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir     virtual Sequence< Type > SAL_CALL getTypes() throw ( RuntimeException );
151*cdf0e10cSrcweir };
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ), mName( pVar->GetName() )
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir     SbObjModule* pMod = PTR_CAST(SbObjModule,pVar);
156*cdf0e10cSrcweir     if ( pMod )
157*cdf0e10cSrcweir     {
158*cdf0e10cSrcweir         if ( pMod->GetModuleType() == ModuleType::DOCUMENT )
159*cdf0e10cSrcweir         {
160*cdf0e10cSrcweir             Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
161*cdf0e10cSrcweir             // Use proxy factory service to create aggregatable proxy.
162*cdf0e10cSrcweir             SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pMod->GetObject() );
163*cdf0e10cSrcweir             Reference< XInterface > xIf;
164*cdf0e10cSrcweir             if ( pUnoObj )
165*cdf0e10cSrcweir             {
166*cdf0e10cSrcweir                    Any aObj = pUnoObj->getUnoAny();
167*cdf0e10cSrcweir                    aObj >>= xIf;
168*cdf0e10cSrcweir                    if ( xIf.is() )
169*cdf0e10cSrcweir                    {
170*cdf0e10cSrcweir                        m_xAggregateTypeProv.set( xIf, UNO_QUERY );
171*cdf0e10cSrcweir                        m_xAggInv.set( xIf, UNO_QUERY );
172*cdf0e10cSrcweir                    }
173*cdf0e10cSrcweir             }
174*cdf0e10cSrcweir             if ( xIf.is() )
175*cdf0e10cSrcweir             {
176*cdf0e10cSrcweir                 try
177*cdf0e10cSrcweir                 {
178*cdf0e10cSrcweir                     Reference< XMultiComponentFactory > xMFac( xFactory, UNO_QUERY_THROW );
179*cdf0e10cSrcweir                     Reference< XPropertySet> xPSMPropertySet( xMFac, UNO_QUERY_THROW );
180*cdf0e10cSrcweir                     Reference< XComponentContext >  xCtx;
181*cdf0e10cSrcweir                     xPSMPropertySet->getPropertyValue(
182*cdf0e10cSrcweir                     String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xCtx;
183*cdf0e10cSrcweir                     Reference< XProxyFactory > xProxyFac( xMFac->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ), xCtx  ), UNO_QUERY_THROW );
184*cdf0e10cSrcweir                     m_xAggProxy = xProxyFac->createProxy( xIf );
185*cdf0e10cSrcweir                 }
186*cdf0e10cSrcweir                 catch(  Exception& )
187*cdf0e10cSrcweir                 {
188*cdf0e10cSrcweir                     OSL_ENSURE( false, "DocObjectWrapper::DocObjectWrapper: Caught exception!" );
189*cdf0e10cSrcweir                 }
190*cdf0e10cSrcweir             }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir             if ( m_xAggProxy.is() )
193*cdf0e10cSrcweir             {
194*cdf0e10cSrcweir                 osl_incrementInterlockedCount( &m_refCount );
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir                 /* i35609 - Fix crash on Solaris. The setDelegator call needs
197*cdf0e10cSrcweir                     to be in its own block to ensure that all temporary Reference
198*cdf0e10cSrcweir                     instances that are acquired during the call are released
199*cdf0e10cSrcweir                     before m_refCount is decremented again */
200*cdf0e10cSrcweir                 {
201*cdf0e10cSrcweir                     m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) );
202*cdf0e10cSrcweir                 }
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir                  osl_decrementInterlockedCount( &m_refCount );
205*cdf0e10cSrcweir             }
206*cdf0e10cSrcweir         }
207*cdf0e10cSrcweir     }
208*cdf0e10cSrcweir }
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir void SAL_CALL
211*cdf0e10cSrcweir DocObjectWrapper::acquire() throw ()
212*cdf0e10cSrcweir {
213*cdf0e10cSrcweir     osl_incrementInterlockedCount( &m_refCount );
214*cdf0e10cSrcweir     OSL_TRACE("DocObjectWrapper::acquire(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
215*cdf0e10cSrcweir }
216*cdf0e10cSrcweir void SAL_CALL
217*cdf0e10cSrcweir DocObjectWrapper::release() throw ()
218*cdf0e10cSrcweir {
219*cdf0e10cSrcweir     if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
220*cdf0e10cSrcweir     {
221*cdf0e10cSrcweir         OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
222*cdf0e10cSrcweir         delete this;
223*cdf0e10cSrcweir     }
224*cdf0e10cSrcweir     else
225*cdf0e10cSrcweir         OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
226*cdf0e10cSrcweir }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir DocObjectWrapper::~DocObjectWrapper()
229*cdf0e10cSrcweir {
230*cdf0e10cSrcweir }
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir Sequence< Type > SAL_CALL DocObjectWrapper::getTypes()
233*cdf0e10cSrcweir     throw ( RuntimeException )
234*cdf0e10cSrcweir {
235*cdf0e10cSrcweir     if ( m_Types.getLength() == 0 )
236*cdf0e10cSrcweir     {
237*cdf0e10cSrcweir         Sequence< Type > sTypes;
238*cdf0e10cSrcweir         if ( m_xAggregateTypeProv.is() )
239*cdf0e10cSrcweir             sTypes = m_xAggregateTypeProv->getTypes();
240*cdf0e10cSrcweir         m_Types.realloc( sTypes.getLength() + 1 );
241*cdf0e10cSrcweir         Type* pPtr = m_Types.getArray();
242*cdf0e10cSrcweir         for ( int i=0; i<m_Types.getLength(); ++i, ++pPtr )
243*cdf0e10cSrcweir         {
244*cdf0e10cSrcweir             if ( i == 0 )
245*cdf0e10cSrcweir                 *pPtr = XInvocation::static_type( NULL );
246*cdf0e10cSrcweir             else
247*cdf0e10cSrcweir                 *pPtr = sTypes[ i - 1 ];
248*cdf0e10cSrcweir         }
249*cdf0e10cSrcweir     }
250*cdf0e10cSrcweir     return m_Types;
251*cdf0e10cSrcweir }
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir Reference< XIntrospectionAccess > SAL_CALL
254*cdf0e10cSrcweir DocObjectWrapper::getIntrospection(  ) throw (RuntimeException)
255*cdf0e10cSrcweir {
256*cdf0e10cSrcweir     return NULL;
257*cdf0e10cSrcweir }
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir Any SAL_CALL
260*cdf0e10cSrcweir DocObjectWrapper::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException)
261*cdf0e10cSrcweir {
262*cdf0e10cSrcweir     if ( m_xAggInv.is() &&  m_xAggInv->hasMethod( aFunctionName ) )
263*cdf0e10cSrcweir             return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam );
264*cdf0e10cSrcweir     SbMethodRef pMethod = getMethod( aFunctionName );
265*cdf0e10cSrcweir     if ( !pMethod )
266*cdf0e10cSrcweir         throw RuntimeException();
267*cdf0e10cSrcweir     // check number of parameters
268*cdf0e10cSrcweir     sal_Int32 nParamsCount = aParams.getLength();
269*cdf0e10cSrcweir     SbxInfo* pInfo = pMethod->GetInfo();
270*cdf0e10cSrcweir     if ( pInfo )
271*cdf0e10cSrcweir     {
272*cdf0e10cSrcweir         sal_Int32 nSbxOptional = 0;
273*cdf0e10cSrcweir         sal_uInt16 n = 1;
274*cdf0e10cSrcweir         for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
275*cdf0e10cSrcweir         {
276*cdf0e10cSrcweir             if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
277*cdf0e10cSrcweir                 ++nSbxOptional;
278*cdf0e10cSrcweir             else
279*cdf0e10cSrcweir                 nSbxOptional = 0;
280*cdf0e10cSrcweir         }
281*cdf0e10cSrcweir         sal_Int32 nSbxCount = n - 1;
282*cdf0e10cSrcweir         if ( nParamsCount < nSbxCount - nSbxOptional )
283*cdf0e10cSrcweir         {
284*cdf0e10cSrcweir             throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "wrong number of parameters!" ) ), Reference< XInterface >() );
285*cdf0e10cSrcweir         }
286*cdf0e10cSrcweir     }
287*cdf0e10cSrcweir     // set parameters
288*cdf0e10cSrcweir     SbxArrayRef xSbxParams;
289*cdf0e10cSrcweir     if ( nParamsCount > 0 )
290*cdf0e10cSrcweir     {
291*cdf0e10cSrcweir         xSbxParams = new SbxArray;
292*cdf0e10cSrcweir         const Any* pParams = aParams.getConstArray();
293*cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < nParamsCount; ++i )
294*cdf0e10cSrcweir         {
295*cdf0e10cSrcweir             SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
296*cdf0e10cSrcweir             unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
297*cdf0e10cSrcweir             xSbxParams->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir             // Enable passing by ref
300*cdf0e10cSrcweir             if ( xSbxVar->GetType() != SbxVARIANT )
301*cdf0e10cSrcweir                 xSbxVar->SetFlag( SBX_FIXED );
302*cdf0e10cSrcweir         }
303*cdf0e10cSrcweir     }
304*cdf0e10cSrcweir     if ( xSbxParams.Is() )
305*cdf0e10cSrcweir         pMethod->SetParameters( xSbxParams );
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir     // call method
308*cdf0e10cSrcweir     SbxVariableRef xReturn = new SbxVariable;
309*cdf0e10cSrcweir     ErrCode nErr = SbxERR_OK;
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir     nErr = pMethod->Call( xReturn );
312*cdf0e10cSrcweir     Any aReturn;
313*cdf0e10cSrcweir     // get output parameters
314*cdf0e10cSrcweir     if ( xSbxParams.Is() )
315*cdf0e10cSrcweir     {
316*cdf0e10cSrcweir         SbxInfo* pInfo_ = pMethod->GetInfo();
317*cdf0e10cSrcweir         if ( pInfo_ )
318*cdf0e10cSrcweir         {
319*cdf0e10cSrcweir             OutParamMap aOutParamMap;
320*cdf0e10cSrcweir             for ( sal_uInt16 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
321*cdf0e10cSrcweir             {
322*cdf0e10cSrcweir                 const SbxParamInfo* pParamInfo = pInfo_->GetParam( n );
323*cdf0e10cSrcweir                 if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
324*cdf0e10cSrcweir                 {
325*cdf0e10cSrcweir                     SbxVariable* pVar = xSbxParams->Get( n );
326*cdf0e10cSrcweir                     if ( pVar )
327*cdf0e10cSrcweir                     {
328*cdf0e10cSrcweir                         SbxVariableRef xVar = pVar;
329*cdf0e10cSrcweir                         aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
330*cdf0e10cSrcweir                     }
331*cdf0e10cSrcweir                 }
332*cdf0e10cSrcweir             }
333*cdf0e10cSrcweir             sal_Int32 nOutParamCount = aOutParamMap.size();
334*cdf0e10cSrcweir             aOutParamIndex.realloc( nOutParamCount );
335*cdf0e10cSrcweir             aOutParam.realloc( nOutParamCount );
336*cdf0e10cSrcweir             sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
337*cdf0e10cSrcweir             Any* pOutParam = aOutParam.getArray();
338*cdf0e10cSrcweir             for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
339*cdf0e10cSrcweir             {
340*cdf0e10cSrcweir                 *pOutParamIndex = aIt->first;
341*cdf0e10cSrcweir                 *pOutParam = aIt->second;
342*cdf0e10cSrcweir             }
343*cdf0e10cSrcweir         }
344*cdf0e10cSrcweir     }
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir     // get return value
347*cdf0e10cSrcweir     aReturn = sbxToUnoValue( xReturn );
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir     pMethod->SetParameters( NULL );
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir     return aReturn;
352*cdf0e10cSrcweir }
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir void SAL_CALL
355*cdf0e10cSrcweir DocObjectWrapper::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException)
356*cdf0e10cSrcweir {
357*cdf0e10cSrcweir     if ( m_xAggInv.is() &&  m_xAggInv->hasProperty( aPropertyName ) )
358*cdf0e10cSrcweir             return m_xAggInv->setValue( aPropertyName, aValue );
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir     SbPropertyRef pProperty = getProperty( aPropertyName );
361*cdf0e10cSrcweir     if ( !pProperty.Is() )
362*cdf0e10cSrcweir        throw UnknownPropertyException();
363*cdf0e10cSrcweir     unoToSbxValue( (SbxVariable*) pProperty, aValue );
364*cdf0e10cSrcweir }
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir Any SAL_CALL
367*cdf0e10cSrcweir DocObjectWrapper::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException)
368*cdf0e10cSrcweir {
369*cdf0e10cSrcweir     if ( m_xAggInv.is() &&  m_xAggInv->hasProperty( aPropertyName ) )
370*cdf0e10cSrcweir             return m_xAggInv->getValue( aPropertyName );
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir     SbPropertyRef pProperty = getProperty( aPropertyName );
373*cdf0e10cSrcweir     if ( !pProperty.Is() )
374*cdf0e10cSrcweir        throw UnknownPropertyException();
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir     SbxVariable* pProp = ( SbxVariable* ) pProperty;
377*cdf0e10cSrcweir     if ( pProp->GetType() == SbxEMPTY )
378*cdf0e10cSrcweir         pProperty->Broadcast( SBX_HINT_DATAWANTED );
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir     Any aRet = sbxToUnoValue( pProp );
381*cdf0e10cSrcweir     return aRet;
382*cdf0e10cSrcweir }
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir ::sal_Bool SAL_CALL
385*cdf0e10cSrcweir DocObjectWrapper::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException)
386*cdf0e10cSrcweir {
387*cdf0e10cSrcweir     if ( m_xAggInv.is() && m_xAggInv->hasMethod( aName ) )
388*cdf0e10cSrcweir         return sal_True;
389*cdf0e10cSrcweir     return getMethod( aName ).Is();
390*cdf0e10cSrcweir }
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir ::sal_Bool SAL_CALL
393*cdf0e10cSrcweir DocObjectWrapper::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException)
394*cdf0e10cSrcweir {
395*cdf0e10cSrcweir     sal_Bool bRes = sal_False;
396*cdf0e10cSrcweir     if ( m_xAggInv.is() && m_xAggInv->hasProperty( aName ) )
397*cdf0e10cSrcweir         bRes = sal_True;
398*cdf0e10cSrcweir     else bRes = getProperty( aName ).Is();
399*cdf0e10cSrcweir     return bRes;
400*cdf0e10cSrcweir }
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir Any SAL_CALL DocObjectWrapper::queryInterface( const Type& aType )
403*cdf0e10cSrcweir     throw ( RuntimeException )
404*cdf0e10cSrcweir {
405*cdf0e10cSrcweir     Any aRet = DocObjectWrapper_BASE::queryInterface( aType );
406*cdf0e10cSrcweir     if ( aRet.hasValue() )
407*cdf0e10cSrcweir         return aRet;
408*cdf0e10cSrcweir     else if ( m_xAggProxy.is() )
409*cdf0e10cSrcweir         aRet = m_xAggProxy->queryAggregation( aType );
410*cdf0e10cSrcweir     return aRet;
411*cdf0e10cSrcweir }
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir SbMethodRef DocObjectWrapper::getMethod( const rtl::OUString& aName ) throw (RuntimeException)
414*cdf0e10cSrcweir {
415*cdf0e10cSrcweir     SbMethodRef pMethod = NULL;
416*cdf0e10cSrcweir     if ( m_pMod )
417*cdf0e10cSrcweir     {
418*cdf0e10cSrcweir         sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
419*cdf0e10cSrcweir         // Limit search to this module
420*cdf0e10cSrcweir         m_pMod->ResetFlag( SBX_GBLSEARCH );
421*cdf0e10cSrcweir         pMethod = (SbMethod*) m_pMod->SbModule::Find( aName,  SbxCLASS_METHOD );
422*cdf0e10cSrcweir         m_pMod->SetFlags( nSaveFlgs );
423*cdf0e10cSrcweir     }
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir     return pMethod;
426*cdf0e10cSrcweir }
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir SbPropertyRef DocObjectWrapper::getProperty( const rtl::OUString& aName ) throw (RuntimeException)
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir     SbPropertyRef pProperty = NULL;
431*cdf0e10cSrcweir     if ( m_pMod )
432*cdf0e10cSrcweir     {
433*cdf0e10cSrcweir         sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
434*cdf0e10cSrcweir         // Limit search to this module.
435*cdf0e10cSrcweir         m_pMod->ResetFlag( SBX_GBLSEARCH );
436*cdf0e10cSrcweir         pProperty = (SbProperty*)m_pMod->SbModule::Find( aName,  SbxCLASS_PROPERTY );
437*cdf0e10cSrcweir         m_pMod->SetFlag( nSaveFlgs );
438*cdf0e10cSrcweir     }
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir     return pProperty;
441*cdf0e10cSrcweir }
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir TYPEINIT1(SbModule,SbxObject)
444*cdf0e10cSrcweir TYPEINIT1(SbMethod,SbxMethod)
445*cdf0e10cSrcweir TYPEINIT1(SbProperty,SbxProperty)
446*cdf0e10cSrcweir TYPEINIT1(SbProcedureProperty,SbxProperty)
447*cdf0e10cSrcweir TYPEINIT1(SbJScriptModule,SbModule)
448*cdf0e10cSrcweir TYPEINIT1(SbJScriptMethod,SbMethod)
449*cdf0e10cSrcweir TYPEINIT1(SbObjModule,SbModule)
450*cdf0e10cSrcweir TYPEINIT1(SbUserFormModule,SbObjModule)
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir typedef std::vector<HighlightPortion> HighlightPortions;
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir uno::Reference< frame::XModel > getDocumentModel( StarBASIC* pb )
455*cdf0e10cSrcweir {
456*cdf0e10cSrcweir     uno::Reference< frame::XModel > xModel;
457*cdf0e10cSrcweir     if( pb && pb->IsDocBasic() )
458*cdf0e10cSrcweir     {
459*cdf0e10cSrcweir         uno::Any aDoc;
460*cdf0e10cSrcweir         if( pb->GetUNOConstant( "ThisComponent", aDoc ) )
461*cdf0e10cSrcweir             xModel.set( aDoc, uno::UNO_QUERY );
462*cdf0e10cSrcweir     }
463*cdf0e10cSrcweir     return xModel;
464*cdf0e10cSrcweir }
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir uno::Reference< vba::XVBACompatibility > getVBACompatibility( const uno::Reference< frame::XModel >& rxModel )
467*cdf0e10cSrcweir {
468*cdf0e10cSrcweir     uno::Reference< vba::XVBACompatibility > xVBACompat;
469*cdf0e10cSrcweir     try
470*cdf0e10cSrcweir     {
471*cdf0e10cSrcweir         uno::Reference< beans::XPropertySet > xModelProps( rxModel, uno::UNO_QUERY_THROW );
472*cdf0e10cSrcweir         xVBACompat.set( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ), uno::UNO_QUERY );
473*cdf0e10cSrcweir     }
474*cdf0e10cSrcweir     catch( uno::Exception& )
475*cdf0e10cSrcweir     {
476*cdf0e10cSrcweir     }
477*cdf0e10cSrcweir     return xVBACompat;
478*cdf0e10cSrcweir }
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir bool getDefaultVBAMode( StarBASIC* pb )
481*cdf0e10cSrcweir {
482*cdf0e10cSrcweir     uno::Reference< vba::XVBACompatibility > xVBACompat = getVBACompatibility( getDocumentModel( pb ) );
483*cdf0e10cSrcweir     return xVBACompat.is() && xVBACompat->getVBACompatibilityMode();
484*cdf0e10cSrcweir }
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir class AsyncQuitHandler
487*cdf0e10cSrcweir {
488*cdf0e10cSrcweir     AsyncQuitHandler() {}
489*cdf0e10cSrcweir     AsyncQuitHandler( const AsyncQuitHandler&);
490*cdf0e10cSrcweir public:
491*cdf0e10cSrcweir     static AsyncQuitHandler& instance()
492*cdf0e10cSrcweir     {
493*cdf0e10cSrcweir         static AsyncQuitHandler dInst;
494*cdf0e10cSrcweir         return dInst;
495*cdf0e10cSrcweir     }
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir     void QuitApplication()
498*cdf0e10cSrcweir     {
499*cdf0e10cSrcweir         uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
500*cdf0e10cSrcweir         if ( xFactory.is() )
501*cdf0e10cSrcweir 	{
502*cdf0e10cSrcweir             uno::Reference< frame::XDesktop > xDeskTop( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ) ), uno::UNO_QUERY );
503*cdf0e10cSrcweir            if ( xDeskTop.is() )
504*cdf0e10cSrcweir                xDeskTop->terminate();
505*cdf0e10cSrcweir         }
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir     DECL_LINK( OnAsyncQuit, void* );
508*cdf0e10cSrcweir };
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir IMPL_LINK( AsyncQuitHandler, OnAsyncQuit, void*, /*pNull*/ )
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir     QuitApplication();
513*cdf0e10cSrcweir     return 0L;
514*cdf0e10cSrcweir }
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir // Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
519*cdf0e10cSrcweir // Elemente von anderen Modulen aus gefunden werden koennen.
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir SbModule::SbModule( const String& rName,  sal_Bool bVBACompat )
522*cdf0e10cSrcweir 		 : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ),
523*cdf0e10cSrcweir 		   pImage( NULL ), pBreaks( NULL ), pClassData( NULL ), mbVBACompat( bVBACompat ),  pDocObject( NULL ), bIsProxyModule( false )
524*cdf0e10cSrcweir {
525*cdf0e10cSrcweir 	SetName( rName );
526*cdf0e10cSrcweir 	SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
527*cdf0e10cSrcweir 	SetModuleType( script::ModuleType::NORMAL );
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir 	// #i92642: Set name property to intitial name
530*cdf0e10cSrcweir 	SbxVariable* pNameProp = pProps->Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
531*cdf0e10cSrcweir 	if( pNameProp != NULL )
532*cdf0e10cSrcweir 		pNameProp->PutString( GetName() );
533*cdf0e10cSrcweir }
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir SbModule::~SbModule()
536*cdf0e10cSrcweir {
537*cdf0e10cSrcweir     OSL_TRACE("Module named %s is destructing", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
538*cdf0e10cSrcweir 	if( pImage )
539*cdf0e10cSrcweir 		delete pImage;
540*cdf0e10cSrcweir 	if( pBreaks )
541*cdf0e10cSrcweir 		delete pBreaks;
542*cdf0e10cSrcweir 	if( pClassData )
543*cdf0e10cSrcweir 		delete pClassData;
544*cdf0e10cSrcweir         mxWrapper = NULL;
545*cdf0e10cSrcweir }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir uno::Reference< script::XInvocation >
548*cdf0e10cSrcweir SbModule::GetUnoModule()
549*cdf0e10cSrcweir {
550*cdf0e10cSrcweir     if ( !mxWrapper.is() )
551*cdf0e10cSrcweir         mxWrapper = new DocObjectWrapper( this );
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir     OSL_TRACE("Module named %s returning wrapper mxWrapper (0x%x)", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mxWrapper.get() );
554*cdf0e10cSrcweir     return mxWrapper;
555*cdf0e10cSrcweir }
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir sal_Bool SbModule::IsCompiled() const
558*cdf0e10cSrcweir {
559*cdf0e10cSrcweir 	return sal_Bool( pImage != 0 );
560*cdf0e10cSrcweir }
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir const SbxObject* SbModule::FindType( String aTypeName ) const
563*cdf0e10cSrcweir {
564*cdf0e10cSrcweir 	return pImage ? pImage->FindType( aTypeName ) : NULL;
565*cdf0e10cSrcweir }
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir // Aus dem Codegenerator: Loeschen des Images und Invalidieren der Entries
569*cdf0e10cSrcweir 
570*cdf0e10cSrcweir void SbModule::StartDefinitions()
571*cdf0e10cSrcweir {
572*cdf0e10cSrcweir 	delete pImage; pImage = NULL;
573*cdf0e10cSrcweir 	if( pClassData )
574*cdf0e10cSrcweir 		pClassData->clear();
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir 	// Methoden und Properties bleiben erhalten, sind jedoch ungueltig
577*cdf0e10cSrcweir 	// schliesslich sind ja u.U. die Infos belegt
578*cdf0e10cSrcweir 	sal_uInt16 i;
579*cdf0e10cSrcweir 	for( i = 0; i < pMethods->Count(); i++ )
580*cdf0e10cSrcweir 	{
581*cdf0e10cSrcweir 		SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
582*cdf0e10cSrcweir 		if( p )
583*cdf0e10cSrcweir 			p->bInvalid = sal_True;
584*cdf0e10cSrcweir 	}
585*cdf0e10cSrcweir 	for( i = 0; i < pProps->Count(); )
586*cdf0e10cSrcweir 	{
587*cdf0e10cSrcweir 		SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
588*cdf0e10cSrcweir 		if( p )
589*cdf0e10cSrcweir 			pProps->Remove( i );
590*cdf0e10cSrcweir 		else
591*cdf0e10cSrcweir 			i++;
592*cdf0e10cSrcweir 	}
593*cdf0e10cSrcweir }
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir // Methode anfordern/anlegen
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir SbMethod* SbModule::GetMethod( const String& rName, SbxDataType t )
598*cdf0e10cSrcweir {
599*cdf0e10cSrcweir 	SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
600*cdf0e10cSrcweir 	SbMethod* pMeth = p ? PTR_CAST(SbMethod,p) : NULL;
601*cdf0e10cSrcweir 	if( p && !pMeth )
602*cdf0e10cSrcweir 		pMethods->Remove( p );
603*cdf0e10cSrcweir 	if( !pMeth )
604*cdf0e10cSrcweir 	{
605*cdf0e10cSrcweir 		pMeth = new SbMethod( rName, t, this );
606*cdf0e10cSrcweir 		pMeth->SetParent( this );
607*cdf0e10cSrcweir 		pMeth->SetFlags( SBX_READ );
608*cdf0e10cSrcweir 		pMethods->Put( pMeth, pMethods->Count() );
609*cdf0e10cSrcweir 		StartListening( pMeth->GetBroadcaster(), sal_True );
610*cdf0e10cSrcweir 	}
611*cdf0e10cSrcweir 	// Per Default ist die Methode GUELTIG, da sie auch vom Compiler
612*cdf0e10cSrcweir 	// (Codegenerator) erzeugt werden kann
613*cdf0e10cSrcweir 	pMeth->bInvalid = sal_False;
614*cdf0e10cSrcweir 	pMeth->ResetFlag( SBX_FIXED );
615*cdf0e10cSrcweir 	pMeth->SetFlag( SBX_WRITE );
616*cdf0e10cSrcweir 	pMeth->SetType( t );
617*cdf0e10cSrcweir 	pMeth->ResetFlag( SBX_WRITE );
618*cdf0e10cSrcweir 	if( t != SbxVARIANT )
619*cdf0e10cSrcweir 		pMeth->SetFlag( SBX_FIXED );
620*cdf0e10cSrcweir 	return pMeth;
621*cdf0e10cSrcweir }
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir // Property anfordern/anlegen
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir SbProperty* SbModule::GetProperty( const String& rName, SbxDataType t )
626*cdf0e10cSrcweir {
627*cdf0e10cSrcweir 	SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
628*cdf0e10cSrcweir 	SbProperty* pProp = p ? PTR_CAST(SbProperty,p) : NULL;
629*cdf0e10cSrcweir 	if( p && !pProp )
630*cdf0e10cSrcweir 		pProps->Remove( p );
631*cdf0e10cSrcweir 	if( !pProp )
632*cdf0e10cSrcweir 	{
633*cdf0e10cSrcweir 		pProp = new SbProperty( rName, t, this );
634*cdf0e10cSrcweir 		pProp->SetFlag( SBX_READWRITE );
635*cdf0e10cSrcweir 		pProp->SetParent( this );
636*cdf0e10cSrcweir 		pProps->Put( pProp, pProps->Count() );
637*cdf0e10cSrcweir 		StartListening( pProp->GetBroadcaster(), sal_True );
638*cdf0e10cSrcweir 	}
639*cdf0e10cSrcweir 	return pProp;
640*cdf0e10cSrcweir }
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir SbProcedureProperty* SbModule::GetProcedureProperty
643*cdf0e10cSrcweir 	( const String& rName, SbxDataType t )
644*cdf0e10cSrcweir {
645*cdf0e10cSrcweir 	SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
646*cdf0e10cSrcweir 	SbProcedureProperty* pProp = p ? PTR_CAST(SbProcedureProperty,p) : NULL;
647*cdf0e10cSrcweir 	if( p && !pProp )
648*cdf0e10cSrcweir 		pProps->Remove( p );
649*cdf0e10cSrcweir 	if( !pProp )
650*cdf0e10cSrcweir 	{
651*cdf0e10cSrcweir 		pProp = new SbProcedureProperty( rName, t );
652*cdf0e10cSrcweir 		pProp->SetFlag( SBX_READWRITE );
653*cdf0e10cSrcweir 		pProp->SetParent( this );
654*cdf0e10cSrcweir 		pProps->Put( pProp, pProps->Count() );
655*cdf0e10cSrcweir 		StartListening( pProp->GetBroadcaster(), sal_True );
656*cdf0e10cSrcweir 	}
657*cdf0e10cSrcweir 	return pProp;
658*cdf0e10cSrcweir }
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir SbIfaceMapperMethod* SbModule::GetIfaceMapperMethod
661*cdf0e10cSrcweir 	( const String& rName, SbMethod* pImplMeth )
662*cdf0e10cSrcweir {
663*cdf0e10cSrcweir 	SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
664*cdf0e10cSrcweir 	SbIfaceMapperMethod* pMapperMethod = p ? PTR_CAST(SbIfaceMapperMethod,p) : NULL;
665*cdf0e10cSrcweir 	if( p && !pMapperMethod )
666*cdf0e10cSrcweir 		pMethods->Remove( p );
667*cdf0e10cSrcweir 	if( !pMapperMethod )
668*cdf0e10cSrcweir 	{
669*cdf0e10cSrcweir 		pMapperMethod = new SbIfaceMapperMethod( rName, pImplMeth );
670*cdf0e10cSrcweir 		pMapperMethod->SetParent( this );
671*cdf0e10cSrcweir 		pMapperMethod->SetFlags( SBX_READ );
672*cdf0e10cSrcweir 		pMethods->Put( pMapperMethod, pMethods->Count() );
673*cdf0e10cSrcweir 	}
674*cdf0e10cSrcweir 	pMapperMethod->bInvalid = sal_False;
675*cdf0e10cSrcweir 	return pMapperMethod;
676*cdf0e10cSrcweir }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir SbIfaceMapperMethod::~SbIfaceMapperMethod()
679*cdf0e10cSrcweir {
680*cdf0e10cSrcweir }
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir TYPEINIT1(SbIfaceMapperMethod,SbMethod)
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir // Aus dem Codegenerator: Ungueltige Eintraege entfernen
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir void SbModule::EndDefinitions( sal_Bool bNewState )
688*cdf0e10cSrcweir {
689*cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < pMethods->Count(); )
690*cdf0e10cSrcweir 	{
691*cdf0e10cSrcweir 		SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
692*cdf0e10cSrcweir 		if( p )
693*cdf0e10cSrcweir 		{
694*cdf0e10cSrcweir 			if( p->bInvalid )
695*cdf0e10cSrcweir 				pMethods->Remove( p );
696*cdf0e10cSrcweir 			else
697*cdf0e10cSrcweir 			{
698*cdf0e10cSrcweir 				p->bInvalid = bNewState;
699*cdf0e10cSrcweir 				i++;
700*cdf0e10cSrcweir 			}
701*cdf0e10cSrcweir 		}
702*cdf0e10cSrcweir 		else
703*cdf0e10cSrcweir 			i++;
704*cdf0e10cSrcweir 	}
705*cdf0e10cSrcweir 	SetModified( sal_True );
706*cdf0e10cSrcweir }
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir void SbModule::Clear()
709*cdf0e10cSrcweir {
710*cdf0e10cSrcweir 	delete pImage; pImage = NULL;
711*cdf0e10cSrcweir 	if( pClassData )
712*cdf0e10cSrcweir 		pClassData->clear();
713*cdf0e10cSrcweir 	SbxObject::Clear();
714*cdf0e10cSrcweir }
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir SbxVariable* SbModule::Find( const XubString& rName, SbxClassType t )
718*cdf0e10cSrcweir {
719*cdf0e10cSrcweir 	// make sure a search in an uninstatiated class module will fail
720*cdf0e10cSrcweir 	SbxVariable* pRes = SbxObject::Find( rName, t );
721*cdf0e10cSrcweir 	if ( bIsProxyModule && !GetSbData()->bRunInit )
722*cdf0e10cSrcweir 		return NULL;
723*cdf0e10cSrcweir 	if( !pRes && pImage )
724*cdf0e10cSrcweir 	{
725*cdf0e10cSrcweir 		SbiInstance* pInst = pINST;
726*cdf0e10cSrcweir 		if( pInst && pInst->IsCompatibility() )
727*cdf0e10cSrcweir 		{
728*cdf0e10cSrcweir 			// Put enum types as objects into module,
729*cdf0e10cSrcweir 			// allows MyEnum.First notation
730*cdf0e10cSrcweir 			SbxArrayRef xArray = pImage->GetEnums();
731*cdf0e10cSrcweir 			if( xArray.Is() )
732*cdf0e10cSrcweir 			{
733*cdf0e10cSrcweir 				SbxVariable* pEnumVar = xArray->Find( rName, SbxCLASS_DONTCARE );
734*cdf0e10cSrcweir 				SbxObject* pEnumObject = PTR_CAST( SbxObject, pEnumVar );
735*cdf0e10cSrcweir 				if( pEnumObject )
736*cdf0e10cSrcweir 				{
737*cdf0e10cSrcweir 					bool bPrivate = pEnumObject->IsSet( SBX_PRIVATE );
738*cdf0e10cSrcweir 					String aEnumName = pEnumObject->GetName();
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir 					pRes = new SbxVariable( SbxOBJECT );
741*cdf0e10cSrcweir 					pRes->SetName( aEnumName );
742*cdf0e10cSrcweir 					pRes->SetParent( this );
743*cdf0e10cSrcweir 					pRes->SetFlag( SBX_READ );
744*cdf0e10cSrcweir 					if( bPrivate )
745*cdf0e10cSrcweir 						pRes->SetFlag( SBX_PRIVATE );
746*cdf0e10cSrcweir 					pRes->PutObject( pEnumObject );
747*cdf0e10cSrcweir 				}
748*cdf0e10cSrcweir 			}
749*cdf0e10cSrcweir 		}
750*cdf0e10cSrcweir 	}
751*cdf0e10cSrcweir 	return pRes;
752*cdf0e10cSrcweir }
753*cdf0e10cSrcweir 
754*cdf0e10cSrcweir const ::rtl::OUString& SbModule::GetSource32() const
755*cdf0e10cSrcweir {
756*cdf0e10cSrcweir 	return aOUSource;
757*cdf0e10cSrcweir }
758*cdf0e10cSrcweir 
759*cdf0e10cSrcweir const String& SbModule::GetSource() const
760*cdf0e10cSrcweir {
761*cdf0e10cSrcweir     static String aRetStr;
762*cdf0e10cSrcweir     aRetStr = aOUSource;
763*cdf0e10cSrcweir 	return aRetStr;
764*cdf0e10cSrcweir }
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir // Parent und BASIC sind eins!
767*cdf0e10cSrcweir 
768*cdf0e10cSrcweir void SbModule::SetParent( SbxObject* p )
769*cdf0e10cSrcweir {
770*cdf0e10cSrcweir 	// #118083: Assertion is not valid any more
771*cdf0e10cSrcweir 	// DBG_ASSERT( !p || p->IsA( TYPE(StarBASIC) ), "SbModules nur in BASIC eintragen" );
772*cdf0e10cSrcweir 	pParent = p;
773*cdf0e10cSrcweir }
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
776*cdf0e10cSrcweir 						   const SfxHint& rHint, const TypeId& rHintType )
777*cdf0e10cSrcweir {
778*cdf0e10cSrcweir 	const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
779*cdf0e10cSrcweir 	if( pHint )
780*cdf0e10cSrcweir 	{
781*cdf0e10cSrcweir 		SbxVariable* pVar = pHint->GetVar();
782*cdf0e10cSrcweir 		SbProperty* pProp = PTR_CAST(SbProperty,pVar);
783*cdf0e10cSrcweir 		SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
784*cdf0e10cSrcweir 		if( pProp )
785*cdf0e10cSrcweir 		{
786*cdf0e10cSrcweir 			if( pProp->GetModule() != this )
787*cdf0e10cSrcweir 				SetError( SbxERR_BAD_ACTION );
788*cdf0e10cSrcweir 		}
789*cdf0e10cSrcweir 		else if( pMeth )
790*cdf0e10cSrcweir 		{
791*cdf0e10cSrcweir 			if( pHint->GetId() == SBX_HINT_DATAWANTED )
792*cdf0e10cSrcweir 			{
793*cdf0e10cSrcweir 				if( pMeth->bInvalid && !Compile() )
794*cdf0e10cSrcweir 					// Auto-Compile hat nicht geklappt!
795*cdf0e10cSrcweir 					StarBASIC::Error( SbERR_BAD_PROP_VALUE );
796*cdf0e10cSrcweir 				else
797*cdf0e10cSrcweir 				{
798*cdf0e10cSrcweir 					// Aufruf eines Unterprogramms
799*cdf0e10cSrcweir 					SbModule* pOld = pMOD;
800*cdf0e10cSrcweir 					pMOD = this;
801*cdf0e10cSrcweir 					Run( (SbMethod*) pVar );
802*cdf0e10cSrcweir 					pMOD = pOld;
803*cdf0e10cSrcweir 				}
804*cdf0e10cSrcweir 			}
805*cdf0e10cSrcweir 		}
806*cdf0e10cSrcweir 		else
807*cdf0e10cSrcweir 		{
808*cdf0e10cSrcweir 			// #i92642: Special handling for name property to avoid
809*cdf0e10cSrcweir 			// side effects when using name as variable implicitely
810*cdf0e10cSrcweir 			bool bForwardToSbxObject = true;
811*cdf0e10cSrcweir 
812*cdf0e10cSrcweir 			sal_uIntPtr nId = pHint->GetId();
813*cdf0e10cSrcweir 			if( (nId == SBX_HINT_DATAWANTED || nId == SBX_HINT_DATACHANGED) &&
814*cdf0e10cSrcweir 				pVar->GetName().EqualsIgnoreCaseAscii( "name" ) )
815*cdf0e10cSrcweir 					bForwardToSbxObject = false;
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir 			if( bForwardToSbxObject )
818*cdf0e10cSrcweir 				SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
819*cdf0e10cSrcweir 		}
820*cdf0e10cSrcweir 	}
821*cdf0e10cSrcweir }
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir // Das Setzen der Source macht das Image ungueltig
824*cdf0e10cSrcweir // und scant die Methoden-Definitionen neu ein
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir void SbModule::SetSource( const String& r )
827*cdf0e10cSrcweir {
828*cdf0e10cSrcweir     SetSource32( r );
829*cdf0e10cSrcweir }
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir void SbModule::SetSource32( const ::rtl::OUString& r )
832*cdf0e10cSrcweir {
833*cdf0e10cSrcweir 	// Default basic mode to library container mode, but.. allow Option VBASupport 0/1 override
834*cdf0e10cSrcweir     SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) );
835*cdf0e10cSrcweir 	aOUSource = r;
836*cdf0e10cSrcweir 	StartDefinitions();
837*cdf0e10cSrcweir 	SbiTokenizer aTok( r );
838*cdf0e10cSrcweir 	while( !aTok.IsEof() )
839*cdf0e10cSrcweir 	{
840*cdf0e10cSrcweir 		SbiToken eEndTok = NIL;
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir 		// Suchen nach SUB oder FUNCTION
843*cdf0e10cSrcweir 		SbiToken eLastTok = NIL;
844*cdf0e10cSrcweir 		while( !aTok.IsEof() )
845*cdf0e10cSrcweir 		{
846*cdf0e10cSrcweir 			// #32385: Nicht bei declare
847*cdf0e10cSrcweir 			SbiToken eCurTok = aTok.Next();
848*cdf0e10cSrcweir 			if( eLastTok != DECLARE )
849*cdf0e10cSrcweir 			{
850*cdf0e10cSrcweir 				if( eCurTok == SUB )
851*cdf0e10cSrcweir 				{
852*cdf0e10cSrcweir 					eEndTok = ENDSUB; break;
853*cdf0e10cSrcweir 				}
854*cdf0e10cSrcweir 				if( eCurTok == FUNCTION )
855*cdf0e10cSrcweir 				{
856*cdf0e10cSrcweir 					eEndTok = ENDFUNC; break;
857*cdf0e10cSrcweir 				}
858*cdf0e10cSrcweir 				if( eCurTok == PROPERTY )
859*cdf0e10cSrcweir 				{
860*cdf0e10cSrcweir 					eEndTok = ENDPROPERTY; break;
861*cdf0e10cSrcweir 				}
862*cdf0e10cSrcweir 				if( eCurTok == OPTION )
863*cdf0e10cSrcweir 				{
864*cdf0e10cSrcweir 					eCurTok = aTok.Next();
865*cdf0e10cSrcweir 					if( eCurTok == COMPATIBLE )
866*cdf0e10cSrcweir 						aTok.SetCompatible( true );
867*cdf0e10cSrcweir 					else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) )
868*cdf0e10cSrcweir 					{
869*cdf0e10cSrcweir         					sal_Bool bIsVBA = ( aTok.GetDbl()== 1 );
870*cdf0e10cSrcweir         					SetVBACompat( bIsVBA );
871*cdf0e10cSrcweir 						aTok.SetCompatible( bIsVBA );
872*cdf0e10cSrcweir 					}
873*cdf0e10cSrcweir 				}
874*cdf0e10cSrcweir 			}
875*cdf0e10cSrcweir 			eLastTok = eCurTok;
876*cdf0e10cSrcweir 		}
877*cdf0e10cSrcweir 		// Definition der Methode
878*cdf0e10cSrcweir 		SbMethod* pMeth = NULL;
879*cdf0e10cSrcweir 		if( eEndTok != NIL )
880*cdf0e10cSrcweir 		{
881*cdf0e10cSrcweir 			sal_uInt16 nLine1 = aTok.GetLine();
882*cdf0e10cSrcweir 			if( aTok.Next() == SYMBOL )
883*cdf0e10cSrcweir 			{
884*cdf0e10cSrcweir 				String aName_( aTok.GetSym() );
885*cdf0e10cSrcweir 				SbxDataType t = aTok.GetType();
886*cdf0e10cSrcweir 				if( t == SbxVARIANT && eEndTok == ENDSUB )
887*cdf0e10cSrcweir 					t = SbxVOID;
888*cdf0e10cSrcweir 				pMeth = GetMethod( aName_, t );
889*cdf0e10cSrcweir 				pMeth->nLine1 = pMeth->nLine2 = nLine1;
890*cdf0e10cSrcweir 				// Die Methode ist erst mal GUELTIG
891*cdf0e10cSrcweir 				pMeth->bInvalid = sal_False;
892*cdf0e10cSrcweir 			}
893*cdf0e10cSrcweir 			else
894*cdf0e10cSrcweir 				eEndTok = NIL;
895*cdf0e10cSrcweir 		}
896*cdf0e10cSrcweir 		// Skip bis END SUB/END FUNCTION
897*cdf0e10cSrcweir 		if( eEndTok != NIL )
898*cdf0e10cSrcweir 		{
899*cdf0e10cSrcweir 			while( !aTok.IsEof() )
900*cdf0e10cSrcweir 			{
901*cdf0e10cSrcweir 				if( aTok.Next() == eEndTok )
902*cdf0e10cSrcweir 				{
903*cdf0e10cSrcweir 					pMeth->nLine2 = aTok.GetLine();
904*cdf0e10cSrcweir 					break;
905*cdf0e10cSrcweir 				}
906*cdf0e10cSrcweir 			}
907*cdf0e10cSrcweir 			if( aTok.IsEof() )
908*cdf0e10cSrcweir 				pMeth->nLine2 = aTok.GetLine();
909*cdf0e10cSrcweir 		}
910*cdf0e10cSrcweir 	}
911*cdf0e10cSrcweir 	EndDefinitions( sal_True );
912*cdf0e10cSrcweir }
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir void SbModule::SetComment( const String& r )
915*cdf0e10cSrcweir {
916*cdf0e10cSrcweir 	aComment = r;
917*cdf0e10cSrcweir 	SetModified( sal_True );
918*cdf0e10cSrcweir }
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir SbMethod* SbModule::GetFunctionForLine( sal_uInt16 nLine )
921*cdf0e10cSrcweir {
922*cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
923*cdf0e10cSrcweir 	{
924*cdf0e10cSrcweir 		SbMethod* p = (SbMethod*) pMethods->Get( i );
925*cdf0e10cSrcweir 		if( p->GetSbxId() == SBXID_BASICMETHOD )
926*cdf0e10cSrcweir 		{
927*cdf0e10cSrcweir 			if( nLine >= p->nLine1 && nLine <= p->nLine2 )
928*cdf0e10cSrcweir 				return p;
929*cdf0e10cSrcweir 		}
930*cdf0e10cSrcweir 	}
931*cdf0e10cSrcweir 	return NULL;
932*cdf0e10cSrcweir }
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir // Ausstrahlen eines Hints an alle Basics
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir static void _SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
937*cdf0e10cSrcweir {
938*cdf0e10cSrcweir 	// Selbst ein BASIC?
939*cdf0e10cSrcweir 	if( pObj->IsA( TYPE(StarBASIC) ) && pObj->IsBroadcaster() )
940*cdf0e10cSrcweir 		pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) );
941*cdf0e10cSrcweir 	// Dann die Unterobjekte fragen
942*cdf0e10cSrcweir 	SbxArray* pObjs = pObj->GetObjects();
943*cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
944*cdf0e10cSrcweir 	{
945*cdf0e10cSrcweir 		SbxVariable* pVar = pObjs->Get( i );
946*cdf0e10cSrcweir 		if( pVar->IsA( TYPE(SbxObject) ) )
947*cdf0e10cSrcweir 			_SendHint( PTR_CAST(SbxObject,pVar), nId, p );
948*cdf0e10cSrcweir 	}
949*cdf0e10cSrcweir }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir static void SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
952*cdf0e10cSrcweir {
953*cdf0e10cSrcweir 	while( pObj->GetParent() )
954*cdf0e10cSrcweir 		pObj = pObj->GetParent();
955*cdf0e10cSrcweir 	_SendHint( pObj, nId, p );
956*cdf0e10cSrcweir }
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir // #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
959*cdf0e10cSrcweir // beim Programm-Ende freigeben, damit nichts gehalten wird.
960*cdf0e10cSrcweir void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic )
961*cdf0e10cSrcweir {
962*cdf0e10cSrcweir 	// return-Wert von CreateUnoService loeschen
963*cdf0e10cSrcweir 	static String aName( RTL_CONSTASCII_USTRINGPARAM("CreateUnoService") );
964*cdf0e10cSrcweir 	SbxVariable* pVar = pBasic->GetRtl()->Find( aName, SbxCLASS_METHOD );
965*cdf0e10cSrcweir 	if( pVar )
966*cdf0e10cSrcweir 		pVar->SbxValue::Clear();
967*cdf0e10cSrcweir 
968*cdf0e10cSrcweir 	// return-Wert von CreateUnoDialog loeschen
969*cdf0e10cSrcweir 	static String aName2( RTL_CONSTASCII_USTRINGPARAM("CreateUnoDialog") );
970*cdf0e10cSrcweir 	pVar = pBasic->GetRtl()->Find( aName2, SbxCLASS_METHOD );
971*cdf0e10cSrcweir 	if( pVar )
972*cdf0e10cSrcweir 		pVar->SbxValue::Clear();
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir 	// return-Wert von CDec loeschen
975*cdf0e10cSrcweir 	static String aName3( RTL_CONSTASCII_USTRINGPARAM("CDec") );
976*cdf0e10cSrcweir 	pVar = pBasic->GetRtl()->Find( aName3, SbxCLASS_METHOD );
977*cdf0e10cSrcweir 	if( pVar )
978*cdf0e10cSrcweir 		pVar->SbxValue::Clear();
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir 	// return-Wert von CreateObject loeschen
981*cdf0e10cSrcweir 	static String aName4( RTL_CONSTASCII_USTRINGPARAM("CreateObject") );
982*cdf0e10cSrcweir 	pVar = pBasic->GetRtl()->Find( aName4, SbxCLASS_METHOD );
983*cdf0e10cSrcweir 	if( pVar )
984*cdf0e10cSrcweir 		pVar->SbxValue::Clear();
985*cdf0e10cSrcweir 
986*cdf0e10cSrcweir 	// Ueber alle Sub-Basics gehen
987*cdf0e10cSrcweir 	SbxArray* pObjs = pBasic->GetObjects();
988*cdf0e10cSrcweir 	sal_uInt16 nCount = pObjs->Count();
989*cdf0e10cSrcweir 	for( sal_uInt16 i = 0 ; i < nCount ; i++ )
990*cdf0e10cSrcweir 	{
991*cdf0e10cSrcweir 		SbxVariable* pObjVar = pObjs->Get( i );
992*cdf0e10cSrcweir 		StarBASIC* pSubBasic = PTR_CAST( StarBASIC, pObjVar );
993*cdf0e10cSrcweir 		if( pSubBasic )
994*cdf0e10cSrcweir 			ClearUnoObjectsInRTL_Impl_Rek( pSubBasic );
995*cdf0e10cSrcweir 	}
996*cdf0e10cSrcweir }
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
999*cdf0e10cSrcweir {
1000*cdf0e10cSrcweir 	// #67781 Rueckgabewerte der Uno-Methoden loeschen
1001*cdf0e10cSrcweir 	clearUnoMethods();
1002*cdf0e10cSrcweir 	clearUnoServiceCtors();
1003*cdf0e10cSrcweir 
1004*cdf0e10cSrcweir 	ClearUnoObjectsInRTL_Impl_Rek( pBasic );
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir     // Oberstes Basic suchen
1007*cdf0e10cSrcweir 	SbxObject* p = pBasic;
1008*cdf0e10cSrcweir 	while( p->GetParent() )
1009*cdf0e10cSrcweir 		p = p->GetParent();
1010*cdf0e10cSrcweir     if( ((StarBASIC*)p) != pBasic )
1011*cdf0e10cSrcweir 	    ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p );
1012*cdf0e10cSrcweir }
1013*cdf0e10cSrcweir sal_Bool SbModule::IsVBACompat() const
1014*cdf0e10cSrcweir {
1015*cdf0e10cSrcweir 	return mbVBACompat;
1016*cdf0e10cSrcweir }
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir void SbModule::SetVBACompat( sal_Bool bCompat )
1019*cdf0e10cSrcweir {
1020*cdf0e10cSrcweir     if( mbVBACompat != bCompat )
1021*cdf0e10cSrcweir     {
1022*cdf0e10cSrcweir         mbVBACompat = bCompat;
1023*cdf0e10cSrcweir         // initialize VBA document API
1024*cdf0e10cSrcweir         if( mbVBACompat ) try
1025*cdf0e10cSrcweir         {
1026*cdf0e10cSrcweir             StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
1027*cdf0e10cSrcweir             uno::Reference< lang::XMultiServiceFactory > xFactory( getDocumentModel( pBasic ), uno::UNO_QUERY_THROW );
1028*cdf0e10cSrcweir             xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
1029*cdf0e10cSrcweir         }
1030*cdf0e10cSrcweir         catch( Exception& )
1031*cdf0e10cSrcweir         {
1032*cdf0e10cSrcweir         }
1033*cdf0e10cSrcweir     }
1034*cdf0e10cSrcweir }
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir // Ausfuehren eines BASIC-Unterprogramms
1037*cdf0e10cSrcweir sal_uInt16 SbModule::Run( SbMethod* pMeth )
1038*cdf0e10cSrcweir {
1039*cdf0e10cSrcweir 	static sal_uInt16 nMaxCallLevel = 0;
1040*cdf0e10cSrcweir 	static String aMSOMacroRuntimeLibName = String::CreateFromAscii( "Launcher" );
1041*cdf0e10cSrcweir 	static String aMSOMacroRuntimeAppSymbol = String::CreateFromAscii( "Application" );
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir 	sal_uInt16 nRes = 0;
1044*cdf0e10cSrcweir 	sal_Bool bDelInst = sal_Bool( pINST == NULL );
1045*cdf0e10cSrcweir 	StarBASICRef xBasic;
1046*cdf0e10cSrcweir 	uno::Reference< frame::XModel > xModel;
1047*cdf0e10cSrcweir 	uno::Reference< script::vba::XVBACompatibility > xVBACompat;
1048*cdf0e10cSrcweir 	if( bDelInst )
1049*cdf0e10cSrcweir 	{
1050*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
1051*cdf0e10cSrcweir 		dbg_InitTrace();
1052*cdf0e10cSrcweir #endif
1053*cdf0e10cSrcweir 		// #32779: Basic waehrend der Ausfuehrung festhalten
1054*cdf0e10cSrcweir 		xBasic = (StarBASIC*) GetParent();
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir 		pINST = new SbiInstance( (StarBASIC*) GetParent() );
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir         /*  If a VBA script in a document is started, get the VBA compatibility
1059*cdf0e10cSrcweir             interface from the document Basic library container, and notify all
1060*cdf0e10cSrcweir             VBA script listeners about the started script. */
1061*cdf0e10cSrcweir         if( mbVBACompat )
1062*cdf0e10cSrcweir         {
1063*cdf0e10cSrcweir             StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
1064*cdf0e10cSrcweir             if( pBasic && pBasic->IsDocBasic() ) try
1065*cdf0e10cSrcweir             {
1066*cdf0e10cSrcweir                 xModel.set( getDocumentModel( pBasic ), uno::UNO_SET_THROW );
1067*cdf0e10cSrcweir                 xVBACompat.set( getVBACompatibility( xModel ), uno::UNO_SET_THROW );
1068*cdf0e10cSrcweir                 xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::SCRIPT_STARTED, GetName() );
1069*cdf0e10cSrcweir             }
1070*cdf0e10cSrcweir             catch( uno::Exception& )
1071*cdf0e10cSrcweir             {
1072*cdf0e10cSrcweir             }
1073*cdf0e10cSrcweir         }
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir 		// Launcher problem
1076*cdf0e10cSrcweir         // i80726 The Find below will genarate an error in Testtool so we reset it unless there was one before already
1077*cdf0e10cSrcweir         sal_Bool bWasError = SbxBase::GetError() != 0;
1078*cdf0e10cSrcweir 		SbxVariable* pMSOMacroRuntimeLibVar = Find( aMSOMacroRuntimeLibName, SbxCLASS_OBJECT );
1079*cdf0e10cSrcweir         if ( !bWasError && (SbxBase::GetError() == SbxERR_PROC_UNDEFINED) )
1080*cdf0e10cSrcweir             SbxBase::ResetError();
1081*cdf0e10cSrcweir 		if( pMSOMacroRuntimeLibVar )
1082*cdf0e10cSrcweir 		{
1083*cdf0e10cSrcweir 			StarBASIC* pMSOMacroRuntimeLib = PTR_CAST(StarBASIC,pMSOMacroRuntimeLibVar);
1084*cdf0e10cSrcweir 			if( pMSOMacroRuntimeLib )
1085*cdf0e10cSrcweir 			{
1086*cdf0e10cSrcweir 				sal_uInt16 nGblFlag = pMSOMacroRuntimeLib->GetFlags() & SBX_GBLSEARCH;
1087*cdf0e10cSrcweir 				pMSOMacroRuntimeLib->ResetFlag( SBX_GBLSEARCH );
1088*cdf0e10cSrcweir 				SbxVariable* pAppSymbol = pMSOMacroRuntimeLib->Find( aMSOMacroRuntimeAppSymbol, SbxCLASS_METHOD );
1089*cdf0e10cSrcweir 				pMSOMacroRuntimeLib->SetFlag( nGblFlag );
1090*cdf0e10cSrcweir 				if( pAppSymbol )
1091*cdf0e10cSrcweir 				{
1092*cdf0e10cSrcweir 					pMSOMacroRuntimeLib->SetFlag( SBX_EXTSEARCH );		// Could have been disabled before
1093*cdf0e10cSrcweir 					GetSbData()->pMSOMacroRuntimLib = pMSOMacroRuntimeLib;
1094*cdf0e10cSrcweir 				}
1095*cdf0e10cSrcweir 			}
1096*cdf0e10cSrcweir 		}
1097*cdf0e10cSrcweir 
1098*cdf0e10cSrcweir 		// Error-Stack loeschen
1099*cdf0e10cSrcweir 		SbErrorStack*& rErrStack = GetSbData()->pErrStack;
1100*cdf0e10cSrcweir 		delete rErrStack;
1101*cdf0e10cSrcweir 		rErrStack = NULL;
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir 		if( nMaxCallLevel == 0 )
1104*cdf0e10cSrcweir 		{
1105*cdf0e10cSrcweir #ifdef UNX
1106*cdf0e10cSrcweir 		  struct rlimit rl;
1107*cdf0e10cSrcweir 		  getrlimit ( RLIMIT_STACK, &rl );
1108*cdf0e10cSrcweir 		  // printf( "RLIMIT_STACK = %ld\n", rl.rlim_cur );
1109*cdf0e10cSrcweir #endif
1110*cdf0e10cSrcweir #if defined LINUX
1111*cdf0e10cSrcweir 		  // Empiric value, 900 = needed bytes/Basic call level
1112*cdf0e10cSrcweir 		  // for Linux including 10% safety margin
1113*cdf0e10cSrcweir 		  nMaxCallLevel = rl.rlim_cur / 900;
1114*cdf0e10cSrcweir #elif defined SOLARIS
1115*cdf0e10cSrcweir 		  // Empiric value, 1650 = needed bytes/Basic call level
1116*cdf0e10cSrcweir 		  // for Solaris including 10% safety margin
1117*cdf0e10cSrcweir 		  nMaxCallLevel = rl.rlim_cur / 1650;
1118*cdf0e10cSrcweir #elif defined WIN32
1119*cdf0e10cSrcweir 		  nMaxCallLevel = 5800;
1120*cdf0e10cSrcweir #else
1121*cdf0e10cSrcweir 		  nMaxCallLevel = MAXRECURSION;
1122*cdf0e10cSrcweir #endif
1123*cdf0e10cSrcweir 		}
1124*cdf0e10cSrcweir 	}
1125*cdf0e10cSrcweir 
1126*cdf0e10cSrcweir 	// Rekursion zu tief?
1127*cdf0e10cSrcweir 	if( ++pINST->nCallLvl <= nMaxCallLevel )
1128*cdf0e10cSrcweir 	{
1129*cdf0e10cSrcweir 		// Globale Variable in allen Mods definieren
1130*cdf0e10cSrcweir 		GlobalRunInit( /* bBasicStart = */ bDelInst );
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir 		// Trat ein Compiler-Fehler auf? Dann starten wir nicht
1133*cdf0e10cSrcweir 		if( GetSbData()->bGlobalInitErr == sal_False )
1134*cdf0e10cSrcweir 		{
1135*cdf0e10cSrcweir 			if( bDelInst )
1136*cdf0e10cSrcweir 			{
1137*cdf0e10cSrcweir 				SendHint( GetParent(), SBX_HINT_BASICSTART, pMeth );
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir 				// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
1140*cdf0e10cSrcweir 				// Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
1141*cdf0e10cSrcweir 				// BreakCallLevel ermitteln
1142*cdf0e10cSrcweir 				pINST->CalcBreakCallLevel( pMeth->GetDebugFlags() );
1143*cdf0e10cSrcweir 			}
1144*cdf0e10cSrcweir 
1145*cdf0e10cSrcweir 			SbModule* pOldMod = pMOD;
1146*cdf0e10cSrcweir 			pMOD = this;
1147*cdf0e10cSrcweir 			SbiRuntime* pRt = new SbiRuntime( this, pMeth, pMeth->nStart );
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
1150*cdf0e10cSrcweir 			dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl );
1151*cdf0e10cSrcweir #endif
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir 			pRt->pNext = pINST->pRun;
1154*cdf0e10cSrcweir 			if( pRt->pNext )
1155*cdf0e10cSrcweir 				pRt->pNext->block();
1156*cdf0e10cSrcweir 			pINST->pRun = pRt;
1157*cdf0e10cSrcweir 			if ( mbVBACompat )
1158*cdf0e10cSrcweir 			{
1159*cdf0e10cSrcweir 				pINST->EnableCompatibility( sal_True );
1160*cdf0e10cSrcweir 			}
1161*cdf0e10cSrcweir 			while( pRt->Step() ) {}
1162*cdf0e10cSrcweir 			if( pRt->pNext )
1163*cdf0e10cSrcweir 				pRt->pNext->unblock();
1164*cdf0e10cSrcweir 
1165*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
1166*cdf0e10cSrcweir 			bool bLeave = true;
1167*cdf0e10cSrcweir 			dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl, bLeave );
1168*cdf0e10cSrcweir #endif
1169*cdf0e10cSrcweir 
1170*cdf0e10cSrcweir 			// #63710 Durch ein anderes Thread-Handling bei Events kann es passieren,
1171*cdf0e10cSrcweir 			// dass show-Aufruf an einem Dialog zurueckkehrt (durch schliessen des
1172*cdf0e10cSrcweir 			// Dialogs per UI), BEVOR ein per Event ausgeloester weitergehender Call,
1173*cdf0e10cSrcweir 			// der in Basic weiter oben im Stack steht und auf einen Basic-Breakpoint
1174*cdf0e10cSrcweir 			// gelaufen ist, zurueckkehrt. Dann wird unten die Instanz zerstoert und
1175*cdf0e10cSrcweir 			// wenn das noch im Call stehende Basic weiterlaeuft, gibt es einen GPF.
1176*cdf0e10cSrcweir 			// Daher muss hier gewartet werden, bis andere Call zurueckkehrt.
1177*cdf0e10cSrcweir 			if( bDelInst )
1178*cdf0e10cSrcweir 			{
1179*cdf0e10cSrcweir 				// Hier mit 1 statt 0 vergleichen, da vor nCallLvl--
1180*cdf0e10cSrcweir 				while( pINST->nCallLvl != 1 )
1181*cdf0e10cSrcweir 					GetpApp()->Yield();
1182*cdf0e10cSrcweir 			}
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir 			nRes = sal_True;
1185*cdf0e10cSrcweir 			pINST->pRun = pRt->pNext;
1186*cdf0e10cSrcweir 			pINST->nCallLvl--;			// Call-Level wieder runter
1187*cdf0e10cSrcweir 
1188*cdf0e10cSrcweir 			// Gibt es eine uebergeordnete Runtime-Instanz?
1189*cdf0e10cSrcweir 			// Dann SbDEBUG_BREAK uebernehmen, wenn gesetzt
1190*cdf0e10cSrcweir 			SbiRuntime* pRtNext = pRt->pNext;
1191*cdf0e10cSrcweir 			if( pRtNext && (pRt->GetDebugFlags() & SbDEBUG_BREAK) )
1192*cdf0e10cSrcweir 				pRtNext->SetDebugFlags( SbDEBUG_BREAK );
1193*cdf0e10cSrcweir 
1194*cdf0e10cSrcweir 			delete pRt;
1195*cdf0e10cSrcweir 			pMOD = pOldMod;
1196*cdf0e10cSrcweir 			if( bDelInst )
1197*cdf0e10cSrcweir 			{
1198*cdf0e10cSrcweir 				// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
1199*cdf0e10cSrcweir 				// beim Programm-Ende freigeben, damit nichts gehalten wird.
1200*cdf0e10cSrcweir 				ClearUnoObjectsInRTL_Impl( xBasic );
1201*cdf0e10cSrcweir 
1202*cdf0e10cSrcweir 				clearNativeObjectWrapperVector();
1203*cdf0e10cSrcweir 
1204*cdf0e10cSrcweir 				DBG_ASSERT(pINST->nCallLvl==0,"BASIC-Call-Level > 0");
1205*cdf0e10cSrcweir 				delete pINST, pINST = NULL, bDelInst = sal_False;
1206*cdf0e10cSrcweir 
1207*cdf0e10cSrcweir 				// #i30690
1208*cdf0e10cSrcweir 				vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1209*cdf0e10cSrcweir 				SendHint( GetParent(), SBX_HINT_BASICSTOP, pMeth );
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir 		        GlobalRunDeInit();
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir #ifdef DBG_UTIL
1214*cdf0e10cSrcweir                 ResetCapturedAssertions();
1215*cdf0e10cSrcweir #endif
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir                 if( xVBACompat.is() )
1218*cdf0e10cSrcweir                 {
1219*cdf0e10cSrcweir                     // notify all VBA script listeners about the stopped script
1220*cdf0e10cSrcweir                     try
1221*cdf0e10cSrcweir                     {
1222*cdf0e10cSrcweir                         xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::SCRIPT_STOPPED, GetName() );
1223*cdf0e10cSrcweir                     }
1224*cdf0e10cSrcweir                     catch( uno::Exception& )
1225*cdf0e10cSrcweir                     {
1226*cdf0e10cSrcweir                     }
1227*cdf0e10cSrcweir                     // VBA always ensures screenupdating is enabled after completing
1228*cdf0e10cSrcweir                     ::basic::vba::lockControllersOfAllDocuments( xModel, sal_False );
1229*cdf0e10cSrcweir                     ::basic::vba::enableContainerWindowsOfAllDocuments( xModel, sal_True );
1230*cdf0e10cSrcweir                 }
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
1233*cdf0e10cSrcweir 				dbg_DeInitTrace();
1234*cdf0e10cSrcweir #endif
1235*cdf0e10cSrcweir 			}
1236*cdf0e10cSrcweir         }
1237*cdf0e10cSrcweir         else
1238*cdf0e10cSrcweir    			pINST->nCallLvl--;			// Call-Level wieder runter
1239*cdf0e10cSrcweir 	}
1240*cdf0e10cSrcweir 	else
1241*cdf0e10cSrcweir     {
1242*cdf0e10cSrcweir 		pINST->nCallLvl--;			// Call-Level wieder runter
1243*cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
1244*cdf0e10cSrcweir     }
1245*cdf0e10cSrcweir 
1246*cdf0e10cSrcweir 	StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
1247*cdf0e10cSrcweir 	if( bDelInst )
1248*cdf0e10cSrcweir 	{
1249*cdf0e10cSrcweir 		// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
1250*cdf0e10cSrcweir 		// beim Programm-Ende freigeben, damit nichts gehalten wird.
1251*cdf0e10cSrcweir 		ClearUnoObjectsInRTL_Impl( xBasic );
1252*cdf0e10cSrcweir 
1253*cdf0e10cSrcweir 		delete pINST;
1254*cdf0e10cSrcweir 		pINST = NULL;
1255*cdf0e10cSrcweir 	}
1256*cdf0e10cSrcweir 	if ( pBasic && pBasic->IsDocBasic() && pBasic->IsQuitApplication() && !pINST )
1257*cdf0e10cSrcweir 	{
1258*cdf0e10cSrcweir 		Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ), NULL );
1259*cdf0e10cSrcweir 	}
1260*cdf0e10cSrcweir 
1261*cdf0e10cSrcweir 	return nRes;
1262*cdf0e10cSrcweir }
1263*cdf0e10cSrcweir 
1264*cdf0e10cSrcweir // Ausfuehren der Init-Methode eines Moduls nach dem Laden
1265*cdf0e10cSrcweir // oder der Compilation
1266*cdf0e10cSrcweir 
1267*cdf0e10cSrcweir void SbModule::RunInit()
1268*cdf0e10cSrcweir {
1269*cdf0e10cSrcweir 	if( pImage
1270*cdf0e10cSrcweir 	 && !pImage->bInit
1271*cdf0e10cSrcweir 	 && pImage->GetFlag( SBIMG_INITCODE ) )
1272*cdf0e10cSrcweir 	{
1273*cdf0e10cSrcweir 		// Flag setzen, dass RunInit aktiv ist (Testtool)
1274*cdf0e10cSrcweir 		GetSbData()->bRunInit = sal_True;
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir 		// sal_Bool bDelInst = sal_Bool( pINST == NULL );
1277*cdf0e10cSrcweir 		// if( bDelInst )
1278*cdf0e10cSrcweir 			// pINST = new SbiInstance( (StarBASIC*) GetParent() );
1279*cdf0e10cSrcweir 		SbModule* pOldMod = pMOD;
1280*cdf0e10cSrcweir 		pMOD = this;
1281*cdf0e10cSrcweir 		// Der Init-Code beginnt immer hier
1282*cdf0e10cSrcweir 		SbiRuntime* pRt = new SbiRuntime( this, NULL, 0 );
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
1285*cdf0e10cSrcweir 		dbg_traceNotifyCall( this, NULL, 0 );
1286*cdf0e10cSrcweir #endif
1287*cdf0e10cSrcweir 
1288*cdf0e10cSrcweir 		pRt->pNext = pINST->pRun;
1289*cdf0e10cSrcweir 		pINST->pRun = pRt;
1290*cdf0e10cSrcweir 		while( pRt->Step() ) {}
1291*cdf0e10cSrcweir 
1292*cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
1293*cdf0e10cSrcweir 		bool bLeave = true;
1294*cdf0e10cSrcweir 		dbg_traceNotifyCall( this, NULL, 0, bLeave );
1295*cdf0e10cSrcweir #endif
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir 		pINST->pRun = pRt->pNext;
1298*cdf0e10cSrcweir 		delete pRt;
1299*cdf0e10cSrcweir 		pMOD = pOldMod;
1300*cdf0e10cSrcweir 		// if( bDelInst )
1301*cdf0e10cSrcweir 			// delete pINST, pINST = NULL;
1302*cdf0e10cSrcweir 		pImage->bInit = sal_True;
1303*cdf0e10cSrcweir         pImage->bFirstInit = sal_False;
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir 		// RunInit ist nicht mehr aktiv
1306*cdf0e10cSrcweir 		GetSbData()->bRunInit = sal_False;
1307*cdf0e10cSrcweir 	}
1308*cdf0e10cSrcweir }
1309*cdf0e10cSrcweir 
1310*cdf0e10cSrcweir // Mit private/dim deklarierte Variablen loeschen
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir void SbModule::AddVarName( const String& aName )
1313*cdf0e10cSrcweir {
1314*cdf0e10cSrcweir     // see if the name is added allready
1315*cdf0e10cSrcweir     std::vector< String >::iterator it_end = mModuleVariableNames.end();
1316*cdf0e10cSrcweir     for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
1317*cdf0e10cSrcweir     {
1318*cdf0e10cSrcweir         if ( aName == *it )
1319*cdf0e10cSrcweir             return;
1320*cdf0e10cSrcweir     }
1321*cdf0e10cSrcweir     mModuleVariableNames.push_back( aName );
1322*cdf0e10cSrcweir }
1323*cdf0e10cSrcweir 
1324*cdf0e10cSrcweir void SbModule::RemoveVars()
1325*cdf0e10cSrcweir {
1326*cdf0e10cSrcweir     std::vector< String >::iterator it_end = mModuleVariableNames.end();
1327*cdf0e10cSrcweir     for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
1328*cdf0e10cSrcweir     {
1329*cdf0e10cSrcweir     // We don't want a Find being called in a derived class ( e.g.
1330*cdf0e10cSrcweir     // SbUserform because it could trigger say an initialise event
1331*cdf0e10cSrcweir     // 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 )
1332*cdf0e10cSrcweir     SbxVariableRef p = SbModule::Find( *it, SbxCLASS_PROPERTY );
1333*cdf0e10cSrcweir     if( p.Is() )
1334*cdf0e10cSrcweir         Remove (p);
1335*cdf0e10cSrcweir     }
1336*cdf0e10cSrcweir }
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir void SbModule::ClearPrivateVars()
1339*cdf0e10cSrcweir {
1340*cdf0e10cSrcweir 	for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
1341*cdf0e10cSrcweir 	{
1342*cdf0e10cSrcweir 		SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
1343*cdf0e10cSrcweir 		if( p )
1344*cdf0e10cSrcweir 		{
1345*cdf0e10cSrcweir 			// Arrays nicht loeschen, sondern nur deren Inhalt
1346*cdf0e10cSrcweir 			if( p->GetType() & SbxARRAY )
1347*cdf0e10cSrcweir 			{
1348*cdf0e10cSrcweir 				SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
1349*cdf0e10cSrcweir 				if( pArray )
1350*cdf0e10cSrcweir 				{
1351*cdf0e10cSrcweir 					for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
1352*cdf0e10cSrcweir 					{
1353*cdf0e10cSrcweir 						SbxVariable* pj = PTR_CAST(SbxVariable,pArray->Get( j ));
1354*cdf0e10cSrcweir 						pj->SbxValue::Clear();
1355*cdf0e10cSrcweir 						/*
1356*cdf0e10cSrcweir 						sal_uInt16 nFlags = pj->GetFlags();
1357*cdf0e10cSrcweir 						pj->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
1358*cdf0e10cSrcweir 						pj->PutEmpty();
1359*cdf0e10cSrcweir 						pj->SetFlags( nFlags );
1360*cdf0e10cSrcweir 						*/
1361*cdf0e10cSrcweir 					}
1362*cdf0e10cSrcweir 				}
1363*cdf0e10cSrcweir 			}
1364*cdf0e10cSrcweir 			else
1365*cdf0e10cSrcweir 			{
1366*cdf0e10cSrcweir 				p->SbxValue::Clear();
1367*cdf0e10cSrcweir 				/*
1368*cdf0e10cSrcweir 				sal_uInt16 nFlags = p->GetFlags();
1369*cdf0e10cSrcweir 				p->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
1370*cdf0e10cSrcweir 				p->PutEmpty();
1371*cdf0e10cSrcweir 				p->SetFlags( nFlags );
1372*cdf0e10cSrcweir 				*/
1373*cdf0e10cSrcweir 			}
1374*cdf0e10cSrcweir 		}
1375*cdf0e10cSrcweir 	}
1376*cdf0e10cSrcweir }
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir void SbModule::implClearIfVarDependsOnDeletedBasic( SbxVariable* pVar, StarBASIC* pDeletedBasic )
1379*cdf0e10cSrcweir {
1380*cdf0e10cSrcweir 	if( pVar->SbxValue::GetType() != SbxOBJECT || pVar->ISA( SbProcedureProperty ) )
1381*cdf0e10cSrcweir 		return;
1382*cdf0e10cSrcweir 
1383*cdf0e10cSrcweir 	SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
1384*cdf0e10cSrcweir 	if( pObj != NULL )
1385*cdf0e10cSrcweir 	{
1386*cdf0e10cSrcweir 		SbxObject* p = pObj;
1387*cdf0e10cSrcweir 
1388*cdf0e10cSrcweir 		SbModule* pMod = PTR_CAST( SbModule, p );
1389*cdf0e10cSrcweir 		if( pMod != NULL )
1390*cdf0e10cSrcweir 			pMod->ClearVarsDependingOnDeletedBasic( pDeletedBasic );
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir 		while( (p = p->GetParent()) != NULL )
1393*cdf0e10cSrcweir 		{
1394*cdf0e10cSrcweir 			StarBASIC* pBasic = PTR_CAST( StarBASIC, p );
1395*cdf0e10cSrcweir 			if( pBasic != NULL && pBasic == pDeletedBasic )
1396*cdf0e10cSrcweir 			{
1397*cdf0e10cSrcweir 				pVar->SbxValue::Clear();
1398*cdf0e10cSrcweir 				break;
1399*cdf0e10cSrcweir 			}
1400*cdf0e10cSrcweir 		}
1401*cdf0e10cSrcweir 	}
1402*cdf0e10cSrcweir }
1403*cdf0e10cSrcweir 
1404*cdf0e10cSrcweir void SbModule::ClearVarsDependingOnDeletedBasic( StarBASIC* pDeletedBasic )
1405*cdf0e10cSrcweir {
1406*cdf0e10cSrcweir 	(void)pDeletedBasic;
1407*cdf0e10cSrcweir 
1408*cdf0e10cSrcweir 	for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
1409*cdf0e10cSrcweir 	{
1410*cdf0e10cSrcweir 		SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
1411*cdf0e10cSrcweir 		if( p )
1412*cdf0e10cSrcweir 		{
1413*cdf0e10cSrcweir 			if( p->GetType() & SbxARRAY )
1414*cdf0e10cSrcweir 			{
1415*cdf0e10cSrcweir 				SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
1416*cdf0e10cSrcweir 				if( pArray )
1417*cdf0e10cSrcweir 				{
1418*cdf0e10cSrcweir 					for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
1419*cdf0e10cSrcweir 					{
1420*cdf0e10cSrcweir 						SbxVariable* pVar = PTR_CAST(SbxVariable,pArray->Get( j ));
1421*cdf0e10cSrcweir 						implClearIfVarDependsOnDeletedBasic( pVar, pDeletedBasic );
1422*cdf0e10cSrcweir 					}
1423*cdf0e10cSrcweir 				}
1424*cdf0e10cSrcweir 			}
1425*cdf0e10cSrcweir 			else
1426*cdf0e10cSrcweir 			{
1427*cdf0e10cSrcweir 				implClearIfVarDependsOnDeletedBasic( p, pDeletedBasic );
1428*cdf0e10cSrcweir 			}
1429*cdf0e10cSrcweir 		}
1430*cdf0e10cSrcweir 	}
1431*cdf0e10cSrcweir }
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir // Zunaechst in dieses Modul, um 358-faehig zu bleiben
1434*cdf0e10cSrcweir // (Branch in sb.cxx vermeiden)
1435*cdf0e10cSrcweir void StarBASIC::ClearAllModuleVars( void )
1436*cdf0e10cSrcweir {
1437*cdf0e10cSrcweir 	// Eigene Module initialisieren
1438*cdf0e10cSrcweir 	for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
1439*cdf0e10cSrcweir 	{
1440*cdf0e10cSrcweir 		SbModule* pModule = (SbModule*)pModules->Get( nMod );
1441*cdf0e10cSrcweir 		// Nur initialisieren, wenn der Startcode schon ausgefuehrt wurde
1442*cdf0e10cSrcweir 		if( pModule->pImage && pModule->pImage->bInit && !pModule->isProxyModule() && !pModule->ISA(SbObjModule) )
1443*cdf0e10cSrcweir 			pModule->ClearPrivateVars();
1444*cdf0e10cSrcweir 	}
1445*cdf0e10cSrcweir 
1446*cdf0e10cSrcweir     /* #88042 This code can delete already used public vars during runtime!
1447*cdf0e10cSrcweir 	// Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
1448*cdf0e10cSrcweir 	// Wenn ja, auch dort initialisieren
1449*cdf0e10cSrcweir 	for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
1450*cdf0e10cSrcweir 	{
1451*cdf0e10cSrcweir 		SbxVariable* pVar = pObjs->Get( nObj );
1452*cdf0e10cSrcweir 		StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
1453*cdf0e10cSrcweir 		if( pBasic )
1454*cdf0e10cSrcweir 			pBasic->ClearAllModuleVars();
1455*cdf0e10cSrcweir 	}
1456*cdf0e10cSrcweir     */
1457*cdf0e10cSrcweir }
1458*cdf0e10cSrcweir 
1459*cdf0e10cSrcweir // Ausfuehren des Init-Codes aller Module
1460*cdf0e10cSrcweir void SbModule::GlobalRunInit( sal_Bool bBasicStart )
1461*cdf0e10cSrcweir {
1462*cdf0e10cSrcweir 	// Wenn kein Basic-Start, nur initialisieren, wenn Modul uninitialisiert
1463*cdf0e10cSrcweir 	if( !bBasicStart )
1464*cdf0e10cSrcweir 		if( !(pImage && !pImage->bInit) )
1465*cdf0e10cSrcweir 			return;
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir 	// GlobalInitErr-Flag fuer Compiler-Error initialisieren
1468*cdf0e10cSrcweir 	// Anhand dieses Flags kann in SbModule::Run() nach dem Aufruf
1469*cdf0e10cSrcweir 	// von GlobalRunInit festgestellt werden, ob beim initialisieren
1470*cdf0e10cSrcweir 	// der Module ein Fehler auftrat. Dann wird nicht gestartet.
1471*cdf0e10cSrcweir 	GetSbData()->bGlobalInitErr = sal_False;
1472*cdf0e10cSrcweir 
1473*cdf0e10cSrcweir 	// Parent vom Modul ist ein Basic
1474*cdf0e10cSrcweir 	StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
1475*cdf0e10cSrcweir 	if( pBasic )
1476*cdf0e10cSrcweir 	{
1477*cdf0e10cSrcweir 		pBasic->InitAllModules();
1478*cdf0e10cSrcweir 
1479*cdf0e10cSrcweir 		SbxObject* pParent_ = pBasic->GetParent();
1480*cdf0e10cSrcweir 		if( pParent_ )
1481*cdf0e10cSrcweir 		{
1482*cdf0e10cSrcweir 			StarBASIC * pParentBasic = PTR_CAST(StarBASIC,pParent_);
1483*cdf0e10cSrcweir 			if( pParentBasic )
1484*cdf0e10cSrcweir 			{
1485*cdf0e10cSrcweir 				pParentBasic->InitAllModules( pBasic );
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir 				// #109018 Parent can also have a parent (library in doc)
1488*cdf0e10cSrcweir 				SbxObject* pParentParent = pParentBasic->GetParent();
1489*cdf0e10cSrcweir 				if( pParentParent )
1490*cdf0e10cSrcweir 				{
1491*cdf0e10cSrcweir 					StarBASIC * pParentParentBasic = PTR_CAST(StarBASIC,pParentParent);
1492*cdf0e10cSrcweir 					if( pParentParentBasic )
1493*cdf0e10cSrcweir 						pParentParentBasic->InitAllModules( pParentBasic );
1494*cdf0e10cSrcweir 				}
1495*cdf0e10cSrcweir 			}
1496*cdf0e10cSrcweir 		}
1497*cdf0e10cSrcweir 	}
1498*cdf0e10cSrcweir }
1499*cdf0e10cSrcweir 
1500*cdf0e10cSrcweir void SbModule::GlobalRunDeInit( void )
1501*cdf0e10cSrcweir {
1502*cdf0e10cSrcweir 	StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
1503*cdf0e10cSrcweir 	if( pBasic )
1504*cdf0e10cSrcweir 	{
1505*cdf0e10cSrcweir 		pBasic->DeInitAllModules();
1506*cdf0e10cSrcweir 
1507*cdf0e10cSrcweir 		SbxObject* pParent_ = pBasic->GetParent();
1508*cdf0e10cSrcweir 		if( pParent_ )
1509*cdf0e10cSrcweir 			pBasic = PTR_CAST(StarBASIC,pParent_);
1510*cdf0e10cSrcweir 		if( pBasic )
1511*cdf0e10cSrcweir 			pBasic->DeInitAllModules();
1512*cdf0e10cSrcweir 	}
1513*cdf0e10cSrcweir }
1514*cdf0e10cSrcweir 
1515*cdf0e10cSrcweir // Suche nach dem naechsten STMNT-Befehl im Code. Wird vom STMNT-
1516*cdf0e10cSrcweir // Opcode verwendet, um die Endspalte zu setzen.
1517*cdf0e10cSrcweir 
1518*cdf0e10cSrcweir const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol ) const
1519*cdf0e10cSrcweir {
1520*cdf0e10cSrcweir 	return FindNextStmnt( p, nLine, nCol, sal_False );
1521*cdf0e10cSrcweir }
1522*cdf0e10cSrcweir 
1523*cdf0e10cSrcweir const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol,
1524*cdf0e10cSrcweir 	sal_Bool bFollowJumps, const SbiImage* pImg ) const
1525*cdf0e10cSrcweir {
1526*cdf0e10cSrcweir 	sal_uInt32 nPC = (sal_uInt32) ( p - (const sal_uInt8*) pImage->GetCode() );
1527*cdf0e10cSrcweir 	while( nPC < pImage->GetCodeSize() )
1528*cdf0e10cSrcweir 	{
1529*cdf0e10cSrcweir 		SbiOpcode eOp = (SbiOpcode ) ( *p++ );
1530*cdf0e10cSrcweir 		nPC++;
1531*cdf0e10cSrcweir 		if( bFollowJumps && eOp == _JUMP && pImg )
1532*cdf0e10cSrcweir 		{
1533*cdf0e10cSrcweir 			DBG_ASSERT( pImg, "FindNextStmnt: pImg==NULL with FollowJumps option" );
1534*cdf0e10cSrcweir 			sal_uInt32 nOp1 = *p++; nOp1 |= *p++ << 8;
1535*cdf0e10cSrcweir 			nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
1536*cdf0e10cSrcweir 			p = (const sal_uInt8*) pImg->GetCode() + nOp1;
1537*cdf0e10cSrcweir 		}
1538*cdf0e10cSrcweir 		else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
1539*cdf0e10cSrcweir 			p += 4, nPC += 4;
1540*cdf0e10cSrcweir 		else if( eOp == _STMNT )
1541*cdf0e10cSrcweir 		{
1542*cdf0e10cSrcweir 			sal_uInt32 nl, nc;
1543*cdf0e10cSrcweir 			nl = *p++; nl |= *p++ << 8;
1544*cdf0e10cSrcweir 			nl |= *p++ << 16 ; nl |= *p++ << 24;
1545*cdf0e10cSrcweir 			nc = *p++; nc |= *p++ << 8;
1546*cdf0e10cSrcweir 			nc |= *p++ << 16 ; nc |= *p++ << 24;
1547*cdf0e10cSrcweir 			nLine = (sal_uInt16)nl; nCol = (sal_uInt16)nc;
1548*cdf0e10cSrcweir 			return p;
1549*cdf0e10cSrcweir 		}
1550*cdf0e10cSrcweir 		else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
1551*cdf0e10cSrcweir 			p += 8, nPC += 8;
1552*cdf0e10cSrcweir 		else if( !( eOp >= SbOP0_START && eOp <= SbOP0_END ) )
1553*cdf0e10cSrcweir 		{
1554*cdf0e10cSrcweir 			StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1555*cdf0e10cSrcweir 			break;
1556*cdf0e10cSrcweir 		}
1557*cdf0e10cSrcweir 	}
1558*cdf0e10cSrcweir 	return NULL;
1559*cdf0e10cSrcweir }
1560*cdf0e10cSrcweir 
1561*cdf0e10cSrcweir // Testen, ob eine Zeile STMNT-Opcodes enthaelt
1562*cdf0e10cSrcweir 
1563*cdf0e10cSrcweir sal_Bool SbModule::IsBreakable( sal_uInt16 nLine ) const
1564*cdf0e10cSrcweir {
1565*cdf0e10cSrcweir 	if( !pImage )
1566*cdf0e10cSrcweir 		return sal_False;
1567*cdf0e10cSrcweir 	const sal_uInt8* p = (const sal_uInt8* ) pImage->GetCode();
1568*cdf0e10cSrcweir 	sal_uInt16 nl, nc;
1569*cdf0e10cSrcweir 	while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
1570*cdf0e10cSrcweir 		if( nl == nLine )
1571*cdf0e10cSrcweir 			return sal_True;
1572*cdf0e10cSrcweir 	return sal_False;
1573*cdf0e10cSrcweir }
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir size_t SbModule::GetBPCount() const
1576*cdf0e10cSrcweir {
1577*cdf0e10cSrcweir 	return pBreaks ? pBreaks->size() : 0;
1578*cdf0e10cSrcweir }
1579*cdf0e10cSrcweir 
1580*cdf0e10cSrcweir sal_uInt16 SbModule::GetBP( size_t n ) const
1581*cdf0e10cSrcweir {
1582*cdf0e10cSrcweir 	if( pBreaks && n < pBreaks->size() )
1583*cdf0e10cSrcweir 		return pBreaks->operator[]( n );
1584*cdf0e10cSrcweir 	else
1585*cdf0e10cSrcweir 		return 0;
1586*cdf0e10cSrcweir }
1587*cdf0e10cSrcweir 
1588*cdf0e10cSrcweir sal_Bool SbModule::IsBP( sal_uInt16 nLine ) const
1589*cdf0e10cSrcweir {
1590*cdf0e10cSrcweir 	if( pBreaks )
1591*cdf0e10cSrcweir 	{
1592*cdf0e10cSrcweir 		for( size_t i = 0; i < pBreaks->size(); i++ )
1593*cdf0e10cSrcweir 		{
1594*cdf0e10cSrcweir 			sal_uInt16 b = pBreaks->operator[]( i );
1595*cdf0e10cSrcweir 			if( b == nLine )
1596*cdf0e10cSrcweir 				return sal_True;
1597*cdf0e10cSrcweir 			if( b < nLine )
1598*cdf0e10cSrcweir 				break;
1599*cdf0e10cSrcweir 		}
1600*cdf0e10cSrcweir 	}
1601*cdf0e10cSrcweir 	return sal_False;
1602*cdf0e10cSrcweir }
1603*cdf0e10cSrcweir 
1604*cdf0e10cSrcweir sal_Bool SbModule::SetBP( sal_uInt16 nLine )
1605*cdf0e10cSrcweir {
1606*cdf0e10cSrcweir 	if( !IsBreakable( nLine ) )
1607*cdf0e10cSrcweir 		return sal_False;
1608*cdf0e10cSrcweir 	if( !pBreaks )
1609*cdf0e10cSrcweir 		pBreaks = new SbiBreakpoints;
1610*cdf0e10cSrcweir 	size_t i;
1611*cdf0e10cSrcweir 	for( i = 0; i < pBreaks->size(); i++ )
1612*cdf0e10cSrcweir 	{
1613*cdf0e10cSrcweir 		sal_uInt16 b = pBreaks->operator[]( i );
1614*cdf0e10cSrcweir 		if( b == nLine )
1615*cdf0e10cSrcweir 			return sal_True;
1616*cdf0e10cSrcweir 		if( b < nLine )
1617*cdf0e10cSrcweir 			break;
1618*cdf0e10cSrcweir 	}
1619*cdf0e10cSrcweir 	pBreaks->insert( pBreaks->begin() + i, nLine );
1620*cdf0e10cSrcweir 
1621*cdf0e10cSrcweir 	// #38568: Zur Laufzeit auch hier SbDEBUG_BREAK setzen
1622*cdf0e10cSrcweir 	if( pINST && pINST->pRun )
1623*cdf0e10cSrcweir 		pINST->pRun->SetDebugFlags( SbDEBUG_BREAK );
1624*cdf0e10cSrcweir 
1625*cdf0e10cSrcweir 	return IsBreakable( nLine );
1626*cdf0e10cSrcweir }
1627*cdf0e10cSrcweir 
1628*cdf0e10cSrcweir sal_Bool SbModule::ClearBP( sal_uInt16 nLine )
1629*cdf0e10cSrcweir {
1630*cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
1631*cdf0e10cSrcweir 	if( pBreaks )
1632*cdf0e10cSrcweir 	{
1633*cdf0e10cSrcweir 		for( size_t i = 0; i < pBreaks->size(); i++ )
1634*cdf0e10cSrcweir 		{
1635*cdf0e10cSrcweir 			sal_uInt16 b = pBreaks->operator[]( i );
1636*cdf0e10cSrcweir 			if( b == nLine )
1637*cdf0e10cSrcweir 			{
1638*cdf0e10cSrcweir 				pBreaks->erase( pBreaks->begin() + i );
1639*cdf0e10cSrcweir 				bRes = sal_True;
1640*cdf0e10cSrcweir 				break;
1641*cdf0e10cSrcweir 			}
1642*cdf0e10cSrcweir 			if( b < nLine )
1643*cdf0e10cSrcweir 				break;
1644*cdf0e10cSrcweir 		}
1645*cdf0e10cSrcweir 		if( pBreaks->empty() )
1646*cdf0e10cSrcweir 			delete pBreaks, pBreaks = NULL;
1647*cdf0e10cSrcweir 	}
1648*cdf0e10cSrcweir 	return bRes;
1649*cdf0e10cSrcweir }
1650*cdf0e10cSrcweir 
1651*cdf0e10cSrcweir void SbModule::ClearAllBP()
1652*cdf0e10cSrcweir {
1653*cdf0e10cSrcweir 	delete pBreaks;
1654*cdf0e10cSrcweir 	pBreaks = NULL;
1655*cdf0e10cSrcweir }
1656*cdf0e10cSrcweir 
1657*cdf0e10cSrcweir void
1658*cdf0e10cSrcweir SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const
1659*cdf0e10cSrcweir {
1660*cdf0e10cSrcweir 		if ( !pImg )
1661*cdf0e10cSrcweir 			pImg = pImage;
1662*cdf0e10cSrcweir 		for( sal_uInt32 i = 0; i < pMethods->Count(); i++ )
1663*cdf0e10cSrcweir 		{
1664*cdf0e10cSrcweir 			SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (sal_uInt16)i ) );
1665*cdf0e10cSrcweir 			if( pMeth )
1666*cdf0e10cSrcweir 			{
1667*cdf0e10cSrcweir 				//fixup method start positions
1668*cdf0e10cSrcweir 				if ( bCvtToLegacy )
1669*cdf0e10cSrcweir 					pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
1670*cdf0e10cSrcweir 				else
1671*cdf0e10cSrcweir 					pMeth->nStart = pImg->CalcNewOffset( (sal_uInt16)pMeth->nStart );
1672*cdf0e10cSrcweir 			}
1673*cdf0e10cSrcweir 		}
1674*cdf0e10cSrcweir 
1675*cdf0e10cSrcweir }
1676*cdf0e10cSrcweir 
1677*cdf0e10cSrcweir sal_Bool SbModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
1678*cdf0e10cSrcweir {
1679*cdf0e10cSrcweir 	Clear();
1680*cdf0e10cSrcweir 	if( !SbxObject::LoadData( rStrm, 1 ) )
1681*cdf0e10cSrcweir 		return sal_False;
1682*cdf0e10cSrcweir 	// Precaution...
1683*cdf0e10cSrcweir 	SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
1684*cdf0e10cSrcweir 	sal_uInt8 bImage;
1685*cdf0e10cSrcweir 	rStrm >> bImage;
1686*cdf0e10cSrcweir 	if( bImage )
1687*cdf0e10cSrcweir 	{
1688*cdf0e10cSrcweir 		SbiImage* p = new SbiImage;
1689*cdf0e10cSrcweir 		sal_uInt32 nImgVer = 0;
1690*cdf0e10cSrcweir 
1691*cdf0e10cSrcweir 		if( !p->Load( rStrm, nImgVer ) )
1692*cdf0e10cSrcweir 		{
1693*cdf0e10cSrcweir 			delete p;
1694*cdf0e10cSrcweir 			return sal_False;
1695*cdf0e10cSrcweir 		}
1696*cdf0e10cSrcweir 		// If the image is in old format, we fix up the method start offsets
1697*cdf0e10cSrcweir 		if ( nImgVer < B_EXT_IMG_VERSION )
1698*cdf0e10cSrcweir 		{
1699*cdf0e10cSrcweir 			fixUpMethodStart( false, p );
1700*cdf0e10cSrcweir 			p->ReleaseLegacyBuffer();
1701*cdf0e10cSrcweir 		}
1702*cdf0e10cSrcweir 		aComment = p->aComment;
1703*cdf0e10cSrcweir 		SetName( p->aName );
1704*cdf0e10cSrcweir 		if( p->GetCodeSize() )
1705*cdf0e10cSrcweir 		{
1706*cdf0e10cSrcweir 			aOUSource = p->aOUSource;
1707*cdf0e10cSrcweir 			// Alte Version: Image weg
1708*cdf0e10cSrcweir 			if( nVer == 1 )
1709*cdf0e10cSrcweir 			{
1710*cdf0e10cSrcweir 				SetSource32( p->aOUSource );
1711*cdf0e10cSrcweir 				delete p;
1712*cdf0e10cSrcweir 			}
1713*cdf0e10cSrcweir 			else
1714*cdf0e10cSrcweir 				pImage = p;
1715*cdf0e10cSrcweir 		}
1716*cdf0e10cSrcweir 		else
1717*cdf0e10cSrcweir 		{
1718*cdf0e10cSrcweir 			SetSource32( p->aOUSource );
1719*cdf0e10cSrcweir 			delete p;
1720*cdf0e10cSrcweir 		}
1721*cdf0e10cSrcweir 	}
1722*cdf0e10cSrcweir 	return sal_True;
1723*cdf0e10cSrcweir }
1724*cdf0e10cSrcweir 
1725*cdf0e10cSrcweir sal_Bool SbModule::StoreData( SvStream& rStrm ) const
1726*cdf0e10cSrcweir {
1727*cdf0e10cSrcweir 	sal_Bool bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
1728*cdf0e10cSrcweir 	if ( bFixup )
1729*cdf0e10cSrcweir 		fixUpMethodStart( true );
1730*cdf0e10cSrcweir 	sal_Bool bRet = SbxObject::StoreData( rStrm );
1731*cdf0e10cSrcweir 	if ( !bRet )
1732*cdf0e10cSrcweir 		return sal_False;
1733*cdf0e10cSrcweir 
1734*cdf0e10cSrcweir 	if( pImage )
1735*cdf0e10cSrcweir 	{
1736*cdf0e10cSrcweir 		pImage->aOUSource = aOUSource;
1737*cdf0e10cSrcweir 		pImage->aComment = aComment;
1738*cdf0e10cSrcweir 		pImage->aName = GetName();
1739*cdf0e10cSrcweir 		rStrm << (sal_uInt8) 1;
1740*cdf0e10cSrcweir 		// # PCode is saved only for legacy formats only
1741*cdf0e10cSrcweir 		// It should be noted that it probably isn't necessary
1742*cdf0e10cSrcweir 		// It would be better not to store the image ( more flexible with
1743*cdf0e10cSrcweir 		// formats )
1744*cdf0e10cSrcweir 		bool bRes = pImage->Save( rStrm, B_LEGACYVERSION );
1745*cdf0e10cSrcweir 		if ( bFixup )
1746*cdf0e10cSrcweir 			fixUpMethodStart( false ); // restore method starts
1747*cdf0e10cSrcweir 		return bRes;
1748*cdf0e10cSrcweir 
1749*cdf0e10cSrcweir 	}
1750*cdf0e10cSrcweir 	else
1751*cdf0e10cSrcweir 	{
1752*cdf0e10cSrcweir 		SbiImage aImg;
1753*cdf0e10cSrcweir 		aImg.aOUSource = aOUSource;
1754*cdf0e10cSrcweir 		aImg.aComment = aComment;
1755*cdf0e10cSrcweir 		aImg.aName = GetName();
1756*cdf0e10cSrcweir 		rStrm << (sal_uInt8) 1;
1757*cdf0e10cSrcweir 		return aImg.Save( rStrm );
1758*cdf0e10cSrcweir 	}
1759*cdf0e10cSrcweir }
1760*cdf0e10cSrcweir 
1761*cdf0e10cSrcweir sal_Bool SbModule::ExceedsLegacyModuleSize()
1762*cdf0e10cSrcweir {
1763*cdf0e10cSrcweir 	if ( !IsCompiled() )
1764*cdf0e10cSrcweir 		Compile();
1765*cdf0e10cSrcweir 	if ( pImage && pImage->ExceedsLegacyLimits() )
1766*cdf0e10cSrcweir 		return true;
1767*cdf0e10cSrcweir 	return false;
1768*cdf0e10cSrcweir }
1769*cdf0e10cSrcweir 
1770*cdf0e10cSrcweir 
1771*cdf0e10cSrcweir // Store only image, no source
1772*cdf0e10cSrcweir sal_Bool SbModule::StoreBinaryData( SvStream& rStrm )
1773*cdf0e10cSrcweir {
1774*cdf0e10cSrcweir 	return StoreBinaryData( rStrm, 0 );
1775*cdf0e10cSrcweir }
1776*cdf0e10cSrcweir 
1777*cdf0e10cSrcweir sal_Bool SbModule::StoreBinaryData( SvStream& rStrm, sal_uInt16 nVer )
1778*cdf0e10cSrcweir {
1779*cdf0e10cSrcweir     sal_Bool bRet = Compile();
1780*cdf0e10cSrcweir     if( bRet )
1781*cdf0e10cSrcweir     {
1782*cdf0e10cSrcweir 		sal_Bool bFixup = ( !nVer && !pImage->ExceedsLegacyLimits() );// save in old image format, fix up method starts
1783*cdf0e10cSrcweir 
1784*cdf0e10cSrcweir 		if ( bFixup ) // save in old image format, fix up method starts
1785*cdf0e10cSrcweir 			fixUpMethodStart( true );
1786*cdf0e10cSrcweir      	bRet = SbxObject::StoreData( rStrm );
1787*cdf0e10cSrcweir         if( bRet )
1788*cdf0e10cSrcweir         {
1789*cdf0e10cSrcweir 		    pImage->aOUSource = ::rtl::OUString();
1790*cdf0e10cSrcweir 		    pImage->aComment = aComment;
1791*cdf0e10cSrcweir 		    pImage->aName = GetName();
1792*cdf0e10cSrcweir 
1793*cdf0e10cSrcweir 		    rStrm << (sal_uInt8) 1;
1794*cdf0e10cSrcweir                     if ( nVer )
1795*cdf0e10cSrcweir 						bRet = pImage->Save( rStrm, B_EXT_IMG_VERSION );
1796*cdf0e10cSrcweir                     else
1797*cdf0e10cSrcweir                         bRet = pImage->Save( rStrm, B_LEGACYVERSION );
1798*cdf0e10cSrcweir                     if ( bFixup )
1799*cdf0e10cSrcweir                         fixUpMethodStart( false ); // restore method starts
1800*cdf0e10cSrcweir 
1801*cdf0e10cSrcweir 		    pImage->aOUSource = aOUSource;
1802*cdf0e10cSrcweir         }
1803*cdf0e10cSrcweir     }
1804*cdf0e10cSrcweir     return bRet;
1805*cdf0e10cSrcweir }
1806*cdf0e10cSrcweir 
1807*cdf0e10cSrcweir // Called for >= OO 1.0 passwd protected libraries only
1808*cdf0e10cSrcweir //
1809*cdf0e10cSrcweir 
1810*cdf0e10cSrcweir sal_Bool SbModule::LoadBinaryData( SvStream& rStrm )
1811*cdf0e10cSrcweir {
1812*cdf0e10cSrcweir 	::rtl::OUString aKeepSource = aOUSource;
1813*cdf0e10cSrcweir     bool bRet = LoadData( rStrm, 2 );
1814*cdf0e10cSrcweir 	LoadCompleted();
1815*cdf0e10cSrcweir     aOUSource = aKeepSource;
1816*cdf0e10cSrcweir     return bRet;
1817*cdf0e10cSrcweir }
1818*cdf0e10cSrcweir 
1819*cdf0e10cSrcweir 
1820*cdf0e10cSrcweir sal_Bool SbModule::LoadCompleted()
1821*cdf0e10cSrcweir {
1822*cdf0e10cSrcweir 	SbxArray* p = GetMethods();
1823*cdf0e10cSrcweir 	sal_uInt16 i;
1824*cdf0e10cSrcweir 	for( i = 0; i < p->Count(); i++ )
1825*cdf0e10cSrcweir 	{
1826*cdf0e10cSrcweir 		SbMethod* q = PTR_CAST(SbMethod,p->Get( i ) );
1827*cdf0e10cSrcweir 		if( q )
1828*cdf0e10cSrcweir 			q->pMod = this;
1829*cdf0e10cSrcweir 	}
1830*cdf0e10cSrcweir 	p = GetProperties();
1831*cdf0e10cSrcweir 	for( i = 0; i < p->Count(); i++ )
1832*cdf0e10cSrcweir 	{
1833*cdf0e10cSrcweir 		SbProperty* q = PTR_CAST(SbProperty,p->Get( i ) );
1834*cdf0e10cSrcweir 		if( q )
1835*cdf0e10cSrcweir 			q->pMod = this;
1836*cdf0e10cSrcweir 	}
1837*cdf0e10cSrcweir 	return sal_True;
1838*cdf0e10cSrcweir }
1839*cdf0e10cSrcweir 
1840*cdf0e10cSrcweir void SbModule::handleProcedureProperties( SfxBroadcaster& rBC, const SfxHint& rHint )
1841*cdf0e10cSrcweir {
1842*cdf0e10cSrcweir 	bool bDone = false;
1843*cdf0e10cSrcweir 
1844*cdf0e10cSrcweir 	const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
1845*cdf0e10cSrcweir 	if( pHint )
1846*cdf0e10cSrcweir 	{
1847*cdf0e10cSrcweir 		SbxVariable* pVar = pHint->GetVar();
1848*cdf0e10cSrcweir 		SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
1849*cdf0e10cSrcweir 		if( pProcProperty )
1850*cdf0e10cSrcweir 		{
1851*cdf0e10cSrcweir 			bDone = true;
1852*cdf0e10cSrcweir 
1853*cdf0e10cSrcweir 			if( pHint->GetId() == SBX_HINT_DATAWANTED )
1854*cdf0e10cSrcweir 			{
1855*cdf0e10cSrcweir 				String aProcName;
1856*cdf0e10cSrcweir 				aProcName.AppendAscii( "Property Get " );
1857*cdf0e10cSrcweir 				aProcName += pProcProperty->GetName();
1858*cdf0e10cSrcweir 
1859*cdf0e10cSrcweir 				SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD );
1860*cdf0e10cSrcweir 				if( pMeth )
1861*cdf0e10cSrcweir 				{
1862*cdf0e10cSrcweir 					SbxValues aVals;
1863*cdf0e10cSrcweir 					aVals.eType = SbxVARIANT;
1864*cdf0e10cSrcweir 
1865*cdf0e10cSrcweir 					SbxArray* pArg = pVar->GetParameters();
1866*cdf0e10cSrcweir 					sal_uInt16 nVarParCount = (pArg != NULL) ? pArg->Count() : 0;
1867*cdf0e10cSrcweir 					if( nVarParCount > 1 )
1868*cdf0e10cSrcweir 					{
1869*cdf0e10cSrcweir 						SbxArrayRef xMethParameters = new SbxArray;
1870*cdf0e10cSrcweir 						xMethParameters->Put( pMeth, 0 );	// Method as parameter 0
1871*cdf0e10cSrcweir 						for( sal_uInt16 i = 1 ; i < nVarParCount ; ++i )
1872*cdf0e10cSrcweir 						{
1873*cdf0e10cSrcweir 							SbxVariable* pPar = pArg->Get( i );
1874*cdf0e10cSrcweir 							xMethParameters->Put( pPar, i );
1875*cdf0e10cSrcweir 						}
1876*cdf0e10cSrcweir 
1877*cdf0e10cSrcweir 						pMeth->SetParameters( xMethParameters );
1878*cdf0e10cSrcweir 						pMeth->Get( aVals );
1879*cdf0e10cSrcweir 						pMeth->SetParameters( NULL );
1880*cdf0e10cSrcweir 					}
1881*cdf0e10cSrcweir 					else
1882*cdf0e10cSrcweir 					{
1883*cdf0e10cSrcweir 						pMeth->Get( aVals );
1884*cdf0e10cSrcweir 					}
1885*cdf0e10cSrcweir 
1886*cdf0e10cSrcweir 					pVar->Put( aVals );
1887*cdf0e10cSrcweir 				}
1888*cdf0e10cSrcweir 			}
1889*cdf0e10cSrcweir 			else if( pHint->GetId() == SBX_HINT_DATACHANGED )
1890*cdf0e10cSrcweir 			{
1891*cdf0e10cSrcweir 				SbxVariable* pMeth = NULL;
1892*cdf0e10cSrcweir 
1893*cdf0e10cSrcweir 				bool bSet = pProcProperty->isSet();
1894*cdf0e10cSrcweir 				if( bSet )
1895*cdf0e10cSrcweir 				{
1896*cdf0e10cSrcweir 					pProcProperty->setSet( false );
1897*cdf0e10cSrcweir 
1898*cdf0e10cSrcweir 					String aProcName;
1899*cdf0e10cSrcweir 					aProcName.AppendAscii( "Property Set " );
1900*cdf0e10cSrcweir 					aProcName += pProcProperty->GetName();
1901*cdf0e10cSrcweir 					pMeth = Find( aProcName, SbxCLASS_METHOD );
1902*cdf0e10cSrcweir 				}
1903*cdf0e10cSrcweir 				if( !pMeth )	// Let
1904*cdf0e10cSrcweir 				{
1905*cdf0e10cSrcweir 					String aProcName;
1906*cdf0e10cSrcweir 					aProcName.AppendAscii( "Property Let " );
1907*cdf0e10cSrcweir 					aProcName += pProcProperty->GetName();
1908*cdf0e10cSrcweir 					pMeth = Find( aProcName, SbxCLASS_METHOD );
1909*cdf0e10cSrcweir 				}
1910*cdf0e10cSrcweir 
1911*cdf0e10cSrcweir 				if( pMeth )
1912*cdf0e10cSrcweir 				{
1913*cdf0e10cSrcweir 					// Setup parameters
1914*cdf0e10cSrcweir 					SbxArrayRef xArray = new SbxArray;
1915*cdf0e10cSrcweir 					xArray->Put( pMeth, 0 );	// Method as parameter 0
1916*cdf0e10cSrcweir 					xArray->Put( pVar, 1 );
1917*cdf0e10cSrcweir 					pMeth->SetParameters( xArray );
1918*cdf0e10cSrcweir 
1919*cdf0e10cSrcweir 					SbxValues aVals;
1920*cdf0e10cSrcweir 					pMeth->Get( aVals );
1921*cdf0e10cSrcweir 					pMeth->SetParameters( NULL );
1922*cdf0e10cSrcweir 				}
1923*cdf0e10cSrcweir 			}
1924*cdf0e10cSrcweir 		}
1925*cdf0e10cSrcweir 	}
1926*cdf0e10cSrcweir 
1927*cdf0e10cSrcweir 	if( !bDone )
1928*cdf0e10cSrcweir 		SbModule::Notify( rBC, rHint );
1929*cdf0e10cSrcweir }
1930*cdf0e10cSrcweir 
1931*cdf0e10cSrcweir 
1932*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
1933*cdf0e10cSrcweir // Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
1934*cdf0e10cSrcweir SbJScriptModule::SbJScriptModule( const String& rName )
1935*cdf0e10cSrcweir 	:SbModule( rName )
1936*cdf0e10cSrcweir {
1937*cdf0e10cSrcweir }
1938*cdf0e10cSrcweir 
1939*cdf0e10cSrcweir sal_Bool SbJScriptModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
1940*cdf0e10cSrcweir {
1941*cdf0e10cSrcweir     (void)nVer;
1942*cdf0e10cSrcweir 
1943*cdf0e10cSrcweir 	Clear();
1944*cdf0e10cSrcweir 	if( !SbxObject::LoadData( rStrm, 1 ) )
1945*cdf0e10cSrcweir 		return sal_False;
1946*cdf0e10cSrcweir 
1947*cdf0e10cSrcweir 	// Source-String holen
1948*cdf0e10cSrcweir     String aTmp;
1949*cdf0e10cSrcweir 	rStrm.ReadByteString( aTmp, gsl_getSystemTextEncoding() );
1950*cdf0e10cSrcweir     aOUSource = aTmp;
1951*cdf0e10cSrcweir 	//rStrm >> aSource;
1952*cdf0e10cSrcweir 	return sal_True;
1953*cdf0e10cSrcweir }
1954*cdf0e10cSrcweir 
1955*cdf0e10cSrcweir sal_Bool SbJScriptModule::StoreData( SvStream& rStrm ) const
1956*cdf0e10cSrcweir {
1957*cdf0e10cSrcweir 	if( !SbxObject::StoreData( rStrm ) )
1958*cdf0e10cSrcweir 		return sal_False;
1959*cdf0e10cSrcweir 
1960*cdf0e10cSrcweir 	// Source-String schreiben
1961*cdf0e10cSrcweir     String aTmp = aOUSource;
1962*cdf0e10cSrcweir 	rStrm.WriteByteString( aTmp, gsl_getSystemTextEncoding() );
1963*cdf0e10cSrcweir 	//rStrm << aSource;
1964*cdf0e10cSrcweir 	return sal_True;
1965*cdf0e10cSrcweir }
1966*cdf0e10cSrcweir 
1967*cdf0e10cSrcweir 
1968*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
1969*cdf0e10cSrcweir 
1970*cdf0e10cSrcweir SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
1971*cdf0e10cSrcweir 		: SbxMethod( r, t ), pMod( p )
1972*cdf0e10cSrcweir {
1973*cdf0e10cSrcweir 	bInvalid	 = sal_True;
1974*cdf0e10cSrcweir 	nStart		 =
1975*cdf0e10cSrcweir 	nDebugFlags  =
1976*cdf0e10cSrcweir 	nLine1		 =
1977*cdf0e10cSrcweir 	nLine2		 = 0;
1978*cdf0e10cSrcweir 	refStatics = new SbxArray;
1979*cdf0e10cSrcweir 	// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
1980*cdf0e10cSrcweir 	SetFlag( SBX_NO_MODIFY );
1981*cdf0e10cSrcweir }
1982*cdf0e10cSrcweir 
1983*cdf0e10cSrcweir SbMethod::SbMethod( const SbMethod& r )
1984*cdf0e10cSrcweir     : SvRefBase( r ), SbxMethod( r )
1985*cdf0e10cSrcweir {
1986*cdf0e10cSrcweir     pMod         = r.pMod;
1987*cdf0e10cSrcweir 	bInvalid	 = r.bInvalid;
1988*cdf0e10cSrcweir 	nStart		 = r.nStart;
1989*cdf0e10cSrcweir 	nDebugFlags  = r.nDebugFlags;
1990*cdf0e10cSrcweir 	nLine1		 = r.nLine1;
1991*cdf0e10cSrcweir 	nLine2		 = r.nLine2;
1992*cdf0e10cSrcweir         refStatics = r.refStatics;
1993*cdf0e10cSrcweir 	SetFlag( SBX_NO_MODIFY );
1994*cdf0e10cSrcweir }
1995*cdf0e10cSrcweir 
1996*cdf0e10cSrcweir SbMethod::~SbMethod()
1997*cdf0e10cSrcweir {
1998*cdf0e10cSrcweir }
1999*cdf0e10cSrcweir 
2000*cdf0e10cSrcweir SbxArray* SbMethod::GetLocals()
2001*cdf0e10cSrcweir {
2002*cdf0e10cSrcweir 	if( pINST )
2003*cdf0e10cSrcweir 		return pINST->GetLocals( this );
2004*cdf0e10cSrcweir 	else
2005*cdf0e10cSrcweir 		return NULL;
2006*cdf0e10cSrcweir }
2007*cdf0e10cSrcweir 
2008*cdf0e10cSrcweir void SbMethod::ClearStatics()
2009*cdf0e10cSrcweir {
2010*cdf0e10cSrcweir 	refStatics = new SbxArray;
2011*cdf0e10cSrcweir 
2012*cdf0e10cSrcweir }
2013*cdf0e10cSrcweir SbxArray* SbMethod::GetStatics()
2014*cdf0e10cSrcweir {
2015*cdf0e10cSrcweir 	return refStatics;
2016*cdf0e10cSrcweir }
2017*cdf0e10cSrcweir 
2018*cdf0e10cSrcweir sal_Bool SbMethod::LoadData( SvStream& rStrm, sal_uInt16 nVer )
2019*cdf0e10cSrcweir {
2020*cdf0e10cSrcweir 	if( !SbxMethod::LoadData( rStrm, 1 ) )
2021*cdf0e10cSrcweir 		return sal_False;
2022*cdf0e10cSrcweir 	sal_Int16 n;
2023*cdf0e10cSrcweir 	rStrm >> n;
2024*cdf0e10cSrcweir 	sal_Int16 nTempStart = (sal_Int16)nStart;
2025*cdf0e10cSrcweir 	// nDebugFlags = n; 	// AB 16.1.96: Nicht mehr uebernehmen
2026*cdf0e10cSrcweir 	if( nVer == 2 )
2027*cdf0e10cSrcweir 		rStrm >> nLine1 >> nLine2 >> nTempStart >> bInvalid;
2028*cdf0e10cSrcweir 	// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
2029*cdf0e10cSrcweir 	SetFlag( SBX_NO_MODIFY );
2030*cdf0e10cSrcweir 	nStart = nTempStart;
2031*cdf0e10cSrcweir 	return sal_True;
2032*cdf0e10cSrcweir }
2033*cdf0e10cSrcweir 
2034*cdf0e10cSrcweir sal_Bool SbMethod::StoreData( SvStream& rStrm ) const
2035*cdf0e10cSrcweir {
2036*cdf0e10cSrcweir 	if( !SbxMethod::StoreData( rStrm ) )
2037*cdf0e10cSrcweir 		return sal_False;
2038*cdf0e10cSrcweir 	rStrm << (sal_Int16) nDebugFlags
2039*cdf0e10cSrcweir 		  << (sal_Int16) nLine1
2040*cdf0e10cSrcweir 		  << (sal_Int16) nLine2
2041*cdf0e10cSrcweir 		  << (sal_Int16) nStart
2042*cdf0e10cSrcweir 		  << (sal_uInt8)  bInvalid;
2043*cdf0e10cSrcweir 	return sal_True;
2044*cdf0e10cSrcweir }
2045*cdf0e10cSrcweir 
2046*cdf0e10cSrcweir void SbMethod::GetLineRange( sal_uInt16& l1, sal_uInt16& l2 )
2047*cdf0e10cSrcweir {
2048*cdf0e10cSrcweir 	l1 = nLine1; l2 = nLine2;
2049*cdf0e10cSrcweir }
2050*cdf0e10cSrcweir 
2051*cdf0e10cSrcweir // Kann spaeter mal weg
2052*cdf0e10cSrcweir 
2053*cdf0e10cSrcweir SbxInfo* SbMethod::GetInfo()
2054*cdf0e10cSrcweir {
2055*cdf0e10cSrcweir 	return pInfo;
2056*cdf0e10cSrcweir }
2057*cdf0e10cSrcweir 
2058*cdf0e10cSrcweir // Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
2059*cdf0e10cSrcweir // #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
2060*cdf0e10cSrcweir // abgeschossen werden kann. Rueckgabewert wird als String geliefert.
2061*cdf0e10cSrcweir ErrCode SbMethod::Call( SbxValue* pRet )
2062*cdf0e10cSrcweir {
2063*cdf0e10cSrcweir 	// RefCount vom Modul hochzaehlen
2064*cdf0e10cSrcweir 	SbModule* pMod_ = (SbModule*)GetParent();
2065*cdf0e10cSrcweir 	pMod_->AddRef();
2066*cdf0e10cSrcweir 
2067*cdf0e10cSrcweir 	// RefCount vom Basic hochzaehlen
2068*cdf0e10cSrcweir 	StarBASIC* pBasic = (StarBASIC*)pMod_->GetParent();
2069*cdf0e10cSrcweir 	pBasic->AddRef();
2070*cdf0e10cSrcweir 
2071*cdf0e10cSrcweir 	// Values anlegen, um Return-Wert zu erhalten
2072*cdf0e10cSrcweir 	SbxValues aVals;
2073*cdf0e10cSrcweir 	aVals.eType = SbxVARIANT;
2074*cdf0e10cSrcweir 
2075*cdf0e10cSrcweir     // #104083: Compile BEFORE get
2076*cdf0e10cSrcweir 	if( bInvalid && !pMod_->Compile() )
2077*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_PROP_VALUE );
2078*cdf0e10cSrcweir 
2079*cdf0e10cSrcweir 	Get( aVals );
2080*cdf0e10cSrcweir 	if ( pRet )
2081*cdf0e10cSrcweir 		pRet->Put( aVals );
2082*cdf0e10cSrcweir 
2083*cdf0e10cSrcweir 	// Gab es einen Error
2084*cdf0e10cSrcweir 	ErrCode nErr = SbxBase::GetError();
2085*cdf0e10cSrcweir 	SbxBase::ResetError();
2086*cdf0e10cSrcweir 
2087*cdf0e10cSrcweir 	// Objekte freigeben
2088*cdf0e10cSrcweir 	pMod_->ReleaseRef();
2089*cdf0e10cSrcweir 	pBasic->ReleaseRef();
2090*cdf0e10cSrcweir 
2091*cdf0e10cSrcweir 	return nErr;
2092*cdf0e10cSrcweir }
2093*cdf0e10cSrcweir 
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir // #100883 Own Broadcast for SbMethod
2096*cdf0e10cSrcweir void SbMethod::Broadcast( sal_uIntPtr nHintId )
2097*cdf0e10cSrcweir {
2098*cdf0e10cSrcweir 	if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() )
2099*cdf0e10cSrcweir 	{
2100*cdf0e10cSrcweir 		// Da die Methode von aussen aufrufbar ist, hier noch einmal
2101*cdf0e10cSrcweir 		// die Berechtigung testen
2102*cdf0e10cSrcweir 		if( nHintId & SBX_HINT_DATAWANTED )
2103*cdf0e10cSrcweir 			if( !CanRead() )
2104*cdf0e10cSrcweir 				return;
2105*cdf0e10cSrcweir 		if( nHintId & SBX_HINT_DATACHANGED )
2106*cdf0e10cSrcweir 			if( !CanWrite() )
2107*cdf0e10cSrcweir 				return;
2108*cdf0e10cSrcweir 
2109*cdf0e10cSrcweir         if( pMod && !pMod->IsCompiled() )
2110*cdf0e10cSrcweir             pMod->Compile();
2111*cdf0e10cSrcweir 
2112*cdf0e10cSrcweir 		// Block broadcasts while creating new method
2113*cdf0e10cSrcweir 		SfxBroadcaster* pSave = pCst;
2114*cdf0e10cSrcweir 		pCst = NULL;
2115*cdf0e10cSrcweir 		SbMethod* pThisCopy = new SbMethod( *this );
2116*cdf0e10cSrcweir         SbMethodRef xHolder = pThisCopy;
2117*cdf0e10cSrcweir 		if( mpPar.Is() )
2118*cdf0e10cSrcweir         {
2119*cdf0e10cSrcweir 			// this, als Element 0 eintragen, aber den Parent nicht umsetzen!
2120*cdf0e10cSrcweir 			if( GetType() != SbxVOID )
2121*cdf0e10cSrcweir         		mpPar->PutDirect( pThisCopy, 0 );
2122*cdf0e10cSrcweir        		SetParameters( NULL );
2123*cdf0e10cSrcweir         }
2124*cdf0e10cSrcweir 
2125*cdf0e10cSrcweir 		pCst = pSave;
2126*cdf0e10cSrcweir 		pSave->Broadcast( SbxHint( nHintId, pThisCopy ) );
2127*cdf0e10cSrcweir 
2128*cdf0e10cSrcweir 		sal_uInt16 nSaveFlags = GetFlags();
2129*cdf0e10cSrcweir 		SetFlag( SBX_READWRITE );
2130*cdf0e10cSrcweir         pCst = NULL;
2131*cdf0e10cSrcweir         Put( pThisCopy->GetValues_Impl() );
2132*cdf0e10cSrcweir 		pCst = pSave;
2133*cdf0e10cSrcweir 		SetFlags( nSaveFlags );
2134*cdf0e10cSrcweir 	}
2135*cdf0e10cSrcweir }
2136*cdf0e10cSrcweir 
2137*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
2138*cdf0e10cSrcweir 
2139*cdf0e10cSrcweir // Implementation SbJScriptMethod (Method-Klasse als Wrapper fuer JavaScript-Funktionen)
2140*cdf0e10cSrcweir 
2141*cdf0e10cSrcweir SbJScriptMethod::SbJScriptMethod( const String& r, SbxDataType t, SbModule* p )
2142*cdf0e10cSrcweir 		: SbMethod( r, t, p )
2143*cdf0e10cSrcweir {
2144*cdf0e10cSrcweir }
2145*cdf0e10cSrcweir 
2146*cdf0e10cSrcweir SbJScriptMethod::~SbJScriptMethod()
2147*cdf0e10cSrcweir {}
2148*cdf0e10cSrcweir 
2149*cdf0e10cSrcweir 
2150*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
2151*cdf0e10cSrcweir SbObjModule::SbObjModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible )
2152*cdf0e10cSrcweir     : SbModule( rName, bIsVbaCompatible )
2153*cdf0e10cSrcweir {
2154*cdf0e10cSrcweir     SetModuleType( mInfo.ModuleType );
2155*cdf0e10cSrcweir     if ( mInfo.ModuleType == script::ModuleType::FORM )
2156*cdf0e10cSrcweir     {
2157*cdf0e10cSrcweir         SetClassName( rtl::OUString::createFromAscii( "Form" ) );
2158*cdf0e10cSrcweir     }
2159*cdf0e10cSrcweir     else if ( mInfo.ModuleObject.is() )
2160*cdf0e10cSrcweir         SetUnoObject( uno::makeAny( mInfo.ModuleObject ) );
2161*cdf0e10cSrcweir }
2162*cdf0e10cSrcweir 
2163*cdf0e10cSrcweir SbObjModule::~SbObjModule()
2164*cdf0e10cSrcweir {
2165*cdf0e10cSrcweir }
2166*cdf0e10cSrcweir 
2167*cdf0e10cSrcweir void
2168*cdf0e10cSrcweir SbObjModule::SetUnoObject( const uno::Any& aObj ) throw ( uno::RuntimeException )
2169*cdf0e10cSrcweir {
2170*cdf0e10cSrcweir     SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxVariable*)pDocObject);
2171*cdf0e10cSrcweir     if ( pUnoObj && pUnoObj->getUnoAny() == aObj ) // object is equal, nothing to do
2172*cdf0e10cSrcweir         return;
2173*cdf0e10cSrcweir     pDocObject = new SbUnoObject( GetName(), uno::makeAny( aObj ) );
2174*cdf0e10cSrcweir 
2175*cdf0e10cSrcweir     com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( aObj, com::sun::star::uno::UNO_QUERY_THROW );
2176*cdf0e10cSrcweir     if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Worksheet" ) ) )
2177*cdf0e10cSrcweir     {
2178*cdf0e10cSrcweir         SetClassName( rtl::OUString::createFromAscii( "Worksheet" ) );
2179*cdf0e10cSrcweir     }
2180*cdf0e10cSrcweir     else if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Workbook" ) ) )
2181*cdf0e10cSrcweir     {
2182*cdf0e10cSrcweir         SetClassName( rtl::OUString::createFromAscii( "Workbook" ) );
2183*cdf0e10cSrcweir     }
2184*cdf0e10cSrcweir }
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir SbxVariable*
2187*cdf0e10cSrcweir SbObjModule::GetObject()
2188*cdf0e10cSrcweir {
2189*cdf0e10cSrcweir     return pDocObject;
2190*cdf0e10cSrcweir }
2191*cdf0e10cSrcweir SbxVariable*
2192*cdf0e10cSrcweir SbObjModule::Find( const XubString& rName, SbxClassType t )
2193*cdf0e10cSrcweir {
2194*cdf0e10cSrcweir     //OSL_TRACE("SbObjectModule find for %s", rtl::OUStringToOString(  rName, RTL_TEXTENCODING_UTF8 ).getStr() );
2195*cdf0e10cSrcweir     SbxVariable* pVar = NULL;
2196*cdf0e10cSrcweir     if ( pDocObject)
2197*cdf0e10cSrcweir         pVar = pDocObject->Find( rName, t );
2198*cdf0e10cSrcweir     if ( !pVar )
2199*cdf0e10cSrcweir         pVar = SbModule::Find( rName, t );
2200*cdf0e10cSrcweir     return pVar;
2201*cdf0e10cSrcweir }
2202*cdf0e10cSrcweir 
2203*cdf0e10cSrcweir void SbObjModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
2204*cdf0e10cSrcweir 						 const SfxHint& rHint, const TypeId& rHintType )
2205*cdf0e10cSrcweir {
2206*cdf0e10cSrcweir 	SbModule::handleProcedureProperties( rBC, rHint );
2207*cdf0e10cSrcweir }
2208*cdf0e10cSrcweir 
2209*cdf0e10cSrcweir 
2210*cdf0e10cSrcweir typedef ::cppu::WeakImplHelper3<
2211*cdf0e10cSrcweir     awt::XTopWindowListener,
2212*cdf0e10cSrcweir     awt::XWindowListener,
2213*cdf0e10cSrcweir     document::XEventListener > FormObjEventListener_BASE;
2214*cdf0e10cSrcweir 
2215*cdf0e10cSrcweir class FormObjEventListenerImpl : public FormObjEventListener_BASE
2216*cdf0e10cSrcweir {
2217*cdf0e10cSrcweir     SbUserFormModule* mpUserForm;
2218*cdf0e10cSrcweir     uno::Reference< lang::XComponent > mxComponent;
2219*cdf0e10cSrcweir     uno::Reference< frame::XModel > mxModel;
2220*cdf0e10cSrcweir     bool mbDisposed;
2221*cdf0e10cSrcweir     sal_Bool mbOpened;
2222*cdf0e10cSrcweir     sal_Bool mbActivated;
2223*cdf0e10cSrcweir     sal_Bool mbShowing;
2224*cdf0e10cSrcweir 
2225*cdf0e10cSrcweir     FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined
2226*cdf0e10cSrcweir     FormObjEventListenerImpl& operator=(const FormObjEventListenerImpl&); // not defined
2227*cdf0e10cSrcweir 
2228*cdf0e10cSrcweir public:
2229*cdf0e10cSrcweir     FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent, const uno::Reference< frame::XModel >& xModel ) :
2230*cdf0e10cSrcweir         mpUserForm( pUserForm ), mxComponent( xComponent), mxModel( xModel ),
2231*cdf0e10cSrcweir         mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False )
2232*cdf0e10cSrcweir     {
2233*cdf0e10cSrcweir         if ( mxComponent.is() )
2234*cdf0e10cSrcweir         {
2235*cdf0e10cSrcweir             OSL_TRACE("*********** Registering the listeners");
2236*cdf0e10cSrcweir             try
2237*cdf0e10cSrcweir             {
2238*cdf0e10cSrcweir                 uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->addTopWindowListener( this );
2239*cdf0e10cSrcweir             }
2240*cdf0e10cSrcweir             catch( uno::Exception& ) {}
2241*cdf0e10cSrcweir             try
2242*cdf0e10cSrcweir             {
2243*cdf0e10cSrcweir                 uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->addWindowListener( this );
2244*cdf0e10cSrcweir             }
2245*cdf0e10cSrcweir             catch( uno::Exception& ) {}
2246*cdf0e10cSrcweir         }
2247*cdf0e10cSrcweir 
2248*cdf0e10cSrcweir         if ( mxModel.is() )
2249*cdf0e10cSrcweir         {
2250*cdf0e10cSrcweir             try
2251*cdf0e10cSrcweir             {
2252*cdf0e10cSrcweir                 uno::Reference< document::XEventBroadcaster >( mxModel, uno::UNO_QUERY_THROW )->addEventListener( this );
2253*cdf0e10cSrcweir             }
2254*cdf0e10cSrcweir             catch( uno::Exception& ) {}
2255*cdf0e10cSrcweir         }
2256*cdf0e10cSrcweir     }
2257*cdf0e10cSrcweir 
2258*cdf0e10cSrcweir     virtual ~FormObjEventListenerImpl()
2259*cdf0e10cSrcweir     {
2260*cdf0e10cSrcweir         removeListener();
2261*cdf0e10cSrcweir     }
2262*cdf0e10cSrcweir 
2263*cdf0e10cSrcweir     sal_Bool isShowing() const { return mbShowing; }
2264*cdf0e10cSrcweir 
2265*cdf0e10cSrcweir     void removeListener()
2266*cdf0e10cSrcweir     {
2267*cdf0e10cSrcweir         if ( mxComponent.is() && !mbDisposed )
2268*cdf0e10cSrcweir         {
2269*cdf0e10cSrcweir             OSL_TRACE("*********** Removing the listeners");
2270*cdf0e10cSrcweir             try
2271*cdf0e10cSrcweir             {
2272*cdf0e10cSrcweir                 uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeTopWindowListener( this );
2273*cdf0e10cSrcweir             }
2274*cdf0e10cSrcweir             catch( uno::Exception& ) {}
2275*cdf0e10cSrcweir             try
2276*cdf0e10cSrcweir             {
2277*cdf0e10cSrcweir                 uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeWindowListener( this );
2278*cdf0e10cSrcweir             }
2279*cdf0e10cSrcweir             catch( uno::Exception& ) {}
2280*cdf0e10cSrcweir         }
2281*cdf0e10cSrcweir         mxComponent.clear();
2282*cdf0e10cSrcweir 
2283*cdf0e10cSrcweir         if ( mxModel.is() && !mbDisposed )
2284*cdf0e10cSrcweir         {
2285*cdf0e10cSrcweir             try
2286*cdf0e10cSrcweir             {
2287*cdf0e10cSrcweir                 uno::Reference< document::XEventBroadcaster >( mxModel, uno::UNO_QUERY_THROW )->removeEventListener( this );
2288*cdf0e10cSrcweir             }
2289*cdf0e10cSrcweir             catch( uno::Exception& ) {}
2290*cdf0e10cSrcweir         }
2291*cdf0e10cSrcweir         mxModel.clear();
2292*cdf0e10cSrcweir     }
2293*cdf0e10cSrcweir 
2294*cdf0e10cSrcweir     virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2295*cdf0e10cSrcweir     {
2296*cdf0e10cSrcweir         if ( mpUserForm )
2297*cdf0e10cSrcweir         {
2298*cdf0e10cSrcweir             mbOpened = sal_True;
2299*cdf0e10cSrcweir             mbShowing = sal_True;
2300*cdf0e10cSrcweir             if ( mbActivated )
2301*cdf0e10cSrcweir             {
2302*cdf0e10cSrcweir                 mbOpened = mbActivated = sal_False;
2303*cdf0e10cSrcweir                 mpUserForm->triggerActivateEvent();
2304*cdf0e10cSrcweir             }
2305*cdf0e10cSrcweir         }
2306*cdf0e10cSrcweir     }
2307*cdf0e10cSrcweir 
2308*cdf0e10cSrcweir     //liuchen 2009-7-21, support Excel VBA Form_QueryClose event
2309*cdf0e10cSrcweir     virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2310*cdf0e10cSrcweir     {
2311*cdf0e10cSrcweir #if IN_THE_FUTURE
2312*cdf0e10cSrcweir 		uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY );
2313*cdf0e10cSrcweir 		if ( xDialog.is() )
2314*cdf0e10cSrcweir 		{
2315*cdf0e10cSrcweir 			uno::Reference< awt::XControl > xControl( xDialog, uno::UNO_QUERY );
2316*cdf0e10cSrcweir 			if ( xControl->getPeer().is() )
2317*cdf0e10cSrcweir 			{
2318*cdf0e10cSrcweir 				uno::Reference< document::XVbaMethodParameter > xVbaMethodParameter( xControl->getPeer(), uno::UNO_QUERY );
2319*cdf0e10cSrcweir 				if ( xVbaMethodParameter.is() )
2320*cdf0e10cSrcweir 				{
2321*cdf0e10cSrcweir #endif
2322*cdf0e10cSrcweir 					sal_Int8 nCancel = 0;
2323*cdf0e10cSrcweir 					sal_Int8 nCloseMode = ::ooo::vba::VbQueryClose::vbFormControlMenu;
2324*cdf0e10cSrcweir 
2325*cdf0e10cSrcweir 					Sequence< Any > aParams;
2326*cdf0e10cSrcweir 					aParams.realloc(2);
2327*cdf0e10cSrcweir 					aParams[0] <<= nCancel;
2328*cdf0e10cSrcweir 					aParams[1] <<= nCloseMode;
2329*cdf0e10cSrcweir 
2330*cdf0e10cSrcweir 					mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ),
2331*cdf0e10cSrcweir 												aParams);
2332*cdf0e10cSrcweir #if IN_THE_FUTURE
2333*cdf0e10cSrcweir 					xVbaMethodParameter->setVbaMethodParameter( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Cancel")), aParams[0]);
2334*cdf0e10cSrcweir 					return;
2335*cdf0e10cSrcweir 
2336*cdf0e10cSrcweir 				}
2337*cdf0e10cSrcweir 			}
2338*cdf0e10cSrcweir 		}
2339*cdf0e10cSrcweir #endif
2340*cdf0e10cSrcweir     }
2341*cdf0e10cSrcweir 	//liuchen 2009-7-21
2342*cdf0e10cSrcweir 
2343*cdf0e10cSrcweir     virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2344*cdf0e10cSrcweir     {
2345*cdf0e10cSrcweir         mbOpened = sal_False;
2346*cdf0e10cSrcweir         mbShowing = sal_False;
2347*cdf0e10cSrcweir     }
2348*cdf0e10cSrcweir 
2349*cdf0e10cSrcweir     virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2350*cdf0e10cSrcweir     {
2351*cdf0e10cSrcweir     }
2352*cdf0e10cSrcweir 
2353*cdf0e10cSrcweir     virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2354*cdf0e10cSrcweir     {
2355*cdf0e10cSrcweir     }
2356*cdf0e10cSrcweir 
2357*cdf0e10cSrcweir     virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2358*cdf0e10cSrcweir     {
2359*cdf0e10cSrcweir         if ( mpUserForm )
2360*cdf0e10cSrcweir         {
2361*cdf0e10cSrcweir             mbActivated = sal_True;
2362*cdf0e10cSrcweir             if ( mbOpened )
2363*cdf0e10cSrcweir             {
2364*cdf0e10cSrcweir                 mbOpened = mbActivated = sal_False;
2365*cdf0e10cSrcweir                 mpUserForm->triggerActivateEvent();
2366*cdf0e10cSrcweir             }
2367*cdf0e10cSrcweir         }
2368*cdf0e10cSrcweir     }
2369*cdf0e10cSrcweir 
2370*cdf0e10cSrcweir     virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2371*cdf0e10cSrcweir     {
2372*cdf0e10cSrcweir         if ( mpUserForm )
2373*cdf0e10cSrcweir             mpUserForm->triggerDeactivateEvent();
2374*cdf0e10cSrcweir     }
2375*cdf0e10cSrcweir 
2376*cdf0e10cSrcweir     virtual void SAL_CALL windowResized( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
2377*cdf0e10cSrcweir     {
2378*cdf0e10cSrcweir         if ( mpUserForm )
2379*cdf0e10cSrcweir         {
2380*cdf0e10cSrcweir             mpUserForm->triggerResizeEvent();
2381*cdf0e10cSrcweir             mpUserForm->triggerLayoutEvent();
2382*cdf0e10cSrcweir         }
2383*cdf0e10cSrcweir     }
2384*cdf0e10cSrcweir 
2385*cdf0e10cSrcweir     virtual void SAL_CALL windowMoved( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
2386*cdf0e10cSrcweir     {
2387*cdf0e10cSrcweir         if ( mpUserForm )
2388*cdf0e10cSrcweir             mpUserForm->triggerLayoutEvent();
2389*cdf0e10cSrcweir     }
2390*cdf0e10cSrcweir 
2391*cdf0e10cSrcweir     virtual void SAL_CALL windowShown( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2392*cdf0e10cSrcweir     {
2393*cdf0e10cSrcweir     }
2394*cdf0e10cSrcweir 
2395*cdf0e10cSrcweir     virtual void SAL_CALL windowHidden( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2396*cdf0e10cSrcweir     {
2397*cdf0e10cSrcweir     }
2398*cdf0e10cSrcweir 
2399*cdf0e10cSrcweir     virtual void SAL_CALL notifyEvent( const document::EventObject& rEvent ) throw (uno::RuntimeException)
2400*cdf0e10cSrcweir     {
2401*cdf0e10cSrcweir         // early dosposing on document event "OnUnload", to be sure Basic still exists when calling VBA "UserForm_Terminate"
2402*cdf0e10cSrcweir         if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) )
2403*cdf0e10cSrcweir         {
2404*cdf0e10cSrcweir             removeListener();
2405*cdf0e10cSrcweir             mbDisposed = true;
2406*cdf0e10cSrcweir             if ( mpUserForm )
2407*cdf0e10cSrcweir                 mpUserForm->ResetApiObj();   // will trigger "UserForm_Terminate"
2408*cdf0e10cSrcweir         }
2409*cdf0e10cSrcweir     }
2410*cdf0e10cSrcweir 
2411*cdf0e10cSrcweir     virtual void SAL_CALL disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
2412*cdf0e10cSrcweir     {
2413*cdf0e10cSrcweir         OSL_TRACE("** Userform/Dialog disposing");
2414*cdf0e10cSrcweir         removeListener();
2415*cdf0e10cSrcweir         mbDisposed = true;
2416*cdf0e10cSrcweir         if ( mpUserForm )
2417*cdf0e10cSrcweir             mpUserForm->ResetApiObj( false );   // pass false (too late to trigger VBA events here)
2418*cdf0e10cSrcweir     }
2419*cdf0e10cSrcweir };
2420*cdf0e10cSrcweir 
2421*cdf0e10cSrcweir SbUserFormModule::SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat )
2422*cdf0e10cSrcweir 	: SbObjModule( rName, mInfo, bIsCompat )
2423*cdf0e10cSrcweir 	, m_mInfo( mInfo )
2424*cdf0e10cSrcweir 	, mbInit( false )
2425*cdf0e10cSrcweir {
2426*cdf0e10cSrcweir     m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW );
2427*cdf0e10cSrcweir }
2428*cdf0e10cSrcweir 
2429*cdf0e10cSrcweir SbUserFormModule::~SbUserFormModule()
2430*cdf0e10cSrcweir {
2431*cdf0e10cSrcweir }
2432*cdf0e10cSrcweir 
2433*cdf0e10cSrcweir void SbUserFormModule::ResetApiObj(  bool bTriggerTerminateEvent )
2434*cdf0e10cSrcweir {
2435*cdf0e10cSrcweir     if ( bTriggerTerminateEvent && m_xDialog.is() ) // probably someone close the dialog window
2436*cdf0e10cSrcweir 	{
2437*cdf0e10cSrcweir         triggerTerminateEvent();
2438*cdf0e10cSrcweir     }
2439*cdf0e10cSrcweir     pDocObject = NULL;
2440*cdf0e10cSrcweir 	m_xDialog = NULL;
2441*cdf0e10cSrcweir }
2442*cdf0e10cSrcweir 
2443*cdf0e10cSrcweir void SbUserFormModule::triggerMethod( const String& aMethodToRun )
2444*cdf0e10cSrcweir {
2445*cdf0e10cSrcweir 	Sequence< Any > aArguments;
2446*cdf0e10cSrcweir 	triggerMethod( aMethodToRun, aArguments );
2447*cdf0e10cSrcweir }
2448*cdf0e10cSrcweir 
2449*cdf0e10cSrcweir void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& aArguments )
2450*cdf0e10cSrcweir {
2451*cdf0e10cSrcweir 	OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() );
2452*cdf0e10cSrcweir 	// Search method
2453*cdf0e10cSrcweir 	SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD );
2454*cdf0e10cSrcweir 	if( pMeth )
2455*cdf0e10cSrcweir 	{
2456*cdf0e10cSrcweir 		if ( aArguments.getLength() > 0 )   // Setup parameters
2457*cdf0e10cSrcweir 		{
2458*cdf0e10cSrcweir 			SbxArrayRef xArray = new SbxArray;
2459*cdf0e10cSrcweir 			xArray->Put( pMeth, 0 );	// Method as parameter 0
2460*cdf0e10cSrcweir 
2461*cdf0e10cSrcweir 			for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
2462*cdf0e10cSrcweir 			{
2463*cdf0e10cSrcweir 				SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
2464*cdf0e10cSrcweir                 unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), aArguments[i] );
2465*cdf0e10cSrcweir                 xArray->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
2466*cdf0e10cSrcweir 
2467*cdf0e10cSrcweir 				// Enable passing by ref
2468*cdf0e10cSrcweir 				if ( xSbxVar->GetType() != SbxVARIANT )
2469*cdf0e10cSrcweir 					xSbxVar->SetFlag( SBX_FIXED );
2470*cdf0e10cSrcweir 			}
2471*cdf0e10cSrcweir 			pMeth->SetParameters( xArray );
2472*cdf0e10cSrcweir 
2473*cdf0e10cSrcweir 			SbxValues aVals;
2474*cdf0e10cSrcweir 			pMeth->Get( aVals );
2475*cdf0e10cSrcweir 
2476*cdf0e10cSrcweir 			for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
2477*cdf0e10cSrcweir 			{
2478*cdf0e10cSrcweir 				aArguments[i] = sbxToUnoValue( xArray->Get( static_cast< sal_uInt16 >(i) + 1) );
2479*cdf0e10cSrcweir 			}
2480*cdf0e10cSrcweir 			pMeth->SetParameters( NULL );
2481*cdf0e10cSrcweir 		}
2482*cdf0e10cSrcweir 		else
2483*cdf0e10cSrcweir 		{
2484*cdf0e10cSrcweir 			SbxValues aVals;
2485*cdf0e10cSrcweir 			pMeth->Get( aVals );
2486*cdf0e10cSrcweir 		}
2487*cdf0e10cSrcweir 	}
2488*cdf0e10cSrcweir }
2489*cdf0e10cSrcweir 
2490*cdf0e10cSrcweir void SbUserFormModule::triggerActivateEvent( void )
2491*cdf0e10cSrcweir {
2492*cdf0e10cSrcweir     OSL_TRACE("**** entering SbUserFormModule::triggerActivate");
2493*cdf0e10cSrcweir 	triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_Activate") ) );
2494*cdf0e10cSrcweir     OSL_TRACE("**** leaving SbUserFormModule::triggerActivate");
2495*cdf0e10cSrcweir }
2496*cdf0e10cSrcweir 
2497*cdf0e10cSrcweir void SbUserFormModule::triggerDeactivateEvent( void )
2498*cdf0e10cSrcweir {
2499*cdf0e10cSrcweir     OSL_TRACE("**** SbUserFormModule::triggerDeactivate");
2500*cdf0e10cSrcweir 	triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_Deactivate") ) );
2501*cdf0e10cSrcweir }
2502*cdf0e10cSrcweir 
2503*cdf0e10cSrcweir void SbUserFormModule::triggerInitializeEvent( void )
2504*cdf0e10cSrcweir {
2505*cdf0e10cSrcweir 	if ( mbInit )
2506*cdf0e10cSrcweir 		return;
2507*cdf0e10cSrcweir     OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent");
2508*cdf0e10cSrcweir 	static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") );
2509*cdf0e10cSrcweir 	triggerMethod( aInitMethodName );
2510*cdf0e10cSrcweir 	mbInit = true;
2511*cdf0e10cSrcweir }
2512*cdf0e10cSrcweir 
2513*cdf0e10cSrcweir void SbUserFormModule::triggerTerminateEvent( void )
2514*cdf0e10cSrcweir {
2515*cdf0e10cSrcweir     OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent");
2516*cdf0e10cSrcweir 	static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") );
2517*cdf0e10cSrcweir 	triggerMethod( aTermMethodName );
2518*cdf0e10cSrcweir 	mbInit=false;
2519*cdf0e10cSrcweir }
2520*cdf0e10cSrcweir 
2521*cdf0e10cSrcweir void SbUserFormModule::triggerLayoutEvent( void )
2522*cdf0e10cSrcweir {
2523*cdf0e10cSrcweir 	static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Layout") );
2524*cdf0e10cSrcweir 	triggerMethod( aMethodName );
2525*cdf0e10cSrcweir }
2526*cdf0e10cSrcweir 
2527*cdf0e10cSrcweir void SbUserFormModule::triggerResizeEvent( void )
2528*cdf0e10cSrcweir {
2529*cdf0e10cSrcweir 	static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Resize") );
2530*cdf0e10cSrcweir 	triggerMethod( aMethodName );
2531*cdf0e10cSrcweir }
2532*cdf0e10cSrcweir 
2533*cdf0e10cSrcweir SbUserFormModuleInstance* SbUserFormModule::CreateInstance()
2534*cdf0e10cSrcweir {
2535*cdf0e10cSrcweir 	SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() );
2536*cdf0e10cSrcweir 	return pInstance;
2537*cdf0e10cSrcweir }
2538*cdf0e10cSrcweir 
2539*cdf0e10cSrcweir SbUserFormModuleInstance::SbUserFormModuleInstance( SbUserFormModule* pParentModule,
2540*cdf0e10cSrcweir 	const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat )
2541*cdf0e10cSrcweir 		: SbUserFormModule( rName, mInfo, bIsVBACompat )
2542*cdf0e10cSrcweir 		, m_pParentModule( pParentModule )
2543*cdf0e10cSrcweir {
2544*cdf0e10cSrcweir }
2545*cdf0e10cSrcweir 
2546*cdf0e10cSrcweir sal_Bool SbUserFormModuleInstance::IsClass( const XubString& rName ) const
2547*cdf0e10cSrcweir {
2548*cdf0e10cSrcweir 	sal_Bool bParentNameMatches = m_pParentModule->GetName().EqualsIgnoreCaseAscii( rName );
2549*cdf0e10cSrcweir 	sal_Bool bRet = bParentNameMatches || SbxObject::IsClass( rName );
2550*cdf0e10cSrcweir 	return bRet;
2551*cdf0e10cSrcweir }
2552*cdf0e10cSrcweir 
2553*cdf0e10cSrcweir SbxVariable* SbUserFormModuleInstance::Find( const XubString& rName, SbxClassType t )
2554*cdf0e10cSrcweir {
2555*cdf0e10cSrcweir 	SbxVariable* pVar = m_pParentModule->Find( rName, t );
2556*cdf0e10cSrcweir 	return pVar;
2557*cdf0e10cSrcweir }
2558*cdf0e10cSrcweir 
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir void SbUserFormModule::Load()
2561*cdf0e10cSrcweir {
2562*cdf0e10cSrcweir     OSL_TRACE("** load() ");
2563*cdf0e10cSrcweir     // forces a load
2564*cdf0e10cSrcweir     if ( !pDocObject )
2565*cdf0e10cSrcweir         InitObject();
2566*cdf0e10cSrcweir }
2567*cdf0e10cSrcweir 
2568*cdf0e10cSrcweir //liuchen 2009-7-21 change to accmordate VBA's beheavior
2569*cdf0e10cSrcweir void SbUserFormModule::Unload()
2570*cdf0e10cSrcweir {
2571*cdf0e10cSrcweir     OSL_TRACE("** Unload() ");
2572*cdf0e10cSrcweir 
2573*cdf0e10cSrcweir 	sal_Int8 nCancel = 0;
2574*cdf0e10cSrcweir 	sal_Int8 nCloseMode = ::ooo::vba::VbQueryClose::vbFormCode;
2575*cdf0e10cSrcweir 
2576*cdf0e10cSrcweir 	Sequence< Any > aParams;
2577*cdf0e10cSrcweir 	aParams.realloc(2);
2578*cdf0e10cSrcweir 	aParams[0] <<= nCancel;
2579*cdf0e10cSrcweir 	aParams[1] <<= nCloseMode;
2580*cdf0e10cSrcweir 
2581*cdf0e10cSrcweir 	triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), aParams);
2582*cdf0e10cSrcweir 
2583*cdf0e10cSrcweir 	aParams[0] >>= nCancel;
2584*cdf0e10cSrcweir 	if (nCancel != 0)  // Basic returns -1 for "True"
2585*cdf0e10cSrcweir 	{
2586*cdf0e10cSrcweir 		return;
2587*cdf0e10cSrcweir 	}
2588*cdf0e10cSrcweir 
2589*cdf0e10cSrcweir     if ( m_xDialog.is() )
2590*cdf0e10cSrcweir     {
2591*cdf0e10cSrcweir 		triggerTerminateEvent();
2592*cdf0e10cSrcweir     }
2593*cdf0e10cSrcweir 	// Search method
2594*cdf0e10cSrcweir 	SbxVariable* pMeth = SbObjModule::Find( String( RTL_CONSTASCII_USTRINGPARAM( "UnloadObject" ) ), SbxCLASS_METHOD );
2595*cdf0e10cSrcweir 	if( pMeth )
2596*cdf0e10cSrcweir 	{
2597*cdf0e10cSrcweir 		OSL_TRACE("Attempting too run the UnloadObjectMethod");
2598*cdf0e10cSrcweir         m_xDialog.clear(); //release ref to the uno object
2599*cdf0e10cSrcweir 		SbxValues aVals;
2600*cdf0e10cSrcweir 		bool bWaitForDispose = true; // assume dialog is showing
2601*cdf0e10cSrcweir         if ( m_DialogListener.get() )
2602*cdf0e10cSrcweir 		{
2603*cdf0e10cSrcweir 			bWaitForDispose = m_DialogListener->isShowing();
2604*cdf0e10cSrcweir 			OSL_TRACE("Showing %d", bWaitForDispose );
2605*cdf0e10cSrcweir 		}
2606*cdf0e10cSrcweir 		pMeth->Get( aVals);
2607*cdf0e10cSrcweir         if ( !bWaitForDispose )
2608*cdf0e10cSrcweir         {
2609*cdf0e10cSrcweir             // we've either already got a dispose or we'er never going to get one
2610*cdf0e10cSrcweir 		    ResetApiObj();
2611*cdf0e10cSrcweir         } // else wait for dispose
2612*cdf0e10cSrcweir 		OSL_TRACE("UnloadObject completed ( we hope )");
2613*cdf0e10cSrcweir 	}
2614*cdf0e10cSrcweir }
2615*cdf0e10cSrcweir //liuchen
2616*cdf0e10cSrcweir 
2617*cdf0e10cSrcweir void registerComponentToBeDisposedForBasic( Reference< XComponent > xComponent, StarBASIC* pBasic );
2618*cdf0e10cSrcweir 
2619*cdf0e10cSrcweir void SbUserFormModule::InitObject()
2620*cdf0e10cSrcweir {
2621*cdf0e10cSrcweir     try
2622*cdf0e10cSrcweir     {
2623*cdf0e10cSrcweir         String aHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
2624*cdf0e10cSrcweir         SbUnoObject* pGlobs = (SbUnoObject*)GetParent()->Find( aHook, SbxCLASS_DONTCARE );
2625*cdf0e10cSrcweir         if ( m_xModel.is() && pGlobs )
2626*cdf0e10cSrcweir         {
2627*cdf0e10cSrcweir             // broadcast INITIALIZE_USERFORM script event before the dialog is created
2628*cdf0e10cSrcweir             Reference< script::vba::XVBACompatibility > xVBACompat( getVBACompatibility( m_xModel ), uno::UNO_SET_THROW );
2629*cdf0e10cSrcweir             xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::INITIALIZE_USERFORM, GetName() );
2630*cdf0e10cSrcweir 
2631*cdf0e10cSrcweir             uno::Reference< lang::XMultiServiceFactory > xVBAFactory( pGlobs->getUnoAny(), uno::UNO_QUERY_THROW );
2632*cdf0e10cSrcweir             uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
2633*cdf0e10cSrcweir             uno::Sequence< uno::Any > aArgs(1);
2634*cdf0e10cSrcweir             aArgs[ 0 ] <<= m_xModel;
2635*cdf0e10cSrcweir             rtl::OUString sDialogUrl( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:" ) );
2636*cdf0e10cSrcweir             rtl::OUString sProjectName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
2637*cdf0e10cSrcweir             if ( this->GetParent()->GetName().Len() )
2638*cdf0e10cSrcweir                 sProjectName = this->GetParent()->GetName();
2639*cdf0e10cSrcweir             sDialogUrl = sDialogUrl.concat( sProjectName ).concat( rtl::OUString( '.') ).concat( GetName() ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) );
2640*cdf0e10cSrcweir 
2641*cdf0e10cSrcweir             uno::Reference< awt::XDialogProvider > xProvider( xFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")), aArgs  ), uno::UNO_QUERY_THROW );
2642*cdf0e10cSrcweir             m_xDialog = xProvider->createDialog( sDialogUrl );
2643*cdf0e10cSrcweir 
2644*cdf0e10cSrcweir             // create vba api object
2645*cdf0e10cSrcweir             aArgs.realloc( 4 );
2646*cdf0e10cSrcweir             aArgs[ 0 ] = uno::Any();
2647*cdf0e10cSrcweir             aArgs[ 1 ] <<= m_xDialog;
2648*cdf0e10cSrcweir             aArgs[ 2 ] <<= m_xModel;
2649*cdf0e10cSrcweir             aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() );
2650*cdf0e10cSrcweir             pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs  ) ) );
2651*cdf0e10cSrcweir 
2652*cdf0e10cSrcweir             uno::Reference< lang::XComponent > xComponent( m_xDialog, uno::UNO_QUERY_THROW );
2653*cdf0e10cSrcweir 
2654*cdf0e10cSrcweir             // the dialog must be disposed at the end!
2655*cdf0e10cSrcweir             StarBASIC* pParentBasic = NULL;
2656*cdf0e10cSrcweir             SbxObject* pCurObject = this;
2657*cdf0e10cSrcweir             do
2658*cdf0e10cSrcweir             {
2659*cdf0e10cSrcweir                 SbxObject* pObjParent = pCurObject->GetParent();
2660*cdf0e10cSrcweir                 pParentBasic = PTR_CAST( StarBASIC, pObjParent );
2661*cdf0e10cSrcweir                 pCurObject = pObjParent;
2662*cdf0e10cSrcweir             }
2663*cdf0e10cSrcweir             while( pParentBasic == NULL && pCurObject != NULL );
2664*cdf0e10cSrcweir 
2665*cdf0e10cSrcweir             OSL_ASSERT( pParentBasic != NULL );
2666*cdf0e10cSrcweir             registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
2667*cdf0e10cSrcweir 
2668*cdf0e10cSrcweir             // if old listener object exists, remove it from dialog and document model
2669*cdf0e10cSrcweir             if( m_DialogListener.is() )
2670*cdf0e10cSrcweir                 m_DialogListener->removeListener();
2671*cdf0e10cSrcweir             m_DialogListener.set( new FormObjEventListenerImpl( this, xComponent, m_xModel ) );
2672*cdf0e10cSrcweir 
2673*cdf0e10cSrcweir             triggerInitializeEvent();
2674*cdf0e10cSrcweir         }
2675*cdf0e10cSrcweir     }
2676*cdf0e10cSrcweir     catch( uno::Exception& )
2677*cdf0e10cSrcweir     {
2678*cdf0e10cSrcweir     }
2679*cdf0e10cSrcweir 
2680*cdf0e10cSrcweir }
2681*cdf0e10cSrcweir 
2682*cdf0e10cSrcweir SbxVariable*
2683*cdf0e10cSrcweir SbUserFormModule::Find( const XubString& rName, SbxClassType t )
2684*cdf0e10cSrcweir {
2685*cdf0e10cSrcweir     if ( !pDocObject && !GetSbData()->bRunInit && pINST )
2686*cdf0e10cSrcweir         InitObject();
2687*cdf0e10cSrcweir     return SbObjModule::Find( rName, t );
2688*cdf0e10cSrcweir }
2689*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
2690*cdf0e10cSrcweir 
2691*cdf0e10cSrcweir SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p )
2692*cdf0e10cSrcweir 		: SbxProperty( r, t ), pMod( p )
2693*cdf0e10cSrcweir {
2694*cdf0e10cSrcweir 	bInvalid = sal_False;
2695*cdf0e10cSrcweir }
2696*cdf0e10cSrcweir 
2697*cdf0e10cSrcweir SbProperty::~SbProperty()
2698*cdf0e10cSrcweir {}
2699*cdf0e10cSrcweir 
2700*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////
2701*cdf0e10cSrcweir 
2702*cdf0e10cSrcweir SbProcedureProperty::~SbProcedureProperty()
2703*cdf0e10cSrcweir {}
2704*cdf0e10cSrcweir 
2705