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