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