LCOV - code coverage report
Current view: top level - basic/source/classes - sbxmod.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 661 1353 48.9 %
Date: 2015-06-13 12:38:46 Functions: 94 213 44.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11