summaryrefslogtreecommitdiff
path: root/binfilter/bf_basic/source/classes/sbunoobj.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_basic/source/classes/sbunoobj.cxx')
-rw-r--r--binfilter/bf_basic/source/classes/sbunoobj.cxx2710
1 files changed, 2710 insertions, 0 deletions
diff --git a/binfilter/bf_basic/source/classes/sbunoobj.cxx b/binfilter/bf_basic/source/classes/sbunoobj.cxx
new file mode 100644
index 000000000000..4853691c678d
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/sbunoobj.cxx
@@ -0,0 +1,2710 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/errcode.hxx>
+#include <bf_svtools/hint.hxx>
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/extract.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/script/ArrayWrapper.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/script/XAllListener.hpp>
+#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/XDefaultProperty.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/reflection/XIdlArray.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
+#include <com/sun/star/bridge/oleautomation/Date.hpp>
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+#include <com/sun/star/bridge/oleautomation/Currency.hpp>
+
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+using namespace com::sun::star::container;
+using namespace com::sun::star::bridge;
+using namespace cppu;
+using namespace rtl;
+
+
+#include "sbstar.hxx"
+#include "sberrors.hxx"
+#include "sbunoobj.hxx"
+#include "sbjsmod.hxx"
+#include "basmgr.hxx"
+#include "sbintern.hxx"
+
+#include<math.h>
+
+namespace binfilter {
+
+TYPEINIT1(SbUnoMethod,SbxMethod)
+TYPEINIT1(SbUnoProperty,SbxProperty)
+TYPEINIT1(SbUnoObject,SbxObject)
+TYPEINIT1(SbUnoClass,SbxObject)
+
+typedef WeakImplHelper1< XAllListener > BasicAllListenerHelper;
+
+// Flag, um immer ueber Invocation zu gehen
+//#define INVOCATION_ONLY
+
+
+// Identifier fuer die dbg_-Properies als Strings anlegen
+static String ID_DBG_SUPPORTEDINTERFACES( RTL_CONSTASCII_USTRINGPARAM("Dbg_SupportedInterfaces") );
+static String ID_DBG_PROPERTIES( RTL_CONSTASCII_USTRINGPARAM("Dbg_Properties") );
+static String ID_DBG_METHODS( RTL_CONSTASCII_USTRINGPARAM("Dbg_Methods") );
+
+static String aIllegalArgumentExceptionName
+ ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.IllegalArgumentException" ) );
+static OUString aSeqLevelStr( RTL_CONSTASCII_USTRINGPARAM("[]") );
+
+Reference< XComponentContext > getComponentContext_Impl( void )
+{
+ static Reference< XComponentContext > xContext;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xContext.is() )
+ {
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ }
+ }
+ return xContext;
+}
+
+// CoreReflection statisch speichern
+Reference< XIdlReflection > getCoreReflection_Impl( void )
+{
+ static Reference< XIdlReflection > xCoreReflection;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xCoreReflection.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) )
+ >>= xCoreReflection;
+ OSL_ENSURE( xCoreReflection.is(), "### CoreReflection singleton not accessable!?" );
+ }
+ if( !xCoreReflection.is() )
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xCoreReflection;
+}
+
+// CoreReflection statisch speichern
+Reference< XHierarchicalNameAccess > getCoreReflection_HierarchicalNameAccess_Impl( void )
+{
+ static Reference< XHierarchicalNameAccess > xCoreReflection_HierarchicalNameAccess;
+
+ if( !xCoreReflection_HierarchicalNameAccess.is() )
+ {
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( xCoreReflection.is() )
+ {
+ xCoreReflection_HierarchicalNameAccess =
+ Reference< XHierarchicalNameAccess >( xCoreReflection, UNO_QUERY );
+ }
+ }
+ return xCoreReflection_HierarchicalNameAccess;
+}
+
+// Hold TypeProvider statically
+Reference< XHierarchicalNameAccess > getTypeProvider_Impl( void )
+{
+ static Reference< XHierarchicalNameAccess > xAccess;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xAccess.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) )
+ >>= xAccess;
+ OSL_ENSURE( xAccess.is(), "### TypeDescriptionManager singleton not accessable!?" );
+ }
+ if( !xAccess.is() )
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM
+ ("/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xAccess;
+}
+
+// #111851 factory function to create an OLE object
+SbUnoObject* createOLEObject_Impl( const String& aType )
+{
+ static Reference< XMultiServiceFactory > xOLEFactory;
+ static bool bNeedsInit = true;
+
+ if( bNeedsInit )
+ {
+ bNeedsInit = false;
+
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
+ xOLEFactory = Reference<XMultiServiceFactory>(
+ xSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.OleObjectFactory")),
+ xContext ), UNO_QUERY );
+ }
+ }
+
+ SbUnoObject* pUnoObj = NULL;
+ if( xOLEFactory.is() )
+ {
+ Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aType );
+ if( xOLEObject.is() )
+ {
+ Any aAny;
+ aAny <<= xOLEObject;
+ pUnoObj = new SbUnoObject( aType, aAny );
+ }
+ }
+ return pUnoObj;
+}
+
+
+String implGetExceptionMsg( Exception& e, const String& aExceptionType_ );
+
+// #105565 Special Object to wrap a strongly typed Uno Any
+TYPEINIT1(SbUnoAnyObject,SbxObject)
+
+// TODO: Spaeter auslagern
+Reference<XIdlClass> TypeToIdlClass( const Type& rType )
+{
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xRetClass;
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+
+ if( pTD )
+ {
+ OUString sOWName( pTD->pTypeName );
+ Reference< XIdlReflection > xRefl = getCoreReflection_Impl();
+ xRetClass = xRefl->forName( sOWName );
+ }
+ return xRetClass;
+}
+
+// Fehlermeldungs-Message bei Exception zusammenbauen
+String implGetExceptionMsg( Exception& e, const String& aExceptionType_ )
+{
+ String aExceptionType = aExceptionType_;
+ if( aExceptionType.Len() == 0 )
+ aExceptionType = String( RTL_CONSTASCII_USTRINGPARAM("Unknown" ) );
+
+ String aTypeLine( RTL_CONSTASCII_USTRINGPARAM("\nType: " ) );
+ aTypeLine += aExceptionType;
+
+ String aMessageLine( RTL_CONSTASCII_USTRINGPARAM("\nMessage: " ) );
+ aMessageLine += String( e.Message );
+
+ String aMsg = aTypeLine;
+ aMsg += aMessageLine;
+ return aMsg;
+}
+
+// Exception type unknown
+String implGetExceptionMsg( Exception& e )
+{
+ String aMsg = implGetExceptionMsg( e, String() );
+ return aMsg;
+}
+
+// Error-Message fuer WrappedTargetExceptions
+String implGetWrappedMsg( WrappedTargetException& e )
+{
+ String aMsg;
+ Any aWrappedAny = e.TargetException;
+ Type aExceptionType = aWrappedAny.getValueType();
+
+ // Really an Exception?
+ if( aExceptionType.getTypeClass() == TypeClass_EXCEPTION )
+ {
+ RuntimeException& e_ = *( (RuntimeException*)aWrappedAny.getValue() );
+ aMsg = implGetExceptionMsg( e_, String( aExceptionType.getTypeName() ) );
+ }
+ // Otherwise use WrappedTargetException itself
+ else
+ {
+ aMsg = implGetExceptionMsg( e );
+ }
+
+ return aMsg;
+}
+
+void implHandleBasicErrorException( BasicErrorException& e )
+{
+ SbError nError = StarBASIC::GetSfxFromVBError( (USHORT)e.ErrorCode );
+ StarBASIC::Error( nError, e.ErrorMessageArgument );
+}
+
+void implHandleWrappedTargetException( WrappedTargetException& e )
+{
+ SbError nError;
+ String aMessage;
+ Any aWrappedAny = e.TargetException;
+ if ( aWrappedAny.getValueType() == ::getCppuType( (BasicErrorException*)NULL ) )
+ {
+ BasicErrorException& be = *( (BasicErrorException*)aWrappedAny.getValue() );
+ nError = StarBASIC::GetSfxFromVBError( (USHORT)be.ErrorCode );
+ aMessage = be.ErrorMessageArgument;
+ }
+ else
+ {
+ nError = ERRCODE_BASIC_EXCEPTION;
+ aMessage = implGetWrappedMsg( e );
+ }
+ StarBASIC::Error( nError, aMessage );
+}
+
+// Von Uno nach Sbx wandeln
+SbxDataType unoToSbxType( TypeClass eType )
+{
+ SbxDataType eRetType = SbxVOID;
+
+ switch( eType )
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_TYPE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION: eRetType = SbxOBJECT; break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ARRAY: break;
+ */
+ case TypeClass_ENUM: eRetType = SbxLONG; break;
+ case TypeClass_SEQUENCE:
+ eRetType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+ */
+
+ case TypeClass_ANY: eRetType = SbxVARIANT; break;
+ case TypeClass_BOOLEAN: eRetType = SbxBOOL; break;
+ case TypeClass_CHAR: eRetType = SbxCHAR; break;
+ case TypeClass_STRING: eRetType = SbxSTRING; break;
+ case TypeClass_FLOAT: eRetType = SbxSINGLE; break;
+ case TypeClass_DOUBLE: eRetType = SbxDOUBLE; break;
+ //case TypeClass_OCTET: break;
+ case TypeClass_BYTE: eRetType = SbxINTEGER; break;
+ //case TypeClass_INT: eRetType = SbxINT; break;
+ case TypeClass_SHORT: eRetType = SbxINTEGER; break;
+ case TypeClass_LONG: eRetType = SbxLONG; break;
+ case TypeClass_HYPER: eRetType = SbxSALINT64; break;
+ //case TypeClass_UNSIGNED_OCTET: break;
+ case TypeClass_UNSIGNED_SHORT: eRetType = SbxUSHORT; break;
+ case TypeClass_UNSIGNED_LONG: eRetType = SbxULONG; break;
+ case TypeClass_UNSIGNED_HYPER: eRetType = SbxSALUINT64;break;
+ //case TypeClass_UNSIGNED_INT: eRetType = SbxUINT; break;
+ //case TypeClass_UNSIGNED_BYTE: eRetType = SbxUSHORT; break;
+ default: break;
+ }
+ return eRetType;
+}
+
+SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass )
+{
+ SbxDataType eRetType = SbxVOID;
+ if( xIdlClass.is() )
+ {
+ TypeClass eType = xIdlClass->getTypeClass();
+ eRetType = unoToSbxType( eType );
+ }
+ return eRetType;
+}
+void unoToSbxValue( SbxVariable* pVar, const Any& aValue );
+static void implSequenceToMultiDimArray( SbxDimArray*& pArray, Sequence< sal_Int32 >& indices, Sequence< sal_Int32 >& sizes, const Any& aValue, sal_Int32& dimension, sal_Bool bIsZeroIndex )
+{
+ Type aType = aValue.getValueType();
+ TypeClass eTypeClass = aType.getTypeClass();
+
+ sal_Int32 indicesIndex = indices.getLength() -1;
+ sal_Int32 dimCopy = dimension;
+
+ if ( eTypeClass == TypeClass_SEQUENCE )
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
+ Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
+ sal_Int32 nLen = xIdlArray->getLen( aValue );
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ Any aElementAny = xIdlArray->get( aValue, (UINT32)index );
+ // This detects the dimension were currently processing
+ if ( dimCopy == dimension )
+ {
+ ++dimCopy;
+ if ( sizes.getLength() < dimCopy )
+ {
+ sizes.realloc( sizes.getLength() + 1 );
+ sizes[ sizes.getLength() - 1 ] = nLen;
+ indices.realloc( indices.getLength() + 1 );
+ indicesIndex = indices.getLength() - 1;
+ }
+ }
+
+ if ( bIsZeroIndex )
+ indices[ dimCopy - 1 ] = index;
+ else
+ indices[ dimCopy - 1] = index + 1;
+
+ implSequenceToMultiDimArray( pArray, indices, sizes, aElementAny, dimCopy, bIsZeroIndex );
+ }
+
+ }
+ else
+ {
+ if ( indices.getLength() < 1 )
+ {
+ // Should never ever get here ( indices.getLength()
+ // should equal number of dimensions in the array )
+ // And that should at least be 1 !
+ // #QUESTION is there a better error?
+ StarBASIC::Error( SbERR_INVALID_OBJECT );
+ return;
+ }
+
+ if ( !pArray )
+ {
+ SbxDataType eSbxElementType = unoToSbxType( aValue.getValueTypeClass() );
+ pArray = new SbxDimArray( eSbxElementType );
+ sal_Int32 nIndexLen = indices.getLength();
+
+ // Dimension the array
+ for ( sal_Int32 index = 0; index < nIndexLen; ++index )
+ {
+ if ( bIsZeroIndex )
+ pArray->unoAddDim32( 0, sizes[ index ] - 1);
+ else
+ pArray->unoAddDim32( 1, sizes[ index ] );
+
+ }
+ }
+
+ if ( pArray )
+ {
+ SbxDataType eSbxElementType = unoToSbxType( aValue.getValueTypeClass() );
+ SbxVariableRef xVar = new SbxVariable( eSbxElementType );
+ unoToSbxValue( (SbxVariable*)xVar, aValue );
+
+ sal_Int32* pIndices = indices.getArray();
+ pArray->Put32( (SbxVariable*)xVar, pIndices );
+
+ }
+ }
+}
+
+void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
+{
+ Type aType = aValue.getValueType();
+ TypeClass eTypeClass = aType.getTypeClass();
+ switch( eTypeClass )
+ {
+ case TypeClass_TYPE:
+ {
+ // Map Type to IdlClass
+ Type aType_;
+ aValue >>= aType_;
+ Reference<XIdlClass> xClass = TypeToIdlClass( aType_ );
+ Any aClassAny;
+ aClassAny <<= xClass;
+
+ // SbUnoObject instanzieren
+ String aName;
+ SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aClassAny );
+ SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
+
+ // #51475 Wenn das Objekt ungueltig ist null liefern
+ if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
+ {
+ pVar->PutObject( NULL );
+ }
+ else
+ {
+ pVar->PutObject( xWrapper );
+ }
+ }
+ break;
+ // Interfaces und Structs muessen in ein SbUnoObject gewrappt werden
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ {
+ if( eTypeClass == TypeClass_STRUCT )
+ {
+ ArrayWrapper aWrap;
+ if ( (aValue >>= aWrap) )
+ {
+ SbxDimArray* pArray = NULL;
+ Sequence< sal_Int32 > indices;
+ Sequence< sal_Int32 > sizes;
+ sal_Int32 dimension = 0;
+ implSequenceToMultiDimArray( pArray, indices, sizes, aWrap.Array, dimension, aWrap.IsZeroIndex );
+ if ( pArray )
+ {
+ SbxDimArrayRef xArray = pArray;
+ USHORT nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+ }
+ else
+ pVar->PutEmpty();
+ break;
+ }
+ }
+ // SbUnoObject instanzieren
+ String aName;
+ SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aValue );
+ SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
+
+ // #51475 Wenn das Objekt ungueltig ist null liefern
+ if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
+ {
+ pVar->PutObject( NULL );
+ }
+ else
+ {
+ pVar->PutObject( xWrapper );
+ }
+ }
+ break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ENUM: break;
+ case TypeClass_ARRAY: break;
+ */
+
+ case TypeClass_ENUM:
+ {
+ sal_Int32 nEnum = 0;
+ enum2int( nEnum, aValue );
+ pVar->PutLong( nEnum );
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
+ Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
+ sal_Int32 i, nLen = xIdlArray->getLen( aValue );
+
+ typelib_TypeDescription * pTD = 0;
+ aType.getDescription( &pTD );
+ OSL_ASSERT( pTD && pTD->eTypeClass == typelib_TypeClass_SEQUENCE );
+ Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
+ ::typelib_typedescription_release( pTD );
+
+ // In Basic Array anlegen
+ SbxDimArrayRef xArray;
+ SbxDataType eSbxElementType = unoToSbxType( aElementType.getTypeClass() );
+ xArray = new SbxDimArray( eSbxElementType );
+ if( nLen > 0 )
+ {
+ xArray->unoAddDim32( 0, nLen - 1 );
+
+ // Elemente als Variablen eintragen
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ // Elemente wandeln
+ Any aElementAny = xIdlArray->get( aValue, (UINT32)i );
+ SbxVariableRef xVar = new SbxVariable( eSbxElementType );
+ unoToSbxValue( (SbxVariable*)xVar, aElementAny );
+
+ // Ins Array braten
+ xArray->Put32( (SbxVariable*)xVar, &i );
+ }
+ }
+ else
+ {
+ xArray->unoAddDim( 0, -1 );
+ }
+
+ // Array zurueckliefern
+ USHORT nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+
+ // #54548, Die Parameter duerfen hier nicht weggehauen werden
+ //pVar->SetParameters( NULL );
+ }
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+
+ case TypeClass_ANY:
+ {
+ // Any rausholen und konvertieren
+ //Any* pAny = (Any*)aValue.get();
+ //if( pAny )
+ //unoToSbxValue( pVar, *pAny );
+ }
+ break;
+ */
+
+ case TypeClass_BOOLEAN: pVar->PutBool( *(sal_Bool*)aValue.getValue() ); break;
+ case TypeClass_CHAR:
+ {
+ pVar->PutChar( *(sal_Unicode*)aValue.getValue() );
+ break;
+ }
+ case TypeClass_STRING: { OUString val; aValue >>= val; pVar->PutString( String( val ) ); } break;
+ case TypeClass_FLOAT: { float val = 0; aValue >>= val; pVar->PutSingle( val ); } break;
+ case TypeClass_DOUBLE: { double val = 0; aValue >>= val; pVar->PutDouble( val ); } break;
+ //case TypeClass_OCTET: break;
+ case TypeClass_BYTE: { sal_Int8 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
+ //case TypeClass_INT: break;
+ case TypeClass_SHORT: { sal_Int16 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
+ case TypeClass_LONG: { sal_Int32 val = 0; aValue >>= val; pVar->PutLong( val ); } break;
+ case TypeClass_HYPER: { sal_Int64 val = 0; aValue >>= val; pVar->PutInt64( val ); } break;
+ //case TypeClass_UNSIGNED_OCTET:break;
+ case TypeClass_UNSIGNED_SHORT: { sal_uInt16 val = 0; aValue >>= val; pVar->PutUShort( val ); } break;
+ case TypeClass_UNSIGNED_LONG: { sal_uInt32 val = 0; aValue >>= val; pVar->PutULong( val ); } break;
+ case TypeClass_UNSIGNED_HYPER: { sal_uInt64 val = 0; aValue >>= val; pVar->PutUInt64( val ); } break;
+ //case TypeClass_UNSIGNED_INT: break;
+ //case TypeClass_UNSIGNED_BYTE: break;
+ default: pVar->PutEmpty(); break;
+ }
+}
+
+// Reflection fuer Sbx-Typen liefern
+Type getUnoTypeForSbxBaseType( SbxDataType eType )
+{
+ Type aRetType = getCppuVoidType();
+ switch( eType )
+ {
+ //case SbxEMPTY: eRet = TypeClass_VOID; break;
+ case SbxNULL: aRetType = ::getCppuType( (const Reference< XInterface > *)0 ); break;
+ case SbxINTEGER: aRetType = ::getCppuType( (sal_Int16*)0 ); break;
+ case SbxLONG: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
+ case SbxSINGLE: aRetType = ::getCppuType( (float*)0 ); break;
+ case SbxDOUBLE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxCURRENCY: aRetType = ::getCppuType( (oleautomation::Currency*)0 ); break;
+ case SbxDECIMAL: aRetType = ::getCppuType( (oleautomation::Decimal*)0 ); break;
+ case SbxDATE: {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // aRetType = ::getCppuType( (double*)0 );
+/*?*/ // else
+ aRetType = ::getCppuType( (oleautomation::Date*)0 );
+ }
+ break;
+ // case SbxDATE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxSTRING: aRetType = ::getCppuType( (OUString*)0 ); break;
+ //case SbxOBJECT: break;
+ //case SbxERROR: break;
+ case SbxBOOL: aRetType = ::getCppuType( (sal_Bool*)0 ); break;
+ case SbxVARIANT: aRetType = ::getCppuType( (Any*)0 ); break;
+ //case SbxDATAOBJECT: break;
+ case SbxCHAR: aRetType = ::getCppuType( (sal_Unicode*)0 ); break;
+ case SbxBYTE: aRetType = ::getCppuType( (sal_Int16*)0 ); break;
+ case SbxUSHORT: aRetType = ::getCppuType( (sal_uInt16*)0 ); break;
+ case SbxULONG: aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
+ //case SbxLONG64: break;
+ //case SbxULONG64: break;
+ // Maschinenabhaengige zur Sicherheit auf Hyper abbilden
+ case SbxINT: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
+ case SbxUINT: aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
+ //case SbxVOID: break;
+ //case SbxHRESULT: break;
+ //case SbxPOINTER: break;
+ //case SbxDIMARRAY: break;
+ //case SbxCARRAY: break;
+ //case SbxUSERDEF: break;
+ //case SbxLPSTR: break;
+ //case SbxLPWSTR: break;
+ //case SbxCoreSTRING: break;
+ default: break;
+ }
+ return aRetType;
+}
+
+// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
+Type getUnoTypeForSbxValue( SbxValue* pVal )
+{
+ Type aRetType = getCppuVoidType();
+ if( !pVal )
+ return aRetType;
+
+ // SbxType nach Uno wandeln
+ SbxDataType eBaseType = pVal->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVal->GetObject();
+ if( !xObj )
+ {
+ // #109936 No error any more
+ // StarBASIC::Error( SbERR_INVALID_OBJECT );
+ aRetType = getCppuType( static_cast<Reference<XInterface> *>(0) );
+ return aRetType;
+ }
+
+ if( xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ SbxDimArray* pArray = (SbxDimArray*)pObj;
+
+ short nDims = pArray->GetDims();
+ Type aElementType = getUnoTypeForSbxBaseType( (SbxDataType)(pArray->GetType() & 0xfff) );
+ TypeClass eElementTypeClass = aElementType.getTypeClass();
+
+ // Normal case: One dimensional array
+ sal_Int32 nLower, nUpper;
+ if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
+ {
+ if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
+ {
+ // Wenn alle Elemente des Arrays vom gleichen Typ sind, wird
+ // der genommen, sonst wird das ganze als Any-Sequence betrachtet
+ sal_Bool bNeedsInit = sal_True;
+
+ INT32 nSize = nUpper - nLower + 1;
+ INT32 nIdx = nLower;
+ for( INT32 i = 0 ; i < nSize ; i++,nIdx++ )
+ {
+ SbxVariableRef xVar = pArray->Get32( &nIdx );
+ Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
+ if( bNeedsInit )
+ {
+ if( aType.getTypeClass() == TypeClass_VOID )
+ {
+ // #88522
+ // if only first element is void: different types -> []any
+ // if all elements are void: []void is not allowed -> []any
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ aElementType = aType;
+ bNeedsInit = sal_False;
+ }
+ else if( aElementType != aType )
+ {
+ // Verschiedene Typen -> AnySequence
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ }
+ }
+
+ OUString aSeqTypeName( aSeqLevelStr );
+ aSeqTypeName += aElementType.getTypeName();
+ aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
+ }
+ // #i33795 Map also multi dimensional arrays to corresponding sequences
+ else if( nDims > 1 )
+ {
+ if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
+ {
+ // For this check the array's dim structure does not matter
+ UINT32 nFlatArraySize = pArray->Count32();
+
+ sal_Bool bNeedsInit = sal_True;
+ for( UINT32 i = 0 ; i < nFlatArraySize ; i++ )
+ {
+ SbxVariableRef xVar = pArray->SbxArray::Get32( i );
+ Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
+ if( bNeedsInit )
+ {
+ if( aType.getTypeClass() == TypeClass_VOID )
+ {
+ // if only first element is void: different types -> []any
+ // if all elements are void: []void is not allowed -> []any
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ aElementType = aType;
+ bNeedsInit = sal_False;
+ }
+ else if( aElementType != aType )
+ {
+ // Verschiedene Typen -> AnySequence
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ }
+ }
+
+ OUString aSeqTypeName;
+ for( short iDim = 0 ; iDim < nDims ; iDim++ )
+ aSeqTypeName += aSeqLevelStr;
+ aSeqTypeName += aElementType.getTypeName();
+ aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
+ }
+ }
+ // Kein Array, sondern...
+ else if( xObj->ISA(SbUnoObject) )
+ {
+ aRetType = ((SbUnoObject*)(SbxBase*)xObj)->getUnoAny().getValueType();
+ }
+ // SbUnoAnyObject?
+ else if( xObj->ISA(SbUnoAnyObject) )
+ {
+ aRetType = ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue().getValueType();
+ }
+ // Sonst ist es ein Nicht-Uno-Basic-Objekt -> default==void liefern
+ }
+ // Kein Objekt, Basistyp konvertieren
+ else
+ {
+ aRetType = getUnoTypeForSbxBaseType( eBaseType );
+ }
+ return aRetType;
+}
+
+// Deklaration Konvertierung von Sbx nach Uno mit bekannter Zielklasse
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );
+
+// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
+Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType = false )
+{
+ SbxDataType eBaseType = pVar->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
+ return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
+ }
+
+ Type aType = getUnoTypeForSbxValue( pVar );
+ TypeClass eType = aType.getTypeClass();
+
+ if( !bBlockConversionToSmallestType )
+ {
+ // #79615 Choose "smallest" represention for int values
+ // because up cast is allowed, downcast not
+ switch( eType )
+ {
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ {
+ double d = pVar->GetDouble();
+ if( d == floor( d ) )
+ {
+ if( d >= -128 && d <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( d >= SbxMININT && d <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
+ aType = ::getCppuType( (sal_Int32*)0 );
+ }
+ break;
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 n = pVar->GetInteger();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ break;
+ }
+ case TypeClass_LONG:
+ {
+ sal_Int32 n = pVar->GetLong();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( n >= SbxMININT && n <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_uInt16 n = pVar->GetUShort();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 n = pVar->GetLong();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ else if( n <= SbxMAXUINT )
+ aType = ::getCppuType( (sal_uInt16*)0 );
+ break;
+ }
+ default: break;
+ }
+ }
+
+ return sbxToUnoValue( pVar, aType );
+}
+
+
+
+// Helper function for StepREDIMP
+static Any implRekMultiDimArrayToSequence( SbxDimArray* pArray,
+ const Type& aElemType, short nMaxDimIndex, short nActualDim,
+ sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
+{
+ sal_Int32 nSeqLevel = nMaxDimIndex - nActualDim + 1;
+ OUString aSeqTypeName;
+ sal_Int32 i;
+ for( i = 0 ; i < nSeqLevel ; i++ )
+ aSeqTypeName += aSeqLevelStr;
+
+ aSeqTypeName += aElemType.getTypeName();
+ Type aSeqType( TypeClass_SEQUENCE, aSeqTypeName );
+
+ // Create Sequence instance
+ Any aRetVal;
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aSeqType );
+ xIdlTargetClass->createObject( aRetVal );
+
+ // Alloc sequence according to array bounds
+ sal_Int32 nUpper = pUpperBounds[nActualDim];
+ sal_Int32 nLower = pLowerBounds[nActualDim];
+ sal_Int32 nSeqSize = nUpper - nLower + 1;
+ Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
+ xArray->realloc( aRetVal, nSeqSize );
+
+ sal_Int32& ri = pActualIndices[nActualDim];
+
+ for( ri = nLower,i = 0 ; ri <= nUpper ; ri++,i++ )
+ {
+ Any aElementVal;
+
+ if( nActualDim < nMaxDimIndex )
+ {
+ aElementVal = implRekMultiDimArrayToSequence( pArray, aElemType,
+ nMaxDimIndex, nActualDim + 1, pActualIndices, pLowerBounds, pUpperBounds );
+ }
+ else
+ {
+ SbxVariable* pSource = pArray->Get32( pActualIndices );
+ aElementVal = sbxToUnoValue( pSource, aElemType );
+ }
+
+ try
+ {
+ // In die Sequence uebernehmen
+ xArray->set( aRetVal, i, aElementVal );
+ }
+ catch( IllegalArgumentException& e1 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e1, aIllegalArgumentExceptionName ) );
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ }
+ return aRetVal;
+}
+
+// Konvertierung von Sbx nach Uno mit bekannter Zielklasse
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty )
+{
+ Any aRetVal;
+
+ // #94560 No conversion of empty/void for MAYBE_VOID properties
+ if( pUnoProperty && pUnoProperty->Attributes & PropertyAttribute::MAYBEVOID )
+ {
+ if( pVar->IsEmpty() )
+ return aRetVal;
+ }
+
+ SbxDataType eBaseType = pVar->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
+ {
+ return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
+ }
+ }
+
+ TypeClass eType = rType.getTypeClass();
+ switch( eType )
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
+
+ // Null-Referenz?
+ if( pVar->IsNull() && eType == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > xRef;
+ OUString aClassName = xIdlTargetClass->getName();
+ Type aClassType( xIdlTargetClass->getTypeClass(), aClassName.getStr() );
+ aRetVal.setValue( &xRef, aClassType );
+ }
+ }
+ break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ENUM: break;
+ case TypeClass_ARRAY: break;
+ */
+
+ // Array -> Sequence
+ case TypeClass_ENUM:
+ {
+ aRetVal = int2enum( pVar->GetLong(), rType );
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj && xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ SbxDimArray* pArray = (SbxDimArray*)pObj;
+
+ short nDims = pArray->GetDims();
+
+ // Normal case: One dimensional array
+ sal_Int32 nLower, nUpper;
+ if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
+ {
+ sal_Int32 nSeqSize = nUpper - nLower + 1;
+
+ // Instanz der geforderten Sequence erzeugen
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
+ xIdlTargetClass->createObject( aRetVal );
+ Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
+ xArray->realloc( aRetVal, nSeqSize );
+
+ // Element-Type
+ OUString aClassName = xIdlTargetClass->getName();
+ typelib_TypeDescription * pSeqTD = 0;
+ typelib_typedescription_getByName( &pSeqTD, aClassName.pData );
+ OSL_ASSERT( pSeqTD );
+ Type aElemType( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
+ // Reference< XIdlClass > xElementClass = TypeToIdlClass( aElemType );
+
+ // Alle Array-Member umwandeln und eintragen
+ sal_Int32 nIdx = nLower;
+ for( sal_Int32 i = 0 ; i < nSeqSize ; i++,nIdx++ )
+ {
+ SbxVariableRef xVar = pArray->Get32( &nIdx );
+
+ // Wert von Sbx nach Uno wandeln
+ Any aAnyValue = sbxToUnoValue( (SbxVariable*)xVar, aElemType );
+
+ try
+ {
+ // In die Sequence uebernehmen
+ xArray->set( aRetVal, i, aAnyValue );
+ }
+ catch( IllegalArgumentException& e1 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e1, aIllegalArgumentExceptionName ) );
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ }
+ }
+ // #i33795 Map also multi dimensional arrays to corresponding sequences
+ else if( nDims > 1 )
+ {
+ // Element-Type
+ typelib_TypeDescription * pSeqTD = 0;
+ Type aCurType( rType );
+ sal_Int32 nSeqLevel = 0;
+ Type aElemType;
+ do
+ {
+ OUString aTypeName = aCurType.getTypeName();
+ typelib_typedescription_getByName( &pSeqTD, aTypeName.pData );
+ OSL_ASSERT( pSeqTD );
+ if( pSeqTD->eTypeClass == typelib_TypeClass_SEQUENCE )
+ {
+ aCurType = Type( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
+ nSeqLevel++;
+ }
+ else
+ {
+ aElemType = aCurType;
+ break;
+ }
+ }
+ while( true );
+
+ if( nSeqLevel == nDims )
+ {
+ sal_Int32* pLowerBounds = new sal_Int32[nDims];
+ sal_Int32* pUpperBounds = new sal_Int32[nDims];
+ sal_Int32* pActualIndices = new sal_Int32[nDims];
+ for( short i = 1 ; i <= nDims ; i++ )
+ {
+ sal_Int32 lBound, uBound;
+ pArray->GetDim32( i, lBound, uBound );
+
+ short j = i - 1;
+ pActualIndices[j] = pLowerBounds[j] = lBound;
+ pUpperBounds[j] = uBound;
+ }
+
+ aRetVal = implRekMultiDimArrayToSequence( pArray, aElemType,
+ nDims - 1, 0, pActualIndices, pLowerBounds, pUpperBounds );
+
+ delete[] pUpperBounds;
+ delete[] pLowerBounds;
+ delete[] pActualIndices;
+ }
+ }
+ }
+ }
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+ */
+
+ // Bei Any die Klassen-unabhaengige Konvertierungs-Routine nutzen
+ case TypeClass_ANY:
+ {
+ aRetVal = sbxToUnoValueImpl( pVar );
+ }
+ break;
+
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool b = pVar->GetBool();
+ aRetVal.setValue( &b, getBooleanCppuType() );
+ break;
+ }
+ case TypeClass_CHAR:
+ {
+ sal_Unicode c = pVar->GetChar();
+ aRetVal.setValue( &c , getCharCppuType() );
+ break;
+ }
+ case TypeClass_STRING: aRetVal <<= OUString( pVar->GetString() ); break;
+ case TypeClass_FLOAT: aRetVal <<= pVar->GetSingle(); break;
+ case TypeClass_DOUBLE: aRetVal <<= pVar->GetDouble(); break;
+ //case TypeClass_OCTET: break;
+
+ case TypeClass_BYTE:
+ {
+ sal_Int16 nVal = pVar->GetInteger();
+ sal_Bool bOverflow = sal_False;
+ if( nVal < -128 )
+ {
+ bOverflow = sal_True;
+ nVal = -128;
+ }
+ else if( nVal > 127 )
+ {
+ bOverflow = sal_True;
+ nVal = 127;
+ }
+ if( bOverflow )
+ StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW );
+
+ sal_Int8 nByteVal = (sal_Int8)nVal;
+ aRetVal <<= nByteVal;
+ break;
+ }
+ //case TypeClass_INT: break;
+ case TypeClass_SHORT: aRetVal <<= (sal_Int16)( pVar->GetInteger() ); break;
+ case TypeClass_LONG: aRetVal <<= (sal_Int32)( pVar->GetLong() ); break;
+ case TypeClass_HYPER: aRetVal <<= (sal_Int64)( pVar->GetInt64() ); break;
+ //case TypeClass_UNSIGNED_OCTET:break;
+ case TypeClass_UNSIGNED_SHORT: aRetVal <<= (sal_uInt16)( pVar->GetUShort() ); break;
+ case TypeClass_UNSIGNED_LONG: aRetVal <<= (sal_uInt32)( pVar->GetULong() ); break;
+ case TypeClass_UNSIGNED_HYPER: aRetVal <<= (sal_uInt64)( pVar->GetUInt64() ); break;
+ //case TypeClass_UNSIGNED_INT: break;
+ //case TypeClass_UNSIGNED_BYTE: break;
+ default: break;
+ }
+
+ return aRetVal;
+}
+
+// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+String Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, USHORT nRekLevel )
+{
+ Type aIfaceType = ::getCppuType( (const Reference< XInterface > *)0 );
+ static Reference< XIdlClass > xIfaceClass = TypeToIdlClass( aIfaceType );
+
+ String aRetStr;
+ for( USHORT i = 0 ; i < nRekLevel ; i++ )
+ aRetStr.AppendAscii( " " );
+ aRetStr += String( xClass->getName() );
+ OUString aClassName = xClass->getName();
+ Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
+
+ // Pruefen, ob das Interface wirklich unterstuetzt wird
+ if( !x->queryInterface( aClassType ).hasValue() )
+ {
+ aRetStr.AppendAscii( " (ERROR: Not really supported!)\n" );
+ }
+ // Gibt es Super-Interfaces
+ else
+ {
+ aRetStr.AppendAscii( "\n" );
+
+ // Super-Interfaces holen
+ Sequence< Reference< XIdlClass > > aSuperClassSeq = xClass->getSuperclasses();
+ const Reference< XIdlClass >* pClasses = aSuperClassSeq.getConstArray();
+ UINT32 nSuperIfaceCount = aSuperClassSeq.getLength();
+ for( UINT32 j = 0 ; j < nSuperIfaceCount ; j++ )
+ {
+ const Reference< XIdlClass >& rxIfaceClass = pClasses[j];
+ if( !rxIfaceClass->equals( xIfaceClass ) )
+ aRetStr += Impl_GetInterfaceInfo( x, rxIfaceClass, nRekLevel + 1 );
+ }
+ }
+ return aRetStr;
+}
+
+String getDbgObjectNameImpl( SbUnoObject* pUnoObj )
+{
+ String aName;
+ if( pUnoObj )
+ {
+ aName = pUnoObj->GetClassName();
+ if( !aName.Len() )
+ {
+ Any aToInspectObj = pUnoObj->getUnoAny();
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ Reference< XInterface > xObj;
+ if( eType == TypeClass_INTERFACE )
+ xObj = *(Reference< XInterface >*)aToInspectObj.getValue();
+ if( xObj.is() )
+ {
+ Reference< XServiceInfo > xServiceInfo( xObj, UNO_QUERY );
+ if( xServiceInfo.is() )
+ aName = xServiceInfo->getImplementationName();
+ }
+ }
+ }
+ return aName;
+}
+
+String getDbgObjectName( SbUnoObject* pUnoObj )
+{
+ String aName = getDbgObjectNameImpl( pUnoObj );
+ if( !aName.Len() )
+ aName.AppendAscii( "Unknown" );
+
+ String aRet;
+ if( aName.Len() > 20 )
+ aRet.AppendAscii( "\n" );
+ aRet.AppendAscii( "\"" );
+ aRet += aName;
+ aRet.AppendAscii( "\":" );
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+String Impl_GetSupportedInterfaces( SbUnoObject* pUnoObj )
+{
+ Any aToInspectObj = pUnoObj->getUnoAny();
+
+ // #54898: Nur TypeClass Interface zulasssen
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ String aRet;
+ if( eType != TypeClass_INTERFACE )
+ {
+ aRet += ID_DBG_SUPPORTEDINTERFACES;
+ aRet.AppendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
+ }
+ else
+ {
+ // Interface aus dem Any besorgen
+ const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();
+
+ // XIdlClassProvider-Interface ansprechen
+ Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
+ Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
+
+ aRet.AssignAscii( "Supported interfaces by object " );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+ aRet.AppendAscii( "\n" );
+ if( xTypeProvider.is() )
+ {
+ // Interfaces der Implementation holen
+ Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
+ const Type* pTypeArray = aTypeSeq.getConstArray();
+ UINT32 nIfaceCount = aTypeSeq.getLength();
+ for( UINT32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const Type& rType = pTypeArray[j];
+
+ Reference<XIdlClass> xClass = TypeToIdlClass( rType );
+ if( xClass.is() )
+ {
+ aRet += Impl_GetInterfaceInfo( x, xClass, 1 );
+ }
+ else
+ {
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+ String TypeName( OUString( pTD->pTypeName ) );
+
+ aRet.AppendAscii( "*** ERROR: No IdlClass for type \"" );
+ aRet += TypeName;
+ aRet.AppendAscii( "\"\n*** Please check type library\n" );
+ }
+ }
+ }
+ else if( xClassProvider.is() )
+ {
+
+ DBG_ERROR( "XClassProvider not supported in UNO3" );
+ }
+ }
+ return aRet;
+}
+
+
+
+// Dbg-Hilfsmethode SbxDataType -> String
+String Dbg_SbxDataType2String( SbxDataType eType )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Unknown Sbx-Type!") );
+ switch( +eType )
+ {
+ case SbxEMPTY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxEMPTY") ); break;
+ case SbxNULL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxNULL") ); break;
+ case SbxINTEGER: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINTEGER") ); break;
+ case SbxLONG: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG") ); break;
+ case SbxSINGLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSINGLE") ); break;
+ case SbxDOUBLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDOUBLE") ); break;
+ case SbxCURRENCY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCURRENCY") ); break;
+ case SbxDECIMAL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDECIMAL") ); break;
+ case SbxDATE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATE") ); break;
+ case SbxSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSTRING") ); break;
+ case SbxOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxOBJECT") ); break;
+ case SbxERROR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxERROR") ); break;
+ case SbxBOOL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBOOL") ); break;
+ case SbxVARIANT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVARIANT") ); break;
+ case SbxDATAOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATAOBJECT") ); break;
+ case SbxCHAR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCHAR") ); break;
+ case SbxBYTE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBYTE") ); break;
+ case SbxUSHORT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSHORT") ); break;
+ case SbxULONG: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG") ); break;
+ case SbxLONG64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG64") ); break;
+ case SbxULONG64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG64") ); break;
+ case SbxSALINT64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT64") ); break;
+ case SbxSALUINT64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT64") ); break;
+ case SbxINT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT") ); break;
+ case SbxUINT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT") ); break;
+ case SbxVOID: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVOID") ); break;
+ case SbxHRESULT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxHRESULT") ); break;
+ case SbxPOINTER: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxPOINTER") ); break;
+ case SbxDIMARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDIMARRAY") ); break;
+ case SbxCARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCARRAY") ); break;
+ case SbxUSERDEF: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSERDEF") ); break;
+ case SbxLPSTR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPSTR") ); break;
+ case SbxLPWSTR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPWSTR") ); break;
+ case SbxCoreSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCoreSTRING" ) ); break;
+ case SbxOBJECT | SbxARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxARRAY") ); break;
+ default: break;
+ }
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Anzeigen der Properties eines SbUnoObjects
+String Impl_DumpProperties( SbUnoObject* pUnoObj )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Properties of object ") );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+
+ // Uno-Infos auswerten, um Arrays zu erkennen
+ Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
+ if( !xAccess.is() )
+ {
+ Reference< XInvocation > xInvok = pUnoObj->getInvocation();
+ if( xInvok.is() )
+ xAccess = xInvok->getIntrospection();
+ }
+ if( !xAccess.is() )
+ {
+ aRet.AppendAscii( "\nUnknown, no introspection available\n" );
+ return aRet;
+ }
+
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ UINT32 nUnoPropCount = props.getLength();
+ const Property* pUnoProps = props.getConstArray();
+
+ SbxArray* pProps = pUnoObj->GetProperties();
+ USHORT nPropCount = pProps->Count();
+ USHORT nPropsPerLine = 1 + nPropCount / 30;
+ for( USHORT i = 0; i < nPropCount; i++ )
+ {
+ SbxVariable* pVar = pProps->Get( i );
+ if( pVar )
+ {
+ String aPropStr;
+ if( (i % nPropsPerLine) == 0 )
+ aPropStr.AppendAscii( "\n" );
+
+ // Typ und Namen ausgeben
+ // Ist es in Uno eine Sequence?
+ SbxDataType eType = pVar->GetFullType();
+
+ BOOL bMaybeVoid = FALSE;
+ if( i < nUnoPropCount )
+ {
+ const Property& rProp = pUnoProps[ i ];
+
+ // #63133: Bei MAYBEVOID Typ aus Uno neu konvertieren,
+ // damit nicht immer nur SbxEMPTY ausgegben wird.
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ {
+ eType = unoToSbxType( rProp.Type.getTypeClass() );
+ bMaybeVoid = TRUE;
+ }
+ if( eType == SbxOBJECT )
+ {
+ Type aType = rProp.Type;
+ if( aType.getTypeClass() == TypeClass_SEQUENCE )
+ eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ }
+ }
+ aPropStr += Dbg_SbxDataType2String( eType );
+ if( bMaybeVoid )
+ aPropStr.AppendAscii( "/void" );
+ aPropStr.AppendAscii( " " );
+ aPropStr += pVar->GetName();
+
+ if( i == nPropCount - 1 )
+ aPropStr.AppendAscii( "\n" );
+ else
+ aPropStr.AppendAscii( "; " );
+
+ aRet += aPropStr;
+ }
+ }
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Anzeigen der Methoden eines SbUnoObjects
+String Impl_DumpMethods( SbUnoObject* pUnoObj )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Methods of object ") );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+
+ // XIntrospectionAccess, um die Typen der Parameter auch ausgeben zu koennen
+ Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
+ if( !xAccess.is() )
+ {
+ Reference< XInvocation > xInvok = pUnoObj->getInvocation();
+ if( xInvok.is() )
+ xAccess = xInvok->getIntrospection();
+ }
+ if( !xAccess.is() )
+ {
+ aRet.AppendAscii( "\nUnknown, no introspection available\n" );
+ return aRet;
+ }
+ Sequence< Reference< XIdlMethod > > methods = xAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ const Reference< XIdlMethod >* pUnoMethods = methods.getConstArray();
+
+ SbxArray* pMethods = pUnoObj->GetMethods();
+ USHORT nMethodCount = pMethods->Count();
+ if( !nMethodCount )
+ {
+ aRet.AppendAscii( "\nNo methods found\n" );
+ return aRet;
+ }
+ USHORT nPropsPerLine = 1 + nMethodCount / 30;
+ for( USHORT i = 0; i < nMethodCount; i++ )
+ {
+ SbxVariable* pVar = pMethods->Get( i );
+ if( pVar )
+ {
+ String aPropStr;
+ if( (i % nPropsPerLine) == 0 )
+ aPropStr.AppendAscii( "\n" );
+
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = pUnoMethods[i];
+
+ // Ist es in Uno eine Sequence?
+ SbxDataType eType = pVar->GetFullType();
+ if( eType == SbxOBJECT )
+ {
+ Reference< XIdlClass > xClass = rxMethod->getReturnType();
+ if( xClass.is() && xClass->getTypeClass() == TypeClass_SEQUENCE )
+ eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ }
+ // Name und Typ ausgeben
+ aPropStr += Dbg_SbxDataType2String( eType );
+ aPropStr.AppendAscii( " " );
+ aPropStr += pVar->GetName();
+ aPropStr.AppendAscii( " ( " );
+
+ // get-Methode darf keinen Parameter haben
+ Sequence< Reference< XIdlClass > > aParamsSeq = rxMethod->getParameterTypes();
+ UINT32 nParamCount = aParamsSeq.getLength();
+ const Reference< XIdlClass >* pParams = aParamsSeq.getConstArray();
+
+ if( nParamCount > 0 )
+ {
+ for( USHORT j = 0; j < nParamCount; j++ )
+ {
+ String aTypeStr = Dbg_SbxDataType2String( unoToSbxType( pParams[ j ] ) );
+ aPropStr += aTypeStr;
+
+ if( j < nParamCount - 1 )
+ aPropStr.AppendAscii( ", " );
+ }
+ }
+ else
+ aPropStr.AppendAscii( "void" );
+
+ aPropStr.AppendAscii( " ) " );
+
+ if( i == nMethodCount - 1 )
+ aPropStr.AppendAscii( "\n" );
+ else
+ aPropStr.AppendAscii( "; " );
+
+ aRet += aPropStr;
+ }
+ }
+ return aRet;
+}
+
+TYPEINIT1(AutomationNamedArgsSbxArray,SbxArray)
+
+// Implementation SbUnoObject
+void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ if( bNeedIntrospection )
+ doIntrospection();
+
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pParams = pVar->GetParameters();
+ SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
+ SbUnoMethod* pMeth = PTR_CAST(SbUnoMethod,pVar);
+ if( pProp )
+ {
+ bool bInvocation = pProp->isInvocationBased();
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Test-Properties
+ INT32 nId = pProp->nId;
+ if( nId < 0 )
+ {
+ // Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
+ if( nId == -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
+ {
+ String aRetStr = Impl_GetSupportedInterfaces( this );
+ pVar->PutString( aRetStr );
+ }
+ // Id == -2: Properties ausgeben
+ else if( nId == -2 ) // Property ID_DBG_PROPERTIES
+ {
+ // Jetzt muessen alle Properties angelegt werden
+ implCreateAll();
+ String aRetStr = Impl_DumpProperties( this );
+ pVar->PutString( aRetStr );
+ }
+ // Id == -3: Methoden ausgeben
+ else if( nId == -3 ) // Property ID_DBG_METHODS
+ {
+ // Jetzt muessen alle Properties angelegt werden
+ implCreateAll();
+ String aRetStr = Impl_DumpMethods( this );
+ pVar->PutString( aRetStr );
+ }
+ return;
+ }
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ try
+ {
+ // Wert holen
+ Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ Any aRetAny = xPropSet->getPropertyValue( pProp->GetName() );
+ // Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
+ // nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
+ // Ansonsten kann auch FastPropertySet genutzt werden
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( Exception& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ try
+ {
+ // Wert holen
+ Any aRetAny = mxInvocation->getValue( pProp->GetName() );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( Exception& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ }
+ }
+ else if( pHint->GetId() == SBX_HINT_DATACHANGED )
+ {
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ if( pProp->aUnoProp.Attributes & PropertyAttribute::READONLY )
+ {
+ StarBASIC::Error( SbERR_PROP_READONLY );
+ return;
+ }
+
+ // Wert von Uno nach Sbx uebernehmen
+ Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
+ try
+ {
+ // Wert setzen
+ Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ xPropSet->setPropertyValue( pProp->GetName(), aAnyValue );
+ // Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
+ // nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
+ // Ansonsten kann auch FastPropertySet genutzt werden
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( IllegalArgumentException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e2, aIllegalArgumentExceptionName ) );
+ }
+ catch( RuntimeException& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ catch( Exception& e4 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e4 ) );
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ // Wert von Uno nach Sbx uebernehmen
+ Any aAnyValue = sbxToUnoValueImpl( pVar );
+ try
+ {
+ // Wert setzen
+ mxInvocation->setValue( pProp->GetName(), aAnyValue );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( Exception& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ }
+ }
+ }
+ else if( pMeth )
+ {
+ bool bInvocation = pMeth->isInvocationBased();
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Anzahl Parameter -1 wegen Param0 == this
+ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
+ Sequence<Any> args;
+ BOOL bOutParams = FALSE;
+ UINT32 i;
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ UINT32 nUnoParamCount = rInfoSeq.getLength();
+ UINT32 nAllocParamCount = nParamCount;
+
+ // Ueberschuessige Parameter ignorieren, Alternative: Error schmeissen
+ if( nParamCount > nUnoParamCount )
+ {
+ nParamCount = nUnoParamCount;
+ nAllocParamCount = nParamCount;
+ }
+ else if( nParamCount < nUnoParamCount )
+ {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // {
+/*?*/ // // Check types
+/*?*/ // bool bError = false;
+/*?*/ // for( i = nParamCount ; i < nUnoParamCount ; i++ )
+/*?*/ // {
+/*?*/ // const ParamInfo& rInfo = pParamInfos[i];
+/*?*/ // const Reference< XIdlClass >& rxClass = rInfo.aType;
+/*?*/ // if( rxClass->getTypeClass() != TypeClass_ANY )
+/*?*/ // {
+/*?*/ // bError = true;
+/*?*/ // StarBASIC::Error( SbERR_NOT_OPTIONAL );
+/*?*/ // }
+/*?*/ // }
+/*?*/ // if( !bError )
+/*?*/ // nAllocParamCount = nUnoParamCount;
+/*?*/ // }
+ }
+
+ if( nAllocParamCount > 0 )
+ {
+ args.realloc( nAllocParamCount );
+ Any* pAnyArgs = args.getArray();
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ const Reference< XIdlClass >& rxClass = rInfo.aType;
+ //const XIdlClassRef& rxClass = pUnoParams[i];
+
+ com::sun::star::uno::Type aType( rxClass->getTypeClass(), rxClass->getName() );
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ pAnyArgs[i] = sbxToUnoValue( pParams->Get( (USHORT)(i+1) ), aType );
+
+ // Wenn es nicht schon feststeht pruefen, ob Out-Parameter vorliegen
+ if( !bOutParams )
+ {
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ bOutParams = TRUE;
+ }
+ }
+ }
+ }
+ else if( bInvocation && pParams && mxInvocation.is() )
+ {
+ bool bOLEAutomation = true;
+ // TODO: bOLEAutomation = xOLEAutomation.is()
+
+ AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
+ if( bOLEAutomation )
+ pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);
+
+ args.realloc( nParamCount );
+ Any* pAnyArgs = args.getArray();
+ bool bBlockConversionToSmallestType( false );
+/*?*/ // bool bBlockConversionToSmallestType = pINST->IsCompatibility();
+ if( pArgNamesArray )
+ {
+ Sequence< OUString >& rNameSeq = pArgNamesArray->getNames();
+ OUString* pNames = rNameSeq.getArray();
+
+ Any aValAny;
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ USHORT iSbx = (USHORT)(i+1);
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ),
+ bBlockConversionToSmallestType );
+
+ OUString aParamName = pNames[iSbx];
+ if( aParamName.getLength() )
+ {
+ oleautomation::NamedArgument aNamedArgument;
+ aNamedArgument.Name = aParamName;
+ aNamedArgument.Value = aValAny;
+ pAnyArgs[i] <<= aNamedArgument;
+ }
+ else
+ {
+ pAnyArgs[i] = aValAny;
+ }
+ }
+ }
+ else
+ {
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ),
+ bBlockConversionToSmallestType );
+ }
+ }
+ }
+
+ // Methode callen
+ GetSbData()->bBlockCompilerError = TRUE; // #106433 Block compiler errors for API calls
+ try
+ {
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ Any aRetAny = pMeth->m_xUnoMethod->invoke( getUnoAny(), args );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+
+ // Muessen wir Out-Parameter zurueckkopieren?
+ if( bOutParams )
+ {
+ const Any* pAnyArgs = args.getConstArray();
+
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+
+ UINT32 j;
+ for( j = 0 ; j < nParamCount ; j++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[j];
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pAnyArgs[ j ] );
+ }
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ Sequence< INT16 > OutParamIndex;
+ Sequence< Any > OutParam;
+ Any aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+
+ const INT16* pIndices = OutParamIndex.getConstArray();
+ UINT32 nLen = OutParamIndex.getLength();
+ if( nLen )
+ {
+ const Any* pNewValues = OutParam.getConstArray();
+ for( UINT32 j = 0 ; j < nLen ; j++ )
+ {
+ INT16 iTarget = pIndices[ j ];
+ if( iTarget >= (INT16)nParamCount )
+ break;
+ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] );
+ }
+ }
+ }
+
+ // #55460, Parameter hier weghauen, da das in unoToSbxValue()
+ // bei Arrays wegen #54548 nicht mehr gemacht wird
+ if( pParams )
+ pVar->SetParameters( NULL );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( IllegalArgumentException& e3)
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e3, aIllegalArgumentExceptionName ) );
+ }
+ catch( Exception& e4 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e4 ) );
+ }
+ /*
+ catch( NullPointerException& e1 )
+ {
+ }
+ catch( InvocationTargetException& e2 )
+ {
+ }
+ */
+ GetSbData()->bBlockCompilerError = FALSE; // #106433 Unblock compiler errors
+ }
+ }
+ else
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+
+#ifdef INVOCATION_ONLY
+// Aus USR
+Reference< XInvocation > createDynamicInvocationFor( const Any& aAny );
+#endif
+
+SbUnoObject::SbUnoObject( const String& aName_, const Any& aUnoObj_ )
+ : SbxObject( aName_ )
+{
+ static Reference< XIntrospection > xIntrospection;
+
+ // Default-Properties von Sbx wieder rauspruegeln
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
+ // Typ des Objekts pruefen
+ TypeClass eType = aUnoObj_.getValueType().getTypeClass();
+ Reference< XInterface > x;
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Interface aus dem Any besorgen
+ x = *(Reference< XInterface >*)aUnoObj_.getValue();
+ if( !x.is() )
+ return;
+ }
+
+ Reference< XTypeProvider > xTypeProvider;
+#ifdef INVOCATION_ONLY
+ // Invocation besorgen
+ mxInvocation = createDynamicInvocationFor( aUnoObj_ );
+#else
+ // Hat das Object selbst eine Invocation?
+ mxInvocation = Reference< XInvocation >( x, UNO_QUERY );
+
+ xTypeProvider = Reference< XTypeProvider >( x, UNO_QUERY );
+#endif
+
+ if( mxInvocation.is() )
+ {
+ // #94670: This is WRONG because then the MaterialHolder doesn't refer
+ // to the object implementing XInvocation but to the object passed to
+ // the invocation service!!!
+ // mxMaterialHolder = Reference< XMaterialHolder >::query( mxInvocation );
+
+ // ExactName holen
+ mxExactNameInvocation = Reference< XExactName >::query( mxInvocation );
+
+ // Rest bezieht sich nur auf Introspection
+ if( !xTypeProvider.is() )
+ {
+ bNeedIntrospection = FALSE;
+ return;
+ }
+ }
+
+ // Introspection-Flag
+ bNeedIntrospection = TRUE;
+ maTmpUnoObj = aUnoObj_;
+
+
+ //*** Namen bestimmen ***
+ BOOL bFatalError = TRUE;
+
+ // Ist es ein Interface oder eine struct?
+ BOOL bSetClassName = FALSE;
+ String aClassName_;
+ if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
+ {
+ // Struct ist Ok
+ bFatalError = FALSE;
+
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ aClassName_ = String( aUnoObj_.getValueType().getTypeName() );
+ bSetClassName = TRUE;
+ }
+ }
+ else if( eType == TypeClass_INTERFACE )
+ {
+ // #70197 Interface geht immer durch Typ im Any
+ bFatalError = FALSE;
+
+ // Nach XIdlClassProvider-Interface fragen
+ Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
+ if( xClassProvider.is() )
+ {
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ Sequence< Reference< XIdlClass > > szClasses = xClassProvider->getIdlClasses();
+ UINT32 nLen = szClasses.getLength();
+ if( nLen )
+ {
+ const Reference< XIdlClass > xImplClass = szClasses.getConstArray()[ 0 ];
+ if( xImplClass.is() )
+ {
+ aClassName_ = String( xImplClass->getName() );
+ bSetClassName = TRUE;
+ }
+ }
+ }
+ }
+ }
+ if( bSetClassName )
+ SetClassName( aClassName_ );
+
+ // Weder Interface noch Struct -> FatalError
+ if( bFatalError )
+ {
+ StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
+ return;
+ }
+
+ // #67781 Introspection erst on demand durchfuehren
+}
+
+SbUnoObject::~SbUnoObject()
+{
+}
+
+
+// #76470 Introspection on Demand durchfuehren
+void SbUnoObject::doIntrospection( void )
+{
+ static Reference< XIntrospection > xIntrospection;
+
+ if( !bNeedIntrospection )
+ return;
+ bNeedIntrospection = FALSE;
+
+ if( !xIntrospection.is() )
+ {
+ // Introspection-Service holen
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ if ( xFactory.is() )
+ {
+ Reference< XInterface > xI = xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") );
+ if (xI.is())
+ xIntrospection = Reference< XIntrospection >::query( xI );
+ //xI->queryInterface( ::getCppuType( (const Reference< XIntrospection > *)0 ), xIntrospection );
+ }
+ }
+ if( !xIntrospection.is() )
+ {
+ StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
+ return;
+ }
+
+ // Introspection durchfuehren
+ try
+ {
+ mxUnoAccess = xIntrospection->inspect( maTmpUnoObj );
+ }
+ catch( RuntimeException& e )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+
+ if( !mxUnoAccess.is() )
+ {
+ // #51475 Ungueltiges Objekt kennzeichnen (kein mxMaterialHolder)
+ return;
+ }
+
+ // MaterialHolder vom Access holen
+ mxMaterialHolder = Reference< XMaterialHolder >::query( mxUnoAccess );
+
+ // ExactName vom Access holen
+ mxExactName = Reference< XExactName >::query( mxUnoAccess );
+}
+
+
+
+
+// #67781 Start einer Liste aller SbUnoMethod-Instanzen
+static SbUnoMethod* pFirst = NULL;
+
+SbUnoMethod::SbUnoMethod
+(
+ const String& aName_,
+ SbxDataType eSbxType,
+ Reference< XIdlMethod > xUnoMethod_,
+ bool bInvocation
+)
+ : SbxMethod( aName_, eSbxType )
+ , mbInvocation( bInvocation )
+{
+ m_xUnoMethod = xUnoMethod_;
+ pParamInfoSeq = NULL;
+
+ // #67781 Methode in Liste eintragen
+ pNext = pFirst;
+ pPrev = NULL;
+ pFirst = this;
+ if( pNext )
+ pNext->pPrev = this;
+}
+
+SbUnoMethod::~SbUnoMethod()
+{
+ delete pParamInfoSeq;
+
+ if( this == pFirst )
+ pFirst = pNext;
+ else if( pPrev )
+ pPrev->pNext = pNext;
+ if( pNext )
+ pNext->pPrev = pPrev;
+}
+
+SbxInfo* SbUnoMethod::GetInfo()
+{
+/*?*/ // if( !pInfo && m_xUnoMethod.is() )
+/*?*/ // {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // {
+/*?*/ // pInfo = new SbxInfo();
+/*?*/ //
+/*?*/ // const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
+/*?*/ // const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+/*?*/ // UINT32 nParamCount = rInfoSeq.getLength();
+/*?*/ //
+/*?*/ // for( UINT32 i = 0 ; i < nParamCount ; i++ )
+/*?*/ // {
+/*?*/ // const ParamInfo& rInfo = pParamInfos[i];
+/*?*/ // OUString aParamName = rInfo.aName;
+/*?*/ //
+/*?*/ // // const Reference< XIdlClass >& rxClass = rInfo.aType;
+/*?*/ // SbxDataType t = SbxVARIANT;
+/*?*/ // USHORT nFlags_ = SBX_READ;
+/*?*/ // pInfo->AddParam( aParamName, t, nFlags_ );
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+ return pInfo;
+}
+
+const Sequence<ParamInfo>& SbUnoMethod::getParamInfos( void )
+{
+ if( !pParamInfoSeq && m_xUnoMethod.is() )
+ {
+ Sequence<ParamInfo> aTmp = m_xUnoMethod->getParameterInfos() ;
+ pParamInfoSeq = new Sequence<ParamInfo>( aTmp );
+ }
+ return *pParamInfoSeq;
+}
+
+SbUnoProperty::SbUnoProperty
+(
+ const String& aName_,
+ SbxDataType eSbxType,
+ const Property& aUnoProp_,
+ INT32 nId_,
+ bool bInvocation
+)
+ : SbxProperty( aName_, eSbxType )
+ , aUnoProp( aUnoProp_ )
+ , nId( nId_ )
+ , mbInvocation( bInvocation )
+{
+ // #54548, bei bedarf Dummy-Array einsetzen, damit SbiRuntime::CheckArray() geht
+ static SbxArrayRef xDummyArray = new SbxArray( SbxVARIANT );
+ if( eSbxType & SbxARRAY )
+ PutObject( xDummyArray );
+}
+
+SbUnoProperty::~SbUnoProperty()
+{}
+
+
+/*?*/ // // #72732 Spezielle SbxVariable, die beim put/get prueft,
+/*?*/ // // ob der Kontext fuer eine UnoClass sinnvoll ist. Sonst
+/*?*/ // // liegt eventuell ein Schreibfehler im Basic-Source vor.
+/*?*/ // BOOL UnoClassMemberVariable::Get( SbxValues& rRes ) const
+/*?*/ // {
+/*?*/ // // Zugriff auf den Member einer UnoClass mit Parametern ist unsinnig
+/*?*/ // if( GetParameters() )
+/*?*/ // {
+/*?*/ // if( mpRuntime )
+/*?*/ // mpRuntime->Error( SbERR_NO_METHOD );
+/*?*/ // }
+/*?*/ // return SbxVariable::Get( rRes );
+/*?*/ // }
+/*?*/ //
+/*?*/ // BOOL UnoClassMemberVariable::Put( const SbxValues& rRes )
+/*?*/ // {
+/*?*/ // if( bInternalUse )
+/*?*/ // {
+/*?*/ // return SbxVariable::Put( rRes );
+/*?*/ // }
+/*?*/ // // Schreibzugriff auf den Member einer UnoClass ist immer falsch
+/*?*/ // mpRuntime->Error( SbERR_NO_METHOD );
+/*?*/ // return FALSE;
+/*?*/ // }
+/*?*/ //
+/*?*/ // TYPEINIT1(UnoClassMemberVariable,SbxVariable)
+
+SbxVariable* SbUnoObject::Find( const XubString& rName, SbxClassType t )
+{
+ static Reference< XIdlMethod > xDummyMethod;
+ static Property aDummyProp;
+
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+
+ if( bNeedIntrospection )
+ doIntrospection();
+
+ // Neu 4.3.1999: Properties on Demand anlegen, daher jetzt perIntrospectionAccess
+ // suchen, ob doch eine Property oder Methode des geforderten Namens existiert
+ if( !pRes )
+ {
+ OUString aUName( rName );
+ if( mxUnoAccess.is() )
+ {
+ if( mxExactName.is() )
+ {
+ OUString aUExactName = mxExactName->getExactName( aUName );
+ if( aUExactName.getLength() )
+ aUName = aUExactName;
+ }
+ if( mxUnoAccess->hasProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ) )
+ {
+ const Property& rProp = mxUnoAccess->
+ getProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+
+ // #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
+ SbxDataType eSbxType;
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ eSbxType = SbxVARIANT;
+ else
+ eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
+
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, 0, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxUnoAccess->hasMethod( aUName,
+ MethodConcept::ALL - MethodConcept::DANGEROUS ) )
+ {
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = mxUnoAccess->
+ getMethod( aUName, MethodConcept::ALL - MethodConcept::DANGEROUS );
+
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( rxMethod->getName(),
+ unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+
+ // Wenn immer noch nichts gefunden wurde, muss geprueft werden, ob NameAccess vorliegt
+ if( !pRes )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ OUString aUName2( rName );
+
+ if( xNameAccess.is() && xNameAccess->hasByName( aUName2 ) )
+ {
+ Any aAny = xNameAccess->getByName( aUName2 );
+
+ // ACHTUNG: Die hier erzeugte Variable darf wegen bei XNameAccess
+ // nicht als feste Property in das Object aufgenommen werden und
+ // wird daher nirgendwo gehalten.
+ // Wenn das Probleme gibt, muss das kuenstlich gemacht werden oder
+ // es muss eine Klasse SbUnoNameAccessProperty geschaffen werden,
+ // bei der die Existenz staendig neu ueberprueft und die ggf. weg-
+ // geworfen wird, wenn der Name nicht mehr gefunden wird.
+ pRes = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( pRes, aAny );
+ }
+ }
+ catch( NoSuchElementException& e )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ }
+ }
+ if( !pRes && mxInvocation.is() )
+ {
+ if( mxExactNameInvocation.is() )
+ {
+ OUString aUExactName = mxExactNameInvocation->getExactName( aUName );
+ if( aUExactName.getLength() )
+ aUName = aUExactName;
+ }
+
+ try
+ {
+ if( mxInvocation->hasProperty( aUName ) )
+ {
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, aDummyProp, 0, true );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxInvocation->hasMethod( aUName ) )
+ {
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+ }
+ catch( RuntimeException& e )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+ }
+ }
+
+ // Ganz am Schluss noch pruefen, ob die Dbg_-Properties gemeint sind
+
+ if( !pRes )
+ {
+ if( rName.EqualsIgnoreCaseAscii( ID_DBG_SUPPORTEDINTERFACES ) ||
+ rName.EqualsIgnoreCaseAscii( ID_DBG_PROPERTIES ) ||
+ rName.EqualsIgnoreCaseAscii( ID_DBG_METHODS ) )
+ {
+ // Anlegen
+ implCreateDbgProperties();
+
+ // Jetzt muessen sie regulaer gefunden werden
+ pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
+ }
+ }
+ return pRes;
+}
+
+
+// Hilfs-Methode zum Anlegen der dbg_-Properties
+void SbUnoObject::implCreateDbgProperties( void )
+{
+ Property aProp;
+
+ // Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
+ SbxVariableRef xVarRef = new SbUnoProperty( ID_DBG_SUPPORTEDINTERFACES, SbxSTRING, aProp, -1, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+
+ // Id == -2: Properties ausgeben
+ xVarRef = new SbUnoProperty( ID_DBG_PROPERTIES, SbxSTRING, aProp, -2, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+
+ // Id == -3: Methoden ausgeben
+ xVarRef = new SbUnoProperty( ID_DBG_METHODS, SbxSTRING, aProp, -3, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+}
+
+void SbUnoObject::implCreateAll( void )
+{
+ // Bestehende Methoden und Properties alle wieder wegwerfen
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+
+ if( bNeedIntrospection ) doIntrospection();
+
+ // Instrospection besorgen
+ Reference< XIntrospectionAccess > xAccess = mxUnoAccess;
+ if( !xAccess.is() )
+ {
+ if( mxInvocation.is() )
+ xAccess = mxInvocation->getIntrospection();
+ }
+ if( !xAccess.is() )
+ return;
+
+ // Properties anlegen
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ UINT32 nPropCount = props.getLength();
+ const Property* pProps_ = props.getConstArray();
+
+ UINT32 i;
+ for( i = 0 ; i < nPropCount ; i++ )
+ {
+ const Property& rProp = pProps_[ i ];
+
+ // #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
+ SbxDataType eSbxType;
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ eSbxType = SbxVARIANT;
+ else
+ eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
+
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, i, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+ }
+
+ // Dbg_-Properties anlegen
+ implCreateDbgProperties();
+
+ // Methoden anlegen
+ Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ UINT32 nMethCount = aMethodSeq.getLength();
+ const Reference< XIdlMethod >* pMethods_ = aMethodSeq.getConstArray();
+ for( i = 0 ; i < nMethCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = pMethods_[i];
+
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod
+ ( rxMethod->getName(), unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
+ QuickInsert( (SbxVariable*)xMethRef );
+ }
+}
+
+
+// Wert rausgeben
+Any SbUnoObject::getUnoAny( void )
+{
+ Any aRetAny;
+ if( bNeedIntrospection ) doIntrospection();
+ if( mxMaterialHolder.is() )
+ aRetAny = mxMaterialHolder->getMaterial();
+ else if( mxInvocation.is() )
+ aRetAny <<= mxInvocation;
+ return aRetAny;
+}
+
+// Hilfsmethode zum Anlegen einer Uno-Struct per CoreReflection
+SbUnoObject* Impl_CreateUnoStruct( const String& aClassName )
+{
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( !xCoreReflection.is() )
+ return NULL;
+
+ // Klasse suchen
+ Reference< XIdlClass > xClass;
+ Reference< XHierarchicalNameAccess > xHarryName =
+ getCoreReflection_HierarchicalNameAccess_Impl();
+ if( xHarryName.is() && xHarryName->hasByHierarchicalName( aClassName ) )
+ xClass = xCoreReflection->forName( aClassName );
+ if( !xClass.is() )
+ return NULL;
+
+ // Ist es ueberhaupt ein struct?
+ TypeClass eType = xClass->getTypeClass();
+ if( eType != TypeClass_STRUCT )
+ return NULL;
+
+ // Instanz erzeugen
+ Any aNewAny;
+ xClass->createObject( aNewAny );
+
+ // SbUnoObject daraus basteln
+ SbUnoObject* pUnoObj = new SbUnoObject( aClassName, aNewAny );
+ return pUnoObj;
+}
+
+
+// Factory-Klasse fuer das Anlegen von Uno-Structs per DIM AS NEW
+SbxBase* SbUnoFactory::Create( UINT16, UINT32 )
+{
+ // Ueber SbxId laeuft in Uno nix
+ return NULL;
+}
+
+SbxObject* SbUnoFactory::CreateObject( const String& rClassName )
+{
+ return Impl_CreateUnoStruct( rClassName );
+}
+
+// Funktion, um einen globalen Bezeichner im
+// UnoScope zu suchen und fuer Sbx zu wrappen
+SbxVariable* findUnoClass( const String& rName )
+{
+ // #105550 Check if module exists
+ SbUnoClass* pUnoClass = NULL;
+
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ Reference< XTypeDescription > xTypeDesc;
+ if( xTypeAccess->hasByHierarchicalName( rName ) )
+ {
+ Any aRet = xTypeAccess->getByHierarchicalName( rName );
+ aRet >>= xTypeDesc;
+
+ if( xTypeDesc.is() )
+ {
+ TypeClass eTypeClass = xTypeDesc->getTypeClass();
+ if( eTypeClass == TypeClass_MODULE || eTypeClass == TypeClass_CONSTANTS )
+ pUnoClass = new SbUnoClass( rName );
+ }
+ }
+ return pUnoClass;
+}
+
+SbxVariable* SbUnoClass::Find( const XubString& rName, SbxClassType t )
+{
+ (void)t;
+
+ SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_VARIABLE );
+
+ // Wenn nichts gefunden wird, ist das Sub-Modul noch nicht bekannt
+ if( !pRes )
+ {
+ // Wenn es schon eine Klasse ist, nach einen Feld fragen
+ if( m_xClass.is() )
+ {
+ // Ist es ein Field
+ OUString aUStr( rName );
+ Reference< XIdlField > xField = m_xClass->getField( aUStr );
+ Reference< XIdlClass > xClass;
+ if( xField.is() )
+ {
+ try
+ {
+ Any aAny;
+ aAny = xField->get( aAny );
+
+ // Nach Sbx wandeln
+ pRes = new SbxVariable( SbxVARIANT );
+ pRes->SetName( rName );
+ unoToSbxValue( pRes, aAny );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( IllegalArgumentException& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e3, aIllegalArgumentExceptionName ) );
+ }
+ }
+ }
+ else
+ {
+ // Vollqualifizierten Namen erweitern
+ String aNewName = GetName();
+ aNewName.AppendAscii( "." );
+ aNewName += rName;
+
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( xCoreReflection.is() )
+ {
+ // Ist es eine Konstante?
+ Reference< XHierarchicalNameAccess > xHarryName( xCoreReflection, UNO_QUERY );
+ if( xHarryName.is() )
+ {
+ try
+ {
+ Any aValue = xHarryName->getByHierarchicalName( aNewName );
+ TypeClass eType = aValue.getValueType().getTypeClass();
+
+ // Interface gefunden? Dann ist es eine Klasse
+ if( eType == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > xIface = *(Reference< XInterface >*)aValue.getValue();
+ Reference< XIdlClass > xClass( xIface, UNO_QUERY );
+ if( xClass.is() )
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)new SbUnoClass( aNewName, xClass );
+ pRes->PutObject( xWrapper );
+
+ }
+ }
+ else
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( pRes, aValue );
+ }
+ }
+ catch( NoSuchElementException& e1 )
+ {
+ String aMsg = implGetExceptionMsg( e1 );
+ }
+ }
+
+ // Sonst wieder als Klasse annehmen
+ if( !pRes )
+ {
+ SbxVariable* pNewClass = findUnoClass( aNewName );
+ if( pNewClass )
+ {
+ Reference< XIdlClass > xClass;
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)pNewClass;
+ pRes->PutObject( xWrapper );
+ }
+ }
+ }
+ }
+
+ if( pRes )
+ {
+ pRes->SetName( rName );
+
+ // Variable einfuegen, damit sie spaeter im Find gefunden wird
+ QuickInsert( pRes );
+
+ // Uns selbst gleich wieder als Listener rausnehmen,
+ // die Werte sind alle konstant
+ if( pRes->IsBroadcaster() )
+ EndListening( pRes->GetBroadcaster(), TRUE );
+ }
+ }
+ return pRes;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */