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>
71 using com::sun::star::uno::Reference
;
72 using namespace com::sun::star::uno
;
73 using namespace com::sun::star::lang
;
74 using namespace com::sun::star::reflection
;
75 using namespace com::sun::star::beans
;
76 using namespace com::sun::star::script
;
77 using namespace com::sun::star::container
;
78 using namespace com::sun::star::bridge
;
82 #include<basic/sbstar.hxx>
83 #include<basic/sbuno.hxx>
84 #include<basic/sberrors.hxx>
85 #include<sbunoobj.hxx>
87 #include<basic/basmgr.hxx>
88 #include<sbintern.hxx>
92 #include <boost/unordered_map.hpp>
93 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
94 #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
96 TYPEINIT1(SbUnoMethod
,SbxMethod
)
97 TYPEINIT1(SbUnoProperty
,SbxProperty
)
98 TYPEINIT1(SbUnoObject
,SbxObject
)
99 TYPEINIT1(SbUnoStructRefObject
,SbxObject
)
100 TYPEINIT1(SbUnoClass
,SbxObject
)
101 TYPEINIT1(SbUnoService
,SbxObject
)
102 TYPEINIT1(SbUnoServiceCtor
,SbxMethod
)
103 TYPEINIT1(SbUnoSingleton
,SbxObject
)
105 typedef WeakImplHelper1
< XAllListener
> BasicAllListenerHelper
;
107 // Identifiers for creating the strings for dbg_Properties
108 static char const ID_DBG_SUPPORTEDINTERFACES
[] = "Dbg_SupportedInterfaces";
109 static char const ID_DBG_PROPERTIES
[] = "Dbg_Properties";
110 static char const ID_DBG_METHODS
[] = "Dbg_Methods";
112 static char const aSeqLevelStr
[] = "[]";
113 static char const defaultNameSpace
[] = "ooo.vba";
115 // Gets the default property for an uno object. Note: There is some
116 // redirection built in. The property name specifies the name
117 // of the default property.
119 bool SbUnoObject::getDefaultPropName( SbUnoObject
* pUnoObj
, OUString
& sDfltProp
)
122 Reference
< XDefaultProperty
> xDefaultProp( pUnoObj
->maTmpUnoObj
, UNO_QUERY
);
123 if ( xDefaultProp
.is() )
125 sDfltProp
= xDefaultProp
->getDefaultPropertyName();
126 if ( !sDfltProp
.isEmpty() )
132 SbxVariable
* getDefaultProp( SbxVariable
* pRef
)
134 SbxVariable
* pDefaultProp
= NULL
;
135 if ( pRef
->GetType() == SbxOBJECT
)
137 SbxObject
* pObj
= PTR_CAST(SbxObject
,(SbxVariable
*) pRef
);
140 SbxBase
* pObjVarObj
= pRef
->GetObject();
141 pObj
= PTR_CAST(SbxObject
,pObjVarObj
);
143 if ( pObj
&& pObj
->ISA(SbUnoObject
) )
145 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,(SbxObject
*)pObj
);
146 pDefaultProp
= pUnoObj
->GetDfltProperty();
152 void SetSbUnoObjectDfltPropName( SbxObject
* pObj
)
154 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,(SbxObject
*) pObj
);
157 OUString sDfltPropName
;
159 if ( SbUnoObject::getDefaultPropName( pUnoObj
, sDfltPropName
) )
161 OSL_TRACE("SetSbUnoObjectDfltPropName setting dflt prop for %s", OUStringToOString( pObj
->GetName(), RTL_TEXTENCODING_UTF8
).getStr() );
162 pUnoObj
->SetDfltProperty( sDfltPropName
);
167 // save CoreReflection statically
168 Reference
< XIdlReflection
> getCoreReflection_Impl( void )
170 static Reference
< XIdlReflection
> xCoreReflection
;
172 // Do we have already CoreReflection; if not obtain it
173 if( !xCoreReflection
.is() )
175 Reference
< XComponentContext
> xContext(
176 comphelper::getProcessComponentContext() );
179 xContext
->getValueByName(
180 OUString( "/singletons/com.sun.star.reflection.theCoreReflection" ) )
182 OSL_ENSURE( xCoreReflection
.is(), "### CoreReflection singleton not accessible!?" );
184 if( !xCoreReflection
.is() )
186 throw DeploymentException(
187 OUString( "/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible" ),
188 Reference
< XInterface
>() );
191 return xCoreReflection
;
194 // save CoreReflection statically
195 Reference
< XHierarchicalNameAccess
> getCoreReflection_HierarchicalNameAccess_Impl( void )
197 static Reference
< XHierarchicalNameAccess
> xCoreReflection_HierarchicalNameAccess
;
199 if( !xCoreReflection_HierarchicalNameAccess
.is() )
201 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
202 if( xCoreReflection
.is() )
204 xCoreReflection_HierarchicalNameAccess
=
205 Reference
< XHierarchicalNameAccess
>( xCoreReflection
, UNO_QUERY
);
208 return xCoreReflection_HierarchicalNameAccess
;
211 // Hold TypeProvider statically
212 Reference
< XHierarchicalNameAccess
> getTypeProvider_Impl( void )
214 static Reference
< XHierarchicalNameAccess
> xAccess
;
216 // Do we have already CoreReflection; if not obtain it
219 Reference
< XComponentContext
> xContext(
220 comphelper::getProcessComponentContext() );
223 xContext
->getValueByName(
224 OUString( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) )
226 OSL_ENSURE( xAccess
.is(), "### TypeDescriptionManager singleton not accessible!?" );
230 throw DeploymentException(
231 OUString("/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessible"),
232 Reference
< XInterface
>() );
238 // Hold TypeConverter statically
239 Reference
< XTypeConverter
> getTypeConverter_Impl( void )
241 static Reference
< XTypeConverter
> xTypeConverter
;
243 // Do we have already CoreReflection; if not obtain it
244 if( !xTypeConverter
.is() )
246 Reference
< XComponentContext
> xContext(
247 comphelper::getProcessComponentContext() );
250 xTypeConverter
= Converter::create(xContext
);
252 if( !xTypeConverter
.is() )
254 throw DeploymentException(
255 OUString("com.sun.star.script.Converter service not accessible"),
256 Reference
< XInterface
>() );
259 return xTypeConverter
;
263 // #111851 factory function to create an OLE object
264 SbUnoObject
* createOLEObject_Impl( const OUString
& aType
)
266 static Reference
< XMultiServiceFactory
> xOLEFactory
;
267 static bool bNeedsInit
= true;
273 Reference
< XComponentContext
> xContext(
274 comphelper::getProcessComponentContext() );
277 Reference
<XMultiComponentFactory
> xSMgr
= xContext
->getServiceManager();
278 xOLEFactory
= Reference
<XMultiServiceFactory
>(
279 xSMgr
->createInstanceWithContext(
280 OUString( "com.sun.star.bridge.OleObjectFactory"),
281 xContext
), UNO_QUERY
);
285 SbUnoObject
* pUnoObj
= NULL
;
286 if( xOLEFactory
.is() )
288 // some type names available in VBA can not be directly used in COM
289 OUString aOLEType
= aType
;
290 if ( aOLEType
== "SAXXMLReader30" )
292 aOLEType
= "Msxml2.SAXXMLReader.3.0";
294 Reference
< XInterface
> xOLEObject
= xOLEFactory
->createInstance( aOLEType
);
295 if( xOLEObject
.is() )
299 pUnoObj
= new SbUnoObject( aType
, aAny
);
300 OUString sDfltPropName
;
302 if ( SbUnoObject::getDefaultPropName( pUnoObj
, sDfltPropName
) )
303 pUnoObj
->SetDfltProperty( sDfltPropName
);
312 void lcl_indent( OUStringBuffer
& _inout_rBuffer
, sal_Int32 _nLevel
)
314 while ( _nLevel
-- > 0 )
316 _inout_rBuffer
.appendAscii( " " );
321 void implAppendExceptionMsg( OUStringBuffer
& _inout_rBuffer
, const Exception
& _e
, const OUString
& _rExceptionType
, sal_Int32 _nLevel
)
323 _inout_rBuffer
.appendAscii( "\n" );
324 lcl_indent( _inout_rBuffer
, _nLevel
);
325 _inout_rBuffer
.appendAscii( "Type: " );
327 if ( _rExceptionType
.isEmpty() )
328 _inout_rBuffer
.appendAscii( "Unknown" );
330 _inout_rBuffer
.append( _rExceptionType
);
332 _inout_rBuffer
.appendAscii( "\n" );
333 lcl_indent( _inout_rBuffer
, _nLevel
);
334 _inout_rBuffer
.appendAscii( "Message: " );
335 _inout_rBuffer
.append( _e
.Message
);
339 // construct an error message for the exception
340 OUString
implGetExceptionMsg( const Exception
& e
, const OUString
& aExceptionType_
)
342 OUStringBuffer aMessageBuf
;
343 implAppendExceptionMsg( aMessageBuf
, e
, aExceptionType_
, 0 );
344 return aMessageBuf
.makeStringAndClear();
347 OUString
implGetExceptionMsg( const Any
& _rCaughtException
)
349 OSL_PRECOND( _rCaughtException
.getValueTypeClass() == TypeClass_EXCEPTION
, "implGetExceptionMsg: illegal argument!" );
350 if ( _rCaughtException
.getValueTypeClass() != TypeClass_EXCEPTION
)
354 return implGetExceptionMsg( *static_cast< const Exception
* >( _rCaughtException
.getValue() ), _rCaughtException
.getValueTypeName() );
357 Any
convertAny( const Any
& rVal
, const Type
& aDestType
)
360 Reference
< XTypeConverter
> xConverter
= getTypeConverter_Impl();
363 aConvertedVal
= xConverter
->convertTo( rVal
, aDestType
);
365 catch( const IllegalArgumentException
& )
367 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
368 implGetExceptionMsg( ::cppu::getCaughtException() ) );
369 return aConvertedVal
;
371 catch( const CannotConvertException
& e2
)
373 OUString
aCannotConvertExceptionName( "com.sun.star.lang.IllegalArgumentException");
374 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
375 implGetExceptionMsg( e2
, aCannotConvertExceptionName
) );
376 return aConvertedVal
;
378 return aConvertedVal
;
382 // #105565 Special Object to wrap a strongly typed Uno Any
383 TYPEINIT1(SbUnoAnyObject
,SbxObject
)
386 // TODO: source out later
387 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
)
389 // register void as default class
390 Reference
<XIdlClass
> xRetClass
;
391 typelib_TypeDescription
* pTD
= 0;
392 rType
.getDescription( &pTD
);
396 OUString
sOWName( pTD
->pTypeName
);
397 Reference
< XIdlReflection
> xRefl
= getCoreReflection_Impl();
398 xRetClass
= xRefl
->forName( sOWName
);
403 // Exception type unknown
404 template< class EXCEPTION
>
405 OUString
implGetExceptionMsg( const EXCEPTION
& e
)
407 return implGetExceptionMsg( e
, ::getCppuType( &e
).getTypeName() );
410 void implHandleBasicErrorException( BasicErrorException
& e
)
412 SbError nError
= StarBASIC::GetSfxFromVBError( (sal_uInt16
)e
.ErrorCode
);
413 StarBASIC::Error( nError
, e
.ErrorMessageArgument
);
416 void implHandleWrappedTargetException( const Any
& _rWrappedTargetException
)
418 Any
aExamine( _rWrappedTargetException
);
420 // completely strip the first InvocationTargetException, its error message isn't of any
421 // interest to the user, it just says something like "invoking the UNO method went wrong.".
422 InvocationTargetException aInvocationError
;
423 if ( aExamine
>>= aInvocationError
)
424 aExamine
= aInvocationError
.TargetException
;
426 BasicErrorException aBasicError
;
428 SbError
nError( ERRCODE_BASIC_EXCEPTION
);
429 OUStringBuffer aMessageBuf
;
431 // strip any other WrappedTargetException instances, but this time preserve the error messages.
432 WrappedTargetException aWrapped
;
433 sal_Int32 nLevel
= 0;
434 while ( aExamine
>>= aWrapped
)
436 // special handling for BasicErrorException errors
437 if ( aWrapped
.TargetException
>>= aBasicError
)
439 nError
= StarBASIC::GetSfxFromVBError( (sal_uInt16
)aBasicError
.ErrorCode
);
440 aMessageBuf
.append( aBasicError
.ErrorMessageArgument
);
445 // append this round's message
446 implAppendExceptionMsg( aMessageBuf
, aWrapped
, aExamine
.getValueTypeName(), nLevel
);
447 if ( aWrapped
.TargetException
.getValueTypeClass() == TypeClass_EXCEPTION
)
448 // there is a next chain element
449 aMessageBuf
.appendAscii( "\nTargetException:" );
452 aExamine
= aWrapped
.TargetException
;
456 if ( aExamine
.getValueTypeClass() == TypeClass_EXCEPTION
)
458 // the last element in the chain is still an exception, but no WrappedTargetException
459 implAppendExceptionMsg( aMessageBuf
, *static_cast< const Exception
* >( aExamine
.getValue() ), aExamine
.getValueTypeName(), nLevel
);
462 StarBASIC::Error( nError
, aMessageBuf
.makeStringAndClear() );
465 static void implHandleAnyException( const Any
& _rCaughtException
)
467 BasicErrorException aBasicError
;
468 WrappedTargetException aWrappedError
;
470 if ( _rCaughtException
>>= aBasicError
)
472 implHandleBasicErrorException( aBasicError
);
474 else if ( _rCaughtException
>>= aWrappedError
)
476 implHandleWrappedTargetException( _rCaughtException
);
480 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( _rCaughtException
) );
484 // NativeObjectWrapper handling
487 SbxObjectRef m_xNativeObj
;
491 ObjectItem( SbxObject
* pNativeObj
)
492 : m_xNativeObj( pNativeObj
)
496 typedef std::vector
< ObjectItem
> NativeObjectWrapperVector
;
497 class GaNativeObjectWrapperVector
: public rtl::Static
<NativeObjectWrapperVector
, GaNativeObjectWrapperVector
> {};
499 void clearNativeObjectWrapperVector( void )
501 GaNativeObjectWrapperVector::get().clear();
504 static sal_uInt32
lcl_registerNativeObjectWrapper( SbxObject
* pNativeObj
)
506 NativeObjectWrapperVector
&rNativeObjectWrapperVector
= GaNativeObjectWrapperVector::get();
507 sal_uInt32 nIndex
= rNativeObjectWrapperVector
.size();
508 rNativeObjectWrapperVector
.push_back( ObjectItem( pNativeObj
) );
512 static SbxObject
* lcl_getNativeObject( sal_uInt32 nIndex
)
514 SbxObjectRef xRetObj
;
515 NativeObjectWrapperVector
&rNativeObjectWrapperVector
= GaNativeObjectWrapperVector::get();
516 if( nIndex
< rNativeObjectWrapperVector
.size() )
518 ObjectItem
& rItem
= rNativeObjectWrapperVector
[ nIndex
];
519 xRetObj
= rItem
.m_xNativeObj
;
524 // convert from Uno to Sbx
525 SbxDataType
unoToSbxType( TypeClass eType
)
527 SbxDataType eRetType
= SbxVOID
;
531 case TypeClass_INTERFACE
:
533 case TypeClass_STRUCT
:
534 case TypeClass_EXCEPTION
: eRetType
= SbxOBJECT
; break;
536 case TypeClass_ENUM
: eRetType
= SbxLONG
; break;
537 case TypeClass_SEQUENCE
:
538 eRetType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
542 case TypeClass_ANY
: eRetType
= SbxVARIANT
; break;
543 case TypeClass_BOOLEAN
: eRetType
= SbxBOOL
; break;
544 case TypeClass_CHAR
: eRetType
= SbxCHAR
; break;
545 case TypeClass_STRING
: eRetType
= SbxSTRING
; break;
546 case TypeClass_FLOAT
: eRetType
= SbxSINGLE
; break;
547 case TypeClass_DOUBLE
: eRetType
= SbxDOUBLE
; break;
548 case TypeClass_BYTE
: eRetType
= SbxINTEGER
; break;
549 case TypeClass_SHORT
: eRetType
= SbxINTEGER
; break;
550 case TypeClass_LONG
: eRetType
= SbxLONG
; break;
551 case TypeClass_HYPER
: eRetType
= SbxSALINT64
; break;
552 case TypeClass_UNSIGNED_SHORT
: eRetType
= SbxUSHORT
; break;
553 case TypeClass_UNSIGNED_LONG
: eRetType
= SbxULONG
; break;
554 case TypeClass_UNSIGNED_HYPER
: eRetType
= SbxSALUINT64
;break;
560 SbxDataType
unoToSbxType( const Reference
< XIdlClass
>& xIdlClass
)
562 SbxDataType eRetType
= SbxVOID
;
565 TypeClass eType
= xIdlClass
->getTypeClass();
566 eRetType
= unoToSbxType( eType
);
571 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
)
573 Type aType
= aValue
.getValueType();
574 TypeClass eTypeClass
= aType
.getTypeClass();
576 sal_Int32 dimCopy
= dimension
;
578 if ( eTypeClass
== TypeClass_SEQUENCE
)
580 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aType
);
581 Reference
< XIdlArray
> xIdlArray
= xIdlTargetClass
->getArray();
582 typelib_TypeDescription
* pTD
= 0;
583 aType
.getDescription( &pTD
);
584 Type
aElementType( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
585 ::typelib_typedescription_release( pTD
);
587 sal_Int32 nLen
= xIdlArray
->getLen( aValue
);
588 for ( sal_Int32 index
= 0; index
< nLen
; ++index
)
590 Any aElementAny
= xIdlArray
->get( aValue
, (sal_uInt32
)index
);
591 // This detects the dimension were currently processing
592 if ( dimCopy
== dimension
)
595 if ( sizes
.getLength() < dimCopy
)
597 sizes
.realloc( sizes
.getLength() + 1 );
598 sizes
[ sizes
.getLength() - 1 ] = nLen
;
599 indices
.realloc( indices
.getLength() + 1 );
604 indices
[ dimCopy
- 1 ] = index
;
606 indices
[ dimCopy
- 1] = index
+ 1;
608 implSequenceToMultiDimArray( pArray
, indices
, sizes
, aElementAny
, dimCopy
, bIsZeroIndex
, &aElementType
);
614 if ( indices
.getLength() < 1 )
616 // Should never ever get here ( indices.getLength()
617 // should equal number of dimensions in the array )
618 // And that should at least be 1 !
619 // #QUESTION is there a better error?
620 StarBASIC::Error( SbERR_INVALID_OBJECT
);
624 SbxDataType eSbxElementType
= unoToSbxType( pType
? pType
->getTypeClass() : aValue
.getValueTypeClass() );
627 pArray
= new SbxDimArray( eSbxElementType
);
628 sal_Int32 nIndexLen
= indices
.getLength();
630 // Dimension the array
631 for ( sal_Int32 index
= 0; index
< nIndexLen
; ++index
)
634 pArray
->unoAddDim32( 0, sizes
[ index
] - 1);
636 pArray
->unoAddDim32( 1, sizes
[ index
] );
643 SbxVariableRef xVar
= new SbxVariable( eSbxElementType
);
644 unoToSbxValue( (SbxVariable
*)xVar
, aValue
);
646 sal_Int32
* pIndices
= indices
.getArray();
647 pArray
->Put32( (SbxVariable
*)xVar
, pIndices
);
653 void unoToSbxValue( SbxVariable
* pVar
, const Any
& aValue
)
655 Type aType
= aValue
.getValueType();
656 TypeClass eTypeClass
= aType
.getTypeClass();
661 // Map Type to IdlClass
664 Reference
<XIdlClass
> xClass
= TypeToIdlClass( aType_
);
666 aClassAny
<<= xClass
;
668 // instantiate SbUnoObject
670 SbUnoObject
* pSbUnoObject
= new SbUnoObject( aName
, aClassAny
);
671 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
673 // If the object is invalid deliver zero
674 if( pSbUnoObject
->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID
)
676 pVar
->PutObject( NULL
);
680 pVar
->PutObject( xWrapper
);
684 // Interfaces and Structs must be wrapped in a SbUnoObject
685 case TypeClass_INTERFACE
:
686 case TypeClass_STRUCT
:
687 case TypeClass_EXCEPTION
:
689 if( eTypeClass
== TypeClass_STRUCT
)
692 NativeObjectWrapper aNativeObjectWrapper
;
693 if ( (aValue
>>= aWrap
) )
695 SbxDimArray
* pArray
= NULL
;
696 Sequence
< sal_Int32
> indices
;
697 Sequence
< sal_Int32
> sizes
;
698 sal_Int32 dimension
= 0;
699 implSequenceToMultiDimArray( pArray
, indices
, sizes
, aWrap
.Array
, dimension
, aWrap
.IsZeroIndex
);
702 SbxDimArrayRef xArray
= pArray
;
703 sal_uInt16 nFlags
= pVar
->GetFlags();
704 pVar
->ResetFlag( SBX_FIXED
);
705 pVar
->PutObject( (SbxDimArray
*)xArray
);
706 pVar
->SetFlags( nFlags
);
712 else if ( (aValue
>>= aNativeObjectWrapper
) )
714 sal_uInt32 nIndex
= 0;
715 if( (aNativeObjectWrapper
.ObjectId
>>= nIndex
) )
717 SbxObject
* pObj
= lcl_getNativeObject( nIndex
);
718 pVar
->PutObject( pObj
);
726 SbiInstance
* pInst
= GetSbData()->pInst
;
727 if( pInst
&& pInst
->IsCompatibility() )
729 oleautomation::Date aDate
;
730 if( (aValue
>>= aDate
) )
732 pVar
->PutDate( aDate
.Value
);
737 oleautomation::Decimal aDecimal
;
738 if( (aValue
>>= aDecimal
) )
740 pVar
->PutDecimal( aDecimal
);
745 oleautomation::Currency aCurrency
;
746 if( (aValue
>>= aCurrency
) )
748 pVar
->PutCurrency( aCurrency
.Value
);
756 // instantiate a SbUnoObject
758 SbUnoObject
* pSbUnoObject
= new SbUnoObject( aName
, aValue
);
759 //If this is called externally e.g. from the scripting
760 //framework then there is no 'active' runtime the default property will not be set up
761 //only a vba object will have XDefaultProp set anyway so... this
762 //test seems a bit of overkill
763 //if ( SbiRuntime::isVBAEnabled() )
765 OUString sDfltPropName
;
767 if ( SbUnoObject::getDefaultPropName( pSbUnoObject
, sDfltPropName
) )
769 pSbUnoObject
->SetDfltProperty( sDfltPropName
);
772 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
774 // If the object is invalid deliver zero
775 if( pSbUnoObject
->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID
)
777 pVar
->PutObject( NULL
);
781 pVar
->PutObject( xWrapper
);
790 enum2int( nEnum
, aValue
);
791 pVar
->PutLong( nEnum
);
795 case TypeClass_SEQUENCE
:
797 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aType
);
798 Reference
< XIdlArray
> xIdlArray
= xIdlTargetClass
->getArray();
799 sal_Int32 i
, nLen
= xIdlArray
->getLen( aValue
);
801 typelib_TypeDescription
* pTD
= 0;
802 aType
.getDescription( &pTD
);
803 OSL_ASSERT( pTD
&& pTD
->eTypeClass
== typelib_TypeClass_SEQUENCE
);
804 Type
aElementType( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
805 ::typelib_typedescription_release( pTD
);
807 // build an Array in Basic
808 SbxDimArrayRef xArray
;
809 SbxDataType eSbxElementType
= unoToSbxType( aElementType
.getTypeClass() );
810 xArray
= new SbxDimArray( eSbxElementType
);
813 xArray
->unoAddDim32( 0, nLen
- 1 );
815 // register the elements as variables
816 for( i
= 0 ; i
< nLen
; i
++ )
819 Any aElementAny
= xIdlArray
->get( aValue
, (sal_uInt32
)i
);
820 SbxVariableRef xVar
= new SbxVariable( eSbxElementType
);
821 unoToSbxValue( (SbxVariable
*)xVar
, aElementAny
);
823 // put into the Array
824 xArray
->Put32( (SbxVariable
*)xVar
, &i
);
829 xArray
->unoAddDim( 0, -1 );
833 sal_uInt16 nFlags
= pVar
->GetFlags();
834 pVar
->ResetFlag( SBX_FIXED
);
835 pVar
->PutObject( (SbxDimArray
*)xArray
);
836 pVar
->SetFlags( nFlags
);
842 case TypeClass_BOOLEAN
: pVar
->PutBool( *(sal_Bool
*)aValue
.getValue() ); break;
845 pVar
->PutChar( *(sal_Unicode
*)aValue
.getValue() );
848 case TypeClass_STRING
: { OUString val
; aValue
>>= val
; pVar
->PutString( val
); } break;
849 case TypeClass_FLOAT
: { float val
= 0; aValue
>>= val
; pVar
->PutSingle( val
); } break;
850 case TypeClass_DOUBLE
: { double val
= 0; aValue
>>= val
; pVar
->PutDouble( val
); } break;
851 case TypeClass_BYTE
: { sal_Int8 val
= 0; aValue
>>= val
; pVar
->PutInteger( val
); } break;
852 case TypeClass_SHORT
: { sal_Int16 val
= 0; aValue
>>= val
; pVar
->PutInteger( val
); } break;
853 case TypeClass_LONG
: { sal_Int32 val
= 0; aValue
>>= val
; pVar
->PutLong( val
); } break;
854 case TypeClass_HYPER
: { sal_Int64 val
= 0; aValue
>>= val
; pVar
->PutInt64( val
); } break;
855 case TypeClass_UNSIGNED_SHORT
: { sal_uInt16 val
= 0; aValue
>>= val
; pVar
->PutUShort( val
); } break;
856 case TypeClass_UNSIGNED_LONG
: { sal_uInt32 val
= 0; aValue
>>= val
; pVar
->PutULong( val
); } break;
857 case TypeClass_UNSIGNED_HYPER
: { sal_uInt64 val
= 0; aValue
>>= val
; pVar
->PutUInt64( val
); } break;
858 default: pVar
->PutEmpty(); break;
862 // Deliver the reflection for Sbx types
863 Type
getUnoTypeForSbxBaseType( SbxDataType eType
)
865 Type aRetType
= getCppuVoidType();
868 case SbxNULL
: aRetType
= ::getCppuType( (const Reference
< XInterface
> *)0 ); break;
869 case SbxINTEGER
: aRetType
= ::getCppuType( (sal_Int16
*)0 ); break;
870 case SbxLONG
: aRetType
= ::getCppuType( (sal_Int32
*)0 ); break;
871 case SbxSINGLE
: aRetType
= ::getCppuType( (float*)0 ); break;
872 case SbxDOUBLE
: aRetType
= ::getCppuType( (double*)0 ); break;
873 case SbxCURRENCY
: aRetType
= ::getCppuType( (oleautomation::Currency
*)0 ); break;
874 case SbxDECIMAL
: aRetType
= ::getCppuType( (oleautomation::Decimal
*)0 ); break;
876 SbiInstance
* pInst
= GetSbData()->pInst
;
877 if( pInst
&& pInst
->IsCompatibility() )
878 aRetType
= ::getCppuType( (double*)0 );
880 aRetType
= ::getCppuType( (oleautomation::Date
*)0 );
883 case SbxSTRING
: aRetType
= ::getCppuType( (OUString
*)0 ); break;
884 case SbxBOOL
: aRetType
= ::getCppuType( (sal_Bool
*)0 ); break;
885 case SbxVARIANT
: aRetType
= ::getCppuType( (Any
*)0 ); break;
886 case SbxCHAR
: aRetType
= ::getCppuType( (sal_Unicode
*)0 ); break;
887 case SbxBYTE
: aRetType
= ::getCppuType( (sal_Int8
*)0 ); break;
888 case SbxUSHORT
: aRetType
= ::getCppuType( (sal_uInt16
*)0 ); break;
889 case SbxULONG
: aRetType
= ::getCppuType( (sal_uInt32
*)0 ); break;
890 // map machine-dependent ones on hyper for secureness
891 case SbxINT
: aRetType
= ::getCppuType( (sal_Int32
*)0 ); break;
892 case SbxUINT
: aRetType
= ::getCppuType( (sal_uInt32
*)0 ); break;
898 // Converting of Sbx to Uno without a know target class for TypeClass_ANY
899 Type
getUnoTypeForSbxValue( const SbxValue
* pVal
)
901 Type aRetType
= getCppuVoidType();
905 // convert SbxType to Uno
906 SbxDataType eBaseType
= pVal
->SbxValue::GetType();
907 if( eBaseType
== SbxOBJECT
)
909 SbxBaseRef xObj
= (SbxBase
*)pVal
->GetObject();
912 aRetType
= getCppuType( static_cast<Reference
<XInterface
> *>(0) );
916 if( xObj
->ISA(SbxDimArray
) )
918 SbxBase
* pObj
= (SbxBase
*)xObj
;
919 SbxDimArray
* pArray
= (SbxDimArray
*)pObj
;
921 short nDims
= pArray
->GetDims();
922 Type aElementType
= getUnoTypeForSbxBaseType( (SbxDataType
)(pArray
->GetType() & 0xfff) );
923 TypeClass eElementTypeClass
= aElementType
.getTypeClass();
925 // Normal case: One dimensional array
926 sal_Int32 nLower
, nUpper
;
927 if( nDims
== 1 && pArray
->GetDim32( 1, nLower
, nUpper
) )
929 if( eElementTypeClass
== TypeClass_VOID
|| eElementTypeClass
== TypeClass_ANY
)
931 // If all elements of the arrays are from the same type, take
932 // this one - otherwise the whole will be considered as Any-Sequence
933 bool bNeedsInit
= true;
935 sal_Int32 nSize
= nUpper
- nLower
+ 1;
936 sal_Int32 nIdx
= nLower
;
937 for( sal_Int32 i
= 0 ; i
< nSize
; i
++,nIdx
++ )
939 SbxVariableRef xVar
= pArray
->Get32( &nIdx
);
940 Type aType
= getUnoTypeForSbxValue( (SbxVariable
*)xVar
);
943 if( aType
.getTypeClass() == TypeClass_VOID
)
945 // if only first element is void: different types -> []any
946 // if all elements are void: []void is not allowed -> []any
947 aElementType
= getCppuType( (Any
*)0 );
950 aElementType
= aType
;
953 else if( aElementType
!= aType
)
955 // different types -> AnySequence
956 aElementType
= getCppuType( (Any
*)0 );
962 OUString aSeqTypeName
= aSeqLevelStr
+ aElementType
.getTypeName();
963 aRetType
= Type( TypeClass_SEQUENCE
, aSeqTypeName
);
965 // #i33795 Map also multi dimensional arrays to corresponding sequences
968 if( eElementTypeClass
== TypeClass_VOID
|| eElementTypeClass
== TypeClass_ANY
)
970 // For this check the array's dim structure does not matter
971 sal_uInt32 nFlatArraySize
= pArray
->Count32();
973 bool bNeedsInit
= true;
974 for( sal_uInt32 i
= 0 ; i
< nFlatArraySize
; i
++ )
976 SbxVariableRef xVar
= pArray
->SbxArray::Get32( i
);
977 Type aType
= getUnoTypeForSbxValue( (SbxVariable
*)xVar
);
980 if( aType
.getTypeClass() == TypeClass_VOID
)
982 // if only first element is void: different types -> []any
983 // if all elements are void: []void is not allowed -> []any
984 aElementType
= getCppuType( (Any
*)0 );
987 aElementType
= aType
;
990 else if( aElementType
!= aType
)
992 // different types -> AnySequence
993 aElementType
= getCppuType( (Any
*)0 );
999 OUStringBuffer aSeqTypeName
;
1000 for( short iDim
= 0 ; iDim
< nDims
; iDim
++ )
1002 aSeqTypeName
.appendAscii(aSeqLevelStr
);
1004 aSeqTypeName
.append(aElementType
.getTypeName());
1005 aRetType
= Type( TypeClass_SEQUENCE
, aSeqTypeName
.makeStringAndClear() );
1008 // No array, but ...
1009 else if( xObj
->ISA(SbUnoObject
) )
1011 aRetType
= ((SbUnoObject
*)(SbxBase
*)xObj
)->getUnoAny().getValueType();
1014 else if( xObj
->ISA(SbUnoAnyObject
) )
1016 aRetType
= ((SbUnoAnyObject
*)(SbxBase
*)xObj
)->getValue().getValueType();
1018 // Otherwise it is a No-Uno-Basic-Object -> default==deliver void
1020 // No object, convert basic type
1023 aRetType
= getUnoTypeForSbxBaseType( eBaseType
);
1028 // converting of Sbx to Uno without known target class for TypeClass_ANY
1029 Any
sbxToUnoValueImpl( const SbxValue
* pVar
, bool bBlockConversionToSmallestType
= false )
1031 SbxDataType eBaseType
= pVar
->SbxValue::GetType();
1032 if( eBaseType
== SbxOBJECT
)
1034 SbxBaseRef xObj
= (SbxBase
*)pVar
->GetObject();
1037 if( xObj
->ISA(SbUnoAnyObject
) )
1038 return ((SbUnoAnyObject
*)(SbxBase
*)xObj
)->getValue();
1039 if( xObj
->ISA(SbClassModuleObject
) )
1042 SbClassModuleObject
* pClassModuleObj
= (SbClassModuleObject
*)(SbxBase
*)xObj
;
1043 SbModule
* pClassModule
= pClassModuleObj
->getClassModule();
1044 if( pClassModule
->createCOMWrapperForIface( aRetAny
, pClassModuleObj
) )
1047 if( !xObj
->ISA(SbUnoObject
) )
1049 // Create NativeObjectWrapper to identify object in case of callbacks
1050 SbxObject
* pObj
= PTR_CAST(SbxObject
,pVar
->GetObject());
1053 NativeObjectWrapper aNativeObjectWrapper
;
1054 sal_uInt32 nIndex
= lcl_registerNativeObjectWrapper( pObj
);
1055 aNativeObjectWrapper
.ObjectId
<<= nIndex
;
1057 aRetAny
<<= aNativeObjectWrapper
;
1064 Type aType
= getUnoTypeForSbxValue( pVar
);
1065 TypeClass eType
= aType
.getTypeClass();
1067 if( !bBlockConversionToSmallestType
)
1069 // #79615 Choose "smallest" represention for int values
1070 // because up cast is allowed, downcast not
1073 case TypeClass_FLOAT
:
1074 case TypeClass_DOUBLE
:
1076 double d
= pVar
->GetDouble();
1077 if( d
== floor( d
) )
1079 if( d
>= -128 && d
<= 127 )
1080 aType
= ::getCppuType( (sal_Int8
*)0 );
1081 else if( d
>= SbxMININT
&& d
<= SbxMAXINT
)
1082 aType
= ::getCppuType( (sal_Int16
*)0 );
1083 else if( d
>= -SbxMAXLNG
&& d
<= SbxMAXLNG
)
1084 aType
= ::getCppuType( (sal_Int32
*)0 );
1088 case TypeClass_SHORT
:
1090 sal_Int16 n
= pVar
->GetInteger();
1091 if( n
>= -128 && n
<= 127 )
1092 aType
= ::getCppuType( (sal_Int8
*)0 );
1095 case TypeClass_LONG
:
1097 sal_Int32 n
= pVar
->GetLong();
1098 if( n
>= -128 && n
<= 127 )
1099 aType
= ::getCppuType( (sal_Int8
*)0 );
1100 else if( n
>= SbxMININT
&& n
<= SbxMAXINT
)
1101 aType
= ::getCppuType( (sal_Int16
*)0 );
1104 case TypeClass_UNSIGNED_SHORT
:
1106 sal_uInt16 n
= pVar
->GetUShort();
1108 aType
= ::getCppuType( (sal_uInt8
*)0 );
1111 case TypeClass_UNSIGNED_LONG
:
1113 sal_uInt32 n
= pVar
->GetLong();
1115 aType
= ::getCppuType( (sal_uInt8
*)0 );
1116 else if( n
<= SbxMAXUINT
)
1117 aType
= ::getCppuType( (sal_uInt16
*)0 );
1120 // TODO: need to add hyper types ?
1125 return sbxToUnoValue( pVar
, aType
);
1130 // Helper function for StepREDIMP
1131 static Any
implRekMultiDimArrayToSequence( SbxDimArray
* pArray
,
1132 const Type
& aElemType
, short nMaxDimIndex
, short nActualDim
,
1133 sal_Int32
* pActualIndices
, sal_Int32
* pLowerBounds
, sal_Int32
* pUpperBounds
)
1135 sal_Int32 nSeqLevel
= nMaxDimIndex
- nActualDim
+ 1;
1136 OUStringBuffer aSeqTypeName
;
1138 for( i
= 0 ; i
< nSeqLevel
; i
++ )
1140 aSeqTypeName
.appendAscii(aSeqLevelStr
);
1142 aSeqTypeName
.append(aElemType
.getTypeName());
1143 Type
aSeqType( TypeClass_SEQUENCE
, aSeqTypeName
.makeStringAndClear() );
1145 // Create Sequence instance
1147 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aSeqType
);
1148 xIdlTargetClass
->createObject( aRetVal
);
1150 // Alloc sequence according to array bounds
1151 sal_Int32 nUpper
= pUpperBounds
[nActualDim
];
1152 sal_Int32 nLower
= pLowerBounds
[nActualDim
];
1153 sal_Int32 nSeqSize
= nUpper
- nLower
+ 1;
1154 Reference
< XIdlArray
> xArray
= xIdlTargetClass
->getArray();
1155 xArray
->realloc( aRetVal
, nSeqSize
);
1157 sal_Int32
& ri
= pActualIndices
[nActualDim
];
1159 for( ri
= nLower
,i
= 0 ; ri
<= nUpper
; ri
++,i
++ )
1163 if( nActualDim
< nMaxDimIndex
)
1165 aElementVal
= implRekMultiDimArrayToSequence( pArray
, aElemType
,
1166 nMaxDimIndex
, nActualDim
+ 1, pActualIndices
, pLowerBounds
, pUpperBounds
);
1170 SbxVariable
* pSource
= pArray
->Get32( pActualIndices
);
1171 aElementVal
= sbxToUnoValue( pSource
, aElemType
);
1176 // transfer to the sequence
1177 xArray
->set( aRetVal
, i
, aElementVal
);
1179 catch( const IllegalArgumentException
& )
1181 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
1182 implGetExceptionMsg( ::cppu::getCaughtException() ) );
1184 catch (const IndexOutOfBoundsException
&)
1186 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
1192 // Map old interface
1193 Any
sbxToUnoValue( const SbxValue
* pVar
)
1195 return sbxToUnoValueImpl( pVar
);
1198 // function to find a global identifier in
1199 // the UnoScope and to wrap it for Sbx
1200 static bool implGetTypeByName( const OUString
& rName
, Type
& rRetType
)
1202 bool bSuccess
= false;
1204 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
1205 if( xTypeAccess
->hasByHierarchicalName( rName
) )
1207 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
1208 Reference
< XTypeDescription
> xTypeDesc
;
1211 if( xTypeDesc
.is() )
1213 rRetType
= Type( xTypeDesc
->getTypeClass(), xTypeDesc
->getName() );
1221 // converting of Sbx to Uno with known target class
1222 Any
sbxToUnoValue( const SbxValue
* pVar
, const Type
& rType
, Property
* pUnoProperty
)
1226 // #94560 No conversion of empty/void for MAYBE_VOID properties
1227 if( pUnoProperty
&& pUnoProperty
->Attributes
& PropertyAttribute::MAYBEVOID
)
1229 if( pVar
->IsEmpty() )
1233 SbxDataType eBaseType
= pVar
->SbxValue::GetType();
1234 if( eBaseType
== SbxOBJECT
)
1236 SbxBaseRef xObj
= (SbxBase
*)pVar
->GetObject();
1237 if( xObj
.Is() && xObj
->ISA(SbUnoAnyObject
) )
1239 return ((SbUnoAnyObject
*)(SbxBase
*)xObj
)->getValue();
1243 TypeClass eType
= rType
.getTypeClass();
1246 case TypeClass_INTERFACE
:
1247 case TypeClass_STRUCT
:
1248 case TypeClass_EXCEPTION
:
1250 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( rType
);
1253 if( pVar
->IsNull() && eType
== TypeClass_INTERFACE
)
1255 Reference
< XInterface
> xRef
;
1256 OUString aClassName
= xIdlTargetClass
->getName();
1257 Type
aClassType( xIdlTargetClass
->getTypeClass(), aClassName
.getStr() );
1258 aRetVal
.setValue( &xRef
, aClassType
);
1262 // #112368 Special conversion for Decimal, Currency and Date
1263 if( eType
== TypeClass_STRUCT
)
1265 SbiInstance
* pInst
= GetSbData()->pInst
;
1266 if( pInst
&& pInst
->IsCompatibility() )
1268 if( rType
== ::getCppuType( (oleautomation::Decimal
*)0 ) )
1270 oleautomation::Decimal aDecimal
;
1271 pVar
->fillAutomationDecimal( aDecimal
);
1272 aRetVal
<<= aDecimal
;
1275 else if( rType
== ::getCppuType( (oleautomation::Currency
*)0 ) )
1277 // assumes per previous code that ole Currency is Int64
1278 aRetVal
<<= (sal_Int64
)( pVar
->GetInt64() );
1281 else if( rType
== ::getCppuType( (oleautomation::Date
*)0 ) )
1283 oleautomation::Date aDate
;
1284 aDate
.Value
= pVar
->GetDate();
1291 SbxBaseRef pObj
= (SbxBase
*)pVar
->GetObject();
1292 if( pObj
&& pObj
->ISA(SbUnoObject
) )
1294 aRetVal
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
1296 else if( pObj
&& pObj
->ISA(SbUnoStructRefObject
) )
1298 aRetVal
= ((SbUnoStructRefObject
*)(SbxBase
*)pObj
)->getUnoAny();
1302 // zero object -> zero XInterface
1303 Reference
<XInterface
> xInt
;
1310 case TypeClass_TYPE
:
1312 if( eBaseType
== SbxOBJECT
)
1315 Reference
< XIdlClass
> xIdlClass
;
1317 SbxBaseRef pObj
= (SbxBase
*)pVar
->GetObject();
1318 if( pObj
&& pObj
->ISA(SbUnoObject
) )
1320 Any aUnoAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
1321 aUnoAny
>>= xIdlClass
;
1324 if( xIdlClass
.is() )
1326 OUString aClassName
= xIdlClass
->getName();
1327 Type
aType( xIdlClass
->getTypeClass(), aClassName
.getStr() );
1331 else if( eBaseType
== SbxSTRING
)
1333 OUString aTypeName
= pVar
->GetOUString();
1335 bool bSuccess
= implGetTypeByName( aTypeName
, aType
);
1345 case TypeClass_ENUM
:
1347 aRetVal
= int2enum( pVar
->GetLong(), rType
);
1351 case TypeClass_SEQUENCE
:
1353 SbxBaseRef xObj
= (SbxBase
*)pVar
->GetObject();
1354 if( xObj
&& xObj
->ISA(SbxDimArray
) )
1356 SbxBase
* pObj
= (SbxBase
*)xObj
;
1357 SbxDimArray
* pArray
= (SbxDimArray
*)pObj
;
1359 short nDims
= pArray
->GetDims();
1361 // Normal case: One dimensional array
1362 sal_Int32 nLower
, nUpper
;
1363 if( nDims
== 1 && pArray
->GetDim32( 1, nLower
, nUpper
) )
1365 sal_Int32 nSeqSize
= nUpper
- nLower
+ 1;
1367 // create the instanz of the required sequence
1368 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( rType
);
1369 xIdlTargetClass
->createObject( aRetVal
);
1370 Reference
< XIdlArray
> xArray
= xIdlTargetClass
->getArray();
1371 xArray
->realloc( aRetVal
, nSeqSize
);
1374 OUString aClassName
= xIdlTargetClass
->getName();
1375 typelib_TypeDescription
* pSeqTD
= 0;
1376 typelib_typedescription_getByName( &pSeqTD
, aClassName
.pData
);
1377 OSL_ASSERT( pSeqTD
);
1378 Type
aElemType( ((typelib_IndirectTypeDescription
*)pSeqTD
)->pType
);
1380 // convert all array member and register them
1381 sal_Int32 nIdx
= nLower
;
1382 for( sal_Int32 i
= 0 ; i
< nSeqSize
; i
++,nIdx
++ )
1384 SbxVariableRef xVar
= pArray
->Get32( &nIdx
);
1386 // Convert the value of Sbx to Uno
1387 Any aAnyValue
= sbxToUnoValue( (SbxVariable
*)xVar
, aElemType
);
1391 // take over to the sequence
1392 xArray
->set( aRetVal
, i
, aAnyValue
);
1394 catch( const IllegalArgumentException
& )
1396 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
1397 implGetExceptionMsg( ::cppu::getCaughtException() ) );
1399 catch (const IndexOutOfBoundsException
&)
1401 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
1405 // #i33795 Map also multi dimensional arrays to corresponding sequences
1406 else if( nDims
> 1 )
1409 typelib_TypeDescription
* pSeqTD
= 0;
1410 Type
aCurType( rType
);
1411 sal_Int32 nSeqLevel
= 0;
1415 OUString aTypeName
= aCurType
.getTypeName();
1416 typelib_typedescription_getByName( &pSeqTD
, aTypeName
.pData
);
1417 OSL_ASSERT( pSeqTD
);
1418 if( pSeqTD
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1420 aCurType
= Type( ((typelib_IndirectTypeDescription
*)pSeqTD
)->pType
);
1425 aElemType
= aCurType
;
1431 if( nSeqLevel
== nDims
)
1433 sal_Int32
* pLowerBounds
= new sal_Int32
[nDims
];
1434 sal_Int32
* pUpperBounds
= new sal_Int32
[nDims
];
1435 sal_Int32
* pActualIndices
= new sal_Int32
[nDims
];
1436 for( short i
= 1 ; i
<= nDims
; i
++ )
1438 sal_Int32 lBound
, uBound
;
1439 pArray
->GetDim32( i
, lBound
, uBound
);
1442 pActualIndices
[j
] = pLowerBounds
[j
] = lBound
;
1443 pUpperBounds
[j
] = uBound
;
1446 aRetVal
= implRekMultiDimArrayToSequence( pArray
, aElemType
,
1447 nDims
- 1, 0, pActualIndices
, pLowerBounds
, pUpperBounds
);
1449 delete[] pUpperBounds
;
1450 delete[] pLowerBounds
;
1451 delete[] pActualIndices
;
1459 // Use for Any the class indipendent converting routine
1462 aRetVal
= sbxToUnoValueImpl( pVar
);
1466 case TypeClass_BOOLEAN
:
1468 sal_Bool b
= pVar
->GetBool();
1469 aRetVal
.setValue( &b
, getBooleanCppuType() );
1472 case TypeClass_CHAR
:
1474 sal_Unicode c
= pVar
->GetChar();
1475 aRetVal
.setValue( &c
, getCharCppuType() );
1478 case TypeClass_STRING
: aRetVal
<<= pVar
->GetOUString(); break;
1479 case TypeClass_FLOAT
: aRetVal
<<= pVar
->GetSingle(); break;
1480 case TypeClass_DOUBLE
: aRetVal
<<= pVar
->GetDouble(); break;
1482 case TypeClass_BYTE
:
1484 sal_Int16 nVal
= pVar
->GetInteger();
1485 sal_Bool bOverflow
= sal_False
;
1488 bOverflow
= sal_True
;
1491 else if( nVal
> 127 )
1493 bOverflow
= sal_True
;
1497 StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW
);
1499 sal_Int8 nByteVal
= (sal_Int8
)nVal
;
1500 aRetVal
<<= nByteVal
;
1503 case TypeClass_SHORT
: aRetVal
<<= (sal_Int16
)( pVar
->GetInteger() ); break;
1504 case TypeClass_LONG
: aRetVal
<<= (sal_Int32
)( pVar
->GetLong() ); break;
1505 case TypeClass_HYPER
: aRetVal
<<= (sal_Int64
)( pVar
->GetInt64() ); break;
1506 case TypeClass_UNSIGNED_SHORT
: aRetVal
<<= (sal_uInt16
)( pVar
->GetUShort() ); break;
1507 case TypeClass_UNSIGNED_LONG
: aRetVal
<<= (sal_uInt32
)( pVar
->GetULong() ); break;
1508 case TypeClass_UNSIGNED_HYPER
: aRetVal
<<= (sal_uInt64
)( pVar
->GetUInt64() ); break;
1515 void processAutomationParams( SbxArray
* pParams
, Sequence
< Any
>& args
, bool bOLEAutomation
, sal_uInt32 nParamCount
)
1517 AutomationNamedArgsSbxArray
* pArgNamesArray
= NULL
;
1518 if( bOLEAutomation
)
1519 pArgNamesArray
= PTR_CAST(AutomationNamedArgsSbxArray
,pParams
);
1521 args
.realloc( nParamCount
);
1522 Any
* pAnyArgs
= args
.getArray();
1523 bool bBlockConversionToSmallestType
= GetSbData()->pInst
->IsCompatibility();
1525 if( pArgNamesArray
)
1527 Sequence
< OUString
>& rNameSeq
= pArgNamesArray
->getNames();
1528 OUString
* pNames
= rNameSeq
.getArray();
1530 for( i
= 0 ; i
< nParamCount
; i
++ )
1532 sal_uInt16 iSbx
= (sal_uInt16
)(i
+1);
1534 aValAny
= sbxToUnoValueImpl( pParams
->Get( iSbx
),
1535 bBlockConversionToSmallestType
);
1537 OUString aParamName
= pNames
[iSbx
];
1538 if( !aParamName
.isEmpty() )
1540 oleautomation::NamedArgument aNamedArgument
;
1541 aNamedArgument
.Name
= aParamName
;
1542 aNamedArgument
.Value
= aValAny
;
1543 pAnyArgs
[i
] <<= aNamedArgument
;
1547 pAnyArgs
[i
] = aValAny
;
1553 for( i
= 0 ; i
< nParamCount
; i
++ )
1555 pAnyArgs
[i
] = sbxToUnoValueImpl( pParams
->Get( (sal_uInt16
)(i
+1) ),
1556 bBlockConversionToSmallestType
);
1567 Any
invokeAutomationMethod( const OUString
& Name
, Sequence
< Any
>& args
, SbxArray
* pParams
, sal_uInt32 nParamCount
, Reference
< XInvocation
>& rxInvocation
, INVOKETYPE invokeType
= Func
)
1569 Sequence
< sal_Int16
> OutParamIndex
;
1570 Sequence
< Any
> OutParam
;
1573 switch( invokeType
)
1576 aRetAny
= rxInvocation
->invoke( Name
, args
, OutParamIndex
, OutParam
);
1580 Reference
< XAutomationInvocation
> xAutoInv( rxInvocation
, UNO_QUERY
);
1581 aRetAny
= xAutoInv
->invokeGetProperty( Name
, args
, OutParamIndex
, OutParam
);
1586 Reference
< XAutomationInvocation
> xAutoInv( rxInvocation
, UNO_QUERY_THROW
);
1587 aRetAny
= xAutoInv
->invokePutProperty( Name
, args
, OutParamIndex
, OutParam
);
1591 break; // should introduce an error here
1594 const sal_Int16
* pIndices
= OutParamIndex
.getConstArray();
1595 sal_uInt32 nLen
= OutParamIndex
.getLength();
1598 const Any
* pNewValues
= OutParam
.getConstArray();
1599 for( sal_uInt32 j
= 0 ; j
< nLen
; j
++ )
1601 sal_Int16 iTarget
= pIndices
[ j
];
1602 if( iTarget
>= (sal_Int16
)nParamCount
)
1604 unoToSbxValue( (SbxVariable
*)pParams
->Get( (sal_uInt16
)(j
+1) ), pNewValues
[ j
] );
1610 // Debugging help method to readout the imlemented interfaces of an object
1611 OUString
Impl_GetInterfaceInfo( const Reference
< XInterface
>& x
, const Reference
< XIdlClass
>& xClass
, sal_uInt16 nRekLevel
)
1613 Type aIfaceType
= ::getCppuType( (const Reference
< XInterface
> *)0 );
1614 static Reference
< XIdlClass
> xIfaceClass
= TypeToIdlClass( aIfaceType
);
1616 OUStringBuffer aRetStr
;
1617 for( sal_uInt16 i
= 0 ; i
< nRekLevel
; i
++ )
1618 aRetStr
.appendAscii( " " );
1619 aRetStr
.append( xClass
->getName() );
1620 OUString aClassName
= xClass
->getName();
1621 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
1623 // checking if the interface is realy supported
1624 if( !x
->queryInterface( aClassType
).hasValue() )
1626 aRetStr
.appendAscii( " (ERROR: Not really supported!)\n" );
1628 // Are there super interfaces?
1631 aRetStr
.appendAscii( "\n" );
1633 // get the super interfaces
1634 Sequence
< Reference
< XIdlClass
> > aSuperClassSeq
= xClass
->getSuperclasses();
1635 const Reference
< XIdlClass
>* pClasses
= aSuperClassSeq
.getConstArray();
1636 sal_uInt32 nSuperIfaceCount
= aSuperClassSeq
.getLength();
1637 for( sal_uInt32 j
= 0 ; j
< nSuperIfaceCount
; j
++ )
1639 const Reference
< XIdlClass
>& rxIfaceClass
= pClasses
[j
];
1640 if( !rxIfaceClass
->equals( xIfaceClass
) )
1641 aRetStr
.append( Impl_GetInterfaceInfo( x
, rxIfaceClass
, nRekLevel
+ 1 ) );
1644 return aRetStr
.makeStringAndClear();
1647 OUString
getDbgObjectNameImpl( SbUnoObject
* pUnoObj
)
1652 aName
= pUnoObj
->GetClassName();
1653 if( aName
.isEmpty() )
1655 Any aToInspectObj
= pUnoObj
->getUnoAny();
1656 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1657 Reference
< XInterface
> xObj
;
1658 if( eType
== TypeClass_INTERFACE
)
1659 xObj
= *(Reference
< XInterface
>*)aToInspectObj
.getValue();
1662 Reference
< XServiceInfo
> xServiceInfo( xObj
, UNO_QUERY
);
1663 if( xServiceInfo
.is() )
1664 aName
= xServiceInfo
->getImplementationName();
1671 OUString
getDbgObjectName( SbUnoObject
* pUnoObj
)
1673 OUString aName
= getDbgObjectNameImpl( pUnoObj
);
1674 if( aName
.isEmpty() )
1677 OUStringBuffer aRet
;
1678 if( aName
.getLength() > 20 )
1680 aRet
.appendAscii( "\n" );
1682 aRet
.appendAscii( "\"" );
1683 aRet
.append( aName
);
1684 aRet
.appendAscii( "\":" );
1685 return aRet
.makeStringAndClear();
1688 OUString
getBasicObjectTypeName( SbxObject
* pObj
)
1693 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
1694 SbUnoStructRefObject
* pUnoStructObj
= PTR_CAST(SbUnoStructRefObject
,pObj
);
1696 aName
= getDbgObjectNameImpl( pUnoObj
);
1697 else if ( pUnoStructObj
)
1698 aName
= pUnoStructObj
->GetClassName();
1703 bool checkUnoObjectType( SbUnoObject
* pUnoObj
, const OUString
& rClass
)
1705 Any aToInspectObj
= pUnoObj
->getUnoAny();
1706 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1707 if( eType
!= TypeClass_INTERFACE
)
1711 const Reference
< XInterface
> x
= *(Reference
< XInterface
>*)aToInspectObj
.getValue();
1713 // Return true for XInvocation based objects as interface type names don't count then
1714 Reference
< XInvocation
> xInvocation( x
, UNO_QUERY
);
1715 if( xInvocation
.is() )
1719 bool result
= false;
1720 Reference
< XTypeProvider
> xTypeProvider( x
, UNO_QUERY
);
1721 if( xTypeProvider
.is() )
1723 /* Although interfaces in the ooo.vba namespace obey the IDL rules and
1724 have a leading 'X', in Basic we want to be able to do something
1725 like 'Dim wb As Workbooks' or 'Dim lb As MSForms.Label'. Here we
1726 add a leading 'X' to the class name and a leading dot to the entire
1727 type name. This results e.g. in '.XWorkbooks' or '.MSForms.XLabel'
1728 which matches the interface names 'ooo.vba.excel.XWorkbooks' or
1729 'ooo.vba.msforms.XLabel'.
1731 OUString
aClassName( sal_Unicode( '.' ) );
1732 sal_Int32 nClassNameDot
= rClass
.lastIndexOf( '.' );
1733 if( nClassNameDot
>= 0 )
1735 aClassName
+= rClass
.copy( 0, nClassNameDot
+ 1 ) + OUString( sal_Unicode( 'X' ) ) + rClass
.copy( nClassNameDot
+ 1 );
1739 aClassName
+= OUString( sal_Unicode( 'X' ) ) + rClass
;
1741 Sequence
< Type
> aTypeSeq
= xTypeProvider
->getTypes();
1742 const Type
* pTypeArray
= aTypeSeq
.getConstArray();
1743 sal_uInt32 nIfaceCount
= aTypeSeq
.getLength();
1744 for( sal_uInt32 j
= 0 ; j
< nIfaceCount
; j
++ )
1746 const Type
& rType
= pTypeArray
[j
];
1748 Reference
<XIdlClass
> xClass
= TypeToIdlClass( rType
);
1751 OSL_FAIL("failed to get XIdlClass for type");
1754 OUString aInterfaceName
= xClass
->getName();
1755 if ( aInterfaceName
== "com.sun.star.bridge.oleautomation.XAutomationObject" )
1757 // there is a hack in the extensions/source/ole/oleobj.cxx to return the typename of the automation object, lets check if it
1759 Reference
< XInvocation
> xInv( aToInspectObj
, UNO_QUERY
);
1763 xInv
->getValue( OUString( "$GetTypeName" ) ) >>= sTypeName
;
1764 if ( sTypeName
.isEmpty() || sTypeName
== "IDispatch" )
1766 // can't check type, leave it pass
1771 result
= sTypeName
.equals( rClass
);
1774 break; // finished checking automation object
1777 // match interface name with passed class name
1778 OSL_TRACE("Checking if object implements %s", OUStringToOString( aClassName
, RTL_TEXTENCODING_UTF8
).getStr() );
1779 if ( (aClassName
.getLength() < aInterfaceName
.getLength()) &&
1780 aInterfaceName
.matchIgnoreAsciiCase( aClassName
, aInterfaceName
.getLength() - aClassName
.getLength() ) )
1790 // Debugging help method to readout the imlemented interfaces of an object
1791 OUString
Impl_GetSupportedInterfaces( SbUnoObject
* pUnoObj
)
1793 Any aToInspectObj
= pUnoObj
->getUnoAny();
1795 // allow only TypeClass interface
1796 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1797 OUStringBuffer aRet
;
1798 if( eType
!= TypeClass_INTERFACE
)
1800 aRet
.appendAscii( ID_DBG_SUPPORTEDINTERFACES
);
1801 aRet
.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
1805 // get the interface from the Any
1806 const Reference
< XInterface
> x
= *(Reference
< XInterface
>*)aToInspectObj
.getValue();
1808 Reference
< XTypeProvider
> xTypeProvider( x
, UNO_QUERY
);
1810 aRet
.appendAscii( "Supported interfaces by object " );
1811 aRet
.append( getDbgObjectName( pUnoObj
) );
1812 aRet
.appendAscii( "\n" );
1813 if( xTypeProvider
.is() )
1815 // get the interfaces of the implementation
1816 Sequence
< Type
> aTypeSeq
= xTypeProvider
->getTypes();
1817 const Type
* pTypeArray
= aTypeSeq
.getConstArray();
1818 sal_uInt32 nIfaceCount
= aTypeSeq
.getLength();
1819 for( sal_uInt32 j
= 0 ; j
< nIfaceCount
; j
++ )
1821 const Type
& rType
= pTypeArray
[j
];
1823 Reference
<XIdlClass
> xClass
= TypeToIdlClass( rType
);
1826 aRet
.append( Impl_GetInterfaceInfo( x
, xClass
, 1 ) );
1830 typelib_TypeDescription
* pTD
= 0;
1831 rType
.getDescription( &pTD
);
1833 aRet
.appendAscii( "*** ERROR: No IdlClass for type \"" );
1834 aRet
.append( pTD
->pTypeName
);
1835 aRet
.appendAscii( "\"\n*** Please check type library\n" );
1840 return aRet
.makeStringAndClear();
1845 // Debugging help method SbxDataType -> String
1846 OUString
Dbg_SbxDataType2String( SbxDataType eType
)
1848 OUStringBuffer aRet
;
1851 case SbxEMPTY
: aRet
.appendAscii("SbxEMPTY"); break;
1852 case SbxNULL
: aRet
.appendAscii("SbxNULL"); break;
1853 case SbxINTEGER
: aRet
.appendAscii("SbxINTEGER"); break;
1854 case SbxLONG
: aRet
.appendAscii("SbxLONG"); break;
1855 case SbxSINGLE
: aRet
.appendAscii("SbxSINGLE"); break;
1856 case SbxDOUBLE
: aRet
.appendAscii("SbxDOUBLE"); break;
1857 case SbxCURRENCY
: aRet
.appendAscii("SbxCURRENCY"); break;
1858 case SbxDECIMAL
: aRet
.appendAscii("SbxDECIMAL"); break;
1859 case SbxDATE
: aRet
.appendAscii("SbxDATE"); break;
1860 case SbxSTRING
: aRet
.appendAscii("SbxSTRING"); break;
1861 case SbxOBJECT
: aRet
.appendAscii("SbxOBJECT"); break;
1862 case SbxERROR
: aRet
.appendAscii("SbxERROR"); break;
1863 case SbxBOOL
: aRet
.appendAscii("SbxBOOL"); break;
1864 case SbxVARIANT
: aRet
.appendAscii("SbxVARIANT"); break;
1865 case SbxDATAOBJECT
: aRet
.appendAscii("SbxDATAOBJECT"); break;
1866 case SbxCHAR
: aRet
.appendAscii("SbxCHAR"); break;
1867 case SbxBYTE
: aRet
.appendAscii("SbxBYTE"); break;
1868 case SbxUSHORT
: aRet
.appendAscii("SbxUSHORT"); break;
1869 case SbxULONG
: aRet
.appendAscii("SbxULONG"); break;
1870 case SbxSALINT64
: aRet
.appendAscii("SbxINT64"); break;
1871 case SbxSALUINT64
: aRet
.appendAscii("SbxUINT64"); break;
1872 case SbxINT
: aRet
.appendAscii("SbxINT"); break;
1873 case SbxUINT
: aRet
.appendAscii("SbxUINT"); break;
1874 case SbxVOID
: aRet
.appendAscii("SbxVOID"); break;
1875 case SbxHRESULT
: aRet
.appendAscii("SbxHRESULT"); break;
1876 case SbxPOINTER
: aRet
.appendAscii("SbxPOINTER"); break;
1877 case SbxDIMARRAY
: aRet
.appendAscii("SbxDIMARRAY"); break;
1878 case SbxCARRAY
: aRet
.appendAscii("SbxCARRAY"); break;
1879 case SbxUSERDEF
: aRet
.appendAscii("SbxUSERDEF"); break;
1880 case SbxLPSTR
: aRet
.appendAscii("SbxLPSTR"); break;
1881 case SbxLPWSTR
: aRet
.appendAscii("SbxLPWSTR"); break;
1882 case SbxCoreSTRING
: aRet
.appendAscii("SbxCoreSTRING"); break;
1883 case SbxOBJECT
| SbxARRAY
: aRet
.appendAscii("SbxARRAY"); break;
1884 default: aRet
.appendAscii("Unknown Sbx-Type!");break;
1886 return aRet
.makeStringAndClear();
1889 // Debugging help method to display the properties of a SbUnoObjects
1890 OUString
Impl_DumpProperties( SbUnoObject
* pUnoObj
)
1892 OUStringBuffer aRet
;
1893 aRet
.appendAscii("Properties of object ");
1894 aRet
.append( getDbgObjectName( pUnoObj
) );
1896 // analyse the Uno-Infos to recognise the arrays
1897 Reference
< XIntrospectionAccess
> xAccess
= pUnoObj
->getIntrospectionAccess();
1900 Reference
< XInvocation
> xInvok
= pUnoObj
->getInvocation();
1902 xAccess
= xInvok
->getIntrospection();
1906 aRet
.appendAscii( "\nUnknown, no introspection available\n" );
1907 return aRet
.makeStringAndClear();
1910 Sequence
<Property
> props
= xAccess
->getProperties( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
1911 sal_uInt32 nUnoPropCount
= props
.getLength();
1912 const Property
* pUnoProps
= props
.getConstArray();
1914 SbxArray
* pProps
= pUnoObj
->GetProperties();
1915 sal_uInt16 nPropCount
= pProps
->Count();
1916 sal_uInt16 nPropsPerLine
= 1 + nPropCount
/ 30;
1917 for( sal_uInt16 i
= 0; i
< nPropCount
; i
++ )
1919 SbxVariable
* pVar
= pProps
->Get( i
);
1922 OUStringBuffer aPropStr
;
1923 if( (i
% nPropsPerLine
) == 0 )
1924 aPropStr
.appendAscii( "\n" );
1926 // output the type and name
1927 // Is it in Uno a sequence?
1928 SbxDataType eType
= pVar
->GetFullType();
1930 sal_Bool bMaybeVoid
= sal_False
;
1931 if( i
< nUnoPropCount
)
1933 const Property
& rProp
= pUnoProps
[ i
];
1935 // By MAYBEVOID convert the type out of Uno newly,
1936 // so that not only SbxEMPTY were outputed.
1937 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
1939 eType
= unoToSbxType( rProp
.Type
.getTypeClass() );
1940 bMaybeVoid
= sal_True
;
1942 if( eType
== SbxOBJECT
)
1944 Type aType
= rProp
.Type
;
1945 if( aType
.getTypeClass() == TypeClass_SEQUENCE
)
1946 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
1949 aPropStr
.append( Dbg_SbxDataType2String( eType
) );
1951 aPropStr
.appendAscii( "/void" );
1952 aPropStr
.appendAscii( " " );
1953 aPropStr
.append( pVar
->GetName() );
1955 if( i
== nPropCount
- 1 )
1956 aPropStr
.appendAscii( "\n" );
1958 aPropStr
.appendAscii( "; " );
1960 aRet
.append( aPropStr
.makeStringAndClear() );
1963 return aRet
.makeStringAndClear();
1966 // Debugging help method to display the methods of an SbUnoObjects
1967 OUString
Impl_DumpMethods( SbUnoObject
* pUnoObj
)
1969 OUStringBuffer aRet
;
1970 aRet
.appendAscii("Methods of object ");
1971 aRet
.append( getDbgObjectName( pUnoObj
) );
1973 // XIntrospectionAccess, so that the types of the parameter could be outputed
1974 Reference
< XIntrospectionAccess
> xAccess
= pUnoObj
->getIntrospectionAccess();
1977 Reference
< XInvocation
> xInvok
= pUnoObj
->getInvocation();
1979 xAccess
= xInvok
->getIntrospection();
1983 aRet
.appendAscii( "\nUnknown, no introspection available\n" );
1984 return aRet
.makeStringAndClear();
1986 Sequence
< Reference
< XIdlMethod
> > methods
= xAccess
->getMethods
1987 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
1988 const Reference
< XIdlMethod
>* pUnoMethods
= methods
.getConstArray();
1990 SbxArray
* pMethods
= pUnoObj
->GetMethods();
1991 sal_uInt16 nMethodCount
= pMethods
->Count();
1994 aRet
.appendAscii( "\nNo methods found\n" );
1995 return aRet
.makeStringAndClear();
1997 sal_uInt16 nPropsPerLine
= 1 + nMethodCount
/ 30;
1998 for( sal_uInt16 i
= 0; i
< nMethodCount
; i
++ )
2000 SbxVariable
* pVar
= pMethods
->Get( i
);
2003 if( (i
% nPropsPerLine
) == 0 )
2004 aRet
.appendAscii( "\n" );
2006 // address the method
2007 const Reference
< XIdlMethod
>& rxMethod
= pUnoMethods
[i
];
2009 // Is it in Uno a sequence?
2010 SbxDataType eType
= pVar
->GetFullType();
2011 if( eType
== SbxOBJECT
)
2013 Reference
< XIdlClass
> xClass
= rxMethod
->getReturnType();
2014 if( xClass
.is() && xClass
->getTypeClass() == TypeClass_SEQUENCE
)
2015 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
2017 // output the name and the type
2018 aRet
.append( Dbg_SbxDataType2String( eType
) );
2019 aRet
.appendAscii( " " );
2020 aRet
.append ( pVar
->GetName() );
2021 aRet
.appendAscii( " ( " );
2023 // the get-method mustn't have a parameter
2024 Sequence
< Reference
< XIdlClass
> > aParamsSeq
= rxMethod
->getParameterTypes();
2025 sal_uInt32 nParamCount
= aParamsSeq
.getLength();
2026 const Reference
< XIdlClass
>* pParams
= aParamsSeq
.getConstArray();
2028 if( nParamCount
> 0 )
2030 for( sal_uInt16 j
= 0; j
< nParamCount
; j
++ )
2032 aRet
.append ( Dbg_SbxDataType2String( unoToSbxType( pParams
[ j
] ) ) );
2033 if( j
< nParamCount
- 1 )
2034 aRet
.appendAscii( ", " );
2038 aRet
.appendAscii( "void" );
2040 aRet
.appendAscii( " ) " );
2042 if( i
== nMethodCount
- 1 )
2043 aRet
.appendAscii( "\n" );
2045 aRet
.appendAscii( "; " );
2048 return aRet
.makeStringAndClear();
2051 TYPEINIT1(AutomationNamedArgsSbxArray
,SbxArray
)
2053 // Implementation SbUnoObject
2054 void SbUnoObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
2055 const SfxHint
& rHint
, const TypeId
& rHintType
)
2057 if( bNeedIntrospection
)
2060 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
2063 SbxVariable
* pVar
= pHint
->GetVar();
2064 SbxArray
* pParams
= pVar
->GetParameters();
2065 SbUnoProperty
* pProp
= PTR_CAST(SbUnoProperty
,pVar
);
2066 SbUnoMethod
* pMeth
= PTR_CAST(SbUnoMethod
,pVar
);
2069 bool bInvocation
= pProp
->isInvocationBased();
2070 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
2073 sal_Int32 nId
= pProp
->nId
;
2076 // Id == -1: Display implemented interfaces according the ClassProvider
2077 if( nId
== -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
2079 OUString aRetStr
= Impl_GetSupportedInterfaces( this );
2080 pVar
->PutString( aRetStr
);
2082 // Id == -2: output properties
2083 else if( nId
== -2 ) // Property ID_DBG_PROPERTIES
2085 // by now all properties must be established
2087 OUString aRetStr
= Impl_DumpProperties( this );
2088 pVar
->PutString( aRetStr
);
2090 // Id == -3: output the methods
2091 else if( nId
== -3 ) // Property ID_DBG_METHODS
2093 // y now all properties must be established
2095 OUString aRetStr
= Impl_DumpMethods( this );
2096 pVar
->PutString( aRetStr
);
2101 if( !bInvocation
&& mxUnoAccess
.is() )
2105 if ( maStructInfo
.get() )
2107 StructRefInfo aMember
= maStructInfo
->getStructMember( pProp
->GetName() );
2108 if ( aMember
.isEmpty() )
2110 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
2114 if ( pProp
->isUnoStruct() )
2116 SbUnoStructRefObject
* pSbUnoObject
= new SbUnoStructRefObject( pProp
->GetName(), aMember
);
2117 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
2118 pVar
->PutObject( xWrapper
);
2122 Any aRetAny
= aMember
.getValue();
2123 // take over the value from Uno to Sbx
2124 unoToSbxValue( pVar
, aRetAny
);
2130 Reference
< XPropertySet
> xPropSet( mxUnoAccess
->queryAdapter( ::getCppuType( (const Reference
< XPropertySet
> *)0 ) ), UNO_QUERY
);
2131 Any aRetAny
= xPropSet
->getPropertyValue( pProp
->GetName() );
2132 // The use of getPropertyValue (instead of using the index) is
2133 // suboptimal, but the refactoring to XInvocation is already pending
2134 // Otherwise it is posible to use FastPropertySet
2136 // take over the value from Uno to Sbx
2137 unoToSbxValue( pVar
, aRetAny
);
2139 catch( const Exception
& )
2141 implHandleAnyException( ::cppu::getCaughtException() );
2144 else if( bInvocation
&& mxInvocation
.is() )
2148 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
2149 sal_Bool bCanBeConsideredAMethod
= mxInvocation
->hasMethod( pProp
->GetName() );
2151 if ( bCanBeConsideredAMethod
&& nParamCount
)
2153 // Automation properties have methods, so.. we need to invoke this through
2156 processAutomationParams( pParams
, args
, true, nParamCount
);
2157 aRetAny
= invokeAutomationMethod( pProp
->GetName(), args
, pParams
, nParamCount
, mxInvocation
, GetProp
);
2160 aRetAny
= mxInvocation
->getValue( pProp
->GetName() );
2161 // take over the value from Uno to Sbx
2162 unoToSbxValue( pVar
, aRetAny
);
2163 if( pParams
&& bCanBeConsideredAMethod
)
2164 pVar
->SetParameters( NULL
);
2167 catch( const Exception
& )
2169 implHandleAnyException( ::cppu::getCaughtException() );
2173 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
2175 if( !bInvocation
&& mxUnoAccess
.is() )
2177 if( pProp
->aUnoProp
.Attributes
& PropertyAttribute::READONLY
)
2179 StarBASIC::Error( SbERR_PROP_READONLY
);
2182 if ( maStructInfo
.get() )
2184 StructRefInfo aMember
= maStructInfo
->getStructMember( pProp
->GetName() );
2185 if ( aMember
.isEmpty() )
2187 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
2191 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
2192 aMember
.setValue( aAnyValue
);
2196 // take over the value from Uno to Sbx
2197 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
2201 Reference
< XPropertySet
> xPropSet( mxUnoAccess
->queryAdapter( ::getCppuType( (const Reference
< XPropertySet
> *)0 ) ), UNO_QUERY
);
2202 xPropSet
->setPropertyValue( pProp
->GetName(), aAnyValue
);
2203 // The use of getPropertyValue (instead of using the index) is
2204 // suboptimal, but the refactoring to XInvocation is already pending
2205 // Otherwise it is posible to use FastPropertySet
2207 catch( const Exception
& )
2209 implHandleAnyException( ::cppu::getCaughtException() );
2212 else if( bInvocation
&& mxInvocation
.is() )
2214 // take over the value from Uno to Sbx
2215 Any aAnyValue
= sbxToUnoValueImpl( pVar
);
2219 mxInvocation
->setValue( pProp
->GetName(), aAnyValue
);
2221 catch( const Exception
& )
2223 implHandleAnyException( ::cppu::getCaughtException() );
2230 bool bInvocation
= pMeth
->isInvocationBased();
2231 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
2233 // number of Parameter -1 because of Param0 == this
2234 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
2236 sal_Bool bOutParams
= sal_False
;
2239 if( !bInvocation
&& mxUnoAccess
.is() )
2242 const Sequence
<ParamInfo
>& rInfoSeq
= pMeth
->getParamInfos();
2243 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2244 sal_uInt32 nUnoParamCount
= rInfoSeq
.getLength();
2245 sal_uInt32 nAllocParamCount
= nParamCount
;
2247 // ignore surplus parameter; alternative: throw an error
2248 if( nParamCount
> nUnoParamCount
)
2250 nParamCount
= nUnoParamCount
;
2251 nAllocParamCount
= nParamCount
;
2253 else if( nParamCount
< nUnoParamCount
)
2255 SbiInstance
* pInst
= GetSbData()->pInst
;
2256 if( pInst
&& pInst
->IsCompatibility() )
2259 bool bError
= false;
2260 for( i
= nParamCount
; i
< nUnoParamCount
; i
++ )
2262 const ParamInfo
& rInfo
= pParamInfos
[i
];
2263 const Reference
< XIdlClass
>& rxClass
= rInfo
.aType
;
2264 if( rxClass
->getTypeClass() != TypeClass_ANY
)
2267 StarBASIC::Error( SbERR_NOT_OPTIONAL
);
2271 nAllocParamCount
= nUnoParamCount
;
2275 if( nAllocParamCount
> 0 )
2277 args
.realloc( nAllocParamCount
);
2278 Any
* pAnyArgs
= args
.getArray();
2279 for( i
= 0 ; i
< nParamCount
; i
++ )
2281 const ParamInfo
& rInfo
= pParamInfos
[i
];
2282 const Reference
< XIdlClass
>& rxClass
= rInfo
.aType
;
2284 com::sun::star::uno::Type
aType( rxClass
->getTypeClass(), rxClass
->getName() );
2286 // ATTENTION: Don't forget for Sbx-Parameter the offset!
2287 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( (sal_uInt16
)(i
+1) ), aType
);
2289 // If it is not certain check whether the out-parameter are available.
2292 ParamMode aParamMode
= rInfo
.aMode
;
2293 if( aParamMode
!= ParamMode_IN
)
2294 bOutParams
= sal_True
;
2299 else if( bInvocation
&& pParams
&& mxInvocation
.is() )
2301 bool bOLEAutomation
= true;
2302 processAutomationParams( pParams
, args
, bOLEAutomation
, nParamCount
);
2306 GetSbData()->bBlockCompilerError
= true; // #106433 Block compiler errors for API calls
2309 if( !bInvocation
&& mxUnoAccess
.is() )
2311 Any aRetAny
= pMeth
->m_xUnoMethod
->invoke( getUnoAny(), args
);
2313 // take over the value from Uno to Sbx
2314 unoToSbxValue( pVar
, aRetAny
);
2316 // Did we to copy back the Out-Parameter?
2319 const Any
* pAnyArgs
= args
.getConstArray();
2322 const Sequence
<ParamInfo
>& rInfoSeq
= pMeth
->getParamInfos();
2323 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2326 for( j
= 0 ; j
< nParamCount
; j
++ )
2328 const ParamInfo
& rInfo
= pParamInfos
[j
];
2329 ParamMode aParamMode
= rInfo
.aMode
;
2330 if( aParamMode
!= ParamMode_IN
)
2331 unoToSbxValue( (SbxVariable
*)pParams
->Get( (sal_uInt16
)(j
+1) ), pAnyArgs
[ j
] );
2335 else if( bInvocation
&& mxInvocation
.is() )
2337 Any aRetAny
= invokeAutomationMethod( pMeth
->GetName(), args
, pParams
, nParamCount
, mxInvocation
);
2338 unoToSbxValue( pVar
, aRetAny
);
2341 // remove parameter here, because this was not done anymore in unoToSbxValue()
2344 pVar
->SetParameters( NULL
);
2346 catch( const Exception
& )
2348 implHandleAnyException( ::cppu::getCaughtException() );
2350 GetSbData()->bBlockCompilerError
= false; // #106433 Unblock compiler errors
2354 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
2359 SbUnoObject::SbUnoObject( const OUString
& aName_
, const Any
& aUnoObj_
)
2360 : SbxObject( aName_
)
2361 , bNeedIntrospection( true )
2362 , bNativeCOMObject( false )
2364 static Reference
< XIntrospection
> xIntrospection
;
2366 // beat out again the default properties of Sbx
2367 Remove( OUString("Name"), SbxCLASS_DONTCARE
);
2368 Remove( OUString("Parent"), SbxCLASS_DONTCARE
);
2370 // check the type of the ojekts
2371 TypeClass eType
= aUnoObj_
.getValueType().getTypeClass();
2372 Reference
< XInterface
> x
;
2373 if( eType
== TypeClass_INTERFACE
)
2375 // get the interface from the Any
2376 x
= *(Reference
< XInterface
>*)aUnoObj_
.getValue();
2381 Reference
< XTypeProvider
> xTypeProvider
;
2382 // Did the object have an invocation itself?
2383 mxInvocation
= Reference
< XInvocation
>( x
, UNO_QUERY
);
2385 xTypeProvider
= Reference
< XTypeProvider
>( x
, UNO_QUERY
);
2387 if( mxInvocation
.is() )
2390 // get the ExactName
2391 mxExactNameInvocation
= Reference
< XExactName
>::query( mxInvocation
);
2393 // The remainder refers only to the introspection
2394 if( !xTypeProvider
.is() )
2396 bNeedIntrospection
= false;
2400 // Ignore introspection based members for COM objects to avoid
2401 // hiding of equally named COM symbols, e.g. XInvocation::getValue
2402 Reference
< oleautomation::XAutomationObject
> xAutomationObject( aUnoObj_
, UNO_QUERY
);
2403 if( xAutomationObject
.is() )
2404 bNativeCOMObject
= true;
2407 maTmpUnoObj
= aUnoObj_
;
2410 //*** Define the name ***
2411 sal_Bool bFatalError
= sal_True
;
2413 // Is it an interface or a struct?
2414 sal_Bool bSetClassName
= sal_False
;
2415 OUString aClassName_
;
2416 if( eType
== TypeClass_STRUCT
|| eType
== TypeClass_EXCEPTION
)
2419 bFatalError
= sal_False
;
2421 // insert the real name of the class
2422 if( aName_
.isEmpty() )
2424 aClassName_
= aUnoObj_
.getValueType().getTypeName();
2425 bSetClassName
= sal_True
;
2427 typelib_TypeDescription
* pDeclTD
= 0;
2428 typelib_typedescription_getByName( &pDeclTD
, maTmpUnoObj
.getValueTypeName().pData
);
2429 StructRefInfo
aThisStruct( maTmpUnoObj
, pDeclTD
, 0 );
2430 maStructInfo
.reset( new SbUnoStructRefObject( GetName(), aThisStruct
) );
2432 else if( eType
== TypeClass_INTERFACE
)
2434 // Interface works always through the type in the Any
2435 bFatalError
= sal_False
;
2438 SetClassName( aClassName_
);
2440 // Neither interface nor Struct -> FatalError
2443 StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION
);
2447 // pass the introspection primal on demand
2450 SbUnoObject::~SbUnoObject()
2455 // pass the introspection on Demand
2456 void SbUnoObject::doIntrospection( void )
2458 static Reference
< XIntrospection
> xIntrospection
;
2460 if( !bNeedIntrospection
)
2462 bNeedIntrospection
= false;
2464 if( !xIntrospection
.is() )
2466 // get the introspection service
2467 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
2468 xIntrospection
= Introspection::create( xContext
);
2471 // pass the introspection
2474 mxUnoAccess
= xIntrospection
->inspect( maTmpUnoObj
);
2476 catch( const RuntimeException
& e
)
2478 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2481 if( !mxUnoAccess
.is() )
2483 // #51475 mark to indicate an invalid object (no mxMaterialHolder)
2487 // get MaterialHolder from access
2488 mxMaterialHolder
= Reference
< XMaterialHolder
>::query( mxUnoAccess
);
2490 // get ExactName from access
2491 mxExactName
= Reference
< XExactName
>::query( mxUnoAccess
);
2497 // Start of a list of all SbUnoMethod-Instances
2498 static SbUnoMethod
* pFirst
= NULL
;
2500 void clearUnoMethodsForBasic( StarBASIC
* pBasic
)
2502 SbUnoMethod
* pMeth
= pFirst
;
2505 SbxObject
* pObject
= dynamic_cast< SbxObject
* >( pMeth
->GetParent() );
2508 StarBASIC
* pModBasic
= dynamic_cast< StarBASIC
* >( pObject
->GetParent() );
2509 if ( pModBasic
== pBasic
)
2511 // for now the solution is to remove the method from the list and to clear it,
2512 // but in case the element should be correctly transferred to another StarBASIC,
2513 // we should either set module parent to NULL without clearing it, or even
2514 // set the new StarBASIC as the parent of the module
2515 // pObject->SetParent( NULL );
2517 if( pMeth
== pFirst
)
2518 pFirst
= pMeth
->pNext
;
2519 else if( pMeth
->pPrev
)
2520 pMeth
->pPrev
->pNext
= pMeth
->pNext
;
2522 pMeth
->pNext
->pPrev
= pMeth
->pPrev
;
2524 pMeth
->pPrev
= NULL
;
2525 pMeth
->pNext
= NULL
;
2527 pMeth
->SbxValue::Clear();
2528 pObject
->SbxValue::Clear();
2530 // start from the beginning after object clearing, the cycle will end since the method is removed each time
2534 pMeth
= pMeth
->pNext
;
2537 pMeth
= pMeth
->pNext
;
2541 void clearUnoMethods( void )
2543 SbUnoMethod
* pMeth
= pFirst
;
2546 pMeth
->SbxValue::Clear();
2547 pMeth
= pMeth
->pNext
;
2552 SbUnoMethod::SbUnoMethod
2554 const OUString
& aName_
,
2555 SbxDataType eSbxType
,
2556 Reference
< XIdlMethod
> xUnoMethod_
,
2560 : SbxMethod( aName_
, eSbxType
)
2561 , mbInvocation( bInvocation
)
2562 , mbDirectInvocation( bDirect
)
2564 m_xUnoMethod
= xUnoMethod_
;
2565 pParamInfoSeq
= NULL
;
2567 // enregister the method in a list
2572 pNext
->pPrev
= this;
2575 SbUnoMethod::~SbUnoMethod()
2577 delete pParamInfoSeq
;
2579 if( this == pFirst
)
2582 pPrev
->pNext
= pNext
;
2584 pNext
->pPrev
= pPrev
;
2587 SbxInfo
* SbUnoMethod::GetInfo()
2589 if( !pInfo
&& m_xUnoMethod
.is() )
2591 SbiInstance
* pInst
= GetSbData()->pInst
;
2592 if( pInst
&& pInst
->IsCompatibility() )
2594 pInfo
= new SbxInfo();
2596 const Sequence
<ParamInfo
>& rInfoSeq
= getParamInfos();
2597 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2598 sal_uInt32 nParamCount
= rInfoSeq
.getLength();
2600 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
2602 const ParamInfo
& rInfo
= pParamInfos
[i
];
2603 OUString aParamName
= rInfo
.aName
;
2605 SbxDataType t
= SbxVARIANT
;
2606 sal_uInt16 nFlags_
= SBX_READ
;
2607 pInfo
->AddParam( aParamName
, t
, nFlags_
);
2614 const Sequence
<ParamInfo
>& SbUnoMethod::getParamInfos( void )
2616 if( !pParamInfoSeq
&& m_xUnoMethod
.is() )
2618 Sequence
<ParamInfo
> aTmp
= m_xUnoMethod
->getParameterInfos() ;
2619 pParamInfoSeq
= new Sequence
<ParamInfo
>( aTmp
);
2621 return *pParamInfoSeq
;
2624 SbUnoProperty::SbUnoProperty
2626 const OUString
& aName_
,
2627 SbxDataType eSbxType
,
2628 SbxDataType eRealSbxType
,
2629 const Property
& aUnoProp_
,
2634 : SbxProperty( aName_
, eSbxType
)
2635 , aUnoProp( aUnoProp_
)
2637 , mbInvocation( bInvocation
)
2638 , mRealType( eRealSbxType
)
2639 , mbUnoStruct( bUnoStruct
)
2641 // as needed establish an dummy array so that SbiRuntime::CheckArray() works
2642 static SbxArrayRef xDummyArray
= new SbxArray( SbxVARIANT
);
2643 if( eSbxType
& SbxARRAY
)
2644 PutObject( xDummyArray
);
2647 SbUnoProperty::~SbUnoProperty()
2651 SbxVariable
* SbUnoObject::Find( const OUString
& rName
, SbxClassType t
)
2653 static Reference
< XIdlMethod
> xDummyMethod
;
2654 static Property aDummyProp
;
2656 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
2658 if( bNeedIntrospection
)
2661 // New 1999-03-04: Create properties on demand. Therefore search now perIntrospectionAccess,
2662 // if a property or a method of the required name exist
2665 OUString
aUName( rName
);
2666 if( mxUnoAccess
.is() && !bNativeCOMObject
)
2668 if( mxExactName
.is() )
2670 OUString aUExactName
= mxExactName
->getExactName( aUName
);
2671 if( !aUExactName
.isEmpty() )
2673 aUName
= aUExactName
;
2676 if( mxUnoAccess
->hasProperty( aUName
, PropertyConcept::ALL
- PropertyConcept::DANGEROUS
) )
2678 const Property
& rProp
= mxUnoAccess
->
2679 getProperty( aUName
, PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
2681 // If the property could be void the type had to be set to Variant
2682 SbxDataType eSbxType
;
2683 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
2684 eSbxType
= SbxVARIANT
;
2686 eSbxType
= unoToSbxType( rProp
.Type
.getTypeClass() );
2688 SbxDataType eRealSbxType
= ( ( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
) ? unoToSbxType( rProp
.Type
.getTypeClass() ) : eSbxType
);
2689 // create the property and superimpose it
2690 SbUnoProperty
* pProp
= new SbUnoProperty( rProp
.Name
, eSbxType
, eRealSbxType
, rProp
, 0, false, ( rProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
2691 SbxVariableRef xVarRef
= pProp
;
2692 QuickInsert( (SbxVariable
*)xVarRef
);
2695 else if( mxUnoAccess
->hasMethod( aUName
,
2696 MethodConcept::ALL
- MethodConcept::DANGEROUS
) )
2698 // address the method
2699 const Reference
< XIdlMethod
>& rxMethod
= mxUnoAccess
->
2700 getMethod( aUName
, MethodConcept::ALL
- MethodConcept::DANGEROUS
);
2702 // create SbUnoMethod and superimpose it
2703 SbxVariableRef xMethRef
= new SbUnoMethod( rxMethod
->getName(),
2704 unoToSbxType( rxMethod
->getReturnType() ), rxMethod
, false );
2705 QuickInsert( (SbxVariable
*)xMethRef
);
2709 // Elsewise nothing would be found it had to be checked, if NameAccess is existent
2714 Reference
< XNameAccess
> xNameAccess( mxUnoAccess
->queryAdapter( ::getCppuType( (const Reference
< XPropertySet
> *)0 ) ), UNO_QUERY
);
2715 OUString
aUName2( rName
);
2717 if( xNameAccess
.is() && xNameAccess
->hasByName( aUName2
) )
2719 Any aAny
= xNameAccess
->getByName( aUName2
);
2721 // ATTENTION: Because of XNameAccess, the variable generated here
2722 // may not be included as a fixed property in the object and therefore
2723 // won't be stored anywhere.
2724 // If this leads to problems, it has to be created synthetically or
2725 // a class SbUnoNameAccessProperty, whose existence had to be checked
2726 // constantly and which were if necessary thrown away
2727 // if the name was not found anymore.
2728 pRes
= new SbxVariable( SbxVARIANT
);
2729 unoToSbxValue( pRes
, aAny
);
2732 catch( const NoSuchElementException
& e
)
2734 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2736 catch( const Exception
& )
2738 // Establish so that the exeption error will not be overwriten
2740 pRes
= new SbxVariable( SbxVARIANT
);
2742 implHandleAnyException( ::cppu::getCaughtException() );
2746 if( !pRes
&& mxInvocation
.is() )
2748 if( mxExactNameInvocation
.is() )
2750 OUString aUExactName
= mxExactNameInvocation
->getExactName( aUName
);
2751 if( !aUExactName
.isEmpty() )
2753 aUName
= aUExactName
;
2759 if( mxInvocation
->hasProperty( aUName
) )
2761 // create a property and superimpose it
2762 SbxVariableRef xVarRef
= new SbUnoProperty( aUName
, SbxVARIANT
, SbxVARIANT
, aDummyProp
, 0, true, false );
2763 QuickInsert( (SbxVariable
*)xVarRef
);
2766 else if( mxInvocation
->hasMethod( aUName
) )
2768 // create SbUnoMethode and superimpose it
2769 SbxVariableRef xMethRef
= new SbUnoMethod( aUName
, SbxVARIANT
, xDummyMethod
, true );
2770 QuickInsert( (SbxVariable
*)xMethRef
);
2775 Reference
< XDirectInvocation
> xDirectInvoke( mxInvocation
, UNO_QUERY
);
2776 if ( xDirectInvoke
.is() && xDirectInvoke
->hasMember( aUName
) )
2778 SbxVariableRef xMethRef
= new SbUnoMethod( aUName
, SbxVARIANT
, xDummyMethod
, true, true );
2779 QuickInsert( (SbxVariable
*)xMethRef
);
2785 catch( const RuntimeException
& e
)
2787 // Establish so that the exeption error will not be overwriten
2789 pRes
= new SbxVariable( SbxVARIANT
);
2791 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2796 // At the very end checking if the Dbg_-Properties are meant
2800 if( rName
.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES
) ||
2801 rName
.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES
) ||
2802 rName
.equalsIgnoreAsciiCase(ID_DBG_METHODS
) )
2805 implCreateDbgProperties();
2807 // Now they have to be found regular
2808 pRes
= SbxObject::Find( rName
, SbxCLASS_DONTCARE
);
2815 // help method to create the dbg_-Properties
2816 void SbUnoObject::implCreateDbgProperties( void )
2820 // Id == -1: display the implemented interfaces corresponding the ClassProvider
2821 SbxVariableRef xVarRef
= new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES
), SbxSTRING
, SbxSTRING
, aProp
, -1, false, false );
2822 QuickInsert( (SbxVariable
*)xVarRef
);
2824 // Id == -2: output the properties
2825 xVarRef
= new SbUnoProperty( OUString(ID_DBG_PROPERTIES
), SbxSTRING
, SbxSTRING
, aProp
, -2, false, false );
2826 QuickInsert( (SbxVariable
*)xVarRef
);
2828 // Id == -3: output the Methods
2829 xVarRef
= new SbUnoProperty( OUString(ID_DBG_METHODS
), SbxSTRING
, SbxSTRING
, aProp
, -3, false, false );
2830 QuickInsert( (SbxVariable
*)xVarRef
);
2833 void SbUnoObject::implCreateAll( void )
2835 // throw away all existing methods and properties
2836 pMethods
= new SbxArray
;
2837 pProps
= new SbxArray
;
2839 if( bNeedIntrospection
) doIntrospection();
2841 // get instrospection
2842 Reference
< XIntrospectionAccess
> xAccess
= mxUnoAccess
;
2843 if( !xAccess
.is() || bNativeCOMObject
)
2845 if( mxInvocation
.is() )
2846 xAccess
= mxInvocation
->getIntrospection();
2847 else if( bNativeCOMObject
)
2853 // Establish properties
2854 Sequence
<Property
> props
= xAccess
->getProperties( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
2855 sal_uInt32 nPropCount
= props
.getLength();
2856 const Property
* pProps_
= props
.getConstArray();
2859 for( i
= 0 ; i
< nPropCount
; i
++ )
2861 const Property
& rProp
= pProps_
[ i
];
2863 // If the property could be void the type had to be set to Variant
2864 SbxDataType eSbxType
;
2865 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
2866 eSbxType
= SbxVARIANT
;
2868 eSbxType
= unoToSbxType( rProp
.Type
.getTypeClass() );
2870 SbxDataType eRealSbxType
= ( ( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
) ? unoToSbxType( rProp
.Type
.getTypeClass() ) : eSbxType
);
2871 // Create property and superimpose it
2872 SbxVariableRef xVarRef
= new SbUnoProperty( rProp
.Name
, eSbxType
, eRealSbxType
, rProp
, i
, false, ( rProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
2873 QuickInsert( (SbxVariable
*)xVarRef
);
2876 // Create Dbg_-Properties
2877 implCreateDbgProperties();
2880 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods
2881 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
2882 sal_uInt32 nMethCount
= aMethodSeq
.getLength();
2883 const Reference
< XIdlMethod
>* pMethods_
= aMethodSeq
.getConstArray();
2884 for( i
= 0 ; i
< nMethCount
; i
++ )
2887 const Reference
< XIdlMethod
>& rxMethod
= pMethods_
[i
];
2889 // Create SbUnoMethod and superimpose it
2890 SbxVariableRef xMethRef
= new SbUnoMethod
2891 ( rxMethod
->getName(), unoToSbxType( rxMethod
->getReturnType() ), rxMethod
, false );
2892 QuickInsert( (SbxVariable
*)xMethRef
);
2898 Any
SbUnoObject::getUnoAny( void )
2901 if( bNeedIntrospection
) doIntrospection();
2902 if ( maStructInfo
.get() )
2903 aRetAny
= maTmpUnoObj
;
2904 else if( mxMaterialHolder
.is() )
2905 aRetAny
= mxMaterialHolder
->getMaterial();
2906 else if( mxInvocation
.is() )
2907 aRetAny
<<= mxInvocation
;
2911 // help method to create an Uno-Struct per CoreReflection
2912 SbUnoObject
* Impl_CreateUnoStruct( const OUString
& aClassName
)
2914 // get CoreReflection
2915 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
2916 if( !xCoreReflection
.is() )
2919 // search for the class
2920 Reference
< XIdlClass
> xClass
;
2921 Reference
< XHierarchicalNameAccess
> xHarryName
=
2922 getCoreReflection_HierarchicalNameAccess_Impl();
2923 if( xHarryName
.is() && xHarryName
->hasByHierarchicalName( aClassName
) )
2924 xClass
= xCoreReflection
->forName( aClassName
);
2928 // Is it realy a struct?
2929 TypeClass eType
= xClass
->getTypeClass();
2930 if ( ( eType
!= TypeClass_STRUCT
) && ( eType
!= TypeClass_EXCEPTION
) )
2933 // create an instance
2935 xClass
->createObject( aNewAny
);
2936 // make a SbUnoObject out of it
2937 SbUnoObject
* pUnoObj
= new SbUnoObject( aClassName
, aNewAny
);
2942 // Factory-Class to create Uno-Structs per DIM AS NEW
2943 SbxBase
* SbUnoFactory::Create( sal_uInt16
, sal_uInt32
)
2945 // Via SbxId nothing works in Uno
2949 SbxObject
* SbUnoFactory::CreateObject( const OUString
& rClassName
)
2951 return Impl_CreateUnoStruct( rClassName
);
2955 // Provisional interface for the UNO-Connection
2956 // Deliver a SbxObject, that wrap an Uno-Interface
2957 SbxObjectRef
GetSbUnoObject( const OUString
& aName
, const Any
& aUnoObj_
)
2959 return new SbUnoObject( aName
, aUnoObj_
);
2962 // Force creation of all properties for debugging
2963 void createAllObjectProperties( SbxObject
* pObj
)
2968 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
2969 SbUnoStructRefObject
* pUnoStructObj
= PTR_CAST(SbUnoStructRefObject
,pObj
);
2972 pUnoObj
->createAllProperties();
2974 else if ( pUnoStructObj
)
2976 pUnoStructObj
->createAllProperties();
2980 pObj
->GetAll( SbxCLASS_DONTCARE
);
2985 void RTL_Impl_CreateUnoStruct( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
2990 // We need 1 parameter minimum
2991 if ( rPar
.Count() < 2 )
2993 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2997 // get the name of the class of the struct
2998 OUString aClassName
= rPar
.Get(1)->GetOUString();
3000 // try to create Struct with the same name
3001 SbUnoObjectRef xUnoObj
= Impl_CreateUnoStruct( aClassName
);
3006 // return the object
3007 SbxVariableRef refVar
= rPar
.Get(0);
3008 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3011 void RTL_Impl_CreateUnoService( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3016 // We need 1 Parameter minimum
3017 if ( rPar
.Count() < 2 )
3019 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3023 // get the name of the class of the struct
3024 OUString aServiceName
= rPar
.Get(1)->GetOUString();
3026 // search for the service and instatiate it
3027 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3028 Reference
< XInterface
> xInterface
;
3031 xInterface
= xFactory
->createInstance( aServiceName
);
3033 catch( const Exception
& )
3035 implHandleAnyException( ::cppu::getCaughtException() );
3038 SbxVariableRef refVar
= rPar
.Get(0);
3039 if( xInterface
.is() )
3042 aAny
<<= xInterface
;
3044 // Create a SbUnoObject out of it and return it
3045 SbUnoObjectRef xUnoObj
= new SbUnoObject( aServiceName
, aAny
);
3046 if( xUnoObj
->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID
)
3048 // return the object
3049 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3053 refVar
->PutObject( NULL
);
3058 refVar
->PutObject( NULL
);
3062 void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3067 // We need 2 parameter minimum
3068 if ( rPar
.Count() < 3 )
3070 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3074 // get the name of the class of the struct
3075 OUString aServiceName
= rPar
.Get(1)->GetOUString();
3076 Any aArgAsAny
= sbxToUnoValue( rPar
.Get(2),
3077 getCppuType( (Sequence
<Any
>*)0 ) );
3078 Sequence
< Any
> aArgs
;
3079 aArgAsAny
>>= aArgs
;
3081 // search for the service and instatiate it
3082 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3083 Reference
< XInterface
> xInterface
;
3086 xInterface
= xFactory
->createInstanceWithArguments( aServiceName
, aArgs
);
3088 catch( const Exception
& )
3090 implHandleAnyException( ::cppu::getCaughtException() );
3093 SbxVariableRef refVar
= rPar
.Get(0);
3094 if( xInterface
.is() )
3097 aAny
<<= xInterface
;
3099 // Create a SbUnoObject out of it and return it
3100 SbUnoObjectRef xUnoObj
= new SbUnoObject( aServiceName
, aAny
);
3101 if( xUnoObj
->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID
)
3103 // return the object
3104 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3108 refVar
->PutObject( NULL
);
3113 refVar
->PutObject( NULL
);
3117 void RTL_Impl_GetProcessServiceManager( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3122 SbxVariableRef refVar
= rPar
.Get(0);
3124 // get the global service manager
3125 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3129 // Create a SbUnoObject out of it and return it
3130 SbUnoObjectRef xUnoObj
= new SbUnoObject( OUString( "ProcessServiceManager" ), aAny
);
3131 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3134 void RTL_Impl_HasInterfaces( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3139 // We need 2 parameter minimum
3140 sal_uInt16 nParCount
= rPar
.Count();
3143 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3147 // variable for the return value
3148 SbxVariableRef refVar
= rPar
.Get(0);
3149 refVar
->PutBool( sal_False
);
3151 // get the Uno-Object
3152 SbxBaseRef pObj
= (SbxBase
*)rPar
.Get( 1 )->GetObject();
3153 if( !(pObj
&& pObj
->ISA(SbUnoObject
)) )
3157 Any aAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
3158 TypeClass eType
= aAny
.getValueType().getTypeClass();
3159 if( eType
!= TypeClass_INTERFACE
)
3163 // get the interface out of the Any
3164 Reference
< XInterface
> x
= *(Reference
< XInterface
>*)aAny
.getValue();
3166 // get CoreReflection
3167 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
3168 if( !xCoreReflection
.is() )
3172 for( sal_uInt16 i
= 2 ; i
< nParCount
; i
++ )
3174 // get the name of the interface of the struct
3175 OUString aIfaceName
= rPar
.Get( i
)->GetOUString();
3177 // search for the class
3178 Reference
< XIdlClass
> xClass
= xCoreReflection
->forName( aIfaceName
);
3183 // check if the interface will be supported
3184 OUString aClassName
= xClass
->getName();
3185 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
3186 if( !x
->queryInterface( aClassType
).hasValue() )
3192 // Every thing works; then return TRUE
3193 refVar
->PutBool( sal_True
);
3196 void RTL_Impl_IsUnoStruct( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3201 // We need 1 parameter minimum
3202 if ( rPar
.Count() < 2 )
3204 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3208 // variable for the return value
3209 SbxVariableRef refVar
= rPar
.Get(0);
3210 refVar
->PutBool( sal_False
);
3212 // get the Uno-Object
3213 SbxVariableRef xParam
= rPar
.Get( 1 );
3214 if( !xParam
->IsObject() )
3218 SbxBaseRef pObj
= (SbxBase
*)rPar
.Get( 1 )->GetObject();
3219 if( !(pObj
&& pObj
->ISA(SbUnoObject
)) )
3223 Any aAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
3224 TypeClass eType
= aAny
.getValueType().getTypeClass();
3225 if( eType
== TypeClass_STRUCT
)
3227 refVar
->PutBool( sal_True
);
3232 void RTL_Impl_EqualUnoObjects( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
3237 if ( rPar
.Count() < 3 )
3239 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3243 // variable for the return value
3244 SbxVariableRef refVar
= rPar
.Get(0);
3245 refVar
->PutBool( sal_False
);
3247 // get the Uno-Objects
3248 SbxVariableRef xParam1
= rPar
.Get( 1 );
3249 if( !xParam1
->IsObject() )
3253 SbxBaseRef pObj1
= (SbxBase
*)xParam1
->GetObject();
3254 if( !(pObj1
&& pObj1
->ISA(SbUnoObject
)) )
3258 Any aAny1
= ((SbUnoObject
*)(SbxBase
*)pObj1
)->getUnoAny();
3259 TypeClass eType1
= aAny1
.getValueType().getTypeClass();
3260 if( eType1
!= TypeClass_INTERFACE
)
3264 Reference
< XInterface
> x1
;
3267 SbxVariableRef xParam2
= rPar
.Get( 2 );
3268 if( !xParam2
->IsObject() )
3272 SbxBaseRef pObj2
= (SbxBase
*)xParam2
->GetObject();
3273 if( !(pObj2
&& pObj2
->ISA(SbUnoObject
)) )
3277 Any aAny2
= ((SbUnoObject
*)(SbxBase
*)pObj2
)->getUnoAny();
3278 TypeClass eType2
= aAny2
.getValueType().getTypeClass();
3279 if( eType2
!= TypeClass_INTERFACE
)
3283 Reference
< XInterface
> x2
;
3288 refVar
->PutBool( sal_True
);
3293 // helper wrapper function to interact with TypeProvider and
3294 // XTypeDescriptionEnumerationAccess.
3295 // if it fails for whatever reason
3296 // returned Reference<> be null e.g. .is() will be false
3298 Reference
< XTypeDescriptionEnumeration
> getTypeDescriptorEnumeration( const OUString
& sSearchRoot
,
3299 const Sequence
< TypeClass
>& types
,
3300 TypeDescriptionSearchDepth depth
)
3302 Reference
< XTypeDescriptionEnumeration
> xEnum
;
3303 Reference
< XTypeDescriptionEnumerationAccess
> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY
);
3304 if ( xTypeEnumAccess
.is() )
3308 xEnum
= xTypeEnumAccess
->createTypeDescriptionEnumeration(
3309 sSearchRoot
, types
, depth
);
3311 catch(const NoSuchTypeNameException
& /*nstne*/ ) {}
3312 catch(const InvalidTypeNameException
& /*nstne*/ ) {}
3317 typedef boost::unordered_map
< OUString
, Any
, OUStringHash
, ::std::equal_to
< OUString
> > VBAConstantsHash
;
3320 VBAConstantHelper::instance()
3322 static VBAConstantHelper aHelper
;
3326 void VBAConstantHelper::init()
3330 Sequence
< TypeClass
> types(1);
3331 types
[ 0 ] = TypeClass_CONSTANTS
;
3332 Reference
< XTypeDescriptionEnumeration
> xEnum
= getTypeDescriptorEnumeration( OUString(defaultNameSpace
), types
, TypeDescriptionSearchDepth_INFINITE
);
3338 while ( xEnum
->hasMoreElements() )
3340 Reference
< XConstantsTypeDescription
> xConstants( xEnum
->nextElement(), UNO_QUERY
);
3341 if ( xConstants
.is() )
3343 // store constant group name
3344 OUString sFullName
= xConstants
->getName();
3345 sal_Int32 indexLastDot
= sFullName
.lastIndexOf('.');
3346 OUString
sLeafName( sFullName
);
3347 if ( indexLastDot
> -1 )
3349 sLeafName
= sFullName
.copy( indexLastDot
+ 1);
3351 aConstCache
.push_back( sLeafName
); // assume constant group names are unique
3352 Sequence
< Reference
< XConstantTypeDescription
> > aConsts
= xConstants
->getConstants();
3353 Reference
< XConstantTypeDescription
>* pSrc
= aConsts
.getArray();
3354 sal_Int32 nLen
= aConsts
.getLength();
3355 for ( sal_Int32 index
=0; index
<nLen
; ++pSrc
, ++index
)
3357 // store constant member name
3358 Reference
< XConstantTypeDescription
>& rXConst
= *pSrc
;
3359 sFullName
= rXConst
->getName();
3360 indexLastDot
= sFullName
.lastIndexOf('.');
3361 sLeafName
= sFullName
;
3362 if ( indexLastDot
> -1 )
3364 sLeafName
= sFullName
.copy( indexLastDot
+ 1);
3366 aConstHash
[ sLeafName
.toAsciiLowerCase() ] = rXConst
->getConstantValue();
3375 VBAConstantHelper::isVBAConstantType( const OUString
& rName
)
3378 bool bConstant
= false;
3379 OUString
sKey( rName
);
3380 VBAConstantsVector::const_iterator it
= aConstCache
.begin();
3382 for( ; it
!= aConstCache
.end(); ++it
)
3384 if( sKey
.equalsIgnoreAsciiCase( *it
) )
3394 VBAConstantHelper::getVBAConstant( const OUString
& rName
)
3396 SbxVariable
* pConst
= NULL
;
3399 OUString
sKey( rName
);
3401 VBAConstantsHash::const_iterator it
= aConstHash
.find( sKey
.toAsciiLowerCase() );
3403 if ( it
!= aConstHash
.end() )
3405 pConst
= new SbxVariable( SbxVARIANT
);
3406 pConst
->SetName( rName
);
3407 unoToSbxValue( pConst
, it
->second
);
3413 // Function to search for a global identifier in the
3414 // UnoScope and to wrap it for Sbx
3415 SbUnoClass
* findUnoClass( const OUString
& rName
)
3417 // #105550 Check if module exists
3418 SbUnoClass
* pUnoClass
= NULL
;
3420 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3421 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3423 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3424 Reference
< XTypeDescription
> xTypeDesc
;
3427 if( xTypeDesc
.is() )
3429 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3430 if( eTypeClass
== TypeClass_MODULE
|| eTypeClass
== TypeClass_CONSTANTS
)
3432 pUnoClass
= new SbUnoClass( rName
);
3439 SbxVariable
* SbUnoClass::Find( const OUString
& rName
, SbxClassType
)
3441 SbxVariable
* pRes
= SbxObject::Find( rName
, SbxCLASS_VARIABLE
);
3443 // If nothing were located the submodule isn't known yet
3446 // If it is already a class, ask for the field
3450 OUString
aUStr( rName
);
3451 Reference
< XIdlField
> xField
= m_xClass
->getField( aUStr
);
3452 Reference
< XIdlClass
> xClass
;
3458 aAny
= xField
->get( aAny
);
3461 pRes
= new SbxVariable( SbxVARIANT
);
3462 pRes
->SetName( rName
);
3463 unoToSbxValue( pRes
, aAny
);
3465 catch( const Exception
& )
3467 implHandleAnyException( ::cppu::getCaughtException() );
3473 // expand fully qualified name
3474 OUString aNewName
= GetName();
3478 // get CoreReflection
3479 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
3480 if( xCoreReflection
.is() )
3482 // Is it a constant?
3483 Reference
< XHierarchicalNameAccess
> xHarryName( xCoreReflection
, UNO_QUERY
);
3484 if( xHarryName
.is() )
3488 Any aValue
= xHarryName
->getByHierarchicalName( aNewName
);
3489 TypeClass eType
= aValue
.getValueType().getTypeClass();
3491 // Interface located? Then it is a class
3492 if( eType
== TypeClass_INTERFACE
)
3494 Reference
< XInterface
> xIface
= *(Reference
< XInterface
>*)aValue
.getValue();
3495 Reference
< XIdlClass
> xClass( xIface
, UNO_QUERY
);
3498 pRes
= new SbxVariable( SbxVARIANT
);
3499 SbxObjectRef xWrapper
= (SbxObject
*)new SbUnoClass( aNewName
, xClass
);
3500 pRes
->PutObject( xWrapper
);
3505 pRes
= new SbxVariable( SbxVARIANT
);
3506 unoToSbxValue( pRes
, aValue
);
3509 catch( const NoSuchElementException
& )
3514 // Otherwise take it again as class
3517 SbUnoClass
* pNewClass
= findUnoClass( aNewName
);
3520 pRes
= new SbxVariable( SbxVARIANT
);
3521 SbxObjectRef xWrapper
= (SbxObject
*)pNewClass
;
3522 pRes
->PutObject( xWrapper
);
3529 SbUnoService
* pUnoService
= findUnoService( aNewName
);
3532 pRes
= new SbxVariable( SbxVARIANT
);
3533 SbxObjectRef xWrapper
= (SbxObject
*)pUnoService
;
3534 pRes
->PutObject( xWrapper
);
3538 // An UNO singleton?
3541 SbUnoSingleton
* pUnoSingleton
= findUnoSingleton( aNewName
);
3544 pRes
= new SbxVariable( SbxVARIANT
);
3545 SbxObjectRef xWrapper
= (SbxObject
*)pUnoSingleton
;
3546 pRes
->PutObject( xWrapper
);
3554 pRes
->SetName( rName
);
3556 // Insert variable, so that it could be found later
3557 QuickInsert( pRes
);
3559 // Take us out as listener at once,
3560 // the values are all constant
3561 if( pRes
->IsBroadcaster() )
3562 EndListening( pRes
->GetBroadcaster(), sal_True
);
3569 SbUnoService
* findUnoService( const OUString
& rName
)
3571 SbUnoService
* pSbUnoService
= NULL
;
3573 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3574 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3576 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3577 Reference
< XTypeDescription
> xTypeDesc
;
3580 if( xTypeDesc
.is() )
3582 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3583 if( eTypeClass
== TypeClass_SERVICE
)
3585 Reference
< XServiceTypeDescription2
> xServiceTypeDesc( xTypeDesc
, UNO_QUERY
);
3586 if( xServiceTypeDesc
.is() )
3587 pSbUnoService
= new SbUnoService( rName
, xServiceTypeDesc
);
3591 return pSbUnoService
;
3594 SbxVariable
* SbUnoService::Find( const OUString
& rName
, SbxClassType
)
3596 SbxVariable
* pRes
= SbxObject::Find( rName
, SbxCLASS_METHOD
);
3600 // If it is already a class ask for a field
3601 if( m_bNeedsInit
&& m_xServiceTypeDesc
.is() )
3603 m_bNeedsInit
= false;
3605 Sequence
< Reference
< XServiceConstructorDescription
> > aSCDSeq
= m_xServiceTypeDesc
->getConstructors();
3606 const Reference
< XServiceConstructorDescription
>* pCtorSeq
= aSCDSeq
.getConstArray();
3607 int nCtorCount
= aSCDSeq
.getLength();
3608 for( int i
= 0 ; i
< nCtorCount
; ++i
)
3610 Reference
< XServiceConstructorDescription
> xCtor
= pCtorSeq
[i
];
3612 OUString
aName( xCtor
->getName() );
3613 if( aName
.isEmpty() )
3615 if( xCtor
->isDefaultConstructor() )
3617 aName
= OUString("create");
3621 if( !aName
.isEmpty() )
3623 // Create and insert SbUnoServiceCtor
3624 SbxVariableRef xSbCtorRef
= new SbUnoServiceCtor( aName
, xCtor
);
3625 QuickInsert( (SbxVariable
*)xSbCtorRef
);
3628 pRes
= SbxObject::Find( rName
, SbxCLASS_METHOD
);
3635 void SbUnoService::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
3636 const SfxHint
& rHint
, const TypeId
& rHintType
)
3638 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
3641 SbxVariable
* pVar
= pHint
->GetVar();
3642 SbxArray
* pParams
= pVar
->GetParameters();
3643 SbUnoServiceCtor
* pUnoCtor
= PTR_CAST(SbUnoServiceCtor
,pVar
);
3644 if( pUnoCtor
&& pHint
->GetId() == SBX_HINT_DATAWANTED
)
3646 // Parameter count -1 because of Param0 == this
3647 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
3649 sal_Bool bOutParams
= sal_False
;
3651 Reference
< XServiceConstructorDescription
> xCtor
= pUnoCtor
->getServiceCtorDesc();
3652 Sequence
< Reference
< XParameter
> > aParameterSeq
= xCtor
->getParameters();
3653 const Reference
< XParameter
>* pParameterSeq
= aParameterSeq
.getConstArray();
3654 sal_uInt32 nUnoParamCount
= aParameterSeq
.getLength();
3656 // Default: Ignore not needed parameters
3657 bool bParameterError
= false;
3659 // Is the last parameter a rest parameter?
3660 bool bRestParameterMode
= false;
3661 if( nUnoParamCount
> 0 )
3663 Reference
< XParameter
> xLastParam
= pParameterSeq
[ nUnoParamCount
- 1 ];
3664 if( xLastParam
.is() )
3666 if( xLastParam
->isRestParameter() )
3667 bRestParameterMode
= true;
3671 // Too many parameters with context as first parameter?
3672 sal_uInt16 nSbxParameterOffset
= 1;
3673 sal_uInt16 nParameterOffsetByContext
= 0;
3674 Reference
< XComponentContext
> xFirstParamContext
;
3675 if( nParamCount
> nUnoParamCount
)
3677 // Check if first parameter is a context and use it
3678 // then in createInstanceWithArgumentsAndContext
3679 Any aArg0
= sbxToUnoValue( pParams
->Get( nSbxParameterOffset
) );
3680 if( (aArg0
>>= xFirstParamContext
) && xFirstParamContext
.is() )
3681 nParameterOffsetByContext
= 1;
3684 sal_uInt32 nEffectiveParamCount
= nParamCount
- nParameterOffsetByContext
;
3685 sal_uInt32 nAllocParamCount
= nEffectiveParamCount
;
3686 if( nEffectiveParamCount
> nUnoParamCount
)
3688 if( !bRestParameterMode
)
3690 nEffectiveParamCount
= nUnoParamCount
;
3691 nAllocParamCount
= nUnoParamCount
;
3694 // Not enough parameters?
3695 else if( nUnoParamCount
> nEffectiveParamCount
)
3697 // RestParameterMode only helps if one (the last) parameter is missing
3698 int nDiff
= nUnoParamCount
- nEffectiveParamCount
;
3699 if( !bRestParameterMode
|| nDiff
> 1 )
3701 bParameterError
= true;
3702 StarBASIC::Error( SbERR_NOT_OPTIONAL
);
3706 if( !bParameterError
)
3708 if( nAllocParamCount
> 0 )
3710 args
.realloc( nAllocParamCount
);
3711 Any
* pAnyArgs
= args
.getArray();
3712 for( sal_uInt32 i
= 0 ; i
< nEffectiveParamCount
; i
++ )
3714 sal_uInt16 iSbx
= (sal_uInt16
)(i
+ nSbxParameterOffset
+ nParameterOffsetByContext
);
3716 // bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
3717 Reference
< XParameter
> xParam
;
3718 if( i
< nUnoParamCount
)
3720 xParam
= pParameterSeq
[i
];
3724 Reference
< XTypeDescription
> xParamTypeDesc
= xParam
->getType();
3725 if( !xParamTypeDesc
.is() )
3727 com::sun::star::uno::Type
aType( xParamTypeDesc
->getTypeClass(), xParamTypeDesc
->getName() );
3729 // sbx paramter needs offset 1
3730 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( iSbx
), aType
);
3732 // Check for out parameter if not already done
3735 if( xParam
->isOut() )
3736 bOutParams
= sal_True
;
3741 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( iSbx
) );
3746 // "Call" ctor using createInstanceWithArgumentsAndContext
3747 Reference
< XComponentContext
> xContext(
3748 xFirstParamContext
.is()
3749 ? xFirstParamContext
3750 : comphelper::getProcessComponentContext() );
3751 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
3754 OUString aServiceName
= GetName();
3755 Reference
< XInterface
> xRet
;
3758 xRet
= xServiceMgr
->createInstanceWithArgumentsAndContext( aServiceName
, args
, xContext
);
3760 catch( const Exception
& )
3762 implHandleAnyException( ::cppu::getCaughtException() );
3765 unoToSbxValue( pVar
, aRetAny
);
3767 // Copy back out parameters?
3770 const Any
* pAnyArgs
= args
.getConstArray();
3772 for( sal_uInt32 j
= 0 ; j
< nUnoParamCount
; j
++ )
3774 Reference
< XParameter
> xParam
= pParameterSeq
[j
];
3778 if( xParam
->isOut() )
3779 unoToSbxValue( (SbxVariable
*)pParams
->Get( (sal_uInt16
)(j
+1) ), pAnyArgs
[ j
] );
3785 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
3791 static SbUnoServiceCtor
* pFirstCtor
= NULL
;
3793 void clearUnoServiceCtors( void )
3795 SbUnoServiceCtor
* pCtor
= pFirstCtor
;
3798 pCtor
->SbxValue::Clear();
3799 pCtor
= pCtor
->pNext
;
3803 SbUnoServiceCtor::SbUnoServiceCtor( const OUString
& aName_
, Reference
< XServiceConstructorDescription
> xServiceCtorDesc
)
3804 : SbxMethod( aName_
, SbxOBJECT
)
3805 , m_xServiceCtorDesc( xServiceCtorDesc
)
3809 SbUnoServiceCtor::~SbUnoServiceCtor()
3813 SbxInfo
* SbUnoServiceCtor::GetInfo()
3815 SbxInfo
* pRet
= NULL
;
3821 SbUnoSingleton
* findUnoSingleton( const OUString
& rName
)
3823 SbUnoSingleton
* pSbUnoSingleton
= NULL
;
3825 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3826 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3828 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3829 Reference
< XTypeDescription
> xTypeDesc
;
3832 if( xTypeDesc
.is() )
3834 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3835 if( eTypeClass
== TypeClass_SINGLETON
)
3837 Reference
< XSingletonTypeDescription
> xSingletonTypeDesc( xTypeDesc
, UNO_QUERY
);
3838 if( xSingletonTypeDesc
.is() )
3839 pSbUnoSingleton
= new SbUnoSingleton( rName
, xSingletonTypeDesc
);
3843 return pSbUnoSingleton
;
3846 SbUnoSingleton::SbUnoSingleton( const OUString
& aName_
,
3847 const Reference
< XSingletonTypeDescription
>& xSingletonTypeDesc
)
3848 : SbxObject( aName_
)
3849 , m_xSingletonTypeDesc( xSingletonTypeDesc
)
3851 SbxVariableRef xGetMethodRef
= new SbxMethod( OUString( "get" ), SbxOBJECT
);
3852 QuickInsert( (SbxVariable
*)xGetMethodRef
);
3855 void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
3856 const SfxHint
& rHint
, const TypeId
& rHintType
)
3858 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
3861 SbxVariable
* pVar
= pHint
->GetVar();
3862 SbxArray
* pParams
= pVar
->GetParameters();
3863 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
3864 sal_uInt32 nAllowedParamCount
= 1;
3866 Reference
< XComponentContext
> xContextToUse
;
3867 if( nParamCount
> 0 )
3869 // Check if first parameter is a context and use it then
3870 Reference
< XComponentContext
> xFirstParamContext
;
3871 Any aArg1
= sbxToUnoValue( pParams
->Get( 1 ) );
3872 if( (aArg1
>>= xFirstParamContext
) && xFirstParamContext
.is() )
3873 xContextToUse
= xFirstParamContext
;
3876 if( !xContextToUse
.is() )
3878 xContextToUse
= comphelper::getProcessComponentContext();
3879 --nAllowedParamCount
;
3882 if( nParamCount
> nAllowedParamCount
)
3884 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3889 if( xContextToUse
.is() )
3891 OUString
aSingletonName( "/singletons/" );
3892 aSingletonName
+= GetName();
3893 Reference
< XInterface
> xRet
;
3894 xContextToUse
->getValueByName( aSingletonName
) >>= xRet
;
3897 unoToSbxValue( pVar
, aRetAny
);
3901 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
3906 //========================================================================
3908 // Implementation of an EventAttacher-drawn AllListener, which
3909 // solely transmits several events to an general AllListener
3910 class BasicAllListener_Impl
: public BasicAllListenerHelper
3912 virtual void firing_impl(const AllEventObject
& Event
, Any
* pRet
);
3915 SbxObjectRef xSbxObj
;
3916 OUString aPrefixName
;
3918 BasicAllListener_Impl( const OUString
& aPrefixName
);
3919 ~BasicAllListener_Impl();
3921 // Methods of XAllListener
3922 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw ( RuntimeException
);
3923 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw ( RuntimeException
);
3925 // Methods of XEventListener
3926 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw ( RuntimeException
);
3930 //========================================================================
3931 BasicAllListener_Impl::BasicAllListener_Impl(const OUString
& aPrefixName_
)
3932 : aPrefixName( aPrefixName_
)
3936 //========================================================================
3937 BasicAllListener_Impl::~BasicAllListener_Impl()
3941 //========================================================================
3943 void BasicAllListener_Impl::firing_impl( const AllEventObject
& Event
, Any
* pRet
)
3945 SolarMutexGuard guard
;
3949 OUString aMethodName
= aPrefixName
;
3950 aMethodName
= aMethodName
+ Event
.MethodName
;
3952 SbxVariable
* pP
= xSbxObj
;
3953 while( pP
->GetParent() )
3955 pP
= pP
->GetParent();
3956 StarBASIC
* pLib
= PTR_CAST(StarBASIC
,pP
);
3959 // Create in a Basic Array
3960 SbxArrayRef xSbxArray
= new SbxArray( SbxVARIANT
);
3961 const Any
* pArgs
= Event
.Arguments
.getConstArray();
3962 sal_Int32 nCount
= Event
.Arguments
.getLength();
3963 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
3966 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
3967 unoToSbxValue( (SbxVariable
*)xVar
, pArgs
[i
] );
3968 xSbxArray
->Put( xVar
, sal::static_int_cast
< sal_uInt16
>(i
+1) );
3971 pLib
->Call( aMethodName
, xSbxArray
);
3973 // get the return value from the Param-Array, if requestet
3976 SbxVariable
* pVar
= xSbxArray
->Get( 0 );
3979 // #95792 Avoid a second call
3980 sal_uInt16 nFlags
= pVar
->GetFlags();
3981 pVar
->SetFlag( SBX_NO_BROADCAST
);
3982 *pRet
= sbxToUnoValueImpl( pVar
);
3983 pVar
->SetFlags( nFlags
);
3993 // Methods of Listener
3994 void BasicAllListener_Impl::firing( const AllEventObject
& Event
) throw ( RuntimeException
)
3996 firing_impl( Event
, NULL
);
3999 Any
BasicAllListener_Impl::approveFiring( const AllEventObject
& Event
) throw ( RuntimeException
)
4002 firing_impl( Event
, &aRetAny
);
4006 //========================================================================
4007 // Methods of XEventListener
4008 void BasicAllListener_Impl ::disposing(const EventObject
& ) throw ( RuntimeException
)
4010 SolarMutexGuard guard
;
4017 //*************************************************************************
4018 // class InvocationToAllListenerMapper
4019 // helper class to map XInvocation to XAllListener (also in project eventattacher!)
4020 //*************************************************************************
4021 class InvocationToAllListenerMapper
: public WeakImplHelper1
< XInvocation
>
4024 InvocationToAllListenerMapper( const Reference
< XIdlClass
>& ListenerType
,
4025 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
);
4028 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection(void) throw( RuntimeException
);
4029 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
4030 throw( IllegalArgumentException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
4031 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
)
4032 throw( UnknownPropertyException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
4033 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) throw( UnknownPropertyException
, RuntimeException
);
4034 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) throw( RuntimeException
);
4035 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) throw( RuntimeException
);
4038 Reference
< XIdlReflection
> m_xCoreReflection
;
4039 Reference
< XAllListener
> m_xAllListener
;
4040 Reference
< XIdlClass
> m_xListenerType
;
4045 // Function to replace AllListenerAdapterService::createAllListerAdapter
4046 Reference
< XInterface
> createAllListenerAdapter
4048 const Reference
< XInvocationAdapterFactory2
>& xInvocationAdapterFactory
,
4049 const Reference
< XIdlClass
>& xListenerType
,
4050 const Reference
< XAllListener
>& xListener
,
4054 Reference
< XInterface
> xAdapter
;
4055 if( xInvocationAdapterFactory
.is() && xListenerType
.is() && xListener
.is() )
4057 Reference
< XInvocation
> xInvocationToAllListenerMapper
=
4058 (XInvocation
*)new InvocationToAllListenerMapper( xListenerType
, xListener
, Helper
);
4059 Type
aListenerType( xListenerType
->getTypeClass(), xListenerType
->getName() );
4060 Sequence
<Type
> arg2(1);
4061 arg2
[0] = aListenerType
;
4062 xAdapter
= xInvocationAdapterFactory
->createAdapter( xInvocationToAllListenerMapper
, arg2
);
4068 //--------------------------------------------------------------------------------------------------
4069 // InvocationToAllListenerMapper
4070 InvocationToAllListenerMapper::InvocationToAllListenerMapper
4071 ( const Reference
< XIdlClass
>& ListenerType
, const Reference
< XAllListener
>& AllListener
, const Any
& Helper
)
4072 : m_xAllListener( AllListener
)
4073 , m_xListenerType( ListenerType
)
4074 , m_Helper( Helper
)
4078 //*************************************************************************
4079 Reference
< XIntrospectionAccess
> SAL_CALL
InvocationToAllListenerMapper::getIntrospection(void)
4080 throw( RuntimeException
)
4082 return Reference
< XIntrospectionAccess
>();
4085 //*************************************************************************
4086 Any SAL_CALL
InvocationToAllListenerMapper::invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
,
4087 Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
4088 throw( IllegalArgumentException
, CannotConvertException
,
4089 InvocationTargetException
, RuntimeException
)
4091 (void)OutParamIndex
;
4096 // Check if to firing or approveFiring has to be called
4097 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( FunctionName
);
4098 sal_Bool bApproveFiring
= sal_False
;
4101 Reference
< XIdlClass
> xReturnType
= xMethod
->getReturnType();
4102 Sequence
< Reference
< XIdlClass
> > aExceptionSeq
= xMethod
->getExceptionTypes();
4103 if( ( xReturnType
.is() && xReturnType
->getTypeClass() != TypeClass_VOID
) ||
4104 aExceptionSeq
.getLength() > 0 )
4106 bApproveFiring
= sal_True
;
4110 Sequence
< ParamInfo
> aParamSeq
= xMethod
->getParameterInfos();
4111 sal_uInt32 nParamCount
= aParamSeq
.getLength();
4112 if( nParamCount
> 1 )
4114 const ParamInfo
* pInfos
= aParamSeq
.getConstArray();
4115 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
4117 if( pInfos
[ i
].aMode
!= ParamMode_IN
)
4119 bApproveFiring
= sal_True
;
4126 AllEventObject aAllEvent
;
4127 aAllEvent
.Source
= (OWeakObject
*) this;
4128 aAllEvent
.Helper
= m_Helper
;
4129 aAllEvent
.ListenerType
= Type(m_xListenerType
->getTypeClass(), m_xListenerType
->getName() );
4130 aAllEvent
.MethodName
= FunctionName
;
4131 aAllEvent
.Arguments
= Params
;
4132 if( bApproveFiring
)
4133 aRet
= m_xAllListener
->approveFiring( aAllEvent
);
4135 m_xAllListener
->firing( aAllEvent
);
4139 //*************************************************************************
4140 void SAL_CALL
InvocationToAllListenerMapper::setValue(const OUString
& PropertyName
, const Any
& Value
)
4141 throw( UnknownPropertyException
, CannotConvertException
,
4142 InvocationTargetException
, RuntimeException
)
4148 //*************************************************************************
4149 Any SAL_CALL
InvocationToAllListenerMapper::getValue(const OUString
& PropertyName
)
4150 throw( UnknownPropertyException
, RuntimeException
)
4157 //*************************************************************************
4158 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasMethod(const OUString
& Name
)
4159 throw( RuntimeException
)
4161 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( Name
);
4162 return xMethod
.is();
4165 //*************************************************************************
4166 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasProperty(const OUString
& Name
)
4167 throw( RuntimeException
)
4169 Reference
< XIdlField
> xField
= m_xListenerType
->getField( Name
);
4173 //========================================================================
4174 // create Uno-Service
4175 // 1. Parameter == Prefix-Name of the macro
4176 // 2. Parameter == fully qualified name of the listener
4177 void SbRtl_CreateUnoListener( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
4178 //RTLFUNC(CreateUnoListener)
4182 // We need 2 parameters
4183 if ( rPar
.Count() != 3 )
4185 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
4189 // get the name of the class of the struct
4190 OUString aPrefixName
= rPar
.Get(1)->GetOUString();
4191 OUString aListenerClassName
= rPar
.Get(2)->GetOUString();
4193 // get the CoreReflection
4194 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
4195 if( !xCoreReflection
.is() )
4198 // get the AllListenerAdapterService
4199 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
4202 Reference
< XIdlClass
> xClass
= xCoreReflection
->forName( aListenerClassName
);
4206 // From 1999-11-30: get the InvocationAdapterFactory
4207 Reference
< XInvocationAdapterFactory2
> xInvocationAdapterFactory
=
4208 InvocationAdapterFactory::create( xContext
);
4210 BasicAllListener_Impl
* p
;
4211 Reference
< XAllListener
> xAllLst
= p
= new BasicAllListener_Impl( aPrefixName
);
4213 Reference
< XInterface
> xLst
= createAllListenerAdapter( xInvocationAdapterFactory
, xClass
, xAllLst
, aTmp
);
4217 OUString aClassName
= xClass
->getName();
4218 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
4219 aTmp
= xLst
->queryInterface( aClassType
);
4220 if( !aTmp
.hasValue() )
4223 SbUnoObject
* pUnoObj
= new SbUnoObject( aListenerClassName
, aTmp
);
4224 p
->xSbxObj
= pUnoObj
;
4225 p
->xSbxObj
->SetParent( pBasic
);
4227 // #100326 Register listener object to set Parent NULL in Dtor
4228 SbxArrayRef xBasicUnoListeners
= pBasic
->getUnoListeners();
4229 xBasicUnoListeners
->Insert( pUnoObj
, xBasicUnoListeners
->Count() );
4231 // return the object
4232 SbxVariableRef refVar
= rPar
.Get(0);
4233 refVar
->PutObject( p
->xSbxObj
);
4236 //========================================================================
4237 // Represents the DefaultContext property of the ProcessServiceManager
4238 // in the Basic runtime system.
4239 void RTL_Impl_GetDefaultContext( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
4244 SbxVariableRef refVar
= rPar
.Get(0);
4246 Any
aContextAny( comphelper::getProcessComponentContext() );
4248 SbUnoObjectRef xUnoObj
= new SbUnoObject( OUString( "DefaultContext" ), aContextAny
);
4249 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
4252 //========================================================================
4253 // Creates a Basic wrapper object for a strongly typed Uno value
4254 // 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
4255 void RTL_Impl_CreateUnoValue( StarBASIC
* pBasic
, SbxArray
& rPar
, sal_Bool bWrite
)
4260 static OUString
aTypeTypeString( "type" );
4262 // 2 parameters needed
4263 if ( rPar
.Count() != 3 )
4265 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
4269 // get the name of the class of the struct
4270 OUString aTypeName
= rPar
.Get(1)->GetOUString();
4271 SbxVariable
* pVal
= rPar
.Get(2);
4273 if( aTypeName
== aTypeTypeString
)
4275 SbxDataType eBaseType
= pVal
->SbxValue::GetType();
4276 OUString aValTypeName
;
4277 if( eBaseType
== SbxSTRING
)
4279 aValTypeName
= pVal
->GetOUString();
4281 else if( eBaseType
== SbxOBJECT
)
4284 Reference
< XIdlClass
> xIdlClass
;
4286 SbxBaseRef pObj
= (SbxBase
*)pVal
->GetObject();
4287 if( pObj
&& pObj
->ISA(SbUnoObject
) )
4289 Any aUnoAny
= ((SbUnoObject
*)(SbxBase
*)pObj
)->getUnoAny();
4290 aUnoAny
>>= xIdlClass
;
4293 if( xIdlClass
.is() )
4295 aValTypeName
= xIdlClass
->getName();
4299 bool bSuccess
= implGetTypeByName( aValTypeName
, aType
);
4302 Any
aTypeAny( aType
);
4303 SbxVariableRef refVar
= rPar
.Get(0);
4304 SbxObjectRef xUnoAnyObject
= new SbUnoAnyObject( aTypeAny
);
4305 refVar
->PutObject( xUnoAnyObject
);
4311 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
4315 aRet
= xTypeAccess
->getByHierarchicalName( aTypeName
);
4317 catch( const NoSuchElementException
& e1
)
4319 OUString
aNoSuchElementExceptionName( "com.sun.star.container.NoSuchElementException" );
4320 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
4321 implGetExceptionMsg( e1
, aNoSuchElementExceptionName
) );
4324 Reference
< XTypeDescription
> xTypeDesc
;
4326 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
4327 Type
aDestType( eTypeClass
, aTypeName
);
4331 Any aVal
= sbxToUnoValueImpl( pVal
);
4332 Any aConvertedVal
= convertAny( aVal
, aDestType
);
4334 SbxVariableRef refVar
= rPar
.Get(0);
4335 SbxObjectRef xUnoAnyObject
= new SbUnoAnyObject( aConvertedVal
);
4336 refVar
->PutObject( xUnoAnyObject
);
4339 //==========================================================================
4345 // this mutex is necessary for OInterfaceContainerHelper
4346 ::osl::Mutex m_aMutex
;
4350 typedef WeakImplHelper2
< XInvocation
, XComponent
> ModuleInvocationProxyHelper
;
4352 class ModuleInvocationProxy
: public OMutexBasis
,
4353 public ModuleInvocationProxyHelper
4356 SbxObjectRef m_xScopeObj
;
4357 bool m_bProxyIsClassModuleObject
;
4359 ::cppu::OInterfaceContainerHelper m_aListeners
;
4362 ModuleInvocationProxy( const OUString
& aPrefix
, SbxObjectRef xScopeObj
);
4363 ~ModuleInvocationProxy()
4367 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection() throw();
4368 virtual void SAL_CALL
setValue( const OUString
& rProperty
, const Any
& rValue
)
4369 throw( UnknownPropertyException
);
4370 virtual Any SAL_CALL
getValue( const OUString
& rProperty
)
4371 throw( UnknownPropertyException
);
4372 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& rName
) throw();
4373 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& rProp
) throw();
4375 virtual Any SAL_CALL
invoke( const OUString
& rFunction
,
4376 const Sequence
< Any
>& rParams
,
4377 Sequence
< sal_Int16
>& rOutParamIndex
,
4378 Sequence
< Any
>& rOutParam
)
4379 throw( CannotConvertException
, InvocationTargetException
);
4382 virtual void SAL_CALL
dispose() throw(RuntimeException
);
4383 virtual void SAL_CALL
addEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
);
4384 virtual void SAL_CALL
removeEventListener( const Reference
< XEventListener
>& aListener
) throw (RuntimeException
);
4387 ModuleInvocationProxy::ModuleInvocationProxy( const OUString
& aPrefix
, SbxObjectRef xScopeObj
)
4388 : m_aPrefix( aPrefix
+ OUString( "_" ) )
4389 , m_xScopeObj( xScopeObj
)
4390 , m_aListeners( m_aMutex
)
4392 m_bProxyIsClassModuleObject
= xScopeObj
.Is() ? xScopeObj
->ISA(SbClassModuleObject
) : false;
4395 Reference
< XIntrospectionAccess
> SAL_CALL
ModuleInvocationProxy::getIntrospection() throw()
4397 return Reference
< XIntrospectionAccess
>();
4400 void SAL_CALL
ModuleInvocationProxy::setValue( const OUString
& rProperty
, const Any
& rValue
) throw( UnknownPropertyException
)
4402 if( !m_bProxyIsClassModuleObject
)
4403 throw UnknownPropertyException();
4405 SolarMutexGuard guard
;
4407 OUString
aPropertyFunctionName( "Property Set " );
4408 aPropertyFunctionName
+= m_aPrefix
;
4409 aPropertyFunctionName
+= rProperty
;
4411 SbxVariable
* p
= m_xScopeObj
->Find( aPropertyFunctionName
, SbxCLASS_METHOD
);
4412 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4415 // TODO: Check vba behavior concernig missing function
4416 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4417 throw UnknownPropertyException();
4421 SbxArrayRef xArray
= new SbxArray
;
4422 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
4423 unoToSbxValue( (SbxVariable
*)xVar
, rValue
);
4424 xArray
->Put( xVar
, 1 );
4426 // Call property method
4427 SbxVariableRef xValue
= new SbxVariable
;
4428 pMeth
->SetParameters( xArray
);
4429 pMeth
->Call( xValue
);
4430 pMeth
->SetParameters( NULL
);
4432 // TODO: OutParameter?
4438 Any SAL_CALL
ModuleInvocationProxy::getValue( const OUString
& rProperty
) throw( UnknownPropertyException
)
4440 if( !m_bProxyIsClassModuleObject
)
4442 throw UnknownPropertyException();
4444 SolarMutexGuard guard
;
4446 OUString
aPropertyFunctionName( "Property Get " );
4447 aPropertyFunctionName
+= m_aPrefix
;
4448 aPropertyFunctionName
+= rProperty
;
4450 SbxVariable
* p
= m_xScopeObj
->Find( aPropertyFunctionName
, SbxCLASS_METHOD
);
4451 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4454 // TODO: Check vba behavior concernig missing function
4455 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4456 throw UnknownPropertyException();
4460 SbxVariableRef xValue
= new SbxVariable
;
4461 pMeth
->Call( xValue
);
4462 Any aRet
= sbxToUnoValue( xValue
);
4466 sal_Bool SAL_CALL
ModuleInvocationProxy::hasMethod( const OUString
& ) throw()
4471 sal_Bool SAL_CALL
ModuleInvocationProxy::hasProperty( const OUString
& ) throw()
4476 Any SAL_CALL
ModuleInvocationProxy::invoke( const OUString
& rFunction
,
4477 const Sequence
< Any
>& rParams
,
4478 Sequence
< sal_Int16
>&,
4480 throw( CannotConvertException
, InvocationTargetException
)
4482 SolarMutexGuard guard
;
4485 SbxObjectRef xScopeObj
= m_xScopeObj
;
4486 if( !xScopeObj
.Is() )
4490 OUString aFunctionName
= m_aPrefix
;
4491 aFunctionName
+= rFunction
;
4493 sal_Bool bSetRescheduleBack
= sal_False
;
4494 sal_Bool bOldReschedule
= sal_True
;
4495 SbiInstance
* pInst
= GetSbData()->pInst
;
4496 if( pInst
&& pInst
->IsCompatibility() )
4498 bOldReschedule
= pInst
->IsReschedule();
4499 if ( bOldReschedule
)
4501 pInst
->EnableReschedule( sal_False
);
4502 bSetRescheduleBack
= sal_True
;
4506 SbxVariable
* p
= xScopeObj
->Find( aFunctionName
, SbxCLASS_METHOD
);
4507 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4510 // TODO: Check vba behavior concernig missing function
4511 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4517 sal_Int32 nParamCount
= rParams
.getLength();
4520 xArray
= new SbxArray
;
4521 const Any
*pArgs
= rParams
.getConstArray();
4522 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
4524 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
4525 unoToSbxValue( (SbxVariable
*)xVar
, pArgs
[i
] );
4526 xArray
->Put( xVar
, sal::static_int_cast
< sal_uInt16
>(i
+1) );
4531 SbxVariableRef xValue
= new SbxVariable
;
4533 pMeth
->SetParameters( xArray
);
4534 pMeth
->Call( xValue
);
4535 aRet
= sbxToUnoValue( xValue
);
4536 pMeth
->SetParameters( NULL
);
4538 if( bSetRescheduleBack
)
4539 pInst
->EnableReschedule( bOldReschedule
);
4541 // TODO: OutParameter?
4546 void SAL_CALL
ModuleInvocationProxy::dispose()
4547 throw(RuntimeException
)
4549 ::osl::MutexGuard
aGuard( m_aMutex
);
4551 EventObject
aEvent( (XComponent
*)this );
4552 m_aListeners
.disposeAndClear( aEvent
);
4557 void SAL_CALL
ModuleInvocationProxy::addEventListener( const Reference
< XEventListener
>& xListener
)
4558 throw (RuntimeException
)
4560 m_aListeners
.addInterface( xListener
);
4563 void SAL_CALL
ModuleInvocationProxy::removeEventListener( const Reference
< XEventListener
>& xListener
)
4564 throw (RuntimeException
)
4566 m_aListeners
.removeInterface( xListener
);
4570 Reference
< XInterface
> createComListener( const Any
& aControlAny
, const OUString
& aVBAType
,
4571 const OUString
& aPrefix
, SbxObjectRef xScopeObj
)
4573 Reference
< XInterface
> xRet
;
4575 Reference
< XComponentContext
> xContext(
4576 comphelper::getProcessComponentContext() );
4577 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
4579 Reference
< XInvocation
> xProxy
= new ModuleInvocationProxy( aPrefix
, xScopeObj
);
4581 Sequence
<Any
> args( 3 );
4582 args
[0] <<= aControlAny
;
4583 args
[1] <<= aVBAType
;
4588 xRet
= xServiceMgr
->createInstanceWithArgumentsAndContext(
4589 OUString( "com.sun.star.custom.UnoComListener"),
4592 catch( const Exception
& )
4594 implHandleAnyException( ::cppu::getCaughtException() );
4600 typedef std::vector
< WeakReference
< XComponent
> > ComponentRefVector
;
4602 struct StarBasicDisposeItem
4604 StarBASIC
* m_pBasic
;
4605 SbxArrayRef m_pRegisteredVariables
;
4606 ComponentRefVector m_vComImplementsObjects
;
4608 StarBasicDisposeItem( StarBASIC
* pBasic
)
4609 : m_pBasic( pBasic
)
4611 m_pRegisteredVariables
= new SbxArray();
4615 typedef std::vector
< StarBasicDisposeItem
* > DisposeItemVector
;
4617 static DisposeItemVector GaDisposeItemVector
;
4619 static DisposeItemVector::iterator
lcl_findItemForBasic( StarBASIC
* pBasic
)
4621 DisposeItemVector::iterator it
;
4622 for( it
= GaDisposeItemVector
.begin() ; it
!= GaDisposeItemVector
.end() ; ++it
)
4624 StarBasicDisposeItem
* pItem
= *it
;
4625 if( pItem
->m_pBasic
== pBasic
)
4628 return GaDisposeItemVector
.end();
4631 static StarBasicDisposeItem
* lcl_getOrCreateItemForBasic( StarBASIC
* pBasic
)
4633 DisposeItemVector::iterator it
= lcl_findItemForBasic( pBasic
);
4634 StarBasicDisposeItem
* pItem
= (it
!= GaDisposeItemVector
.end()) ? *it
: NULL
;
4637 pItem
= new StarBasicDisposeItem( pBasic
);
4638 GaDisposeItemVector
.push_back( pItem
);
4643 void registerComponentToBeDisposedForBasic
4644 ( Reference
< XComponent
> xComponent
, StarBASIC
* pBasic
)
4646 StarBasicDisposeItem
* pItem
= lcl_getOrCreateItemForBasic( pBasic
);
4647 pItem
->m_vComImplementsObjects
.push_back( xComponent
);
4650 void registerComListenerVariableForBasic( SbxVariable
* pVar
, StarBASIC
* pBasic
)
4652 StarBasicDisposeItem
* pItem
= lcl_getOrCreateItemForBasic( pBasic
);
4653 SbxArray
* pArray
= pItem
->m_pRegisteredVariables
;
4654 pArray
->Put( pVar
, pArray
->Count() );
4657 void disposeComVariablesForBasic( StarBASIC
* pBasic
)
4659 DisposeItemVector::iterator it
= lcl_findItemForBasic( pBasic
);
4660 if( it
!= GaDisposeItemVector
.end() )
4662 StarBasicDisposeItem
* pItem
= *it
;
4664 SbxArray
* pArray
= pItem
->m_pRegisteredVariables
;
4665 sal_uInt16 nCount
= pArray
->Count();
4666 for( sal_uInt16 i
= 0 ; i
< nCount
; ++i
)
4668 SbxVariable
* pVar
= pArray
->Get( i
);
4669 pVar
->ClearComListener();
4672 ComponentRefVector
& rv
= pItem
->m_vComImplementsObjects
;
4673 ComponentRefVector::iterator itCRV
;
4674 for( itCRV
= rv
.begin() ; itCRV
!= rv
.end() ; ++itCRV
)
4678 Reference
< XComponent
> xComponent( (*itCRV
).get(), UNO_QUERY_THROW
);
4679 xComponent
->dispose();
4681 catch(const Exception
& )
4686 GaDisposeItemVector
.erase( it
);
4691 // Handle module implements mechanism for OLE types
4692 bool SbModule::createCOMWrapperForIface( Any
& o_rRetAny
, SbClassModuleObject
* pProxyClassModuleObject
)
4694 // For now: Take first interface that allows to instantiate COM wrapper
4695 // TODO: Check if support for multiple interfaces is needed
4697 Reference
< XComponentContext
> xContext(
4698 comphelper::getProcessComponentContext() );
4699 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
4700 Reference
< XSingleServiceFactory
> xComImplementsFactory
4702 xServiceMgr
->createInstanceWithContext(
4703 OUString( "com.sun.star.custom.ComImplementsFactory"), xContext
),
4706 if( !xComImplementsFactory
.is() )
4709 bool bSuccess
= false;
4711 SbxArray
* pModIfaces
= pClassData
->mxIfaces
;
4712 sal_uInt16 nCount
= pModIfaces
->Count();
4713 for( sal_uInt16 i
= 0 ; i
< nCount
; ++i
)
4715 SbxVariable
* pVar
= pModIfaces
->Get( i
);
4716 OUString aIfaceName
= pVar
->GetName();
4718 if( !aIfaceName
.isEmpty() )
4720 OUString aPureIfaceName
= aIfaceName
;
4721 sal_Int32 indexLastDot
= aIfaceName
.lastIndexOf('.');
4722 if ( indexLastDot
> -1 )
4724 aPureIfaceName
= aIfaceName
.copy( indexLastDot
+ 1 );
4726 Reference
< XInvocation
> xProxy
= new ModuleInvocationProxy( aPureIfaceName
, pProxyClassModuleObject
);
4728 Sequence
<Any
> args( 2 );
4729 args
[0] <<= aIfaceName
;
4732 Reference
< XInterface
> xRet
;
4736 xRet
= xComImplementsFactory
->createInstanceWithArguments( args
);
4739 catch( const Exception
& )
4741 implHandleAnyException( ::cppu::getCaughtException() );
4746 Reference
< XComponent
> xComponent( xProxy
, UNO_QUERY
);
4747 if( xComponent
.is() )
4749 StarBASIC
* pParentBasic
= NULL
;
4750 SbxObject
* pCurObject
= this;
4753 SbxObject
* pObjParent
= pCurObject
->GetParent();
4754 pParentBasic
= PTR_CAST( StarBASIC
, pObjParent
);
4755 pCurObject
= pObjParent
;
4757 while( pParentBasic
== NULL
&& pCurObject
!= NULL
);
4759 OSL_ASSERT( pParentBasic
!= NULL
);
4760 registerComponentToBeDisposedForBasic( xComponent
, pParentBasic
);
4773 // Due to an incorrect behavior IE returns an object instead of a string
4774 // in some scenarios. Calling toString at the object may correct this.
4775 // Helper function used in sbxvalue.cxx
4776 bool handleToStringForCOMObjects( SbxObject
* pObj
, SbxValue
* pVal
)
4778 bool bSuccess
= false;
4780 SbUnoObject
* pUnoObj
= NULL
;
4781 if( pObj
!= NULL
&& (pUnoObj
= PTR_CAST(SbUnoObject
,(SbxObject
*)pObj
)) != NULL
)
4783 // Only for native COM objects
4784 if( pUnoObj
->isNativeCOMObject() )
4786 SbxVariableRef pMeth
= pObj
->Find( OUString( "toString" ), SbxCLASS_METHOD
);
4799 Any
StructRefInfo::getValue()
4803 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
4805 &aRet
, getInst(), mpTD
,
4806 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
4810 void StructRefInfo::setValue( const Any
& rValue
)
4812 uno_type_assignData( getInst(),
4814 (void*)rValue
.getValue(),
4815 rValue
.getValueTypeRef(),
4816 reinterpret_cast< uno_QueryInterfaceFunc
>(cpp_queryInterface
),
4817 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
4818 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
4821 OUString
StructRefInfo::getTypeName() const
4826 sTypeName
= mpTD
->pTypeName
;
4831 void* StructRefInfo::getInst()
4833 return ((char*)maAny
.getValue() + mnPos
);
4836 TypeClass
StructRefInfo::getTypeClass() const
4838 TypeClass t
= TypeClass_VOID
;
4840 t
= (TypeClass
)mpTD
->eTypeClass
;
4844 SbUnoStructRefObject::SbUnoStructRefObject( const OUString
& aName_
, const StructRefInfo
& rMemberInfo
) : SbxObject( aName_
), maMemberInfo( rMemberInfo
), mbMemberCacheInit( false )
4846 SetClassName( OUString( maMemberInfo
.getTypeName() ) );
4849 SbUnoStructRefObject::~SbUnoStructRefObject()
4851 for ( StructFieldInfo::iterator it
= maFields
.begin(), it_end
= maFields
.end(); it
!= it_end
; ++it
)
4855 void SbUnoStructRefObject::initMemberCache()
4857 if ( mbMemberCacheInit
)
4860 typelib_TypeDescription
* pTD
= maMemberInfo
.getTD();
4861 typelib_CompoundTypeDescription
* pCompTypeDescr
= (typelib_CompoundTypeDescription
*)pTD
;
4862 for ( ; pCompTypeDescr
; pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
4863 nAll
+= pCompTypeDescr
->nMembers
;
4864 for ( pCompTypeDescr
= (typelib_CompoundTypeDescription
*)pTD
; pCompTypeDescr
;
4865 pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
4867 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompTypeDescr
->ppTypeRefs
;
4868 rtl_uString
** ppNames
= pCompTypeDescr
->ppMemberNames
;
4869 sal_Int32
* pMemberOffsets
= pCompTypeDescr
->pMemberOffsets
;
4870 for ( sal_Int32 nPos
= pCompTypeDescr
->nMembers
; nPos
--; )
4872 typelib_TypeDescription
* pMemberTD
= 0;
4873 TYPELIB_DANGER_GET( &pMemberTD
, ppTypeRefs
[nPos
] );
4874 OSL_ENSURE( pMemberTD
, "### cannot get field in struct!" );
4877 OUString
aName( ppNames
[nPos
] );
4878 TYPELIB_DANGER_RELEASE( pMemberTD
);
4879 maFields
[ aName
] = new StructRefInfo( maMemberInfo
.getRootAnyRef(), pMemberTD
, maMemberInfo
.getPos() + pMemberOffsets
[nPos
] );
4883 mbMemberCacheInit
= true;
4886 SbxVariable
* SbUnoStructRefObject::Find( const OUString
& rName
, SbxClassType t
)
4888 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
4891 if ( !mbMemberCacheInit
)
4893 StructFieldInfo::iterator it
= maFields
.find( OUString( rName
).toAsciiUpperCase() );
4894 if ( it
!= maFields
.end() )
4896 SbxDataType eSbxType
;
4897 eSbxType
= unoToSbxType( it
->second
->getTypeClass() );
4898 SbxDataType eRealSbxType
= eSbxType
;
4901 aProp
.Type
= com::sun::star::uno::Type( it
->second
->getTypeClass(), it
->second
->getTypeName() );
4902 SbUnoProperty
* pProp
= new SbUnoProperty( rName
, eSbxType
, eRealSbxType
, aProp
, 0, false, ( aProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
4903 SbxVariableRef xVarRef
= pProp
;
4904 QuickInsert( (SbxVariable
*)xVarRef
);
4911 if( rName
.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES
) ||
4912 rName
.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES
) ||
4913 rName
.equalsIgnoreAsciiCase(ID_DBG_METHODS
) )
4916 implCreateDbgProperties();
4918 // Now they have to be found regular
4919 pRes
= SbxObject::Find( rName
, SbxCLASS_DONTCARE
);
4926 // help method to create the dbg_-Properties
4927 void SbUnoStructRefObject::implCreateDbgProperties( void )
4931 // Id == -1: display the implemented interfaces corresponding the ClassProvider
4932 SbxVariableRef xVarRef
= new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES
), SbxSTRING
, SbxSTRING
, aProp
, -1, false, false );
4933 QuickInsert( (SbxVariable
*)xVarRef
);
4935 // Id == -2: output the properties
4936 xVarRef
= new SbUnoProperty( OUString(ID_DBG_PROPERTIES
), SbxSTRING
, SbxSTRING
, aProp
, -2, false, false );
4937 QuickInsert( (SbxVariable
*)xVarRef
);
4939 // Id == -3: output the Methods
4940 xVarRef
= new SbUnoProperty( OUString(ID_DBG_METHODS
), SbxSTRING
, SbxSTRING
, aProp
, -3, false, false );
4941 QuickInsert( (SbxVariable
*)xVarRef
);
4944 void SbUnoStructRefObject::implCreateAll()
4946 // throw away all existing methods and properties
4947 pMethods
= new SbxArray
;
4948 pProps
= new SbxArray
;
4950 if (!mbMemberCacheInit
)
4953 for ( StructFieldInfo::iterator it
= maFields
.begin(), it_end
= maFields
.end(); it
!= it_end
; ++it
)
4955 const OUString
& rName
= it
->first
;
4956 SbxDataType eSbxType
;
4957 eSbxType
= unoToSbxType( it
->second
->getTypeClass() );
4958 SbxDataType eRealSbxType
= eSbxType
;
4961 aProp
.Type
= com::sun::star::uno::Type( it
->second
->getTypeClass(), it
->second
->getTypeName() );
4962 SbUnoProperty
* pProp
= new SbUnoProperty( rName
, eSbxType
, eRealSbxType
, aProp
, 0, false, ( aProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
4963 SbxVariableRef xVarRef
= pProp
;
4964 QuickInsert( (SbxVariable
*)xVarRef
);
4967 // Create Dbg_-Properties
4968 implCreateDbgProperties();
4972 Any
SbUnoStructRefObject::getUnoAny( void )
4974 return maMemberInfo
.getValue();
4977 OUString
SbUnoStructRefObject::Impl_DumpProperties()
4979 OUStringBuffer aRet
;
4980 aRet
.appendAscii("Properties of object ");
4981 aRet
.append( getDbgObjectName() );
4983 sal_uInt16 nPropCount
= pProps
->Count();
4984 sal_uInt16 nPropsPerLine
= 1 + nPropCount
/ 30;
4985 for( sal_uInt16 i
= 0; i
< nPropCount
; i
++ )
4987 SbxVariable
* pVar
= pProps
->Get( i
);
4990 OUStringBuffer aPropStr
;
4991 if( (i
% nPropsPerLine
) == 0 )
4993 aPropStr
.appendAscii( "\n" );
4995 // output the type and name
4996 // Is it in Uno a sequence?
4997 SbxDataType eType
= pVar
->GetFullType();
4999 sal_Bool bMaybeVoid
= sal_False
;
5000 OUString
aName( pVar
->GetName() );
5001 StructFieldInfo::iterator it
= maFields
.find( aName
);
5003 if ( it
!= maFields
.end() )
5005 const StructRefInfo
& rPropInfo
= *it
->second
;
5007 if( eType
== SbxOBJECT
)
5009 if( rPropInfo
.getTypeClass() == TypeClass_SEQUENCE
)
5011 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
5015 aPropStr
.append( Dbg_SbxDataType2String( eType
) );
5018 aPropStr
.appendAscii( "/void" );
5020 aPropStr
.appendAscii( " " );
5021 aPropStr
.append( pVar
->GetName() );
5023 if( i
== nPropCount
- 1 )
5025 aPropStr
.appendAscii( "\n" );
5029 aPropStr
.appendAscii( "; " );
5031 aRet
.append( aPropStr
.makeStringAndClear() );
5034 return aRet
.makeStringAndClear();
5037 void SbUnoStructRefObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
5038 const SfxHint
& rHint
, const TypeId
& rHintType
)
5040 if ( !mbMemberCacheInit
)
5042 const SbxHint
* pHint
= PTR_CAST(SbxHint
,&rHint
);
5045 SbxVariable
* pVar
= pHint
->GetVar();
5046 SbUnoProperty
* pProp
= PTR_CAST(SbUnoProperty
,pVar
);
5049 StructFieldInfo::iterator it
= maFields
.find( pProp
->GetName() );
5050 // handle get/set of members of struct
5051 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
5054 sal_Int32 nId
= pProp
->nId
;
5057 // Id == -1: Display implemented interfaces according the ClassProvider
5058 if( nId
== -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
5060 OUStringBuffer aRet
;
5061 aRet
.appendAscii( ID_DBG_SUPPORTEDINTERFACES
);
5062 aRet
.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
5064 pVar
->PutString( aRet
.makeStringAndClear() );
5066 // Id == -2: output properties
5067 else if( nId
== -2 ) // Property ID_DBG_PROPERTIES
5069 // by now all properties must be established
5071 OUString aRetStr
= Impl_DumpProperties();
5072 pVar
->PutString( aRetStr
);
5074 // Id == -3: output the methods
5075 else if( nId
== -3 ) // Property ID_DBG_METHODS
5077 // by now all properties must be established
5079 OUStringBuffer aRet
;
5080 aRet
.appendAscii("Methods of object ");
5081 aRet
.append( getDbgObjectName() );
5082 aRet
.appendAscii( "\nNo methods found\n" );
5083 pVar
->PutString( aRet
.makeStringAndClear() );
5088 if ( it
!= maFields
.end() )
5090 Any aRetAny
= it
->second
->getValue();
5091 unoToSbxValue( pVar
, aRetAny
);
5094 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
5096 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
5098 if ( it
!= maFields
.end() )
5100 // take over the value from Uno to Sbx
5101 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
5102 it
->second
->setValue( aAnyValue
);
5105 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
5109 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
5113 StructRefInfo
SbUnoStructRefObject::getStructMember( const OUString
& rMemberName
)
5115 if (!mbMemberCacheInit
)
5119 StructFieldInfo::iterator it
= maFields
.find( rMemberName
);
5121 typelib_TypeDescription
* pFoundTD
= NULL
;
5122 sal_Int32 nFoundPos
= -1;
5124 if ( it
!= maFields
.end() )
5126 pFoundTD
= it
->second
->getTD();
5127 nFoundPos
= it
->second
->getPos();
5129 StructRefInfo
aRet( maMemberInfo
.getRootAnyRef(), pFoundTD
, nFoundPos
);
5133 OUString
SbUnoStructRefObject::getDbgObjectName()
5135 OUString aName
= GetClassName();
5136 if( aName
.isEmpty() )
5140 OUStringBuffer aRet
;
5141 if( aName
.getLength() > 20 )
5143 aRet
.appendAscii( "\n" );
5145 aRet
.appendAscii( "\"" );
5146 aRet
.append( aName
);
5147 aRet
.appendAscii( "\":" );
5148 return aRet
.makeStringAndClear();
5151 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */