1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/mutex.hxx>
21 #include <vcl/svapp.hxx>
22 #include <tools/errcode.hxx>
23 #include <svl/hint.hxx>
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>
33 #include <rtl/instance.hxx>
34 #include <rtl/strbuf.hxx>
35 #include <rtl/ustrbuf.hxx>
37 #include <com/sun/star/script/ArrayWrapper.hpp>
38 #include <com/sun/star/script/NativeObjectWrapper.hpp>
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/Introspection.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/bridge/oleautomation/NamedArgument.hpp>
65 #include <com/sun/star/bridge/oleautomation/Date.hpp>
66 #include <com/sun/star/bridge/oleautomation/Decimal.hpp>
67 #include <com/sun/star/bridge/oleautomation/Currency.hpp>
68 #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
69 #include <com/sun/star/script/XAutomationInvocation.hpp>
70 #include <basic/codecompletecache.hxx>
72 using com::sun::star::uno::Reference
;
73 using namespace com::sun::star::uno
;
74 using namespace com::sun::star::lang
;
75 using namespace com::sun::star::reflection
;
76 using namespace com::sun::star::beans
;
77 using namespace com::sun::star::script
;
78 using namespace com::sun::star::container
;
79 using namespace com::sun::star::bridge
;
83 #include<basic/sbstar.hxx>
84 #include<basic/sbuno.hxx>
85 #include<basic/sberrors.hxx>
86 #include<sbunoobj.hxx>
88 #include<basic/basmgr.hxx>
89 #include<sbintern.hxx>
93 #include <boost/unordered_map.hpp>
94 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
95 #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
97 TYPEINIT1(SbUnoMethod
,SbxMethod
)
98 TYPEINIT1(SbUnoProperty
,SbxProperty
)
99 TYPEINIT1(SbUnoObject
,SbxObject
)
100 TYPEINIT1(SbUnoStructRefObject
,SbxObject
)
101 TYPEINIT1(SbUnoClass
,SbxObject
)
102 TYPEINIT1(SbUnoService
,SbxObject
)
103 TYPEINIT1(SbUnoServiceCtor
,SbxMethod
)
104 TYPEINIT1(SbUnoSingleton
,SbxObject
)
106 typedef WeakImplHelper1
< XAllListener
> BasicAllListenerHelper
;
108 // Identifiers for creating the strings for dbg_Properties
109 static char const ID_DBG_SUPPORTEDINTERFACES
[] = "Dbg_SupportedInterfaces";
110 static char const ID_DBG_PROPERTIES
[] = "Dbg_Properties";
111 static char const ID_DBG_METHODS
[] = "Dbg_Methods";
113 static char const aSeqLevelStr
[] = "[]";
114 static char const defaultNameSpace
[] = "ooo.vba";
116 // Gets the default property for an uno object. Note: There is some
117 // redirection built in. The property name specifies the name
118 // of the default property.
120 bool SbUnoObject::getDefaultPropName( SbUnoObject
* pUnoObj
, OUString
& sDfltProp
)
123 Reference
< XDefaultProperty
> xDefaultProp( pUnoObj
->maTmpUnoObj
, UNO_QUERY
);
124 if ( xDefaultProp
.is() )
126 sDfltProp
= xDefaultProp
->getDefaultPropertyName();
127 if ( !sDfltProp
.isEmpty() )
133 SbxVariable
* getDefaultProp( SbxVariable
* pRef
)
135 SbxVariable
* pDefaultProp
= NULL
;
136 if ( pRef
->GetType() == SbxOBJECT
)
138 SbxObject
* pObj
= PTR_CAST(SbxObject
,(SbxVariable
*) pRef
);
141 SbxBase
* pObjVarObj
= pRef
->GetObject();
142 pObj
= PTR_CAST(SbxObject
,pObjVarObj
);
144 if ( pObj
&& pObj
->ISA(SbUnoObject
) )
146 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,(SbxObject
*)pObj
);
147 pDefaultProp
= pUnoObj
->GetDfltProperty();
153 void SetSbUnoObjectDfltPropName( SbxObject
* pObj
)
155 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,(SbxObject
*) pObj
);
158 OUString sDfltPropName
;
160 if ( SbUnoObject::getDefaultPropName( pUnoObj
, sDfltPropName
) )
162 OSL_TRACE("SetSbUnoObjectDfltPropName setting dflt prop for %s", OUStringToOString( pObj
->GetName(), RTL_TEXTENCODING_UTF8
).getStr() );
163 pUnoObj
->SetDfltProperty( sDfltPropName
);
168 // save CoreReflection statically
169 Reference
< XIdlReflection
> getCoreReflection_Impl( void )
171 static Reference
< XIdlReflection
> xCoreReflection
;
173 // Do we have already CoreReflection; if not obtain it
174 if( !xCoreReflection
.is() )
176 Reference
< XComponentContext
> xContext(
177 comphelper::getProcessComponentContext() );
180 xContext
->getValueByName(
181 OUString( "/singletons/com.sun.star.reflection.theCoreReflection" ) )
183 OSL_ENSURE( xCoreReflection
.is(), "### CoreReflection singleton not accessible!?" );
185 if( !xCoreReflection
.is() )
187 throw DeploymentException(
188 OUString( "/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible" ),
189 Reference
< XInterface
>() );
192 return xCoreReflection
;
195 // save CoreReflection statically
196 Reference
< XHierarchicalNameAccess
> getCoreReflection_HierarchicalNameAccess_Impl( void )
198 static Reference
< XHierarchicalNameAccess
> xCoreReflection_HierarchicalNameAccess
;
200 if( !xCoreReflection_HierarchicalNameAccess
.is() )
202 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
203 if( xCoreReflection
.is() )
205 xCoreReflection_HierarchicalNameAccess
=
206 Reference
< XHierarchicalNameAccess
>( xCoreReflection
, UNO_QUERY
);
209 return xCoreReflection_HierarchicalNameAccess
;
212 // Hold TypeProvider statically
213 Reference
< XHierarchicalNameAccess
> getTypeProvider_Impl( void )
215 static Reference
< XHierarchicalNameAccess
> xAccess
;
217 // Do we have already CoreReflection; if not obtain it
220 Reference
< XComponentContext
> xContext(
221 comphelper::getProcessComponentContext() );
224 xContext
->getValueByName(
225 OUString( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) )
227 OSL_ENSURE( xAccess
.is(), "### TypeDescriptionManager singleton not accessible!?" );
231 throw DeploymentException(
232 OUString("/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessible"),
233 Reference
< XInterface
>() );
239 // Hold TypeConverter statically
240 Reference
< XTypeConverter
> getTypeConverter_Impl( void )
242 static Reference
< XTypeConverter
> xTypeConverter
;
244 // Do we have already CoreReflection; if not obtain it
245 if( !xTypeConverter
.is() )
247 Reference
< XComponentContext
> xContext(
248 comphelper::getProcessComponentContext() );
251 xTypeConverter
= Converter::create(xContext
);
253 if( !xTypeConverter
.is() )
255 throw DeploymentException(
256 OUString("com.sun.star.script.Converter service not accessible"),
257 Reference
< XInterface
>() );
260 return xTypeConverter
;
264 // #111851 factory function to create an OLE object
265 SbUnoObject
* createOLEObject_Impl( const OUString
& aType
)
267 static Reference
< XMultiServiceFactory
> xOLEFactory
;
268 static bool bNeedsInit
= true;
274 Reference
< XComponentContext
> xContext(
275 comphelper::getProcessComponentContext() );
278 Reference
<XMultiComponentFactory
> xSMgr
= xContext
->getServiceManager();
279 xOLEFactory
= Reference
<XMultiServiceFactory
>(
280 xSMgr
->createInstanceWithContext(
281 OUString( "com.sun.star.bridge.OleObjectFactory"),
282 xContext
), UNO_QUERY
);
286 SbUnoObject
* pUnoObj
= NULL
;
287 if( xOLEFactory
.is() )
289 // some type names available in VBA can not be directly used in COM
290 OUString aOLEType
= aType
;
291 if ( aOLEType
== "SAXXMLReader30" )
293 aOLEType
= "Msxml2.SAXXMLReader.3.0";
295 Reference
< XInterface
> xOLEObject
= xOLEFactory
->createInstance( aOLEType
);
296 if( xOLEObject
.is() )
300 pUnoObj
= new SbUnoObject( aType
, aAny
);
301 OUString sDfltPropName
;
303 if ( SbUnoObject::getDefaultPropName( pUnoObj
, sDfltPropName
) )
304 pUnoObj
->SetDfltProperty( sDfltPropName
);
313 void lcl_indent( OUStringBuffer
& _inout_rBuffer
, sal_Int32 _nLevel
)
315 while ( _nLevel
-- > 0 )
317 _inout_rBuffer
.appendAscii( " " );
322 void implAppendExceptionMsg( OUStringBuffer
& _inout_rBuffer
, const Exception
& _e
, const OUString
& _rExceptionType
, sal_Int32 _nLevel
)
324 _inout_rBuffer
.appendAscii( "\n" );
325 lcl_indent( _inout_rBuffer
, _nLevel
);
326 _inout_rBuffer
.appendAscii( "Type: " );
328 if ( _rExceptionType
.isEmpty() )
329 _inout_rBuffer
.appendAscii( "Unknown" );
331 _inout_rBuffer
.append( _rExceptionType
);
333 _inout_rBuffer
.appendAscii( "\n" );
334 lcl_indent( _inout_rBuffer
, _nLevel
);
335 _inout_rBuffer
.appendAscii( "Message: " );
336 _inout_rBuffer
.append( _e
.Message
);
340 // construct an error message for the exception
341 OUString
implGetExceptionMsg( const Exception
& e
, const OUString
& aExceptionType_
)
343 OUStringBuffer aMessageBuf
;
344 implAppendExceptionMsg( aMessageBuf
, e
, aExceptionType_
, 0 );
345 return aMessageBuf
.makeStringAndClear();
348 OUString
implGetExceptionMsg( const Any
& _rCaughtException
)
350 OSL_PRECOND( _rCaughtException
.getValueTypeClass() == TypeClass_EXCEPTION
, "implGetExceptionMsg: illegal argument!" );
351 if ( _rCaughtException
.getValueTypeClass() != TypeClass_EXCEPTION
)
355 return implGetExceptionMsg( *static_cast< const Exception
* >( _rCaughtException
.getValue() ), _rCaughtException
.getValueTypeName() );
358 Any
convertAny( const Any
& rVal
, const Type
& aDestType
)
361 Reference
< XTypeConverter
> xConverter
= getTypeConverter_Impl();
364 aConvertedVal
= xConverter
->convertTo( rVal
, aDestType
);
366 catch( const IllegalArgumentException
& )
368 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
369 implGetExceptionMsg( ::cppu::getCaughtException() ) );
370 return aConvertedVal
;
372 catch( const CannotConvertException
& e2
)
374 OUString
aCannotConvertExceptionName( "com.sun.star.lang.IllegalArgumentException");
375 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
376 implGetExceptionMsg( e2
, aCannotConvertExceptionName
) );
377 return aConvertedVal
;
379 return aConvertedVal
;
383 // #105565 Special Object to wrap a strongly typed Uno Any
384 TYPEINIT1(SbUnoAnyObject
,SbxObject
)
387 // TODO: source out later
388 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
)
390 // register void as default class
391 Reference
<XIdlClass
> xRetClass
;
392 typelib_TypeDescription
* pTD
= 0;
393 rType
.getDescription( &pTD
);
397 OUString
sOWName( pTD
->pTypeName
);
398 Reference
< XIdlReflection
> xRefl
= getCoreReflection_Impl();
399 xRetClass
= xRefl
->forName( sOWName
);
404 // Exception type unknown
405 template< class EXCEPTION
>
406 OUString
implGetExceptionMsg( const EXCEPTION
& e
)
408 return implGetExceptionMsg( e
, ::getCppuType( &e
).getTypeName() );
411 void implHandleBasicErrorException( BasicErrorException
& e
)
413 SbError nError
= StarBASIC::GetSfxFromVBError( (sal_uInt16
)e
.ErrorCode
);
414 StarBASIC::Error( nError
, e
.ErrorMessageArgument
);
417 void implHandleWrappedTargetException( const Any
& _rWrappedTargetException
)
419 Any
aExamine( _rWrappedTargetException
);
421 // completely strip the first InvocationTargetException, its error message isn't of any
422 // interest to the user, it just says something like "invoking the UNO method went wrong.".
423 InvocationTargetException aInvocationError
;
424 if ( aExamine
>>= aInvocationError
)
425 aExamine
= aInvocationError
.TargetException
;
427 BasicErrorException aBasicError
;
429 SbError
nError( ERRCODE_BASIC_EXCEPTION
);
430 OUStringBuffer aMessageBuf
;
432 // strip any other WrappedTargetException instances, but this time preserve the error messages.
433 WrappedTargetException aWrapped
;
434 sal_Int32 nLevel
= 0;
435 while ( aExamine
>>= aWrapped
)
437 // special handling for BasicErrorException errors
438 if ( aWrapped
.TargetException
>>= aBasicError
)
440 nError
= StarBASIC::GetSfxFromVBError( (sal_uInt16
)aBasicError
.ErrorCode
);
441 aMessageBuf
.append( aBasicError
.ErrorMessageArgument
);
446 // append this round's message
447 implAppendExceptionMsg( aMessageBuf
, aWrapped
, aExamine
.getValueTypeName(), nLevel
);
448 if ( aWrapped
.TargetException
.getValueTypeClass() == TypeClass_EXCEPTION
)
449 // there is a next chain element
450 aMessageBuf
.appendAscii( "\nTargetException:" );
453 aExamine
= aWrapped
.TargetException
;
457 if ( aExamine
.getValueTypeClass() == TypeClass_EXCEPTION
)
459 // the last element in the chain is still an exception, but no WrappedTargetException
460 implAppendExceptionMsg( aMessageBuf
, *static_cast< const Exception
* >( aExamine
.getValue() ), aExamine
.getValueTypeName(), nLevel
);
463 StarBASIC::Error( nError
, aMessageBuf
.makeStringAndClear() );
466 static void implHandleAnyException( const Any
& _rCaughtException
)
468 BasicErrorException aBasicError
;
469 WrappedTargetException aWrappedError
;
471 if ( _rCaughtException
>>= aBasicError
)
473 implHandleBasicErrorException( aBasicError
);
475 else if ( _rCaughtException
>>= aWrappedError
)
477 implHandleWrappedTargetException( _rCaughtException
);
481 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( _rCaughtException
) );
485 // NativeObjectWrapper handling
488 SbxObjectRef m_xNativeObj
;
492 ObjectItem( SbxObject
* pNativeObj
)
493 : m_xNativeObj( pNativeObj
)
497 typedef std::vector
< ObjectItem
> NativeObjectWrapperVector
;
498 class GaNativeObjectWrapperVector
: public rtl::Static
<NativeObjectWrapperVector
, GaNativeObjectWrapperVector
> {};
500 void clearNativeObjectWrapperVector( void )
502 GaNativeObjectWrapperVector::get().clear();
505 static sal_uInt32
lcl_registerNativeObjectWrapper( SbxObject
* pNativeObj
)
507 NativeObjectWrapperVector
&rNativeObjectWrapperVector
= GaNativeObjectWrapperVector::get();
508 sal_uInt32 nIndex
= rNativeObjectWrapperVector
.size();
509 rNativeObjectWrapperVector
.push_back( ObjectItem( pNativeObj
) );
513 static SbxObject
* lcl_getNativeObject( sal_uInt32 nIndex
)
515 SbxObjectRef xRetObj
;
516 NativeObjectWrapperVector
&rNativeObjectWrapperVector
= GaNativeObjectWrapperVector::get();
517 if( nIndex
< rNativeObjectWrapperVector
.size() )
519 ObjectItem
& rItem
= rNativeObjectWrapperVector
[ nIndex
];
520 xRetObj
= rItem
.m_xNativeObj
;
525 // convert from Uno to Sbx
526 SbxDataType
unoToSbxType( TypeClass eType
)
528 SbxDataType eRetType
= SbxVOID
;
532 case TypeClass_INTERFACE
:
534 case TypeClass_STRUCT
:
535 case TypeClass_EXCEPTION
: eRetType
= SbxOBJECT
; break;
537 case TypeClass_ENUM
: eRetType
= SbxLONG
; break;
538 case TypeClass_SEQUENCE
:
539 eRetType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
543 case TypeClass_ANY
: eRetType
= SbxVARIANT
; break;
544 case TypeClass_BOOLEAN
: eRetType
= SbxBOOL
; break;
545 case TypeClass_CHAR
: eRetType
= SbxCHAR
; break;
546 case TypeClass_STRING
: eRetType
= SbxSTRING
; break;
547 case TypeClass_FLOAT
: eRetType
= SbxSINGLE
; break;
548 case TypeClass_DOUBLE
: eRetType
= SbxDOUBLE
; break;
549 case TypeClass_BYTE
: eRetType
= SbxINTEGER
; break;
550 case TypeClass_SHORT
: eRetType
= SbxINTEGER
; break;
551 case TypeClass_LONG
: eRetType
= SbxLONG
; break;
552 case TypeClass_HYPER
: eRetType
= SbxSALINT64
; break;
553 case TypeClass_UNSIGNED_SHORT
: eRetType
= SbxUSHORT
; break;
554 case TypeClass_UNSIGNED_LONG
: eRetType
= SbxULONG
; break;
555 case TypeClass_UNSIGNED_HYPER
: eRetType
= SbxSALUINT64
;break;
561 SbxDataType
unoToSbxType( const Reference
< XIdlClass
>& xIdlClass
)
563 SbxDataType eRetType
= SbxVOID
;
566 TypeClass eType
= xIdlClass
->getTypeClass();
567 eRetType
= unoToSbxType( eType
);
572 static void implSequenceToMultiDimArray( SbxDimArray
*& pArray
, Sequence
< sal_Int32
>& indices
, Sequence
< sal_Int32
>& sizes
, const Any
& aValue
, sal_Int32
& dimension
, sal_Bool bIsZeroIndex
, Type
* pType
= NULL
)
574 Type aType
= aValue
.getValueType();
575 TypeClass eTypeClass
= aType
.getTypeClass();
577 sal_Int32 dimCopy
= dimension
;
579 if ( eTypeClass
== TypeClass_SEQUENCE
)
581 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aType
);
582 Reference
< XIdlArray
> xIdlArray
= xIdlTargetClass
->getArray();
583 typelib_TypeDescription
* pTD
= 0;
584 aType
.getDescription( &pTD
);
585 Type
aElementType( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
586 ::typelib_typedescription_release( pTD
);
588 sal_Int32 nLen
= xIdlArray
->getLen( aValue
);
589 for ( sal_Int32 index
= 0; index
< nLen
; ++index
)
591 Any aElementAny
= xIdlArray
->get( aValue
, (sal_uInt32
)index
);
592 // This detects the dimension were currently processing
593 if ( dimCopy
== dimension
)
596 if ( sizes
.getLength() < dimCopy
)
598 sizes
.realloc( sizes
.getLength() + 1 );
599 sizes
[ sizes
.getLength() - 1 ] = nLen
;
600 indices
.realloc( indices
.getLength() + 1 );
605 indices
[ dimCopy
- 1 ] = index
;
607 indices
[ dimCopy
- 1] = index
+ 1;
609 implSequenceToMultiDimArray( pArray
, indices
, sizes
, aElementAny
, dimCopy
, bIsZeroIndex
, &aElementType
);
615 if ( indices
.getLength() < 1 )
617 // Should never ever get here ( indices.getLength()
618 // should equal number of dimensions in the array )
619 // And that should at least be 1 !
620 // #QUESTION is there a better error?
621 StarBASIC::Error( SbERR_INVALID_OBJECT
);
625 SbxDataType eSbxElementType
= unoToSbxType( pType
? pType
->getTypeClass() : aValue
.getValueTypeClass() );
628 pArray
= new SbxDimArray( eSbxElementType
);
629 sal_Int32 nIndexLen
= indices
.getLength();
631 // Dimension the array
632 for ( sal_Int32 index
= 0; index
< nIndexLen
; ++index
)
635 pArray
->unoAddDim32( 0, sizes
[ index
] - 1);
637 pArray
->unoAddDim32( 1, sizes
[ index
] );
644 SbxVariableRef xVar
= new SbxVariable( eSbxElementType
);
645 unoToSbxValue( (SbxVariable
*)xVar
, aValue
);
647 sal_Int32
* pIndices
= indices
.getArray();
648 pArray
->Put32( (SbxVariable
*)xVar
, pIndices
);
654 void unoToSbxValue( SbxVariable
* pVar
, const Any
& aValue
)
656 Type aType
= aValue
.getValueType();
657 TypeClass eTypeClass
= aType
.getTypeClass();
662 // Map Type to IdlClass
665 Reference
<XIdlClass
> xClass
= TypeToIdlClass( aType_
);
667 aClassAny
<<= xClass
;
669 // instantiate SbUnoObject
671 SbUnoObject
* pSbUnoObject
= new SbUnoObject( aName
, aClassAny
);
672 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
674 // If the object is invalid deliver null
675 if( pSbUnoObject
->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID
)
677 pVar
->PutObject( NULL
);
681 pVar
->PutObject( xWrapper
);
685 // Interfaces and Structs must be wrapped in a SbUnoObject
686 case TypeClass_INTERFACE
:
687 case TypeClass_STRUCT
:
688 case TypeClass_EXCEPTION
:
690 if( eTypeClass
== TypeClass_STRUCT
)
693 NativeObjectWrapper aNativeObjectWrapper
;
694 if ( (aValue
>>= aWrap
) )
696 SbxDimArray
* pArray
= NULL
;
697 Sequence
< sal_Int32
> indices
;
698 Sequence
< sal_Int32
> sizes
;
699 sal_Int32 dimension
= 0;
700 implSequenceToMultiDimArray( pArray
, indices
, sizes
, aWrap
.Array
, dimension
, aWrap
.IsZeroIndex
);
703 SbxDimArrayRef xArray
= pArray
;
704 sal_uInt16 nFlags
= pVar
->GetFlags();
705 pVar
->ResetFlag( SBX_FIXED
);
706 pVar
->PutObject( (SbxDimArray
*)xArray
);
707 pVar
->SetFlags( nFlags
);
713 else if ( (aValue
>>= aNativeObjectWrapper
) )
715 sal_uInt32 nIndex
= 0;
716 if( (aNativeObjectWrapper
.ObjectId
>>= nIndex
) )
718 SbxObject
* pObj
= lcl_getNativeObject( nIndex
);
719 pVar
->PutObject( pObj
);
727 SbiInstance
* pInst
= GetSbData()->pInst
;
728 if( pInst
&& pInst
->IsCompatibility() )
730 oleautomation::Date aDate
;
731 if( (aValue
>>= aDate
) )
733 pVar
->PutDate( aDate
.Value
);
738 oleautomation::Decimal aDecimal
;
739 if( (aValue
>>= aDecimal
) )
741 pVar
->PutDecimal( aDecimal
);
746 oleautomation::Currency aCurrency
;
747 if( (aValue
>>= aCurrency
) )
749 pVar
->PutCurrency( aCurrency
.Value
);
757 // instantiate a SbUnoObject
759 SbUnoObject
* pSbUnoObject
= new SbUnoObject( aName
, aValue
);
760 //If this is called externally e.g. from the scripting
761 //framework then there is no 'active' runtime the default property will not be set up
762 //only a vba object will have XDefaultProp set anyway so... this
763 //test seems a bit of overkill
764 //if ( SbiRuntime::isVBAEnabled() )
766 OUString sDfltPropName
;
768 if ( SbUnoObject::getDefaultPropName( pSbUnoObject
, sDfltPropName
) )
770 pSbUnoObject
->SetDfltProperty( sDfltPropName
);
773 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
775 // If the object is invalid deliver null
776 if( pSbUnoObject
->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID
)
778 pVar
->PutObject( NULL
);
782 pVar
->PutObject( xWrapper
);
791 enum2int( nEnum
, aValue
);
792 pVar
->PutLong( nEnum
);
796 case TypeClass_SEQUENCE
:
798 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aType
);
799 Reference
< XIdlArray
> xIdlArray
= xIdlTargetClass
->getArray();
800 sal_Int32 i
, nLen
= xIdlArray
->getLen( aValue
);
802 typelib_TypeDescription
* pTD
= 0;
803 aType
.getDescription( &pTD
);
804 OSL_ASSERT( pTD
&& pTD
->eTypeClass
== typelib_TypeClass_SEQUENCE
);
805 Type
aElementType( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
806 ::typelib_typedescription_release( pTD
);
808 // build an Array in Basic
809 SbxDimArrayRef xArray
;
810 SbxDataType eSbxElementType
= unoToSbxType( aElementType
.getTypeClass() );
811 xArray
= new SbxDimArray( eSbxElementType
);
814 xArray
->unoAddDim32( 0, nLen
- 1 );
816 // register the elements as variables
817 for( i
= 0 ; i
< nLen
; i
++ )
820 Any aElementAny
= xIdlArray
->get( aValue
, (sal_uInt32
)i
);
821 SbxVariableRef xVar
= new SbxVariable( eSbxElementType
);
822 unoToSbxValue( (SbxVariable
*)xVar
, aElementAny
);
824 // put into the Array
825 xArray
->Put32( (SbxVariable
*)xVar
, &i
);
830 xArray
->unoAddDim( 0, -1 );
834 sal_uInt16 nFlags
= pVar
->GetFlags();
835 pVar
->ResetFlag( SBX_FIXED
);
836 pVar
->PutObject( (SbxDimArray
*)xArray
);
837 pVar
->SetFlags( nFlags
);
843 case TypeClass_BOOLEAN
: pVar
->PutBool( *(sal_Bool
*)aValue
.getValue() ); break;
846 pVar
->PutChar( *(sal_Unicode
*)aValue
.getValue() );
849 case TypeClass_STRING
: { OUString val
; aValue
>>= val
; pVar
->PutString( val
); } break;
850 case TypeClass_FLOAT
: { float val
= 0; aValue
>>= val
; pVar
->PutSingle( val
); } break;
851 case TypeClass_DOUBLE
: { double val
= 0; aValue
>>= val
; pVar
->PutDouble( val
); } break;
852 case TypeClass_BYTE
: { sal_Int8 val
= 0; aValue
>>= val
; pVar
->PutInteger( val
); } break;
853 case TypeClass_SHORT
: { sal_Int16 val
= 0; aValue
>>= val
; pVar
->PutInteger( val
); } break;
854 case TypeClass_LONG
: { sal_Int32 val
= 0; aValue
>>= val
; pVar
->PutLong( val
); } break;
855 case TypeClass_HYPER
: { sal_Int64 val
= 0; aValue
>>= val
; pVar
->PutInt64( val
); } break;
856 case TypeClass_UNSIGNED_SHORT
: { sal_uInt16 val
= 0; aValue
>>= val
; pVar
->PutUShort( val
); } break;
857 case TypeClass_UNSIGNED_LONG
: { sal_uInt32 val
= 0; aValue
>>= val
; pVar
->PutULong( val
); } break;
858 case TypeClass_UNSIGNED_HYPER
: { sal_uInt64 val
= 0; aValue
>>= val
; pVar
->PutUInt64( val
); } break;
859 default: pVar
->PutEmpty(); break;
863 // Deliver the reflection for Sbx types
864 Type
getUnoTypeForSbxBaseType( SbxDataType eType
)
866 Type aRetType
= getCppuVoidType();
869 case SbxNULL
: aRetType
= ::getCppuType( (const Reference
< XInterface
> *)0 ); break;
870 case SbxINTEGER
: aRetType
= ::getCppuType( (sal_Int16
*)0 ); break;
871 case SbxLONG
: aRetType
= ::getCppuType( (sal_Int32
*)0 ); break;
872 case SbxSINGLE
: aRetType
= ::getCppuType( (float*)0 ); break;
873 case SbxDOUBLE
: aRetType
= ::getCppuType( (double*)0 ); break;
874 case SbxCURRENCY
: aRetType
= ::getCppuType( (oleautomation::Currency
*)0 ); break;
875 case SbxDECIMAL
: aRetType
= ::getCppuType( (oleautomation::Decimal
*)0 ); break;
877 SbiInstance
* pInst
= GetSbData()->pInst
;
878 if( pInst
&& pInst
->IsCompatibility() )
879 aRetType
= ::getCppuType( (double*)0 );
881 aRetType
= ::getCppuType( (oleautomation::Date
*)0 );
884 case SbxSTRING
: aRetType
= ::getCppuType( (OUString
*)0 ); break;
885 case SbxBOOL
: aRetType
= ::getCppuType( (sal_Bool
*)0 ); break;
886 case SbxVARIANT
: aRetType
= ::getCppuType( (Any
*)0 ); break;
887 case SbxCHAR
: aRetType
= ::getCppuType( (sal_Unicode
*)0 ); break;
888 case SbxBYTE
: aRetType
= ::getCppuType( (sal_Int8
*)0 ); break;
889 case SbxUSHORT
: aRetType
= ::getCppuType( (sal_uInt16
*)0 ); break;
890 case SbxULONG
: aRetType
= ::getCppuType( (sal_uInt32
*)0 ); break;
891 // map machine-dependent ones to long for consistency
892 case SbxINT
: aRetType
= ::getCppuType( (sal_Int32
*)0 ); break;
893 case SbxUINT
: aRetType
= ::getCppuType( (sal_uInt32
*)0 ); break;
899 // Converting of Sbx to Uno without a know target class for TypeClass_ANY
900 Type
getUnoTypeForSbxValue( const SbxValue
* pVal
)
902 Type aRetType
= getCppuVoidType();
906 // convert SbxType to Uno
907 SbxDataType eBaseType
= pVal
->SbxValue::GetType();
908 if( eBaseType
== SbxOBJECT
)
910 SbxBaseRef xObj
= (SbxBase
*)pVal
->GetObject();
913 aRetType
= getCppuType( static_cast<Reference
<XInterface
> *>(0) );
917 if( xObj
->ISA(SbxDimArray
) )
919 SbxBase
* pObj
= (SbxBase
*)xObj
;
920 SbxDimArray
* pArray
= (SbxDimArray
*)pObj
;
922 short nDims
= pArray
->GetDims();
923 Type aElementType
= getUnoTypeForSbxBaseType( (SbxDataType
)(pArray
->GetType() & 0xfff) );
924 TypeClass eElementTypeClass
= aElementType
.getTypeClass();
926 // Normal case: One dimensional array
927 sal_Int32 nLower
, nUpper
;
928 if( nDims
== 1 && pArray
->GetDim32( 1, nLower
, nUpper
) )
930 if( eElementTypeClass
== TypeClass_VOID
|| eElementTypeClass
== TypeClass_ANY
)
932 // If all elements of the arrays are from the same type, take
933 // this one - otherwise the whole will be considered as Any-Sequence
934 bool bNeedsInit
= true;
936 sal_Int32 nSize
= nUpper
- nLower
+ 1;
937 sal_Int32 nIdx
= nLower
;
938 for( sal_Int32 i
= 0 ; i
< nSize
; i
++,nIdx
++ )
940 SbxVariableRef xVar
= pArray
->Get32( &nIdx
);
941 Type aType
= getUnoTypeForSbxValue( (SbxVariable
*)xVar
);
944 if( aType
.getTypeClass() == TypeClass_VOID
)
946 // if only first element is void: different types -> []any
947 // if all elements are void: []void is not allowed -> []any
948 aElementType
= getCppuType( (Any
*)0 );
951 aElementType
= aType
;
954 else if( aElementType
!= aType
)
956 // different types -> AnySequence
957 aElementType
= getCppuType( (Any
*)0 );
963 OUString aSeqTypeName
= aSeqLevelStr
+ aElementType
.getTypeName();
964 aRetType
= Type( TypeClass_SEQUENCE
, aSeqTypeName
);
966 // #i33795 Map also multi dimensional arrays to corresponding sequences
969 if( eElementTypeClass
== TypeClass_VOID
|| eElementTypeClass
== TypeClass_ANY
)
971 // For this check the array's dim structure does not matter
972 sal_uInt32 nFlatArraySize
= pArray
->Count32();
974 bool bNeedsInit
= true;
975 for( sal_uInt32 i
= 0 ; i
< nFlatArraySize
; i
++ )
977 SbxVariableRef xVar
= pArray
->SbxArray::Get32( i
);
978 Type aType
= getUnoTypeForSbxValue( (SbxVariable
*)xVar
);
981 if( aType
.getTypeClass() == TypeClass_VOID
)
983 // if only first element is void: different types -> []any
984 // if all elements are void: []void is not allowed -> []any
985 aElementType
= getCppuType( (Any
*)0 );
988 aElementType
= aType
;
991 else if( aElementType
!= aType
)
993 // different types -> AnySequence
994 aElementType
= getCppuType( (Any
*)0 );
1000 OUStringBuffer aSeqTypeName
;
1001 for( short iDim
= 0 ; iDim
< nDims
; iDim
++ )
1003 aSeqTypeName
.appendAscii(aSeqLevelStr
);
1005 aSeqTypeName
.append(aElementType
.getTypeName());
1006 aRetType
= Type( TypeClass_SEQUENCE
, aSeqTypeName
.makeStringAndClear() );
1009 // No array, but ...
1010 else if( xObj
->ISA(SbUnoObject
) )
1012 aRetType
= ((SbUnoObject
*)(SbxBase
*)xObj
)->getUnoAny().getValueType();
1015 else if( xObj
->ISA(SbUnoAnyObject
) )
1017 aRetType
= ((SbUnoAnyObject
*)(SbxBase
*)xObj
)->getValue().getValueType();
1019 // Otherwise it is a No-Uno-Basic-Object -> default==deliver void
1021 // No object, convert basic type
1024 aRetType
= getUnoTypeForSbxBaseType( eBaseType
);
1029 // converting of Sbx to Uno without known target class for TypeClass_ANY
1030 Any
sbxToUnoValueImpl( const SbxValue
* pVar
, bool bBlockConversionToSmallestType
= false )
1032 SbxDataType eBaseType
= pVar
->SbxValue::GetType();
1033 if( eBaseType
== SbxOBJECT
)
1035 SbxBaseRef xObj
= (SbxBase
*)pVar
->GetObject();
1038 if( xObj
->ISA(SbUnoAnyObject
) )
1039 return ((SbUnoAnyObject
*)(SbxBase
*)xObj
)->getValue();
1040 if( xObj
->ISA(SbClassModuleObject
) )
1043 SbClassModuleObject
* pClassModuleObj
= (SbClassModuleObject
*)(SbxBase
*)xObj
;
1044 SbModule
* pClassModule
= pClassModuleObj
->getClassModule();
1045 if( pClassModule
->createCOMWrapperForIface( aRetAny
, pClassModuleObj
) )
1048 if( !xObj
->ISA(SbUnoObject
) )
1050 // Create NativeObjectWrapper to identify object in case of callbacks
1051 SbxObject
* pObj
= PTR_CAST(SbxObject
,pVar
->GetObject());
1054 NativeObjectWrapper aNativeObjectWrapper
;
1055 sal_uInt32 nIndex
= lcl_registerNativeObjectWrapper( pObj
);
1056 aNativeObjectWrapper
.ObjectId
<<= nIndex
;
1058 aRetAny
<<= aNativeObjectWrapper
;
1065 Type aType
= getUnoTypeForSbxValue( pVar
);
1066 TypeClass eType
= aType
.getTypeClass();
1068 if( !bBlockConversionToSmallestType
)
1070 // #79615 Choose "smallest" represention for int values
1071 // because up cast is allowed, downcast not
1074 case TypeClass_FLOAT
:
1075 case TypeClass_DOUBLE
:
1077 double d
= pVar
->GetDouble();
1078 if( d
== floor( d
) )
1080 if( d
>= -128 && d
<= 127 )
1081 aType
= ::getCppuType( (sal_Int8
*)0 );
1082 else if( d
>= SbxMININT
&& d
<= SbxMAXINT
)
1083 aType
= ::getCppuType( (sal_Int16
*)0 );
1084 else if( d
>= -SbxMAXLNG
&& d
<= SbxMAXLNG
)
1085 aType
= ::getCppuType( (sal_Int32
*)0 );
1089 case TypeClass_SHORT
:
1091 sal_Int16 n
= pVar
->GetInteger();
1092 if( n
>= -128 && n
<= 127 )
1093 aType
= ::getCppuType( (sal_Int8
*)0 );
1096 case TypeClass_LONG
:
1098 sal_Int32 n
= pVar
->GetLong();
1099 if( n
>= -128 && n
<= 127 )
1100 aType
= ::getCppuType( (sal_Int8
*)0 );
1101 else if( n
>= SbxMININT
&& n
<= SbxMAXINT
)
1102 aType
= ::getCppuType( (sal_Int16
*)0 );
1105 case TypeClass_UNSIGNED_SHORT
:
1107 sal_uInt16 n
= pVar
->GetUShort();
1109 aType
= ::getCppuType( (sal_uInt8
*)0 );
1112 case TypeClass_UNSIGNED_LONG
:
1114 sal_uInt32 n
= pVar
->GetLong();
1116 aType
= ::getCppuType( (sal_uInt8
*)0 );
1117 else if( n
<= SbxMAXUINT
)
1118 aType
= ::getCppuType( (sal_uInt16
*)0 );
1121 // TODO: need to add hyper types ?
1126 return sbxToUnoValue( pVar
, aType
);
1131 // Helper function for StepREDIMP
1132 static Any
implRekMultiDimArrayToSequence( SbxDimArray
* pArray
,
1133 const Type
& aElemType
, short nMaxDimIndex
, short nActualDim
,
1134 sal_Int32
* pActualIndices
, sal_Int32
* pLowerBounds
, sal_Int32
* pUpperBounds
)
1136 sal_Int32 nSeqLevel
= nMaxDimIndex
- nActualDim
+ 1;
1137 OUStringBuffer aSeqTypeName
;
1139 for( i
= 0 ; i
< nSeqLevel
; i
++ )
1141 aSeqTypeName
.appendAscii(aSeqLevelStr
);
1143 aSeqTypeName
.append(aElemType
.getTypeName());
1144 Type
aSeqType( TypeClass_SEQUENCE
, aSeqTypeName
.makeStringAndClear() );
1146 // Create Sequence instance
1148 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aSeqType
);
1149 xIdlTargetClass
->createObject( aRetVal
);
1151 // Alloc sequence according to array bounds
1152 sal_Int32 nUpper
= pUpperBounds
[nActualDim
];
1153 sal_Int32 nLower
= pLowerBounds
[nActualDim
];
1154 sal_Int32 nSeqSize
= nUpper
- nLower
+ 1;
1155 Reference
< XIdlArray
> xArray
= xIdlTargetClass
->getArray();
1156 xArray
->realloc( aRetVal
, nSeqSize
);
1158 sal_Int32
& ri
= pActualIndices
[nActualDim
];
1160 for( ri
= nLower
,i
= 0 ; ri
<= nUpper
; ri
++,i
++ )
1164 if( nActualDim
< nMaxDimIndex
)
1166 aElementVal
= implRekMultiDimArrayToSequence( pArray
, aElemType
,
1167 nMaxDimIndex
, nActualDim
+ 1, pActualIndices
, pLowerBounds
, pUpperBounds
);
1171 SbxVariable
* pSource
= pArray
->Get32( pActualIndices
);
1172 aElementVal
= sbxToUnoValue( pSource
, aElemType
);
1177 // transfer to the sequence
1178 xArray
->set( aRetVal
, i
, aElementVal
);
1180 catch( const IllegalArgumentException
& )
1182 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
1183 implGetExceptionMsg( ::cppu::getCaughtException() ) );
1185 catch (const IndexOutOfBoundsException
&)
1187 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
1193 // Map old interface
1194 Any
sbxToUnoValue( const SbxValue
* pVar
)
1196 return sbxToUnoValueImpl( pVar
);
1199 // function to find a global identifier in
1200 // the UnoScope and to wrap it for Sbx
1201 static bool implGetTypeByName( const OUString
& rName
, Type
& rRetType
)
1203 bool bSuccess
= false;
1205 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
1206 if( xTypeAccess
->hasByHierarchicalName( rName
) )
1208 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
1209 Reference
< XTypeDescription
> xTypeDesc
;
1212 if( xTypeDesc
.is() )
1214 rRetType
= Type( xTypeDesc
->getTypeClass(), xTypeDesc
->getName() );
1222 // converting of Sbx to Uno with known target class
1223 Any
sbxToUnoValue( const SbxValue
* pVar
, const Type
& rType
, Property
* pUnoProperty
)
1227 // #94560 No conversion of empty/void for MAYBE_VOID properties
1228 if( pUnoProperty
&& pUnoProperty
->Attributes
& PropertyAttribute::MAYBEVOID
)
1230 if( pVar
->IsEmpty() )
1234 SbxDataType eBaseType
= pVar
->SbxValue::GetType();
1235 if( eBaseType
== SbxOBJECT
)
1237 SbxBaseRef xObj
= (SbxBase
*)pVar
->GetObject();
1238 if( xObj
.Is() && xObj
->ISA(SbUnoAnyObject
) )
1240 return ((SbUnoAnyObject
*)(SbxBase
*)xObj
)->getValue();
1244 TypeClass eType
= rType
.getTypeClass();
1247 case TypeClass_INTERFACE
:
1248 case TypeClass_STRUCT
:
1249 case TypeClass_EXCEPTION
:
1251 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( rType
);
1254 if( pVar
->IsNull() && eType
== TypeClass_INTERFACE
)
1256 Reference
< XInterface
> xRef
;
1257 OUString aClassName
= xIdlTargetClass
->getName();
1258 Type
aClassType( xIdlTargetClass
->getTypeClass(), aClassName
.getStr() );
1259 aRetVal
.setValue( &xRef
, aClassType
);
1263 // #112368 Special conversion for Decimal, Currency and Date
1264 if( eType
== TypeClass_STRUCT
)
1266 SbiInstance
* pInst
= GetSbData()->pInst
;
1267 if( pInst
&& pInst
->IsCompatibility() )
1269 if( rType
== ::getCppuType( (oleautomation::Decimal
*)0 ) )
1271 oleautomation::Decimal aDecimal
;
1272 pVar
->fillAutomationDecimal( aDecimal
);
1273 aRetVal
<<= aDecimal
;
1276 else if( rType
== ::getCppuType( (oleautomation::Currency
*)0 ) )
1278 // assumes per previous code that ole Currency is Int64
1279 aRetVal
<<= (sal_Int64
)( pVar
->GetInt64() );
1282 else if( rType
== ::getCppuType( (oleautomation::Date
*)0 ) )
1284 oleautomation::Date aDate
;
1285 aDate
.Value
= pVar
->GetDate();
1292 SbxBaseRef pObj
= (SbxBase
*)pVar
->GetObject();
1293 if( pObj
&& pObj
->ISA(SbUnoObject
) )
1295 aRetVal
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
1297 else if( pObj
&& pObj
->ISA(SbUnoStructRefObject
) )
1299 aRetVal
= ((SbUnoStructRefObject
*)(SbxBase
*)pObj
)->getUnoAny();
1303 // null object -> null XInterface
1304 Reference
<XInterface
> xInt
;
1311 case TypeClass_TYPE
:
1313 if( eBaseType
== SbxOBJECT
)
1316 Reference
< XIdlClass
> xIdlClass
;
1318 SbxBaseRef pObj
= (SbxBase
*)pVar
->GetObject();
1319 if( pObj
&& pObj
->ISA(SbUnoObject
) )
1321 Any aUnoAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
1322 aUnoAny
>>= xIdlClass
;
1325 if( xIdlClass
.is() )
1327 OUString aClassName
= xIdlClass
->getName();
1328 Type
aType( xIdlClass
->getTypeClass(), aClassName
.getStr() );
1332 else if( eBaseType
== SbxSTRING
)
1334 OUString aTypeName
= pVar
->GetOUString();
1336 bool bSuccess
= implGetTypeByName( aTypeName
, aType
);
1346 case TypeClass_ENUM
:
1348 aRetVal
= int2enum( pVar
->GetLong(), rType
);
1352 case TypeClass_SEQUENCE
:
1354 SbxBaseRef xObj
= (SbxBase
*)pVar
->GetObject();
1355 if( xObj
&& xObj
->ISA(SbxDimArray
) )
1357 SbxBase
* pObj
= (SbxBase
*)xObj
;
1358 SbxDimArray
* pArray
= (SbxDimArray
*)pObj
;
1360 short nDims
= pArray
->GetDims();
1362 // Normal case: One dimensional array
1363 sal_Int32 nLower
, nUpper
;
1364 if( nDims
== 1 && pArray
->GetDim32( 1, nLower
, nUpper
) )
1366 sal_Int32 nSeqSize
= nUpper
- nLower
+ 1;
1368 // create the instance of the required sequence
1369 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( rType
);
1370 xIdlTargetClass
->createObject( aRetVal
);
1371 Reference
< XIdlArray
> xArray
= xIdlTargetClass
->getArray();
1372 xArray
->realloc( aRetVal
, nSeqSize
);
1375 OUString aClassName
= xIdlTargetClass
->getName();
1376 typelib_TypeDescription
* pSeqTD
= 0;
1377 typelib_typedescription_getByName( &pSeqTD
, aClassName
.pData
);
1378 OSL_ASSERT( pSeqTD
);
1379 Type
aElemType( ((typelib_IndirectTypeDescription
*)pSeqTD
)->pType
);
1381 // convert all array member and register them
1382 sal_Int32 nIdx
= nLower
;
1383 for( sal_Int32 i
= 0 ; i
< nSeqSize
; i
++,nIdx
++ )
1385 SbxVariableRef xVar
= pArray
->Get32( &nIdx
);
1387 // Convert the value of Sbx to Uno
1388 Any aAnyValue
= sbxToUnoValue( (SbxVariable
*)xVar
, aElemType
);
1392 // insert in the sequence
1393 xArray
->set( aRetVal
, i
, aAnyValue
);
1395 catch( const IllegalArgumentException
& )
1397 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
1398 implGetExceptionMsg( ::cppu::getCaughtException() ) );
1400 catch (const IndexOutOfBoundsException
&)
1402 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
1406 // #i33795 Map also multi dimensional arrays to corresponding sequences
1407 else if( nDims
> 1 )
1410 typelib_TypeDescription
* pSeqTD
= 0;
1411 Type
aCurType( rType
);
1412 sal_Int32 nSeqLevel
= 0;
1416 OUString aTypeName
= aCurType
.getTypeName();
1417 typelib_typedescription_getByName( &pSeqTD
, aTypeName
.pData
);
1418 OSL_ASSERT( pSeqTD
);
1419 if( pSeqTD
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1421 aCurType
= Type( ((typelib_IndirectTypeDescription
*)pSeqTD
)->pType
);
1426 aElemType
= aCurType
;
1432 if( nSeqLevel
== nDims
)
1434 sal_Int32
* pLowerBounds
= new sal_Int32
[nDims
];
1435 sal_Int32
* pUpperBounds
= new sal_Int32
[nDims
];
1436 sal_Int32
* pActualIndices
= new sal_Int32
[nDims
];
1437 for( short i
= 1 ; i
<= nDims
; i
++ )
1439 sal_Int32 lBound
, uBound
;
1440 pArray
->GetDim32( i
, lBound
, uBound
);
1443 pActualIndices
[j
] = pLowerBounds
[j
] = lBound
;
1444 pUpperBounds
[j
] = uBound
;
1447 aRetVal
= implRekMultiDimArrayToSequence( pArray
, aElemType
,
1448 nDims
- 1, 0, pActualIndices
, pLowerBounds
, pUpperBounds
);
1450 delete[] pUpperBounds
;
1451 delete[] pLowerBounds
;
1452 delete[] pActualIndices
;
1460 // for Any use the class independent converting routine
1463 aRetVal
= sbxToUnoValueImpl( pVar
);
1467 case TypeClass_BOOLEAN
:
1469 sal_Bool b
= pVar
->GetBool();
1470 aRetVal
.setValue( &b
, getBooleanCppuType() );
1473 case TypeClass_CHAR
:
1475 sal_Unicode c
= pVar
->GetChar();
1476 aRetVal
.setValue( &c
, getCharCppuType() );
1479 case TypeClass_STRING
: aRetVal
<<= pVar
->GetOUString(); break;
1480 case TypeClass_FLOAT
: aRetVal
<<= pVar
->GetSingle(); break;
1481 case TypeClass_DOUBLE
: aRetVal
<<= pVar
->GetDouble(); break;
1483 case TypeClass_BYTE
:
1485 sal_Int16 nVal
= pVar
->GetInteger();
1486 bool bOverflow
= false;
1492 else if( nVal
> 127 )
1498 StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW
);
1500 sal_Int8 nByteVal
= (sal_Int8
)nVal
;
1501 aRetVal
<<= nByteVal
;
1504 case TypeClass_SHORT
: aRetVal
<<= (sal_Int16
)( pVar
->GetInteger() ); break;
1505 case TypeClass_LONG
: aRetVal
<<= (sal_Int32
)( pVar
->GetLong() ); break;
1506 case TypeClass_HYPER
: aRetVal
<<= (sal_Int64
)( pVar
->GetInt64() ); break;
1507 case TypeClass_UNSIGNED_SHORT
: aRetVal
<<= (sal_uInt16
)( pVar
->GetUShort() ); break;
1508 case TypeClass_UNSIGNED_LONG
: aRetVal
<<= (sal_uInt32
)( pVar
->GetULong() ); break;
1509 case TypeClass_UNSIGNED_HYPER
: aRetVal
<<= (sal_uInt64
)( pVar
->GetUInt64() ); break;
1516 void processAutomationParams( SbxArray
* pParams
, Sequence
< Any
>& args
, bool bOLEAutomation
, sal_uInt32 nParamCount
)
1518 AutomationNamedArgsSbxArray
* pArgNamesArray
= NULL
;
1519 if( bOLEAutomation
)
1520 pArgNamesArray
= PTR_CAST(AutomationNamedArgsSbxArray
,pParams
);
1522 args
.realloc( nParamCount
);
1523 Any
* pAnyArgs
= args
.getArray();
1524 bool bBlockConversionToSmallestType
= GetSbData()->pInst
->IsCompatibility();
1526 if( pArgNamesArray
)
1528 Sequence
< OUString
>& rNameSeq
= pArgNamesArray
->getNames();
1529 OUString
* pNames
= rNameSeq
.getArray();
1531 for( i
= 0 ; i
< nParamCount
; i
++ )
1533 sal_uInt16 iSbx
= (sal_uInt16
)(i
+1);
1535 aValAny
= sbxToUnoValueImpl( pParams
->Get( iSbx
),
1536 bBlockConversionToSmallestType
);
1538 OUString aParamName
= pNames
[iSbx
];
1539 if( !aParamName
.isEmpty() )
1541 oleautomation::NamedArgument aNamedArgument
;
1542 aNamedArgument
.Name
= aParamName
;
1543 aNamedArgument
.Value
= aValAny
;
1544 pAnyArgs
[i
] <<= aNamedArgument
;
1548 pAnyArgs
[i
] = aValAny
;
1554 for( i
= 0 ; i
< nParamCount
; i
++ )
1556 pAnyArgs
[i
] = sbxToUnoValueImpl( pParams
->Get( (sal_uInt16
)(i
+1) ),
1557 bBlockConversionToSmallestType
);
1568 Any
invokeAutomationMethod( const OUString
& Name
, Sequence
< Any
>& args
, SbxArray
* pParams
, sal_uInt32 nParamCount
, Reference
< XInvocation
>& rxInvocation
, INVOKETYPE invokeType
= Func
)
1570 Sequence
< sal_Int16
> OutParamIndex
;
1571 Sequence
< Any
> OutParam
;
1574 switch( invokeType
)
1577 aRetAny
= rxInvocation
->invoke( Name
, args
, OutParamIndex
, OutParam
);
1581 Reference
< XAutomationInvocation
> xAutoInv( rxInvocation
, UNO_QUERY
);
1582 aRetAny
= xAutoInv
->invokeGetProperty( Name
, args
, OutParamIndex
, OutParam
);
1587 Reference
< XAutomationInvocation
> xAutoInv( rxInvocation
, UNO_QUERY_THROW
);
1588 aRetAny
= xAutoInv
->invokePutProperty( Name
, args
, OutParamIndex
, OutParam
);
1592 break; // should introduce an error here
1595 const sal_Int16
* pIndices
= OutParamIndex
.getConstArray();
1596 sal_uInt32 nLen
= OutParamIndex
.getLength();
1599 const Any
* pNewValues
= OutParam
.getConstArray();
1600 for( sal_uInt32 j
= 0 ; j
< nLen
; j
++ )
1602 sal_Int16 iTarget
= pIndices
[ j
];
1603 if( iTarget
>= (sal_Int16
)nParamCount
)
1605 unoToSbxValue( (SbxVariable
*)pParams
->Get( (sal_uInt16
)(j
+1) ), pNewValues
[ j
] );
1611 // Debugging help method to readout the imlemented interfaces of an object
1612 OUString
Impl_GetInterfaceInfo( const Reference
< XInterface
>& x
, const Reference
< XIdlClass
>& xClass
, sal_uInt16 nRekLevel
)
1614 Type aIfaceType
= ::getCppuType( (const Reference
< XInterface
> *)0 );
1615 static Reference
< XIdlClass
> xIfaceClass
= TypeToIdlClass( aIfaceType
);
1617 OUStringBuffer aRetStr
;
1618 for( sal_uInt16 i
= 0 ; i
< nRekLevel
; i
++ )
1619 aRetStr
.appendAscii( " " );
1620 aRetStr
.append( xClass
->getName() );
1621 OUString aClassName
= xClass
->getName();
1622 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
1624 // checking if the interface is really supported
1625 if( !x
->queryInterface( aClassType
).hasValue() )
1627 aRetStr
.appendAscii( " (ERROR: Not really supported!)\n" );
1629 // Are there super interfaces?
1632 aRetStr
.appendAscii( "\n" );
1634 // get the super interfaces
1635 Sequence
< Reference
< XIdlClass
> > aSuperClassSeq
= xClass
->getSuperclasses();
1636 const Reference
< XIdlClass
>* pClasses
= aSuperClassSeq
.getConstArray();
1637 sal_uInt32 nSuperIfaceCount
= aSuperClassSeq
.getLength();
1638 for( sal_uInt32 j
= 0 ; j
< nSuperIfaceCount
; j
++ )
1640 const Reference
< XIdlClass
>& rxIfaceClass
= pClasses
[j
];
1641 if( !rxIfaceClass
->equals( xIfaceClass
) )
1642 aRetStr
.append( Impl_GetInterfaceInfo( x
, rxIfaceClass
, nRekLevel
+ 1 ) );
1645 return aRetStr
.makeStringAndClear();
1648 OUString
getDbgObjectNameImpl( SbUnoObject
* pUnoObj
)
1653 aName
= pUnoObj
->GetClassName();
1654 if( aName
.isEmpty() )
1656 Any aToInspectObj
= pUnoObj
->getUnoAny();
1657 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1658 Reference
< XInterface
> xObj
;
1659 if( eType
== TypeClass_INTERFACE
)
1660 xObj
= *(Reference
< XInterface
>*)aToInspectObj
.getValue();
1663 Reference
< XServiceInfo
> xServiceInfo( xObj
, UNO_QUERY
);
1664 if( xServiceInfo
.is() )
1665 aName
= xServiceInfo
->getImplementationName();
1672 OUString
getDbgObjectName( SbUnoObject
* pUnoObj
)
1674 OUString aName
= getDbgObjectNameImpl( pUnoObj
);
1675 if( aName
.isEmpty() )
1678 OUStringBuffer aRet
;
1679 if( aName
.getLength() > 20 )
1681 aRet
.appendAscii( "\n" );
1683 aRet
.appendAscii( "\"" );
1684 aRet
.append( aName
);
1685 aRet
.appendAscii( "\":" );
1686 return aRet
.makeStringAndClear();
1689 OUString
getBasicObjectTypeName( SbxObject
* pObj
)
1694 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
1695 SbUnoStructRefObject
* pUnoStructObj
= PTR_CAST(SbUnoStructRefObject
,pObj
);
1697 aName
= getDbgObjectNameImpl( pUnoObj
);
1698 else if ( pUnoStructObj
)
1699 aName
= pUnoStructObj
->GetClassName();
1704 bool checkUnoObjectType( SbUnoObject
* pUnoObj
, const OUString
& rClass
)
1706 Any aToInspectObj
= pUnoObj
->getUnoAny();
1707 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1708 if( eType
!= TypeClass_INTERFACE
)
1712 const Reference
< XInterface
> x
= *(Reference
< XInterface
>*)aToInspectObj
.getValue();
1714 // Return true for XInvocation based objects as interface type names don't count then
1715 Reference
< XInvocation
> xInvocation( x
, UNO_QUERY
);
1716 if( xInvocation
.is() )
1720 bool result
= false;
1721 Reference
< XTypeProvider
> xTypeProvider( x
, UNO_QUERY
);
1722 if( xTypeProvider
.is() )
1724 /* Although interfaces in the ooo.vba namespace obey the IDL rules and
1725 have a leading 'X', in Basic we want to be able to do something
1726 like 'Dim wb As Workbooks' or 'Dim lb As MSForms.Label'. Here we
1727 add a leading 'X' to the class name and a leading dot to the entire
1728 type name. This results e.g. in '.XWorkbooks' or '.MSForms.XLabel'
1729 which matches the interface names 'ooo.vba.excel.XWorkbooks' or
1730 'ooo.vba.msforms.XLabel'.
1732 OUString aClassName
;
1733 if ( SbiRuntime::isVBAEnabled() )
1736 sal_Int32 nClassNameDot
= rClass
.lastIndexOf( '.' );
1737 if( nClassNameDot
>= 0 )
1739 aClassName
+= rClass
.copy( 0, nClassNameDot
+ 1 ) + OUString( 'X' ) + rClass
.copy( nClassNameDot
+ 1 );
1743 aClassName
+= OUString( 'X' ) + rClass
;
1746 else // assume extended type declaration support for basic ( can't get here
1748 aClassName
= rClass
;
1750 Sequence
< Type
> aTypeSeq
= xTypeProvider
->getTypes();
1751 const Type
* pTypeArray
= aTypeSeq
.getConstArray();
1752 sal_uInt32 nIfaceCount
= aTypeSeq
.getLength();
1753 for( sal_uInt32 j
= 0 ; j
< nIfaceCount
; j
++ )
1755 const Type
& rType
= pTypeArray
[j
];
1757 Reference
<XIdlClass
> xClass
= TypeToIdlClass( rType
);
1760 OSL_FAIL("failed to get XIdlClass for type");
1763 OUString aInterfaceName
= xClass
->getName();
1764 if ( aInterfaceName
== "com.sun.star.bridge.oleautomation.XAutomationObject" )
1766 // there is a hack in the extensions/source/ole/oleobj.cxx to return the typename of the automation object, lets check if it
1768 Reference
< XInvocation
> xInv( aToInspectObj
, UNO_QUERY
);
1772 xInv
->getValue( OUString( "$GetTypeName" ) ) >>= sTypeName
;
1773 if ( sTypeName
.isEmpty() || sTypeName
== "IDispatch" )
1775 // can't check type, leave it pass
1780 result
= sTypeName
.equals( rClass
);
1783 break; // finished checking automation object
1786 // match interface name with passed class name
1787 OSL_TRACE("Checking if object implements %s", OUStringToOString( aClassName
, RTL_TEXTENCODING_UTF8
).getStr() );
1788 if ( (aClassName
.getLength() <= aInterfaceName
.getLength()) &&
1789 aInterfaceName
.matchIgnoreAsciiCase( aClassName
, aInterfaceName
.getLength() - aClassName
.getLength() ) )
1799 // Debugging help method to readout the imlemented interfaces of an object
1800 OUString
Impl_GetSupportedInterfaces( SbUnoObject
* pUnoObj
)
1802 Any aToInspectObj
= pUnoObj
->getUnoAny();
1804 // allow only TypeClass interface
1805 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1806 OUStringBuffer aRet
;
1807 if( eType
!= TypeClass_INTERFACE
)
1809 aRet
.appendAscii( ID_DBG_SUPPORTEDINTERFACES
);
1810 aRet
.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
1814 // get the interface from the Any
1815 const Reference
< XInterface
> x
= *(Reference
< XInterface
>*)aToInspectObj
.getValue();
1817 Reference
< XTypeProvider
> xTypeProvider( x
, UNO_QUERY
);
1819 aRet
.appendAscii( "Supported interfaces by object " );
1820 aRet
.append( getDbgObjectName( pUnoObj
) );
1821 aRet
.appendAscii( "\n" );
1822 if( xTypeProvider
.is() )
1824 // get the interfaces of the implementation
1825 Sequence
< Type
> aTypeSeq
= xTypeProvider
->getTypes();
1826 const Type
* pTypeArray
= aTypeSeq
.getConstArray();
1827 sal_uInt32 nIfaceCount
= aTypeSeq
.getLength();
1828 for( sal_uInt32 j
= 0 ; j
< nIfaceCount
; j
++ )
1830 const Type
& rType
= pTypeArray
[j
];
1832 Reference
<XIdlClass
> xClass
= TypeToIdlClass( rType
);
1835 aRet
.append( Impl_GetInterfaceInfo( x
, xClass
, 1 ) );
1839 typelib_TypeDescription
* pTD
= 0;
1840 rType
.getDescription( &pTD
);
1842 aRet
.appendAscii( "*** ERROR: No IdlClass for type \"" );
1843 aRet
.append( pTD
->pTypeName
);
1844 aRet
.appendAscii( "\"\n*** Please check type library\n" );
1849 return aRet
.makeStringAndClear();
1854 // Debugging help method SbxDataType -> String
1855 OUString
Dbg_SbxDataType2String( SbxDataType eType
)
1857 OUStringBuffer aRet
;
1860 case SbxEMPTY
: aRet
.appendAscii("SbxEMPTY"); break;
1861 case SbxNULL
: aRet
.appendAscii("SbxNULL"); break;
1862 case SbxINTEGER
: aRet
.appendAscii("SbxINTEGER"); break;
1863 case SbxLONG
: aRet
.appendAscii("SbxLONG"); break;
1864 case SbxSINGLE
: aRet
.appendAscii("SbxSINGLE"); break;
1865 case SbxDOUBLE
: aRet
.appendAscii("SbxDOUBLE"); break;
1866 case SbxCURRENCY
: aRet
.appendAscii("SbxCURRENCY"); break;
1867 case SbxDECIMAL
: aRet
.appendAscii("SbxDECIMAL"); break;
1868 case SbxDATE
: aRet
.appendAscii("SbxDATE"); break;
1869 case SbxSTRING
: aRet
.appendAscii("SbxSTRING"); break;
1870 case SbxOBJECT
: aRet
.appendAscii("SbxOBJECT"); break;
1871 case SbxERROR
: aRet
.appendAscii("SbxERROR"); break;
1872 case SbxBOOL
: aRet
.appendAscii("SbxBOOL"); break;
1873 case SbxVARIANT
: aRet
.appendAscii("SbxVARIANT"); break;
1874 case SbxDATAOBJECT
: aRet
.appendAscii("SbxDATAOBJECT"); break;
1875 case SbxCHAR
: aRet
.appendAscii("SbxCHAR"); break;
1876 case SbxBYTE
: aRet
.appendAscii("SbxBYTE"); break;
1877 case SbxUSHORT
: aRet
.appendAscii("SbxUSHORT"); break;
1878 case SbxULONG
: aRet
.appendAscii("SbxULONG"); break;
1879 case SbxSALINT64
: aRet
.appendAscii("SbxINT64"); break;
1880 case SbxSALUINT64
: aRet
.appendAscii("SbxUINT64"); break;
1881 case SbxINT
: aRet
.appendAscii("SbxINT"); break;
1882 case SbxUINT
: aRet
.appendAscii("SbxUINT"); break;
1883 case SbxVOID
: aRet
.appendAscii("SbxVOID"); break;
1884 case SbxHRESULT
: aRet
.appendAscii("SbxHRESULT"); break;
1885 case SbxPOINTER
: aRet
.appendAscii("SbxPOINTER"); break;
1886 case SbxDIMARRAY
: aRet
.appendAscii("SbxDIMARRAY"); break;
1887 case SbxCARRAY
: aRet
.appendAscii("SbxCARRAY"); break;
1888 case SbxUSERDEF
: aRet
.appendAscii("SbxUSERDEF"); break;
1889 case SbxLPSTR
: aRet
.appendAscii("SbxLPSTR"); break;
1890 case SbxLPWSTR
: aRet
.appendAscii("SbxLPWSTR"); break;
1891 case SbxCoreSTRING
: aRet
.appendAscii("SbxCoreSTRING"); break;
1892 case SbxOBJECT
| SbxARRAY
: aRet
.appendAscii("SbxARRAY"); break;
1893 default: aRet
.appendAscii("Unknown Sbx-Type!");break;
1895 return aRet
.makeStringAndClear();
1898 // Debugging help method to display the properties of a SbUnoObjects
1899 OUString
Impl_DumpProperties( SbUnoObject
* pUnoObj
)
1901 OUStringBuffer aRet
;
1902 aRet
.appendAscii("Properties of object ");
1903 aRet
.append( getDbgObjectName( pUnoObj
) );
1905 // analyse the Uno-Infos to recognise the arrays
1906 Reference
< XIntrospectionAccess
> xAccess
= pUnoObj
->getIntrospectionAccess();
1909 Reference
< XInvocation
> xInvok
= pUnoObj
->getInvocation();
1911 xAccess
= xInvok
->getIntrospection();
1915 aRet
.appendAscii( "\nUnknown, no introspection available\n" );
1916 return aRet
.makeStringAndClear();
1919 Sequence
<Property
> props
= xAccess
->getProperties( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
1920 sal_uInt32 nUnoPropCount
= props
.getLength();
1921 const Property
* pUnoProps
= props
.getConstArray();
1923 SbxArray
* pProps
= pUnoObj
->GetProperties();
1924 sal_uInt16 nPropCount
= pProps
->Count();
1925 sal_uInt16 nPropsPerLine
= 1 + nPropCount
/ 30;
1926 for( sal_uInt16 i
= 0; i
< nPropCount
; i
++ )
1928 SbxVariable
* pVar
= pProps
->Get( i
);
1931 OUStringBuffer aPropStr
;
1932 if( (i
% nPropsPerLine
) == 0 )
1933 aPropStr
.appendAscii( "\n" );
1935 // output the type and name
1936 // Is it in Uno a sequence?
1937 SbxDataType eType
= pVar
->GetFullType();
1939 bool bMaybeVoid
= false;
1940 if( i
< nUnoPropCount
)
1942 const Property
& rProp
= pUnoProps
[ i
];
1944 // For MAYBEVOID freshly convert the type from Uno,
1945 // so not just SbxEMPTY is returned.
1946 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
1948 eType
= unoToSbxType( rProp
.Type
.getTypeClass() );
1951 if( eType
== SbxOBJECT
)
1953 Type aType
= rProp
.Type
;
1954 if( aType
.getTypeClass() == TypeClass_SEQUENCE
)
1955 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
1958 aPropStr
.append( Dbg_SbxDataType2String( eType
) );
1960 aPropStr
.appendAscii( "/void" );
1961 aPropStr
.appendAscii( " " );
1962 aPropStr
.append( pVar
->GetName() );
1964 if( i
== nPropCount
- 1 )
1965 aPropStr
.appendAscii( "\n" );
1967 aPropStr
.appendAscii( "; " );
1969 aRet
.append( aPropStr
.makeStringAndClear() );
1972 return aRet
.makeStringAndClear();
1975 // Debugging help method to display the methods of an SbUnoObjects
1976 OUString
Impl_DumpMethods( SbUnoObject
* pUnoObj
)
1978 OUStringBuffer aRet
;
1979 aRet
.appendAscii("Methods of object ");
1980 aRet
.append( getDbgObjectName( pUnoObj
) );
1982 // XIntrospectionAccess, so that the types of the parameter could be outputed
1983 Reference
< XIntrospectionAccess
> xAccess
= pUnoObj
->getIntrospectionAccess();
1986 Reference
< XInvocation
> xInvok
= pUnoObj
->getInvocation();
1988 xAccess
= xInvok
->getIntrospection();
1992 aRet
.appendAscii( "\nUnknown, no introspection available\n" );
1993 return aRet
.makeStringAndClear();
1995 Sequence
< Reference
< XIdlMethod
> > methods
= xAccess
->getMethods
1996 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
1997 const Reference
< XIdlMethod
>* pUnoMethods
= methods
.getConstArray();
1999 SbxArray
* pMethods
= pUnoObj
->GetMethods();
2000 sal_uInt16 nMethodCount
= pMethods
->Count();
2003 aRet
.appendAscii( "\nNo methods found\n" );
2004 return aRet
.makeStringAndClear();
2006 sal_uInt16 nPropsPerLine
= 1 + nMethodCount
/ 30;
2007 for( sal_uInt16 i
= 0; i
< nMethodCount
; i
++ )
2009 SbxVariable
* pVar
= pMethods
->Get( i
);
2012 if( (i
% nPropsPerLine
) == 0 )
2013 aRet
.appendAscii( "\n" );
2015 // address the method
2016 const Reference
< XIdlMethod
>& rxMethod
= pUnoMethods
[i
];
2018 // Is it in Uno a sequence?
2019 SbxDataType eType
= pVar
->GetFullType();
2020 if( eType
== SbxOBJECT
)
2022 Reference
< XIdlClass
> xClass
= rxMethod
->getReturnType();
2023 if( xClass
.is() && xClass
->getTypeClass() == TypeClass_SEQUENCE
)
2024 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
2026 // output the name and the type
2027 aRet
.append( Dbg_SbxDataType2String( eType
) );
2028 aRet
.appendAscii( " " );
2029 aRet
.append ( pVar
->GetName() );
2030 aRet
.appendAscii( " ( " );
2032 // the get-method mustn't have a parameter
2033 Sequence
< Reference
< XIdlClass
> > aParamsSeq
= rxMethod
->getParameterTypes();
2034 sal_uInt32 nParamCount
= aParamsSeq
.getLength();
2035 const Reference
< XIdlClass
>* pParams
= aParamsSeq
.getConstArray();
2037 if( nParamCount
> 0 )
2039 for( sal_uInt16 j
= 0; j
< nParamCount
; j
++ )
2041 aRet
.append ( Dbg_SbxDataType2String( unoToSbxType( pParams
[ j
] ) ) );
2042 if( j
< nParamCount
- 1 )
2043 aRet
.appendAscii( ", " );
2047 aRet
.appendAscii( "void" );
2049 aRet
.appendAscii( " ) " );
2051 if( i
== nMethodCount
- 1 )
2052 aRet
.appendAscii( "\n" );
2054 aRet
.appendAscii( "; " );
2057 return aRet
.makeStringAndClear();
2060 TYPEINIT1(AutomationNamedArgsSbxArray
,SbxArray
)
2062 // Implementation SbUnoObject
2063 void SbUnoObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
2064 const SfxHint
& rHint
, const TypeId
& rHintType
)
2066 if( bNeedIntrospection
)
2069 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
2072 SbxVariable
* pVar
= pHint
->GetVar();
2073 SbxArray
* pParams
= pVar
->GetParameters();
2074 SbUnoProperty
* pProp
= PTR_CAST(SbUnoProperty
,pVar
);
2075 SbUnoMethod
* pMeth
= PTR_CAST(SbUnoMethod
,pVar
);
2078 bool bInvocation
= pProp
->isInvocationBased();
2079 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
2082 sal_Int32 nId
= pProp
->nId
;
2085 // Id == -1: Display implemented interfaces according the ClassProvider
2086 if( nId
== -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
2088 OUString aRetStr
= Impl_GetSupportedInterfaces( this );
2089 pVar
->PutString( aRetStr
);
2091 // Id == -2: output properties
2092 else if( nId
== -2 ) // Property ID_DBG_PROPERTIES
2094 // now all properties must be created
2096 OUString aRetStr
= Impl_DumpProperties( this );
2097 pVar
->PutString( aRetStr
);
2099 // Id == -3: output the methods
2100 else if( nId
== -3 ) // Property ID_DBG_METHODS
2102 // now all properties must be created
2104 OUString aRetStr
= Impl_DumpMethods( this );
2105 pVar
->PutString( aRetStr
);
2110 if( !bInvocation
&& mxUnoAccess
.is() )
2114 if ( maStructInfo
.get() )
2116 StructRefInfo aMember
= maStructInfo
->getStructMember( pProp
->GetName() );
2117 if ( aMember
.isEmpty() )
2119 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
2123 if ( pProp
->isUnoStruct() )
2125 SbUnoStructRefObject
* pSbUnoObject
= new SbUnoStructRefObject( pProp
->GetName(), aMember
);
2126 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
2127 pVar
->PutObject( xWrapper
);
2131 Any aRetAny
= aMember
.getValue();
2132 // take over the value from Uno to Sbx
2133 unoToSbxValue( pVar
, aRetAny
);
2139 Reference
< XPropertySet
> xPropSet( mxUnoAccess
->queryAdapter( ::getCppuType( (const Reference
< XPropertySet
> *)0 ) ), UNO_QUERY
);
2140 Any aRetAny
= xPropSet
->getPropertyValue( pProp
->GetName() );
2141 // The use of getPropertyValue (instead of using the index) is
2142 // suboptimal, but the refactoring to XInvocation is already pending
2143 // Otherwise it is posible to use FastPropertySet
2145 // take over the value from Uno to Sbx
2146 unoToSbxValue( pVar
, aRetAny
);
2148 catch( const Exception
& )
2150 implHandleAnyException( ::cppu::getCaughtException() );
2153 else if( bInvocation
&& mxInvocation
.is() )
2157 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
2158 sal_Bool bCanBeConsideredAMethod
= mxInvocation
->hasMethod( pProp
->GetName() );
2160 if ( bCanBeConsideredAMethod
&& nParamCount
)
2162 // Automation properties have methods, so.. we need to invoke this through
2165 processAutomationParams( pParams
, args
, true, nParamCount
);
2166 aRetAny
= invokeAutomationMethod( pProp
->GetName(), args
, pParams
, nParamCount
, mxInvocation
, GetProp
);
2169 aRetAny
= mxInvocation
->getValue( pProp
->GetName() );
2170 // take over the value from Uno to Sbx
2171 unoToSbxValue( pVar
, aRetAny
);
2172 if( pParams
&& bCanBeConsideredAMethod
)
2173 pVar
->SetParameters( NULL
);
2176 catch( const Exception
& )
2178 implHandleAnyException( ::cppu::getCaughtException() );
2182 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
2184 if( !bInvocation
&& mxUnoAccess
.is() )
2186 if( pProp
->aUnoProp
.Attributes
& PropertyAttribute::READONLY
)
2188 StarBASIC::Error( SbERR_PROP_READONLY
);
2191 if ( maStructInfo
.get() )
2193 StructRefInfo aMember
= maStructInfo
->getStructMember( pProp
->GetName() );
2194 if ( aMember
.isEmpty() )
2196 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
2200 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
2201 aMember
.setValue( aAnyValue
);
2205 // take over the value from Uno to Sbx
2206 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
2210 Reference
< XPropertySet
> xPropSet( mxUnoAccess
->queryAdapter( ::getCppuType( (const Reference
< XPropertySet
> *)0 ) ), UNO_QUERY
);
2211 xPropSet
->setPropertyValue( pProp
->GetName(), aAnyValue
);
2212 // The use of getPropertyValue (instead of using the index) is
2213 // suboptimal, but the refactoring to XInvocation is already pending
2214 // Otherwise it is posible to use FastPropertySet
2216 catch( const Exception
& )
2218 implHandleAnyException( ::cppu::getCaughtException() );
2221 else if( bInvocation
&& mxInvocation
.is() )
2223 // take over the value from Uno to Sbx
2224 Any aAnyValue
= sbxToUnoValueImpl( pVar
);
2228 mxInvocation
->setValue( pProp
->GetName(), aAnyValue
);
2230 catch( const Exception
& )
2232 implHandleAnyException( ::cppu::getCaughtException() );
2239 bool bInvocation
= pMeth
->isInvocationBased();
2240 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
2242 // number of Parameter -1 because of Param0 == this
2243 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
2245 bool bOutParams
= false;
2248 if( !bInvocation
&& mxUnoAccess
.is() )
2251 const Sequence
<ParamInfo
>& rInfoSeq
= pMeth
->getParamInfos();
2252 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2253 sal_uInt32 nUnoParamCount
= rInfoSeq
.getLength();
2254 sal_uInt32 nAllocParamCount
= nParamCount
;
2256 // ignore surplus parameter; alternative: throw an error
2257 if( nParamCount
> nUnoParamCount
)
2259 nParamCount
= nUnoParamCount
;
2260 nAllocParamCount
= nParamCount
;
2262 else if( nParamCount
< nUnoParamCount
)
2264 SbiInstance
* pInst
= GetSbData()->pInst
;
2265 if( pInst
&& pInst
->IsCompatibility() )
2268 bool bError
= false;
2269 for( i
= nParamCount
; i
< nUnoParamCount
; i
++ )
2271 const ParamInfo
& rInfo
= pParamInfos
[i
];
2272 const Reference
< XIdlClass
>& rxClass
= rInfo
.aType
;
2273 if( rxClass
->getTypeClass() != TypeClass_ANY
)
2276 StarBASIC::Error( SbERR_NOT_OPTIONAL
);
2280 nAllocParamCount
= nUnoParamCount
;
2284 if( nAllocParamCount
> 0 )
2286 args
.realloc( nAllocParamCount
);
2287 Any
* pAnyArgs
= args
.getArray();
2288 for( i
= 0 ; i
< nParamCount
; i
++ )
2290 const ParamInfo
& rInfo
= pParamInfos
[i
];
2291 const Reference
< XIdlClass
>& rxClass
= rInfo
.aType
;
2293 com::sun::star::uno::Type
aType( rxClass
->getTypeClass(), rxClass
->getName() );
2295 // ATTENTION: Don't forget for Sbx-Parameter the offset!
2296 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( (sal_uInt16
)(i
+1) ), aType
);
2298 // If it is not certain check whether the out-parameter are available.
2301 ParamMode aParamMode
= rInfo
.aMode
;
2302 if( aParamMode
!= ParamMode_IN
)
2308 else if( bInvocation
&& pParams
&& mxInvocation
.is() )
2310 bool bOLEAutomation
= true;
2311 processAutomationParams( pParams
, args
, bOLEAutomation
, nParamCount
);
2315 GetSbData()->bBlockCompilerError
= true; // #106433 Block compiler errors for API calls
2318 if( !bInvocation
&& mxUnoAccess
.is() )
2320 Any aRetAny
= pMeth
->m_xUnoMethod
->invoke( getUnoAny(), args
);
2322 // take over the value from Uno to Sbx
2323 unoToSbxValue( pVar
, aRetAny
);
2325 // Did we to copy back the Out-Parameter?
2328 const Any
* pAnyArgs
= args
.getConstArray();
2331 const Sequence
<ParamInfo
>& rInfoSeq
= pMeth
->getParamInfos();
2332 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2335 for( j
= 0 ; j
< nParamCount
; j
++ )
2337 const ParamInfo
& rInfo
= pParamInfos
[j
];
2338 ParamMode aParamMode
= rInfo
.aMode
;
2339 if( aParamMode
!= ParamMode_IN
)
2340 unoToSbxValue( (SbxVariable
*)pParams
->Get( (sal_uInt16
)(j
+1) ), pAnyArgs
[ j
] );
2344 else if( bInvocation
&& mxInvocation
.is() )
2346 Any aRetAny
= invokeAutomationMethod( pMeth
->GetName(), args
, pParams
, nParamCount
, mxInvocation
);
2347 unoToSbxValue( pVar
, aRetAny
);
2350 // remove parameter here, because this was not done anymore in unoToSbxValue()
2353 pVar
->SetParameters( NULL
);
2355 catch( const Exception
& )
2357 implHandleAnyException( ::cppu::getCaughtException() );
2359 GetSbData()->bBlockCompilerError
= false; // #106433 Unblock compiler errors
2363 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
2368 SbUnoObject::SbUnoObject( const OUString
& aName_
, const Any
& aUnoObj_
)
2369 : SbxObject( aName_
)
2370 , bNeedIntrospection( true )
2371 , bNativeCOMObject( false )
2373 static Reference
< XIntrospection
> xIntrospection
;
2375 // beat out again the default properties of Sbx
2376 Remove( OUString("Name"), SbxCLASS_DONTCARE
);
2377 Remove( OUString("Parent"), SbxCLASS_DONTCARE
);
2379 // check the type of the ojekts
2380 TypeClass eType
= aUnoObj_
.getValueType().getTypeClass();
2381 Reference
< XInterface
> x
;
2382 if( eType
== TypeClass_INTERFACE
)
2384 // get the interface from the Any
2385 x
= *(Reference
< XInterface
>*)aUnoObj_
.getValue();
2390 Reference
< XTypeProvider
> xTypeProvider
;
2391 // Did the object have an invocation itself?
2392 mxInvocation
= Reference
< XInvocation
>( x
, UNO_QUERY
);
2394 xTypeProvider
= Reference
< XTypeProvider
>( x
, UNO_QUERY
);
2396 if( mxInvocation
.is() )
2399 // get the ExactName
2400 mxExactNameInvocation
= Reference
< XExactName
>::query( mxInvocation
);
2402 // The remainder refers only to the introspection
2403 if( !xTypeProvider
.is() )
2405 bNeedIntrospection
= false;
2409 // Ignore introspection based members for COM objects to avoid
2410 // hiding of equally named COM symbols, e.g. XInvocation::getValue
2411 Reference
< oleautomation::XAutomationObject
> xAutomationObject( aUnoObj_
, UNO_QUERY
);
2412 if( xAutomationObject
.is() )
2413 bNativeCOMObject
= true;
2416 maTmpUnoObj
= aUnoObj_
;
2419 //*** Define the name ***
2420 bool bFatalError
= true;
2422 // Is it an interface or a struct?
2423 bool bSetClassName
= false;
2424 OUString aClassName_
;
2425 if( eType
== TypeClass_STRUCT
|| eType
== TypeClass_EXCEPTION
)
2428 bFatalError
= false;
2430 // insert the real name of the class
2431 if( aName_
.isEmpty() )
2433 aClassName_
= aUnoObj_
.getValueType().getTypeName();
2434 bSetClassName
= true;
2436 typelib_TypeDescription
* pDeclTD
= 0;
2437 typelib_typedescription_getByName( &pDeclTD
, maTmpUnoObj
.getValueTypeName().pData
);
2438 StructRefInfo
aThisStruct( maTmpUnoObj
, pDeclTD
, 0 );
2439 maStructInfo
.reset( new SbUnoStructRefObject( GetName(), aThisStruct
) );
2441 else if( eType
== TypeClass_INTERFACE
)
2443 // Interface works always through the type in the Any
2444 bFatalError
= false;
2447 SetClassName( aClassName_
);
2449 // Neither interface nor Struct -> FatalError
2452 StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION
);
2456 // pass the introspection primal on demand
2459 SbUnoObject::~SbUnoObject()
2464 // pass the introspection on Demand
2465 void SbUnoObject::doIntrospection( void )
2467 static Reference
< XIntrospection
> xIntrospection
;
2469 if( !bNeedIntrospection
)
2471 bNeedIntrospection
= false;
2473 if( !xIntrospection
.is() )
2475 // get the introspection service
2476 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
2477 xIntrospection
= Introspection::create( xContext
);
2480 // pass the introspection
2483 mxUnoAccess
= xIntrospection
->inspect( maTmpUnoObj
);
2485 catch( const RuntimeException
& e
)
2487 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2490 if( !mxUnoAccess
.is() )
2492 // #51475 mark to indicate an invalid object (no mxMaterialHolder)
2496 // get MaterialHolder from access
2497 mxMaterialHolder
= Reference
< XMaterialHolder
>::query( mxUnoAccess
);
2499 // get ExactName from access
2500 mxExactName
= Reference
< XExactName
>::query( mxUnoAccess
);
2506 // Start of a list of all SbUnoMethod-Instances
2507 static SbUnoMethod
* pFirst
= NULL
;
2509 void clearUnoMethodsForBasic( StarBASIC
* pBasic
)
2511 SbUnoMethod
* pMeth
= pFirst
;
2514 SbxObject
* pObject
= dynamic_cast< SbxObject
* >( pMeth
->GetParent() );
2517 StarBASIC
* pModBasic
= dynamic_cast< StarBASIC
* >( pObject
->GetParent() );
2518 if ( pModBasic
== pBasic
)
2520 // for now the solution is to remove the method from the list and to clear it,
2521 // but in case the element should be correctly transferred to another StarBASIC,
2522 // we should either set module parent to NULL without clearing it, or even
2523 // set the new StarBASIC as the parent of the module
2524 // pObject->SetParent( NULL );
2526 if( pMeth
== pFirst
)
2527 pFirst
= pMeth
->pNext
;
2528 else if( pMeth
->pPrev
)
2529 pMeth
->pPrev
->pNext
= pMeth
->pNext
;
2531 pMeth
->pNext
->pPrev
= pMeth
->pPrev
;
2533 pMeth
->pPrev
= NULL
;
2534 pMeth
->pNext
= NULL
;
2536 pMeth
->SbxValue::Clear();
2537 pObject
->SbxValue::Clear();
2539 // start from the beginning after object clearing, the cycle will end since the method is removed each time
2543 pMeth
= pMeth
->pNext
;
2546 pMeth
= pMeth
->pNext
;
2550 void clearUnoMethods( void )
2552 SbUnoMethod
* pMeth
= pFirst
;
2555 pMeth
->SbxValue::Clear();
2556 pMeth
= pMeth
->pNext
;
2561 SbUnoMethod::SbUnoMethod
2563 const OUString
& aName_
,
2564 SbxDataType eSbxType
,
2565 Reference
< XIdlMethod
> xUnoMethod_
,
2569 : SbxMethod( aName_
, eSbxType
)
2570 , mbInvocation( bInvocation
)
2571 , mbDirectInvocation( bDirect
)
2573 m_xUnoMethod
= xUnoMethod_
;
2574 pParamInfoSeq
= NULL
;
2576 // enregister the method in a list
2581 pNext
->pPrev
= this;
2584 SbUnoMethod::~SbUnoMethod()
2586 delete pParamInfoSeq
;
2588 if( this == pFirst
)
2591 pPrev
->pNext
= pNext
;
2593 pNext
->pPrev
= pPrev
;
2596 SbxInfo
* SbUnoMethod::GetInfo()
2598 if( !pInfo
&& m_xUnoMethod
.is() )
2600 SbiInstance
* pInst
= GetSbData()->pInst
;
2601 if( pInst
&& pInst
->IsCompatibility() )
2603 pInfo
= new SbxInfo();
2605 const Sequence
<ParamInfo
>& rInfoSeq
= getParamInfos();
2606 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2607 sal_uInt32 nParamCount
= rInfoSeq
.getLength();
2609 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
2611 const ParamInfo
& rInfo
= pParamInfos
[i
];
2612 OUString aParamName
= rInfo
.aName
;
2614 SbxDataType t
= SbxVARIANT
;
2615 sal_uInt16 nFlags_
= SBX_READ
;
2616 pInfo
->AddParam( aParamName
, t
, nFlags_
);
2623 const Sequence
<ParamInfo
>& SbUnoMethod::getParamInfos( void )
2625 if( !pParamInfoSeq
&& m_xUnoMethod
.is() )
2627 Sequence
<ParamInfo
> aTmp
= m_xUnoMethod
->getParameterInfos() ;
2628 pParamInfoSeq
= new Sequence
<ParamInfo
>( aTmp
);
2630 return *pParamInfoSeq
;
2633 SbUnoProperty::SbUnoProperty
2635 const OUString
& aName_
,
2636 SbxDataType eSbxType
,
2637 SbxDataType eRealSbxType
,
2638 const Property
& aUnoProp_
,
2643 : SbxProperty( aName_
, eSbxType
)
2644 , aUnoProp( aUnoProp_
)
2646 , mbInvocation( bInvocation
)
2647 , mRealType( eRealSbxType
)
2648 , mbUnoStruct( bUnoStruct
)
2650 // as needed establish an dummy array so that SbiRuntime::CheckArray() works
2651 static SbxArrayRef xDummyArray
= new SbxArray( SbxVARIANT
);
2652 if( eSbxType
& SbxARRAY
)
2653 PutObject( xDummyArray
);
2656 SbUnoProperty::~SbUnoProperty()
2660 SbxVariable
* SbUnoObject::Find( const OUString
& rName
, SbxClassType t
)
2662 static Reference
< XIdlMethod
> xDummyMethod
;
2663 static Property aDummyProp
;
2665 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
2667 if( bNeedIntrospection
)
2670 // New 1999-03-04: Create properties on demand. Therefore search now via
2671 // IntrospectionAccess if a property or a method of the required name exist
2674 OUString
aUName( rName
);
2675 if( mxUnoAccess
.is() && !bNativeCOMObject
)
2677 if( mxExactName
.is() )
2679 OUString aUExactName
= mxExactName
->getExactName( aUName
);
2680 if( !aUExactName
.isEmpty() )
2682 aUName
= aUExactName
;
2685 if( mxUnoAccess
->hasProperty( aUName
, PropertyConcept::ALL
- PropertyConcept::DANGEROUS
) )
2687 const Property
& rProp
= mxUnoAccess
->
2688 getProperty( aUName
, PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
2690 // If the property could be void the type had to be set to Variant
2691 SbxDataType eSbxType
;
2692 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
2693 eSbxType
= SbxVARIANT
;
2695 eSbxType
= unoToSbxType( rProp
.Type
.getTypeClass() );
2697 SbxDataType eRealSbxType
= ( ( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
) ? unoToSbxType( rProp
.Type
.getTypeClass() ) : eSbxType
);
2698 // create the property and superimpose it
2699 SbUnoProperty
* pProp
= new SbUnoProperty( rProp
.Name
, eSbxType
, eRealSbxType
, rProp
, 0, false, ( rProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
2700 SbxVariableRef xVarRef
= pProp
;
2701 QuickInsert( (SbxVariable
*)xVarRef
);
2704 else if( mxUnoAccess
->hasMethod( aUName
,
2705 MethodConcept::ALL
- MethodConcept::DANGEROUS
) )
2707 // address the method
2708 const Reference
< XIdlMethod
>& rxMethod
= mxUnoAccess
->
2709 getMethod( aUName
, MethodConcept::ALL
- MethodConcept::DANGEROUS
);
2711 // create SbUnoMethod and superimpose it
2712 SbxVariableRef xMethRef
= new SbUnoMethod( rxMethod
->getName(),
2713 unoToSbxType( rxMethod
->getReturnType() ), rxMethod
, false );
2714 QuickInsert( (SbxVariable
*)xMethRef
);
2718 // If nothing was found check via XNameAccess
2723 Reference
< XNameAccess
> xNameAccess( mxUnoAccess
->queryAdapter( ::getCppuType( (const Reference
< XPropertySet
> *)0 ) ), UNO_QUERY
);
2724 OUString
aUName2( rName
);
2726 if( xNameAccess
.is() && xNameAccess
->hasByName( aUName2
) )
2728 Any aAny
= xNameAccess
->getByName( aUName2
);
2730 // ATTENTION: Because of XNameAccess, the variable generated here
2731 // may not be included as a fixed property in the object and therefore
2732 // won't be stored anywhere.
2733 // If this leads to problems, it has to be created
2734 // synthetically or a class SbUnoNameAccessProperty,
2735 // witch checks the existence on access and which
2736 // is disposed if the name is not found anymore.
2737 pRes
= new SbxVariable( SbxVARIANT
);
2738 unoToSbxValue( pRes
, aAny
);
2741 catch( const NoSuchElementException
& e
)
2743 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2745 catch( const Exception
& )
2747 // Establish so that the exeption error will not be overwriten
2749 pRes
= new SbxVariable( SbxVARIANT
);
2751 implHandleAnyException( ::cppu::getCaughtException() );
2755 if( !pRes
&& mxInvocation
.is() )
2757 if( mxExactNameInvocation
.is() )
2759 OUString aUExactName
= mxExactNameInvocation
->getExactName( aUName
);
2760 if( !aUExactName
.isEmpty() )
2762 aUName
= aUExactName
;
2768 if( mxInvocation
->hasProperty( aUName
) )
2770 // create a property and superimpose it
2771 SbxVariableRef xVarRef
= new SbUnoProperty( aUName
, SbxVARIANT
, SbxVARIANT
, aDummyProp
, 0, true, false );
2772 QuickInsert( (SbxVariable
*)xVarRef
);
2775 else if( mxInvocation
->hasMethod( aUName
) )
2777 // create SbUnoMethode and superimpose it
2778 SbxVariableRef xMethRef
= new SbUnoMethod( aUName
, SbxVARIANT
, xDummyMethod
, true );
2779 QuickInsert( (SbxVariable
*)xMethRef
);
2784 Reference
< XDirectInvocation
> xDirectInvoke( mxInvocation
, UNO_QUERY
);
2785 if ( xDirectInvoke
.is() && xDirectInvoke
->hasMember( aUName
) )
2787 SbxVariableRef xMethRef
= new SbUnoMethod( aUName
, SbxVARIANT
, xDummyMethod
, true, true );
2788 QuickInsert( (SbxVariable
*)xMethRef
);
2794 catch( const RuntimeException
& e
)
2796 // Establish so that the exeption error will not be overwriten
2798 pRes
= new SbxVariable( SbxVARIANT
);
2800 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2805 // At the very end checking if the Dbg_-Properties are meant
2809 if( rName
.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES
) ||
2810 rName
.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES
) ||
2811 rName
.equalsIgnoreAsciiCase(ID_DBG_METHODS
) )
2814 implCreateDbgProperties();
2816 // Now they have to be found regular
2817 pRes
= SbxObject::Find( rName
, SbxCLASS_DONTCARE
);
2824 // help method to create the dbg_-Properties
2825 void SbUnoObject::implCreateDbgProperties( void )
2829 // Id == -1: display the implemented interfaces corresponding the ClassProvider
2830 SbxVariableRef xVarRef
= new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES
), SbxSTRING
, SbxSTRING
, aProp
, -1, false, false );
2831 QuickInsert( (SbxVariable
*)xVarRef
);
2833 // Id == -2: output the properties
2834 xVarRef
= new SbUnoProperty( OUString(ID_DBG_PROPERTIES
), SbxSTRING
, SbxSTRING
, aProp
, -2, false, false );
2835 QuickInsert( (SbxVariable
*)xVarRef
);
2837 // Id == -3: output the Methods
2838 xVarRef
= new SbUnoProperty( OUString(ID_DBG_METHODS
), SbxSTRING
, SbxSTRING
, aProp
, -3, false, false );
2839 QuickInsert( (SbxVariable
*)xVarRef
);
2842 void SbUnoObject::implCreateAll( void )
2844 // throw away all existing methods and properties
2845 pMethods
= new SbxArray
;
2846 pProps
= new SbxArray
;
2848 if( bNeedIntrospection
) doIntrospection();
2850 // get introspection
2851 Reference
< XIntrospectionAccess
> xAccess
= mxUnoAccess
;
2852 if( !xAccess
.is() || bNativeCOMObject
)
2854 if( mxInvocation
.is() )
2855 xAccess
= mxInvocation
->getIntrospection();
2856 else if( bNativeCOMObject
)
2862 // Establish properties
2863 Sequence
<Property
> props
= xAccess
->getProperties( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
2864 sal_uInt32 nPropCount
= props
.getLength();
2865 const Property
* pProps_
= props
.getConstArray();
2868 for( i
= 0 ; i
< nPropCount
; i
++ )
2870 const Property
& rProp
= pProps_
[ i
];
2872 // If the property could be void the type had to be set to Variant
2873 SbxDataType eSbxType
;
2874 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
2875 eSbxType
= SbxVARIANT
;
2877 eSbxType
= unoToSbxType( rProp
.Type
.getTypeClass() );
2879 SbxDataType eRealSbxType
= ( ( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
) ? unoToSbxType( rProp
.Type
.getTypeClass() ) : eSbxType
);
2880 // Create property and superimpose it
2881 SbxVariableRef xVarRef
= new SbUnoProperty( rProp
.Name
, eSbxType
, eRealSbxType
, rProp
, i
, false, ( rProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
2882 QuickInsert( (SbxVariable
*)xVarRef
);
2885 // Create Dbg_-Properties
2886 implCreateDbgProperties();
2889 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods
2890 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
2891 sal_uInt32 nMethCount
= aMethodSeq
.getLength();
2892 const Reference
< XIdlMethod
>* pMethods_
= aMethodSeq
.getConstArray();
2893 for( i
= 0 ; i
< nMethCount
; i
++ )
2896 const Reference
< XIdlMethod
>& rxMethod
= pMethods_
[i
];
2898 // Create SbUnoMethod and superimpose it
2899 SbxVariableRef xMethRef
= new SbUnoMethod
2900 ( rxMethod
->getName(), unoToSbxType( rxMethod
->getReturnType() ), rxMethod
, false );
2901 QuickInsert( (SbxVariable
*)xMethRef
);
2907 Any
SbUnoObject::getUnoAny( void )
2910 if( bNeedIntrospection
) doIntrospection();
2911 if ( maStructInfo
.get() )
2912 aRetAny
= maTmpUnoObj
;
2913 else if( mxMaterialHolder
.is() )
2914 aRetAny
= mxMaterialHolder
->getMaterial();
2915 else if( mxInvocation
.is() )
2916 aRetAny
<<= mxInvocation
;
2920 // help method to create an Uno-Struct per CoreReflection
2921 SbUnoObject
* Impl_CreateUnoStruct( const OUString
& aClassName
)
2923 // get CoreReflection
2924 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
2925 if( !xCoreReflection
.is() )
2928 // search for the class
2929 Reference
< XIdlClass
> xClass
;
2930 Reference
< XHierarchicalNameAccess
> xHarryName
=
2931 getCoreReflection_HierarchicalNameAccess_Impl();
2932 if( xHarryName
.is() && xHarryName
->hasByHierarchicalName( aClassName
) )
2933 xClass
= xCoreReflection
->forName( aClassName
);
2937 // Is it really a struct?
2938 TypeClass eType
= xClass
->getTypeClass();
2939 if ( ( eType
!= TypeClass_STRUCT
) && ( eType
!= TypeClass_EXCEPTION
) )
2942 // create an instance
2944 xClass
->createObject( aNewAny
);
2945 // make a SbUnoObject out of it
2946 SbUnoObject
* pUnoObj
= new SbUnoObject( aClassName
, aNewAny
);
2951 // Factory-Class to create Uno-Structs per DIM AS NEW
2952 SbxBase
* SbUnoFactory::Create( sal_uInt16
, sal_uInt32
)
2954 // Via SbxId nothing works in Uno
2958 SbxObject
* SbUnoFactory::CreateObject( const OUString
& rClassName
)
2960 return Impl_CreateUnoStruct( rClassName
);
2964 // Provisional interface for the UNO-Connection
2965 // Deliver a SbxObject, that wrap an Uno-Interface
2966 SbxObjectRef
GetSbUnoObject( const OUString
& aName
, const Any
& aUnoObj_
)
2968 return new SbUnoObject( aName
, aUnoObj_
);
2971 // Force creation of all properties for debugging
2972 void createAllObjectProperties( SbxObject
* pObj
)
2977 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
2978 SbUnoStructRefObject
* pUnoStructObj
= PTR_CAST(SbUnoStructRefObject
,pObj
);
2981 pUnoObj
->createAllProperties();
2983 else if ( pUnoStructObj
)
2985 pUnoStructObj
->createAllProperties();
2989 pObj
->GetAll( SbxCLASS_DONTCARE
);
2994 void RTL_Impl_CreateUnoStruct( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
2999 // We need 1 parameter minimum
3000 if ( rPar
.Count() < 2 )
3002 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3006 // get the name of the class of the struct
3007 OUString aClassName
= rPar
.Get(1)->GetOUString();
3009 // try to create Struct with the same name
3010 SbUnoObjectRef xUnoObj
= Impl_CreateUnoStruct( aClassName
);
3015 // return the object
3016 SbxVariableRef refVar
= rPar
.Get(0);
3017 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3020 void RTL_Impl_CreateUnoService( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3025 // We need 1 Parameter minimum
3026 if ( rPar
.Count() < 2 )
3028 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3032 // get the name of the class of the struct
3033 OUString aServiceName
= rPar
.Get(1)->GetOUString();
3035 // search for the service and instatiate it
3036 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3037 Reference
< XInterface
> xInterface
;
3040 xInterface
= xFactory
->createInstance( aServiceName
);
3042 catch( const Exception
& )
3044 implHandleAnyException( ::cppu::getCaughtException() );
3047 SbxVariableRef refVar
= rPar
.Get(0);
3048 if( xInterface
.is() )
3051 aAny
<<= xInterface
;
3053 // Create a SbUnoObject out of it and return it
3054 SbUnoObjectRef xUnoObj
= new SbUnoObject( aServiceName
, aAny
);
3055 if( xUnoObj
->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID
)
3057 // return the object
3058 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3062 refVar
->PutObject( NULL
);
3067 refVar
->PutObject( NULL
);
3071 void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3076 // We need 2 parameter minimum
3077 if ( rPar
.Count() < 3 )
3079 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3083 // get the name of the class of the struct
3084 OUString aServiceName
= rPar
.Get(1)->GetOUString();
3085 Any aArgAsAny
= sbxToUnoValue( rPar
.Get(2),
3086 getCppuType( (Sequence
<Any
>*)0 ) );
3087 Sequence
< Any
> aArgs
;
3088 aArgAsAny
>>= aArgs
;
3090 // search for the service and instatiate it
3091 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3092 Reference
< XInterface
> xInterface
;
3095 xInterface
= xFactory
->createInstanceWithArguments( aServiceName
, aArgs
);
3097 catch( const Exception
& )
3099 implHandleAnyException( ::cppu::getCaughtException() );
3102 SbxVariableRef refVar
= rPar
.Get(0);
3103 if( xInterface
.is() )
3106 aAny
<<= xInterface
;
3108 // Create a SbUnoObject out of it and return it
3109 SbUnoObjectRef xUnoObj
= new SbUnoObject( aServiceName
, aAny
);
3110 if( xUnoObj
->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID
)
3112 // return the object
3113 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3117 refVar
->PutObject( NULL
);
3122 refVar
->PutObject( NULL
);
3126 void RTL_Impl_GetProcessServiceManager( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3131 SbxVariableRef refVar
= rPar
.Get(0);
3133 // get the global service manager
3134 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3138 // Create a SbUnoObject out of it and return it
3139 SbUnoObjectRef xUnoObj
= new SbUnoObject( OUString( "ProcessServiceManager" ), aAny
);
3140 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3143 void RTL_Impl_HasInterfaces( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3148 // We need 2 parameter minimum
3149 sal_uInt16 nParCount
= rPar
.Count();
3152 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3156 // variable for the return value
3157 SbxVariableRef refVar
= rPar
.Get(0);
3158 refVar
->PutBool( sal_False
);
3160 // get the Uno-Object
3161 SbxBaseRef pObj
= (SbxBase
*)rPar
.Get( 1 )->GetObject();
3162 if( !(pObj
&& pObj
->ISA(SbUnoObject
)) )
3166 Any aAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
3167 TypeClass eType
= aAny
.getValueType().getTypeClass();
3168 if( eType
!= TypeClass_INTERFACE
)
3172 // get the interface out of the Any
3173 Reference
< XInterface
> x
= *(Reference
< XInterface
>*)aAny
.getValue();
3175 // get CoreReflection
3176 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
3177 if( !xCoreReflection
.is() )
3181 for( sal_uInt16 i
= 2 ; i
< nParCount
; i
++ )
3183 // get the name of the interface of the struct
3184 OUString aIfaceName
= rPar
.Get( i
)->GetOUString();
3186 // search for the class
3187 Reference
< XIdlClass
> xClass
= xCoreReflection
->forName( aIfaceName
);
3192 // check if the interface will be supported
3193 OUString aClassName
= xClass
->getName();
3194 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
3195 if( !x
->queryInterface( aClassType
).hasValue() )
3201 // Every thing works; then return TRUE
3202 refVar
->PutBool( sal_True
);
3205 void RTL_Impl_IsUnoStruct( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3210 // We need 1 parameter minimum
3211 if ( rPar
.Count() < 2 )
3213 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3217 // variable for the return value
3218 SbxVariableRef refVar
= rPar
.Get(0);
3219 refVar
->PutBool( sal_False
);
3221 // get the Uno-Object
3222 SbxVariableRef xParam
= rPar
.Get( 1 );
3223 if( !xParam
->IsObject() )
3227 SbxBaseRef pObj
= (SbxBase
*)rPar
.Get( 1 )->GetObject();
3228 if( !(pObj
&& pObj
->ISA(SbUnoObject
)) )
3232 Any aAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
3233 TypeClass eType
= aAny
.getValueType().getTypeClass();
3234 if( eType
== TypeClass_STRUCT
)
3236 refVar
->PutBool( sal_True
);
3241 void RTL_Impl_EqualUnoObjects( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3246 if ( rPar
.Count() < 3 )
3248 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3252 // variable for the return value
3253 SbxVariableRef refVar
= rPar
.Get(0);
3254 refVar
->PutBool( sal_False
);
3256 // get the Uno-Objects
3257 SbxVariableRef xParam1
= rPar
.Get( 1 );
3258 if( !xParam1
->IsObject() )
3262 SbxBaseRef pObj1
= (SbxBase
*)xParam1
->GetObject();
3263 if( !(pObj1
&& pObj1
->ISA(SbUnoObject
)) )
3267 Any aAny1
= ((SbUnoObject
*)(SbxBase
*)pObj1
)->getUnoAny();
3268 TypeClass eType1
= aAny1
.getValueType().getTypeClass();
3269 if( eType1
!= TypeClass_INTERFACE
)
3273 Reference
< XInterface
> x1
;
3276 SbxVariableRef xParam2
= rPar
.Get( 2 );
3277 if( !xParam2
->IsObject() )
3281 SbxBaseRef pObj2
= (SbxBase
*)xParam2
->GetObject();
3282 if( !(pObj2
&& pObj2
->ISA(SbUnoObject
)) )
3286 Any aAny2
= ((SbUnoObject
*)(SbxBase
*)pObj2
)->getUnoAny();
3287 TypeClass eType2
= aAny2
.getValueType().getTypeClass();
3288 if( eType2
!= TypeClass_INTERFACE
)
3292 Reference
< XInterface
> x2
;
3297 refVar
->PutBool( sal_True
);
3302 // helper wrapper function to interact with TypeProvider and
3303 // XTypeDescriptionEnumerationAccess.
3304 // if it fails for whatever reason
3305 // returned Reference<> be null e.g. .is() will be false
3307 Reference
< XTypeDescriptionEnumeration
> getTypeDescriptorEnumeration( const OUString
& sSearchRoot
,
3308 const Sequence
< TypeClass
>& types
,
3309 TypeDescriptionSearchDepth depth
)
3311 Reference
< XTypeDescriptionEnumeration
> xEnum
;
3312 Reference
< XTypeDescriptionEnumerationAccess
> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY
);
3313 if ( xTypeEnumAccess
.is() )
3317 xEnum
= xTypeEnumAccess
->createTypeDescriptionEnumeration(
3318 sSearchRoot
, types
, depth
);
3320 catch(const NoSuchTypeNameException
& /*nstne*/ ) {}
3321 catch(const InvalidTypeNameException
& /*nstne*/ ) {}
3326 typedef boost::unordered_map
< OUString
, Any
, OUStringHash
, ::std::equal_to
< OUString
> > VBAConstantsHash
;
3329 VBAConstantHelper::instance()
3331 static VBAConstantHelper aHelper
;
3335 void VBAConstantHelper::init()
3339 Sequence
< TypeClass
> types(1);
3340 types
[ 0 ] = TypeClass_CONSTANTS
;
3341 Reference
< XTypeDescriptionEnumeration
> xEnum
= getTypeDescriptorEnumeration( OUString(defaultNameSpace
), types
, TypeDescriptionSearchDepth_INFINITE
);
3347 while ( xEnum
->hasMoreElements() )
3349 Reference
< XConstantsTypeDescription
> xConstants( xEnum
->nextElement(), UNO_QUERY
);
3350 if ( xConstants
.is() )
3352 // store constant group name
3353 OUString sFullName
= xConstants
->getName();
3354 sal_Int32 indexLastDot
= sFullName
.lastIndexOf('.');
3355 OUString
sLeafName( sFullName
);
3356 if ( indexLastDot
> -1 )
3358 sLeafName
= sFullName
.copy( indexLastDot
+ 1);
3360 aConstCache
.push_back( sLeafName
); // assume constant group names are unique
3361 Sequence
< Reference
< XConstantTypeDescription
> > aConsts
= xConstants
->getConstants();
3362 for (sal_Int32 i
= 0; i
!= aConsts
.getLength(); ++i
)
3364 // store constant member name
3365 sFullName
= aConsts
[i
]->getName();
3366 indexLastDot
= sFullName
.lastIndexOf('.');
3367 sLeafName
= sFullName
;
3368 if ( indexLastDot
> -1 )
3370 sLeafName
= sFullName
.copy( indexLastDot
+ 1);
3372 aConstHash
[ sLeafName
.toAsciiLowerCase() ] = aConsts
[i
]->getConstantValue();
3381 VBAConstantHelper::isVBAConstantType( const OUString
& rName
)
3384 bool bConstant
= false;
3385 OUString
sKey( rName
);
3386 VBAConstantsVector::const_iterator it
= aConstCache
.begin();
3388 for( ; it
!= aConstCache
.end(); ++it
)
3390 if( sKey
.equalsIgnoreAsciiCase( *it
) )
3400 VBAConstantHelper::getVBAConstant( const OUString
& rName
)
3402 SbxVariable
* pConst
= NULL
;
3405 OUString
sKey( rName
);
3407 VBAConstantsHash::const_iterator it
= aConstHash
.find( sKey
.toAsciiLowerCase() );
3409 if ( it
!= aConstHash
.end() )
3411 pConst
= new SbxVariable( SbxVARIANT
);
3412 pConst
->SetName( rName
);
3413 unoToSbxValue( pConst
, it
->second
);
3419 // Function to search for a global identifier in the
3420 // UnoScope and to wrap it for Sbx
3421 SbUnoClass
* findUnoClass( const OUString
& rName
)
3423 // #105550 Check if module exists
3424 SbUnoClass
* pUnoClass
= NULL
;
3426 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3427 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3429 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3430 Reference
< XTypeDescription
> xTypeDesc
;
3433 if( xTypeDesc
.is() )
3435 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3436 if( eTypeClass
== TypeClass_MODULE
|| eTypeClass
== TypeClass_CONSTANTS
)
3438 pUnoClass
= new SbUnoClass( rName
);
3445 SbxVariable
* SbUnoClass::Find( const OUString
& rName
, SbxClassType
)
3447 SbxVariable
* pRes
= SbxObject::Find( rName
, SbxCLASS_VARIABLE
);
3449 // If nothing were located the submodule isn't known yet
3452 // If it is already a class, ask for the field
3456 OUString
aUStr( rName
);
3457 Reference
< XIdlField
> xField
= m_xClass
->getField( aUStr
);
3458 Reference
< XIdlClass
> xClass
;
3464 aAny
= xField
->get( aAny
);
3467 pRes
= new SbxVariable( SbxVARIANT
);
3468 pRes
->SetName( rName
);
3469 unoToSbxValue( pRes
, aAny
);
3471 catch( const Exception
& )
3473 implHandleAnyException( ::cppu::getCaughtException() );
3479 // expand fully qualified name
3480 OUString aNewName
= GetName();
3484 // get CoreReflection
3485 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
3486 if( xCoreReflection
.is() )
3488 // Is it a constant?
3489 Reference
< XHierarchicalNameAccess
> xHarryName( xCoreReflection
, UNO_QUERY
);
3490 if( xHarryName
.is() )
3494 Any aValue
= xHarryName
->getByHierarchicalName( aNewName
);
3495 TypeClass eType
= aValue
.getValueType().getTypeClass();
3497 // Interface located? Then it is a class
3498 if( eType
== TypeClass_INTERFACE
)
3500 Reference
< XInterface
> xIface
= *(Reference
< XInterface
>*)aValue
.getValue();
3501 Reference
< XIdlClass
> xClass( xIface
, UNO_QUERY
);
3504 pRes
= new SbxVariable( SbxVARIANT
);
3505 SbxObjectRef xWrapper
= (SbxObject
*)new SbUnoClass( aNewName
, xClass
);
3506 pRes
->PutObject( xWrapper
);
3511 pRes
= new SbxVariable( SbxVARIANT
);
3512 unoToSbxValue( pRes
, aValue
);
3515 catch( const NoSuchElementException
& )
3520 // Otherwise take it again as class
3523 SbUnoClass
* pNewClass
= findUnoClass( aNewName
);
3526 pRes
= new SbxVariable( SbxVARIANT
);
3527 SbxObjectRef xWrapper
= (SbxObject
*)pNewClass
;
3528 pRes
->PutObject( xWrapper
);
3535 SbUnoService
* pUnoService
= findUnoService( aNewName
);
3538 pRes
= new SbxVariable( SbxVARIANT
);
3539 SbxObjectRef xWrapper
= (SbxObject
*)pUnoService
;
3540 pRes
->PutObject( xWrapper
);
3544 // An UNO singleton?
3547 SbUnoSingleton
* pUnoSingleton
= findUnoSingleton( aNewName
);
3550 pRes
= new SbxVariable( SbxVARIANT
);
3551 SbxObjectRef xWrapper
= (SbxObject
*)pUnoSingleton
;
3552 pRes
->PutObject( xWrapper
);
3560 pRes
->SetName( rName
);
3562 // Insert variable, so that it could be found later
3563 QuickInsert( pRes
);
3565 // Take us out as listener at once,
3566 // the values are all constant
3567 if( pRes
->IsBroadcaster() )
3568 EndListening( pRes
->GetBroadcaster(), sal_True
);
3575 SbUnoService
* findUnoService( const OUString
& rName
)
3577 SbUnoService
* pSbUnoService
= NULL
;
3579 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3580 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3582 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3583 Reference
< XTypeDescription
> xTypeDesc
;
3586 if( xTypeDesc
.is() )
3588 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3589 if( eTypeClass
== TypeClass_SERVICE
)
3591 Reference
< XServiceTypeDescription2
> xServiceTypeDesc( xTypeDesc
, UNO_QUERY
);
3592 if( xServiceTypeDesc
.is() )
3593 pSbUnoService
= new SbUnoService( rName
, xServiceTypeDesc
);
3597 return pSbUnoService
;
3600 SbxVariable
* SbUnoService::Find( const OUString
& rName
, SbxClassType
)
3602 SbxVariable
* pRes
= SbxObject::Find( rName
, SbxCLASS_METHOD
);
3606 // If it is already a class ask for a field
3607 if( m_bNeedsInit
&& m_xServiceTypeDesc
.is() )
3609 m_bNeedsInit
= false;
3611 Sequence
< Reference
< XServiceConstructorDescription
> > aSCDSeq
= m_xServiceTypeDesc
->getConstructors();
3612 const Reference
< XServiceConstructorDescription
>* pCtorSeq
= aSCDSeq
.getConstArray();
3613 int nCtorCount
= aSCDSeq
.getLength();
3614 for( int i
= 0 ; i
< nCtorCount
; ++i
)
3616 Reference
< XServiceConstructorDescription
> xCtor
= pCtorSeq
[i
];
3618 OUString
aName( xCtor
->getName() );
3619 if( aName
.isEmpty() )
3621 if( xCtor
->isDefaultConstructor() )
3627 if( !aName
.isEmpty() )
3629 // Create and insert SbUnoServiceCtor
3630 SbxVariableRef xSbCtorRef
= new SbUnoServiceCtor( aName
, xCtor
);
3631 QuickInsert( (SbxVariable
*)xSbCtorRef
);
3634 pRes
= SbxObject::Find( rName
, SbxCLASS_METHOD
);
3641 void SbUnoService::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
3642 const SfxHint
& rHint
, const TypeId
& rHintType
)
3644 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
3647 SbxVariable
* pVar
= pHint
->GetVar();
3648 SbxArray
* pParams
= pVar
->GetParameters();
3649 SbUnoServiceCtor
* pUnoCtor
= PTR_CAST(SbUnoServiceCtor
,pVar
);
3650 if( pUnoCtor
&& pHint
->GetId() == SBX_HINT_DATAWANTED
)
3652 // Parameter count -1 because of Param0 == this
3653 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
3655 bool bOutParams
= false;
3657 Reference
< XServiceConstructorDescription
> xCtor
= pUnoCtor
->getServiceCtorDesc();
3658 Sequence
< Reference
< XParameter
> > aParameterSeq
= xCtor
->getParameters();
3659 const Reference
< XParameter
>* pParameterSeq
= aParameterSeq
.getConstArray();
3660 sal_uInt32 nUnoParamCount
= aParameterSeq
.getLength();
3662 // Default: Ignore not needed parameters
3663 bool bParameterError
= false;
3665 // Is the last parameter a rest parameter?
3666 bool bRestParameterMode
= false;
3667 if( nUnoParamCount
> 0 )
3669 Reference
< XParameter
> xLastParam
= pParameterSeq
[ nUnoParamCount
- 1 ];
3670 if( xLastParam
.is() )
3672 if( xLastParam
->isRestParameter() )
3673 bRestParameterMode
= true;
3677 // Too many parameters with context as first parameter?
3678 sal_uInt16 nSbxParameterOffset
= 1;
3679 sal_uInt16 nParameterOffsetByContext
= 0;
3680 Reference
< XComponentContext
> xFirstParamContext
;
3681 if( nParamCount
> nUnoParamCount
)
3683 // Check if first parameter is a context and use it
3684 // then in createInstanceWithArgumentsAndContext
3685 Any aArg0
= sbxToUnoValue( pParams
->Get( nSbxParameterOffset
) );
3686 if( (aArg0
>>= xFirstParamContext
) && xFirstParamContext
.is() )
3687 nParameterOffsetByContext
= 1;
3690 sal_uInt32 nEffectiveParamCount
= nParamCount
- nParameterOffsetByContext
;
3691 sal_uInt32 nAllocParamCount
= nEffectiveParamCount
;
3692 if( nEffectiveParamCount
> nUnoParamCount
)
3694 if( !bRestParameterMode
)
3696 nEffectiveParamCount
= nUnoParamCount
;
3697 nAllocParamCount
= nUnoParamCount
;
3700 // Not enough parameters?
3701 else if( nUnoParamCount
> nEffectiveParamCount
)
3703 // RestParameterMode only helps if one (the last) parameter is missing
3704 int nDiff
= nUnoParamCount
- nEffectiveParamCount
;
3705 if( !bRestParameterMode
|| nDiff
> 1 )
3707 bParameterError
= true;
3708 StarBASIC::Error( SbERR_NOT_OPTIONAL
);
3712 if( !bParameterError
)
3714 if( nAllocParamCount
> 0 )
3716 args
.realloc( nAllocParamCount
);
3717 Any
* pAnyArgs
= args
.getArray();
3718 for( sal_uInt32 i
= 0 ; i
< nEffectiveParamCount
; i
++ )
3720 sal_uInt16 iSbx
= (sal_uInt16
)(i
+ nSbxParameterOffset
+ nParameterOffsetByContext
);
3722 // bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
3723 Reference
< XParameter
> xParam
;
3724 if( i
< nUnoParamCount
)
3726 xParam
= pParameterSeq
[i
];
3730 Reference
< XTypeDescription
> xParamTypeDesc
= xParam
->getType();
3731 if( !xParamTypeDesc
.is() )
3733 com::sun::star::uno::Type
aType( xParamTypeDesc
->getTypeClass(), xParamTypeDesc
->getName() );
3735 // sbx paramter needs offset 1
3736 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( iSbx
), aType
);
3738 // Check for out parameter if not already done
3741 if( xParam
->isOut() )
3747 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( iSbx
) );
3752 // "Call" ctor using createInstanceWithArgumentsAndContext
3753 Reference
< XComponentContext
> xContext(
3754 xFirstParamContext
.is()
3755 ? xFirstParamContext
3756 : comphelper::getProcessComponentContext() );
3757 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
3760 OUString aServiceName
= GetName();
3761 Reference
< XInterface
> xRet
;
3764 xRet
= xServiceMgr
->createInstanceWithArgumentsAndContext( aServiceName
, args
, xContext
);
3766 catch( const Exception
& )
3768 implHandleAnyException( ::cppu::getCaughtException() );
3771 unoToSbxValue( pVar
, aRetAny
);
3773 // Copy back out parameters?
3776 const Any
* pAnyArgs
= args
.getConstArray();
3778 for( sal_uInt32 j
= 0 ; j
< nUnoParamCount
; j
++ )
3780 Reference
< XParameter
> xParam
= pParameterSeq
[j
];
3784 if( xParam
->isOut() )
3785 unoToSbxValue( (SbxVariable
*)pParams
->Get( (sal_uInt16
)(j
+1) ), pAnyArgs
[ j
] );
3791 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
3797 static SbUnoServiceCtor
* pFirstCtor
= NULL
;
3799 void clearUnoServiceCtors( void )
3801 SbUnoServiceCtor
* pCtor
= pFirstCtor
;
3804 pCtor
->SbxValue::Clear();
3805 pCtor
= pCtor
->pNext
;
3809 SbUnoServiceCtor::SbUnoServiceCtor( const OUString
& aName_
, Reference
< XServiceConstructorDescription
> xServiceCtorDesc
)
3810 : SbxMethod( aName_
, SbxOBJECT
)
3811 , m_xServiceCtorDesc( xServiceCtorDesc
)
3816 SbUnoServiceCtor::~SbUnoServiceCtor()
3820 SbxInfo
* SbUnoServiceCtor::GetInfo()
3822 SbxInfo
* pRet
= NULL
;
3828 SbUnoSingleton
* findUnoSingleton( const OUString
& rName
)
3830 SbUnoSingleton
* pSbUnoSingleton
= NULL
;
3832 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3833 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3835 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3836 Reference
< XTypeDescription
> xTypeDesc
;
3839 if( xTypeDesc
.is() )
3841 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3842 if( eTypeClass
== TypeClass_SINGLETON
)
3844 Reference
< XSingletonTypeDescription
> xSingletonTypeDesc( xTypeDesc
, UNO_QUERY
);
3845 if( xSingletonTypeDesc
.is() )
3846 pSbUnoSingleton
= new SbUnoSingleton( rName
, xSingletonTypeDesc
);
3850 return pSbUnoSingleton
;
3853 SbUnoSingleton::SbUnoSingleton( const OUString
& aName_
,
3854 const Reference
< XSingletonTypeDescription
>& xSingletonTypeDesc
)
3855 : SbxObject( aName_
)
3856 , m_xSingletonTypeDesc( xSingletonTypeDesc
)
3858 SbxVariableRef xGetMethodRef
= new SbxMethod( OUString( "get" ), SbxOBJECT
);
3859 QuickInsert( (SbxVariable
*)xGetMethodRef
);
3862 void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
3863 const SfxHint
& rHint
, const TypeId
& rHintType
)
3865 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
3868 SbxVariable
* pVar
= pHint
->GetVar();
3869 SbxArray
* pParams
= pVar
->GetParameters();
3870 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
3871 sal_uInt32 nAllowedParamCount
= 1;
3873 Reference
< XComponentContext
> xContextToUse
;
3874 if( nParamCount
> 0 )
3876 // Check if first parameter is a context and use it then
3877 Reference
< XComponentContext
> xFirstParamContext
;
3878 Any aArg1
= sbxToUnoValue( pParams
->Get( 1 ) );
3879 if( (aArg1
>>= xFirstParamContext
) && xFirstParamContext
.is() )
3880 xContextToUse
= xFirstParamContext
;
3883 if( !xContextToUse
.is() )
3885 xContextToUse
= comphelper::getProcessComponentContext();
3886 --nAllowedParamCount
;
3889 if( nParamCount
> nAllowedParamCount
)
3891 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3896 if( xContextToUse
.is() )
3898 OUString
aSingletonName( "/singletons/" );
3899 aSingletonName
+= GetName();
3900 Reference
< XInterface
> xRet
;
3901 xContextToUse
->getValueByName( aSingletonName
) >>= xRet
;
3904 unoToSbxValue( pVar
, aRetAny
);
3908 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
3913 //========================================================================
3915 // Implementation of an EventAttacher-drawn AllListener, which
3916 // solely transmits several events to an general AllListener
3917 class BasicAllListener_Impl
: public BasicAllListenerHelper
3919 virtual void firing_impl(const AllEventObject
& Event
, Any
* pRet
);
3922 SbxObjectRef xSbxObj
;
3923 OUString aPrefixName
;
3925 BasicAllListener_Impl( const OUString
& aPrefixName
);
3926 ~BasicAllListener_Impl();
3928 // Methods of XAllListener
3929 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw ( RuntimeException
);
3930 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw ( RuntimeException
);
3932 // Methods of XEventListener
3933 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw ( RuntimeException
);
3937 //========================================================================
3938 BasicAllListener_Impl::BasicAllListener_Impl(const OUString
& aPrefixName_
)
3939 : aPrefixName( aPrefixName_
)
3943 //========================================================================
3944 BasicAllListener_Impl::~BasicAllListener_Impl()
3948 //========================================================================
3950 void BasicAllListener_Impl::firing_impl( const AllEventObject
& Event
, Any
* pRet
)
3952 SolarMutexGuard guard
;
3956 OUString aMethodName
= aPrefixName
;
3957 aMethodName
= aMethodName
+ Event
.MethodName
;
3959 SbxVariable
* pP
= xSbxObj
;
3960 while( pP
->GetParent() )
3962 pP
= pP
->GetParent();
3963 StarBASIC
* pLib
= PTR_CAST(StarBASIC
,pP
);
3966 // Create in a Basic Array
3967 SbxArrayRef xSbxArray
= new SbxArray( SbxVARIANT
);
3968 const Any
* pArgs
= Event
.Arguments
.getConstArray();
3969 sal_Int32 nCount
= Event
.Arguments
.getLength();
3970 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
3973 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
3974 unoToSbxValue( (SbxVariable
*)xVar
, pArgs
[i
] );
3975 xSbxArray
->Put( xVar
, sal::static_int_cast
< sal_uInt16
>(i
+1) );
3978 pLib
->Call( aMethodName
, xSbxArray
);
3980 // get the return value from the Param-Array, if requested
3983 SbxVariable
* pVar
= xSbxArray
->Get( 0 );
3986 // #95792 Avoid a second call
3987 sal_uInt16 nFlags
= pVar
->GetFlags();
3988 pVar
->SetFlag( SBX_NO_BROADCAST
);
3989 *pRet
= sbxToUnoValueImpl( pVar
);
3990 pVar
->SetFlags( nFlags
);
4000 // Methods of Listener
4001 void BasicAllListener_Impl::firing( const AllEventObject
& Event
) throw ( RuntimeException
)
4003 firing_impl( Event
, NULL
);
4006 Any
BasicAllListener_Impl::approveFiring( const AllEventObject
& Event
) throw ( RuntimeException
)
4009 firing_impl( Event
, &aRetAny
);
4013 //========================================================================
4014 // Methods of XEventListener
4015 void BasicAllListener_Impl ::disposing(const EventObject
& ) throw ( RuntimeException
)
4017 SolarMutexGuard guard
;
4024 //*************************************************************************
4025 // class InvocationToAllListenerMapper
4026 // helper class to map XInvocation to XAllListener (also in project eventattacher!)
4027 //*************************************************************************
4028 class InvocationToAllListenerMapper
: public WeakImplHelper1
< XInvocation
>
4031 InvocationToAllListenerMapper( const Reference
< XIdlClass
>& ListenerType
,
4032 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
);
4035 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection(void) throw( RuntimeException
);
4036 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
4037 throw( IllegalArgumentException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
4038 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
)
4039 throw( UnknownPropertyException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
4040 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) throw( UnknownPropertyException
, RuntimeException
);
4041 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) throw( RuntimeException
);
4042 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) throw( RuntimeException
);
4045 Reference
< XIdlReflection
> m_xCoreReflection
;
4046 Reference
< XAllListener
> m_xAllListener
;
4047 Reference
< XIdlClass
> m_xListenerType
;
4052 // Function to replace AllListenerAdapterService::createAllListerAdapter
4053 Reference
< XInterface
> createAllListenerAdapter
4055 const Reference
< XInvocationAdapterFactory2
>& xInvocationAdapterFactory
,
4056 const Reference
< XIdlClass
>& xListenerType
,
4057 const Reference
< XAllListener
>& xListener
,
4061 Reference
< XInterface
> xAdapter
;
4062 if( xInvocationAdapterFactory
.is() && xListenerType
.is() && xListener
.is() )
4064 Reference
< XInvocation
> xInvocationToAllListenerMapper
=
4065 (XInvocation
*)new InvocationToAllListenerMapper( xListenerType
, xListener
, Helper
);
4066 Type
aListenerType( xListenerType
->getTypeClass(), xListenerType
->getName() );
4067 Sequence
<Type
> arg2(1);
4068 arg2
[0] = aListenerType
;
4069 xAdapter
= xInvocationAdapterFactory
->createAdapter( xInvocationToAllListenerMapper
, arg2
);
4075 //--------------------------------------------------------------------------------------------------
4076 // InvocationToAllListenerMapper
4077 InvocationToAllListenerMapper::InvocationToAllListenerMapper
4078 ( const Reference
< XIdlClass
>& ListenerType
, const Reference
< XAllListener
>& AllListener
, const Any
& Helper
)
4079 : m_xAllListener( AllListener
)
4080 , m_xListenerType( ListenerType
)
4081 , m_Helper( Helper
)
4085 //*************************************************************************
4086 Reference
< XIntrospectionAccess
> SAL_CALL
InvocationToAllListenerMapper::getIntrospection(void)
4087 throw( RuntimeException
)
4089 return Reference
< XIntrospectionAccess
>();
4092 //*************************************************************************
4093 Any SAL_CALL
InvocationToAllListenerMapper::invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
,
4094 Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
4095 throw( IllegalArgumentException
, CannotConvertException
,
4096 InvocationTargetException
, RuntimeException
)
4098 (void)OutParamIndex
;
4103 // Check if to firing or approveFiring has to be called
4104 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( FunctionName
);
4105 bool bApproveFiring
= false;
4108 Reference
< XIdlClass
> xReturnType
= xMethod
->getReturnType();
4109 Sequence
< Reference
< XIdlClass
> > aExceptionSeq
= xMethod
->getExceptionTypes();
4110 if( ( xReturnType
.is() && xReturnType
->getTypeClass() != TypeClass_VOID
) ||
4111 aExceptionSeq
.getLength() > 0 )
4113 bApproveFiring
= true;
4117 Sequence
< ParamInfo
> aParamSeq
= xMethod
->getParameterInfos();
4118 sal_uInt32 nParamCount
= aParamSeq
.getLength();
4119 if( nParamCount
> 1 )
4121 const ParamInfo
* pInfos
= aParamSeq
.getConstArray();
4122 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
4124 if( pInfos
[ i
].aMode
!= ParamMode_IN
)
4126 bApproveFiring
= true;
4133 AllEventObject aAllEvent
;
4134 aAllEvent
.Source
= (OWeakObject
*) this;
4135 aAllEvent
.Helper
= m_Helper
;
4136 aAllEvent
.ListenerType
= Type(m_xListenerType
->getTypeClass(), m_xListenerType
->getName() );
4137 aAllEvent
.MethodName
= FunctionName
;
4138 aAllEvent
.Arguments
= Params
;
4139 if( bApproveFiring
)
4140 aRet
= m_xAllListener
->approveFiring( aAllEvent
);
4142 m_xAllListener
->firing( aAllEvent
);
4146 //*************************************************************************
4147 void SAL_CALL
InvocationToAllListenerMapper::setValue(const OUString
& PropertyName
, const Any
& Value
)
4148 throw( UnknownPropertyException
, CannotConvertException
,
4149 InvocationTargetException
, RuntimeException
)
4155 //*************************************************************************
4156 Any SAL_CALL
InvocationToAllListenerMapper::getValue(const OUString
& PropertyName
)
4157 throw( UnknownPropertyException
, RuntimeException
)
4164 //*************************************************************************
4165 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasMethod(const OUString
& Name
)
4166 throw( RuntimeException
)
4168 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( Name
);
4169 return xMethod
.is();
4172 //*************************************************************************
4173 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasProperty(const OUString
& Name
)
4174 throw( RuntimeException
)
4176 Reference
< XIdlField
> xField
= m_xListenerType
->getField( Name
);
4180 //========================================================================
4181 // create Uno-Service
4182 // 1. Parameter == Prefix-Name of the macro
4183 // 2. Parameter == fully qualified name of the listener
4184 void SbRtl_CreateUnoListener( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
4185 //RTLFUNC(CreateUnoListener)
4189 // We need 2 parameters
4190 if ( rPar
.Count() != 3 )
4192 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
4196 // get the name of the class of the struct
4197 OUString aPrefixName
= rPar
.Get(1)->GetOUString();
4198 OUString aListenerClassName
= rPar
.Get(2)->GetOUString();
4200 // get the CoreReflection
4201 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
4202 if( !xCoreReflection
.is() )
4205 // get the AllListenerAdapterService
4206 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
4209 Reference
< XIdlClass
> xClass
= xCoreReflection
->forName( aListenerClassName
);
4213 // From 1999-11-30: get the InvocationAdapterFactory
4214 Reference
< XInvocationAdapterFactory2
> xInvocationAdapterFactory
=
4215 InvocationAdapterFactory::create( xContext
);
4217 BasicAllListener_Impl
* p
;
4218 Reference
< XAllListener
> xAllLst
= p
= new BasicAllListener_Impl( aPrefixName
);
4220 Reference
< XInterface
> xLst
= createAllListenerAdapter( xInvocationAdapterFactory
, xClass
, xAllLst
, aTmp
);
4224 OUString aClassName
= xClass
->getName();
4225 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
4226 aTmp
= xLst
->queryInterface( aClassType
);
4227 if( !aTmp
.hasValue() )
4230 SbUnoObject
* pUnoObj
= new SbUnoObject( aListenerClassName
, aTmp
);
4231 p
->xSbxObj
= pUnoObj
;
4232 p
->xSbxObj
->SetParent( pBasic
);
4234 // #100326 Register listener object to set Parent NULL in Dtor
4235 SbxArrayRef xBasicUnoListeners
= pBasic
->getUnoListeners();
4236 xBasicUnoListeners
->Insert( pUnoObj
, xBasicUnoListeners
->Count() );
4238 // return the object
4239 SbxVariableRef refVar
= rPar
.Get(0);
4240 refVar
->PutObject( p
->xSbxObj
);
4243 //========================================================================
4244 // Represents the DefaultContext property of the ProcessServiceManager
4245 // in the Basic runtime system.
4246 void RTL_Impl_GetDefaultContext( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
4251 SbxVariableRef refVar
= rPar
.Get(0);
4253 Any
aContextAny( comphelper::getProcessComponentContext() );
4255 SbUnoObjectRef xUnoObj
= new SbUnoObject( OUString( "DefaultContext" ), aContextAny
);
4256 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
4259 //========================================================================
4260 // Creates a Basic wrapper object for a strongly typed Uno value
4261 // 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
4262 void RTL_Impl_CreateUnoValue( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
4267 static OUString
aTypeTypeString( "type" );
4269 // 2 parameters needed
4270 if ( rPar
.Count() != 3 )
4272 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
4276 // get the name of the class of the struct
4277 OUString aTypeName
= rPar
.Get(1)->GetOUString();
4278 SbxVariable
* pVal
= rPar
.Get(2);
4280 if( aTypeName
== aTypeTypeString
)
4282 SbxDataType eBaseType
= pVal
->SbxValue::GetType();
4283 OUString aValTypeName
;
4284 if( eBaseType
== SbxSTRING
)
4286 aValTypeName
= pVal
->GetOUString();
4288 else if( eBaseType
== SbxOBJECT
)
4291 Reference
< XIdlClass
> xIdlClass
;
4293 SbxBaseRef pObj
= (SbxBase
*)pVal
->GetObject();
4294 if( pObj
&& pObj
->ISA(SbUnoObject
) )
4296 Any aUnoAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
4297 aUnoAny
>>= xIdlClass
;
4300 if( xIdlClass
.is() )
4302 aValTypeName
= xIdlClass
->getName();
4306 bool bSuccess
= implGetTypeByName( aValTypeName
, aType
);
4309 Any
aTypeAny( aType
);
4310 SbxVariableRef refVar
= rPar
.Get(0);
4311 SbxObjectRef xUnoAnyObject
= new SbUnoAnyObject( aTypeAny
);
4312 refVar
->PutObject( xUnoAnyObject
);
4318 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
4322 aRet
= xTypeAccess
->getByHierarchicalName( aTypeName
);
4324 catch( const NoSuchElementException
& e1
)
4326 OUString
aNoSuchElementExceptionName( "com.sun.star.container.NoSuchElementException" );
4327 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
4328 implGetExceptionMsg( e1
, aNoSuchElementExceptionName
) );
4331 Reference
< XTypeDescription
> xTypeDesc
;
4333 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
4334 Type
aDestType( eTypeClass
, aTypeName
);
4338 Any aVal
= sbxToUnoValueImpl( pVal
);
4339 Any aConvertedVal
= convertAny( aVal
, aDestType
);
4341 SbxVariableRef refVar
= rPar
.Get(0);
4342 SbxObjectRef xUnoAnyObject
= new SbUnoAnyObject( aConvertedVal
);
4343 refVar
->PutObject( xUnoAnyObject
);
4346 //==========================================================================
4352 // this mutex is necessary for OInterfaceContainerHelper
4353 ::osl::Mutex m_aMutex
;
4357 typedef WeakImplHelper2
< XInvocation
, XComponent
> ModuleInvocationProxyHelper
;
4359 class ModuleInvocationProxy
: public OMutexBasis
,
4360 public ModuleInvocationProxyHelper
4363 SbxObjectRef m_xScopeObj
;
4364 bool m_bProxyIsClassModuleObject
;
4366 ::cppu::OInterfaceContainerHelper m_aListeners
;
4369 ModuleInvocationProxy( const OUString
& aPrefix
, SbxObjectRef xScopeObj
);
4370 ~ModuleInvocationProxy()
4374 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection() throw();
4375 virtual void SAL_CALL
setValue( const OUString
& rProperty
, const Any
& rValue
)
4376 throw( UnknownPropertyException
);
4377 virtual Any SAL_CALL
getValue( const OUString
& rProperty
)
4378 throw( UnknownPropertyException
);
4379 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& rName
) throw();
4380 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& rProp
) throw();
4382 virtual Any SAL_CALL
invoke( const OUString
& rFunction
,
4383 const Sequence
< Any
>& rParams
,
4384 Sequence
< sal_Int16
>& rOutParamIndex
,
4385 Sequence
< Any
>& rOutParam
)
4386 throw( CannotConvertException
, InvocationTargetException
);
4389 virtual void SAL_CALL
dispose() throw(RuntimeException
);
4390 virtual void SAL_CALL
addEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
);
4391 virtual void SAL_CALL
removeEventListener( const Reference
< XEventListener
>& aListener
) throw (RuntimeException
);
4394 ModuleInvocationProxy::ModuleInvocationProxy( const OUString
& aPrefix
, SbxObjectRef xScopeObj
)
4395 : m_aPrefix( aPrefix
+ OUString( "_" ) )
4396 , m_xScopeObj( xScopeObj
)
4397 , m_aListeners( m_aMutex
)
4399 m_bProxyIsClassModuleObject
= xScopeObj
.Is() ? xScopeObj
->ISA(SbClassModuleObject
) : false;
4402 Reference
< XIntrospectionAccess
> SAL_CALL
ModuleInvocationProxy::getIntrospection() throw()
4404 return Reference
< XIntrospectionAccess
>();
4407 void SAL_CALL
ModuleInvocationProxy::setValue( const OUString
& rProperty
, const Any
& rValue
) throw( UnknownPropertyException
)
4409 if( !m_bProxyIsClassModuleObject
)
4410 throw UnknownPropertyException();
4412 SolarMutexGuard guard
;
4414 OUString
aPropertyFunctionName( "Property Set " );
4415 aPropertyFunctionName
+= m_aPrefix
;
4416 aPropertyFunctionName
+= rProperty
;
4418 SbxVariable
* p
= m_xScopeObj
->Find( aPropertyFunctionName
, SbxCLASS_METHOD
);
4419 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4422 // TODO: Check vba behavior concernig missing function
4423 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4424 throw UnknownPropertyException();
4428 SbxArrayRef xArray
= new SbxArray
;
4429 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
4430 unoToSbxValue( (SbxVariable
*)xVar
, rValue
);
4431 xArray
->Put( xVar
, 1 );
4433 // Call property method
4434 SbxVariableRef xValue
= new SbxVariable
;
4435 pMeth
->SetParameters( xArray
);
4436 pMeth
->Call( xValue
);
4437 pMeth
->SetParameters( NULL
);
4439 // TODO: OutParameter?
4445 Any SAL_CALL
ModuleInvocationProxy::getValue( const OUString
& rProperty
) throw( UnknownPropertyException
)
4447 if( !m_bProxyIsClassModuleObject
)
4449 throw UnknownPropertyException();
4451 SolarMutexGuard guard
;
4453 OUString
aPropertyFunctionName( "Property Get " );
4454 aPropertyFunctionName
+= m_aPrefix
;
4455 aPropertyFunctionName
+= rProperty
;
4457 SbxVariable
* p
= m_xScopeObj
->Find( aPropertyFunctionName
, SbxCLASS_METHOD
);
4458 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4461 // TODO: Check vba behavior concernig missing function
4462 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4463 throw UnknownPropertyException();
4467 SbxVariableRef xValue
= new SbxVariable
;
4468 pMeth
->Call( xValue
);
4469 Any aRet
= sbxToUnoValue( xValue
);
4473 sal_Bool SAL_CALL
ModuleInvocationProxy::hasMethod( const OUString
& ) throw()
4478 sal_Bool SAL_CALL
ModuleInvocationProxy::hasProperty( const OUString
& ) throw()
4483 Any SAL_CALL
ModuleInvocationProxy::invoke( const OUString
& rFunction
,
4484 const Sequence
< Any
>& rParams
,
4485 Sequence
< sal_Int16
>&,
4487 throw( CannotConvertException
, InvocationTargetException
)
4489 SolarMutexGuard guard
;
4492 SbxObjectRef xScopeObj
= m_xScopeObj
;
4493 if( !xScopeObj
.Is() )
4497 OUString aFunctionName
= m_aPrefix
;
4498 aFunctionName
+= rFunction
;
4500 bool bSetRescheduleBack
= false;
4501 sal_Bool bOldReschedule
= sal_True
;
4502 SbiInstance
* pInst
= GetSbData()->pInst
;
4503 if( pInst
&& pInst
->IsCompatibility() )
4505 bOldReschedule
= pInst
->IsReschedule();
4506 if ( bOldReschedule
)
4508 pInst
->EnableReschedule( sal_False
);
4509 bSetRescheduleBack
= true;
4513 SbxVariable
* p
= xScopeObj
->Find( aFunctionName
, SbxCLASS_METHOD
);
4514 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4517 // TODO: Check vba behavior concernig missing function
4518 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4524 sal_Int32 nParamCount
= rParams
.getLength();
4527 xArray
= new SbxArray
;
4528 const Any
*pArgs
= rParams
.getConstArray();
4529 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
4531 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
4532 unoToSbxValue( (SbxVariable
*)xVar
, pArgs
[i
] );
4533 xArray
->Put( xVar
, sal::static_int_cast
< sal_uInt16
>(i
+1) );
4538 SbxVariableRef xValue
= new SbxVariable
;
4540 pMeth
->SetParameters( xArray
);
4541 pMeth
->Call( xValue
);
4542 aRet
= sbxToUnoValue( xValue
);
4543 pMeth
->SetParameters( NULL
);
4545 if( bSetRescheduleBack
)
4546 pInst
->EnableReschedule( bOldReschedule
);
4548 // TODO: OutParameter?
4553 void SAL_CALL
ModuleInvocationProxy::dispose()
4554 throw(RuntimeException
)
4556 ::osl::MutexGuard
aGuard( m_aMutex
);
4558 EventObject
aEvent( (XComponent
*)this );
4559 m_aListeners
.disposeAndClear( aEvent
);
4564 void SAL_CALL
ModuleInvocationProxy::addEventListener( const Reference
< XEventListener
>& xListener
)
4565 throw (RuntimeException
)
4567 m_aListeners
.addInterface( xListener
);
4570 void SAL_CALL
ModuleInvocationProxy::removeEventListener( const Reference
< XEventListener
>& xListener
)
4571 throw (RuntimeException
)
4573 m_aListeners
.removeInterface( xListener
);
4577 Reference
< XInterface
> createComListener( const Any
& aControlAny
, const OUString
& aVBAType
,
4578 const OUString
& aPrefix
, SbxObjectRef xScopeObj
)
4580 Reference
< XInterface
> xRet
;
4582 Reference
< XComponentContext
> xContext(
4583 comphelper::getProcessComponentContext() );
4584 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
4586 Reference
< XInvocation
> xProxy
= new ModuleInvocationProxy( aPrefix
, xScopeObj
);
4588 Sequence
<Any
> args( 3 );
4589 args
[0] <<= aControlAny
;
4590 args
[1] <<= aVBAType
;
4595 xRet
= xServiceMgr
->createInstanceWithArgumentsAndContext(
4596 OUString( "com.sun.star.custom.UnoComListener"),
4599 catch( const Exception
& )
4601 implHandleAnyException( ::cppu::getCaughtException() );
4607 typedef std::vector
< WeakReference
< XComponent
> > ComponentRefVector
;
4609 struct StarBasicDisposeItem
4611 StarBASIC
* m_pBasic
;
4612 SbxArrayRef m_pRegisteredVariables
;
4613 ComponentRefVector m_vComImplementsObjects
;
4615 StarBasicDisposeItem( StarBASIC
* pBasic
)
4616 : m_pBasic( pBasic
)
4618 m_pRegisteredVariables
= new SbxArray();
4622 typedef std::vector
< StarBasicDisposeItem
* > DisposeItemVector
;
4624 static DisposeItemVector GaDisposeItemVector
;
4626 static DisposeItemVector::iterator
lcl_findItemForBasic( StarBASIC
* pBasic
)
4628 DisposeItemVector::iterator it
;
4629 for( it
= GaDisposeItemVector
.begin() ; it
!= GaDisposeItemVector
.end() ; ++it
)
4631 StarBasicDisposeItem
* pItem
= *it
;
4632 if( pItem
->m_pBasic
== pBasic
)
4635 return GaDisposeItemVector
.end();
4638 static StarBasicDisposeItem
* lcl_getOrCreateItemForBasic( StarBASIC
* pBasic
)
4640 DisposeItemVector::iterator it
= lcl_findItemForBasic( pBasic
);
4641 StarBasicDisposeItem
* pItem
= (it
!= GaDisposeItemVector
.end()) ? *it
: NULL
;
4644 pItem
= new StarBasicDisposeItem( pBasic
);
4645 GaDisposeItemVector
.push_back( pItem
);
4650 void registerComponentToBeDisposedForBasic
4651 ( Reference
< XComponent
> xComponent
, StarBASIC
* pBasic
)
4653 StarBasicDisposeItem
* pItem
= lcl_getOrCreateItemForBasic( pBasic
);
4654 pItem
->m_vComImplementsObjects
.push_back( xComponent
);
4657 void registerComListenerVariableForBasic( SbxVariable
* pVar
, StarBASIC
* pBasic
)
4659 StarBasicDisposeItem
* pItem
= lcl_getOrCreateItemForBasic( pBasic
);
4660 SbxArray
* pArray
= pItem
->m_pRegisteredVariables
;
4661 pArray
->Put( pVar
, pArray
->Count() );
4664 void disposeComVariablesForBasic( StarBASIC
* pBasic
)
4666 DisposeItemVector::iterator it
= lcl_findItemForBasic( pBasic
);
4667 if( it
!= GaDisposeItemVector
.end() )
4669 StarBasicDisposeItem
* pItem
= *it
;
4671 SbxArray
* pArray
= pItem
->m_pRegisteredVariables
;
4672 sal_uInt16 nCount
= pArray
->Count();
4673 for( sal_uInt16 i
= 0 ; i
< nCount
; ++i
)
4675 SbxVariable
* pVar
= pArray
->Get( i
);
4676 pVar
->ClearComListener();
4679 ComponentRefVector
& rv
= pItem
->m_vComImplementsObjects
;
4680 ComponentRefVector::iterator itCRV
;
4681 for( itCRV
= rv
.begin() ; itCRV
!= rv
.end() ; ++itCRV
)
4685 Reference
< XComponent
> xComponent( (*itCRV
).get(), UNO_QUERY_THROW
);
4686 xComponent
->dispose();
4688 catch(const Exception
& )
4693 GaDisposeItemVector
.erase( it
);
4698 // Handle module implements mechanism for OLE types
4699 bool SbModule::createCOMWrapperForIface( Any
& o_rRetAny
, SbClassModuleObject
* pProxyClassModuleObject
)
4701 // For now: Take first interface that allows to instantiate COM wrapper
4702 // TODO: Check if support for multiple interfaces is needed
4704 Reference
< XComponentContext
> xContext(
4705 comphelper::getProcessComponentContext() );
4706 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
4707 Reference
< XSingleServiceFactory
> xComImplementsFactory
4709 xServiceMgr
->createInstanceWithContext(
4710 OUString( "com.sun.star.custom.ComImplementsFactory"), xContext
),
4713 if( !xComImplementsFactory
.is() )
4716 bool bSuccess
= false;
4718 SbxArray
* pModIfaces
= pClassData
->mxIfaces
;
4719 sal_uInt16 nCount
= pModIfaces
->Count();
4720 for( sal_uInt16 i
= 0 ; i
< nCount
; ++i
)
4722 SbxVariable
* pVar
= pModIfaces
->Get( i
);
4723 OUString aIfaceName
= pVar
->GetName();
4725 if( !aIfaceName
.isEmpty() )
4727 OUString aPureIfaceName
= aIfaceName
;
4728 sal_Int32 indexLastDot
= aIfaceName
.lastIndexOf('.');
4729 if ( indexLastDot
> -1 )
4731 aPureIfaceName
= aIfaceName
.copy( indexLastDot
+ 1 );
4733 Reference
< XInvocation
> xProxy
= new ModuleInvocationProxy( aPureIfaceName
, pProxyClassModuleObject
);
4735 Sequence
<Any
> args( 2 );
4736 args
[0] <<= aIfaceName
;
4739 Reference
< XInterface
> xRet
;
4743 xRet
= xComImplementsFactory
->createInstanceWithArguments( args
);
4746 catch( const Exception
& )
4748 implHandleAnyException( ::cppu::getCaughtException() );
4753 Reference
< XComponent
> xComponent( xProxy
, UNO_QUERY
);
4754 if( xComponent
.is() )
4756 StarBASIC
* pParentBasic
= NULL
;
4757 SbxObject
* pCurObject
= this;
4760 SbxObject
* pObjParent
= pCurObject
->GetParent();
4761 pParentBasic
= PTR_CAST( StarBASIC
, pObjParent
);
4762 pCurObject
= pObjParent
;
4764 while( pParentBasic
== NULL
&& pCurObject
!= NULL
);
4766 OSL_ASSERT( pParentBasic
!= NULL
);
4767 registerComponentToBeDisposedForBasic( xComponent
, pParentBasic
);
4780 // Due to an incorrect behavior IE returns an object instead of a string
4781 // in some scenarios. Calling toString at the object may correct this.
4782 // Helper function used in sbxvalue.cxx
4783 bool handleToStringForCOMObjects( SbxObject
* pObj
, SbxValue
* pVal
)
4785 bool bSuccess
= false;
4787 SbUnoObject
* pUnoObj
= NULL
;
4788 if( pObj
!= NULL
&& (pUnoObj
= PTR_CAST(SbUnoObject
,(SbxObject
*)pObj
)) != NULL
)
4790 // Only for native COM objects
4791 if( pUnoObj
->isNativeCOMObject() )
4793 SbxVariableRef pMeth
= pObj
->Find( OUString( "toString" ), SbxCLASS_METHOD
);
4806 Any
StructRefInfo::getValue()
4810 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
4812 &aRet
, getInst(), mpTD
,
4813 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
4817 void StructRefInfo::setValue( const Any
& rValue
)
4819 uno_type_assignData( getInst(),
4821 (void*)rValue
.getValue(),
4822 rValue
.getValueTypeRef(),
4823 reinterpret_cast< uno_QueryInterfaceFunc
>(cpp_queryInterface
),
4824 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
4825 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
4828 OUString
StructRefInfo::getTypeName() const
4833 sTypeName
= mpTD
->pTypeName
;
4838 void* StructRefInfo::getInst()
4840 return ((char*)maAny
.getValue() + mnPos
);
4843 TypeClass
StructRefInfo::getTypeClass() const
4845 TypeClass t
= TypeClass_VOID
;
4847 t
= (TypeClass
)mpTD
->eTypeClass
;
4851 SbUnoStructRefObject::SbUnoStructRefObject( const OUString
& aName_
, const StructRefInfo
& rMemberInfo
) : SbxObject( aName_
), maMemberInfo( rMemberInfo
), mbMemberCacheInit( false )
4853 SetClassName( OUString( maMemberInfo
.getTypeName() ) );
4856 SbUnoStructRefObject::~SbUnoStructRefObject()
4858 for ( StructFieldInfo::iterator it
= maFields
.begin(), it_end
= maFields
.end(); it
!= it_end
; ++it
)
4862 void SbUnoStructRefObject::initMemberCache()
4864 if ( mbMemberCacheInit
)
4867 typelib_TypeDescription
* pTD
= maMemberInfo
.getTD();
4868 typelib_CompoundTypeDescription
* pCompTypeDescr
= (typelib_CompoundTypeDescription
*)pTD
;
4869 for ( ; pCompTypeDescr
; pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
4870 nAll
+= pCompTypeDescr
->nMembers
;
4871 for ( pCompTypeDescr
= (typelib_CompoundTypeDescription
*)pTD
; pCompTypeDescr
;
4872 pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
4874 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompTypeDescr
->ppTypeRefs
;
4875 rtl_uString
** ppNames
= pCompTypeDescr
->ppMemberNames
;
4876 sal_Int32
* pMemberOffsets
= pCompTypeDescr
->pMemberOffsets
;
4877 for ( sal_Int32 nPos
= pCompTypeDescr
->nMembers
; nPos
--; )
4879 typelib_TypeDescription
* pMemberTD
= 0;
4880 TYPELIB_DANGER_GET( &pMemberTD
, ppTypeRefs
[nPos
] );
4881 OSL_ENSURE( pMemberTD
, "### cannot get field in struct!" );
4884 OUString
aName( ppNames
[nPos
] );
4885 TYPELIB_DANGER_RELEASE( pMemberTD
);
4886 maFields
[ aName
] = new StructRefInfo( maMemberInfo
.getRootAnyRef(), pMemberTD
, maMemberInfo
.getPos() + pMemberOffsets
[nPos
] );
4890 mbMemberCacheInit
= true;
4893 SbxVariable
* SbUnoStructRefObject::Find( const OUString
& rName
, SbxClassType t
)
4895 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
4898 if ( !mbMemberCacheInit
)
4900 StructFieldInfo::iterator it
= maFields
.find( OUString( rName
).toAsciiUpperCase() );
4901 if ( it
!= maFields
.end() )
4903 SbxDataType eSbxType
;
4904 eSbxType
= unoToSbxType( it
->second
->getTypeClass() );
4905 SbxDataType eRealSbxType
= eSbxType
;
4908 aProp
.Type
= com::sun::star::uno::Type( it
->second
->getTypeClass(), it
->second
->getTypeName() );
4909 SbUnoProperty
* pProp
= new SbUnoProperty( rName
, eSbxType
, eRealSbxType
, aProp
, 0, false, ( aProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
4910 SbxVariableRef xVarRef
= pProp
;
4911 QuickInsert( (SbxVariable
*)xVarRef
);
4918 if( rName
.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES
) ||
4919 rName
.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES
) ||
4920 rName
.equalsIgnoreAsciiCase(ID_DBG_METHODS
) )
4923 implCreateDbgProperties();
4925 // Now they have to be found regular
4926 pRes
= SbxObject::Find( rName
, SbxCLASS_DONTCARE
);
4933 // help method to create the dbg_-Properties
4934 void SbUnoStructRefObject::implCreateDbgProperties( void )
4938 // Id == -1: display the implemented interfaces corresponding the ClassProvider
4939 SbxVariableRef xVarRef
= new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES
), SbxSTRING
, SbxSTRING
, aProp
, -1, false, false );
4940 QuickInsert( (SbxVariable
*)xVarRef
);
4942 // Id == -2: output the properties
4943 xVarRef
= new SbUnoProperty( OUString(ID_DBG_PROPERTIES
), SbxSTRING
, SbxSTRING
, aProp
, -2, false, false );
4944 QuickInsert( (SbxVariable
*)xVarRef
);
4946 // Id == -3: output the Methods
4947 xVarRef
= new SbUnoProperty( OUString(ID_DBG_METHODS
), SbxSTRING
, SbxSTRING
, aProp
, -3, false, false );
4948 QuickInsert( (SbxVariable
*)xVarRef
);
4951 void SbUnoStructRefObject::implCreateAll()
4953 // throw away all existing methods and properties
4954 pMethods
= new SbxArray
;
4955 pProps
= new SbxArray
;
4957 if (!mbMemberCacheInit
)
4960 for ( StructFieldInfo::iterator it
= maFields
.begin(), it_end
= maFields
.end(); it
!= it_end
; ++it
)
4962 const OUString
& rName
= it
->first
;
4963 SbxDataType eSbxType
;
4964 eSbxType
= unoToSbxType( it
->second
->getTypeClass() );
4965 SbxDataType eRealSbxType
= eSbxType
;
4968 aProp
.Type
= com::sun::star::uno::Type( it
->second
->getTypeClass(), it
->second
->getTypeName() );
4969 SbUnoProperty
* pProp
= new SbUnoProperty( rName
, eSbxType
, eRealSbxType
, aProp
, 0, false, ( aProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
4970 SbxVariableRef xVarRef
= pProp
;
4971 QuickInsert( (SbxVariable
*)xVarRef
);
4974 // Create Dbg_-Properties
4975 implCreateDbgProperties();
4979 Any
SbUnoStructRefObject::getUnoAny( void )
4981 return maMemberInfo
.getValue();
4984 OUString
SbUnoStructRefObject::Impl_DumpProperties()
4986 OUStringBuffer aRet
;
4987 aRet
.appendAscii("Properties of object ");
4988 aRet
.append( getDbgObjectName() );
4990 sal_uInt16 nPropCount
= pProps
->Count();
4991 sal_uInt16 nPropsPerLine
= 1 + nPropCount
/ 30;
4992 for( sal_uInt16 i
= 0; i
< nPropCount
; i
++ )
4994 SbxVariable
* pVar
= pProps
->Get( i
);
4997 OUStringBuffer aPropStr
;
4998 if( (i
% nPropsPerLine
) == 0 )
5000 aPropStr
.appendAscii( "\n" );
5002 // output the type and name
5003 // Is it in Uno a sequence?
5004 SbxDataType eType
= pVar
->GetFullType();
5006 bool bMaybeVoid
= false;
5007 OUString
aName( pVar
->GetName() );
5008 StructFieldInfo::iterator it
= maFields
.find( aName
);
5010 if ( it
!= maFields
.end() )
5012 const StructRefInfo
& rPropInfo
= *it
->second
;
5014 if( eType
== SbxOBJECT
)
5016 if( rPropInfo
.getTypeClass() == TypeClass_SEQUENCE
)
5018 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
5022 aPropStr
.append( Dbg_SbxDataType2String( eType
) );
5025 aPropStr
.appendAscii( "/void" );
5027 aPropStr
.appendAscii( " " );
5028 aPropStr
.append( pVar
->GetName() );
5030 if( i
== nPropCount
- 1 )
5032 aPropStr
.appendAscii( "\n" );
5036 aPropStr
.appendAscii( "; " );
5038 aRet
.append( aPropStr
.makeStringAndClear() );
5041 return aRet
.makeStringAndClear();
5044 void SbUnoStructRefObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
5045 const SfxHint
& rHint
, const TypeId
& rHintType
)
5047 if ( !mbMemberCacheInit
)
5049 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
5052 SbxVariable
* pVar
= pHint
->GetVar();
5053 SbUnoProperty
* pProp
= PTR_CAST(SbUnoProperty
,pVar
);
5056 StructFieldInfo::iterator it
= maFields
.find( pProp
->GetName() );
5057 // handle get/set of members of struct
5058 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
5061 sal_Int32 nId
= pProp
->nId
;
5064 // Id == -1: Display implemented interfaces according the ClassProvider
5065 if( nId
== -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
5067 OUStringBuffer aRet
;
5068 aRet
.appendAscii( ID_DBG_SUPPORTEDINTERFACES
);
5069 aRet
.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
5071 pVar
->PutString( aRet
.makeStringAndClear() );
5073 // Id == -2: output properties
5074 else if( nId
== -2 ) // Property ID_DBG_PROPERTIES
5076 // by now all properties must be established
5078 OUString aRetStr
= Impl_DumpProperties();
5079 pVar
->PutString( aRetStr
);
5081 // Id == -3: output the methods
5082 else if( nId
== -3 ) // Property ID_DBG_METHODS
5084 // by now all properties must be established
5086 OUStringBuffer aRet
;
5087 aRet
.appendAscii("Methods of object ");
5088 aRet
.append( getDbgObjectName() );
5089 aRet
.appendAscii( "\nNo methods found\n" );
5090 pVar
->PutString( aRet
.makeStringAndClear() );
5095 if ( it
!= maFields
.end() )
5097 Any aRetAny
= it
->second
->getValue();
5098 unoToSbxValue( pVar
, aRetAny
);
5101 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
5103 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
5105 if ( it
!= maFields
.end() )
5107 // take over the value from Uno to Sbx
5108 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
5109 it
->second
->setValue( aAnyValue
);
5112 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
5116 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
5120 StructRefInfo
SbUnoStructRefObject::getStructMember( const OUString
& rMemberName
)
5122 if (!mbMemberCacheInit
)
5126 StructFieldInfo::iterator it
= maFields
.find( rMemberName
);
5128 typelib_TypeDescription
* pFoundTD
= NULL
;
5129 sal_Int32 nFoundPos
= -1;
5131 if ( it
!= maFields
.end() )
5133 pFoundTD
= it
->second
->getTD();
5134 nFoundPos
= it
->second
->getPos();
5136 StructRefInfo
aRet( maMemberInfo
.getRootAnyRef(), pFoundTD
, nFoundPos
);
5140 OUString
SbUnoStructRefObject::getDbgObjectName()
5142 OUString aName
= GetClassName();
5143 if( aName
.isEmpty() )
5147 OUStringBuffer aRet
;
5148 if( aName
.getLength() > 20 )
5150 aRet
.appendAscii( "\n" );
5152 aRet
.appendAscii( "\"" );
5153 aRet
.append( aName
);
5154 aRet
.appendAscii( "\":" );
5155 return aRet
.makeStringAndClear();
5158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */