LCOV - code coverage report
Current view: top level - basic/source/classes - sbunoobj.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1189 2534 46.9 %
Date: 2015-06-13 12:38:46 Functions: 101 221 45.7 %
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             : #include <osl/mutex.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <tools/errcode.hxx>
      23             : #include <svl/hint.hxx>
      24             : 
      25             : #include <cppuhelper/implbase1.hxx>
      26             : #include <cppuhelper/implbase2.hxx>
      27             : #include <cppuhelper/exc_hlp.hxx>
      28             : #include <cppuhelper/typeprovider.hxx>
      29             : #include <cppuhelper/interfacecontainer.hxx>
      30             : #include <comphelper/extract.hxx>
      31             : #include <comphelper/processfactory.hxx>
      32             : 
      33             : #include <rtl/instance.hxx>
      34             : #include <rtl/strbuf.hxx>
      35             : #include <rtl/ustrbuf.hxx>
      36             : 
      37             : #include <com/sun/star/script/ArrayWrapper.hpp>
      38             : #include <com/sun/star/script/NativeObjectWrapper.hpp>
      39             : 
      40             : #include <com/sun/star/uno/XComponentContext.hpp>
      41             : #include <com/sun/star/uno/DeploymentException.hpp>
      42             : #include <com/sun/star/lang/XTypeProvider.hpp>
      43             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      44             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      45             : #include <com/sun/star/lang/XServiceInfo.hpp>
      46             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      47             : #include <com/sun/star/beans/PropertyConcept.hpp>
      48             : #include <com/sun/star/beans/MethodConcept.hpp>
      49             : #include <com/sun/star/beans/XPropertySet.hpp>
      50             : #include <com/sun/star/beans/theIntrospection.hpp>
      51             : #include <com/sun/star/script/BasicErrorException.hpp>
      52             : #include <com/sun/star/script/InvocationAdapterFactory.hpp>
      53             : #include <com/sun/star/script/XAllListener.hpp>
      54             : #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
      55             : #include <com/sun/star/script/Converter.hpp>
      56             : #include <com/sun/star/script/XDefaultProperty.hpp>
      57             : #include <com/sun/star/script/XDefaultMethod.hpp>
      58             : #include <com/sun/star/script/XDirectInvocation.hpp>
      59             : #include <com/sun/star/container/XNameAccess.hpp>
      60             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      61             : #include <com/sun/star/reflection/XIdlArray.hpp>
      62             : #include <com/sun/star/reflection/XIdlReflection.hpp>
      63             : #include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
      64             : #include <com/sun/star/reflection/theCoreReflection.hpp>
      65             : #include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
      66             : #include <com/sun/star/bridge/oleautomation/Date.hpp>
      67             : #include <com/sun/star/bridge/oleautomation/Decimal.hpp>
      68             : #include <com/sun/star/bridge/oleautomation/Currency.hpp>
      69             : #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
      70             : #include <com/sun/star/script/XAutomationInvocation.hpp>
      71             : #include <basic/codecompletecache.hxx>
      72             : 
      73             : #include <rtlproto.hxx>
      74             : 
      75             : #include <basic/sbstar.hxx>
      76             : #include <basic/sbuno.hxx>
      77             : #include <basic/sberrors.hxx>
      78             : #include <sbunoobj.hxx>
      79             : #include "sbjsmod.hxx"
      80             : #include <basic/basmgr.hxx>
      81             : #include <sbintern.hxx>
      82             : #include <runtime.hxx>
      83             : 
      84             : #include <math.h>
      85             : #include <boost/scoped_array.hpp>
      86             : #include <unordered_map>
      87             : #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
      88             : #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
      89             : 
      90             : using com::sun::star::uno::Reference;
      91             : using namespace com::sun::star::uno;
      92             : using namespace com::sun::star::lang;
      93             : using namespace com::sun::star::reflection;
      94             : using namespace com::sun::star::beans;
      95             : using namespace com::sun::star::script;
      96             : using namespace com::sun::star::container;
      97             : using namespace com::sun::star::bridge;
      98             : using namespace cppu;
      99             : 
     100       40025 : TYPEINIT1(SbUnoMethod,SbxMethod)
     101       58160 : TYPEINIT1(SbUnoProperty,SbxProperty)
     102      628632 : TYPEINIT1(SbUnoObject,SbxObject)
     103         562 : TYPEINIT1(SbUnoStructRefObject,SbxObject)
     104          42 : TYPEINIT1(SbUnoClass,SbxObject)
     105           0 : TYPEINIT1(SbUnoService,SbxObject)
     106           0 : TYPEINIT1(SbUnoServiceCtor,SbxMethod)
     107           0 : TYPEINIT1(SbUnoSingleton,SbxObject)
     108             : 
     109             : typedef WeakImplHelper1< XAllListener > BasicAllListenerHelper;
     110             : 
     111             : // Identifiers for creating the strings for dbg_Properties
     112             : static char const ID_DBG_SUPPORTEDINTERFACES[] = "Dbg_SupportedInterfaces";
     113             : static char const ID_DBG_PROPERTIES[] = "Dbg_Properties";
     114             : static char const ID_DBG_METHODS[] = "Dbg_Methods";
     115             : 
     116             : static char const aSeqLevelStr[] = "[]";
     117             : static char const defaultNameSpace[] = "ooo.vba";
     118             : 
     119             : // Gets the default property for an uno object. Note: There is some
     120             : // redirection built in. The property name specifies the name
     121             : // of the default property.
     122             : 
     123        2606 : bool SbUnoObject::getDefaultPropName( SbUnoObject* pUnoObj, OUString& sDfltProp )
     124             : {
     125        2606 :     bool result = false;
     126        2606 :     Reference< XDefaultProperty> xDefaultProp( pUnoObj->maTmpUnoObj, UNO_QUERY );
     127        2606 :     if ( xDefaultProp.is() )
     128             :     {
     129        1548 :         sDfltProp = xDefaultProp->getDefaultPropertyName();
     130        1548 :         if ( !sDfltProp.isEmpty() )
     131        1548 :             result = true;
     132             :     }
     133        2606 :     return result;
     134             : }
     135             : 
     136         253 : SbxVariable* getDefaultProp( SbxVariable* pRef )
     137             : {
     138         253 :     SbxVariable* pDefaultProp = NULL;
     139         253 :     if ( pRef->GetType() == SbxOBJECT )
     140             :     {
     141         253 :           SbxObject* pObj = PTR_CAST(SbxObject, pRef);
     142         253 :         if ( !pObj )
     143             :         {
     144         249 :             SbxBase* pObjVarObj = pRef->GetObject();
     145         249 :             pObj = PTR_CAST(SbxObject,pObjVarObj);
     146             :         }
     147         253 :         if ( pObj && pObj->ISA(SbUnoObject) )
     148             :         {
     149         246 :             SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
     150         246 :             pDefaultProp = pUnoObj->GetDfltProperty();
     151             :         }
     152             :     }
     153         253 :     return pDefaultProp;
     154             : }
     155             : 
     156           0 : void SetSbUnoObjectDfltPropName( SbxObject* pObj )
     157             : {
     158           0 :     SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject, pObj);
     159           0 :     if ( pUnoObj )
     160             :     {
     161           0 :         OUString sDfltPropName;
     162             : 
     163           0 :         if ( SbUnoObject::getDefaultPropName( pUnoObj, sDfltPropName ) )
     164             :         {
     165             :             OSL_TRACE("SetSbUnoObjectDfltPropName setting default prop for %s", OUStringToOString( pObj->GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
     166           0 :             pUnoObj->SetDfltProperty( sDfltPropName );
     167           0 :         }
     168             :     }
     169           0 : }
     170             : 
     171             : // save CoreReflection statically
     172       13354 : Reference< XIdlReflection > getCoreReflection_Impl()
     173             : {
     174             :     return css::reflection::theCoreReflection::get(
     175       13354 :         comphelper::getProcessComponentContext());
     176             : }
     177             : 
     178             : // save CoreReflection statically
     179          57 : Reference< XHierarchicalNameAccess > getCoreReflection_HierarchicalNameAccess_Impl()
     180             : {
     181          57 :     static Reference< XHierarchicalNameAccess > xCoreReflection_HierarchicalNameAccess;
     182             : 
     183          57 :     if( !xCoreReflection_HierarchicalNameAccess.is() )
     184             :     {
     185           4 :         Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
     186           4 :         if( xCoreReflection.is() )
     187             :         {
     188           8 :             xCoreReflection_HierarchicalNameAccess =
     189           4 :                 Reference< XHierarchicalNameAccess >( xCoreReflection, UNO_QUERY );
     190           4 :         }
     191             :     }
     192          57 :     return xCoreReflection_HierarchicalNameAccess;
     193             : }
     194             : 
     195             : // Hold TypeProvider statically
     196         116 : Reference< XHierarchicalNameAccess > getTypeProvider_Impl()
     197             : {
     198         116 :     static Reference< XHierarchicalNameAccess > xAccess;
     199             : 
     200             :     // Do we have already CoreReflection; if not obtain it
     201         116 :     if( !xAccess.is() )
     202             :     {
     203             :         Reference< XComponentContext > xContext(
     204           4 :             comphelper::getProcessComponentContext() );
     205           4 :         if( xContext.is() )
     206             :         {
     207           4 :             xContext->getValueByName(
     208           4 :                 OUString( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) )
     209           4 :                     >>= xAccess;
     210             :             OSL_ENSURE( xAccess.is(), "### TypeDescriptionManager singleton not accessible!?" );
     211             :         }
     212           4 :         if( !xAccess.is() )
     213             :         {
     214             :             throw DeploymentException(
     215           0 :                     "/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessible" );
     216           4 :         }
     217             :     }
     218         116 :     return xAccess;
     219             : }
     220             : 
     221             : // Hold TypeConverter statically
     222           0 : Reference< XTypeConverter > getTypeConverter_Impl()
     223             : {
     224           0 :     static Reference< XTypeConverter > xTypeConverter;
     225             : 
     226             :     // Do we have already CoreReflection; if not obtain it
     227           0 :     if( !xTypeConverter.is() )
     228             :     {
     229             :         Reference< XComponentContext > xContext(
     230           0 :             comphelper::getProcessComponentContext() );
     231           0 :         if( xContext.is() )
     232             :         {
     233           0 :             xTypeConverter = Converter::create(xContext);
     234             :         }
     235           0 :         if( !xTypeConverter.is() )
     236             :         {
     237             :             throw DeploymentException(
     238           0 :                 "com.sun.star.script.Converter service not accessible" );
     239           0 :         }
     240             :     }
     241           0 :     return xTypeConverter;
     242             : }
     243             : 
     244             : 
     245             : // #111851 factory function to create an OLE object
     246          20 : SbUnoObject* createOLEObject_Impl( const OUString& aType )
     247             : {
     248          20 :     static Reference< XMultiServiceFactory > xOLEFactory;
     249             :     static bool bNeedsInit = true;
     250             : 
     251          20 :     if( bNeedsInit )
     252             :     {
     253           4 :         bNeedsInit = false;
     254             : 
     255             :         Reference< XComponentContext > xContext(
     256           4 :             comphelper::getProcessComponentContext() );
     257           4 :         if( xContext.is() )
     258             :         {
     259           4 :             Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
     260           8 :             xOLEFactory = Reference<XMultiServiceFactory>(
     261           4 :                 xSMgr->createInstanceWithContext(
     262             :                     OUString( "com.sun.star.bridge.OleObjectFactory"),
     263          12 :                         xContext ), UNO_QUERY );
     264           4 :         }
     265             :     }
     266             : 
     267          20 :     SbUnoObject* pUnoObj = NULL;
     268          20 :     if( xOLEFactory.is() )
     269             :     {
     270             :         // some type names available in VBA can not be directly used in COM
     271           0 :         OUString aOLEType = aType;
     272           0 :         if ( aOLEType == "SAXXMLReader30" )
     273             :         {
     274           0 :             aOLEType = "Msxml2.SAXXMLReader.3.0";
     275             :         }
     276           0 :         Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aOLEType );
     277           0 :         if( xOLEObject.is() )
     278             :         {
     279           0 :             Any aAny;
     280           0 :             aAny <<= xOLEObject;
     281           0 :             pUnoObj = new SbUnoObject( aType, aAny );
     282           0 :             OUString sDfltPropName;
     283             : 
     284           0 :             if ( SbUnoObject::getDefaultPropName( pUnoObj, sDfltPropName ) )
     285           0 :                 pUnoObj->SetDfltProperty( sDfltPropName );
     286           0 :         }
     287             :     }
     288          20 :     return pUnoObj;
     289             : }
     290             : 
     291             : 
     292             : namespace
     293             : {
     294           6 :     void lcl_indent( OUStringBuffer& _inout_rBuffer, sal_Int32 _nLevel )
     295             :     {
     296          12 :         while ( _nLevel-- > 0 )
     297             :         {
     298           0 :             _inout_rBuffer.appendAscii( "  " );
     299             :         }
     300           6 :     }
     301             : }
     302             : 
     303           3 : void implAppendExceptionMsg( OUStringBuffer& _inout_rBuffer, const Exception& _e, const OUString& _rExceptionType, sal_Int32 _nLevel )
     304             : {
     305           3 :     _inout_rBuffer.appendAscii( "\n" );
     306           3 :     lcl_indent( _inout_rBuffer, _nLevel );
     307           3 :     _inout_rBuffer.appendAscii( "Type: " );
     308             : 
     309           3 :     if ( _rExceptionType.isEmpty() )
     310           0 :         _inout_rBuffer.appendAscii( "Unknown" );
     311             :     else
     312           3 :         _inout_rBuffer.append( _rExceptionType );
     313             : 
     314           3 :     _inout_rBuffer.appendAscii( "\n" );
     315           3 :     lcl_indent( _inout_rBuffer, _nLevel );
     316           3 :     _inout_rBuffer.appendAscii( "Message: " );
     317           3 :     _inout_rBuffer.append( _e.Message );
     318             : 
     319           3 : }
     320             : 
     321             : // construct an error message for the exception
     322           0 : OUString implGetExceptionMsg( const Exception& e, const OUString& aExceptionType_ )
     323             : {
     324           0 :     OUStringBuffer aMessageBuf;
     325           0 :     implAppendExceptionMsg( aMessageBuf, e, aExceptionType_, 0 );
     326           0 :     return aMessageBuf.makeStringAndClear();
     327             : }
     328             : 
     329           0 : OUString implGetExceptionMsg( const Any& _rCaughtException )
     330             : {
     331             :     OSL_PRECOND( _rCaughtException.getValueTypeClass() == TypeClass_EXCEPTION, "implGetExceptionMsg: illegal argument!" );
     332           0 :     if ( _rCaughtException.getValueTypeClass() != TypeClass_EXCEPTION )
     333             :     {
     334           0 :         return OUString();
     335             :     }
     336           0 :     return implGetExceptionMsg( *static_cast< const Exception* >( _rCaughtException.getValue() ), _rCaughtException.getValueTypeName() );
     337             : }
     338             : 
     339           0 : Any convertAny( const Any& rVal, const Type& aDestType )
     340             : {
     341           0 :     Any aConvertedVal;
     342           0 :     Reference< XTypeConverter > xConverter = getTypeConverter_Impl();
     343             :     try
     344             :     {
     345           0 :         aConvertedVal = xConverter->convertTo( rVal, aDestType );
     346             :     }
     347           0 :     catch( const IllegalArgumentException& )
     348             :     {
     349             :         StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
     350           0 :             implGetExceptionMsg( ::cppu::getCaughtException() ) );
     351           0 :         return aConvertedVal;
     352             :     }
     353           0 :     catch( const CannotConvertException& e2 )
     354             :     {
     355           0 :         OUString aCannotConvertExceptionName( "com.sun.star.lang.IllegalArgumentException");
     356             :         StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
     357           0 :                           implGetExceptionMsg( e2, aCannotConvertExceptionName ) );
     358           0 :         return aConvertedVal;
     359             :     }
     360           0 :     return aConvertedVal;
     361             : }
     362             : 
     363             : 
     364             : // #105565 Special Object to wrap a strongly typed Uno Any
     365       48245 : TYPEINIT1(SbUnoAnyObject,SbxObject)
     366             : 
     367             : 
     368             : // TODO: source out later
     369       13278 : Reference<XIdlClass> TypeToIdlClass( const Type& rType )
     370             : {
     371       13278 :     return getCoreReflection_Impl()->forName(rType.getTypeName());
     372             : }
     373             : 
     374             : // Exception type unknown
     375             : template< class EXCEPTION >
     376           0 : OUString implGetExceptionMsg( const EXCEPTION& e )
     377             : {
     378           0 :     return implGetExceptionMsg( e, cppu::UnoType<decltype(e)>::get().getTypeName() );
     379             : }
     380             : 
     381           0 : void implHandleBasicErrorException( BasicErrorException& e )
     382             : {
     383           0 :     SbError nError = StarBASIC::GetSfxFromVBError( (sal_uInt16)e.ErrorCode );
     384           0 :     StarBASIC::Error( nError, e.ErrorMessageArgument );
     385           0 : }
     386             : 
     387           3 : void implHandleWrappedTargetException( const Any& _rWrappedTargetException )
     388             : {
     389           3 :     Any aExamine( _rWrappedTargetException );
     390             : 
     391             :     // completely strip the first InvocationTargetException, its error message isn't of any
     392             :     // interest to the user, it just says something like "invoking the UNO method went wrong.".
     393           6 :     InvocationTargetException aInvocationError;
     394           3 :     if ( aExamine >>= aInvocationError )
     395           3 :         aExamine = aInvocationError.TargetException;
     396             : 
     397           6 :     BasicErrorException aBasicError;
     398             : 
     399           3 :     SbError nError( ERRCODE_BASIC_EXCEPTION );
     400           6 :     OUStringBuffer aMessageBuf;
     401             : 
     402             :     // strip any other WrappedTargetException instances, but this time preserve the error messages.
     403           6 :     WrappedTargetException aWrapped;
     404           3 :     sal_Int32 nLevel = 0;
     405           6 :     while ( aExamine >>= aWrapped )
     406             :     {
     407             :         // special handling for BasicErrorException errors
     408           0 :         if ( aWrapped.TargetException >>= aBasicError )
     409             :         {
     410           0 :             nError = StarBASIC::GetSfxFromVBError( (sal_uInt16)aBasicError.ErrorCode );
     411           0 :             aMessageBuf.append( aBasicError.ErrorMessageArgument );
     412           0 :             aExamine.clear();
     413           0 :             break;
     414             :         }
     415             : 
     416             :         // append this round's message
     417           0 :         implAppendExceptionMsg( aMessageBuf, aWrapped, aExamine.getValueTypeName(), nLevel );
     418           0 :         if ( aWrapped.TargetException.getValueTypeClass() == TypeClass_EXCEPTION )
     419             :             // there is a next chain element
     420           0 :             aMessageBuf.appendAscii( "\nTargetException:" );
     421             : 
     422             :         // next round
     423           0 :         aExamine = aWrapped.TargetException;
     424           0 :         ++nLevel;
     425             :     }
     426             : 
     427           3 :     if ( aExamine.getValueTypeClass() == TypeClass_EXCEPTION )
     428             :     {
     429             :         // the last element in the chain is still an exception, but no WrappedTargetException
     430           3 :         implAppendExceptionMsg( aMessageBuf, *static_cast< const Exception* >( aExamine.getValue() ), aExamine.getValueTypeName(), nLevel );
     431             :     }
     432             : 
     433           6 :     StarBASIC::Error( nError, aMessageBuf.makeStringAndClear() );
     434           3 : }
     435             : 
     436           3 : static void implHandleAnyException( const Any& _rCaughtException )
     437             : {
     438           3 :     BasicErrorException aBasicError;
     439           6 :     WrappedTargetException aWrappedError;
     440             : 
     441           3 :     if ( _rCaughtException >>= aBasicError )
     442             :     {
     443           0 :         implHandleBasicErrorException( aBasicError );
     444             :     }
     445           3 :     else if ( _rCaughtException >>= aWrappedError )
     446             :     {
     447           3 :         implHandleWrappedTargetException( _rCaughtException );
     448             :     }
     449             :     else
     450             :     {
     451           0 :         StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( _rCaughtException ) );
     452           3 :     }
     453           3 : }
     454             : 
     455             : // NativeObjectWrapper handling
     456           0 : struct ObjectItem
     457             : {
     458             :     SbxObjectRef    m_xNativeObj;
     459             : 
     460           0 :     explicit ObjectItem( SbxObject* pNativeObj )
     461           0 :         : m_xNativeObj( pNativeObj )
     462           0 :     {}
     463             : };
     464             : 
     465             : typedef std::vector< ObjectItem > NativeObjectWrapperVector;
     466             : class GaNativeObjectWrapperVector : public rtl::Static<NativeObjectWrapperVector, GaNativeObjectWrapperVector> {};
     467             : 
     468          70 : void clearNativeObjectWrapperVector()
     469             : {
     470          70 :     GaNativeObjectWrapperVector::get().clear();
     471          70 : }
     472             : 
     473           0 : static sal_uInt32 lcl_registerNativeObjectWrapper( SbxObject* pNativeObj )
     474             : {
     475           0 :     NativeObjectWrapperVector &rNativeObjectWrapperVector = GaNativeObjectWrapperVector::get();
     476           0 :     sal_uInt32 nIndex = rNativeObjectWrapperVector.size();
     477           0 :     rNativeObjectWrapperVector.push_back( ObjectItem( pNativeObj ) );
     478           0 :     return nIndex;
     479             : }
     480             : 
     481           0 : static SbxObject* lcl_getNativeObject( sal_uInt32 nIndex )
     482             : {
     483           0 :     SbxObjectRef xRetObj;
     484           0 :     NativeObjectWrapperVector &rNativeObjectWrapperVector = GaNativeObjectWrapperVector::get();
     485           0 :     if( nIndex < rNativeObjectWrapperVector.size() )
     486             :     {
     487           0 :         ObjectItem& rItem = rNativeObjectWrapperVector[ nIndex ];
     488           0 :         xRetObj = rItem.m_xNativeObj;
     489             :     }
     490           0 :     return xRetObj;
     491             : }
     492             : 
     493             : // convert from Uno to Sbx
     494        6213 : SbxDataType unoToSbxType( TypeClass eType )
     495             : {
     496        6213 :     SbxDataType eRetType = SbxVOID;
     497             : 
     498        6213 :     switch( eType )
     499             :     {
     500             :         case TypeClass_INTERFACE:
     501             :         case TypeClass_TYPE:
     502             :         case TypeClass_STRUCT:
     503         742 :         case TypeClass_EXCEPTION:       eRetType = SbxOBJECT;   break;
     504             : 
     505           0 :         case TypeClass_ENUM:            eRetType = SbxLONG;     break;
     506             :         case TypeClass_SEQUENCE:
     507           3 :             eRetType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
     508           3 :             break;
     509             : 
     510             : 
     511        4519 :         case TypeClass_ANY:             eRetType = SbxVARIANT;  break;
     512         122 :         case TypeClass_BOOLEAN:         eRetType = SbxBOOL;     break;
     513           0 :         case TypeClass_CHAR:            eRetType = SbxCHAR;     break;
     514         310 :         case TypeClass_STRING:          eRetType = SbxSTRING;   break;
     515           0 :         case TypeClass_FLOAT:           eRetType = SbxSINGLE;   break;
     516          36 :         case TypeClass_DOUBLE:          eRetType = SbxDOUBLE;   break;
     517           0 :         case TypeClass_BYTE:            eRetType = SbxINTEGER;  break;
     518          15 :         case TypeClass_SHORT:           eRetType = SbxINTEGER;  break;
     519         233 :         case TypeClass_LONG:            eRetType = SbxLONG;     break;
     520           0 :         case TypeClass_HYPER:           eRetType = SbxSALINT64; break;
     521           0 :         case TypeClass_UNSIGNED_SHORT:  eRetType = SbxUSHORT;   break;
     522           0 :         case TypeClass_UNSIGNED_LONG:   eRetType = SbxULONG;    break;
     523           0 :         case TypeClass_UNSIGNED_HYPER:  eRetType = SbxSALUINT64;break;
     524         233 :         default: break;
     525             :     }
     526        6213 :     return eRetType;
     527             : }
     528             : 
     529        1295 : SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass )
     530             : {
     531        1295 :     SbxDataType eRetType = SbxVOID;
     532        1295 :     if( xIdlClass.is() )
     533             :     {
     534        1295 :         TypeClass eType = xIdlClass->getTypeClass();
     535        1295 :         eRetType = unoToSbxType( eType );
     536             :     }
     537        1295 :     return eRetType;
     538             : }
     539             : 
     540        3550 : static void implSequenceToMultiDimArray( SbxDimArray*& pArray, Sequence< sal_Int32 >& indices, Sequence< sal_Int32 >& sizes, const Any& aValue, sal_Int32& dimension, bool bIsZeroIndex, Type* pType = NULL )
     541             : {
     542        3550 :     Type aType = aValue.getValueType();
     543        3550 :     TypeClass eTypeClass = aType.getTypeClass();
     544             : 
     545        3550 :     sal_Int32 dimCopy = dimension;
     546             : 
     547        3550 :     if ( eTypeClass == TypeClass_SEQUENCE )
     548             :     {
     549         144 :         Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
     550         288 :         Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
     551         144 :         typelib_TypeDescription * pTD = 0;
     552         144 :         aType.getDescription( &pTD );
     553         288 :         Type aElementType( reinterpret_cast<typelib_IndirectTypeDescription *>(pTD)->pType );
     554         144 :         ::typelib_typedescription_release( pTD );
     555             : 
     556         144 :         sal_Int32 nLen = xIdlArray->getLen( aValue );
     557        3663 :         for ( sal_Int32 index = 0; index < nLen; ++index )
     558             :         {
     559        3519 :             Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)index );
     560             :             // This detects the dimension were currently processing
     561        3519 :             if ( dimCopy == dimension )
     562             :             {
     563         144 :                 ++dimCopy;
     564         144 :                 if ( sizes.getLength() < dimCopy )
     565             :                 {
     566          62 :                     sizes.realloc( sizes.getLength() + 1 );
     567          62 :                     sizes[ sizes.getLength() - 1 ] = nLen;
     568          62 :                     indices.realloc( indices.getLength() + 1 );
     569             :                 }
     570             :             }
     571             : 
     572        3519 :             if ( bIsZeroIndex )
     573           0 :                 indices[ dimCopy - 1 ] = index;
     574             :             else
     575        3519 :                 indices[ dimCopy - 1] = index + 1;
     576             : 
     577        3519 :             implSequenceToMultiDimArray( pArray, indices, sizes, aElementAny, dimCopy, bIsZeroIndex, &aElementType );
     578        3663 :         }
     579             : 
     580             :     }
     581             :     else
     582             :     {
     583        3406 :         if ( indices.getLength() < 1 )
     584             :         {
     585             :             // Should never ever get here ( indices.getLength()
     586             :             // should equal number of dimensions in the array )
     587             :             // And that should at least be 1 !
     588             :             // #QUESTION is there a better error?
     589           0 :             StarBASIC::Error( SbERR_INVALID_OBJECT );
     590        3550 :             return;
     591             :         }
     592             : 
     593        3406 :         SbxDataType eSbxElementType = unoToSbxType( pType ? pType->getTypeClass() : aValue.getValueTypeClass() );
     594        3406 :         if ( !pArray )
     595             :         {
     596          31 :             pArray = new SbxDimArray( eSbxElementType );
     597          31 :             sal_Int32 nIndexLen = indices.getLength();
     598             : 
     599             :             // Dimension the array
     600          93 :             for ( sal_Int32 index = 0; index < nIndexLen; ++index )
     601             :             {
     602          62 :                 if ( bIsZeroIndex )
     603           0 :                     pArray->unoAddDim32( 0, sizes[ index ] - 1);
     604             :                 else
     605          62 :                     pArray->unoAddDim32( 1, sizes[ index ] );
     606             : 
     607             :             }
     608             :         }
     609             : 
     610        3406 :         if ( pArray )
     611             :         {
     612        3406 :             SbxVariableRef xVar = new SbxVariable( eSbxElementType );
     613        3406 :             unoToSbxValue( static_cast<SbxVariable*>(xVar), aValue );
     614             : 
     615        3406 :             sal_Int32* pIndices = indices.getArray();
     616        3406 :             pArray->Put32(  static_cast<SbxVariable*>(xVar), pIndices );
     617             : 
     618             :         }
     619        3550 :     }
     620             : }
     621             : 
     622        8206 : void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
     623             : {
     624        8206 :     Type aType = aValue.getValueType();
     625        8206 :     TypeClass eTypeClass = aType.getTypeClass();
     626        8206 :     switch( eTypeClass )
     627             :     {
     628             :         case TypeClass_TYPE:
     629             :         {
     630             :             // Map Type to IdlClass
     631           0 :             Type aType_;
     632           0 :             aValue >>= aType_;
     633           0 :             Reference<XIdlClass> xClass = TypeToIdlClass( aType_ );
     634           0 :             Any aClassAny;
     635           0 :             aClassAny <<= xClass;
     636             : 
     637             :             // instantiate SbUnoObject
     638           0 :             OUString aName;
     639           0 :             SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aClassAny );
     640           0 :             SbxObjectRef xWrapper = static_cast<SbxObject*>(pSbUnoObject);
     641             : 
     642             :             // If the object is invalid deliver null
     643           0 :             if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
     644             :             {
     645           0 :                 pVar->PutObject( NULL );
     646             :             }
     647             :             else
     648             :             {
     649           0 :                 pVar->PutObject( xWrapper );
     650           0 :             }
     651             :         }
     652           0 :         break;
     653             :         // Interfaces and Structs must be wrapped in a SbUnoObject
     654             :         case TypeClass_INTERFACE:
     655             :         case TypeClass_STRUCT:
     656             :         case TypeClass_EXCEPTION:
     657             :         {
     658        2637 :             if( eTypeClass == TypeClass_STRUCT )
     659             :             {
     660          73 :                 ArrayWrapper aWrap;
     661         115 :                 NativeObjectWrapper aNativeObjectWrapper;
     662          73 :                 if ( (aValue >>= aWrap) )
     663             :                 {
     664          31 :                     SbxDimArray* pArray = NULL;
     665          31 :                     Sequence< sal_Int32 > indices;
     666          62 :                     Sequence< sal_Int32 > sizes;
     667          31 :                     sal_Int32 dimension = 0;
     668          31 :                     implSequenceToMultiDimArray( pArray, indices, sizes, aWrap.Array, dimension, aWrap.IsZeroIndex );
     669          31 :                     if ( pArray )
     670             :                     {
     671          31 :                         SbxDimArrayRef xArray = pArray;
     672          31 :                         SbxFlagBits nFlags = pVar->GetFlags();
     673          31 :                         pVar->ResetFlag( SBX_FIXED );
     674          31 :                         pVar->PutObject( static_cast<SbxDimArray*>(xArray) );
     675          31 :                         pVar->SetFlags( nFlags );
     676             :                     }
     677             :                     else
     678           0 :                         pVar->PutEmpty();
     679          62 :                     break;
     680             :                 }
     681          42 :                 else if ( (aValue >>= aNativeObjectWrapper) )
     682             :                 {
     683           0 :                     sal_uInt32 nIndex = 0;
     684           0 :                     if( (aNativeObjectWrapper.ObjectId >>= nIndex) )
     685             :                     {
     686           0 :                         SbxObject* pObj = lcl_getNativeObject( nIndex );
     687           0 :                         pVar->PutObject( pObj );
     688             :                     }
     689             :                     else
     690           0 :                         pVar->PutEmpty();
     691           0 :                     break;
     692             :                 }
     693             :                 else
     694             :                 {
     695          42 :                     SbiInstance* pInst = GetSbData()->pInst;
     696          42 :                     if( pInst && pInst->IsCompatibility() )
     697             :                     {
     698          10 :                         oleautomation::Date aDate;
     699          10 :                         if( (aValue >>= aDate) )
     700             :                         {
     701           0 :                             pVar->PutDate( aDate.Value );
     702           0 :                             break;
     703             :                         }
     704             :                         else
     705             :                         {
     706          10 :                             oleautomation::Decimal aDecimal;
     707          10 :                             if( (aValue >>= aDecimal) )
     708             :                             {
     709           0 :                                 pVar->PutDecimal( aDecimal );
     710           0 :                                 break;
     711             :                             }
     712             :                             else
     713             :                             {
     714          10 :                                 oleautomation::Currency aCurrency;
     715          10 :                                 if( (aValue >>= aCurrency) )
     716             :                                 {
     717           0 :                                     pVar->PutCurrency( aCurrency.Value );
     718           0 :                                     break;
     719             :                                 }
     720             :                             }
     721             :                         }
     722             :                     }
     723          42 :                 }
     724             :             }
     725             :             // instantiate a SbUnoObject
     726        2606 :             OUString aName;
     727        2606 :             SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aValue );
     728             :             //If this is called externally e.g. from the scripting
     729             :             //framework then there is no 'active' runtime the default property will not be set up
     730             :             //only a vba object will have XDefaultProp set anyway so... this
     731             :             //test seems a bit of overkill
     732             :             //if ( SbiRuntime::isVBAEnabled() )
     733             :             {
     734        2606 :                 OUString sDfltPropName;
     735             : 
     736        2606 :                 if ( SbUnoObject::getDefaultPropName( pSbUnoObject, sDfltPropName ) )
     737             :                 {
     738        1548 :                     pSbUnoObject->SetDfltProperty( sDfltPropName );
     739        2606 :                 }
     740             :             }
     741        5212 :             SbxObjectRef xWrapper = static_cast<SbxObject*>(pSbUnoObject);
     742             : 
     743             :             // If the object is invalid deliver null
     744        2606 :             if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
     745             :             {
     746          12 :                 pVar->PutObject( NULL );
     747             :             }
     748             :             else
     749             :             {
     750        2594 :                 pVar->PutObject( xWrapper );
     751        2606 :             }
     752             :         }
     753        2606 :         break;
     754             : 
     755             : 
     756             :         case TypeClass_ENUM:
     757             :         {
     758           0 :             sal_Int32 nEnum = 0;
     759           0 :             enum2int( nEnum, aValue );
     760           0 :             pVar->PutLong( nEnum );
     761             :         }
     762           0 :             break;
     763             : 
     764             :         case TypeClass_SEQUENCE:
     765             :         {
     766           8 :             Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
     767          16 :             Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
     768           8 :             sal_Int32 i, nLen = xIdlArray->getLen( aValue );
     769             : 
     770           8 :             typelib_TypeDescription * pTD = 0;
     771           8 :             aType.getDescription( &pTD );
     772             :             OSL_ASSERT( pTD && pTD->eTypeClass == typelib_TypeClass_SEQUENCE );
     773          16 :             Type aElementType( reinterpret_cast<typelib_IndirectTypeDescription *>(pTD)->pType );
     774           8 :             ::typelib_typedescription_release( pTD );
     775             : 
     776             :             // build an Array in Basic
     777          16 :             SbxDimArrayRef xArray;
     778           8 :             SbxDataType eSbxElementType = unoToSbxType( aElementType.getTypeClass() );
     779           8 :             xArray = new SbxDimArray( eSbxElementType );
     780           8 :             if( nLen > 0 )
     781             :             {
     782           7 :                 xArray->unoAddDim32( 0, nLen - 1 );
     783             : 
     784             :                 // register the elements as variables
     785          29 :                 for( i = 0 ; i < nLen ; i++ )
     786             :                 {
     787             :                     // convert elements
     788          22 :                     Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)i );
     789          44 :                     SbxVariableRef xVar = new SbxVariable( eSbxElementType );
     790          22 :                     unoToSbxValue( static_cast<SbxVariable*>(xVar), aElementAny );
     791             : 
     792             :                     // put into the Array
     793          22 :                     xArray->Put32( static_cast<SbxVariable*>(xVar), &i );
     794          22 :                 }
     795             :             }
     796             :             else
     797             :             {
     798           1 :                 xArray->unoAddDim( 0, -1 );
     799             :             }
     800             : 
     801             :             // return the Array
     802           8 :             SbxFlagBits nFlags = pVar->GetFlags();
     803           8 :             pVar->ResetFlag( SBX_FIXED );
     804           8 :             pVar->PutObject( static_cast<SbxDimArray*>(xArray) );
     805          16 :             pVar->SetFlags( nFlags );
     806             : 
     807             :         }
     808           8 :         break;
     809             : 
     810             : 
     811         282 :         case TypeClass_BOOLEAN:         pVar->PutBool( *static_cast<sal_Bool const *>(aValue.getValue()) ); break;
     812             :         case TypeClass_CHAR:
     813             :         {
     814           0 :             pVar->PutChar( *static_cast<sal_Unicode const *>(aValue.getValue()) );
     815           0 :             break;
     816             :         }
     817         551 :         case TypeClass_STRING:          { OUString val; aValue >>= val; pVar->PutString( val ); }  break;
     818           2 :         case TypeClass_FLOAT:           { float val = 0; aValue >>= val; pVar->PutSingle( val ); } break;
     819        2629 :         case TypeClass_DOUBLE:          { double val = 0; aValue >>= val; pVar->PutDouble( val ); } break;
     820           0 :         case TypeClass_BYTE:            { sal_Int8 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
     821          40 :         case TypeClass_SHORT:           { sal_Int16 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
     822         527 :         case TypeClass_LONG:            { sal_Int32 val = 0; aValue >>= val; pVar->PutLong( val ); } break;
     823           0 :         case TypeClass_HYPER:           { sal_Int64 val = 0; aValue >>= val; pVar->PutInt64( val ); } break;
     824           0 :         case TypeClass_UNSIGNED_SHORT:  { sal_uInt16 val = 0; aValue >>= val; pVar->PutUShort( val ); } break;
     825           0 :         case TypeClass_UNSIGNED_LONG:   { sal_uInt32 val = 0; aValue >>= val; pVar->PutULong( val ); } break;
     826           0 :         case TypeClass_UNSIGNED_HYPER:  { sal_uInt64 val = 0; aValue >>= val; pVar->PutUInt64( val ); } break;
     827        1530 :         default:                        pVar->PutEmpty();                       break;
     828        8206 :     }
     829        8206 : }
     830             : 
     831             : // Deliver the reflection for Sbx types
     832        2621 : Type getUnoTypeForSbxBaseType( SbxDataType eType )
     833             : {
     834        2621 :     Type aRetType = cppu::UnoType<void>::get();
     835        2621 :     switch( eType )
     836             :     {
     837           0 :         case SbxNULL:       aRetType = cppu::UnoType<XInterface>::get(); break;
     838         619 :         case SbxINTEGER:    aRetType = cppu::UnoType<sal_Int16>::get(); break;
     839         201 :         case SbxLONG:       aRetType = cppu::UnoType<sal_Int32>::get(); break;
     840           0 :         case SbxSINGLE:     aRetType = cppu::UnoType<float>::get(); break;
     841          91 :         case SbxDOUBLE:     aRetType = cppu::UnoType<double>::get(); break;
     842           0 :         case SbxCURRENCY:   aRetType = cppu::UnoType<oleautomation::Currency>::get(); break;
     843           0 :         case SbxDECIMAL:    aRetType = cppu::UnoType<oleautomation::Decimal>::get(); break;
     844             :         case SbxDATE:       {
     845           0 :                             SbiInstance* pInst = GetSbData()->pInst;
     846           0 :                             if( pInst && pInst->IsCompatibility() )
     847           0 :                                 aRetType = cppu::UnoType<double>::get();
     848             :                             else
     849           0 :                                 aRetType = cppu::UnoType<oleautomation::Date>::get();
     850             :                             }
     851           0 :                             break;
     852        1477 :         case SbxSTRING:     aRetType = cppu::UnoType<OUString>::get(); break;
     853          73 :         case SbxBOOL:       aRetType = cppu::UnoType<sal_Bool>::get(); break;
     854          10 :         case SbxVARIANT:    aRetType = cppu::UnoType<Any>::get(); break;
     855           0 :         case SbxCHAR:       aRetType = cppu::UnoType<cppu::UnoCharType>::get(); break;
     856           0 :         case SbxBYTE:       aRetType = cppu::UnoType<sal_Int8>::get(); break;
     857           0 :         case SbxUSHORT:     aRetType = cppu::UnoType<cppu::UnoUnsignedShortType>::get(); break;
     858           0 :         case SbxULONG:      aRetType = ::cppu::UnoType<sal_uInt32>::get(); break;
     859             :         // map machine-dependent ones to long for consistency
     860           0 :         case SbxINT:        aRetType = ::cppu::UnoType<sal_Int32>::get(); break;
     861           0 :         case SbxUINT:       aRetType = ::cppu::UnoType<sal_uInt32>::get(); break;
     862         150 :         default: break;
     863             :     }
     864        2621 :     return aRetType;
     865             : }
     866             : 
     867             : // Converting of Sbx to Uno without a know target class for TypeClass_ANY
     868       26493 : Type getUnoTypeForSbxValue( const SbxValue* pVal )
     869             : {
     870       26493 :     Type aRetType = cppu::UnoType<void>::get();
     871       26493 :     if( !pVal )
     872           0 :         return aRetType;
     873             : 
     874             :     // convert SbxType to Uno
     875       26493 :     SbxDataType eBaseType = pVal->SbxValue::GetType();
     876       26493 :     if( eBaseType == SbxOBJECT )
     877             :     {
     878       23882 :         SbxBaseRef xObj = pVal->GetObject();
     879       23882 :         if( !xObj )
     880             :         {
     881           0 :             aRetType = cppu::UnoType<XInterface>::get();
     882           0 :             return aRetType;
     883             :         }
     884             : 
     885       23882 :         if( xObj->ISA(SbxDimArray) )
     886             :         {
     887          10 :             SbxBase* pObj = static_cast<SbxBase*>(xObj);
     888          10 :             SbxDimArray* pArray = static_cast<SbxDimArray*>(pObj);
     889             : 
     890          10 :             short nDims = pArray->GetDims();
     891          10 :             Type aElementType = getUnoTypeForSbxBaseType( (SbxDataType)(pArray->GetType() & 0xfff) );
     892          10 :             TypeClass eElementTypeClass = aElementType.getTypeClass();
     893             : 
     894             :             // Normal case: One dimensional array
     895             :             sal_Int32 nLower, nUpper;
     896          10 :             if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
     897             :             {
     898           8 :                 if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
     899             :                 {
     900             :                     // If all elements of the arrays are from the same type, take
     901             :                     // this one - otherwise the whole will be considered as Any-Sequence
     902           8 :                     bool bNeedsInit = true;
     903             : 
     904           8 :                     sal_Int32 nSize = nUpper - nLower + 1;
     905           8 :                     sal_Int32 nIdx = nLower;
     906          30 :                     for( sal_Int32 i = 0 ; i < nSize ; i++,nIdx++ )
     907             :                     {
     908             :                         // coverity[callee_ptr_arith]
     909          25 :                         SbxVariableRef xVar = pArray->Get32( &nIdx );
     910          47 :                         Type aType = getUnoTypeForSbxValue( static_cast<SbxVariable*>(xVar) );
     911          25 :                         if( bNeedsInit )
     912             :                         {
     913           8 :                             if( aType.getTypeClass() == TypeClass_VOID )
     914             :                             {
     915             :                                 // if only first element is void: different types  -> []any
     916             :                                 // if all elements are void: []void is not allowed -> []any
     917           0 :                                 aElementType = cppu::UnoType<Any>::get();
     918           0 :                                 break;
     919             :                             }
     920           8 :                             aElementType = aType;
     921           8 :                             bNeedsInit = false;
     922             :                         }
     923          17 :                         else if( aElementType != aType )
     924             :                         {
     925             :                             // different types -> AnySequence
     926           3 :                             aElementType = cppu::UnoType<Any>::get();
     927           3 :                             break;
     928             :                         }
     929          22 :                     }
     930             :                 }
     931             : 
     932           8 :                 OUString aSeqTypeName = aSeqLevelStr + aElementType.getTypeName();
     933           8 :                 aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
     934             :             }
     935             :             // #i33795 Map also multi dimensional arrays to corresponding sequences
     936           2 :             else if( nDims > 1 )
     937             :             {
     938           2 :                 if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
     939             :                 {
     940             :                     // For this check the array's dim structure does not matter
     941           2 :                     sal_uInt32 nFlatArraySize = pArray->Count32();
     942             : 
     943           2 :                     bool bNeedsInit = true;
     944          26 :                     for( sal_uInt32 i = 0 ; i < nFlatArraySize ; i++ )
     945             :                     {
     946          24 :                         SbxVariableRef xVar = pArray->SbxArray::Get32( i );
     947          48 :                         Type aType = getUnoTypeForSbxValue( static_cast<SbxVariable*>(xVar) );
     948          24 :                         if( bNeedsInit )
     949             :                         {
     950           2 :                             if( aType.getTypeClass() == TypeClass_VOID )
     951             :                             {
     952             :                                 // if only first element is void: different types  -> []any
     953             :                                 // if all elements are void: []void is not allowed -> []any
     954           0 :                                 aElementType = cppu::UnoType<Any>::get();
     955           0 :                                 break;
     956             :                             }
     957           2 :                             aElementType = aType;
     958           2 :                             bNeedsInit = false;
     959             :                         }
     960          22 :                         else if( aElementType != aType )
     961             :                         {
     962             :                             // different types -> AnySequence
     963           0 :                             aElementType = cppu::UnoType<Any>::get();
     964           0 :                             break;
     965             :                         }
     966          24 :                     }
     967             :                 }
     968             : 
     969           2 :                 OUStringBuffer aSeqTypeName;
     970           6 :                 for( short iDim = 0 ; iDim < nDims ; iDim++ )
     971             :                 {
     972           4 :                     aSeqTypeName.appendAscii(aSeqLevelStr);
     973             :                 }
     974           2 :                 aSeqTypeName.append(aElementType.getTypeName());
     975           2 :                 aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName.makeStringAndClear() );
     976          10 :             }
     977             :         }
     978             :         // No array, but ...
     979       23872 :         else if( xObj->ISA(SbUnoObject) )
     980             :         {
     981       23872 :             aRetType = static_cast<SbUnoObject*>(static_cast<SbxBase*>(xObj))->getUnoAny().getValueType();
     982             :         }
     983             :         // SbUnoAnyObject?
     984           0 :         else if( xObj->ISA(SbUnoAnyObject) )
     985             :         {
     986           0 :             aRetType = static_cast<SbUnoAnyObject*>(static_cast<SbxBase*>(xObj))->getValue().getValueType();
     987       23882 :         }
     988             :         // Otherwise it is a No-Uno-Basic-Object -> default==deliver void
     989             :     }
     990             :     // No object, convert basic type
     991             :     else
     992             :     {
     993        2611 :         aRetType = getUnoTypeForSbxBaseType( eBaseType );
     994             :     }
     995       26493 :     return aRetType;
     996             : }
     997             : 
     998             : // converting of Sbx to Uno without known target class for TypeClass_ANY
     999       26444 : Any sbxToUnoValueImpl( const SbxValue* pVar, bool bBlockConversionToSmallestType = false )
    1000             : {
    1001       26444 :     SbxDataType eBaseType = pVar->SbxValue::GetType();
    1002       26444 :     if( eBaseType == SbxOBJECT )
    1003             :     {
    1004       23878 :         SbxBaseRef xObj = pVar->GetObject();
    1005       23878 :         if( xObj.Is() )
    1006             :         {
    1007       23878 :             if( xObj->ISA(SbUnoAnyObject) )
    1008           0 :                 return static_cast<SbUnoAnyObject*>(static_cast<SbxBase*>(xObj))->getValue();
    1009       23878 :             if( xObj->ISA(SbClassModuleObject) )
    1010             :             {
    1011           0 :                 Any aRetAny;
    1012           0 :                 SbClassModuleObject* pClassModuleObj = static_cast<SbClassModuleObject*>(static_cast<SbxBase*>(xObj));
    1013           0 :                 SbModule* pClassModule = pClassModuleObj->getClassModule();
    1014           0 :                 if( pClassModule->createCOMWrapperForIface( aRetAny, pClassModuleObj ) )
    1015           0 :                     return aRetAny;
    1016             :             }
    1017       23878 :             if( !xObj->ISA(SbUnoObject) )
    1018             :             {
    1019             :                 // Create NativeObjectWrapper to identify object in case of callbacks
    1020          10 :                 SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
    1021          10 :                 if( pObj != NULL )
    1022             :                 {
    1023           0 :                     NativeObjectWrapper aNativeObjectWrapper;
    1024           0 :                     sal_uInt32 nIndex = lcl_registerNativeObjectWrapper( pObj );
    1025           0 :                     aNativeObjectWrapper.ObjectId <<= nIndex;
    1026           0 :                     Any aRetAny;
    1027           0 :                     aRetAny <<= aNativeObjectWrapper;
    1028           0 :                     return aRetAny;
    1029             :                 }
    1030             :             }
    1031       23878 :         }
    1032             :     }
    1033             : 
    1034       26444 :     Type aType = getUnoTypeForSbxValue( pVar );
    1035       26444 :     TypeClass eType = aType.getTypeClass();
    1036             : 
    1037       26444 :     if( !bBlockConversionToSmallestType )
    1038             :     {
    1039             :         // #79615 Choose "smallest" represention for int values
    1040             :         // because up cast is allowed, downcast not
    1041       26444 :         switch( eType )
    1042             :         {
    1043             :             case TypeClass_FLOAT:
    1044             :             case TypeClass_DOUBLE:
    1045             :             {
    1046          79 :                 double d = pVar->GetDouble();
    1047          79 :                 if( d == floor( d ) )
    1048             :                 {
    1049          77 :                     if( d >= -128 && d <= 127 )
    1050          76 :                         aType = ::cppu::UnoType<sal_Int8>::get();
    1051           1 :                     else if( d >= SbxMININT && d <= SbxMAXINT )
    1052           0 :                         aType = ::cppu::UnoType<sal_Int16>::get();
    1053           1 :                     else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
    1054           1 :                         aType = ::cppu::UnoType<sal_Int32>::get();
    1055             :                 }
    1056          79 :                 break;
    1057             :             }
    1058             :             case TypeClass_SHORT:
    1059             :             {
    1060         587 :                 sal_Int16 n = pVar->GetInteger();
    1061         587 :                 if( n >= -128 && n <= 127 )
    1062         585 :                     aType = ::cppu::UnoType<sal_Int8>::get();
    1063         587 :                 break;
    1064             :             }
    1065             :             case TypeClass_LONG:
    1066             :             {
    1067         201 :                 sal_Int32 n = pVar->GetLong();
    1068         201 :                 if( n >= -128 && n <= 127 )
    1069         132 :                     aType = ::cppu::UnoType<sal_Int8>::get();
    1070          69 :                 else if( n >= SbxMININT && n <= SbxMAXINT )
    1071          58 :                     aType = ::cppu::UnoType<sal_Int16>::get();
    1072         201 :                 break;
    1073             :             }
    1074             :             case TypeClass_UNSIGNED_SHORT:
    1075             :             {
    1076           0 :                 sal_uInt16 n = pVar->GetUShort();
    1077           0 :                 if( n <= 255 )
    1078           0 :                     aType = cppu::UnoType<sal_uInt8>::get();
    1079           0 :                 break;
    1080             :             }
    1081             :             case TypeClass_UNSIGNED_LONG:
    1082             :             {
    1083           0 :                 sal_uInt32 n = pVar->GetLong();
    1084           0 :                 if( n <= 255 )
    1085           0 :                     aType = cppu::UnoType<sal_uInt8>::get();
    1086           0 :                 else if( n <= SbxMAXUINT )
    1087           0 :                     aType = cppu::UnoType<cppu::UnoUnsignedShortType>::get();
    1088           0 :                 break;
    1089             :             }
    1090             :             // TODO: need to add hyper types ?
    1091       25577 :             default: break;
    1092             :         }
    1093             :     }
    1094             : 
    1095       26444 :     return sbxToUnoValue( pVar, aType );
    1096             : }
    1097             : 
    1098             : 
    1099             : 
    1100             : // Helper function for StepREDIMP
    1101           8 : static Any implRekMultiDimArrayToSequence( SbxDimArray* pArray,
    1102             :     const Type& aElemType, short nMaxDimIndex, short nActualDim,
    1103             :     sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
    1104             : {
    1105           8 :     sal_Int32 nSeqLevel = nMaxDimIndex - nActualDim + 1;
    1106           8 :     OUStringBuffer aSeqTypeName;
    1107             :     sal_Int32 i;
    1108          18 :     for( i = 0 ; i < nSeqLevel ; i++ )
    1109             :     {
    1110          10 :         aSeqTypeName.appendAscii(aSeqLevelStr);
    1111             :     }
    1112           8 :     aSeqTypeName.append(aElemType.getTypeName());
    1113          16 :     Type aSeqType( TypeClass_SEQUENCE, aSeqTypeName.makeStringAndClear() );
    1114             : 
    1115             :     // Create Sequence instance
    1116           8 :     Any aRetVal;
    1117          16 :     Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aSeqType );
    1118           8 :     xIdlTargetClass->createObject( aRetVal );
    1119             : 
    1120             :     // Alloc sequence according to array bounds
    1121           8 :     sal_Int32 nUpper = pUpperBounds[nActualDim];
    1122           8 :     sal_Int32 nLower = pLowerBounds[nActualDim];
    1123           8 :     sal_Int32 nSeqSize = nUpper - nLower + 1;
    1124          16 :     Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
    1125           8 :     xArray->realloc( aRetVal, nSeqSize );
    1126             : 
    1127           8 :     sal_Int32& ri = pActualIndices[nActualDim];
    1128             : 
    1129          38 :     for( ri = nLower,i = 0 ; ri <= nUpper ; ri++,i++ )
    1130             :     {
    1131          30 :         Any aElementVal;
    1132             : 
    1133          30 :         if( nActualDim < nMaxDimIndex )
    1134             :         {
    1135          12 :             aElementVal = implRekMultiDimArrayToSequence( pArray, aElemType,
    1136           6 :                 nMaxDimIndex, nActualDim + 1, pActualIndices, pLowerBounds, pUpperBounds );
    1137             :         }
    1138             :         else
    1139             :         {
    1140          24 :             SbxVariable* pSource = pArray->Get32( pActualIndices );
    1141          24 :             aElementVal = sbxToUnoValue( pSource, aElemType );
    1142             :         }
    1143             : 
    1144             :         try
    1145             :         {
    1146             :             // transfer to the sequence
    1147          30 :             xArray->set( aRetVal, i, aElementVal );
    1148             :         }
    1149           0 :         catch( const IllegalArgumentException& )
    1150             :         {
    1151             :             StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
    1152           0 :                 implGetExceptionMsg( ::cppu::getCaughtException() ) );
    1153             :         }
    1154           0 :         catch (const IndexOutOfBoundsException&)
    1155             :         {
    1156           0 :             StarBASIC::Error( SbERR_OUT_OF_RANGE );
    1157             :         }
    1158          30 :     }
    1159          16 :     return aRetVal;
    1160             : }
    1161             : 
    1162             : // Map old interface
    1163       23915 : Any sbxToUnoValue( const SbxValue* pVar )
    1164             : {
    1165       23915 :     return sbxToUnoValueImpl( pVar );
    1166             : }
    1167             : 
    1168             : // function to find a global identifier in
    1169             : // the UnoScope and to wrap it for Sbx
    1170           0 : static bool implGetTypeByName( const OUString& rName, Type& rRetType )
    1171             : {
    1172           0 :     bool bSuccess = false;
    1173             : 
    1174           0 :     Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    1175           0 :     if( xTypeAccess->hasByHierarchicalName( rName ) )
    1176             :     {
    1177           0 :         Any aRet = xTypeAccess->getByHierarchicalName( rName );
    1178           0 :         Reference< XTypeDescription > xTypeDesc;
    1179           0 :         aRet >>= xTypeDesc;
    1180             : 
    1181           0 :         if( xTypeDesc.is() )
    1182             :         {
    1183           0 :             rRetType = Type( xTypeDesc->getTypeClass(), xTypeDesc->getName() );
    1184           0 :             bSuccess = true;
    1185           0 :         }
    1186             :     }
    1187           0 :     return bSuccess;
    1188             : }
    1189             : 
    1190             : 
    1191             : // converting of Sbx to Uno with known target class
    1192       29553 : Any sbxToUnoValue( const SbxValue* pVar, const Type& rType, Property* pUnoProperty )
    1193             : {
    1194       29553 :     Any aRetVal;
    1195             : 
    1196             :     // #94560 No conversion of empty/void for MAYBE_VOID properties
    1197       29553 :     if( pUnoProperty && pUnoProperty->Attributes & PropertyAttribute::MAYBEVOID )
    1198             :     {
    1199           1 :         if( pVar->IsEmpty() )
    1200           0 :             return aRetVal;
    1201             :     }
    1202             : 
    1203       29553 :     SbxDataType eBaseType = pVar->SbxValue::GetType();
    1204       29553 :     if( eBaseType == SbxOBJECT )
    1205             :     {
    1206       24036 :         SbxBaseRef xObj = pVar->GetObject();
    1207       24036 :         if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
    1208             :         {
    1209           0 :             return static_cast<SbUnoAnyObject*>(static_cast<SbxBase*>(xObj))->getValue();
    1210       24036 :         }
    1211             :     }
    1212             : 
    1213       29553 :     TypeClass eType = rType.getTypeClass();
    1214       29553 :     switch( eType )
    1215             :     {
    1216             :         case TypeClass_INTERFACE:
    1217             :         case TypeClass_STRUCT:
    1218             :         case TypeClass_EXCEPTION:
    1219             :         {
    1220       12945 :             Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
    1221             : 
    1222             :             // null reference?
    1223       12945 :             if( pVar->IsNull() && eType == TypeClass_INTERFACE )
    1224             :             {
    1225           0 :                 Reference< XInterface > xRef;
    1226           0 :                 OUString aClassName = xIdlTargetClass->getName();
    1227           0 :                 Type aClassType( xIdlTargetClass->getTypeClass(), aClassName.getStr() );
    1228           0 :                 aRetVal.setValue( &xRef, aClassType );
    1229             :             }
    1230             :             else
    1231             :             {
    1232             :                 // #112368 Special conversion for Decimal, Currency and Date
    1233       12945 :                 if( eType == TypeClass_STRUCT )
    1234             :                 {
    1235          41 :                     SbiInstance* pInst = GetSbData()->pInst;
    1236          41 :                     if( pInst && pInst->IsCompatibility() )
    1237             :                     {
    1238           2 :                         if( rType == cppu::UnoType<oleautomation::Decimal>::get())
    1239             :                         {
    1240           0 :                             oleautomation::Decimal aDecimal;
    1241           0 :                             pVar->fillAutomationDecimal( aDecimal );
    1242           0 :                             aRetVal <<= aDecimal;
    1243           0 :                             break;
    1244             :                         }
    1245           2 :                         else if( rType == cppu::UnoType<oleautomation::Currency>::get())
    1246             :                         {
    1247             :                             // assumes per previous code that ole Currency is Int64
    1248           0 :                             aRetVal <<= (sal_Int64)( pVar->GetInt64() );
    1249           0 :                             break;
    1250             :                         }
    1251           2 :                         else if( rType == cppu::UnoType<oleautomation::Date>::get())
    1252             :                         {
    1253           0 :                             oleautomation::Date aDate;
    1254           0 :                             aDate.Value = pVar->GetDate();
    1255           0 :                             aRetVal <<= aDate;
    1256           0 :                             break;
    1257             :                         }
    1258             :                     }
    1259             :                 }
    1260             : 
    1261       12945 :                 SbxBaseRef pObj = pVar->GetObject();
    1262       12945 :                 if( pObj && pObj->ISA(SbUnoObject) )
    1263             :                 {
    1264       12943 :                     aRetVal = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj))->getUnoAny();
    1265             :                 }
    1266           2 :                 else if( pObj && pObj->ISA(SbUnoStructRefObject) )
    1267             :                 {
    1268           0 :                     aRetVal = static_cast<SbUnoStructRefObject*>(static_cast<SbxBase*>(pObj))->getUnoAny();
    1269             :                 }
    1270             :                 else
    1271             :                 {
    1272             :                     // null object -> null XInterface
    1273           2 :                     Reference<XInterface> xInt;
    1274           2 :                     aRetVal <<= xInt;
    1275       12945 :                 }
    1276       12945 :             }
    1277             :         }
    1278       12945 :         break;
    1279             : 
    1280             :         case TypeClass_TYPE:
    1281             :         {
    1282           1 :             if( eBaseType == SbxOBJECT )
    1283             :             {
    1284             :                 // XIdlClass?
    1285           1 :                 Reference< XIdlClass > xIdlClass;
    1286             : 
    1287           2 :                 SbxBaseRef pObj = pVar->GetObject();
    1288           1 :                 if( pObj && pObj->ISA(SbUnoObject) )
    1289             :                 {
    1290           0 :                     Any aUnoAny = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj))->getUnoAny();
    1291           0 :                     aUnoAny >>= xIdlClass;
    1292             :                 }
    1293             : 
    1294           1 :                 if( xIdlClass.is() )
    1295             :                 {
    1296           0 :                     OUString aClassName = xIdlClass->getName();
    1297           0 :                     Type aType( xIdlClass->getTypeClass(), aClassName.getStr() );
    1298           0 :                     aRetVal <<= aType;
    1299           1 :                 }
    1300             :             }
    1301           0 :             else if( eBaseType == SbxSTRING )
    1302             :             {
    1303           0 :                 OUString aTypeName = pVar->GetOUString();
    1304           0 :                 Type aType;
    1305           0 :                 bool bSuccess = implGetTypeByName( aTypeName, aType );
    1306           0 :                 if( bSuccess )
    1307             :                 {
    1308           0 :                     aRetVal <<= aType;
    1309           0 :                 }
    1310             :             }
    1311             :         }
    1312           1 :         break;
    1313             : 
    1314             : 
    1315             :         case TypeClass_ENUM:
    1316             :         {
    1317           0 :             aRetVal = int2enum( pVar->GetLong(), rType );
    1318             :         }
    1319           0 :         break;
    1320             : 
    1321             :         case TypeClass_SEQUENCE:
    1322             :         {
    1323          39 :             SbxBaseRef xObj = pVar->GetObject();
    1324          39 :             if( xObj && xObj->ISA(SbxDimArray) )
    1325             :             {
    1326          39 :                 SbxBase* pObj = static_cast<SbxBase*>(xObj);
    1327          39 :                 SbxDimArray* pArray = static_cast<SbxDimArray*>(pObj);
    1328             : 
    1329          39 :                 short nDims = pArray->GetDims();
    1330             : 
    1331             :                 // Normal case: One dimensional array
    1332             :                 sal_Int32 nLower, nUpper;
    1333          39 :                 if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
    1334             :                 {
    1335          37 :                     sal_Int32 nSeqSize = nUpper - nLower + 1;
    1336             : 
    1337             :                     // create the instance of the required sequence
    1338          37 :                     Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
    1339          37 :                     xIdlTargetClass->createObject( aRetVal );
    1340          74 :                     Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
    1341          37 :                     xArray->realloc( aRetVal, nSeqSize );
    1342             : 
    1343             :                     // Element-Type
    1344          74 :                     OUString aClassName = xIdlTargetClass->getName();
    1345          37 :                     typelib_TypeDescription * pSeqTD = 0;
    1346          37 :                     typelib_typedescription_getByName( &pSeqTD, aClassName.pData );
    1347             :                     OSL_ASSERT( pSeqTD );
    1348          74 :                     Type aElemType( reinterpret_cast<typelib_IndirectTypeDescription *>(pSeqTD)->pType );
    1349             : 
    1350             :                     // convert all array member and register them
    1351          37 :                     sal_Int32 nIdx = nLower;
    1352          88 :                     for( sal_Int32 i = 0 ; i < nSeqSize ; i++,nIdx++ )
    1353             :                     {
    1354             :                         // coverity[callee_ptr_arith]
    1355          51 :                         SbxVariableRef xVar = pArray->Get32( &nIdx );
    1356             : 
    1357             :                         // Convert the value of Sbx to Uno
    1358         102 :                         Any aAnyValue = sbxToUnoValue( static_cast<SbxVariable*>(xVar), aElemType );
    1359             : 
    1360             :                         try
    1361             :                         {
    1362             :                             // insert in the sequence
    1363          51 :                             xArray->set( aRetVal, i, aAnyValue );
    1364             :                         }
    1365           0 :                         catch( const IllegalArgumentException& )
    1366             :                         {
    1367             :                             StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
    1368           0 :                                 implGetExceptionMsg( ::cppu::getCaughtException() ) );
    1369             :                         }
    1370           0 :                         catch (const IndexOutOfBoundsException&)
    1371             :                         {
    1372           0 :                             StarBASIC::Error( SbERR_OUT_OF_RANGE );
    1373             :                         }
    1374          88 :                     }
    1375             :                 }
    1376             :                 // #i33795 Map also multi dimensional arrays to corresponding sequences
    1377           2 :                 else if( nDims > 1 )
    1378             :                 {
    1379             :                     // Element-Type
    1380           2 :                     typelib_TypeDescription * pSeqTD = 0;
    1381           2 :                     Type aCurType( rType );
    1382           2 :                     sal_Int32 nSeqLevel = 0;
    1383           4 :                     Type aElemType;
    1384             :                     do
    1385             :                     {
    1386           6 :                         OUString aTypeName = aCurType.getTypeName();
    1387           6 :                         typelib_typedescription_getByName( &pSeqTD, aTypeName.pData );
    1388             :                         OSL_ASSERT( pSeqTD );
    1389           6 :                         if( pSeqTD->eTypeClass == typelib_TypeClass_SEQUENCE )
    1390             :                         {
    1391           4 :                             aCurType = Type( reinterpret_cast<typelib_IndirectTypeDescription *>(pSeqTD)->pType );
    1392           4 :                             nSeqLevel++;
    1393             :                         }
    1394             :                         else
    1395             :                         {
    1396           2 :                             aElemType = aCurType;
    1397           2 :                             break;
    1398           4 :                         }
    1399             :                     }
    1400             :                     while( true );
    1401             : 
    1402           2 :                     if( nSeqLevel == nDims )
    1403             :                     {
    1404           2 :                         boost::scoped_array<sal_Int32> pLowerBounds(new sal_Int32[nDims]);
    1405           4 :                         boost::scoped_array<sal_Int32> pUpperBounds(new sal_Int32[nDims]);
    1406           4 :                         boost::scoped_array<sal_Int32> pActualIndices(new sal_Int32[nDims]);
    1407           6 :                         for( short i = 1 ; i <= nDims ; i++ )
    1408             :                         {
    1409             :                             sal_Int32 lBound, uBound;
    1410           4 :                             pArray->GetDim32( i, lBound, uBound );
    1411             : 
    1412           4 :                             short j = i - 1;
    1413           4 :                             pActualIndices[j] = pLowerBounds[j] = lBound;
    1414           4 :                             pUpperBounds[j] = uBound;
    1415             :                         }
    1416             : 
    1417           4 :                         aRetVal = implRekMultiDimArrayToSequence( pArray, aElemType,
    1418           4 :                             nDims - 1, 0, pActualIndices.get(), pLowerBounds.get(), pUpperBounds.get() );
    1419           2 :                     }
    1420             :                 }
    1421          39 :             }
    1422             :         }
    1423          39 :         break;
    1424             : 
    1425             : 
    1426             :         // for Any use the class independent converting routine
    1427             :         case TypeClass_ANY:
    1428             :         {
    1429        2517 :             aRetVal = sbxToUnoValueImpl( pVar );
    1430             :         }
    1431        2517 :         break;
    1432             : 
    1433             :         case TypeClass_BOOLEAN:
    1434             :         {
    1435         174 :             sal_Bool b = pVar->GetBool();
    1436         174 :             aRetVal.setValue( &b, cppu::UnoType<bool>::get() );
    1437         174 :             break;
    1438             :         }
    1439             :         case TypeClass_CHAR:
    1440             :         {
    1441           0 :             sal_Unicode c = pVar->GetChar();
    1442           0 :             aRetVal.setValue( &c , cppu::UnoType<cppu::UnoCharType>::get() );
    1443           0 :             break;
    1444             :         }
    1445        1616 :         case TypeClass_STRING:          aRetVal <<= pVar->GetOUString(); break;
    1446           0 :         case TypeClass_FLOAT:           aRetVal <<= pVar->GetSingle(); break;
    1447          48 :         case TypeClass_DOUBLE:          aRetVal <<= pVar->GetDouble(); break;
    1448             : 
    1449             :         case TypeClass_BYTE:
    1450             :         {
    1451         793 :             sal_Int16 nVal = pVar->GetInteger();
    1452         793 :             bool bOverflow = false;
    1453         793 :             if( nVal < -128 )
    1454             :             {
    1455           0 :                 bOverflow = true;
    1456           0 :                 nVal = -128;
    1457             :             }
    1458         793 :             else if( nVal > 127 )
    1459             :             {
    1460           0 :                 bOverflow = true;
    1461           0 :                 nVal = 127;
    1462             :             }
    1463         793 :             if( bOverflow )
    1464           0 :                    StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW );
    1465             : 
    1466         793 :             sal_Int8 nByteVal = (sal_Int8)nVal;
    1467         793 :             aRetVal <<= nByteVal;
    1468         793 :             break;
    1469             :         }
    1470         105 :         case TypeClass_SHORT:           aRetVal <<= (sal_Int16)( pVar->GetInteger() );  break;
    1471         159 :         case TypeClass_LONG:            aRetVal <<= (sal_Int32)( pVar->GetLong() );     break;
    1472           0 :         case TypeClass_HYPER:           aRetVal <<= (sal_Int64)( pVar->GetInt64() );    break;
    1473           0 :         case TypeClass_UNSIGNED_SHORT:  aRetVal <<= (sal_uInt16)( pVar->GetUShort() );  break;
    1474           0 :         case TypeClass_UNSIGNED_LONG:   aRetVal <<= (sal_uInt32)( pVar->GetULong() );   break;
    1475           0 :         case TypeClass_UNSIGNED_HYPER:  aRetVal <<= (sal_uInt64)( pVar->GetUInt64() );  break;
    1476       11156 :         default: break;
    1477             :     }
    1478             : 
    1479       29553 :     return aRetVal;
    1480             : }
    1481             : 
    1482           0 : void processAutomationParams( SbxArray* pParams, Sequence< Any >& args, bool bOLEAutomation, sal_uInt32 nParamCount )
    1483             : {
    1484           0 :     AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
    1485           0 :     if( bOLEAutomation )
    1486           0 :         pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);
    1487             : 
    1488           0 :     args.realloc( nParamCount );
    1489           0 :     Any* pAnyArgs = args.getArray();
    1490           0 :     bool bBlockConversionToSmallestType = GetSbData()->pInst->IsCompatibility();
    1491           0 :     sal_uInt32 i = 0;
    1492           0 :     if( pArgNamesArray )
    1493             :     {
    1494           0 :         Sequence< OUString >& rNameSeq = pArgNamesArray->getNames();
    1495           0 :         OUString* pNames = rNameSeq.getArray();
    1496           0 :         Any aValAny;
    1497           0 :         for( i = 0 ; i < nParamCount ; i++ )
    1498             :         {
    1499           0 :             sal_uInt16 iSbx = (sal_uInt16)(i+1);
    1500             : 
    1501           0 :             aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ),
    1502           0 :             bBlockConversionToSmallestType );
    1503             : 
    1504           0 :             OUString aParamName = pNames[iSbx];
    1505           0 :             if( !aParamName.isEmpty() )
    1506             :             {
    1507           0 :                 oleautomation::NamedArgument aNamedArgument;
    1508           0 :                 aNamedArgument.Name = aParamName;
    1509           0 :                 aNamedArgument.Value = aValAny;
    1510           0 :                 pAnyArgs[i] <<= aNamedArgument;
    1511             :             }
    1512             :             else
    1513             :             {
    1514           0 :                 pAnyArgs[i] = aValAny;
    1515             :             }
    1516           0 :         }
    1517             :     }
    1518             :     else
    1519             :     {
    1520           0 :         for( i = 0 ; i < nParamCount ; i++ )
    1521             :         {
    1522           0 :             pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (sal_uInt16)(i+1) ),
    1523           0 :             bBlockConversionToSmallestType );
    1524             :         }
    1525             :     }
    1526             : 
    1527           0 : }
    1528             : enum INVOKETYPE
    1529             : {
    1530             :    GetProp = 0,
    1531             :    SetProp,
    1532             :    Func
    1533             : };
    1534           0 : Any invokeAutomationMethod( const OUString& Name, Sequence< Any >& args, SbxArray* pParams, sal_uInt32 nParamCount, Reference< XInvocation >& rxInvocation, INVOKETYPE invokeType = Func )
    1535             : {
    1536           0 :     Sequence< sal_Int16 > OutParamIndex;
    1537           0 :     Sequence< Any > OutParam;
    1538             : 
    1539           0 :     Any aRetAny;
    1540           0 :     switch( invokeType )
    1541             :     {
    1542             :         case Func:
    1543           0 :             aRetAny = rxInvocation->invoke( Name, args, OutParamIndex, OutParam );
    1544           0 :             break;
    1545             :         case GetProp:
    1546             :             {
    1547           0 :                 Reference< XAutomationInvocation > xAutoInv( rxInvocation, UNO_QUERY );
    1548           0 :                 aRetAny = xAutoInv->invokeGetProperty( Name, args, OutParamIndex, OutParam );
    1549           0 :                 break;
    1550             :             }
    1551             :         case SetProp:
    1552             :             {
    1553           0 :                 Reference< XAutomationInvocation > xAutoInv( rxInvocation, UNO_QUERY_THROW );
    1554           0 :                 aRetAny = xAutoInv->invokePutProperty( Name, args, OutParamIndex, OutParam );
    1555           0 :                 break;
    1556             :             }
    1557             :         default:
    1558           0 :             break; // should introduce an error here
    1559             : 
    1560             :     }
    1561           0 :     const sal_Int16* pIndices = OutParamIndex.getConstArray();
    1562           0 :     sal_uInt32 nLen = OutParamIndex.getLength();
    1563           0 :     if( nLen )
    1564             :     {
    1565           0 :         const Any* pNewValues = OutParam.getConstArray();
    1566           0 :         for( sal_uInt32 j = 0 ; j < nLen ; j++ )
    1567             :         {
    1568           0 :             sal_Int16 iTarget = pIndices[ j ];
    1569           0 :             if( iTarget >= (sal_Int16)nParamCount )
    1570           0 :                 break;
    1571           0 :             unoToSbxValue( pParams->Get( (sal_uInt16)(j+1) ), pNewValues[ j ] );
    1572             :         }
    1573             :     }
    1574           0 :     return aRetAny;
    1575             : }
    1576             : 
    1577             : // Debugging help method to readout the imlemented interfaces of an object
    1578           0 : OUString Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, sal_uInt16 nRekLevel )
    1579             : {
    1580           0 :     Type aIfaceType = cppu::UnoType<XInterface>::get();
    1581           0 :     static Reference< XIdlClass > xIfaceClass = TypeToIdlClass( aIfaceType );
    1582             : 
    1583           0 :     OUStringBuffer aRetStr;
    1584           0 :     for( sal_uInt16 i = 0 ; i < nRekLevel ; i++ )
    1585           0 :         aRetStr.appendAscii( "    " );
    1586           0 :     aRetStr.append( xClass->getName() );
    1587           0 :     OUString aClassName = xClass->getName();
    1588           0 :     Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
    1589             : 
    1590             :     // checking if the interface is really supported
    1591           0 :     if( !x->queryInterface( aClassType ).hasValue() )
    1592             :     {
    1593           0 :         aRetStr.appendAscii( " (ERROR: Not really supported!)\n" );
    1594             :     }
    1595             :     // Are there super interfaces?
    1596             :     else
    1597             :     {
    1598           0 :         aRetStr.appendAscii( "\n" );
    1599             : 
    1600             :         // get the super interfaces
    1601           0 :         Sequence< Reference< XIdlClass > > aSuperClassSeq = xClass->getSuperclasses();
    1602           0 :         const Reference< XIdlClass >* pClasses = aSuperClassSeq.getConstArray();
    1603           0 :         sal_uInt32 nSuperIfaceCount = aSuperClassSeq.getLength();
    1604           0 :         for( sal_uInt32 j = 0 ; j < nSuperIfaceCount ; j++ )
    1605             :         {
    1606           0 :             const Reference< XIdlClass >& rxIfaceClass = pClasses[j];
    1607           0 :             if( !rxIfaceClass->equals( xIfaceClass ) )
    1608           0 :                 aRetStr.append( Impl_GetInterfaceInfo( x, rxIfaceClass, nRekLevel + 1 ) );
    1609           0 :         }
    1610             :     }
    1611           0 :     return aRetStr.makeStringAndClear();
    1612             : }
    1613             : 
    1614           0 : OUString getDbgObjectNameImpl( SbUnoObject* pUnoObj )
    1615             : {
    1616           0 :     OUString aName;
    1617           0 :     if( pUnoObj )
    1618             :     {
    1619           0 :         aName = pUnoObj->GetClassName();
    1620           0 :         if( aName.isEmpty() )
    1621             :         {
    1622           0 :             Any aToInspectObj = pUnoObj->getUnoAny();
    1623           0 :             TypeClass eType = aToInspectObj.getValueType().getTypeClass();
    1624           0 :             Reference< XInterface > xObj;
    1625           0 :             if( eType == TypeClass_INTERFACE )
    1626           0 :                 xObj = *static_cast<Reference< XInterface > const *>(aToInspectObj.getValue());
    1627           0 :             if( xObj.is() )
    1628             :             {
    1629           0 :                 Reference< XServiceInfo > xServiceInfo( xObj, UNO_QUERY );
    1630           0 :                 if( xServiceInfo.is() )
    1631           0 :                     aName = xServiceInfo->getImplementationName();
    1632           0 :             }
    1633             :         }
    1634             :     }
    1635           0 :     return aName;
    1636             : }
    1637             : 
    1638           0 : OUString getDbgObjectName( SbUnoObject* pUnoObj )
    1639             : {
    1640           0 :     OUString aName = getDbgObjectNameImpl( pUnoObj );
    1641           0 :     if( aName.isEmpty() )
    1642           0 :         aName += "Unknown";
    1643             : 
    1644           0 :     OUStringBuffer aRet;
    1645           0 :     if( aName.getLength() > 20 )
    1646             :     {
    1647           0 :         aRet.appendAscii( "\n" );
    1648             :     }
    1649           0 :     aRet.appendAscii( "\"" );
    1650           0 :     aRet.append( aName );
    1651           0 :     aRet.appendAscii( "\":" );
    1652           0 :     return aRet.makeStringAndClear();
    1653             : }
    1654             : 
    1655           0 : OUString getBasicObjectTypeName( SbxObject* pObj )
    1656             : {
    1657           0 :     OUString aName;
    1658           0 :     if( pObj )
    1659             :     {
    1660           0 :         SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
    1661           0 :         SbUnoStructRefObject* pUnoStructObj = PTR_CAST(SbUnoStructRefObject,pObj);
    1662           0 :         if( pUnoObj )
    1663           0 :             aName = getDbgObjectNameImpl( pUnoObj );
    1664           0 :         else if ( pUnoStructObj )
    1665           0 :             aName = pUnoStructObj->GetClassName();
    1666             :     }
    1667           0 :     return aName;
    1668             : }
    1669             : 
    1670         144 : bool checkUnoObjectType( SbUnoObject* pUnoObj, const OUString& rClass )
    1671             : {
    1672         144 :     Any aToInspectObj = pUnoObj->getUnoAny();
    1673         144 :     TypeClass eType = aToInspectObj.getValueType().getTypeClass();
    1674         144 :     if( eType != TypeClass_INTERFACE )
    1675             :     {
    1676           0 :         return false;
    1677             :     }
    1678         288 :     const Reference< XInterface > x = *static_cast<Reference< XInterface > const *>(aToInspectObj.getValue());
    1679             : 
    1680             :     // Return true for XInvocation based objects as interface type names don't count then
    1681         288 :     Reference< XInvocation > xInvocation( x, UNO_QUERY );
    1682         144 :     if( xInvocation.is() )
    1683             :     {
    1684           8 :         return true;
    1685             :     }
    1686         136 :     bool result = false;
    1687         272 :     Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
    1688         136 :     if( xTypeProvider.is() )
    1689             :     {
    1690             :         /*  Although interfaces in the ooo.vba namespace obey the IDL rules and
    1691             :             have a leading 'X', in Basic we want to be able to do something
    1692             :             like 'Dim wb As Workbooks' or 'Dim lb As MSForms.Label'. Here we
    1693             :             add a leading 'X' to the class name and a leading dot to the entire
    1694             :             type name. This results e.g. in '.XWorkbooks' or '.MSForms.XLabel'
    1695             :             which matches the interface names 'ooo.vba.excel.XWorkbooks' or
    1696             :             'ooo.vba.msforms.XLabel'.
    1697             :          */
    1698         136 :         OUString aClassName;
    1699         136 :         if ( SbiRuntime::isVBAEnabled() )
    1700             :         {
    1701         136 :             aClassName = ".";
    1702         136 :             sal_Int32 nClassNameDot = rClass.lastIndexOf( '.' );
    1703         136 :             if( nClassNameDot >= 0 )
    1704             :             {
    1705           0 :                 aClassName += rClass.copy( 0, nClassNameDot + 1 ) + "X" + rClass.copy( nClassNameDot + 1 );
    1706             :             }
    1707             :             else
    1708             :             {
    1709         136 :                 aClassName += "X" + rClass;
    1710             :             }
    1711             :         }
    1712             :         else // assume extended type declaration support for basic ( can't get here
    1713             :              // otherwise.
    1714           0 :             aClassName = rClass;
    1715             : 
    1716         272 :         Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
    1717         136 :         const Type* pTypeArray = aTypeSeq.getConstArray();
    1718         136 :         sal_uInt32 nIfaceCount = aTypeSeq.getLength();
    1719         136 :         for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
    1720             :         {
    1721         136 :             const Type& rType = pTypeArray[j];
    1722             : 
    1723         136 :             Reference<XIdlClass> xClass = TypeToIdlClass( rType );
    1724         136 :             if( !xClass.is() )
    1725             :             {
    1726             :                 OSL_FAIL("failed to get XIdlClass for type");
    1727           0 :                 break;
    1728             :             }
    1729         136 :             OUString aInterfaceName = xClass->getName();
    1730         136 :             if ( aInterfaceName == "com.sun.star.bridge.oleautomation.XAutomationObject" )
    1731             :             {
    1732             :                 // there is a hack in the extensions/source/ole/oleobj.cxx  to return the typename of the automation object, lets check if it
    1733             :                 // matches
    1734           0 :                 Reference< XInvocation > xInv( aToInspectObj, UNO_QUERY );
    1735           0 :                 if ( xInv.is() )
    1736             :                 {
    1737           0 :                     OUString sTypeName;
    1738           0 :                     xInv->getValue( OUString( "$GetTypeName" ) ) >>= sTypeName;
    1739           0 :                     if ( sTypeName.isEmpty() || sTypeName == "IDispatch" )
    1740             :                     {
    1741             :                         // can't check type, leave it pass
    1742           0 :                         result = true;
    1743             :                     }
    1744             :                     else
    1745             :                     {
    1746           0 :                         result = sTypeName.equals( rClass );
    1747           0 :                     }
    1748             :                 }
    1749           0 :                 break; // finished checking automation object
    1750             :             }
    1751             : 
    1752             :             // match interface name with passed class name
    1753             :             OSL_TRACE("Checking if object implements %s", OUStringToOString( aClassName, RTL_TEXTENCODING_UTF8 ).getStr() );
    1754         272 :             if ( (aClassName.getLength() <= aInterfaceName.getLength()) &&
    1755         136 :                     aInterfaceName.endsWithIgnoreAsciiCase( aClassName ) )
    1756             :             {
    1757         136 :                 result = true;
    1758         136 :                 break;
    1759             :             }
    1760         136 :         }
    1761             :     }
    1762         280 :     return result;
    1763             : }
    1764             : 
    1765             : // Debugging help method to readout the imlemented interfaces of an object
    1766           0 : OUString Impl_GetSupportedInterfaces( SbUnoObject* pUnoObj )
    1767             : {
    1768           0 :     Any aToInspectObj = pUnoObj->getUnoAny();
    1769             : 
    1770             :     // allow only TypeClass interface
    1771           0 :     TypeClass eType = aToInspectObj.getValueType().getTypeClass();
    1772           0 :     OUStringBuffer aRet;
    1773           0 :     if( eType != TypeClass_INTERFACE )
    1774             :     {
    1775           0 :         aRet.appendAscii( ID_DBG_SUPPORTEDINTERFACES );
    1776           0 :         aRet.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
    1777             :     }
    1778             :     else
    1779             :     {
    1780             :         // get the interface from the Any
    1781           0 :         const Reference< XInterface > x = *static_cast<Reference< XInterface > const *>(aToInspectObj.getValue());
    1782             : 
    1783           0 :         Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
    1784             : 
    1785           0 :         aRet.appendAscii( "Supported interfaces by object " );
    1786           0 :         aRet.append( getDbgObjectName( pUnoObj ) );
    1787           0 :         aRet.appendAscii( "\n" );
    1788           0 :         if( xTypeProvider.is() )
    1789             :         {
    1790             :             // get the interfaces of the implementation
    1791           0 :             Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
    1792           0 :             const Type* pTypeArray = aTypeSeq.getConstArray();
    1793           0 :             sal_uInt32 nIfaceCount = aTypeSeq.getLength();
    1794           0 :             for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
    1795             :             {
    1796           0 :                 const Type& rType = pTypeArray[j];
    1797             : 
    1798           0 :                 Reference<XIdlClass> xClass = TypeToIdlClass( rType );
    1799           0 :                 if( xClass.is() )
    1800             :                 {
    1801           0 :                     aRet.append( Impl_GetInterfaceInfo( x, xClass, 1 ) );
    1802             :                 }
    1803             :                 else
    1804             :                 {
    1805           0 :                     typelib_TypeDescription * pTD = 0;
    1806           0 :                     rType.getDescription( &pTD );
    1807             : 
    1808           0 :                     aRet.appendAscii( "*** ERROR: No IdlClass for type \"" );
    1809           0 :                     aRet.append( pTD->pTypeName );
    1810           0 :                     aRet.appendAscii( "\"\n*** Please check type library\n" );
    1811             :                 }
    1812           0 :             }
    1813           0 :         }
    1814             :     }
    1815           0 :     return aRet.makeStringAndClear();
    1816             : }
    1817             : 
    1818             : 
    1819             : 
    1820             : // Debugging help method SbxDataType -> String
    1821           0 : OUString Dbg_SbxDataType2String( SbxDataType eType )
    1822             : {
    1823           0 :     OUStringBuffer aRet;
    1824           0 :     switch( +eType )
    1825             :     {
    1826           0 :         case SbxEMPTY:      aRet.appendAscii("SbxEMPTY"); break;
    1827           0 :         case SbxNULL:       aRet.appendAscii("SbxNULL"); break;
    1828           0 :         case SbxINTEGER:    aRet.appendAscii("SbxINTEGER"); break;
    1829           0 :         case SbxLONG:       aRet.appendAscii("SbxLONG"); break;
    1830           0 :         case SbxSINGLE:     aRet.appendAscii("SbxSINGLE"); break;
    1831           0 :         case SbxDOUBLE:     aRet.appendAscii("SbxDOUBLE"); break;
    1832           0 :         case SbxCURRENCY:   aRet.appendAscii("SbxCURRENCY"); break;
    1833           0 :         case SbxDECIMAL:    aRet.appendAscii("SbxDECIMAL"); break;
    1834           0 :         case SbxDATE:       aRet.appendAscii("SbxDATE"); break;
    1835           0 :         case SbxSTRING:     aRet.appendAscii("SbxSTRING"); break;
    1836           0 :         case SbxOBJECT:     aRet.appendAscii("SbxOBJECT"); break;
    1837           0 :         case SbxERROR:      aRet.appendAscii("SbxERROR"); break;
    1838           0 :         case SbxBOOL:       aRet.appendAscii("SbxBOOL"); break;
    1839           0 :         case SbxVARIANT:    aRet.appendAscii("SbxVARIANT"); break;
    1840           0 :         case SbxDATAOBJECT: aRet.appendAscii("SbxDATAOBJECT"); break;
    1841           0 :         case SbxCHAR:       aRet.appendAscii("SbxCHAR"); break;
    1842           0 :         case SbxBYTE:       aRet.appendAscii("SbxBYTE"); break;
    1843           0 :         case SbxUSHORT:     aRet.appendAscii("SbxUSHORT"); break;
    1844           0 :         case SbxULONG:      aRet.appendAscii("SbxULONG"); break;
    1845           0 :         case SbxSALINT64:   aRet.appendAscii("SbxINT64"); break;
    1846           0 :         case SbxSALUINT64:  aRet.appendAscii("SbxUINT64"); break;
    1847           0 :         case SbxINT:        aRet.appendAscii("SbxINT"); break;
    1848           0 :         case SbxUINT:       aRet.appendAscii("SbxUINT"); break;
    1849           0 :         case SbxVOID:       aRet.appendAscii("SbxVOID"); break;
    1850           0 :         case SbxHRESULT:    aRet.appendAscii("SbxHRESULT"); break;
    1851           0 :         case SbxPOINTER:    aRet.appendAscii("SbxPOINTER"); break;
    1852           0 :         case SbxDIMARRAY:   aRet.appendAscii("SbxDIMARRAY"); break;
    1853           0 :         case SbxCARRAY:     aRet.appendAscii("SbxCARRAY"); break;
    1854           0 :         case SbxUSERDEF:    aRet.appendAscii("SbxUSERDEF"); break;
    1855           0 :         case SbxLPSTR:      aRet.appendAscii("SbxLPSTR"); break;
    1856           0 :         case SbxLPWSTR:     aRet.appendAscii("SbxLPWSTR"); break;
    1857           0 :         case SbxCoreSTRING: aRet.appendAscii("SbxCoreSTRING"); break;
    1858           0 :         case SbxOBJECT | SbxARRAY: aRet.appendAscii("SbxARRAY"); break;
    1859           0 :         default: aRet.appendAscii("Unknown Sbx-Type!");break;
    1860             :     }
    1861           0 :     return aRet.makeStringAndClear();
    1862             : }
    1863             : 
    1864             : // Debugging help method to display the properties of a SbUnoObjects
    1865           0 : OUString Impl_DumpProperties( SbUnoObject* pUnoObj )
    1866             : {
    1867           0 :     OUStringBuffer aRet;
    1868           0 :     aRet.appendAscii("Properties of object ");
    1869           0 :     aRet.append( getDbgObjectName( pUnoObj ) );
    1870             : 
    1871             :     // analyse the Uno-Infos to recognise the arrays
    1872           0 :     Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
    1873           0 :     if( !xAccess.is() )
    1874             :     {
    1875           0 :         Reference< XInvocation > xInvok = pUnoObj->getInvocation();
    1876           0 :         if( xInvok.is() )
    1877           0 :             xAccess = xInvok->getIntrospection();
    1878             :     }
    1879           0 :     if( !xAccess.is() )
    1880             :     {
    1881           0 :         aRet.appendAscii( "\nUnknown, no introspection available\n" );
    1882           0 :         return aRet.makeStringAndClear();
    1883             :     }
    1884             : 
    1885           0 :     Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
    1886           0 :     sal_uInt32 nUnoPropCount = props.getLength();
    1887           0 :     const Property* pUnoProps = props.getConstArray();
    1888             : 
    1889           0 :     SbxArray* pProps = pUnoObj->GetProperties();
    1890           0 :     sal_uInt16 nPropCount = pProps->Count();
    1891           0 :     sal_uInt16 nPropsPerLine = 1 + nPropCount / 30;
    1892           0 :     for( sal_uInt16 i = 0; i < nPropCount; i++ )
    1893             :     {
    1894           0 :         SbxVariable* pVar = pProps->Get( i );
    1895           0 :         if( pVar )
    1896             :         {
    1897           0 :             OUStringBuffer aPropStr;
    1898           0 :             if( (i % nPropsPerLine) == 0 )
    1899           0 :                 aPropStr.appendAscii( "\n" );
    1900             : 
    1901             :             // output the type and name
    1902             :             // Is it in Uno a sequence?
    1903           0 :             SbxDataType eType = pVar->GetFullType();
    1904             : 
    1905           0 :             bool bMaybeVoid = false;
    1906           0 :             if( i < nUnoPropCount )
    1907             :             {
    1908           0 :                 const Property& rProp = pUnoProps[ i ];
    1909             : 
    1910             :                 // For MAYBEVOID freshly convert the type from Uno,
    1911             :                 // so not just SbxEMPTY is returned.
    1912           0 :                 if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
    1913             :                 {
    1914           0 :                     eType = unoToSbxType( rProp.Type.getTypeClass() );
    1915           0 :                     bMaybeVoid = true;
    1916             :                 }
    1917           0 :                 if( eType == SbxOBJECT )
    1918             :                 {
    1919           0 :                     Type aType = rProp.Type;
    1920           0 :                     if( aType.getTypeClass() == TypeClass_SEQUENCE )
    1921           0 :                         eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
    1922             :                 }
    1923             :             }
    1924           0 :             aPropStr.append( Dbg_SbxDataType2String( eType ) );
    1925           0 :             if( bMaybeVoid )
    1926           0 :                 aPropStr.appendAscii( "/void" );
    1927           0 :             aPropStr.appendAscii( " " );
    1928           0 :             aPropStr.append( pVar->GetName() );
    1929             : 
    1930           0 :             if( i == nPropCount - 1 )
    1931           0 :                 aPropStr.appendAscii( "\n" );
    1932             :             else
    1933           0 :                 aPropStr.appendAscii( "; " );
    1934             : 
    1935           0 :             aRet.append( aPropStr.makeStringAndClear() );
    1936             :         }
    1937             :     }
    1938           0 :     return aRet.makeStringAndClear();
    1939             : }
    1940             : 
    1941             : // Debugging help method to display the methods of an SbUnoObjects
    1942           0 : OUString Impl_DumpMethods( SbUnoObject* pUnoObj )
    1943             : {
    1944           0 :     OUStringBuffer aRet;
    1945           0 :     aRet.appendAscii("Methods of object ");
    1946           0 :     aRet.append( getDbgObjectName( pUnoObj ) );
    1947             : 
    1948             :     // XIntrospectionAccess, so that the types of the parameter could be outputed
    1949           0 :     Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
    1950           0 :     if( !xAccess.is() )
    1951             :     {
    1952           0 :         Reference< XInvocation > xInvok = pUnoObj->getInvocation();
    1953           0 :         if( xInvok.is() )
    1954           0 :             xAccess = xInvok->getIntrospection();
    1955             :     }
    1956           0 :     if( !xAccess.is() )
    1957             :     {
    1958           0 :         aRet.appendAscii( "\nUnknown, no introspection available\n" );
    1959           0 :         return aRet.makeStringAndClear();
    1960             :     }
    1961           0 :     Sequence< Reference< XIdlMethod > > methods = xAccess->getMethods
    1962           0 :         ( MethodConcept::ALL - MethodConcept::DANGEROUS );
    1963           0 :     const Reference< XIdlMethod >* pUnoMethods = methods.getConstArray();
    1964             : 
    1965           0 :     SbxArray* pMethods = pUnoObj->GetMethods();
    1966           0 :     sal_uInt16 nMethodCount = pMethods->Count();
    1967           0 :     if( !nMethodCount )
    1968             :     {
    1969           0 :         aRet.appendAscii( "\nNo methods found\n" );
    1970           0 :         return aRet.makeStringAndClear();
    1971             :     }
    1972           0 :     sal_uInt16 nPropsPerLine = 1 + nMethodCount / 30;
    1973           0 :     for( sal_uInt16 i = 0; i < nMethodCount; i++ )
    1974             :     {
    1975           0 :         SbxVariable* pVar = pMethods->Get( i );
    1976           0 :         if( pVar )
    1977             :         {
    1978           0 :             if( (i % nPropsPerLine) == 0 )
    1979           0 :                 aRet.appendAscii( "\n" );
    1980             : 
    1981             :             // address the method
    1982           0 :             const Reference< XIdlMethod >& rxMethod = pUnoMethods[i];
    1983             : 
    1984             :             // Is it in Uno a sequence?
    1985           0 :             SbxDataType eType = pVar->GetFullType();
    1986           0 :             if( eType == SbxOBJECT )
    1987             :             {
    1988           0 :                 Reference< XIdlClass > xClass = rxMethod->getReturnType();
    1989           0 :                 if( xClass.is() && xClass->getTypeClass() == TypeClass_SEQUENCE )
    1990           0 :                     eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
    1991             :             }
    1992             :             // output the name and the type
    1993           0 :             aRet.append( Dbg_SbxDataType2String( eType ) );
    1994           0 :             aRet.appendAscii( " " );
    1995           0 :             aRet.append ( pVar->GetName() );
    1996           0 :             aRet.appendAscii( " ( " );
    1997             : 
    1998             :             // the get-method mustn't have a parameter
    1999           0 :             Sequence< Reference< XIdlClass > > aParamsSeq = rxMethod->getParameterTypes();
    2000           0 :             sal_uInt32 nParamCount = aParamsSeq.getLength();
    2001           0 :             const Reference< XIdlClass >* pParams = aParamsSeq.getConstArray();
    2002             : 
    2003           0 :             if( nParamCount > 0 )
    2004             :             {
    2005           0 :                 for( sal_uInt32 j = 0; j < nParamCount; j++ )
    2006             :                 {
    2007           0 :                     aRet.append ( Dbg_SbxDataType2String( unoToSbxType( pParams[ j ] ) ) );
    2008           0 :                     if( j < nParamCount - 1 )
    2009           0 :                         aRet.appendAscii( ", " );
    2010             :                 }
    2011             :             }
    2012             :             else
    2013           0 :                 aRet.appendAscii( "void" );
    2014             : 
    2015           0 :             aRet.appendAscii( " ) " );
    2016             : 
    2017           0 :             if( i == nMethodCount - 1 )
    2018           0 :                 aRet.appendAscii( "\n" );
    2019             :             else
    2020           0 :                 aRet.appendAscii( "; " );
    2021             :         }
    2022             :     }
    2023           0 :     return aRet.makeStringAndClear();
    2024             : }
    2025             : 
    2026           0 : TYPEINIT1(AutomationNamedArgsSbxArray,SbxArray)
    2027             : 
    2028             : // Implementation SbUnoObject
    2029        5279 : void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
    2030             :                            const SfxHint& rHint, const TypeId& rHintType )
    2031             : {
    2032        5279 :     if( bNeedIntrospection )
    2033           0 :         doIntrospection();
    2034             : 
    2035        5279 :     const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
    2036        5279 :     if( pHint )
    2037             :     {
    2038        5279 :         SbxVariable* pVar = pHint->GetVar();
    2039        5279 :         SbxArray* pParams = pVar->GetParameters();
    2040        5279 :         SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
    2041        5279 :         SbUnoMethod* pMeth = PTR_CAST(SbUnoMethod,pVar);
    2042        5279 :         if( pProp )
    2043             :         {
    2044        2611 :             bool bInvocation = pProp->isInvocationBased();
    2045        2611 :             if( pHint->GetId() == SBX_HINT_DATAWANTED )
    2046             :             {
    2047             :                 // Test-Properties
    2048        1954 :                 sal_Int32 nId = pProp->nId;
    2049        1954 :                 if( nId < 0 )
    2050             :                 {
    2051             :                     // Id == -1: Display implemented interfaces according the ClassProvider
    2052           0 :                     if( nId == -1 )     // Property ID_DBG_SUPPORTEDINTERFACES"
    2053             :                     {
    2054           0 :                         OUString aRetStr = Impl_GetSupportedInterfaces( this );
    2055           0 :                         pVar->PutString( aRetStr );
    2056             :                     }
    2057             :                     // Id == -2: output properties
    2058           0 :                     else if( nId == -2 )        // Property ID_DBG_PROPERTIES
    2059             :                     {
    2060             :                         // now all properties must be created
    2061           0 :                         implCreateAll();
    2062           0 :                         OUString aRetStr = Impl_DumpProperties( this );
    2063           0 :                         pVar->PutString( aRetStr );
    2064             :                     }
    2065             :                     // Id == -3: output the methods
    2066           0 :                     else if( nId == -3 )        // Property ID_DBG_METHODS
    2067             :                     {
    2068             :                         // now all properties must be created
    2069           0 :                         implCreateAll();
    2070           0 :                         OUString aRetStr = Impl_DumpMethods( this );
    2071           0 :                         pVar->PutString( aRetStr );
    2072             :                     }
    2073           0 :                     return;
    2074             :                 }
    2075             : 
    2076        1954 :                 if( !bInvocation && mxUnoAccess.is() )
    2077             :                 {
    2078             :                     try
    2079             :                     {
    2080        1843 :                         if ( maStructInfo.get()  )
    2081             :                         {
    2082          49 :                             StructRefInfo aMember = maStructInfo->getStructMember( pProp->GetName() );
    2083          49 :                             if ( aMember.isEmpty() )
    2084             :                             {
    2085           0 :                                  StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
    2086             :                             }
    2087             :                             else
    2088             :                             {
    2089          49 :                                 if ( pProp->isUnoStruct() )
    2090             :                                 {
    2091          23 :                                     SbUnoStructRefObject* pSbUnoObject = new SbUnoStructRefObject( pProp->GetName(), aMember );
    2092          23 :                                     SbxObjectRef xWrapper = static_cast<SbxObject*>(pSbUnoObject);
    2093          23 :                                     pVar->PutObject( xWrapper );
    2094             :                                 }
    2095             :                                 else
    2096             :                                 {
    2097          26 :                                     Any aRetAny = aMember.getValue();
    2098             :                                     // take over the value from Uno to Sbx
    2099          26 :                                     unoToSbxValue( pVar, aRetAny );
    2100             :                                 }
    2101          49 :                                 return;
    2102           0 :                             }
    2103             :                         }
    2104             :                         // get the value
    2105        1794 :                         Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()), UNO_QUERY );
    2106        3588 :                         Any aRetAny = xPropSet->getPropertyValue( pProp->GetName() );
    2107             :                         // The use of getPropertyValue (instead of using the index) is
    2108             :                         // suboptimal, but the refactoring to XInvocation is already pending
    2109             :                         // Otherwise it is possible to use FastPropertySet
    2110             : 
    2111             :                         // take over the value from Uno to Sbx
    2112        3588 :                         unoToSbxValue( pVar, aRetAny );
    2113             :                     }
    2114           0 :                     catch( const Exception& )
    2115             :                     {
    2116           0 :                         implHandleAnyException( ::cppu::getCaughtException() );
    2117             :                     }
    2118             :                 }
    2119         111 :                 else if( bInvocation && mxInvocation.is() )
    2120             :                 {
    2121             :                     try
    2122             :                     {
    2123         111 :                         sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
    2124         111 :                         bool bCanBeConsideredAMethod = mxInvocation->hasMethod( pProp->GetName() );
    2125         111 :                         Any aRetAny;
    2126         111 :                         if ( bCanBeConsideredAMethod && nParamCount )
    2127             :                         {
    2128             :                             // Automation properties have methods, so.. we need to invoke this through
    2129             :                             // XInvocation
    2130           0 :                             Sequence<Any> args;
    2131           0 :                             processAutomationParams( pParams, args, true, nParamCount );
    2132           0 :                             aRetAny = invokeAutomationMethod( pProp->GetName(), args, pParams, nParamCount, mxInvocation, GetProp );
    2133             :                         }
    2134             :                         else
    2135         111 :                             aRetAny = mxInvocation->getValue( pProp->GetName() );
    2136             :                         // take over the value from Uno to Sbx
    2137         111 :                         unoToSbxValue( pVar, aRetAny );
    2138         111 :                         if( pParams && bCanBeConsideredAMethod )
    2139           0 :                             pVar->SetParameters( NULL );
    2140             : 
    2141             :                     }
    2142           0 :                     catch( const Exception& )
    2143             :                     {
    2144           0 :                         implHandleAnyException( ::cppu::getCaughtException() );
    2145             :                     }
    2146             :                 }
    2147             :             }
    2148         657 :             else if( pHint->GetId() == SBX_HINT_DATACHANGED )
    2149             :             {
    2150         657 :                 if( !bInvocation && mxUnoAccess.is() )
    2151             :                 {
    2152         657 :                     if( pProp->aUnoProp.Attributes & PropertyAttribute::READONLY )
    2153             :                     {
    2154           0 :                         StarBASIC::Error( SbERR_PROP_READONLY );
    2155          77 :                         return;
    2156             :                     }
    2157         657 :                     if (  maStructInfo.get()  )
    2158             :                     {
    2159          77 :                         StructRefInfo aMember = maStructInfo->getStructMember( pProp->GetName() );
    2160          77 :                         if ( aMember.isEmpty() )
    2161             :                         {
    2162           0 :                             StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
    2163             :                         }
    2164             :                         else
    2165             :                         {
    2166          77 :                             Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
    2167          77 :                             aMember.setValue( aAnyValue );
    2168             :                         }
    2169          77 :                         return;
    2170             :                    }
    2171             :                     // take over the value from Uno to Sbx
    2172         580 :                     Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
    2173             :                     try
    2174             :                     {
    2175             :                         // set the value
    2176         580 :                         Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()), UNO_QUERY );
    2177         580 :                         xPropSet->setPropertyValue( pProp->GetName(), aAnyValue );
    2178             :                         // The use of getPropertyValue (instead of using the index) is
    2179             :                         // suboptimal, but the refactoring to XInvocation is already pending
    2180             :                         // Otherwise it is possible to use FastPropertySet
    2181             :                     }
    2182           0 :                     catch( const Exception& )
    2183             :                     {
    2184           0 :                         implHandleAnyException( ::cppu::getCaughtException() );
    2185         580 :                     }
    2186             :                 }
    2187           0 :                 else if( bInvocation && mxInvocation.is() )
    2188             :                 {
    2189             :                     // take over the value from Uno to Sbx
    2190           0 :                     Any aAnyValue = sbxToUnoValueImpl( pVar );
    2191             :                     try
    2192             :                     {
    2193             :                         // set the value
    2194           0 :                         mxInvocation->setValue( pProp->GetName(), aAnyValue );
    2195             :                     }
    2196           0 :                     catch( const Exception& )
    2197             :                     {
    2198           0 :                         implHandleAnyException( ::cppu::getCaughtException() );
    2199           0 :                     }
    2200             :                 }
    2201             :             }
    2202             :         }
    2203        2668 :         else if( pMeth )
    2204             :         {
    2205        2668 :             bool bInvocation = pMeth->isInvocationBased();
    2206        2668 :             if( pHint->GetId() == SBX_HINT_DATAWANTED )
    2207             :             {
    2208             :                 // number of Parameter -1 because of Param0 == this
    2209        2659 :                 sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
    2210        2659 :                 Sequence<Any> args;
    2211        2659 :                 bool bOutParams = false;
    2212             :                 sal_uInt32 i;
    2213             : 
    2214        2659 :                 if( !bInvocation && mxUnoAccess.is() )
    2215             :                 {
    2216             :                     // get info
    2217        2659 :                     const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
    2218        2659 :                     const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
    2219        2659 :                     sal_uInt32 nUnoParamCount = rInfoSeq.getLength();
    2220        2659 :                     sal_uInt32 nAllocParamCount = nParamCount;
    2221             : 
    2222             :                     // ignore surplus parameter; alternative: throw an error
    2223        2659 :                     if( nParamCount > nUnoParamCount )
    2224             :                     {
    2225           0 :                         nParamCount = nUnoParamCount;
    2226           0 :                         nAllocParamCount = nParamCount;
    2227             :                     }
    2228        2659 :                     else if( nParamCount < nUnoParamCount )
    2229             :                     {
    2230        1368 :                         SbiInstance* pInst = GetSbData()->pInst;
    2231        1368 :                         if( pInst && pInst->IsCompatibility() )
    2232             :                         {
    2233             :                             // Check types
    2234        1368 :                             bool bError = false;
    2235        4069 :                             for( i = nParamCount ; i < nUnoParamCount ; i++ )
    2236             :                             {
    2237        2701 :                                 const ParamInfo& rInfo = pParamInfos[i];
    2238        2701 :                                 const Reference< XIdlClass >& rxClass = rInfo.aType;
    2239        2701 :                                 if( rxClass->getTypeClass() != TypeClass_ANY )
    2240             :                                 {
    2241           0 :                                     bError = true;
    2242           0 :                                     StarBASIC::Error( SbERR_NOT_OPTIONAL );
    2243             :                                 }
    2244             :                             }
    2245        1368 :                             if( !bError )
    2246        1368 :                                 nAllocParamCount = nUnoParamCount;
    2247             :                         }
    2248             :                     }
    2249             : 
    2250        2659 :                     if( nAllocParamCount > 0 )
    2251             :                     {
    2252        2272 :                         args.realloc( nAllocParamCount );
    2253        2272 :                         Any* pAnyArgs = args.getArray();
    2254        4647 :                         for( i = 0 ; i < nParamCount ; i++ )
    2255             :                         {
    2256        2375 :                             const ParamInfo& rInfo = pParamInfos[i];
    2257        2375 :                             const Reference< XIdlClass >& rxClass = rInfo.aType;
    2258             : 
    2259        2375 :                             com::sun::star::uno::Type aType( rxClass->getTypeClass(), rxClass->getName() );
    2260             : 
    2261             :                             // ATTENTION: Don't forget for Sbx-Parameter the offset!
    2262        2375 :                             pAnyArgs[i] = sbxToUnoValue( pParams->Get( (sal_uInt16)(i+1) ), aType );
    2263             : 
    2264             :                             // If it is not certain check whether the out-parameter are available.
    2265        2375 :                             if( !bOutParams )
    2266             :                             {
    2267        2375 :                                 ParamMode aParamMode = rInfo.aMode;
    2268        2375 :                                 if( aParamMode != ParamMode_IN )
    2269           8 :                                     bOutParams = true;
    2270             :                             }
    2271        2375 :                         }
    2272             :                     }
    2273             :                 }
    2274           0 :                 else if( bInvocation && pParams && mxInvocation.is() )
    2275             :                 {
    2276           0 :                     bool bOLEAutomation = true;
    2277           0 :                     processAutomationParams( pParams, args, bOLEAutomation, nParamCount );
    2278             :                 }
    2279             : 
    2280             :                 // call the method
    2281        2659 :                 GetSbData()->bBlockCompilerError = true;  // #106433 Block compiler errors for API calls
    2282             :                 try
    2283             :                 {
    2284        2659 :                     if( !bInvocation && mxUnoAccess.is() )
    2285             :                     {
    2286        2662 :                         Any aRetAny = pMeth->m_xUnoMethod->invoke( getUnoAny(), args );
    2287             : 
    2288             :                         // take over the value from Uno to Sbx
    2289        2656 :                         unoToSbxValue( pVar, aRetAny );
    2290             : 
    2291             :                         // Did we to copy back the Out-Parameter?
    2292        2656 :                         if( bOutParams )
    2293             :                         {
    2294           8 :                             const Any* pAnyArgs = args.getConstArray();
    2295             : 
    2296             :                             // get info
    2297           8 :                             const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
    2298           8 :                             const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
    2299             : 
    2300             :                             sal_uInt32 j;
    2301          16 :                             for( j = 0 ; j < nParamCount ; j++ )
    2302             :                             {
    2303           8 :                                 const ParamInfo& rInfo = pParamInfos[j];
    2304           8 :                                 ParamMode aParamMode = rInfo.aMode;
    2305           8 :                                 if( aParamMode != ParamMode_IN )
    2306           8 :                                     unoToSbxValue( pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
    2307             :                             }
    2308        2656 :                         }
    2309             :                     }
    2310           0 :                     else if( bInvocation && mxInvocation.is() )
    2311             :                     {
    2312           0 :                         Any aRetAny = invokeAutomationMethod( pMeth->GetName(), args, pParams, nParamCount, mxInvocation );
    2313           0 :                         unoToSbxValue( pVar, aRetAny );
    2314             :                         }
    2315             : 
    2316             :                     // remove parameter here, because this was not done anymore in unoToSbxValue()
    2317             :                     // for arrays
    2318        2656 :                     if( pParams )
    2319        1876 :                         pVar->SetParameters( NULL );
    2320             :                 }
    2321           3 :                 catch( const Exception& )
    2322             :                 {
    2323           3 :                     implHandleAnyException( ::cppu::getCaughtException() );
    2324             :                 }
    2325        2659 :                 GetSbData()->bBlockCompilerError = false;  // #106433 Unblock compiler errors
    2326             :             }
    2327             :         }
    2328             :         else
    2329           0 :             SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
    2330             :     }
    2331             : }
    2332             : 
    2333             : 
    2334       24820 : SbUnoObject::SbUnoObject( const OUString& aName_, const Any& aUnoObj_ )
    2335             :     : SbxObject( aName_ )
    2336             :     , bNeedIntrospection( true )
    2337       24820 :     , bNativeCOMObject( false )
    2338             : {
    2339       24820 :     static Reference< XIntrospection > xIntrospection;
    2340             : 
    2341             :     // beat out again the default properties of Sbx
    2342       24820 :     Remove( OUString("Name"), SbxCLASS_DONTCARE );
    2343       24820 :     Remove( OUString("Parent"), SbxCLASS_DONTCARE );
    2344             : 
    2345             :     // check the type of the ojekts
    2346       24820 :     TypeClass eType = aUnoObj_.getValueType().getTypeClass();
    2347       24820 :     Reference< XInterface > x;
    2348       24820 :     if( eType == TypeClass_INTERFACE )
    2349             :     {
    2350             :         // get the interface from the Any
    2351       24652 :         x = *static_cast<Reference< XInterface > const *>(aUnoObj_.getValue());
    2352       24652 :         if( !x.is() )
    2353        9370 :             return;
    2354             :     }
    2355             : 
    2356       30900 :     Reference< XTypeProvider > xTypeProvider;
    2357             :     // Did the object have an invocation itself?
    2358       15450 :     mxInvocation = Reference< XInvocation >( x, UNO_QUERY );
    2359             : 
    2360       15450 :     xTypeProvider = Reference< XTypeProvider >( x, UNO_QUERY );
    2361             : 
    2362       15450 :     if( mxInvocation.is() )
    2363             :     {
    2364             : 
    2365             :         // get the ExactName
    2366         710 :         mxExactNameInvocation = Reference< XExactName >::query( mxInvocation );
    2367             : 
    2368             :         // The remainder refers only to the introspection
    2369         710 :         if( !xTypeProvider.is() )
    2370             :         {
    2371           0 :             bNeedIntrospection = false;
    2372           0 :             return;
    2373             :         }
    2374             : 
    2375             :         // Ignore introspection based members for COM objects to avoid
    2376             :         // hiding of equally named COM symbols, e.g. XInvocation::getValue
    2377         710 :         Reference< oleautomation::XAutomationObject > xAutomationObject( aUnoObj_, UNO_QUERY );
    2378         710 :         if( xAutomationObject.is() )
    2379           0 :             bNativeCOMObject = true;
    2380             :     }
    2381             : 
    2382       15450 :     maTmpUnoObj = aUnoObj_;
    2383             : 
    2384             : 
    2385             :     //*** Define the name ***
    2386       15450 :     bool bFatalError = true;
    2387             : 
    2388             :     // Is it an interface or a struct?
    2389       15450 :     bool bSetClassName = false;
    2390       30900 :     OUString aClassName_;
    2391       15450 :     if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
    2392             :     {
    2393             :         // Struct is Ok
    2394         168 :         bFatalError = false;
    2395             : 
    2396             :         // insert the real name of the class
    2397         168 :         if( aName_.isEmpty() )
    2398             :         {
    2399          43 :             aClassName_ = aUnoObj_.getValueType().getTypeName();
    2400          43 :             bSetClassName = true;
    2401             :         }
    2402         168 :         StructRefInfo aThisStruct( maTmpUnoObj, maTmpUnoObj.getValueType(), 0 );
    2403         168 :         maStructInfo.reset( new SbUnoStructRefObject( GetName(), aThisStruct ) );
    2404             :     }
    2405       15282 :     else if( eType == TypeClass_INTERFACE )
    2406             :     {
    2407             :         // Interface works always through the type in the Any
    2408       15282 :         bFatalError = false;
    2409             :     }
    2410       15450 :     if( bSetClassName )
    2411          43 :         SetClassName( aClassName_ );
    2412             : 
    2413             :     // Neither interface nor Struct -> FatalError
    2414       15450 :     if( bFatalError )
    2415             :     {
    2416           0 :         StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
    2417           0 :         return;
    2418       15450 :     }
    2419             : 
    2420             :     // pass the introspection primal on demand
    2421             : }
    2422             : 
    2423       73485 : SbUnoObject::~SbUnoObject()
    2424             : {
    2425       73485 : }
    2426             : 
    2427             : 
    2428             : // pass the introspection on Demand
    2429       18345 : void SbUnoObject::doIntrospection()
    2430             : {
    2431       18345 :     if( !bNeedIntrospection )
    2432        9158 :         return;
    2433             : 
    2434       18345 :     Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
    2435             : 
    2436       18345 :     if (!xContext.is())
    2437           0 :         return;
    2438             : 
    2439             : 
    2440             :     // get the introspection service
    2441       27532 :     Reference<XIntrospection> xIntrospection;
    2442             : 
    2443             :     try
    2444             :     {
    2445       18345 :         xIntrospection = theIntrospection::get(xContext);
    2446             :     }
    2447           0 :     catch ( const css::uno::DeploymentException& )
    2448             :     {
    2449             :     }
    2450             : 
    2451       18345 :     if (!xIntrospection.is())
    2452           0 :         return;
    2453             : 
    2454       18345 :     bNeedIntrospection = false;
    2455             : 
    2456             :     // pass the introspection
    2457             :     try
    2458             :     {
    2459       18345 :         mxUnoAccess = xIntrospection->inspect( maTmpUnoObj );
    2460             :     }
    2461           0 :     catch( const RuntimeException& e )
    2462             :     {
    2463           0 :         StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
    2464             :     }
    2465             : 
    2466       18345 :     if( !mxUnoAccess.is() )
    2467             :     {
    2468             :         // #51475 mark to indicate an invalid object (no mxMaterialHolder)
    2469        9158 :         return;
    2470             :     }
    2471             : 
    2472             :     // get MaterialHolder from access
    2473        9187 :     mxMaterialHolder = Reference< XMaterialHolder >::query( mxUnoAccess );
    2474             : 
    2475             :     // get ExactName from access
    2476       18374 :     mxExactName = Reference< XExactName >::query( mxUnoAccess );
    2477             : }
    2478             : 
    2479             : 
    2480             : 
    2481             : 
    2482             : // Start of a list of all SbUnoMethod-Instances
    2483             : static SbUnoMethod* pFirst = NULL;
    2484             : 
    2485        2537 : void clearUnoMethodsForBasic( StarBASIC* pBasic )
    2486             : {
    2487        2537 :     SbUnoMethod* pMeth = pFirst;
    2488        5405 :     while( pMeth )
    2489             :     {
    2490         331 :         SbxObject* pObject = dynamic_cast< SbxObject* >( pMeth->GetParent() );
    2491         331 :         if ( pObject )
    2492             :         {
    2493         331 :             StarBASIC* pModBasic = dynamic_cast< StarBASIC* >( pObject->GetParent() );
    2494         331 :             if ( pModBasic == pBasic )
    2495             :             {
    2496             :                 // for now the solution is to remove the method from the list and to clear it,
    2497             :                 // but in case the element should be correctly transferred to another StarBASIC,
    2498             :                 // we should either set module parent to NULL without clearing it, or even
    2499             :                 // set the new StarBASIC as the parent of the module
    2500             :                 // pObject->SetParent( NULL );
    2501             : 
    2502          58 :                 if( pMeth == pFirst )
    2503          37 :                     pFirst = pMeth->pNext;
    2504          21 :                 else if( pMeth->pPrev )
    2505          21 :                     pMeth->pPrev->pNext = pMeth->pNext;
    2506          58 :                 if( pMeth->pNext )
    2507          32 :                     pMeth->pNext->pPrev = pMeth->pPrev;
    2508             : 
    2509          58 :                 pMeth->pPrev = NULL;
    2510          58 :                 pMeth->pNext = NULL;
    2511             : 
    2512          58 :                 pMeth->SbxValue::Clear();
    2513          58 :                 pObject->SbxValue::Clear();
    2514             : 
    2515             :                 // start from the beginning after object clearing, the cycle will end since the method is removed each time
    2516          58 :                 pMeth = pFirst;
    2517             :             }
    2518             :             else
    2519         273 :                 pMeth = pMeth->pNext;
    2520             :         }
    2521             :         else
    2522           0 :             pMeth = pMeth->pNext;
    2523             :     }
    2524        2537 : }
    2525             : 
    2526          70 : void clearUnoMethods()
    2527             : {
    2528          70 :     SbUnoMethod* pMeth = pFirst;
    2529         341 :     while( pMeth )
    2530             :     {
    2531         201 :         pMeth->SbxValue::Clear();
    2532         201 :         pMeth = pMeth->pNext;
    2533             :     }
    2534          70 : }
    2535             : 
    2536             : 
    2537        1295 : SbUnoMethod::SbUnoMethod
    2538             : (
    2539             :     const OUString& aName_,
    2540             :     SbxDataType eSbxType,
    2541             :     Reference< XIdlMethod > xUnoMethod_,
    2542             :     bool bInvocation,
    2543             :     bool bDirect
    2544             : )
    2545             :     : SbxMethod( aName_, eSbxType )
    2546             :     , mbInvocation( bInvocation )
    2547        1295 :     , mbDirectInvocation( bDirect )
    2548             : {
    2549        1295 :     m_xUnoMethod = xUnoMethod_;
    2550        1295 :     pParamInfoSeq = NULL;
    2551             : 
    2552             :     // enregister the method in a list
    2553        1295 :     pNext = pFirst;
    2554        1295 :     pPrev = NULL;
    2555        1295 :     pFirst = this;
    2556        1295 :     if( pNext )
    2557        1253 :         pNext->pPrev = this;
    2558        1295 : }
    2559             : 
    2560        5180 : SbUnoMethod::~SbUnoMethod()
    2561             : {
    2562        1295 :     delete pParamInfoSeq;
    2563             : 
    2564        1295 :     if( this == pFirst )
    2565         636 :         pFirst = pNext;
    2566         659 :     else if( pPrev )
    2567         601 :         pPrev->pNext = pNext;
    2568        1295 :     if( pNext )
    2569        1178 :         pNext->pPrev = pPrev;
    2570        3885 : }
    2571             : 
    2572          74 : SbxInfo* SbUnoMethod::GetInfo()
    2573             : {
    2574          74 :     if( !pInfo && m_xUnoMethod.is() )
    2575             :     {
    2576          58 :         SbiInstance* pInst = GetSbData()->pInst;
    2577          58 :         if( pInst && pInst->IsCompatibility() )
    2578             :         {
    2579          58 :             pInfo = new SbxInfo();
    2580             : 
    2581          58 :             const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
    2582          58 :             const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
    2583          58 :             sal_uInt32 nParamCount = rInfoSeq.getLength();
    2584             : 
    2585         309 :             for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
    2586             :             {
    2587         251 :                 const ParamInfo& rInfo = pParamInfos[i];
    2588         251 :                 OUString aParamName = rInfo.aName;
    2589             : 
    2590         251 :                 SbxDataType t = SbxVARIANT;
    2591         251 :                 SbxFlagBits nFlags_ = SBX_READ;
    2592         251 :                 pInfo->AddParam( aParamName, t, nFlags_ );
    2593         251 :             }
    2594             :         }
    2595             :     }
    2596          74 :     return pInfo;
    2597             : }
    2598             : 
    2599        2725 : const Sequence<ParamInfo>& SbUnoMethod::getParamInfos()
    2600             : {
    2601        2725 :     if (!pParamInfoSeq)
    2602             :     {
    2603        1295 :         Sequence<ParamInfo> aTmp;
    2604        1295 :         if (m_xUnoMethod.is())
    2605        1295 :             aTmp = m_xUnoMethod->getParameterInfos();
    2606        1295 :         pParamInfoSeq = new Sequence<ParamInfo>(aTmp);
    2607             :     }
    2608        2725 :     return *pParamInfoSeq;
    2609             : }
    2610             : 
    2611        1516 : SbUnoProperty::SbUnoProperty
    2612             : (
    2613             :     const OUString& aName_,
    2614             :     SbxDataType eSbxType,
    2615             :     SbxDataType eRealSbxType,
    2616             :     const Property& aUnoProp_,
    2617             :     sal_Int32 nId_,
    2618             :     bool bInvocation,
    2619             :     bool bUnoStruct
    2620             : )
    2621             :     : SbxProperty( aName_, eSbxType )
    2622             :     , aUnoProp( aUnoProp_ )
    2623             :     , nId( nId_ )
    2624             :     , mbInvocation( bInvocation )
    2625             :     , mRealType( eRealSbxType )
    2626        1516 :     , mbUnoStruct( bUnoStruct )
    2627             : {
    2628             :     // as needed establish an dummy array so that SbiRuntime::CheckArray() works
    2629        1516 :     static SbxArrayRef xDummyArray = new SbxArray( SbxVARIANT );
    2630        1516 :     if( eSbxType & SbxARRAY )
    2631           2 :         PutObject( xDummyArray );
    2632        1516 : }
    2633             : 
    2634        4548 : SbUnoProperty::~SbUnoProperty()
    2635        4548 : {}
    2636             : 
    2637             : 
    2638        3809 : SbxVariable* SbUnoObject::Find( const OUString& rName, SbxClassType t )
    2639             : {
    2640        3809 :     static Reference< XIdlMethod > xDummyMethod;
    2641        3809 :     static Property aDummyProp;
    2642             : 
    2643        3809 :     SbxVariable* pRes = SbxObject::Find( rName, t );
    2644             : 
    2645        3809 :     if( bNeedIntrospection )
    2646          66 :         doIntrospection();
    2647             : 
    2648             :     // New 1999-03-04: Create properties on demand. Therefore search now via
    2649             :     // IntrospectionAccess if a property or a method of the required name exist
    2650        3809 :     if( !pRes )
    2651             :     {
    2652        2970 :         OUString aUName( rName );
    2653        2970 :         if( mxUnoAccess.is() && !bNativeCOMObject )
    2654             :         {
    2655        2970 :             if( mxExactName.is() )
    2656             :             {
    2657        2970 :                 OUString aUExactName = mxExactName->getExactName( aUName );
    2658        2970 :                 if( !aUExactName.isEmpty() )
    2659             :                 {
    2660        2793 :                     aUName = aUExactName;
    2661        2970 :                 }
    2662             :             }
    2663        2970 :             if( mxUnoAccess->hasProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ) )
    2664             :             {
    2665        1498 :                 const Property& rProp = mxUnoAccess->
    2666        1498 :                     getProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS );
    2667             : 
    2668             :                 // If the property could be void the type had to be set to Variant
    2669             :                 SbxDataType eSbxType;
    2670        1498 :                 if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
    2671           1 :                     eSbxType = SbxVARIANT;
    2672             :                 else
    2673        1497 :                     eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
    2674             : 
    2675        1498 :                 SbxDataType eRealSbxType = ( ( rProp.Attributes & PropertyAttribute::MAYBEVOID ) ? unoToSbxType( rProp.Type.getTypeClass() ) : eSbxType );
    2676             :                 // create the property and superimpose it
    2677        1498 :                 SbUnoProperty* pProp = new SbUnoProperty( rProp.Name, eSbxType, eRealSbxType, rProp, 0, false, ( rProp.Type.getTypeClass() ==  com::sun::star::uno::TypeClass_STRUCT  ) );
    2678        2996 :                 SbxVariableRef xVarRef = pProp;
    2679        1498 :                 QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    2680        2996 :                 pRes = xVarRef;
    2681             :             }
    2682        2944 :             else if( mxUnoAccess->hasMethod( aUName,
    2683        1472 :                 MethodConcept::ALL - MethodConcept::DANGEROUS ) )
    2684             :             {
    2685             :                 // address the method
    2686        1295 :                 const Reference< XIdlMethod >& rxMethod = mxUnoAccess->
    2687        1295 :                     getMethod( aUName, MethodConcept::ALL - MethodConcept::DANGEROUS );
    2688             : 
    2689             :                 // create SbUnoMethod and superimpose it
    2690        2590 :                 SbxVariableRef xMethRef = new SbUnoMethod( rxMethod->getName(),
    2691        3885 :                     unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
    2692        1295 :                 QuickInsert( static_cast<SbxVariable*>(xMethRef) );
    2693        2590 :                 pRes = xMethRef;
    2694             :             }
    2695             : 
    2696             :             // If nothing was found check via XNameAccess
    2697        2970 :             if( !pRes )
    2698             :             {
    2699             :                 try
    2700             :                 {
    2701         177 :                     Reference< XNameAccess > xNameAccess( mxUnoAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()), UNO_QUERY );
    2702         354 :                     OUString aUName2( rName );
    2703             : 
    2704         177 :                     if( xNameAccess.is() && xNameAccess->hasByName( aUName2 ) )
    2705             :                     {
    2706           0 :                         Any aAny = xNameAccess->getByName( aUName2 );
    2707             : 
    2708             :                         // ATTENTION: Because of XNameAccess, the variable generated here
    2709             :                         // may not be included as a fixed property in the object and therefore
    2710             :                         // won't be stored anywhere.
    2711             :                         // If this leads to problems, it has to be created
    2712             :                         // synthetically or a class SbUnoNameAccessProperty,
    2713             :                         // witch checks the existence on access and which
    2714             :                         // is disposed if the name is not found anymore.
    2715           0 :                         pRes = new SbxVariable( SbxVARIANT );
    2716           0 :                         unoToSbxValue( pRes, aAny );
    2717         177 :                     }
    2718             :                 }
    2719           0 :                 catch( const NoSuchElementException& e )
    2720             :                 {
    2721           0 :                     StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
    2722             :                 }
    2723           0 :                 catch( const Exception& )
    2724             :                 {
    2725             :                     // Establish so that the exception error will not be overwritten
    2726           0 :                     if( !pRes )
    2727           0 :                         pRes = new SbxVariable( SbxVARIANT );
    2728             : 
    2729           0 :                     implHandleAnyException( ::cppu::getCaughtException() );
    2730             :                 }
    2731             :             }
    2732             :         }
    2733        2970 :         if( !pRes && mxInvocation.is() )
    2734             :         {
    2735          19 :             if( mxExactNameInvocation.is() )
    2736             :             {
    2737           0 :                 OUString aUExactName = mxExactNameInvocation->getExactName( aUName );
    2738           0 :                 if( !aUExactName.isEmpty() )
    2739             :                 {
    2740           0 :                     aUName = aUExactName;
    2741           0 :                 }
    2742             :             }
    2743             : 
    2744             :             try
    2745             :             {
    2746          19 :                 if( mxInvocation->hasProperty( aUName ) )
    2747             :                 {
    2748             :                     // create a property and superimpose it
    2749          12 :                     SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, SbxVARIANT, aDummyProp, 0, true, false );
    2750          12 :                     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    2751          12 :                     pRes = xVarRef;
    2752             :                 }
    2753           7 :                 else if( mxInvocation->hasMethod( aUName ) )
    2754             :                 {
    2755             :                     // create SbUnoMethode and superimpose it
    2756           0 :                     SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true );
    2757           0 :                     QuickInsert( static_cast<SbxVariable*>(xMethRef) );
    2758           0 :                     pRes = xMethRef;
    2759             :                 }
    2760             :                 else
    2761             :                 {
    2762           7 :                     Reference< XDirectInvocation > xDirectInvoke( mxInvocation, UNO_QUERY );
    2763           7 :                     if ( xDirectInvoke.is() && xDirectInvoke->hasMember( aUName ) )
    2764             :                     {
    2765           0 :                         SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true, true );
    2766           0 :                         QuickInsert( static_cast<SbxVariable*>(xMethRef) );
    2767           0 :                         pRes = xMethRef;
    2768           7 :                     }
    2769             : 
    2770             :                 }
    2771             :             }
    2772           0 :             catch( const RuntimeException& e )
    2773             :             {
    2774             :                 // Establish so that the exception error will not be overwritten
    2775           0 :                 if( !pRes )
    2776           0 :                     pRes = new SbxVariable( SbxVARIANT );
    2777             : 
    2778           0 :                 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
    2779             :             }
    2780        2970 :         }
    2781             :     }
    2782             : 
    2783             :     // At the very end checking if the Dbg_-Properties are meant
    2784             : 
    2785        3809 :     if( !pRes )
    2786             :     {
    2787         495 :         if( rName.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES) ||
    2788         330 :             rName.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES) ||
    2789         165 :             rName.equalsIgnoreAsciiCase(ID_DBG_METHODS) )
    2790             :         {
    2791             :             // Create
    2792           0 :             implCreateDbgProperties();
    2793             : 
    2794             :             // Now they have to be found regular
    2795           0 :             pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
    2796             :         }
    2797             :     }
    2798        3809 :     return pRes;
    2799             : }
    2800             : 
    2801             : 
    2802             : // help method to create the dbg_-Properties
    2803           0 : void SbUnoObject::implCreateDbgProperties()
    2804             : {
    2805           0 :     Property aProp;
    2806             : 
    2807             :     // Id == -1: display the implemented interfaces corresponding the ClassProvider
    2808           0 :     SbxVariableRef xVarRef = new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES), SbxSTRING, SbxSTRING, aProp, -1, false, false );
    2809           0 :     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    2810             : 
    2811             :     // Id == -2: output the properties
    2812           0 :     xVarRef = new SbUnoProperty( OUString(ID_DBG_PROPERTIES), SbxSTRING, SbxSTRING, aProp, -2, false, false );
    2813           0 :     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    2814             : 
    2815             :     // Id == -3: output the Methods
    2816           0 :     xVarRef = new SbUnoProperty( OUString(ID_DBG_METHODS), SbxSTRING, SbxSTRING, aProp, -3, false, false );
    2817           0 :     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    2818           0 : }
    2819             : 
    2820           0 : void SbUnoObject::implCreateAll()
    2821             : {
    2822             :     // throw away all existing methods and properties
    2823           0 :     pMethods   = new SbxArray;
    2824           0 :     pProps     = new SbxArray;
    2825             : 
    2826           0 :     if( bNeedIntrospection ) doIntrospection();
    2827             : 
    2828             :     // get introspection
    2829           0 :     Reference< XIntrospectionAccess > xAccess = mxUnoAccess;
    2830           0 :     if( !xAccess.is() || bNativeCOMObject )
    2831             :     {
    2832           0 :         if( mxInvocation.is() )
    2833           0 :             xAccess = mxInvocation->getIntrospection();
    2834           0 :         else if( bNativeCOMObject )
    2835           0 :             return;
    2836             :     }
    2837           0 :     if( !xAccess.is() )
    2838           0 :         return;
    2839             : 
    2840             :     // Establish properties
    2841           0 :     Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
    2842           0 :     sal_uInt32 nPropCount = props.getLength();
    2843           0 :     const Property* pProps_ = props.getConstArray();
    2844             : 
    2845             :     sal_uInt32 i;
    2846           0 :     for( i = 0 ; i < nPropCount ; i++ )
    2847             :     {
    2848           0 :         const Property& rProp = pProps_[ i ];
    2849             : 
    2850             :         // If the property could be void the type had to be set to Variant
    2851             :         SbxDataType eSbxType;
    2852           0 :         if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
    2853           0 :             eSbxType = SbxVARIANT;
    2854             :         else
    2855           0 :             eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
    2856             : 
    2857           0 :         SbxDataType eRealSbxType = ( ( rProp.Attributes & PropertyAttribute::MAYBEVOID ) ? unoToSbxType( rProp.Type.getTypeClass() ) : eSbxType );
    2858             :         // Create property and superimpose it
    2859           0 :         SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, eRealSbxType, rProp, i, false, ( rProp.Type.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT   ) );
    2860           0 :         QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    2861           0 :     }
    2862             : 
    2863             :     // Create Dbg_-Properties
    2864           0 :     implCreateDbgProperties();
    2865             : 
    2866             :     // Create methods
    2867           0 :     Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods
    2868           0 :         ( MethodConcept::ALL - MethodConcept::DANGEROUS );
    2869           0 :     sal_uInt32 nMethCount = aMethodSeq.getLength();
    2870           0 :     const Reference< XIdlMethod >* pMethods_ = aMethodSeq.getConstArray();
    2871           0 :     for( i = 0 ; i < nMethCount ; i++ )
    2872             :     {
    2873             :         // address method
    2874           0 :         const Reference< XIdlMethod >& rxMethod = pMethods_[i];
    2875             : 
    2876             :         // Create SbUnoMethod and superimpose it
    2877             :         SbxVariableRef xMethRef = new SbUnoMethod
    2878           0 :             ( rxMethod->getName(), unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
    2879           0 :         QuickInsert( static_cast<SbxVariable*>(xMethRef) );
    2880           0 :     }
    2881             : }
    2882             : 
    2883             : 
    2884             : // output the value
    2885       46771 : Any SbUnoObject::getUnoAny()
    2886             : {
    2887       46771 :     Any aRetAny;
    2888       46771 :     if( bNeedIntrospection ) doIntrospection();
    2889       46771 :     if ( maStructInfo.get() )
    2890         166 :        aRetAny = maTmpUnoObj;
    2891       46605 :     else if( mxMaterialHolder.is() )
    2892       31926 :         aRetAny = mxMaterialHolder->getMaterial();
    2893       14679 :     else if( mxInvocation.is() )
    2894           0 :         aRetAny <<= mxInvocation;
    2895       46771 :     return aRetAny;
    2896             : }
    2897             : 
    2898             : // help method to create an Uno-Struct per CoreReflection
    2899          57 : SbUnoObject* Impl_CreateUnoStruct( const OUString& aClassName )
    2900             : {
    2901             :     // get CoreReflection
    2902          57 :     Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
    2903          57 :     if( !xCoreReflection.is() )
    2904           0 :         return NULL;
    2905             : 
    2906             :     // search for the class
    2907         114 :     Reference< XIdlClass > xClass;
    2908             :     Reference< XHierarchicalNameAccess > xHarryName =
    2909         114 :         getCoreReflection_HierarchicalNameAccess_Impl();
    2910          57 :     if( xHarryName.is() && xHarryName->hasByHierarchicalName( aClassName ) )
    2911          57 :         xClass = xCoreReflection->forName( aClassName );
    2912          57 :     if( !xClass.is() )
    2913           0 :         return NULL;
    2914             : 
    2915             :     // Is it really a struct?
    2916          57 :     TypeClass eType = xClass->getTypeClass();
    2917          57 :     if ( ( eType != TypeClass_STRUCT ) && ( eType != TypeClass_EXCEPTION ) )
    2918           0 :         return NULL;
    2919             : 
    2920             :     // create an instance
    2921         114 :     Any aNewAny;
    2922          57 :     xClass->createObject( aNewAny );
    2923             :     // make a SbUnoObject out of it
    2924          57 :     SbUnoObject* pUnoObj = new SbUnoObject( aClassName, aNewAny );
    2925         114 :     return pUnoObj;
    2926             : }
    2927             : 
    2928             : 
    2929             : // Factory-Class to create Uno-Structs per DIM AS NEW
    2930           0 : SbxBase* SbUnoFactory::Create( sal_uInt16, sal_uInt32 )
    2931             : {
    2932             :     // Via SbxId nothing works in Uno
    2933           0 :     return NULL;
    2934             : }
    2935             : 
    2936          20 : SbxObject* SbUnoFactory::CreateObject( const OUString& rClassName )
    2937             : {
    2938          20 :     return Impl_CreateUnoStruct( rClassName );
    2939             : }
    2940             : 
    2941             : 
    2942             : // Provisional interface for the UNO-Connection
    2943             : // Deliver a SbxObject, that wrap an Uno-Interface
    2944       21934 : SbxObjectRef GetSbUnoObject( const OUString& aName, const Any& aUnoObj_ )
    2945             : {
    2946       21934 :     return new SbUnoObject( aName, aUnoObj_ );
    2947             : }
    2948             : 
    2949             : // Force creation of all properties for debugging
    2950           0 : void createAllObjectProperties( SbxObject* pObj )
    2951             : {
    2952           0 :     if( !pObj )
    2953           0 :         return;
    2954             : 
    2955           0 :     SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
    2956           0 :     SbUnoStructRefObject* pUnoStructObj = PTR_CAST(SbUnoStructRefObject,pObj);
    2957           0 :     if( pUnoObj )
    2958             :     {
    2959           0 :         pUnoObj->createAllProperties();
    2960             :     }
    2961           0 :     else if ( pUnoStructObj )
    2962             :     {
    2963           0 :         pUnoStructObj->createAllProperties();
    2964             :     }
    2965             : }
    2966             : 
    2967             : 
    2968          37 : void RTL_Impl_CreateUnoStruct( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    2969             : {
    2970             :     (void)pBasic;
    2971             :     (void)bWrite;
    2972             : 
    2973             :     // We need 1 parameter minimum
    2974          37 :     if ( rPar.Count() < 2 )
    2975             :     {
    2976           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    2977           0 :         return;
    2978             :     }
    2979             : 
    2980             :     // get the name of the class of the struct
    2981          37 :     OUString aClassName = rPar.Get(1)->GetOUString();
    2982             : 
    2983             :     // try to create Struct with the same name
    2984          74 :     SbUnoObjectRef xUnoObj = Impl_CreateUnoStruct( aClassName );
    2985          37 :     if( !xUnoObj )
    2986             :     {
    2987           0 :         return;
    2988             :     }
    2989             :     // return the object
    2990          74 :     SbxVariableRef refVar = rPar.Get(0);
    2991          74 :     refVar->PutObject( static_cast<SbUnoObject*>(xUnoObj) );
    2992             : }
    2993             : 
    2994          31 : void RTL_Impl_CreateUnoService( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    2995             : {
    2996             :     (void)pBasic;
    2997             :     (void)bWrite;
    2998             : 
    2999             :     // We need 1 Parameter minimum
    3000          31 :     if ( rPar.Count() < 2 )
    3001             :     {
    3002           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    3003          31 :         return;
    3004             :     }
    3005             : 
    3006             :     // get the name of the class of the struct
    3007          31 :     OUString aServiceName = rPar.Get(1)->GetOUString();
    3008             : 
    3009             :     // search for the service and instatiate it
    3010          62 :     Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
    3011          62 :     Reference< XInterface > xInterface;
    3012             :     try
    3013             :     {
    3014          31 :         xInterface = xFactory->createInstance( aServiceName );
    3015             :     }
    3016           0 :     catch( const Exception& )
    3017             :     {
    3018           0 :         implHandleAnyException( ::cppu::getCaughtException() );
    3019             :     }
    3020             : 
    3021          62 :     SbxVariableRef refVar = rPar.Get(0);
    3022          31 :     if( xInterface.is() )
    3023             :     {
    3024          30 :         Any aAny;
    3025          30 :         aAny <<= xInterface;
    3026             : 
    3027             :         // Create a SbUnoObject out of it and return it
    3028          60 :         SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
    3029          30 :         if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
    3030             :         {
    3031             :             // return the object
    3032          30 :             refVar->PutObject( static_cast<SbUnoObject*>(xUnoObj) );
    3033             :         }
    3034             :         else
    3035             :         {
    3036           0 :             refVar->PutObject( NULL );
    3037          30 :         }
    3038             :     }
    3039             :     else
    3040             :     {
    3041           1 :         refVar->PutObject( NULL );
    3042          31 :     }
    3043             : }
    3044             : 
    3045           0 : void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    3046             : {
    3047             :     (void)pBasic;
    3048             :     (void)bWrite;
    3049             : 
    3050             :     // We need 2 parameter minimum
    3051           0 :     if ( rPar.Count() < 3 )
    3052             :     {
    3053           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    3054           0 :         return;
    3055             :     }
    3056             : 
    3057             :     // get the name of the class of the struct
    3058           0 :     OUString aServiceName = rPar.Get(1)->GetOUString();
    3059           0 :     Any aArgAsAny = sbxToUnoValue( rPar.Get(2),
    3060           0 :                 cppu::UnoType<Sequence<Any>>::get() );
    3061           0 :     Sequence< Any > aArgs;
    3062           0 :     aArgAsAny >>= aArgs;
    3063             : 
    3064             :     // search for the service and instatiate it
    3065           0 :     Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
    3066           0 :     Reference< XInterface > xInterface;
    3067             :     try
    3068             :     {
    3069           0 :         xInterface = xFactory->createInstanceWithArguments( aServiceName, aArgs );
    3070             :     }
    3071           0 :     catch( const Exception& )
    3072             :     {
    3073           0 :         implHandleAnyException( ::cppu::getCaughtException() );
    3074             :     }
    3075             : 
    3076           0 :     SbxVariableRef refVar = rPar.Get(0);
    3077           0 :     if( xInterface.is() )
    3078             :     {
    3079           0 :         Any aAny;
    3080           0 :         aAny <<= xInterface;
    3081             : 
    3082             :         // Create a SbUnoObject out of it and return it
    3083           0 :         SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
    3084           0 :         if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
    3085             :         {
    3086             :             // return the object
    3087           0 :             refVar->PutObject( static_cast<SbUnoObject*>(xUnoObj) );
    3088             :         }
    3089             :         else
    3090             :         {
    3091           0 :             refVar->PutObject( NULL );
    3092           0 :         }
    3093             :     }
    3094             :     else
    3095             :     {
    3096           0 :         refVar->PutObject( NULL );
    3097           0 :     }
    3098             : }
    3099             : 
    3100           0 : void RTL_Impl_GetProcessServiceManager( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    3101             : {
    3102             :     (void)pBasic;
    3103             :     (void)bWrite;
    3104             : 
    3105           0 :     SbxVariableRef refVar = rPar.Get(0);
    3106             : 
    3107             :     // get the global service manager
    3108           0 :     Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
    3109           0 :     Any aAny;
    3110           0 :     aAny <<= xFactory;
    3111             : 
    3112             :     // Create a SbUnoObject out of it and return it
    3113           0 :     SbUnoObjectRef xUnoObj = new SbUnoObject( OUString( "ProcessServiceManager" ), aAny );
    3114           0 :     refVar->PutObject( static_cast<SbUnoObject*>(xUnoObj) );
    3115           0 : }
    3116             : 
    3117           0 : void RTL_Impl_HasInterfaces( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    3118             : {
    3119             :     (void)pBasic;
    3120             :     (void)bWrite;
    3121             : 
    3122             :     // We need 2 parameter minimum
    3123           0 :     sal_uInt16 nParCount = rPar.Count();
    3124           0 :     if( nParCount < 3 )
    3125             :     {
    3126           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    3127           0 :         return;
    3128             :     }
    3129             : 
    3130             :     // variable for the return value
    3131           0 :     SbxVariableRef refVar = rPar.Get(0);
    3132           0 :     refVar->PutBool( false );
    3133             : 
    3134             :     // get the Uno-Object
    3135           0 :     SbxBaseRef pObj = rPar.Get( 1 )->GetObject();
    3136           0 :     if( !(pObj && pObj->ISA(SbUnoObject)) )
    3137             :     {
    3138           0 :         return;
    3139             :     }
    3140           0 :     Any aAny = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj))->getUnoAny();
    3141           0 :     TypeClass eType = aAny.getValueType().getTypeClass();
    3142           0 :     if( eType != TypeClass_INTERFACE )
    3143             :     {
    3144           0 :         return;
    3145             :     }
    3146             :     // get the interface out of the Any
    3147           0 :     Reference< XInterface > x = *static_cast<Reference< XInterface > const *>(aAny.getValue());
    3148             : 
    3149             :     // get CoreReflection
    3150           0 :     Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
    3151           0 :     if( !xCoreReflection.is() )
    3152             :     {
    3153           0 :         return;
    3154             :     }
    3155           0 :     for( sal_uInt16 i = 2 ; i < nParCount ; i++ )
    3156             :     {
    3157             :         // get the name of the interface of the struct
    3158           0 :         OUString aIfaceName = rPar.Get( i )->GetOUString();
    3159             : 
    3160             :         // search for the class
    3161           0 :         Reference< XIdlClass > xClass = xCoreReflection->forName( aIfaceName );
    3162           0 :         if( !xClass.is() )
    3163             :         {
    3164           0 :             return;
    3165             :         }
    3166             :         // check if the interface will be supported
    3167           0 :         OUString aClassName = xClass->getName();
    3168           0 :         Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
    3169           0 :         if( !x->queryInterface( aClassType ).hasValue() )
    3170             :         {
    3171           0 :             return;
    3172             :         }
    3173           0 :     }
    3174             : 
    3175             :     // Every thing works; then return TRUE
    3176           0 :     refVar->PutBool( true );
    3177             : }
    3178             : 
    3179           0 : void RTL_Impl_IsUnoStruct( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    3180             : {
    3181             :     (void)pBasic;
    3182             :     (void)bWrite;
    3183             : 
    3184             :     // We need 1 parameter minimum
    3185           0 :     if ( rPar.Count() < 2 )
    3186             :     {
    3187           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    3188           0 :         return;
    3189             :     }
    3190             : 
    3191             :     // variable for the return value
    3192           0 :     SbxVariableRef refVar = rPar.Get(0);
    3193           0 :     refVar->PutBool( false );
    3194             : 
    3195             :     // get the Uno-Object
    3196           0 :     SbxVariableRef xParam = rPar.Get( 1 );
    3197           0 :     if( !xParam->IsObject() )
    3198             :     {
    3199           0 :         return;
    3200             :     }
    3201           0 :     SbxBaseRef pObj = rPar.Get( 1 )->GetObject();
    3202           0 :     if( !(pObj && pObj->ISA(SbUnoObject)) )
    3203             :     {
    3204           0 :         return;
    3205             :     }
    3206           0 :     Any aAny = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj))->getUnoAny();
    3207           0 :     TypeClass eType = aAny.getValueType().getTypeClass();
    3208           0 :     if( eType == TypeClass_STRUCT )
    3209             :     {
    3210           0 :         refVar->PutBool( true );
    3211           0 :     }
    3212             : }
    3213             : 
    3214             : 
    3215           0 : void RTL_Impl_EqualUnoObjects( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    3216             : {
    3217             :     (void)pBasic;
    3218             :     (void)bWrite;
    3219             : 
    3220           0 :     if ( rPar.Count() < 3 )
    3221             :     {
    3222           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    3223           0 :         return;
    3224             :     }
    3225             : 
    3226             :     // variable for the return value
    3227           0 :     SbxVariableRef refVar = rPar.Get(0);
    3228           0 :     refVar->PutBool( false );
    3229             : 
    3230             :     // get the Uno-Objects
    3231           0 :     SbxVariableRef xParam1 = rPar.Get( 1 );
    3232           0 :     if( !xParam1->IsObject() )
    3233             :     {
    3234           0 :         return;
    3235             :     }
    3236           0 :     SbxBaseRef pObj1 = xParam1->GetObject();
    3237           0 :     if( !(pObj1 && pObj1->ISA(SbUnoObject)) )
    3238             :     {
    3239           0 :         return;
    3240             :     }
    3241           0 :     Any aAny1 = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj1))->getUnoAny();
    3242           0 :     TypeClass eType1 = aAny1.getValueType().getTypeClass();
    3243           0 :     if( eType1 != TypeClass_INTERFACE )
    3244             :     {
    3245           0 :         return;
    3246             :     }
    3247           0 :     Reference< XInterface > x1;
    3248           0 :     aAny1 >>= x1;
    3249             : 
    3250           0 :     SbxVariableRef xParam2 = rPar.Get( 2 );
    3251           0 :     if( !xParam2->IsObject() )
    3252             :     {
    3253           0 :         return;
    3254             :     }
    3255           0 :     SbxBaseRef pObj2 = xParam2->GetObject();
    3256           0 :     if( !(pObj2 && pObj2->ISA(SbUnoObject)) )
    3257             :     {
    3258           0 :         return;
    3259             :     }
    3260           0 :     Any aAny2 = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj2))->getUnoAny();
    3261           0 :     TypeClass eType2 = aAny2.getValueType().getTypeClass();
    3262           0 :     if( eType2 != TypeClass_INTERFACE )
    3263             :     {
    3264           0 :         return;
    3265             :     }
    3266           0 :     Reference< XInterface > x2;
    3267           0 :     aAny2 >>= x2;
    3268             : 
    3269           0 :     if( x1 == x2 )
    3270             :     {
    3271           0 :         refVar->PutBool( true );
    3272           0 :     }
    3273             : }
    3274             : 
    3275             : 
    3276             : // helper wrapper function to interact with TypeProvider and
    3277             : // XTypeDescriptionEnumerationAccess.
    3278             : // if it fails for whatever reason
    3279             : // returned Reference<> be null e.g. .is() will be false
    3280             : 
    3281           2 : Reference< XTypeDescriptionEnumeration > getTypeDescriptorEnumeration( const OUString& sSearchRoot,
    3282             :                                                                        const Sequence< TypeClass >& types,
    3283             :                                                                        TypeDescriptionSearchDepth depth )
    3284             : {
    3285           2 :     Reference< XTypeDescriptionEnumeration > xEnum;
    3286           4 :     Reference< XTypeDescriptionEnumerationAccess> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY );
    3287           2 :     if ( xTypeEnumAccess.is() )
    3288             :     {
    3289             :         try
    3290             :         {
    3291           6 :             xEnum = xTypeEnumAccess->createTypeDescriptionEnumeration(
    3292           4 :                 sSearchRoot, types, depth );
    3293             :         }
    3294           0 :         catch(const NoSuchTypeNameException& /*nstne*/ ) {}
    3295           0 :         catch(const InvalidTypeNameException& /*nstne*/ ) {}
    3296             :     }
    3297           4 :     return xEnum;
    3298             : }
    3299             : 
    3300             : typedef std::unordered_map< OUString, Any, OUStringHash, ::std::equal_to< OUString > > VBAConstantsHash;
    3301             : 
    3302             : VBAConstantHelper&
    3303         272 : VBAConstantHelper::instance()
    3304             : {
    3305         272 :     static VBAConstantHelper aHelper;
    3306         272 :     return aHelper;
    3307             : }
    3308             : 
    3309         272 : void VBAConstantHelper::init()
    3310             : {
    3311         272 :     if ( !isInited )
    3312             :     {
    3313           2 :         Sequence< TypeClass > types(1);
    3314           2 :         types[ 0 ] = TypeClass_CONSTANTS;
    3315           4 :         Reference< XTypeDescriptionEnumeration > xEnum = getTypeDescriptorEnumeration( OUString(defaultNameSpace), types, TypeDescriptionSearchDepth_INFINITE  );
    3316             : 
    3317           2 :         if ( !xEnum.is())
    3318             :         {
    3319         272 :             return; //NULL;
    3320             :         }
    3321        1668 :         while ( xEnum->hasMoreElements() )
    3322             :         {
    3323        1664 :             Reference< XConstantsTypeDescription > xConstants( xEnum->nextElement(), UNO_QUERY );
    3324        1664 :             if ( xConstants.is() )
    3325             :             {
    3326             :                 // store constant group name
    3327        1664 :                 OUString sFullName = xConstants->getName();
    3328        1664 :                 sal_Int32 indexLastDot = sFullName.lastIndexOf('.');
    3329        3328 :                 OUString sLeafName( sFullName );
    3330        1664 :                 if ( indexLastDot > -1 )
    3331             :                 {
    3332        1664 :                     sLeafName = sFullName.copy( indexLastDot + 1);
    3333             :                 }
    3334        1664 :                 aConstCache.push_back( sLeafName ); // assume constant group names are unique
    3335        3328 :                 Sequence< Reference< XConstantTypeDescription > > aConsts = xConstants->getConstants();
    3336       18582 :                 for (sal_Int32 i = 0; i != aConsts.getLength(); ++i)
    3337             :                 {
    3338             :                     // store constant member name
    3339       16918 :                     sFullName = aConsts[i]->getName();
    3340       16918 :                     indexLastDot = sFullName.lastIndexOf('.');
    3341       16918 :                     sLeafName = sFullName;
    3342       16918 :                     if ( indexLastDot > -1 )
    3343             :                     {
    3344       16918 :                         sLeafName = sFullName.copy( indexLastDot + 1);
    3345             :                     }
    3346       16918 :                     aConstHash[ sLeafName.toAsciiLowerCase() ] = aConsts[i]->getConstantValue();
    3347        1664 :                 }
    3348             :             }
    3349        1664 :         }
    3350           4 :         isInited = true;
    3351             :     }
    3352             : }
    3353             : 
    3354             : bool
    3355         110 : VBAConstantHelper::isVBAConstantType( const OUString& rName )
    3356             : {
    3357         110 :     init();
    3358         110 :     bool bConstant = false;
    3359         110 :     OUString sKey( rName );
    3360         110 :     VBAConstantsVector::const_iterator it = aConstCache.begin();
    3361             : 
    3362       91630 :     for( ; it != aConstCache.end(); ++it )
    3363             :     {
    3364       91520 :         if( sKey.equalsIgnoreAsciiCase( *it ) )
    3365             :         {
    3366           0 :             bConstant = true;
    3367           0 :             break;
    3368             :         }
    3369             :     }
    3370         110 :     return bConstant;
    3371             : }
    3372             : 
    3373             : SbxVariable*
    3374         162 : VBAConstantHelper::getVBAConstant( const OUString& rName )
    3375             : {
    3376         162 :     SbxVariable* pConst = NULL;
    3377         162 :     init();
    3378             : 
    3379         162 :     OUString sKey( rName );
    3380             : 
    3381         162 :     VBAConstantsHash::const_iterator it = aConstHash.find( sKey.toAsciiLowerCase() );
    3382             : 
    3383         162 :     if ( it != aConstHash.end() )
    3384             :     {
    3385          93 :         pConst = new SbxVariable( SbxVARIANT );
    3386          93 :         pConst->SetName( rName );
    3387          93 :         unoToSbxValue( pConst, it->second );
    3388             :     }
    3389             : 
    3390         162 :     return pConst;
    3391             : }
    3392             : 
    3393             : // Function to search for a global identifier in the
    3394             : // UnoScope and to wrap it for Sbx
    3395         114 : SbUnoClass* findUnoClass( const OUString& rName )
    3396             : {
    3397             :     // #105550 Check if module exists
    3398         114 :     SbUnoClass* pUnoClass = NULL;
    3399             : 
    3400         114 :     Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    3401         114 :     if( xTypeAccess->hasByHierarchicalName( rName ) )
    3402             :     {
    3403           9 :         Any aRet = xTypeAccess->getByHierarchicalName( rName );
    3404          18 :         Reference< XTypeDescription > xTypeDesc;
    3405           9 :         aRet >>= xTypeDesc;
    3406             : 
    3407           9 :         if( xTypeDesc.is() )
    3408             :         {
    3409           9 :             TypeClass eTypeClass = xTypeDesc->getTypeClass();
    3410           9 :             if( eTypeClass == TypeClass_MODULE || eTypeClass == TypeClass_CONSTANTS )
    3411             :             {
    3412           9 :                 pUnoClass = new SbUnoClass( rName );
    3413             :             }
    3414           9 :         }
    3415             :     }
    3416         114 :     return pUnoClass;
    3417             : }
    3418             : 
    3419           9 : SbxVariable* SbUnoClass::Find( const OUString& rName, SbxClassType )
    3420             : {
    3421           9 :     SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_VARIABLE );
    3422             : 
    3423             :     // If nothing were located the submodule isn't known yet
    3424           9 :     if( !pRes )
    3425             :     {
    3426             :         // If it is already a class, ask for the field
    3427           9 :         if( m_xClass.is() )
    3428             :         {
    3429             :             // Is it a field(?)
    3430           0 :             OUString aUStr( rName );
    3431           0 :             Reference< XIdlField > xField = m_xClass->getField( aUStr );
    3432           0 :             Reference< XIdlClass > xClass;
    3433           0 :             if( xField.is() )
    3434             :             {
    3435             :                 try
    3436             :                 {
    3437           0 :                     Any aAny;
    3438           0 :                     aAny = xField->get( aAny );
    3439             : 
    3440             :                     // Convert to Sbx
    3441           0 :                     pRes = new SbxVariable( SbxVARIANT );
    3442           0 :                     pRes->SetName( rName );
    3443           0 :                     unoToSbxValue( pRes, aAny );
    3444             :                 }
    3445           0 :                 catch( const Exception& )
    3446             :                 {
    3447           0 :                     implHandleAnyException( ::cppu::getCaughtException() );
    3448             :                 }
    3449           0 :             }
    3450             :         }
    3451             :         else
    3452             :         {
    3453             :             // expand fully qualified name
    3454           9 :             OUString aNewName = GetName();
    3455           9 :             aNewName += ".";
    3456           9 :             aNewName += rName;
    3457             : 
    3458             :             // get CoreReflection
    3459          18 :             Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
    3460           9 :             if( xCoreReflection.is() )
    3461             :             {
    3462             :                 // Is it a constant?
    3463           9 :                 Reference< XHierarchicalNameAccess > xHarryName( xCoreReflection, UNO_QUERY );
    3464           9 :                 if( xHarryName.is() )
    3465             :                 {
    3466             :                     try
    3467             :                     {
    3468           9 :                         Any aValue = xHarryName->getByHierarchicalName( aNewName );
    3469           2 :                         TypeClass eType = aValue.getValueType().getTypeClass();
    3470             : 
    3471             :                         // Interface located? Then it is a class
    3472           2 :                         if( eType == TypeClass_INTERFACE )
    3473             :                         {
    3474           1 :                             Reference< XInterface > xIface = *static_cast<Reference< XInterface > const *>(aValue.getValue());
    3475           2 :                             Reference< XIdlClass > xClass( xIface, UNO_QUERY );
    3476           1 :                             if( xClass.is() )
    3477             :                             {
    3478           1 :                                 pRes = new SbxVariable( SbxVARIANT );
    3479           1 :                                 SbxObjectRef xWrapper = static_cast<SbxObject*>(new SbUnoClass( aNewName, xClass ));
    3480           1 :                                 pRes->PutObject( xWrapper );
    3481           1 :                             }
    3482             :                         }
    3483             :                         else
    3484             :                         {
    3485           1 :                             pRes = new SbxVariable( SbxVARIANT );
    3486           1 :                             unoToSbxValue( pRes, aValue );
    3487           2 :                         }
    3488             :                     }
    3489           7 :                     catch( const NoSuchElementException& )
    3490             :                     {
    3491             :                     }
    3492             :                 }
    3493             : 
    3494             :                 // Otherwise take it again as class
    3495           9 :                 if( !pRes )
    3496             :                 {
    3497           7 :                     SbUnoClass* pNewClass = findUnoClass( aNewName );
    3498           7 :                     if( pNewClass )
    3499             :                     {
    3500           7 :                         pRes = new SbxVariable( SbxVARIANT );
    3501           7 :                         SbxObjectRef xWrapper = static_cast<SbxObject*>(pNewClass);
    3502           7 :                         pRes->PutObject( xWrapper );
    3503             :                     }
    3504             :                 }
    3505             : 
    3506             :                 // An UNO service?
    3507           9 :                 if( !pRes )
    3508             :                 {
    3509           0 :                     SbUnoService* pUnoService = findUnoService( aNewName );
    3510           0 :                     if( pUnoService )
    3511             :                     {
    3512           0 :                         pRes = new SbxVariable( SbxVARIANT );
    3513           0 :                         SbxObjectRef xWrapper = static_cast<SbxObject*>(pUnoService);
    3514           0 :                         pRes->PutObject( xWrapper );
    3515             :                     }
    3516             :                 }
    3517             : 
    3518             :                 // An UNO singleton?
    3519           9 :                 if( !pRes )
    3520             :                 {
    3521           0 :                     SbUnoSingleton* pUnoSingleton = findUnoSingleton( aNewName );
    3522           0 :                     if( pUnoSingleton )
    3523             :                     {
    3524           0 :                         pRes = new SbxVariable( SbxVARIANT );
    3525           0 :                         SbxObjectRef xWrapper = static_cast<SbxObject*>(pUnoSingleton);
    3526           0 :                         pRes->PutObject( xWrapper );
    3527             :                     }
    3528           9 :                 }
    3529           9 :             }
    3530             :         }
    3531             : 
    3532           9 :         if( pRes )
    3533             :         {
    3534           9 :             pRes->SetName( rName );
    3535             : 
    3536             :             // Insert variable, so that it could be found later
    3537           9 :             QuickInsert( pRes );
    3538             : 
    3539             :             // Take us out as listener at once,
    3540             :             // the values are all constant
    3541           9 :             if( pRes->IsBroadcaster() )
    3542           9 :                 EndListening( pRes->GetBroadcaster(), true );
    3543             :         }
    3544             :     }
    3545           9 :     return pRes;
    3546             : }
    3547             : 
    3548             : 
    3549           0 : SbUnoService* findUnoService( const OUString& rName )
    3550             : {
    3551           0 :     SbUnoService* pSbUnoService = NULL;
    3552             : 
    3553           0 :     Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    3554           0 :     if( xTypeAccess->hasByHierarchicalName( rName ) )
    3555             :     {
    3556           0 :         Any aRet = xTypeAccess->getByHierarchicalName( rName );
    3557           0 :         Reference< XTypeDescription > xTypeDesc;
    3558           0 :         aRet >>= xTypeDesc;
    3559             : 
    3560           0 :         if( xTypeDesc.is() )
    3561             :         {
    3562           0 :             TypeClass eTypeClass = xTypeDesc->getTypeClass();
    3563           0 :             if( eTypeClass == TypeClass_SERVICE )
    3564             :             {
    3565           0 :                 Reference< XServiceTypeDescription2 > xServiceTypeDesc( xTypeDesc, UNO_QUERY );
    3566           0 :                 if( xServiceTypeDesc.is() )
    3567           0 :                     pSbUnoService = new SbUnoService( rName, xServiceTypeDesc );
    3568             :             }
    3569           0 :         }
    3570             :     }
    3571           0 :     return pSbUnoService;
    3572             : }
    3573             : 
    3574           0 : SbxVariable* SbUnoService::Find( const OUString& rName, SbxClassType )
    3575             : {
    3576           0 :     SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
    3577             : 
    3578           0 :     if( !pRes )
    3579             :     {
    3580             :         // If it is already a class ask for a field
    3581           0 :         if( m_bNeedsInit && m_xServiceTypeDesc.is() )
    3582             :         {
    3583           0 :             m_bNeedsInit = false;
    3584             : 
    3585           0 :             Sequence< Reference< XServiceConstructorDescription > > aSCDSeq = m_xServiceTypeDesc->getConstructors();
    3586           0 :             const Reference< XServiceConstructorDescription >* pCtorSeq = aSCDSeq.getConstArray();
    3587           0 :             int nCtorCount = aSCDSeq.getLength();
    3588           0 :             for( int i = 0 ; i < nCtorCount ; ++i )
    3589             :             {
    3590           0 :                 Reference< XServiceConstructorDescription > xCtor = pCtorSeq[i];
    3591             : 
    3592           0 :                 OUString aName( xCtor->getName() );
    3593           0 :                 if( aName.isEmpty() )
    3594             :                 {
    3595           0 :                     if( xCtor->isDefaultConstructor() )
    3596             :                     {
    3597           0 :                         aName = "create";
    3598             :                     }
    3599             :                 }
    3600             : 
    3601           0 :                 if( !aName.isEmpty() )
    3602             :                 {
    3603             :                     // Create and insert SbUnoServiceCtor
    3604           0 :                     SbxVariableRef xSbCtorRef = new SbUnoServiceCtor( aName, xCtor );
    3605           0 :                     QuickInsert( static_cast<SbxVariable*>(xSbCtorRef) );
    3606             :                 }
    3607           0 :             }
    3608           0 :             pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
    3609             :         }
    3610             :     }
    3611             : 
    3612           0 :     return pRes;
    3613             : }
    3614             : 
    3615           0 : void SbUnoService::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
    3616             :                            const SfxHint& rHint, const TypeId& rHintType )
    3617             : {
    3618           0 :     const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
    3619           0 :     if( pHint )
    3620             :     {
    3621           0 :         SbxVariable* pVar = pHint->GetVar();
    3622           0 :         SbxArray* pParams = pVar->GetParameters();
    3623           0 :         SbUnoServiceCtor* pUnoCtor = PTR_CAST(SbUnoServiceCtor,pVar);
    3624           0 :         if( pUnoCtor && pHint->GetId() == SBX_HINT_DATAWANTED )
    3625             :         {
    3626             :             // Parameter count -1 because of Param0 == this
    3627           0 :             sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
    3628           0 :             Sequence<Any> args;
    3629             : 
    3630           0 :             Reference< XServiceConstructorDescription > xCtor = pUnoCtor->getServiceCtorDesc();
    3631           0 :             Sequence< Reference< XParameter > > aParameterSeq = xCtor->getParameters();
    3632           0 :             const Reference< XParameter >* pParameterSeq = aParameterSeq.getConstArray();
    3633           0 :             sal_uInt32 nUnoParamCount = aParameterSeq.getLength();
    3634             : 
    3635             :             // Default: Ignore not needed parameters
    3636           0 :             bool bParameterError = false;
    3637             : 
    3638             :             // Is the last parameter a rest parameter?
    3639           0 :             bool bRestParameterMode = false;
    3640           0 :             if( nUnoParamCount > 0 )
    3641             :             {
    3642           0 :                 Reference< XParameter > xLastParam = pParameterSeq[ nUnoParamCount - 1 ];
    3643           0 :                 if( xLastParam.is() )
    3644             :                 {
    3645           0 :                     if( xLastParam->isRestParameter() )
    3646           0 :                         bRestParameterMode = true;
    3647           0 :                 }
    3648             :             }
    3649             : 
    3650             :             // Too many parameters with context as first parameter?
    3651           0 :             sal_uInt16 nSbxParameterOffset = 1;
    3652           0 :             sal_uInt16 nParameterOffsetByContext = 0;
    3653           0 :             Reference < XComponentContext > xFirstParamContext;
    3654           0 :             if( nParamCount > nUnoParamCount )
    3655             :             {
    3656             :                 // Check if first parameter is a context and use it
    3657             :                 // then in createInstanceWithArgumentsAndContext
    3658           0 :                 Any aArg0 = sbxToUnoValue( pParams->Get( nSbxParameterOffset ) );
    3659           0 :                 if( (aArg0 >>= xFirstParamContext) && xFirstParamContext.is() )
    3660           0 :                     nParameterOffsetByContext = 1;
    3661             :             }
    3662             : 
    3663           0 :             sal_uInt32 nEffectiveParamCount = nParamCount - nParameterOffsetByContext;
    3664           0 :             sal_uInt32 nAllocParamCount = nEffectiveParamCount;
    3665           0 :             if( nEffectiveParamCount > nUnoParamCount )
    3666             :             {
    3667           0 :                 if( !bRestParameterMode )
    3668             :                 {
    3669           0 :                     nEffectiveParamCount = nUnoParamCount;
    3670           0 :                     nAllocParamCount = nUnoParamCount;
    3671             :                 }
    3672             :             }
    3673             :             // Not enough parameters?
    3674           0 :             else if( nUnoParamCount > nEffectiveParamCount )
    3675             :             {
    3676             :                 // RestParameterMode only helps if one (the last) parameter is missing
    3677           0 :                 int nDiff = nUnoParamCount - nEffectiveParamCount;
    3678           0 :                 if( !bRestParameterMode || nDiff > 1 )
    3679             :                 {
    3680           0 :                     bParameterError = true;
    3681           0 :                     StarBASIC::Error( SbERR_NOT_OPTIONAL );
    3682             :                 }
    3683             :             }
    3684             : 
    3685           0 :             if( !bParameterError )
    3686             :             {
    3687           0 :                 bool bOutParams = false;
    3688           0 :                 if( nAllocParamCount > 0 )
    3689             :                 {
    3690           0 :                     args.realloc( nAllocParamCount );
    3691           0 :                     Any* pAnyArgs = args.getArray();
    3692           0 :                     for( sal_uInt32 i = 0 ; i < nEffectiveParamCount ; i++ )
    3693             :                     {
    3694           0 :                         sal_uInt16 iSbx = (sal_uInt16)(i + nSbxParameterOffset + nParameterOffsetByContext);
    3695             : 
    3696             :                         // bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
    3697           0 :                         Reference< XParameter > xParam;
    3698           0 :                         if( i < nUnoParamCount )
    3699             :                         {
    3700           0 :                             xParam = pParameterSeq[i];
    3701           0 :                             if( !xParam.is() )
    3702           0 :                                 continue;
    3703             : 
    3704           0 :                             Reference< XTypeDescription > xParamTypeDesc = xParam->getType();
    3705           0 :                             if( !xParamTypeDesc.is() )
    3706           0 :                                 continue;
    3707           0 :                             com::sun::star::uno::Type aType( xParamTypeDesc->getTypeClass(), xParamTypeDesc->getName() );
    3708             : 
    3709             :                             // sbx parameter needs offset 1
    3710           0 :                             pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ), aType );
    3711             : 
    3712             :                             // Check for out parameter if not already done
    3713           0 :                             if( !bOutParams )
    3714             :                             {
    3715           0 :                                 if( xParam->isOut() )
    3716           0 :                                     bOutParams = true;
    3717           0 :                             }
    3718             :                         }
    3719             :                         else
    3720             :                         {
    3721           0 :                             pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ) );
    3722             :                         }
    3723           0 :                     }
    3724             :                 }
    3725             : 
    3726             :                 // "Call" ctor using createInstanceWithArgumentsAndContext
    3727             :                 Reference < XComponentContext > xContext(
    3728           0 :                     xFirstParamContext.is()
    3729             :                     ? xFirstParamContext
    3730           0 :                     : comphelper::getProcessComponentContext() );
    3731           0 :                 Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
    3732             : 
    3733           0 :                 Any aRetAny;
    3734           0 :                 OUString aServiceName = GetName();
    3735           0 :                 Reference < XInterface > xRet;
    3736             :                 try
    3737             :                 {
    3738           0 :                     xRet = xServiceMgr->createInstanceWithArgumentsAndContext( aServiceName, args, xContext );
    3739             :                 }
    3740           0 :                 catch( const Exception& )
    3741             :                 {
    3742           0 :                     implHandleAnyException( ::cppu::getCaughtException() );
    3743             :                 }
    3744           0 :                 aRetAny <<= xRet;
    3745           0 :                 unoToSbxValue( pVar, aRetAny );
    3746             : 
    3747             :                 // Copy back out parameters?
    3748           0 :                 if( bOutParams )
    3749             :                 {
    3750           0 :                     const Any* pAnyArgs = args.getConstArray();
    3751             : 
    3752           0 :                     for( sal_uInt32 j = 0 ; j < nUnoParamCount ; j++ )
    3753             :                     {
    3754           0 :                         Reference< XParameter > xParam = pParameterSeq[j];
    3755           0 :                         if( !xParam.is() )
    3756           0 :                             continue;
    3757             : 
    3758           0 :                         if( xParam->isOut() )
    3759           0 :                             unoToSbxValue( pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
    3760           0 :                     }
    3761           0 :                 }
    3762           0 :             }
    3763             :         }
    3764             :         else
    3765           0 :             SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
    3766             :     }
    3767           0 : }
    3768             : 
    3769             : 
    3770             : 
    3771             : static SbUnoServiceCtor* pFirstCtor = NULL;
    3772             : 
    3773          70 : void clearUnoServiceCtors()
    3774             : {
    3775          70 :     SbUnoServiceCtor* pCtor = pFirstCtor;
    3776         140 :     while( pCtor )
    3777             :     {
    3778           0 :         pCtor->SbxValue::Clear();
    3779           0 :         pCtor = pCtor->pNext;
    3780             :     }
    3781          70 : }
    3782             : 
    3783           0 : SbUnoServiceCtor::SbUnoServiceCtor( const OUString& aName_, Reference< XServiceConstructorDescription > xServiceCtorDesc )
    3784             :     : SbxMethod( aName_, SbxOBJECT )
    3785             :     , m_xServiceCtorDesc( xServiceCtorDesc )
    3786           0 :     , pNext(0)
    3787             : {
    3788           0 : }
    3789             : 
    3790           0 : SbUnoServiceCtor::~SbUnoServiceCtor()
    3791             : {
    3792           0 : }
    3793             : 
    3794           0 : SbxInfo* SbUnoServiceCtor::GetInfo()
    3795             : {
    3796           0 :     SbxInfo* pRet = NULL;
    3797             : 
    3798           0 :     return pRet;
    3799             : }
    3800             : 
    3801             : 
    3802           0 : SbUnoSingleton* findUnoSingleton( const OUString& rName )
    3803             : {
    3804           0 :     SbUnoSingleton* pSbUnoSingleton = NULL;
    3805             : 
    3806           0 :     Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    3807           0 :     if( xTypeAccess->hasByHierarchicalName( rName ) )
    3808             :     {
    3809           0 :         Any aRet = xTypeAccess->getByHierarchicalName( rName );
    3810           0 :         Reference< XTypeDescription > xTypeDesc;
    3811           0 :         aRet >>= xTypeDesc;
    3812             : 
    3813           0 :         if( xTypeDesc.is() )
    3814             :         {
    3815           0 :             TypeClass eTypeClass = xTypeDesc->getTypeClass();
    3816           0 :             if( eTypeClass == TypeClass_SINGLETON )
    3817             :             {
    3818           0 :                 Reference< XSingletonTypeDescription > xSingletonTypeDesc( xTypeDesc, UNO_QUERY );
    3819           0 :                 if( xSingletonTypeDesc.is() )
    3820           0 :                     pSbUnoSingleton = new SbUnoSingleton( rName, xSingletonTypeDesc );
    3821             :             }
    3822           0 :         }
    3823             :     }
    3824           0 :     return pSbUnoSingleton;
    3825             : }
    3826             : 
    3827           0 : SbUnoSingleton::SbUnoSingleton( const OUString& aName_,
    3828             :     const Reference< XSingletonTypeDescription >& xSingletonTypeDesc )
    3829             :         : SbxObject( aName_ )
    3830           0 :         , m_xSingletonTypeDesc( xSingletonTypeDesc )
    3831             : {
    3832           0 :     SbxVariableRef xGetMethodRef = new SbxMethod( OUString( "get"  ), SbxOBJECT );
    3833           0 :     QuickInsert( static_cast<SbxVariable*>(xGetMethodRef) );
    3834           0 : }
    3835             : 
    3836           0 : void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
    3837             :                            const SfxHint& rHint, const TypeId& rHintType )
    3838             : {
    3839           0 :     const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
    3840           0 :     if( pHint )
    3841             :     {
    3842           0 :         SbxVariable* pVar = pHint->GetVar();
    3843           0 :         SbxArray* pParams = pVar->GetParameters();
    3844           0 :         sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
    3845           0 :         sal_uInt32 nAllowedParamCount = 1;
    3846             : 
    3847           0 :         Reference < XComponentContext > xContextToUse;
    3848           0 :         if( nParamCount > 0 )
    3849             :         {
    3850             :             // Check if first parameter is a context and use it then
    3851           0 :             Reference < XComponentContext > xFirstParamContext;
    3852           0 :             Any aArg1 = sbxToUnoValue( pParams->Get( 1 ) );
    3853           0 :             if( (aArg1 >>= xFirstParamContext) && xFirstParamContext.is() )
    3854           0 :                 xContextToUse = xFirstParamContext;
    3855             :         }
    3856             : 
    3857           0 :         if( !xContextToUse.is() )
    3858             :         {
    3859           0 :             xContextToUse = comphelper::getProcessComponentContext();
    3860           0 :             --nAllowedParamCount;
    3861             :         }
    3862             : 
    3863           0 :         if( nParamCount > nAllowedParamCount )
    3864             :         {
    3865           0 :             StarBASIC::Error( SbERR_BAD_ARGUMENT );
    3866           0 :             return;
    3867             :         }
    3868             : 
    3869           0 :         Any aRetAny;
    3870           0 :         if( xContextToUse.is() )
    3871             :         {
    3872           0 :             OUString aSingletonName( "/singletons/" );
    3873           0 :             aSingletonName += GetName();
    3874           0 :             Reference < XInterface > xRet;
    3875           0 :             xContextToUse->getValueByName( aSingletonName ) >>= xRet;
    3876           0 :             aRetAny <<= xRet;
    3877             :         }
    3878           0 :         unoToSbxValue( pVar, aRetAny );
    3879             :     }
    3880             :     else
    3881             :     {
    3882           0 :         SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
    3883             :     }
    3884             : }
    3885             : 
    3886             : 
    3887             : 
    3888             : 
    3889             : // Implementation of an EventAttacher-drawn AllListener, which
    3890             : // solely transmits several events to an general AllListener
    3891             : class BasicAllListener_Impl : public BasicAllListenerHelper
    3892             : {
    3893             :     void firing_impl(const AllEventObject& Event, Any* pRet);
    3894             : 
    3895             : public:
    3896             :     SbxObjectRef    xSbxObj;
    3897             :     OUString        aPrefixName;
    3898             : 
    3899             :     explicit BasicAllListener_Impl( const OUString& aPrefixName );
    3900             :     virtual ~BasicAllListener_Impl();
    3901             : 
    3902             :     // Methods of XAllListener
    3903             :     virtual void SAL_CALL firing(const AllEventObject& Event) throw ( RuntimeException, std::exception ) SAL_OVERRIDE;
    3904             :     virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw ( RuntimeException, std::exception ) SAL_OVERRIDE;
    3905             : 
    3906             :     // Methods of XEventListener
    3907             :     virtual void SAL_CALL disposing(const EventObject& Source) throw ( RuntimeException, std::exception ) SAL_OVERRIDE;
    3908             : };
    3909             : 
    3910             : 
    3911             : 
    3912           6 : BasicAllListener_Impl::BasicAllListener_Impl(const OUString& aPrefixName_)
    3913           6 :     : aPrefixName( aPrefixName_ )
    3914             : {
    3915           6 : }
    3916             : 
    3917             : 
    3918           0 : BasicAllListener_Impl::~BasicAllListener_Impl()
    3919             : {
    3920           0 : }
    3921             : 
    3922             : 
    3923             : 
    3924          18 : void BasicAllListener_Impl::firing_impl( const AllEventObject& Event, Any* pRet )
    3925             : {
    3926          18 :     SolarMutexGuard guard;
    3927             : 
    3928          18 :     if( xSbxObj.Is() )
    3929             :     {
    3930          18 :         OUString aMethodName = aPrefixName;
    3931          18 :         aMethodName = aMethodName + Event.MethodName;
    3932             : 
    3933          18 :         SbxVariable * pP = xSbxObj;
    3934          18 :         while( pP->GetParent() )
    3935             :         {
    3936          18 :             pP = pP->GetParent();
    3937          18 :             StarBASIC * pLib = PTR_CAST(StarBASIC,pP);
    3938          18 :             if( pLib )
    3939             :             {
    3940             :                 // Create in a Basic Array
    3941          18 :                 SbxArrayRef xSbxArray = new SbxArray( SbxVARIANT );
    3942          18 :                 const Any * pArgs = Event.Arguments.getConstArray();
    3943          18 :                 sal_Int32 nCount = Event.Arguments.getLength();
    3944          42 :                 for( sal_Int32 i = 0; i < nCount; i++ )
    3945             :                 {
    3946             :                     // Convert elements
    3947          24 :                     SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
    3948          24 :                     unoToSbxValue( static_cast<SbxVariable*>(xVar), pArgs[i] );
    3949          24 :                     xSbxArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
    3950          24 :                 }
    3951             : 
    3952          18 :                 pLib->Call( aMethodName, xSbxArray );
    3953             : 
    3954             :                 // get the return value from the Param-Array, if requested
    3955          18 :                 if( pRet )
    3956             :                 {
    3957          12 :                     SbxVariable* pVar = xSbxArray->Get( 0 );
    3958          12 :                     if( pVar )
    3959             :                     {
    3960             :                         // #95792 Avoid a second call
    3961          12 :                         SbxFlagBits nFlags = pVar->GetFlags();
    3962          12 :                         pVar->SetFlag( SBX_NO_BROADCAST );
    3963          12 :                         *pRet = sbxToUnoValueImpl( pVar );
    3964          12 :                         pVar->SetFlags( nFlags );
    3965             :                     }
    3966             :                 }
    3967          18 :                 break;
    3968             :             }
    3969          18 :         }
    3970          18 :     }
    3971          18 : }
    3972             : 
    3973             : 
    3974             : // Methods of Listener
    3975           6 : void BasicAllListener_Impl::firing( const AllEventObject& Event ) throw ( RuntimeException, std::exception )
    3976             : {
    3977           6 :     firing_impl( Event, NULL );
    3978           6 : }
    3979             : 
    3980          12 : Any BasicAllListener_Impl::approveFiring( const AllEventObject& Event ) throw ( RuntimeException, std::exception )
    3981             : {
    3982          12 :     Any aRetAny;
    3983          12 :     firing_impl( Event, &aRetAny );
    3984          12 :     return aRetAny;
    3985             : }
    3986             : 
    3987             : 
    3988             : // Methods of XEventListener
    3989           0 : void BasicAllListener_Impl ::disposing(const EventObject& ) throw ( RuntimeException, std::exception )
    3990             : {
    3991           0 :     SolarMutexGuard guard;
    3992             : 
    3993           0 :     xSbxObj.Clear();
    3994           0 : }
    3995             : 
    3996             : 
    3997             : 
    3998             : 
    3999             : //  class InvocationToAllListenerMapper
    4000             : //  helper class to map XInvocation to XAllListener (also in project eventattacher!)
    4001             : 
    4002           0 : class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
    4003             : {
    4004             : public:
    4005             :     InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
    4006             :         const Reference< XAllListener >& AllListener, const Any& Helper );
    4007             : 
    4008             :     // XInvocation
    4009             :     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
    4010             :     virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
    4011             :         throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
    4012             :     virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value)
    4013             :         throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
    4014             :     virtual Any SAL_CALL getValue(const OUString& PropertyName) throw( UnknownPropertyException, RuntimeException, std::exception ) SAL_OVERRIDE;
    4015             :     virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
    4016             :     virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
    4017             : 
    4018             : private:
    4019             :     Reference< XIdlReflection >  m_xCoreReflection;
    4020             :     Reference< XAllListener >    m_xAllListener;
    4021             :     Reference< XIdlClass >       m_xListenerType;
    4022             :     Any                          m_Helper;
    4023             : };
    4024             : 
    4025             : 
    4026             : // Function to replace AllListenerAdapterService::createAllListerAdapter
    4027           6 : Reference< XInterface > createAllListenerAdapter
    4028             : (
    4029             :     const Reference< XInvocationAdapterFactory2 >& xInvocationAdapterFactory,
    4030             :     const Reference< XIdlClass >& xListenerType,
    4031             :     const Reference< XAllListener >& xListener,
    4032             :     const Any& Helper
    4033             : )
    4034             : {
    4035           6 :     Reference< XInterface > xAdapter;
    4036           6 :     if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
    4037             :     {
    4038             :         Reference< XInvocation > xInvocationToAllListenerMapper =
    4039           6 :             static_cast<XInvocation*>(new InvocationToAllListenerMapper( xListenerType, xListener, Helper ));
    4040          12 :         Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName() );
    4041          12 :         Sequence<Type> arg2(1);
    4042           6 :         arg2[0] = aListenerType;
    4043          12 :         xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, arg2 );
    4044             :     }
    4045           6 :     return xAdapter;
    4046             : }
    4047             : 
    4048             : 
    4049             : 
    4050             : // InvocationToAllListenerMapper
    4051           6 : InvocationToAllListenerMapper::InvocationToAllListenerMapper
    4052             :     ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
    4053             :         : m_xAllListener( AllListener )
    4054             :         , m_xListenerType( ListenerType )
    4055           6 :         , m_Helper( Helper )
    4056             : {
    4057           6 : }
    4058             : 
    4059             : 
    4060           0 : Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection()
    4061             :     throw( RuntimeException, std::exception )
    4062             : {
    4063           0 :     return Reference< XIntrospectionAccess >();
    4064             : }
    4065             : 
    4066             : 
    4067          18 : Any SAL_CALL InvocationToAllListenerMapper::invoke(const OUString& FunctionName, const Sequence< Any >& Params,
    4068             :     Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
    4069             :         throw( IllegalArgumentException, CannotConvertException,
    4070             :         InvocationTargetException, RuntimeException, std::exception )
    4071             : {
    4072             :     (void)OutParamIndex;
    4073             :     (void)OutParam     ;
    4074             : 
    4075          18 :     Any aRet;
    4076             : 
    4077             :     // Check if to firing or approveFiring has to be called
    4078          36 :     Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
    4079          18 :     bool bApproveFiring = false;
    4080          18 :     if( !xMethod.is() )
    4081           0 :         return aRet;
    4082          36 :     Reference< XIdlClass > xReturnType = xMethod->getReturnType();
    4083          36 :     Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
    4084          36 :     if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
    4085          18 :         aExceptionSeq.getLength() > 0 )
    4086             :     {
    4087          12 :         bApproveFiring = true;
    4088             :     }
    4089             :     else
    4090             :     {
    4091           6 :         Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
    4092           6 :         sal_uInt32 nParamCount = aParamSeq.getLength();
    4093           6 :         if( nParamCount > 1 )
    4094             :         {
    4095           0 :             const ParamInfo* pInfos = aParamSeq.getConstArray();
    4096           0 :             for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
    4097             :             {
    4098           0 :                 if( pInfos[ i ].aMode != ParamMode_IN )
    4099             :                 {
    4100           0 :                     bApproveFiring = true;
    4101           0 :                     break;
    4102             :                 }
    4103             :             }
    4104           6 :         }
    4105             :     }
    4106             : 
    4107          36 :     AllEventObject aAllEvent;
    4108          18 :     aAllEvent.Source = static_cast<OWeakObject*>(this);
    4109          18 :     aAllEvent.Helper = m_Helper;
    4110          18 :     aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName() );
    4111          18 :     aAllEvent.MethodName = FunctionName;
    4112          18 :     aAllEvent.Arguments = Params;
    4113          18 :     if( bApproveFiring )
    4114          12 :         aRet = m_xAllListener->approveFiring( aAllEvent );
    4115             :     else
    4116           6 :         m_xAllListener->firing( aAllEvent );
    4117          18 :     return aRet;
    4118             : }
    4119             : 
    4120             : 
    4121           0 : void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& PropertyName, const Any& Value)
    4122             :     throw( UnknownPropertyException, CannotConvertException,
    4123             :            InvocationTargetException, RuntimeException, std::exception )
    4124             : {
    4125             :     (void)PropertyName;
    4126             :     (void)Value;
    4127           0 : }
    4128             : 
    4129             : 
    4130           0 : Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& PropertyName)
    4131             :     throw( UnknownPropertyException, RuntimeException, std::exception )
    4132             : {
    4133             :     (void)PropertyName;
    4134             : 
    4135           0 :     return Any();
    4136             : }
    4137             : 
    4138             : 
    4139           0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name)
    4140             :     throw( RuntimeException, std::exception )
    4141             : {
    4142           0 :     Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
    4143           0 :     return xMethod.is();
    4144             : }
    4145             : 
    4146             : 
    4147           0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name)
    4148             :     throw( RuntimeException, std::exception )
    4149             : {
    4150           0 :     Reference< XIdlField > xField = m_xListenerType->getField( Name );
    4151           0 :     return xField.is();
    4152             : }
    4153             : 
    4154             : 
    4155             : // create Uno-Service
    4156             : // 1. Parameter == Prefix-Name of the macro
    4157             : // 2. Parameter == fully qualified name of the listener
    4158           6 : void SbRtl_CreateUnoListener( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    4159             : //RTLFUNC(CreateUnoListener)
    4160             : {
    4161             :     (void)bWrite;
    4162             : 
    4163             :     // We need 2 parameters
    4164           6 :     if ( rPar.Count() != 3 )
    4165             :     {
    4166           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    4167           0 :         return;
    4168             :     }
    4169             : 
    4170             :     // get the name of the class of the struct
    4171           6 :     OUString aPrefixName = rPar.Get(1)->GetOUString();
    4172          12 :     OUString aListenerClassName = rPar.Get(2)->GetOUString();
    4173             : 
    4174             :     // get the CoreReflection
    4175          12 :     Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
    4176           6 :     if( !xCoreReflection.is() )
    4177           0 :         return;
    4178             : 
    4179             :     // get the AllListenerAdapterService
    4180          12 :     Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
    4181             : 
    4182             :     // search the class
    4183          12 :     Reference< XIdlClass > xClass = xCoreReflection->forName( aListenerClassName );
    4184           6 :     if( !xClass.is() )
    4185           0 :         return;
    4186             : 
    4187             :     // From 1999-11-30: get the InvocationAdapterFactory
    4188             :     Reference< XInvocationAdapterFactory2 > xInvocationAdapterFactory =
    4189          12 :          InvocationAdapterFactory::create( xContext );
    4190             : 
    4191             :     BasicAllListener_Impl * p;
    4192          12 :     Reference< XAllListener > xAllLst = p = new BasicAllListener_Impl( aPrefixName );
    4193          12 :     Any aTmp;
    4194          12 :     Reference< XInterface > xLst = createAllListenerAdapter( xInvocationAdapterFactory, xClass, xAllLst, aTmp );
    4195           6 :     if( !xLst.is() )
    4196           0 :         return;
    4197             : 
    4198          12 :     OUString aClassName = xClass->getName();
    4199          12 :     Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
    4200           6 :     aTmp = xLst->queryInterface( aClassType );
    4201           6 :     if( !aTmp.hasValue() )
    4202           0 :         return;
    4203             : 
    4204           6 :     SbUnoObject* pUnoObj = new SbUnoObject( aListenerClassName, aTmp );
    4205           6 :     p->xSbxObj = pUnoObj;
    4206           6 :     p->xSbxObj->SetParent( pBasic );
    4207             : 
    4208             :     // #100326 Register listener object to set Parent NULL in Dtor
    4209          12 :     SbxArrayRef xBasicUnoListeners = pBasic->getUnoListeners();
    4210           6 :     xBasicUnoListeners->Insert( pUnoObj, xBasicUnoListeners->Count() );
    4211             : 
    4212             :     // return the object
    4213          12 :     SbxVariableRef refVar = rPar.Get(0);
    4214          12 :     refVar->PutObject( p->xSbxObj );
    4215             : }
    4216             : 
    4217             : 
    4218             : // Represents the DefaultContext property of the ProcessServiceManager
    4219             : // in the Basic runtime system.
    4220           1 : void RTL_Impl_GetDefaultContext( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    4221             : {
    4222             :     (void)pBasic;
    4223             :     (void)bWrite;
    4224             : 
    4225           1 :     SbxVariableRef refVar = rPar.Get(0);
    4226             : 
    4227           2 :     Any aContextAny( comphelper::getProcessComponentContext() );
    4228             : 
    4229           2 :     SbUnoObjectRef xUnoObj = new SbUnoObject( OUString( "DefaultContext" ), aContextAny );
    4230           2 :     refVar->PutObject( static_cast<SbUnoObject*>(xUnoObj) );
    4231           1 : }
    4232             : 
    4233             : 
    4234             : // Creates a Basic wrapper object for a strongly typed Uno value
    4235             : // 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
    4236           0 : void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
    4237             : {
    4238             :     (void)pBasic;
    4239             :     (void)bWrite;
    4240             : 
    4241             :     static const char aTypeTypeString[] = "type";
    4242             : 
    4243             :     // 2 parameters needed
    4244           0 :     if ( rPar.Count() != 3 )
    4245             :     {
    4246           0 :         StarBASIC::Error( SbERR_BAD_ARGUMENT );
    4247           0 :         return;
    4248             :     }
    4249             : 
    4250             :     // get the name of the class of the struct
    4251           0 :     OUString aTypeName = rPar.Get(1)->GetOUString();
    4252           0 :     SbxVariable* pVal = rPar.Get(2);
    4253             : 
    4254           0 :     if( aTypeName == aTypeTypeString )
    4255             :     {
    4256           0 :         SbxDataType eBaseType = pVal->SbxValue::GetType();
    4257           0 :         OUString aValTypeName;
    4258           0 :         if( eBaseType == SbxSTRING )
    4259             :         {
    4260           0 :             aValTypeName = pVal->GetOUString();
    4261             :         }
    4262           0 :         else if( eBaseType == SbxOBJECT )
    4263             :         {
    4264             :             // XIdlClass?
    4265           0 :             Reference< XIdlClass > xIdlClass;
    4266             : 
    4267           0 :             SbxBaseRef pObj = pVal->GetObject();
    4268           0 :             if( pObj && pObj->ISA(SbUnoObject) )
    4269             :             {
    4270           0 :                 Any aUnoAny = static_cast<SbUnoObject*>(static_cast<SbxBase*>(pObj))->getUnoAny();
    4271           0 :                 aUnoAny >>= xIdlClass;
    4272             :             }
    4273             : 
    4274           0 :             if( xIdlClass.is() )
    4275             :             {
    4276           0 :                 aValTypeName = xIdlClass->getName();
    4277           0 :             }
    4278             :         }
    4279           0 :         Type aType;
    4280           0 :         bool bSuccess = implGetTypeByName( aValTypeName, aType );
    4281           0 :         if( bSuccess )
    4282             :         {
    4283           0 :             Any aTypeAny( aType );
    4284           0 :             SbxVariableRef refVar = rPar.Get(0);
    4285           0 :             SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aTypeAny );
    4286           0 :             refVar->PutObject( xUnoAnyObject );
    4287             :         }
    4288           0 :         return;
    4289             :     }
    4290             : 
    4291             :     // Check the type
    4292           0 :     Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    4293           0 :     Any aRet;
    4294             :     try
    4295             :     {
    4296           0 :         aRet = xTypeAccess->getByHierarchicalName( aTypeName );
    4297             :     }
    4298           0 :     catch( const NoSuchElementException& e1 )
    4299             :     {
    4300           0 :         OUString aNoSuchElementExceptionName( "com.sun.star.container.NoSuchElementException"  );
    4301             :         StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
    4302           0 :             implGetExceptionMsg( e1, aNoSuchElementExceptionName ) );
    4303           0 :         return;
    4304             :     }
    4305           0 :     Reference< XTypeDescription > xTypeDesc;
    4306           0 :     aRet >>= xTypeDesc;
    4307           0 :     TypeClass eTypeClass = xTypeDesc->getTypeClass();
    4308           0 :     Type aDestType( eTypeClass, aTypeName );
    4309             : 
    4310             : 
    4311             :     // Preconvert value
    4312           0 :     Any aVal = sbxToUnoValueImpl( pVal );
    4313           0 :     Any aConvertedVal = convertAny( aVal, aDestType );
    4314             : 
    4315           0 :     SbxVariableRef refVar = rPar.Get(0);
    4316           0 :     SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aConvertedVal );
    4317           0 :     refVar->PutObject( xUnoAnyObject );
    4318             : }
    4319             : 
    4320             : 
    4321             : 
    4322             : namespace {
    4323           0 : class OMutexBasis
    4324             : {
    4325             : protected:
    4326             :     // this mutex is necessary for OInterfaceContainerHelper
    4327             :     ::osl::Mutex m_aMutex;
    4328             : };
    4329             : } // namespace
    4330             : 
    4331             : typedef WeakImplHelper2< XInvocation, XComponent > ModuleInvocationProxyHelper;
    4332             : 
    4333             : class ModuleInvocationProxy : public OMutexBasis,
    4334             :                               public ModuleInvocationProxyHelper
    4335             : {
    4336             :     OUString            m_aPrefix;
    4337             :     SbxObjectRef        m_xScopeObj;
    4338             :     bool                m_bProxyIsClassModuleObject;
    4339             : 
    4340             :     ::cppu::OInterfaceContainerHelper m_aListeners;
    4341             : 
    4342             : public:
    4343             :     ModuleInvocationProxy( const OUString& aPrefix, SbxObjectRef xScopeObj );
    4344           0 :     virtual ~ModuleInvocationProxy()
    4345           0 :     {}
    4346             : 
    4347             :     // XInvocation
    4348             :     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw(std::exception) SAL_OVERRIDE;
    4349             :     virtual void SAL_CALL setValue( const OUString& rProperty, const Any& rValue )
    4350             :         throw (UnknownPropertyException, RuntimeException, std::exception) SAL_OVERRIDE;
    4351             :     virtual Any SAL_CALL getValue( const OUString& rProperty )
    4352             :         throw (UnknownPropertyException, RuntimeException, std::exception) SAL_OVERRIDE;
    4353             :     virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw(std::exception) SAL_OVERRIDE;
    4354             :     virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw(std::exception) SAL_OVERRIDE;
    4355             : 
    4356             :     virtual Any SAL_CALL invoke( const OUString& rFunction,
    4357             :                                  const Sequence< Any >& rParams,
    4358             :                                  Sequence< sal_Int16 >& rOutParamIndex,
    4359             :                                  Sequence< Any >& rOutParam )
    4360             :         throw (CannotConvertException, InvocationTargetException,
    4361             :                RuntimeException, std::exception ) SAL_OVERRIDE;
    4362             : 
    4363             :     // XComponent
    4364             :     virtual void SAL_CALL dispose() throw(RuntimeException, std::exception) SAL_OVERRIDE;
    4365             :     virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    4366             :     virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    4367             : };
    4368             : 
    4369           0 : ModuleInvocationProxy::ModuleInvocationProxy( const OUString& aPrefix, SbxObjectRef xScopeObj )
    4370           0 :     : m_aPrefix( aPrefix + "_" )
    4371             :     , m_xScopeObj( xScopeObj )
    4372           0 :     , m_aListeners( m_aMutex )
    4373             : {
    4374           0 :     m_bProxyIsClassModuleObject = xScopeObj.Is() && xScopeObj->ISA(SbClassModuleObject);
    4375           0 : }
    4376             : 
    4377           0 : Reference< XIntrospectionAccess > SAL_CALL ModuleInvocationProxy::getIntrospection() throw(std::exception)
    4378             : {
    4379           0 :     return Reference< XIntrospectionAccess >();
    4380             : }
    4381             : 
    4382           0 : void SAL_CALL ModuleInvocationProxy::setValue(const OUString& rProperty, const Any& rValue)
    4383             :     throw (UnknownPropertyException, RuntimeException, std::exception)
    4384             : {
    4385           0 :     if( !m_bProxyIsClassModuleObject )
    4386           0 :         throw UnknownPropertyException();
    4387             : 
    4388           0 :     SolarMutexGuard guard;
    4389             : 
    4390           0 :     OUString aPropertyFunctionName( "Property Set " );
    4391           0 :     aPropertyFunctionName += m_aPrefix;
    4392           0 :     aPropertyFunctionName += rProperty;
    4393             : 
    4394           0 :     SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
    4395           0 :     SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
    4396           0 :     if( pMeth == NULL )
    4397             :     {
    4398             :         // TODO: Check vba behavior concernig missing function
    4399             :         //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
    4400           0 :         throw UnknownPropertyException();
    4401             :     }
    4402             : 
    4403             :     // Setup parameter
    4404           0 :     SbxArrayRef xArray = new SbxArray;
    4405           0 :     SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
    4406           0 :     unoToSbxValue( static_cast<SbxVariable*>(xVar), rValue );
    4407           0 :     xArray->Put( xVar, 1 );
    4408             : 
    4409             :     // Call property method
    4410           0 :     SbxVariableRef xValue = new SbxVariable;
    4411           0 :     pMeth->SetParameters( xArray );
    4412           0 :     pMeth->Call( xValue );
    4413           0 :     pMeth->SetParameters( NULL );
    4414             : 
    4415             :     // TODO: OutParameter?
    4416             : 
    4417             : 
    4418             : 
    4419           0 : }
    4420             : 
    4421           0 : Any SAL_CALL ModuleInvocationProxy::getValue(const OUString& rProperty)
    4422             :     throw (UnknownPropertyException, RuntimeException, std::exception)
    4423             : {
    4424           0 :     if( !m_bProxyIsClassModuleObject )
    4425             :     {
    4426           0 :         throw UnknownPropertyException();
    4427             :     }
    4428           0 :     SolarMutexGuard guard;
    4429             : 
    4430           0 :     OUString aPropertyFunctionName( "Property Get " );
    4431           0 :     aPropertyFunctionName += m_aPrefix;
    4432           0 :     aPropertyFunctionName += rProperty;
    4433             : 
    4434           0 :     SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
    4435           0 :     SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
    4436           0 :     if( pMeth == NULL )
    4437             :     {
    4438             :         // TODO: Check vba behavior concernig missing function
    4439             :         //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
    4440           0 :         throw UnknownPropertyException();
    4441             :     }
    4442             : 
    4443             :     // Call method
    4444           0 :     SbxVariableRef xValue = new SbxVariable;
    4445           0 :     pMeth->Call( xValue );
    4446           0 :     Any aRet = sbxToUnoValue( xValue );
    4447           0 :     return aRet;
    4448             : }
    4449             : 
    4450           0 : sal_Bool SAL_CALL ModuleInvocationProxy::hasMethod( const OUString& ) throw(std::exception)
    4451             : {
    4452           0 :     return sal_False;
    4453             : }
    4454             : 
    4455           0 : sal_Bool SAL_CALL ModuleInvocationProxy::hasProperty( const OUString& ) throw(std::exception)
    4456             : {
    4457           0 :     return sal_False;
    4458             : }
    4459             : 
    4460           0 : Any SAL_CALL ModuleInvocationProxy::invoke( const OUString& rFunction,
    4461             :                                             const Sequence< Any >& rParams,
    4462             :                                             Sequence< sal_Int16 >&,
    4463             :                                             Sequence< Any >& )
    4464             :     throw (CannotConvertException, InvocationTargetException,
    4465             :            RuntimeException, std::exception)
    4466             : {
    4467           0 :     SolarMutexGuard guard;
    4468             : 
    4469           0 :     Any aRet;
    4470           0 :     SbxObjectRef xScopeObj = m_xScopeObj;
    4471           0 :     if( !xScopeObj.Is() )
    4472             :     {
    4473           0 :         return aRet;
    4474             :     }
    4475           0 :     OUString aFunctionName = m_aPrefix;
    4476           0 :     aFunctionName += rFunction;
    4477             : 
    4478           0 :     bool bSetRescheduleBack = false;
    4479           0 :     bool bOldReschedule = true;
    4480           0 :     SbiInstance* pInst = GetSbData()->pInst;
    4481           0 :     if( pInst && pInst->IsCompatibility() )
    4482             :     {
    4483           0 :         bOldReschedule = pInst->IsReschedule();
    4484           0 :         if ( bOldReschedule )
    4485             :         {
    4486           0 :             pInst->EnableReschedule( false );
    4487           0 :             bSetRescheduleBack = true;
    4488             :         }
    4489             :     }
    4490             : 
    4491           0 :     SbxVariable* p = xScopeObj->Find( aFunctionName, SbxCLASS_METHOD );
    4492           0 :     SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
    4493           0 :     if( pMeth == NULL )
    4494             :     {
    4495             :         // TODO: Check vba behavior concernig missing function
    4496             :         //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
    4497           0 :         return aRet;
    4498             :     }
    4499             : 
    4500             :     // Setup parameters
    4501           0 :     SbxArrayRef xArray;
    4502           0 :     sal_Int32 nParamCount = rParams.getLength();
    4503           0 :     if( nParamCount )
    4504             :     {
    4505           0 :         xArray = new SbxArray;
    4506           0 :         const Any *pArgs = rParams.getConstArray();
    4507           0 :         for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
    4508             :         {
    4509           0 :             SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
    4510           0 :             unoToSbxValue( static_cast<SbxVariable*>(xVar), pArgs[i] );
    4511           0 :             xArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
    4512           0 :         }
    4513             :     }
    4514             : 
    4515             :     // Call method
    4516           0 :     SbxVariableRef xValue = new SbxVariable;
    4517           0 :     if( xArray.Is() )
    4518           0 :         pMeth->SetParameters( xArray );
    4519           0 :     pMeth->Call( xValue );
    4520           0 :     aRet = sbxToUnoValue( xValue );
    4521           0 :     pMeth->SetParameters( NULL );
    4522             : 
    4523           0 :     if( bSetRescheduleBack )
    4524           0 :         pInst->EnableReschedule( bOldReschedule );
    4525             : 
    4526             :     // TODO: OutParameter?
    4527             : 
    4528           0 :     return aRet;
    4529             : }
    4530             : 
    4531           0 : void SAL_CALL ModuleInvocationProxy::dispose()
    4532             :     throw(RuntimeException, std::exception)
    4533             : {
    4534           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    4535             : 
    4536           0 :     EventObject aEvent( static_cast<XComponent*>(this) );
    4537           0 :     m_aListeners.disposeAndClear( aEvent );
    4538             : 
    4539           0 :     m_xScopeObj = NULL;
    4540           0 : }
    4541             : 
    4542           0 : void SAL_CALL ModuleInvocationProxy::addEventListener( const Reference< XEventListener >& xListener )
    4543             :     throw (RuntimeException, std::exception)
    4544             : {
    4545           0 :     m_aListeners.addInterface( xListener );
    4546           0 : }
    4547             : 
    4548           0 : void SAL_CALL ModuleInvocationProxy::removeEventListener( const Reference< XEventListener >& xListener )
    4549             :     throw (RuntimeException, std::exception)
    4550             : {
    4551           0 :     m_aListeners.removeInterface( xListener );
    4552           0 : }
    4553             : 
    4554             : 
    4555           0 : Reference< XInterface > createComListener( const Any& aControlAny, const OUString& aVBAType,
    4556             :                                            const OUString& aPrefix, SbxObjectRef xScopeObj )
    4557             : {
    4558           0 :     Reference< XInterface > xRet;
    4559             : 
    4560             :     Reference< XComponentContext > xContext(
    4561           0 :         comphelper::getProcessComponentContext() );
    4562           0 :     Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
    4563             : 
    4564           0 :     Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPrefix, xScopeObj );
    4565             : 
    4566           0 :     Sequence<Any> args( 3 );
    4567           0 :     args[0] <<= aControlAny;
    4568           0 :     args[1] <<= aVBAType;
    4569           0 :     args[2] <<= xProxy;
    4570             : 
    4571             :     try
    4572             :     {
    4573           0 :         xRet = xServiceMgr->createInstanceWithArgumentsAndContext(
    4574             :             OUString( "com.sun.star.custom.UnoComListener"),
    4575           0 :             args, xContext );
    4576             :     }
    4577           0 :     catch( const Exception& )
    4578             :     {
    4579           0 :         implHandleAnyException( ::cppu::getCaughtException() );
    4580             :     }
    4581             : 
    4582           0 :     return xRet;
    4583             : }
    4584             : 
    4585             : typedef std::vector< WeakReference< XComponent > >  ComponentRefVector;
    4586             : 
    4587           2 : struct StarBasicDisposeItem
    4588             : {
    4589             :     StarBASIC*              m_pBasic;
    4590             :     SbxArrayRef             m_pRegisteredVariables;
    4591             :     ComponentRefVector      m_vComImplementsObjects;
    4592             : 
    4593           2 :     explicit StarBasicDisposeItem( StarBASIC* pBasic )
    4594           2 :         : m_pBasic( pBasic )
    4595             :     {
    4596           2 :         m_pRegisteredVariables = new SbxArray();
    4597           2 :     }
    4598             : };
    4599             : 
    4600             : typedef std::vector< StarBasicDisposeItem* > DisposeItemVector;
    4601             : 
    4602         262 : static DisposeItemVector GaDisposeItemVector;
    4603             : 
    4604        2539 : static DisposeItemVector::iterator lcl_findItemForBasic( StarBASIC* pBasic )
    4605             : {
    4606        2539 :     DisposeItemVector::iterator it;
    4607        2541 :     for( it = GaDisposeItemVector.begin() ; it != GaDisposeItemVector.end() ; ++it )
    4608             :     {
    4609           4 :         StarBasicDisposeItem* pItem = *it;
    4610           4 :         if( pItem->m_pBasic == pBasic )
    4611           2 :             return it;
    4612             :     }
    4613        2537 :     return GaDisposeItemVector.end();
    4614             : }
    4615             : 
    4616           2 : static StarBasicDisposeItem* lcl_getOrCreateItemForBasic( StarBASIC* pBasic )
    4617             : {
    4618           2 :     DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
    4619           2 :     StarBasicDisposeItem* pItem = (it != GaDisposeItemVector.end()) ? *it : NULL;
    4620           2 :     if( pItem == NULL )
    4621             :     {
    4622           2 :         pItem = new StarBasicDisposeItem( pBasic );
    4623           2 :         GaDisposeItemVector.push_back( pItem );
    4624             :     }
    4625           2 :     return pItem;
    4626             : }
    4627             : 
    4628           2 : void registerComponentToBeDisposedForBasic
    4629             :     ( Reference< XComponent > xComponent, StarBASIC* pBasic )
    4630             : {
    4631           2 :     StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
    4632           2 :     pItem->m_vComImplementsObjects.push_back( xComponent );
    4633           2 : }
    4634             : 
    4635           0 : void registerComListenerVariableForBasic( SbxVariable* pVar, StarBASIC* pBasic )
    4636             : {
    4637           0 :     StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
    4638           0 :     SbxArray* pArray = pItem->m_pRegisteredVariables;
    4639           0 :     pArray->Put( pVar, pArray->Count() );
    4640           0 : }
    4641             : 
    4642        2537 : void disposeComVariablesForBasic( StarBASIC* pBasic )
    4643             : {
    4644        2537 :     DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
    4645        2537 :     if( it != GaDisposeItemVector.end() )
    4646             :     {
    4647           2 :         StarBasicDisposeItem* pItem = *it;
    4648             : 
    4649           2 :         SbxArray* pArray = pItem->m_pRegisteredVariables;
    4650           2 :         sal_uInt16 nCount = pArray->Count();
    4651           2 :         for( sal_uInt16 i = 0 ; i < nCount ; ++i )
    4652             :         {
    4653           0 :             SbxVariable* pVar = pArray->Get( i );
    4654           0 :             pVar->ClearComListener();
    4655             :         }
    4656             : 
    4657           2 :         ComponentRefVector& rv = pItem->m_vComImplementsObjects;
    4658           2 :         ComponentRefVector::iterator itCRV;
    4659           4 :         for( itCRV = rv.begin() ; itCRV != rv.end() ; ++itCRV )
    4660             :         {
    4661             :             try
    4662             :             {
    4663           2 :                 Reference< XComponent > xComponent( (*itCRV).get(), UNO_QUERY_THROW );
    4664           2 :                 xComponent->dispose();
    4665             :             }
    4666           0 :             catch(const Exception& )
    4667             :             {}
    4668             :         }
    4669             : 
    4670           2 :         delete pItem;
    4671           2 :         GaDisposeItemVector.erase( it );
    4672             :     }
    4673        2537 : }
    4674             : 
    4675             : 
    4676             : // Handle module implements mechanism for OLE types
    4677           0 : bool SbModule::createCOMWrapperForIface( Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject )
    4678             : {
    4679             :     // For now: Take first interface that allows to instantiate COM wrapper
    4680             :     // TODO: Check if support for multiple interfaces is needed
    4681             : 
    4682             :     Reference< XComponentContext > xContext(
    4683           0 :         comphelper::getProcessComponentContext() );
    4684           0 :     Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
    4685             :     Reference< XSingleServiceFactory > xComImplementsFactory
    4686             :     (
    4687           0 :         xServiceMgr->createInstanceWithContext(
    4688           0 :             OUString( "com.sun.star.custom.ComImplementsFactory"), xContext ),
    4689             :         UNO_QUERY
    4690           0 :     );
    4691           0 :     if( !xComImplementsFactory.is() )
    4692           0 :         return false;
    4693             : 
    4694           0 :     bool bSuccess = false;
    4695             : 
    4696           0 :     SbxArray* pModIfaces = pClassData->mxIfaces;
    4697           0 :     sal_uInt16 nCount = pModIfaces->Count();
    4698           0 :     for( sal_uInt16 i = 0 ; i < nCount ; ++i )
    4699             :     {
    4700           0 :         SbxVariable* pVar = pModIfaces->Get( i );
    4701           0 :         OUString aIfaceName = pVar->GetName();
    4702             : 
    4703           0 :         if( !aIfaceName.isEmpty() )
    4704             :         {
    4705           0 :             OUString aPureIfaceName = aIfaceName;
    4706           0 :             sal_Int32 indexLastDot = aIfaceName.lastIndexOf('.');
    4707           0 :             if ( indexLastDot > -1 )
    4708             :             {
    4709           0 :                 aPureIfaceName = aIfaceName.copy( indexLastDot + 1 );
    4710             :             }
    4711           0 :             Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPureIfaceName, pProxyClassModuleObject );
    4712             : 
    4713           0 :             Sequence<Any> args( 2 );
    4714           0 :             args[0] <<= aIfaceName;
    4715           0 :             args[1] <<= xProxy;
    4716             : 
    4717           0 :             Reference< XInterface > xRet;
    4718           0 :             bSuccess = false;
    4719             :             try
    4720             :             {
    4721           0 :                 xRet = xComImplementsFactory->createInstanceWithArguments( args );
    4722           0 :                 bSuccess = true;
    4723             :             }
    4724           0 :             catch( const Exception& )
    4725             :             {
    4726           0 :                 implHandleAnyException( ::cppu::getCaughtException() );
    4727             :             }
    4728             : 
    4729           0 :             if( bSuccess )
    4730             :             {
    4731           0 :                 Reference< XComponent > xComponent( xProxy, UNO_QUERY );
    4732           0 :                 if( xComponent.is() )
    4733             :                 {
    4734           0 :                     StarBASIC* pParentBasic = NULL;
    4735           0 :                     SbxObject* pCurObject = this;
    4736           0 :                     do
    4737             :                     {
    4738           0 :                         SbxObject* pObjParent = pCurObject->GetParent();
    4739           0 :                         pParentBasic = PTR_CAST( StarBASIC, pObjParent );
    4740           0 :                         pCurObject = pObjParent;
    4741             :                     }
    4742           0 :                     while( pParentBasic == NULL && pCurObject != NULL );
    4743             : 
    4744             :                     OSL_ASSERT( pParentBasic != NULL );
    4745           0 :                     registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
    4746             :                 }
    4747             : 
    4748           0 :                 o_rRetAny <<= xRet;
    4749           0 :                 break;
    4750           0 :             }
    4751             :         }
    4752           0 :      }
    4753             : 
    4754           0 :     return bSuccess;
    4755             : }
    4756             : 
    4757             : 
    4758             : // Due to an incorrect behavior IE returns an object instead of a string
    4759             : // in some scenarios. Calling toString at the object may correct this.
    4760             : // Helper function used in sbxvalue.cxx
    4761           0 : bool handleToStringForCOMObjects( SbxObject* pObj, SbxValue* pVal )
    4762             : {
    4763           0 :     bool bSuccess = false;
    4764             : 
    4765           0 :     SbUnoObject* pUnoObj = NULL;
    4766           0 :     if( pObj != NULL && (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
    4767             :     {
    4768             :         // Only for native COM objects
    4769           0 :         if( pUnoObj->isNativeCOMObject() )
    4770             :         {
    4771           0 :             SbxVariableRef pMeth = pObj->Find( OUString( "toString"  ), SbxCLASS_METHOD );
    4772           0 :             if ( pMeth.Is() )
    4773             :             {
    4774           0 :                 SbxValues aRes;
    4775           0 :                 pMeth->Get( aRes );
    4776           0 :                 pVal->Put( aRes );
    4777           0 :                 bSuccess = true;
    4778           0 :             }
    4779             :         }
    4780             :     }
    4781           0 :     return bSuccess;
    4782             : }
    4783             : 
    4784          36 : Any StructRefInfo::getValue()
    4785             : {
    4786          36 :     Any aRet;
    4787             :     uno_any_destruct(
    4788          36 :         &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
    4789          36 :     typelib_TypeDescription * pTD = 0;
    4790          36 :     maType.getDescription(&pTD);
    4791             :     uno_any_construct(
    4792             :         &aRet, getInst(), pTD,
    4793          36 :                 reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
    4794          36 :     typelib_typedescription_release(pTD);
    4795          36 :     return aRet;
    4796             : }
    4797             : 
    4798          86 : bool StructRefInfo::setValue( const Any& rValue )
    4799             : {
    4800             :     return uno_type_assignData( getInst(),
    4801             :        maType.getTypeLibType(),
    4802          86 :        const_cast<void*>(rValue.getValue()),
    4803             :        rValue.getValueTypeRef(),
    4804             :        reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
    4805             :        reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
    4806         172 :        reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
    4807             : }
    4808             : 
    4809         197 : OUString StructRefInfo::getTypeName() const
    4810             : {
    4811         197 :     return maType.getTypeName();
    4812             : }
    4813             : 
    4814         122 : void* StructRefInfo::getInst()
    4815             : {
    4816         122 :     return const_cast<char *>(static_cast<char const *>(maAny.getValue()) + mnPos);
    4817             : }
    4818             : 
    4819          12 : TypeClass StructRefInfo::getTypeClass() const
    4820             : {
    4821          12 :     return maType.getTypeClass();
    4822             : }
    4823             : 
    4824         191 : SbUnoStructRefObject::SbUnoStructRefObject( const OUString& aName_, const StructRefInfo& rMemberInfo ) :  SbxObject( aName_ ), maMemberInfo( rMemberInfo ), mbMemberCacheInit( false )
    4825             : {
    4826         191 :    SetClassName( OUString( maMemberInfo.getTypeName() ) );
    4827         191 : }
    4828             : 
    4829         764 : SbUnoStructRefObject::~SbUnoStructRefObject()
    4830             : {
    4831         742 :     for ( StructFieldInfo::iterator it = maFields.begin(), it_end = maFields.end(); it != it_end; ++it )
    4832         551 :         delete it->second;
    4833         573 : }
    4834             : 
    4835          71 : void SbUnoStructRefObject::initMemberCache()
    4836             : {
    4837          71 :     if ( mbMemberCacheInit )
    4838          71 :         return;
    4839          71 :     sal_Int32 nAll = 0;
    4840          71 :     typelib_TypeDescription * pTD = 0;
    4841          71 :     maMemberInfo.getType().getDescription(&pTD);
    4842          71 :     typelib_CompoundTypeDescription * pCompTypeDescr = reinterpret_cast<typelib_CompoundTypeDescription *>(pTD);
    4843         146 :     for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
    4844          75 :         nAll += pCompTypeDescr->nMembers;
    4845         146 :     for ( pCompTypeDescr = reinterpret_cast<typelib_CompoundTypeDescription *>(pTD); pCompTypeDescr;
    4846             :         pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
    4847             :     {
    4848          75 :         typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs;
    4849          75 :         rtl_uString ** ppNames                         = pCompTypeDescr->ppMemberNames;
    4850          75 :         sal_Int32 * pMemberOffsets                     = pCompTypeDescr->pMemberOffsets;
    4851         701 :         for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; )
    4852             :         {
    4853         551 :             OUString aName( ppNames[nPos] );
    4854         551 :             maFields[ aName ] = new StructRefInfo( maMemberInfo.getRootAnyRef(), ppTypeRefs[nPos], maMemberInfo.getPos() + pMemberOffsets[nPos] );
    4855         551 :         }
    4856             :     }
    4857          71 :     typelib_typedescription_release(pTD);
    4858          71 :     mbMemberCacheInit = true;
    4859             : }
    4860             : 
    4861           6 : SbxVariable* SbUnoStructRefObject::Find( const OUString& rName, SbxClassType t )
    4862             : {
    4863           6 :     SbxVariable* pRes = SbxObject::Find( rName, t );
    4864           6 :     if ( !pRes )
    4865             :     {
    4866           6 :         if ( !mbMemberCacheInit )
    4867           6 :             initMemberCache();
    4868           6 :         StructFieldInfo::iterator it = maFields.find( OUString( rName ).toAsciiUpperCase() );
    4869           6 :         if ( it != maFields.end() )
    4870             :         {
    4871             :             SbxDataType eSbxType;
    4872           6 :             eSbxType = unoToSbxType( it->second->getTypeClass() );
    4873           6 :             SbxDataType eRealSbxType = eSbxType;
    4874           6 :             Property aProp;
    4875           6 :             aProp.Name = rName;
    4876           6 :             aProp.Type = com::sun::star::uno::Type( it->second->getTypeClass(), it->second->getTypeName() );
    4877           6 :             SbUnoProperty* pProp = new SbUnoProperty( rName, eSbxType, eRealSbxType, aProp, 0, false, ( aProp.Type.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT) );
    4878          12 :             SbxVariableRef xVarRef = pProp;
    4879           6 :             QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    4880          12 :             pRes = xVarRef;
    4881             :         }
    4882             :     }
    4883             : 
    4884           6 :     if( !pRes )
    4885             :     {
    4886           0 :         if( rName.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES) ||
    4887           0 :             rName.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES) ||
    4888           0 :             rName.equalsIgnoreAsciiCase(ID_DBG_METHODS) )
    4889             :         {
    4890             :             // Create
    4891           0 :             implCreateDbgProperties();
    4892             : 
    4893             :             // Now they have to be found regular
    4894           0 :             pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
    4895             :         }
    4896             :     }
    4897             : 
    4898           6 :     return pRes;
    4899             : }
    4900             : 
    4901             : // help method to create the dbg_-Properties
    4902           0 : void SbUnoStructRefObject::implCreateDbgProperties()
    4903             : {
    4904           0 :     Property aProp;
    4905             : 
    4906             :     // Id == -1: display the implemented interfaces corresponding the ClassProvider
    4907           0 :     SbxVariableRef xVarRef = new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES), SbxSTRING, SbxSTRING, aProp, -1, false, false );
    4908           0 :     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    4909             : 
    4910             :     // Id == -2: output the properties
    4911           0 :     xVarRef = new SbUnoProperty( OUString(ID_DBG_PROPERTIES), SbxSTRING, SbxSTRING, aProp, -2, false, false );
    4912           0 :     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    4913             : 
    4914             :     // Id == -3: output the Methods
    4915           0 :     xVarRef = new SbUnoProperty( OUString(ID_DBG_METHODS), SbxSTRING, SbxSTRING, aProp, -3, false, false );
    4916           0 :     QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    4917           0 : }
    4918             : 
    4919           0 : void SbUnoStructRefObject::implCreateAll()
    4920             : {
    4921             :      // throw away all existing methods and properties
    4922           0 :     pMethods   = new SbxArray;
    4923           0 :     pProps     = new SbxArray;
    4924             : 
    4925           0 :     if (!mbMemberCacheInit)
    4926           0 :         initMemberCache();
    4927             : 
    4928           0 :     for ( StructFieldInfo::iterator it = maFields.begin(), it_end = maFields.end(); it != it_end; ++it )
    4929             :     {
    4930           0 :         const OUString& rName = it->first;
    4931             :         SbxDataType eSbxType;
    4932           0 :         eSbxType = unoToSbxType( it->second->getTypeClass() );
    4933           0 :         SbxDataType eRealSbxType = eSbxType;
    4934           0 :         Property aProp;
    4935           0 :         aProp.Name = rName;
    4936           0 :         aProp.Type = com::sun::star::uno::Type( it->second->getTypeClass(), it->second->getTypeName() );
    4937           0 :         SbUnoProperty* pProp = new SbUnoProperty( rName, eSbxType, eRealSbxType, aProp, 0, false, ( aProp.Type.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT) );
    4938           0 :         SbxVariableRef xVarRef = pProp;
    4939           0 :         QuickInsert( static_cast<SbxVariable*>(xVarRef) );
    4940           0 :     }
    4941             : 
    4942             :     // Create Dbg_-Properties
    4943           0 :     implCreateDbgProperties();
    4944           0 : }
    4945             : 
    4946             :  // output the value
    4947           6 : Any SbUnoStructRefObject::getUnoAny()
    4948             : {
    4949           6 :     return maMemberInfo.getValue();
    4950             : }
    4951             : 
    4952           0 : OUString SbUnoStructRefObject::Impl_DumpProperties()
    4953             : {
    4954           0 :     OUStringBuffer aRet;
    4955           0 :     aRet.appendAscii("Properties of object ");
    4956           0 :     aRet.append( getDbgObjectName() );
    4957             : 
    4958           0 :     sal_uInt16 nPropCount = pProps->Count();
    4959           0 :     sal_uInt16 nPropsPerLine = 1 + nPropCount / 30;
    4960           0 :     for( sal_uInt16 i = 0; i < nPropCount; i++ )
    4961             :     {
    4962           0 :         SbxVariable* pVar = pProps->Get( i );
    4963           0 :         if( pVar )
    4964             :         {
    4965           0 :             OUStringBuffer aPropStr;
    4966           0 :             if( (i % nPropsPerLine) == 0 )
    4967             :             {
    4968           0 :                 aPropStr.appendAscii( "\n" );
    4969             :             }
    4970             :             // output the type and name
    4971             :             // Is it in Uno a sequence?
    4972           0 :             SbxDataType eType = pVar->GetFullType();
    4973             : 
    4974           0 :             OUString aName( pVar->GetName() );
    4975           0 :             StructFieldInfo::iterator it = maFields.find( aName );
    4976             : 
    4977           0 :             if ( it != maFields.end() )
    4978             :             {
    4979           0 :                 const StructRefInfo& rPropInfo = *it->second;
    4980             : 
    4981           0 :                 if( eType == SbxOBJECT )
    4982             :                 {
    4983           0 :                     if( rPropInfo.getTypeClass() == TypeClass_SEQUENCE )
    4984             :                     {
    4985           0 :                         eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
    4986             :                     }
    4987             :                 }
    4988             :             }
    4989           0 :             aPropStr.append( Dbg_SbxDataType2String( eType ) );
    4990             : 
    4991           0 :             aPropStr.appendAscii( " " );
    4992           0 :             aPropStr.append( pVar->GetName() );
    4993             : 
    4994           0 :             if( i == nPropCount - 1 )
    4995             :             {
    4996           0 :                 aPropStr.appendAscii( "\n" );
    4997             :             }
    4998             :             else
    4999             :             {
    5000           0 :                 aPropStr.appendAscii( "; " );
    5001             :             }
    5002           0 :             aRet.append( aPropStr.makeStringAndClear() );
    5003             :         }
    5004             :     }
    5005           0 :     return aRet.makeStringAndClear();
    5006             : }
    5007             : 
    5008           6 : void SbUnoStructRefObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
    5009             :                            const SfxHint& rHint, const TypeId& rHintType )
    5010             : {
    5011           6 :     if ( !mbMemberCacheInit )
    5012           0 :         initMemberCache();
    5013           6 :     const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
    5014           6 :     if( pHint )
    5015             :     {
    5016           6 :         SbxVariable* pVar = pHint->GetVar();
    5017           6 :         SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
    5018           6 :         if( pProp )
    5019             :         {
    5020           6 :              StructFieldInfo::iterator it =  maFields.find(  pProp->GetName() );
    5021             :             // handle get/set of members of struct
    5022           6 :             if( pHint->GetId() == SBX_HINT_DATAWANTED )
    5023             :             {
    5024             :                 // Test-Properties
    5025           4 :                 sal_Int32 nId = pProp->nId;
    5026           4 :                 if( nId < 0 )
    5027             :                 {
    5028             :                     // Id == -1: Display implemented interfaces according the ClassProvider
    5029           0 :                     if( nId == -1 )     // Property ID_DBG_SUPPORTEDINTERFACES"
    5030             :                     {
    5031           0 :                         OUStringBuffer aRet;
    5032           0 :                         aRet.appendAscii( ID_DBG_SUPPORTEDINTERFACES );
    5033           0 :                         aRet.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
    5034             : 
    5035           0 :                         pVar->PutString( aRet.makeStringAndClear() );
    5036             :                     }
    5037             :                     // Id == -2: output properties
    5038           0 :                     else if( nId == -2 )        // Property ID_DBG_PROPERTIES
    5039             :                     {
    5040             :                         // by now all properties must be established
    5041           0 :                         implCreateAll();
    5042           0 :                         OUString aRetStr = Impl_DumpProperties();
    5043           0 :                         pVar->PutString( aRetStr );
    5044             :                     }
    5045             :                     // Id == -3: output the methods
    5046           0 :                     else if( nId == -3 )        // Property ID_DBG_METHODS
    5047             :                     {
    5048             :                         // by now all properties must be established
    5049           0 :                         implCreateAll();
    5050           0 :                         OUStringBuffer aRet;
    5051           0 :                         aRet.appendAscii("Methods of object ");
    5052           0 :                         aRet.append( getDbgObjectName() );
    5053           0 :                         aRet.appendAscii( "\nNo methods found\n" );
    5054           0 :                         pVar->PutString( aRet.makeStringAndClear() );
    5055             :                     }
    5056           6 :                     return;
    5057             :                 }
    5058             : 
    5059           4 :                 if ( it != maFields.end() )
    5060             :                 {
    5061           4 :                     Any aRetAny = it->second->getValue();
    5062           4 :                     unoToSbxValue( pVar, aRetAny );
    5063             :                 }
    5064             :                 else
    5065           0 :                     StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
    5066             :             }
    5067           2 :             else if( pHint->GetId() == SBX_HINT_DATACHANGED )
    5068             :             {
    5069           2 :                 if ( it != maFields.end() )
    5070             :                 {
    5071             :                     // take over the value from Uno to Sbx
    5072           2 :                     Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
    5073           2 :                     it->second->setValue( aAnyValue );
    5074             :                 }
    5075             :                 else
    5076           0 :                     StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
    5077             :             }
    5078             :         }
    5079             :         else
    5080           0 :            SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
    5081             :     }
    5082             : }
    5083             : 
    5084         126 : StructRefInfo SbUnoStructRefObject::getStructMember( const OUString& rMemberName )
    5085             : {
    5086         126 :     if (!mbMemberCacheInit)
    5087             :     {
    5088          65 :         initMemberCache();
    5089             :     }
    5090         126 :     StructFieldInfo::iterator it = maFields.find( rMemberName );
    5091             : 
    5092         126 :     css::uno::Type aFoundType;
    5093         126 :     sal_Int32 nFoundPos = -1;
    5094             : 
    5095         126 :     if ( it != maFields.end() )
    5096             :     {
    5097         126 :         aFoundType = it->second->getType();
    5098         126 :         nFoundPos = it->second->getPos();
    5099             :     }
    5100         126 :     StructRefInfo aRet( maMemberInfo.getRootAnyRef(), aFoundType, nFoundPos );
    5101         126 :     return aRet;
    5102             : }
    5103             : 
    5104           0 : OUString SbUnoStructRefObject::getDbgObjectName()
    5105             : {
    5106           0 :     OUString aName = GetClassName();
    5107           0 :     if( aName.isEmpty() )
    5108             :     {
    5109           0 :         aName += "Unknown";
    5110             :     }
    5111           0 :     OUStringBuffer aRet;
    5112           0 :     if( aName.getLength() > 20 )
    5113             :     {
    5114           0 :         aRet.appendAscii( "\n" );
    5115             :     }
    5116           0 :     aRet.appendAscii( "\"" );
    5117           0 :     aRet.append( aName );
    5118           0 :     aRet.appendAscii( "\":" );
    5119           0 :     return aRet.makeStringAndClear();
    5120         786 : }
    5121             : 
    5122             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11