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/theIntrospection.hpp>
51 #include <com/sun/star/script/BasicErrorException.hpp>
52 #include <com/sun/star/script/InvocationAdapterFactory.hpp>
53 #include <com/sun/star/script/XAllListener.hpp>
54 #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
55 #include <com/sun/star/script/Converter.hpp>
56 #include <com/sun/star/script/XDefaultProperty.hpp>
57 #include <com/sun/star/script/XDefaultMethod.hpp>
58 #include <com/sun/star/script/XDirectInvocation.hpp>
59 #include <com/sun/star/container/XNameAccess.hpp>
60 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
61 #include <com/sun/star/reflection/XIdlArray.hpp>
62 #include <com/sun/star/reflection/XIdlReflection.hpp>
63 #include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
64 #include <com/sun/star/reflection/theCoreReflection.hpp>
65 #include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
66 #include <com/sun/star/bridge/oleautomation/Date.hpp>
67 #include <com/sun/star/bridge/oleautomation/Decimal.hpp>
68 #include <com/sun/star/bridge/oleautomation/Currency.hpp>
69 #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
70 #include <com/sun/star/script/XAutomationInvocation.hpp>
71 #include <basic/codecompletecache.hxx>
73 #include <rtlproto.hxx>
75 #include <basic/sbstar.hxx>
76 #include <basic/sbuno.hxx>
77 #include <basic/sberrors.hxx>
78 #include <sbunoobj.hxx>
79 #include "sbjsmod.hxx"
80 #include <basic/basmgr.hxx>
81 #include <sbintern.hxx>
82 #include <runtime.hxx>
85 #include <boost/scoped_array.hpp>
86 #include <unordered_map>
87 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
88 #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
90 using com::sun::star::uno::Reference
;
91 using namespace com::sun::star::uno
;
92 using namespace com::sun::star::lang
;
93 using namespace com::sun::star::reflection
;
94 using namespace com::sun::star::beans
;
95 using namespace com::sun::star::script
;
96 using namespace com::sun::star::container
;
97 using namespace com::sun::star::bridge
;
100 TYPEINIT1(SbUnoMethod
,SbxMethod
)
101 TYPEINIT1(SbUnoProperty
,SbxProperty
)
102 TYPEINIT1(SbUnoObject
,SbxObject
)
103 TYPEINIT1(SbUnoStructRefObject
,SbxObject
)
104 TYPEINIT1(SbUnoClass
,SbxObject
)
105 TYPEINIT1(SbUnoService
,SbxObject
)
106 TYPEINIT1(SbUnoServiceCtor
,SbxMethod
)
107 TYPEINIT1(SbUnoSingleton
,SbxObject
)
109 typedef WeakImplHelper1
< XAllListener
> BasicAllListenerHelper
;
111 // Identifiers for creating the strings for dbg_Properties
112 static char const ID_DBG_SUPPORTEDINTERFACES
[] = "Dbg_SupportedInterfaces";
113 static char const ID_DBG_PROPERTIES
[] = "Dbg_Properties";
114 static char const ID_DBG_METHODS
[] = "Dbg_Methods";
116 static char const aSeqLevelStr
[] = "[]";
117 static char const defaultNameSpace
[] = "ooo.vba";
119 // Gets the default property for an uno object. Note: There is some
120 // redirection built in. The property name specifies the name
121 // of the default property.
123 bool SbUnoObject::getDefaultPropName( SbUnoObject
* pUnoObj
, OUString
& sDfltProp
)
126 Reference
< XDefaultProperty
> xDefaultProp( pUnoObj
->maTmpUnoObj
, UNO_QUERY
);
127 if ( xDefaultProp
.is() )
129 sDfltProp
= xDefaultProp
->getDefaultPropertyName();
130 if ( !sDfltProp
.isEmpty() )
136 SbxVariable
* getDefaultProp( SbxVariable
* pRef
)
138 SbxVariable
* pDefaultProp
= NULL
;
139 if ( pRef
->GetType() == SbxOBJECT
)
141 SbxObject
* pObj
= PTR_CAST(SbxObject
, pRef
);
144 SbxBase
* pObjVarObj
= pRef
->GetObject();
145 pObj
= PTR_CAST(SbxObject
,pObjVarObj
);
147 if ( pObj
&& pObj
->ISA(SbUnoObject
) )
149 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
150 pDefaultProp
= pUnoObj
->GetDfltProperty();
156 void SetSbUnoObjectDfltPropName( SbxObject
* pObj
)
158 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
, pObj
);
161 OUString sDfltPropName
;
163 if ( SbUnoObject::getDefaultPropName( pUnoObj
, sDfltPropName
) )
165 OSL_TRACE("SetSbUnoObjectDfltPropName setting default prop for %s", OUStringToOString( pObj
->GetName(), RTL_TEXTENCODING_UTF8
).getStr() );
166 pUnoObj
->SetDfltProperty( sDfltPropName
);
171 // save CoreReflection statically
172 Reference
< XIdlReflection
> getCoreReflection_Impl()
174 return css::reflection::theCoreReflection::get(
175 comphelper::getProcessComponentContext());
178 // save CoreReflection statically
179 Reference
< XHierarchicalNameAccess
> getCoreReflection_HierarchicalNameAccess_Impl()
181 static Reference
< XHierarchicalNameAccess
> xCoreReflection_HierarchicalNameAccess
;
183 if( !xCoreReflection_HierarchicalNameAccess
.is() )
185 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
186 if( xCoreReflection
.is() )
188 xCoreReflection_HierarchicalNameAccess
=
189 Reference
< XHierarchicalNameAccess
>( xCoreReflection
, UNO_QUERY
);
192 return xCoreReflection_HierarchicalNameAccess
;
195 // Hold TypeProvider statically
196 Reference
< XHierarchicalNameAccess
> getTypeProvider_Impl()
198 static Reference
< XHierarchicalNameAccess
> xAccess
;
200 // Do we have already CoreReflection; if not obtain it
203 Reference
< XComponentContext
> xContext(
204 comphelper::getProcessComponentContext() );
207 xContext
->getValueByName(
208 OUString( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) )
210 OSL_ENSURE( xAccess
.is(), "### TypeDescriptionManager singleton not accessible!?" );
214 throw DeploymentException(
215 "/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessible" );
221 // Hold TypeConverter statically
222 Reference
< XTypeConverter
> getTypeConverter_Impl()
224 static Reference
< XTypeConverter
> xTypeConverter
;
226 // Do we have already CoreReflection; if not obtain it
227 if( !xTypeConverter
.is() )
229 Reference
< XComponentContext
> xContext(
230 comphelper::getProcessComponentContext() );
233 xTypeConverter
= Converter::create(xContext
);
235 if( !xTypeConverter
.is() )
237 throw DeploymentException(
238 "com.sun.star.script.Converter service not accessible" );
241 return xTypeConverter
;
245 // #111851 factory function to create an OLE object
246 SbUnoObject
* createOLEObject_Impl( const OUString
& aType
)
248 static Reference
< XMultiServiceFactory
> xOLEFactory
;
249 static bool bNeedsInit
= true;
255 Reference
< XComponentContext
> xContext(
256 comphelper::getProcessComponentContext() );
259 Reference
<XMultiComponentFactory
> xSMgr
= xContext
->getServiceManager();
260 xOLEFactory
= Reference
<XMultiServiceFactory
>(
261 xSMgr
->createInstanceWithContext(
262 OUString( "com.sun.star.bridge.OleObjectFactory"),
263 xContext
), UNO_QUERY
);
267 SbUnoObject
* pUnoObj
= NULL
;
268 if( xOLEFactory
.is() )
270 // some type names available in VBA can not be directly used in COM
271 OUString aOLEType
= aType
;
272 if ( aOLEType
== "SAXXMLReader30" )
274 aOLEType
= "Msxml2.SAXXMLReader.3.0";
276 Reference
< XInterface
> xOLEObject
= xOLEFactory
->createInstance( aOLEType
);
277 if( xOLEObject
.is() )
281 pUnoObj
= new SbUnoObject( aType
, aAny
);
282 OUString sDfltPropName
;
284 if ( SbUnoObject::getDefaultPropName( pUnoObj
, sDfltPropName
) )
285 pUnoObj
->SetDfltProperty( sDfltPropName
);
294 void lcl_indent( OUStringBuffer
& _inout_rBuffer
, sal_Int32 _nLevel
)
296 while ( _nLevel
-- > 0 )
298 _inout_rBuffer
.appendAscii( " " );
303 void implAppendExceptionMsg( OUStringBuffer
& _inout_rBuffer
, const Exception
& _e
, const OUString
& _rExceptionType
, sal_Int32 _nLevel
)
305 _inout_rBuffer
.appendAscii( "\n" );
306 lcl_indent( _inout_rBuffer
, _nLevel
);
307 _inout_rBuffer
.appendAscii( "Type: " );
309 if ( _rExceptionType
.isEmpty() )
310 _inout_rBuffer
.appendAscii( "Unknown" );
312 _inout_rBuffer
.append( _rExceptionType
);
314 _inout_rBuffer
.appendAscii( "\n" );
315 lcl_indent( _inout_rBuffer
, _nLevel
);
316 _inout_rBuffer
.appendAscii( "Message: " );
317 _inout_rBuffer
.append( _e
.Message
);
321 // construct an error message for the exception
322 OUString
implGetExceptionMsg( const Exception
& e
, const OUString
& aExceptionType_
)
324 OUStringBuffer aMessageBuf
;
325 implAppendExceptionMsg( aMessageBuf
, e
, aExceptionType_
, 0 );
326 return aMessageBuf
.makeStringAndClear();
329 OUString
implGetExceptionMsg( const Any
& _rCaughtException
)
331 OSL_PRECOND( _rCaughtException
.getValueTypeClass() == TypeClass_EXCEPTION
, "implGetExceptionMsg: illegal argument!" );
332 if ( _rCaughtException
.getValueTypeClass() != TypeClass_EXCEPTION
)
336 return implGetExceptionMsg( *static_cast< const Exception
* >( _rCaughtException
.getValue() ), _rCaughtException
.getValueTypeName() );
339 Any
convertAny( const Any
& rVal
, const Type
& aDestType
)
342 Reference
< XTypeConverter
> xConverter
= getTypeConverter_Impl();
345 aConvertedVal
= xConverter
->convertTo( rVal
, aDestType
);
347 catch( const IllegalArgumentException
& )
349 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
350 implGetExceptionMsg( ::cppu::getCaughtException() ) );
351 return aConvertedVal
;
353 catch( const CannotConvertException
& e2
)
355 OUString
aCannotConvertExceptionName( "com.sun.star.lang.IllegalArgumentException");
356 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
357 implGetExceptionMsg( e2
, aCannotConvertExceptionName
) );
358 return aConvertedVal
;
360 return aConvertedVal
;
364 // #105565 Special Object to wrap a strongly typed Uno Any
365 TYPEINIT1(SbUnoAnyObject
,SbxObject
)
368 // TODO: source out later
369 Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
)
371 return getCoreReflection_Impl()->forName(rType
.getTypeName());
374 // Exception type unknown
375 template< class EXCEPTION
>
376 OUString
implGetExceptionMsg( const EXCEPTION
& e
)
378 return implGetExceptionMsg( e
, cppu::UnoType
<decltype(e
)>::get().getTypeName() );
381 void implHandleBasicErrorException( BasicErrorException
& e
)
383 SbError nError
= StarBASIC::GetSfxFromVBError( (sal_uInt16
)e
.ErrorCode
);
384 StarBASIC::Error( nError
, e
.ErrorMessageArgument
);
387 void implHandleWrappedTargetException( const Any
& _rWrappedTargetException
)
389 Any
aExamine( _rWrappedTargetException
);
391 // completely strip the first InvocationTargetException, its error message isn't of any
392 // interest to the user, it just says something like "invoking the UNO method went wrong.".
393 InvocationTargetException aInvocationError
;
394 if ( aExamine
>>= aInvocationError
)
395 aExamine
= aInvocationError
.TargetException
;
397 BasicErrorException aBasicError
;
399 SbError
nError( ERRCODE_BASIC_EXCEPTION
);
400 OUStringBuffer aMessageBuf
;
402 // strip any other WrappedTargetException instances, but this time preserve the error messages.
403 WrappedTargetException aWrapped
;
404 sal_Int32 nLevel
= 0;
405 while ( aExamine
>>= aWrapped
)
407 // special handling for BasicErrorException errors
408 if ( aWrapped
.TargetException
>>= aBasicError
)
410 nError
= StarBASIC::GetSfxFromVBError( (sal_uInt16
)aBasicError
.ErrorCode
);
411 aMessageBuf
.append( aBasicError
.ErrorMessageArgument
);
416 // append this round's message
417 implAppendExceptionMsg( aMessageBuf
, aWrapped
, aExamine
.getValueTypeName(), nLevel
);
418 if ( aWrapped
.TargetException
.getValueTypeClass() == TypeClass_EXCEPTION
)
419 // there is a next chain element
420 aMessageBuf
.appendAscii( "\nTargetException:" );
423 aExamine
= aWrapped
.TargetException
;
427 if ( aExamine
.getValueTypeClass() == TypeClass_EXCEPTION
)
429 // the last element in the chain is still an exception, but no WrappedTargetException
430 implAppendExceptionMsg( aMessageBuf
, *static_cast< const Exception
* >( aExamine
.getValue() ), aExamine
.getValueTypeName(), nLevel
);
433 StarBASIC::Error( nError
, aMessageBuf
.makeStringAndClear() );
436 static void implHandleAnyException( const Any
& _rCaughtException
)
438 BasicErrorException aBasicError
;
439 WrappedTargetException aWrappedError
;
441 if ( _rCaughtException
>>= aBasicError
)
443 implHandleBasicErrorException( aBasicError
);
445 else if ( _rCaughtException
>>= aWrappedError
)
447 implHandleWrappedTargetException( _rCaughtException
);
451 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( _rCaughtException
) );
455 // NativeObjectWrapper handling
458 SbxObjectRef m_xNativeObj
;
460 ObjectItem( SbxObject
* pNativeObj
)
461 : m_xNativeObj( pNativeObj
)
465 typedef std::vector
< ObjectItem
> NativeObjectWrapperVector
;
466 class GaNativeObjectWrapperVector
: public rtl::Static
<NativeObjectWrapperVector
, GaNativeObjectWrapperVector
> {};
468 void clearNativeObjectWrapperVector()
470 GaNativeObjectWrapperVector::get().clear();
473 static sal_uInt32
lcl_registerNativeObjectWrapper( SbxObject
* pNativeObj
)
475 NativeObjectWrapperVector
&rNativeObjectWrapperVector
= GaNativeObjectWrapperVector::get();
476 sal_uInt32 nIndex
= rNativeObjectWrapperVector
.size();
477 rNativeObjectWrapperVector
.push_back( ObjectItem( pNativeObj
) );
481 static SbxObject
* lcl_getNativeObject( sal_uInt32 nIndex
)
483 SbxObjectRef xRetObj
;
484 NativeObjectWrapperVector
&rNativeObjectWrapperVector
= GaNativeObjectWrapperVector::get();
485 if( nIndex
< rNativeObjectWrapperVector
.size() )
487 ObjectItem
& rItem
= rNativeObjectWrapperVector
[ nIndex
];
488 xRetObj
= rItem
.m_xNativeObj
;
493 // convert from Uno to Sbx
494 SbxDataType
unoToSbxType( TypeClass eType
)
496 SbxDataType eRetType
= SbxVOID
;
500 case TypeClass_INTERFACE
:
502 case TypeClass_STRUCT
:
503 case TypeClass_EXCEPTION
: eRetType
= SbxOBJECT
; break;
505 case TypeClass_ENUM
: eRetType
= SbxLONG
; break;
506 case TypeClass_SEQUENCE
:
507 eRetType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
511 case TypeClass_ANY
: eRetType
= SbxVARIANT
; break;
512 case TypeClass_BOOLEAN
: eRetType
= SbxBOOL
; break;
513 case TypeClass_CHAR
: eRetType
= SbxCHAR
; break;
514 case TypeClass_STRING
: eRetType
= SbxSTRING
; break;
515 case TypeClass_FLOAT
: eRetType
= SbxSINGLE
; break;
516 case TypeClass_DOUBLE
: eRetType
= SbxDOUBLE
; break;
517 case TypeClass_BYTE
: eRetType
= SbxINTEGER
; break;
518 case TypeClass_SHORT
: eRetType
= SbxINTEGER
; break;
519 case TypeClass_LONG
: eRetType
= SbxLONG
; break;
520 case TypeClass_HYPER
: eRetType
= SbxSALINT64
; break;
521 case TypeClass_UNSIGNED_SHORT
: eRetType
= SbxUSHORT
; break;
522 case TypeClass_UNSIGNED_LONG
: eRetType
= SbxULONG
; break;
523 case TypeClass_UNSIGNED_HYPER
: eRetType
= SbxSALUINT64
;break;
529 SbxDataType
unoToSbxType( const Reference
< XIdlClass
>& xIdlClass
)
531 SbxDataType eRetType
= SbxVOID
;
534 TypeClass eType
= xIdlClass
->getTypeClass();
535 eRetType
= unoToSbxType( eType
);
540 static void implSequenceToMultiDimArray( SbxDimArray
*& pArray
, Sequence
< sal_Int32
>& indices
, Sequence
< sal_Int32
>& sizes
, const Any
& aValue
, sal_Int32
& dimension
, bool bIsZeroIndex
, Type
* pType
= NULL
)
542 Type aType
= aValue
.getValueType();
543 TypeClass eTypeClass
= aType
.getTypeClass();
545 sal_Int32 dimCopy
= dimension
;
547 if ( eTypeClass
== TypeClass_SEQUENCE
)
549 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aType
);
550 Reference
< XIdlArray
> xIdlArray
= xIdlTargetClass
->getArray();
551 typelib_TypeDescription
* pTD
= 0;
552 aType
.getDescription( &pTD
);
553 Type
aElementType( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
554 ::typelib_typedescription_release( pTD
);
556 sal_Int32 nLen
= xIdlArray
->getLen( aValue
);
557 for ( sal_Int32 index
= 0; index
< nLen
; ++index
)
559 Any aElementAny
= xIdlArray
->get( aValue
, (sal_uInt32
)index
);
560 // This detects the dimension were currently processing
561 if ( dimCopy
== dimension
)
564 if ( sizes
.getLength() < dimCopy
)
566 sizes
.realloc( sizes
.getLength() + 1 );
567 sizes
[ sizes
.getLength() - 1 ] = nLen
;
568 indices
.realloc( indices
.getLength() + 1 );
573 indices
[ dimCopy
- 1 ] = index
;
575 indices
[ dimCopy
- 1] = index
+ 1;
577 implSequenceToMultiDimArray( pArray
, indices
, sizes
, aElementAny
, dimCopy
, bIsZeroIndex
, &aElementType
);
583 if ( indices
.getLength() < 1 )
585 // Should never ever get here ( indices.getLength()
586 // should equal number of dimensions in the array )
587 // And that should at least be 1 !
588 // #QUESTION is there a better error?
589 StarBASIC::Error( SbERR_INVALID_OBJECT
);
593 SbxDataType eSbxElementType
= unoToSbxType( pType
? pType
->getTypeClass() : aValue
.getValueTypeClass() );
596 pArray
= new SbxDimArray( eSbxElementType
);
597 sal_Int32 nIndexLen
= indices
.getLength();
599 // Dimension the array
600 for ( sal_Int32 index
= 0; index
< nIndexLen
; ++index
)
603 pArray
->unoAddDim32( 0, sizes
[ index
] - 1);
605 pArray
->unoAddDim32( 1, sizes
[ index
] );
612 SbxVariableRef xVar
= new SbxVariable( eSbxElementType
);
613 unoToSbxValue( (SbxVariable
*)xVar
, aValue
);
615 sal_Int32
* pIndices
= indices
.getArray();
616 pArray
->Put32( (SbxVariable
*)xVar
, pIndices
);
622 void unoToSbxValue( SbxVariable
* pVar
, const Any
& aValue
)
624 Type aType
= aValue
.getValueType();
625 TypeClass eTypeClass
= aType
.getTypeClass();
630 // Map Type to IdlClass
633 Reference
<XIdlClass
> xClass
= TypeToIdlClass( aType_
);
635 aClassAny
<<= xClass
;
637 // instantiate SbUnoObject
639 SbUnoObject
* pSbUnoObject
= new SbUnoObject( aName
, aClassAny
);
640 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
642 // If the object is invalid deliver null
643 if( pSbUnoObject
->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID
)
645 pVar
->PutObject( NULL
);
649 pVar
->PutObject( xWrapper
);
653 // Interfaces and Structs must be wrapped in a SbUnoObject
654 case TypeClass_INTERFACE
:
655 case TypeClass_STRUCT
:
656 case TypeClass_EXCEPTION
:
658 if( eTypeClass
== TypeClass_STRUCT
)
661 NativeObjectWrapper aNativeObjectWrapper
;
662 if ( (aValue
>>= aWrap
) )
664 SbxDimArray
* pArray
= NULL
;
665 Sequence
< sal_Int32
> indices
;
666 Sequence
< sal_Int32
> sizes
;
667 sal_Int32 dimension
= 0;
668 implSequenceToMultiDimArray( pArray
, indices
, sizes
, aWrap
.Array
, dimension
, aWrap
.IsZeroIndex
);
671 SbxDimArrayRef xArray
= pArray
;
672 SbxFlagBits nFlags
= pVar
->GetFlags();
673 pVar
->ResetFlag( SBX_FIXED
);
674 pVar
->PutObject( (SbxDimArray
*)xArray
);
675 pVar
->SetFlags( nFlags
);
681 else if ( (aValue
>>= aNativeObjectWrapper
) )
683 sal_uInt32 nIndex
= 0;
684 if( (aNativeObjectWrapper
.ObjectId
>>= nIndex
) )
686 SbxObject
* pObj
= lcl_getNativeObject( nIndex
);
687 pVar
->PutObject( pObj
);
695 SbiInstance
* pInst
= GetSbData()->pInst
;
696 if( pInst
&& pInst
->IsCompatibility() )
698 oleautomation::Date aDate
;
699 if( (aValue
>>= aDate
) )
701 pVar
->PutDate( aDate
.Value
);
706 oleautomation::Decimal aDecimal
;
707 if( (aValue
>>= aDecimal
) )
709 pVar
->PutDecimal( aDecimal
);
714 oleautomation::Currency aCurrency
;
715 if( (aValue
>>= aCurrency
) )
717 pVar
->PutCurrency( aCurrency
.Value
);
725 // instantiate a SbUnoObject
727 SbUnoObject
* pSbUnoObject
= new SbUnoObject( aName
, aValue
);
728 //If this is called externally e.g. from the scripting
729 //framework then there is no 'active' runtime the default property will not be set up
730 //only a vba object will have XDefaultProp set anyway so... this
731 //test seems a bit of overkill
732 //if ( SbiRuntime::isVBAEnabled() )
734 OUString sDfltPropName
;
736 if ( SbUnoObject::getDefaultPropName( pSbUnoObject
, sDfltPropName
) )
738 pSbUnoObject
->SetDfltProperty( sDfltPropName
);
741 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
743 // If the object is invalid deliver null
744 if( pSbUnoObject
->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID
)
746 pVar
->PutObject( NULL
);
750 pVar
->PutObject( xWrapper
);
759 enum2int( nEnum
, aValue
);
760 pVar
->PutLong( nEnum
);
764 case TypeClass_SEQUENCE
:
766 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aType
);
767 Reference
< XIdlArray
> xIdlArray
= xIdlTargetClass
->getArray();
768 sal_Int32 i
, nLen
= xIdlArray
->getLen( aValue
);
770 typelib_TypeDescription
* pTD
= 0;
771 aType
.getDescription( &pTD
);
772 OSL_ASSERT( pTD
&& pTD
->eTypeClass
== typelib_TypeClass_SEQUENCE
);
773 Type
aElementType( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
774 ::typelib_typedescription_release( pTD
);
776 // build an Array in Basic
777 SbxDimArrayRef xArray
;
778 SbxDataType eSbxElementType
= unoToSbxType( aElementType
.getTypeClass() );
779 xArray
= new SbxDimArray( eSbxElementType
);
782 xArray
->unoAddDim32( 0, nLen
- 1 );
784 // register the elements as variables
785 for( i
= 0 ; i
< nLen
; i
++ )
788 Any aElementAny
= xIdlArray
->get( aValue
, (sal_uInt32
)i
);
789 SbxVariableRef xVar
= new SbxVariable( eSbxElementType
);
790 unoToSbxValue( (SbxVariable
*)xVar
, aElementAny
);
792 // put into the Array
793 xArray
->Put32( (SbxVariable
*)xVar
, &i
);
798 xArray
->unoAddDim( 0, -1 );
802 SbxFlagBits nFlags
= pVar
->GetFlags();
803 pVar
->ResetFlag( SBX_FIXED
);
804 pVar
->PutObject( (SbxDimArray
*)xArray
);
805 pVar
->SetFlags( nFlags
);
811 case TypeClass_BOOLEAN
: pVar
->PutBool( *static_cast<sal_Bool
const *>(aValue
.getValue()) ); break;
814 pVar
->PutChar( *static_cast<sal_Unicode
const *>(aValue
.getValue()) );
817 case TypeClass_STRING
: { OUString val
; aValue
>>= val
; pVar
->PutString( val
); } break;
818 case TypeClass_FLOAT
: { float val
= 0; aValue
>>= val
; pVar
->PutSingle( val
); } break;
819 case TypeClass_DOUBLE
: { double val
= 0; aValue
>>= val
; pVar
->PutDouble( val
); } break;
820 case TypeClass_BYTE
: { sal_Int8 val
= 0; aValue
>>= val
; pVar
->PutInteger( val
); } break;
821 case TypeClass_SHORT
: { sal_Int16 val
= 0; aValue
>>= val
; pVar
->PutInteger( val
); } break;
822 case TypeClass_LONG
: { sal_Int32 val
= 0; aValue
>>= val
; pVar
->PutLong( val
); } break;
823 case TypeClass_HYPER
: { sal_Int64 val
= 0; aValue
>>= val
; pVar
->PutInt64( val
); } break;
824 case TypeClass_UNSIGNED_SHORT
: { sal_uInt16 val
= 0; aValue
>>= val
; pVar
->PutUShort( val
); } break;
825 case TypeClass_UNSIGNED_LONG
: { sal_uInt32 val
= 0; aValue
>>= val
; pVar
->PutULong( val
); } break;
826 case TypeClass_UNSIGNED_HYPER
: { sal_uInt64 val
= 0; aValue
>>= val
; pVar
->PutUInt64( val
); } break;
827 default: pVar
->PutEmpty(); break;
831 // Deliver the reflection for Sbx types
832 Type
getUnoTypeForSbxBaseType( SbxDataType eType
)
834 Type aRetType
= cppu::UnoType
<void>::get();
837 case SbxNULL
: aRetType
= cppu::UnoType
<XInterface
>::get(); break;
838 case SbxINTEGER
: aRetType
= cppu::UnoType
<sal_Int16
>::get(); break;
839 case SbxLONG
: aRetType
= cppu::UnoType
<sal_Int32
>::get(); break;
840 case SbxSINGLE
: aRetType
= cppu::UnoType
<float>::get(); break;
841 case SbxDOUBLE
: aRetType
= cppu::UnoType
<double>::get(); break;
842 case SbxCURRENCY
: aRetType
= cppu::UnoType
<oleautomation::Currency
>::get(); break;
843 case SbxDECIMAL
: aRetType
= cppu::UnoType
<oleautomation::Decimal
>::get(); break;
845 SbiInstance
* pInst
= GetSbData()->pInst
;
846 if( pInst
&& pInst
->IsCompatibility() )
847 aRetType
= cppu::UnoType
<double>::get();
849 aRetType
= cppu::UnoType
<oleautomation::Date
>::get();
852 case SbxSTRING
: aRetType
= cppu::UnoType
<OUString
>::get(); break;
853 case SbxBOOL
: aRetType
= cppu::UnoType
<sal_Bool
>::get(); break;
854 case SbxVARIANT
: aRetType
= cppu::UnoType
<Any
>::get(); break;
855 case SbxCHAR
: aRetType
= cppu::UnoType
<cppu::UnoCharType
>::get(); break;
856 case SbxBYTE
: aRetType
= cppu::UnoType
<sal_Int8
>::get(); break;
857 case SbxUSHORT
: aRetType
= cppu::UnoType
<cppu::UnoUnsignedShortType
>::get(); break;
858 case SbxULONG
: aRetType
= ::cppu::UnoType
<sal_uInt32
>::get(); break;
859 // map machine-dependent ones to long for consistency
860 case SbxINT
: aRetType
= ::cppu::UnoType
<sal_Int32
>::get(); break;
861 case SbxUINT
: aRetType
= ::cppu::UnoType
<sal_uInt32
>::get(); break;
867 // Converting of Sbx to Uno without a know target class for TypeClass_ANY
868 Type
getUnoTypeForSbxValue( const SbxValue
* pVal
)
870 Type aRetType
= cppu::UnoType
<void>::get();
874 // convert SbxType to Uno
875 SbxDataType eBaseType
= pVal
->SbxValue::GetType();
876 if( eBaseType
== SbxOBJECT
)
878 SbxBaseRef xObj
= pVal
->GetObject();
881 aRetType
= cppu::UnoType
<XInterface
>::get();
885 if( xObj
->ISA(SbxDimArray
) )
887 SbxBase
* pObj
= static_cast<SbxBase
*>(xObj
);
888 SbxDimArray
* pArray
= static_cast<SbxDimArray
*>(pObj
);
890 short nDims
= pArray
->GetDims();
891 Type aElementType
= getUnoTypeForSbxBaseType( (SbxDataType
)(pArray
->GetType() & 0xfff) );
892 TypeClass eElementTypeClass
= aElementType
.getTypeClass();
894 // Normal case: One dimensional array
895 sal_Int32 nLower
, nUpper
;
896 if( nDims
== 1 && pArray
->GetDim32( 1, nLower
, nUpper
) )
898 if( eElementTypeClass
== TypeClass_VOID
|| eElementTypeClass
== TypeClass_ANY
)
900 // If all elements of the arrays are from the same type, take
901 // this one - otherwise the whole will be considered as Any-Sequence
902 bool bNeedsInit
= true;
904 sal_Int32 nSize
= nUpper
- nLower
+ 1;
905 sal_Int32 nIdx
= nLower
;
906 for( sal_Int32 i
= 0 ; i
< nSize
; i
++,nIdx
++ )
908 // coverity[callee_ptr_arith]
909 SbxVariableRef xVar
= pArray
->Get32( &nIdx
);
910 Type aType
= getUnoTypeForSbxValue( (SbxVariable
*)xVar
);
913 if( aType
.getTypeClass() == TypeClass_VOID
)
915 // if only first element is void: different types -> []any
916 // if all elements are void: []void is not allowed -> []any
917 aElementType
= cppu::UnoType
<Any
>::get();
920 aElementType
= aType
;
923 else if( aElementType
!= aType
)
925 // different types -> AnySequence
926 aElementType
= cppu::UnoType
<Any
>::get();
932 OUString aSeqTypeName
= aSeqLevelStr
+ aElementType
.getTypeName();
933 aRetType
= Type( TypeClass_SEQUENCE
, aSeqTypeName
);
935 // #i33795 Map also multi dimensional arrays to corresponding sequences
938 if( eElementTypeClass
== TypeClass_VOID
|| eElementTypeClass
== TypeClass_ANY
)
940 // For this check the array's dim structure does not matter
941 sal_uInt32 nFlatArraySize
= pArray
->Count32();
943 bool bNeedsInit
= true;
944 for( sal_uInt32 i
= 0 ; i
< nFlatArraySize
; i
++ )
946 SbxVariableRef xVar
= pArray
->SbxArray::Get32( i
);
947 Type aType
= getUnoTypeForSbxValue( (SbxVariable
*)xVar
);
950 if( aType
.getTypeClass() == TypeClass_VOID
)
952 // if only first element is void: different types -> []any
953 // if all elements are void: []void is not allowed -> []any
954 aElementType
= cppu::UnoType
<Any
>::get();
957 aElementType
= aType
;
960 else if( aElementType
!= aType
)
962 // different types -> AnySequence
963 aElementType
= cppu::UnoType
<Any
>::get();
969 OUStringBuffer aSeqTypeName
;
970 for( short iDim
= 0 ; iDim
< nDims
; iDim
++ )
972 aSeqTypeName
.appendAscii(aSeqLevelStr
);
974 aSeqTypeName
.append(aElementType
.getTypeName());
975 aRetType
= Type( TypeClass_SEQUENCE
, aSeqTypeName
.makeStringAndClear() );
979 else if( xObj
->ISA(SbUnoObject
) )
981 aRetType
= static_cast<SbUnoObject
*>((SbxBase
*)xObj
)->getUnoAny().getValueType();
984 else if( xObj
->ISA(SbUnoAnyObject
) )
986 aRetType
= static_cast<SbUnoAnyObject
*>((SbxBase
*)xObj
)->getValue().getValueType();
988 // Otherwise it is a No-Uno-Basic-Object -> default==deliver void
990 // No object, convert basic type
993 aRetType
= getUnoTypeForSbxBaseType( eBaseType
);
998 // converting of Sbx to Uno without known target class for TypeClass_ANY
999 Any
sbxToUnoValueImpl( const SbxValue
* pVar
, bool bBlockConversionToSmallestType
= false )
1001 SbxDataType eBaseType
= pVar
->SbxValue::GetType();
1002 if( eBaseType
== SbxOBJECT
)
1004 SbxBaseRef xObj
= pVar
->GetObject();
1007 if( xObj
->ISA(SbUnoAnyObject
) )
1008 return static_cast<SbUnoAnyObject
*>((SbxBase
*)xObj
)->getValue();
1009 if( xObj
->ISA(SbClassModuleObject
) )
1012 SbClassModuleObject
* pClassModuleObj
= static_cast<SbClassModuleObject
*>((SbxBase
*)xObj
);
1013 SbModule
* pClassModule
= pClassModuleObj
->getClassModule();
1014 if( pClassModule
->createCOMWrapperForIface( aRetAny
, pClassModuleObj
) )
1017 if( !xObj
->ISA(SbUnoObject
) )
1019 // Create NativeObjectWrapper to identify object in case of callbacks
1020 SbxObject
* pObj
= PTR_CAST(SbxObject
,pVar
->GetObject());
1023 NativeObjectWrapper aNativeObjectWrapper
;
1024 sal_uInt32 nIndex
= lcl_registerNativeObjectWrapper( pObj
);
1025 aNativeObjectWrapper
.ObjectId
<<= nIndex
;
1027 aRetAny
<<= aNativeObjectWrapper
;
1034 Type aType
= getUnoTypeForSbxValue( pVar
);
1035 TypeClass eType
= aType
.getTypeClass();
1037 if( !bBlockConversionToSmallestType
)
1039 // #79615 Choose "smallest" represention for int values
1040 // because up cast is allowed, downcast not
1043 case TypeClass_FLOAT
:
1044 case TypeClass_DOUBLE
:
1046 double d
= pVar
->GetDouble();
1047 if( d
== floor( d
) )
1049 if( d
>= -128 && d
<= 127 )
1050 aType
= ::cppu::UnoType
<sal_Int8
>::get();
1051 else if( d
>= SbxMININT
&& d
<= SbxMAXINT
)
1052 aType
= ::cppu::UnoType
<sal_Int16
>::get();
1053 else if( d
>= -SbxMAXLNG
&& d
<= SbxMAXLNG
)
1054 aType
= ::cppu::UnoType
<sal_Int32
>::get();
1058 case TypeClass_SHORT
:
1060 sal_Int16 n
= pVar
->GetInteger();
1061 if( n
>= -128 && n
<= 127 )
1062 aType
= ::cppu::UnoType
<sal_Int8
>::get();
1065 case TypeClass_LONG
:
1067 sal_Int32 n
= pVar
->GetLong();
1068 if( n
>= -128 && n
<= 127 )
1069 aType
= ::cppu::UnoType
<sal_Int8
>::get();
1070 else if( n
>= SbxMININT
&& n
<= SbxMAXINT
)
1071 aType
= ::cppu::UnoType
<sal_Int16
>::get();
1074 case TypeClass_UNSIGNED_SHORT
:
1076 sal_uInt16 n
= pVar
->GetUShort();
1078 aType
= cppu::UnoType
<sal_uInt8
>::get();
1081 case TypeClass_UNSIGNED_LONG
:
1083 sal_uInt32 n
= pVar
->GetLong();
1085 aType
= cppu::UnoType
<sal_uInt8
>::get();
1086 else if( n
<= SbxMAXUINT
)
1087 aType
= cppu::UnoType
<cppu::UnoUnsignedShortType
>::get();
1090 // TODO: need to add hyper types ?
1095 return sbxToUnoValue( pVar
, aType
);
1100 // Helper function for StepREDIMP
1101 static Any
implRekMultiDimArrayToSequence( SbxDimArray
* pArray
,
1102 const Type
& aElemType
, short nMaxDimIndex
, short nActualDim
,
1103 sal_Int32
* pActualIndices
, sal_Int32
* pLowerBounds
, sal_Int32
* pUpperBounds
)
1105 sal_Int32 nSeqLevel
= nMaxDimIndex
- nActualDim
+ 1;
1106 OUStringBuffer aSeqTypeName
;
1108 for( i
= 0 ; i
< nSeqLevel
; i
++ )
1110 aSeqTypeName
.appendAscii(aSeqLevelStr
);
1112 aSeqTypeName
.append(aElemType
.getTypeName());
1113 Type
aSeqType( TypeClass_SEQUENCE
, aSeqTypeName
.makeStringAndClear() );
1115 // Create Sequence instance
1117 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( aSeqType
);
1118 xIdlTargetClass
->createObject( aRetVal
);
1120 // Alloc sequence according to array bounds
1121 sal_Int32 nUpper
= pUpperBounds
[nActualDim
];
1122 sal_Int32 nLower
= pLowerBounds
[nActualDim
];
1123 sal_Int32 nSeqSize
= nUpper
- nLower
+ 1;
1124 Reference
< XIdlArray
> xArray
= xIdlTargetClass
->getArray();
1125 xArray
->realloc( aRetVal
, nSeqSize
);
1127 sal_Int32
& ri
= pActualIndices
[nActualDim
];
1129 for( ri
= nLower
,i
= 0 ; ri
<= nUpper
; ri
++,i
++ )
1133 if( nActualDim
< nMaxDimIndex
)
1135 aElementVal
= implRekMultiDimArrayToSequence( pArray
, aElemType
,
1136 nMaxDimIndex
, nActualDim
+ 1, pActualIndices
, pLowerBounds
, pUpperBounds
);
1140 SbxVariable
* pSource
= pArray
->Get32( pActualIndices
);
1141 aElementVal
= sbxToUnoValue( pSource
, aElemType
);
1146 // transfer to the sequence
1147 xArray
->set( aRetVal
, i
, aElementVal
);
1149 catch( const IllegalArgumentException
& )
1151 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
1152 implGetExceptionMsg( ::cppu::getCaughtException() ) );
1154 catch (const IndexOutOfBoundsException
&)
1156 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
1162 // Map old interface
1163 Any
sbxToUnoValue( const SbxValue
* pVar
)
1165 return sbxToUnoValueImpl( pVar
);
1168 // function to find a global identifier in
1169 // the UnoScope and to wrap it for Sbx
1170 static bool implGetTypeByName( const OUString
& rName
, Type
& rRetType
)
1172 bool bSuccess
= false;
1174 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
1175 if( xTypeAccess
->hasByHierarchicalName( rName
) )
1177 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
1178 Reference
< XTypeDescription
> xTypeDesc
;
1181 if( xTypeDesc
.is() )
1183 rRetType
= Type( xTypeDesc
->getTypeClass(), xTypeDesc
->getName() );
1191 // converting of Sbx to Uno with known target class
1192 Any
sbxToUnoValue( const SbxValue
* pVar
, const Type
& rType
, Property
* pUnoProperty
)
1196 // #94560 No conversion of empty/void for MAYBE_VOID properties
1197 if( pUnoProperty
&& pUnoProperty
->Attributes
& PropertyAttribute::MAYBEVOID
)
1199 if( pVar
->IsEmpty() )
1203 SbxDataType eBaseType
= pVar
->SbxValue::GetType();
1204 if( eBaseType
== SbxOBJECT
)
1206 SbxBaseRef xObj
= pVar
->GetObject();
1207 if( xObj
.Is() && xObj
->ISA(SbUnoAnyObject
) )
1209 return static_cast<SbUnoAnyObject
*>((SbxBase
*)xObj
)->getValue();
1213 TypeClass eType
= rType
.getTypeClass();
1216 case TypeClass_INTERFACE
:
1217 case TypeClass_STRUCT
:
1218 case TypeClass_EXCEPTION
:
1220 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( rType
);
1223 if( pVar
->IsNull() && eType
== TypeClass_INTERFACE
)
1225 Reference
< XInterface
> xRef
;
1226 OUString aClassName
= xIdlTargetClass
->getName();
1227 Type
aClassType( xIdlTargetClass
->getTypeClass(), aClassName
.getStr() );
1228 aRetVal
.setValue( &xRef
, aClassType
);
1232 // #112368 Special conversion for Decimal, Currency and Date
1233 if( eType
== TypeClass_STRUCT
)
1235 SbiInstance
* pInst
= GetSbData()->pInst
;
1236 if( pInst
&& pInst
->IsCompatibility() )
1238 if( rType
== cppu::UnoType
<oleautomation::Decimal
>::get())
1240 oleautomation::Decimal aDecimal
;
1241 pVar
->fillAutomationDecimal( aDecimal
);
1242 aRetVal
<<= aDecimal
;
1245 else if( rType
== cppu::UnoType
<oleautomation::Currency
>::get())
1247 // assumes per previous code that ole Currency is Int64
1248 aRetVal
<<= (sal_Int64
)( pVar
->GetInt64() );
1251 else if( rType
== cppu::UnoType
<oleautomation::Date
>::get())
1253 oleautomation::Date aDate
;
1254 aDate
.Value
= pVar
->GetDate();
1261 SbxBaseRef pObj
= pVar
->GetObject();
1262 if( pObj
&& pObj
->ISA(SbUnoObject
) )
1264 aRetVal
= static_cast<SbUnoObject
*>((SbxBase
*)pObj
)->getUnoAny();
1266 else if( pObj
&& pObj
->ISA(SbUnoStructRefObject
) )
1268 aRetVal
= static_cast<SbUnoStructRefObject
*>((SbxBase
*)pObj
)->getUnoAny();
1272 // null object -> null XInterface
1273 Reference
<XInterface
> xInt
;
1280 case TypeClass_TYPE
:
1282 if( eBaseType
== SbxOBJECT
)
1285 Reference
< XIdlClass
> xIdlClass
;
1287 SbxBaseRef pObj
= pVar
->GetObject();
1288 if( pObj
&& pObj
->ISA(SbUnoObject
) )
1290 Any aUnoAny
= static_cast<SbUnoObject
*>((SbxBase
*)pObj
)->getUnoAny();
1291 aUnoAny
>>= xIdlClass
;
1294 if( xIdlClass
.is() )
1296 OUString aClassName
= xIdlClass
->getName();
1297 Type
aType( xIdlClass
->getTypeClass(), aClassName
.getStr() );
1301 else if( eBaseType
== SbxSTRING
)
1303 OUString aTypeName
= pVar
->GetOUString();
1305 bool bSuccess
= implGetTypeByName( aTypeName
, aType
);
1315 case TypeClass_ENUM
:
1317 aRetVal
= int2enum( pVar
->GetLong(), rType
);
1321 case TypeClass_SEQUENCE
:
1323 SbxBaseRef xObj
= pVar
->GetObject();
1324 if( xObj
&& xObj
->ISA(SbxDimArray
) )
1326 SbxBase
* pObj
= static_cast<SbxBase
*>(xObj
);
1327 SbxDimArray
* pArray
= static_cast<SbxDimArray
*>(pObj
);
1329 short nDims
= pArray
->GetDims();
1331 // Normal case: One dimensional array
1332 sal_Int32 nLower
, nUpper
;
1333 if( nDims
== 1 && pArray
->GetDim32( 1, nLower
, nUpper
) )
1335 sal_Int32 nSeqSize
= nUpper
- nLower
+ 1;
1337 // create the instance of the required sequence
1338 Reference
< XIdlClass
> xIdlTargetClass
= TypeToIdlClass( rType
);
1339 xIdlTargetClass
->createObject( aRetVal
);
1340 Reference
< XIdlArray
> xArray
= xIdlTargetClass
->getArray();
1341 xArray
->realloc( aRetVal
, nSeqSize
);
1344 OUString aClassName
= xIdlTargetClass
->getName();
1345 typelib_TypeDescription
* pSeqTD
= 0;
1346 typelib_typedescription_getByName( &pSeqTD
, aClassName
.pData
);
1347 OSL_ASSERT( pSeqTD
);
1348 Type
aElemType( reinterpret_cast<typelib_IndirectTypeDescription
*>(pSeqTD
)->pType
);
1350 // convert all array member and register them
1351 sal_Int32 nIdx
= nLower
;
1352 for( sal_Int32 i
= 0 ; i
< nSeqSize
; i
++,nIdx
++ )
1354 // coverity[callee_ptr_arith]
1355 SbxVariableRef xVar
= pArray
->Get32( &nIdx
);
1357 // Convert the value of Sbx to Uno
1358 Any aAnyValue
= sbxToUnoValue( (SbxVariable
*)xVar
, aElemType
);
1362 // insert in the sequence
1363 xArray
->set( aRetVal
, i
, aAnyValue
);
1365 catch( const IllegalArgumentException
& )
1367 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
1368 implGetExceptionMsg( ::cppu::getCaughtException() ) );
1370 catch (const IndexOutOfBoundsException
&)
1372 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
1376 // #i33795 Map also multi dimensional arrays to corresponding sequences
1377 else if( nDims
> 1 )
1380 typelib_TypeDescription
* pSeqTD
= 0;
1381 Type
aCurType( rType
);
1382 sal_Int32 nSeqLevel
= 0;
1386 OUString aTypeName
= aCurType
.getTypeName();
1387 typelib_typedescription_getByName( &pSeqTD
, aTypeName
.pData
);
1388 OSL_ASSERT( pSeqTD
);
1389 if( pSeqTD
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1391 aCurType
= Type( reinterpret_cast<typelib_IndirectTypeDescription
*>(pSeqTD
)->pType
);
1396 aElemType
= aCurType
;
1402 if( nSeqLevel
== nDims
)
1404 boost::scoped_array
<sal_Int32
> pLowerBounds(new sal_Int32
[nDims
]);
1405 boost::scoped_array
<sal_Int32
> pUpperBounds(new sal_Int32
[nDims
]);
1406 boost::scoped_array
<sal_Int32
> pActualIndices(new sal_Int32
[nDims
]);
1407 for( short i
= 1 ; i
<= nDims
; i
++ )
1409 sal_Int32 lBound
, uBound
;
1410 pArray
->GetDim32( i
, lBound
, uBound
);
1413 pActualIndices
[j
] = pLowerBounds
[j
] = lBound
;
1414 pUpperBounds
[j
] = uBound
;
1417 aRetVal
= implRekMultiDimArrayToSequence( pArray
, aElemType
,
1418 nDims
- 1, 0, pActualIndices
.get(), pLowerBounds
.get(), pUpperBounds
.get() );
1426 // for Any use the class independent converting routine
1429 aRetVal
= sbxToUnoValueImpl( pVar
);
1433 case TypeClass_BOOLEAN
:
1435 sal_Bool b
= pVar
->GetBool();
1436 aRetVal
.setValue( &b
, cppu::UnoType
<bool>::get() );
1439 case TypeClass_CHAR
:
1441 sal_Unicode c
= pVar
->GetChar();
1442 aRetVal
.setValue( &c
, cppu::UnoType
<cppu::UnoCharType
>::get() );
1445 case TypeClass_STRING
: aRetVal
<<= pVar
->GetOUString(); break;
1446 case TypeClass_FLOAT
: aRetVal
<<= pVar
->GetSingle(); break;
1447 case TypeClass_DOUBLE
: aRetVal
<<= pVar
->GetDouble(); break;
1449 case TypeClass_BYTE
:
1451 sal_Int16 nVal
= pVar
->GetInteger();
1452 bool bOverflow
= false;
1458 else if( nVal
> 127 )
1464 StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW
);
1466 sal_Int8 nByteVal
= (sal_Int8
)nVal
;
1467 aRetVal
<<= nByteVal
;
1470 case TypeClass_SHORT
: aRetVal
<<= (sal_Int16
)( pVar
->GetInteger() ); break;
1471 case TypeClass_LONG
: aRetVal
<<= (sal_Int32
)( pVar
->GetLong() ); break;
1472 case TypeClass_HYPER
: aRetVal
<<= (sal_Int64
)( pVar
->GetInt64() ); break;
1473 case TypeClass_UNSIGNED_SHORT
: aRetVal
<<= (sal_uInt16
)( pVar
->GetUShort() ); break;
1474 case TypeClass_UNSIGNED_LONG
: aRetVal
<<= (sal_uInt32
)( pVar
->GetULong() ); break;
1475 case TypeClass_UNSIGNED_HYPER
: aRetVal
<<= (sal_uInt64
)( pVar
->GetUInt64() ); break;
1482 void processAutomationParams( SbxArray
* pParams
, Sequence
< Any
>& args
, bool bOLEAutomation
, sal_uInt32 nParamCount
)
1484 AutomationNamedArgsSbxArray
* pArgNamesArray
= NULL
;
1485 if( bOLEAutomation
)
1486 pArgNamesArray
= PTR_CAST(AutomationNamedArgsSbxArray
,pParams
);
1488 args
.realloc( nParamCount
);
1489 Any
* pAnyArgs
= args
.getArray();
1490 bool bBlockConversionToSmallestType
= GetSbData()->pInst
->IsCompatibility();
1492 if( pArgNamesArray
)
1494 Sequence
< OUString
>& rNameSeq
= pArgNamesArray
->getNames();
1495 OUString
* pNames
= rNameSeq
.getArray();
1497 for( i
= 0 ; i
< nParamCount
; i
++ )
1499 sal_uInt16 iSbx
= (sal_uInt16
)(i
+1);
1501 aValAny
= sbxToUnoValueImpl( pParams
->Get( iSbx
),
1502 bBlockConversionToSmallestType
);
1504 OUString aParamName
= pNames
[iSbx
];
1505 if( !aParamName
.isEmpty() )
1507 oleautomation::NamedArgument aNamedArgument
;
1508 aNamedArgument
.Name
= aParamName
;
1509 aNamedArgument
.Value
= aValAny
;
1510 pAnyArgs
[i
] <<= aNamedArgument
;
1514 pAnyArgs
[i
] = aValAny
;
1520 for( i
= 0 ; i
< nParamCount
; i
++ )
1522 pAnyArgs
[i
] = sbxToUnoValueImpl( pParams
->Get( (sal_uInt16
)(i
+1) ),
1523 bBlockConversionToSmallestType
);
1534 Any
invokeAutomationMethod( const OUString
& Name
, Sequence
< Any
>& args
, SbxArray
* pParams
, sal_uInt32 nParamCount
, Reference
< XInvocation
>& rxInvocation
, INVOKETYPE invokeType
= Func
)
1536 Sequence
< sal_Int16
> OutParamIndex
;
1537 Sequence
< Any
> OutParam
;
1540 switch( invokeType
)
1543 aRetAny
= rxInvocation
->invoke( Name
, args
, OutParamIndex
, OutParam
);
1547 Reference
< XAutomationInvocation
> xAutoInv( rxInvocation
, UNO_QUERY
);
1548 aRetAny
= xAutoInv
->invokeGetProperty( Name
, args
, OutParamIndex
, OutParam
);
1553 Reference
< XAutomationInvocation
> xAutoInv( rxInvocation
, UNO_QUERY_THROW
);
1554 aRetAny
= xAutoInv
->invokePutProperty( Name
, args
, OutParamIndex
, OutParam
);
1558 break; // should introduce an error here
1561 const sal_Int16
* pIndices
= OutParamIndex
.getConstArray();
1562 sal_uInt32 nLen
= OutParamIndex
.getLength();
1565 const Any
* pNewValues
= OutParam
.getConstArray();
1566 for( sal_uInt32 j
= 0 ; j
< nLen
; j
++ )
1568 sal_Int16 iTarget
= pIndices
[ j
];
1569 if( iTarget
>= (sal_Int16
)nParamCount
)
1571 unoToSbxValue( pParams
->Get( (sal_uInt16
)(j
+1) ), pNewValues
[ j
] );
1577 // Debugging help method to readout the imlemented interfaces of an object
1578 OUString
Impl_GetInterfaceInfo( const Reference
< XInterface
>& x
, const Reference
< XIdlClass
>& xClass
, sal_uInt16 nRekLevel
)
1580 Type aIfaceType
= cppu::UnoType
<XInterface
>::get();
1581 static Reference
< XIdlClass
> xIfaceClass
= TypeToIdlClass( aIfaceType
);
1583 OUStringBuffer aRetStr
;
1584 for( sal_uInt16 i
= 0 ; i
< nRekLevel
; i
++ )
1585 aRetStr
.appendAscii( " " );
1586 aRetStr
.append( xClass
->getName() );
1587 OUString aClassName
= xClass
->getName();
1588 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
1590 // checking if the interface is really supported
1591 if( !x
->queryInterface( aClassType
).hasValue() )
1593 aRetStr
.appendAscii( " (ERROR: Not really supported!)\n" );
1595 // Are there super interfaces?
1598 aRetStr
.appendAscii( "\n" );
1600 // get the super interfaces
1601 Sequence
< Reference
< XIdlClass
> > aSuperClassSeq
= xClass
->getSuperclasses();
1602 const Reference
< XIdlClass
>* pClasses
= aSuperClassSeq
.getConstArray();
1603 sal_uInt32 nSuperIfaceCount
= aSuperClassSeq
.getLength();
1604 for( sal_uInt32 j
= 0 ; j
< nSuperIfaceCount
; j
++ )
1606 const Reference
< XIdlClass
>& rxIfaceClass
= pClasses
[j
];
1607 if( !rxIfaceClass
->equals( xIfaceClass
) )
1608 aRetStr
.append( Impl_GetInterfaceInfo( x
, rxIfaceClass
, nRekLevel
+ 1 ) );
1611 return aRetStr
.makeStringAndClear();
1614 OUString
getDbgObjectNameImpl( SbUnoObject
* pUnoObj
)
1619 aName
= pUnoObj
->GetClassName();
1620 if( aName
.isEmpty() )
1622 Any aToInspectObj
= pUnoObj
->getUnoAny();
1623 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1624 Reference
< XInterface
> xObj
;
1625 if( eType
== TypeClass_INTERFACE
)
1626 xObj
= *static_cast<Reference
< XInterface
> const *>(aToInspectObj
.getValue());
1629 Reference
< XServiceInfo
> xServiceInfo( xObj
, UNO_QUERY
);
1630 if( xServiceInfo
.is() )
1631 aName
= xServiceInfo
->getImplementationName();
1638 OUString
getDbgObjectName( SbUnoObject
* pUnoObj
)
1640 OUString aName
= getDbgObjectNameImpl( pUnoObj
);
1641 if( aName
.isEmpty() )
1644 OUStringBuffer aRet
;
1645 if( aName
.getLength() > 20 )
1647 aRet
.appendAscii( "\n" );
1649 aRet
.appendAscii( "\"" );
1650 aRet
.append( aName
);
1651 aRet
.appendAscii( "\":" );
1652 return aRet
.makeStringAndClear();
1655 OUString
getBasicObjectTypeName( SbxObject
* pObj
)
1660 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
1661 SbUnoStructRefObject
* pUnoStructObj
= PTR_CAST(SbUnoStructRefObject
,pObj
);
1663 aName
= getDbgObjectNameImpl( pUnoObj
);
1664 else if ( pUnoStructObj
)
1665 aName
= pUnoStructObj
->GetClassName();
1670 bool checkUnoObjectType( SbUnoObject
* pUnoObj
, const OUString
& rClass
)
1672 Any aToInspectObj
= pUnoObj
->getUnoAny();
1673 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1674 if( eType
!= TypeClass_INTERFACE
)
1678 const Reference
< XInterface
> x
= *static_cast<Reference
< XInterface
> const *>(aToInspectObj
.getValue());
1680 // Return true for XInvocation based objects as interface type names don't count then
1681 Reference
< XInvocation
> xInvocation( x
, UNO_QUERY
);
1682 if( xInvocation
.is() )
1686 bool result
= false;
1687 Reference
< XTypeProvider
> xTypeProvider( x
, UNO_QUERY
);
1688 if( xTypeProvider
.is() )
1690 /* Although interfaces in the ooo.vba namespace obey the IDL rules and
1691 have a leading 'X', in Basic we want to be able to do something
1692 like 'Dim wb As Workbooks' or 'Dim lb As MSForms.Label'. Here we
1693 add a leading 'X' to the class name and a leading dot to the entire
1694 type name. This results e.g. in '.XWorkbooks' or '.MSForms.XLabel'
1695 which matches the interface names 'ooo.vba.excel.XWorkbooks' or
1696 'ooo.vba.msforms.XLabel'.
1698 OUString aClassName
;
1699 if ( SbiRuntime::isVBAEnabled() )
1702 sal_Int32 nClassNameDot
= rClass
.lastIndexOf( '.' );
1703 if( nClassNameDot
>= 0 )
1705 aClassName
+= rClass
.copy( 0, nClassNameDot
+ 1 ) + "X" + rClass
.copy( nClassNameDot
+ 1 );
1709 aClassName
+= "X" + rClass
;
1712 else // assume extended type declaration support for basic ( can't get here
1714 aClassName
= rClass
;
1716 Sequence
< Type
> aTypeSeq
= xTypeProvider
->getTypes();
1717 const Type
* pTypeArray
= aTypeSeq
.getConstArray();
1718 sal_uInt32 nIfaceCount
= aTypeSeq
.getLength();
1719 for( sal_uInt32 j
= 0 ; j
< nIfaceCount
; j
++ )
1721 const Type
& rType
= pTypeArray
[j
];
1723 Reference
<XIdlClass
> xClass
= TypeToIdlClass( rType
);
1726 OSL_FAIL("failed to get XIdlClass for type");
1729 OUString aInterfaceName
= xClass
->getName();
1730 if ( aInterfaceName
== "com.sun.star.bridge.oleautomation.XAutomationObject" )
1732 // there is a hack in the extensions/source/ole/oleobj.cxx to return the typename of the automation object, lets check if it
1734 Reference
< XInvocation
> xInv( aToInspectObj
, UNO_QUERY
);
1738 xInv
->getValue( OUString( "$GetTypeName" ) ) >>= sTypeName
;
1739 if ( sTypeName
.isEmpty() || sTypeName
== "IDispatch" )
1741 // can't check type, leave it pass
1746 result
= sTypeName
.equals( rClass
);
1749 break; // finished checking automation object
1752 // match interface name with passed class name
1753 OSL_TRACE("Checking if object implements %s", OUStringToOString( aClassName
, RTL_TEXTENCODING_UTF8
).getStr() );
1754 if ( (aClassName
.getLength() <= aInterfaceName
.getLength()) &&
1755 aInterfaceName
.endsWithIgnoreAsciiCase( aClassName
) )
1765 // Debugging help method to readout the imlemented interfaces of an object
1766 OUString
Impl_GetSupportedInterfaces( SbUnoObject
* pUnoObj
)
1768 Any aToInspectObj
= pUnoObj
->getUnoAny();
1770 // allow only TypeClass interface
1771 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1772 OUStringBuffer aRet
;
1773 if( eType
!= TypeClass_INTERFACE
)
1775 aRet
.appendAscii( ID_DBG_SUPPORTEDINTERFACES
);
1776 aRet
.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
1780 // get the interface from the Any
1781 const Reference
< XInterface
> x
= *static_cast<Reference
< XInterface
> const *>(aToInspectObj
.getValue());
1783 Reference
< XTypeProvider
> xTypeProvider( x
, UNO_QUERY
);
1785 aRet
.appendAscii( "Supported interfaces by object " );
1786 aRet
.append( getDbgObjectName( pUnoObj
) );
1787 aRet
.appendAscii( "\n" );
1788 if( xTypeProvider
.is() )
1790 // get the interfaces of the implementation
1791 Sequence
< Type
> aTypeSeq
= xTypeProvider
->getTypes();
1792 const Type
* pTypeArray
= aTypeSeq
.getConstArray();
1793 sal_uInt32 nIfaceCount
= aTypeSeq
.getLength();
1794 for( sal_uInt32 j
= 0 ; j
< nIfaceCount
; j
++ )
1796 const Type
& rType
= pTypeArray
[j
];
1798 Reference
<XIdlClass
> xClass
= TypeToIdlClass( rType
);
1801 aRet
.append( Impl_GetInterfaceInfo( x
, xClass
, 1 ) );
1805 typelib_TypeDescription
* pTD
= 0;
1806 rType
.getDescription( &pTD
);
1808 aRet
.appendAscii( "*** ERROR: No IdlClass for type \"" );
1809 aRet
.append( pTD
->pTypeName
);
1810 aRet
.appendAscii( "\"\n*** Please check type library\n" );
1815 return aRet
.makeStringAndClear();
1820 // Debugging help method SbxDataType -> String
1821 OUString
Dbg_SbxDataType2String( SbxDataType eType
)
1823 OUStringBuffer aRet
;
1826 case SbxEMPTY
: aRet
.appendAscii("SbxEMPTY"); break;
1827 case SbxNULL
: aRet
.appendAscii("SbxNULL"); break;
1828 case SbxINTEGER
: aRet
.appendAscii("SbxINTEGER"); break;
1829 case SbxLONG
: aRet
.appendAscii("SbxLONG"); break;
1830 case SbxSINGLE
: aRet
.appendAscii("SbxSINGLE"); break;
1831 case SbxDOUBLE
: aRet
.appendAscii("SbxDOUBLE"); break;
1832 case SbxCURRENCY
: aRet
.appendAscii("SbxCURRENCY"); break;
1833 case SbxDECIMAL
: aRet
.appendAscii("SbxDECIMAL"); break;
1834 case SbxDATE
: aRet
.appendAscii("SbxDATE"); break;
1835 case SbxSTRING
: aRet
.appendAscii("SbxSTRING"); break;
1836 case SbxOBJECT
: aRet
.appendAscii("SbxOBJECT"); break;
1837 case SbxERROR
: aRet
.appendAscii("SbxERROR"); break;
1838 case SbxBOOL
: aRet
.appendAscii("SbxBOOL"); break;
1839 case SbxVARIANT
: aRet
.appendAscii("SbxVARIANT"); break;
1840 case SbxDATAOBJECT
: aRet
.appendAscii("SbxDATAOBJECT"); break;
1841 case SbxCHAR
: aRet
.appendAscii("SbxCHAR"); break;
1842 case SbxBYTE
: aRet
.appendAscii("SbxBYTE"); break;
1843 case SbxUSHORT
: aRet
.appendAscii("SbxUSHORT"); break;
1844 case SbxULONG
: aRet
.appendAscii("SbxULONG"); break;
1845 case SbxSALINT64
: aRet
.appendAscii("SbxINT64"); break;
1846 case SbxSALUINT64
: aRet
.appendAscii("SbxUINT64"); break;
1847 case SbxINT
: aRet
.appendAscii("SbxINT"); break;
1848 case SbxUINT
: aRet
.appendAscii("SbxUINT"); break;
1849 case SbxVOID
: aRet
.appendAscii("SbxVOID"); break;
1850 case SbxHRESULT
: aRet
.appendAscii("SbxHRESULT"); break;
1851 case SbxPOINTER
: aRet
.appendAscii("SbxPOINTER"); break;
1852 case SbxDIMARRAY
: aRet
.appendAscii("SbxDIMARRAY"); break;
1853 case SbxCARRAY
: aRet
.appendAscii("SbxCARRAY"); break;
1854 case SbxUSERDEF
: aRet
.appendAscii("SbxUSERDEF"); break;
1855 case SbxLPSTR
: aRet
.appendAscii("SbxLPSTR"); break;
1856 case SbxLPWSTR
: aRet
.appendAscii("SbxLPWSTR"); break;
1857 case SbxCoreSTRING
: aRet
.appendAscii("SbxCoreSTRING"); break;
1858 case SbxOBJECT
| SbxARRAY
: aRet
.appendAscii("SbxARRAY"); break;
1859 default: aRet
.appendAscii("Unknown Sbx-Type!");break;
1861 return aRet
.makeStringAndClear();
1864 // Debugging help method to display the properties of a SbUnoObjects
1865 OUString
Impl_DumpProperties( SbUnoObject
* pUnoObj
)
1867 OUStringBuffer aRet
;
1868 aRet
.appendAscii("Properties of object ");
1869 aRet
.append( getDbgObjectName( pUnoObj
) );
1871 // analyse the Uno-Infos to recognise the arrays
1872 Reference
< XIntrospectionAccess
> xAccess
= pUnoObj
->getIntrospectionAccess();
1875 Reference
< XInvocation
> xInvok
= pUnoObj
->getInvocation();
1877 xAccess
= xInvok
->getIntrospection();
1881 aRet
.appendAscii( "\nUnknown, no introspection available\n" );
1882 return aRet
.makeStringAndClear();
1885 Sequence
<Property
> props
= xAccess
->getProperties( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
1886 sal_uInt32 nUnoPropCount
= props
.getLength();
1887 const Property
* pUnoProps
= props
.getConstArray();
1889 SbxArray
* pProps
= pUnoObj
->GetProperties();
1890 sal_uInt16 nPropCount
= pProps
->Count();
1891 sal_uInt16 nPropsPerLine
= 1 + nPropCount
/ 30;
1892 for( sal_uInt16 i
= 0; i
< nPropCount
; i
++ )
1894 SbxVariable
* pVar
= pProps
->Get( i
);
1897 OUStringBuffer aPropStr
;
1898 if( (i
% nPropsPerLine
) == 0 )
1899 aPropStr
.appendAscii( "\n" );
1901 // output the type and name
1902 // Is it in Uno a sequence?
1903 SbxDataType eType
= pVar
->GetFullType();
1905 bool bMaybeVoid
= false;
1906 if( i
< nUnoPropCount
)
1908 const Property
& rProp
= pUnoProps
[ i
];
1910 // For MAYBEVOID freshly convert the type from Uno,
1911 // so not just SbxEMPTY is returned.
1912 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
1914 eType
= unoToSbxType( rProp
.Type
.getTypeClass() );
1917 if( eType
== SbxOBJECT
)
1919 Type aType
= rProp
.Type
;
1920 if( aType
.getTypeClass() == TypeClass_SEQUENCE
)
1921 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
1924 aPropStr
.append( Dbg_SbxDataType2String( eType
) );
1926 aPropStr
.appendAscii( "/void" );
1927 aPropStr
.appendAscii( " " );
1928 aPropStr
.append( pVar
->GetName() );
1930 if( i
== nPropCount
- 1 )
1931 aPropStr
.appendAscii( "\n" );
1933 aPropStr
.appendAscii( "; " );
1935 aRet
.append( aPropStr
.makeStringAndClear() );
1938 return aRet
.makeStringAndClear();
1941 // Debugging help method to display the methods of an SbUnoObjects
1942 OUString
Impl_DumpMethods( SbUnoObject
* pUnoObj
)
1944 OUStringBuffer aRet
;
1945 aRet
.appendAscii("Methods of object ");
1946 aRet
.append( getDbgObjectName( pUnoObj
) );
1948 // XIntrospectionAccess, so that the types of the parameter could be outputed
1949 Reference
< XIntrospectionAccess
> xAccess
= pUnoObj
->getIntrospectionAccess();
1952 Reference
< XInvocation
> xInvok
= pUnoObj
->getInvocation();
1954 xAccess
= xInvok
->getIntrospection();
1958 aRet
.appendAscii( "\nUnknown, no introspection available\n" );
1959 return aRet
.makeStringAndClear();
1961 Sequence
< Reference
< XIdlMethod
> > methods
= xAccess
->getMethods
1962 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
1963 const Reference
< XIdlMethod
>* pUnoMethods
= methods
.getConstArray();
1965 SbxArray
* pMethods
= pUnoObj
->GetMethods();
1966 sal_uInt16 nMethodCount
= pMethods
->Count();
1969 aRet
.appendAscii( "\nNo methods found\n" );
1970 return aRet
.makeStringAndClear();
1972 sal_uInt16 nPropsPerLine
= 1 + nMethodCount
/ 30;
1973 for( sal_uInt16 i
= 0; i
< nMethodCount
; i
++ )
1975 SbxVariable
* pVar
= pMethods
->Get( i
);
1978 if( (i
% nPropsPerLine
) == 0 )
1979 aRet
.appendAscii( "\n" );
1981 // address the method
1982 const Reference
< XIdlMethod
>& rxMethod
= pUnoMethods
[i
];
1984 // Is it in Uno a sequence?
1985 SbxDataType eType
= pVar
->GetFullType();
1986 if( eType
== SbxOBJECT
)
1988 Reference
< XIdlClass
> xClass
= rxMethod
->getReturnType();
1989 if( xClass
.is() && xClass
->getTypeClass() == TypeClass_SEQUENCE
)
1990 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
1992 // output the name and the type
1993 aRet
.append( Dbg_SbxDataType2String( eType
) );
1994 aRet
.appendAscii( " " );
1995 aRet
.append ( pVar
->GetName() );
1996 aRet
.appendAscii( " ( " );
1998 // the get-method mustn't have a parameter
1999 Sequence
< Reference
< XIdlClass
> > aParamsSeq
= rxMethod
->getParameterTypes();
2000 sal_uInt32 nParamCount
= aParamsSeq
.getLength();
2001 const Reference
< XIdlClass
>* pParams
= aParamsSeq
.getConstArray();
2003 if( nParamCount
> 0 )
2005 for( sal_uInt16 j
= 0; j
< nParamCount
; j
++ )
2007 aRet
.append ( Dbg_SbxDataType2String( unoToSbxType( pParams
[ j
] ) ) );
2008 if( j
< nParamCount
- 1 )
2009 aRet
.appendAscii( ", " );
2013 aRet
.appendAscii( "void" );
2015 aRet
.appendAscii( " ) " );
2017 if( i
== nMethodCount
- 1 )
2018 aRet
.appendAscii( "\n" );
2020 aRet
.appendAscii( "; " );
2023 return aRet
.makeStringAndClear();
2026 TYPEINIT1(AutomationNamedArgsSbxArray
,SbxArray
)
2028 // Implementation SbUnoObject
2029 void SbUnoObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
2030 const SfxHint
& rHint
, const TypeId
& rHintType
)
2032 if( bNeedIntrospection
)
2035 const SbxHint
* pHint
= dynamic_cast<const SbxHint
*>(&rHint
);
2038 SbxVariable
* pVar
= pHint
->GetVar();
2039 SbxArray
* pParams
= pVar
->GetParameters();
2040 SbUnoProperty
* pProp
= PTR_CAST(SbUnoProperty
,pVar
);
2041 SbUnoMethod
* pMeth
= PTR_CAST(SbUnoMethod
,pVar
);
2044 bool bInvocation
= pProp
->isInvocationBased();
2045 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
2048 sal_Int32 nId
= pProp
->nId
;
2051 // Id == -1: Display implemented interfaces according the ClassProvider
2052 if( nId
== -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
2054 OUString aRetStr
= Impl_GetSupportedInterfaces( this );
2055 pVar
->PutString( aRetStr
);
2057 // Id == -2: output properties
2058 else if( nId
== -2 ) // Property ID_DBG_PROPERTIES
2060 // now all properties must be created
2062 OUString aRetStr
= Impl_DumpProperties( this );
2063 pVar
->PutString( aRetStr
);
2065 // Id == -3: output the methods
2066 else if( nId
== -3 ) // Property ID_DBG_METHODS
2068 // now all properties must be created
2070 OUString aRetStr
= Impl_DumpMethods( this );
2071 pVar
->PutString( aRetStr
);
2076 if( !bInvocation
&& mxUnoAccess
.is() )
2080 if ( maStructInfo
.get() )
2082 StructRefInfo aMember
= maStructInfo
->getStructMember( pProp
->GetName() );
2083 if ( aMember
.isEmpty() )
2085 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
2089 if ( pProp
->isUnoStruct() )
2091 SbUnoStructRefObject
* pSbUnoObject
= new SbUnoStructRefObject( pProp
->GetName(), aMember
);
2092 SbxObjectRef xWrapper
= (SbxObject
*)pSbUnoObject
;
2093 pVar
->PutObject( xWrapper
);
2097 Any aRetAny
= aMember
.getValue();
2098 // take over the value from Uno to Sbx
2099 unoToSbxValue( pVar
, aRetAny
);
2105 Reference
< XPropertySet
> xPropSet( mxUnoAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()), UNO_QUERY
);
2106 Any aRetAny
= xPropSet
->getPropertyValue( pProp
->GetName() );
2107 // The use of getPropertyValue (instead of using the index) is
2108 // suboptimal, but the refactoring to XInvocation is already pending
2109 // Otherwise it is possible to use FastPropertySet
2111 // take over the value from Uno to Sbx
2112 unoToSbxValue( pVar
, aRetAny
);
2114 catch( const Exception
& )
2116 implHandleAnyException( ::cppu::getCaughtException() );
2119 else if( bInvocation
&& mxInvocation
.is() )
2123 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
2124 bool bCanBeConsideredAMethod
= mxInvocation
->hasMethod( pProp
->GetName() );
2126 if ( bCanBeConsideredAMethod
&& nParamCount
)
2128 // Automation properties have methods, so.. we need to invoke this through
2131 processAutomationParams( pParams
, args
, true, nParamCount
);
2132 aRetAny
= invokeAutomationMethod( pProp
->GetName(), args
, pParams
, nParamCount
, mxInvocation
, GetProp
);
2135 aRetAny
= mxInvocation
->getValue( pProp
->GetName() );
2136 // take over the value from Uno to Sbx
2137 unoToSbxValue( pVar
, aRetAny
);
2138 if( pParams
&& bCanBeConsideredAMethod
)
2139 pVar
->SetParameters( NULL
);
2142 catch( const Exception
& )
2144 implHandleAnyException( ::cppu::getCaughtException() );
2148 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
2150 if( !bInvocation
&& mxUnoAccess
.is() )
2152 if( pProp
->aUnoProp
.Attributes
& PropertyAttribute::READONLY
)
2154 StarBASIC::Error( SbERR_PROP_READONLY
);
2157 if ( maStructInfo
.get() )
2159 StructRefInfo aMember
= maStructInfo
->getStructMember( pProp
->GetName() );
2160 if ( aMember
.isEmpty() )
2162 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
2166 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
2167 aMember
.setValue( aAnyValue
);
2171 // take over the value from Uno to Sbx
2172 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
2176 Reference
< XPropertySet
> xPropSet( mxUnoAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()), UNO_QUERY
);
2177 xPropSet
->setPropertyValue( pProp
->GetName(), aAnyValue
);
2178 // The use of getPropertyValue (instead of using the index) is
2179 // suboptimal, but the refactoring to XInvocation is already pending
2180 // Otherwise it is possible to use FastPropertySet
2182 catch( const Exception
& )
2184 implHandleAnyException( ::cppu::getCaughtException() );
2187 else if( bInvocation
&& mxInvocation
.is() )
2189 // take over the value from Uno to Sbx
2190 Any aAnyValue
= sbxToUnoValueImpl( pVar
);
2194 mxInvocation
->setValue( pProp
->GetName(), aAnyValue
);
2196 catch( const Exception
& )
2198 implHandleAnyException( ::cppu::getCaughtException() );
2205 bool bInvocation
= pMeth
->isInvocationBased();
2206 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
2208 // number of Parameter -1 because of Param0 == this
2209 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
2211 bool bOutParams
= false;
2214 if( !bInvocation
&& mxUnoAccess
.is() )
2217 const Sequence
<ParamInfo
>& rInfoSeq
= pMeth
->getParamInfos();
2218 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2219 sal_uInt32 nUnoParamCount
= rInfoSeq
.getLength();
2220 sal_uInt32 nAllocParamCount
= nParamCount
;
2222 // ignore surplus parameter; alternative: throw an error
2223 if( nParamCount
> nUnoParamCount
)
2225 nParamCount
= nUnoParamCount
;
2226 nAllocParamCount
= nParamCount
;
2228 else if( nParamCount
< nUnoParamCount
)
2230 SbiInstance
* pInst
= GetSbData()->pInst
;
2231 if( pInst
&& pInst
->IsCompatibility() )
2234 bool bError
= false;
2235 for( i
= nParamCount
; i
< nUnoParamCount
; i
++ )
2237 const ParamInfo
& rInfo
= pParamInfos
[i
];
2238 const Reference
< XIdlClass
>& rxClass
= rInfo
.aType
;
2239 if( rxClass
->getTypeClass() != TypeClass_ANY
)
2242 StarBASIC::Error( SbERR_NOT_OPTIONAL
);
2246 nAllocParamCount
= nUnoParamCount
;
2250 if( nAllocParamCount
> 0 )
2252 args
.realloc( nAllocParamCount
);
2253 Any
* pAnyArgs
= args
.getArray();
2254 for( i
= 0 ; i
< nParamCount
; i
++ )
2256 const ParamInfo
& rInfo
= pParamInfos
[i
];
2257 const Reference
< XIdlClass
>& rxClass
= rInfo
.aType
;
2259 com::sun::star::uno::Type
aType( rxClass
->getTypeClass(), rxClass
->getName() );
2261 // ATTENTION: Don't forget for Sbx-Parameter the offset!
2262 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( (sal_uInt16
)(i
+1) ), aType
);
2264 // If it is not certain check whether the out-parameter are available.
2267 ParamMode aParamMode
= rInfo
.aMode
;
2268 if( aParamMode
!= ParamMode_IN
)
2274 else if( bInvocation
&& pParams
&& mxInvocation
.is() )
2276 bool bOLEAutomation
= true;
2277 processAutomationParams( pParams
, args
, bOLEAutomation
, nParamCount
);
2281 GetSbData()->bBlockCompilerError
= true; // #106433 Block compiler errors for API calls
2284 if( !bInvocation
&& mxUnoAccess
.is() )
2286 Any aRetAny
= pMeth
->m_xUnoMethod
->invoke( getUnoAny(), args
);
2288 // take over the value from Uno to Sbx
2289 unoToSbxValue( pVar
, aRetAny
);
2291 // Did we to copy back the Out-Parameter?
2294 const Any
* pAnyArgs
= args
.getConstArray();
2297 const Sequence
<ParamInfo
>& rInfoSeq
= pMeth
->getParamInfos();
2298 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2301 for( j
= 0 ; j
< nParamCount
; j
++ )
2303 const ParamInfo
& rInfo
= pParamInfos
[j
];
2304 ParamMode aParamMode
= rInfo
.aMode
;
2305 if( aParamMode
!= ParamMode_IN
)
2306 unoToSbxValue( pParams
->Get( (sal_uInt16
)(j
+1) ), pAnyArgs
[ j
] );
2310 else if( bInvocation
&& mxInvocation
.is() )
2312 Any aRetAny
= invokeAutomationMethod( pMeth
->GetName(), args
, pParams
, nParamCount
, mxInvocation
);
2313 unoToSbxValue( pVar
, aRetAny
);
2316 // remove parameter here, because this was not done anymore in unoToSbxValue()
2319 pVar
->SetParameters( NULL
);
2321 catch( const Exception
& )
2323 implHandleAnyException( ::cppu::getCaughtException() );
2325 GetSbData()->bBlockCompilerError
= false; // #106433 Unblock compiler errors
2329 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
2334 SbUnoObject::SbUnoObject( const OUString
& aName_
, const Any
& aUnoObj_
)
2335 : SbxObject( aName_
)
2336 , bNeedIntrospection( true )
2337 , bNativeCOMObject( false )
2339 static Reference
< XIntrospection
> xIntrospection
;
2341 // beat out again the default properties of Sbx
2342 Remove( OUString("Name"), SbxCLASS_DONTCARE
);
2343 Remove( OUString("Parent"), SbxCLASS_DONTCARE
);
2345 // check the type of the ojekts
2346 TypeClass eType
= aUnoObj_
.getValueType().getTypeClass();
2347 Reference
< XInterface
> x
;
2348 if( eType
== TypeClass_INTERFACE
)
2350 // get the interface from the Any
2351 x
= *static_cast<Reference
< XInterface
> const *>(aUnoObj_
.getValue());
2356 Reference
< XTypeProvider
> xTypeProvider
;
2357 // Did the object have an invocation itself?
2358 mxInvocation
= Reference
< XInvocation
>( x
, UNO_QUERY
);
2360 xTypeProvider
= Reference
< XTypeProvider
>( x
, UNO_QUERY
);
2362 if( mxInvocation
.is() )
2365 // get the ExactName
2366 mxExactNameInvocation
= Reference
< XExactName
>::query( mxInvocation
);
2368 // The remainder refers only to the introspection
2369 if( !xTypeProvider
.is() )
2371 bNeedIntrospection
= false;
2375 // Ignore introspection based members for COM objects to avoid
2376 // hiding of equally named COM symbols, e.g. XInvocation::getValue
2377 Reference
< oleautomation::XAutomationObject
> xAutomationObject( aUnoObj_
, UNO_QUERY
);
2378 if( xAutomationObject
.is() )
2379 bNativeCOMObject
= true;
2382 maTmpUnoObj
= aUnoObj_
;
2385 //*** Define the name ***
2386 bool bFatalError
= true;
2388 // Is it an interface or a struct?
2389 bool bSetClassName
= false;
2390 OUString aClassName_
;
2391 if( eType
== TypeClass_STRUCT
|| eType
== TypeClass_EXCEPTION
)
2394 bFatalError
= false;
2396 // insert the real name of the class
2397 if( aName_
.isEmpty() )
2399 aClassName_
= aUnoObj_
.getValueType().getTypeName();
2400 bSetClassName
= true;
2402 StructRefInfo
aThisStruct( maTmpUnoObj
, maTmpUnoObj
.getValueType(), 0 );
2403 maStructInfo
.reset( new SbUnoStructRefObject( GetName(), aThisStruct
) );
2405 else if( eType
== TypeClass_INTERFACE
)
2407 // Interface works always through the type in the Any
2408 bFatalError
= false;
2411 SetClassName( aClassName_
);
2413 // Neither interface nor Struct -> FatalError
2416 StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION
);
2420 // pass the introspection primal on demand
2423 SbUnoObject::~SbUnoObject()
2428 // pass the introspection on Demand
2429 void SbUnoObject::doIntrospection()
2431 if( !bNeedIntrospection
)
2434 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
2440 // get the introspection service
2441 Reference
<XIntrospection
> xIntrospection
;
2445 xIntrospection
= theIntrospection::get(xContext
);
2447 catch ( const css::uno::DeploymentException
& )
2451 if (!xIntrospection
.is())
2454 bNeedIntrospection
= false;
2456 // pass the introspection
2459 mxUnoAccess
= xIntrospection
->inspect( maTmpUnoObj
);
2461 catch( const RuntimeException
& e
)
2463 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2466 if( !mxUnoAccess
.is() )
2468 // #51475 mark to indicate an invalid object (no mxMaterialHolder)
2472 // get MaterialHolder from access
2473 mxMaterialHolder
= Reference
< XMaterialHolder
>::query( mxUnoAccess
);
2475 // get ExactName from access
2476 mxExactName
= Reference
< XExactName
>::query( mxUnoAccess
);
2482 // Start of a list of all SbUnoMethod-Instances
2483 static SbUnoMethod
* pFirst
= NULL
;
2485 void clearUnoMethodsForBasic( StarBASIC
* pBasic
)
2487 SbUnoMethod
* pMeth
= pFirst
;
2490 SbxObject
* pObject
= dynamic_cast< SbxObject
* >( pMeth
->GetParent() );
2493 StarBASIC
* pModBasic
= dynamic_cast< StarBASIC
* >( pObject
->GetParent() );
2494 if ( pModBasic
== pBasic
)
2496 // for now the solution is to remove the method from the list and to clear it,
2497 // but in case the element should be correctly transferred to another StarBASIC,
2498 // we should either set module parent to NULL without clearing it, or even
2499 // set the new StarBASIC as the parent of the module
2500 // pObject->SetParent( NULL );
2502 if( pMeth
== pFirst
)
2503 pFirst
= pMeth
->pNext
;
2504 else if( pMeth
->pPrev
)
2505 pMeth
->pPrev
->pNext
= pMeth
->pNext
;
2507 pMeth
->pNext
->pPrev
= pMeth
->pPrev
;
2509 pMeth
->pPrev
= NULL
;
2510 pMeth
->pNext
= NULL
;
2512 pMeth
->SbxValue::Clear();
2513 pObject
->SbxValue::Clear();
2515 // start from the beginning after object clearing, the cycle will end since the method is removed each time
2519 pMeth
= pMeth
->pNext
;
2522 pMeth
= pMeth
->pNext
;
2526 void clearUnoMethods()
2528 SbUnoMethod
* pMeth
= pFirst
;
2531 pMeth
->SbxValue::Clear();
2532 pMeth
= pMeth
->pNext
;
2537 SbUnoMethod::SbUnoMethod
2539 const OUString
& aName_
,
2540 SbxDataType eSbxType
,
2541 Reference
< XIdlMethod
> xUnoMethod_
,
2545 : SbxMethod( aName_
, eSbxType
)
2546 , mbInvocation( bInvocation
)
2547 , mbDirectInvocation( bDirect
)
2549 m_xUnoMethod
= xUnoMethod_
;
2550 pParamInfoSeq
= NULL
;
2552 // enregister the method in a list
2557 pNext
->pPrev
= this;
2560 SbUnoMethod::~SbUnoMethod()
2562 delete pParamInfoSeq
;
2564 if( this == pFirst
)
2567 pPrev
->pNext
= pNext
;
2569 pNext
->pPrev
= pPrev
;
2572 SbxInfo
* SbUnoMethod::GetInfo()
2574 if( !pInfo
&& m_xUnoMethod
.is() )
2576 SbiInstance
* pInst
= GetSbData()->pInst
;
2577 if( pInst
&& pInst
->IsCompatibility() )
2579 pInfo
= new SbxInfo();
2581 const Sequence
<ParamInfo
>& rInfoSeq
= getParamInfos();
2582 const ParamInfo
* pParamInfos
= rInfoSeq
.getConstArray();
2583 sal_uInt32 nParamCount
= rInfoSeq
.getLength();
2585 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
2587 const ParamInfo
& rInfo
= pParamInfos
[i
];
2588 OUString aParamName
= rInfo
.aName
;
2590 SbxDataType t
= SbxVARIANT
;
2591 SbxFlagBits nFlags_
= SBX_READ
;
2592 pInfo
->AddParam( aParamName
, t
, nFlags_
);
2599 const Sequence
<ParamInfo
>& SbUnoMethod::getParamInfos()
2603 Sequence
<ParamInfo
> aTmp
;
2604 if (m_xUnoMethod
.is())
2605 aTmp
= m_xUnoMethod
->getParameterInfos();
2606 pParamInfoSeq
= new Sequence
<ParamInfo
>(aTmp
);
2608 return *pParamInfoSeq
;
2611 SbUnoProperty::SbUnoProperty
2613 const OUString
& aName_
,
2614 SbxDataType eSbxType
,
2615 SbxDataType eRealSbxType
,
2616 const Property
& aUnoProp_
,
2621 : SbxProperty( aName_
, eSbxType
)
2622 , aUnoProp( aUnoProp_
)
2624 , mbInvocation( bInvocation
)
2625 , mRealType( eRealSbxType
)
2626 , mbUnoStruct( bUnoStruct
)
2628 // as needed establish an dummy array so that SbiRuntime::CheckArray() works
2629 static SbxArrayRef xDummyArray
= new SbxArray( SbxVARIANT
);
2630 if( eSbxType
& SbxARRAY
)
2631 PutObject( xDummyArray
);
2634 SbUnoProperty::~SbUnoProperty()
2638 SbxVariable
* SbUnoObject::Find( const OUString
& rName
, SbxClassType t
)
2640 static Reference
< XIdlMethod
> xDummyMethod
;
2641 static Property aDummyProp
;
2643 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
2645 if( bNeedIntrospection
)
2648 // New 1999-03-04: Create properties on demand. Therefore search now via
2649 // IntrospectionAccess if a property or a method of the required name exist
2652 OUString
aUName( rName
);
2653 if( mxUnoAccess
.is() && !bNativeCOMObject
)
2655 if( mxExactName
.is() )
2657 OUString aUExactName
= mxExactName
->getExactName( aUName
);
2658 if( !aUExactName
.isEmpty() )
2660 aUName
= aUExactName
;
2663 if( mxUnoAccess
->hasProperty( aUName
, PropertyConcept::ALL
- PropertyConcept::DANGEROUS
) )
2665 const Property
& rProp
= mxUnoAccess
->
2666 getProperty( aUName
, PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
2668 // If the property could be void the type had to be set to Variant
2669 SbxDataType eSbxType
;
2670 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
2671 eSbxType
= SbxVARIANT
;
2673 eSbxType
= unoToSbxType( rProp
.Type
.getTypeClass() );
2675 SbxDataType eRealSbxType
= ( ( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
) ? unoToSbxType( rProp
.Type
.getTypeClass() ) : eSbxType
);
2676 // create the property and superimpose it
2677 SbUnoProperty
* pProp
= new SbUnoProperty( rProp
.Name
, eSbxType
, eRealSbxType
, rProp
, 0, false, ( rProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
2678 SbxVariableRef xVarRef
= pProp
;
2679 QuickInsert( (SbxVariable
*)xVarRef
);
2682 else if( mxUnoAccess
->hasMethod( aUName
,
2683 MethodConcept::ALL
- MethodConcept::DANGEROUS
) )
2685 // address the method
2686 const Reference
< XIdlMethod
>& rxMethod
= mxUnoAccess
->
2687 getMethod( aUName
, MethodConcept::ALL
- MethodConcept::DANGEROUS
);
2689 // create SbUnoMethod and superimpose it
2690 SbxVariableRef xMethRef
= new SbUnoMethod( rxMethod
->getName(),
2691 unoToSbxType( rxMethod
->getReturnType() ), rxMethod
, false );
2692 QuickInsert( (SbxVariable
*)xMethRef
);
2696 // If nothing was found check via XNameAccess
2701 Reference
< XNameAccess
> xNameAccess( mxUnoAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()), UNO_QUERY
);
2702 OUString
aUName2( rName
);
2704 if( xNameAccess
.is() && xNameAccess
->hasByName( aUName2
) )
2706 Any aAny
= xNameAccess
->getByName( aUName2
);
2708 // ATTENTION: Because of XNameAccess, the variable generated here
2709 // may not be included as a fixed property in the object and therefore
2710 // won't be stored anywhere.
2711 // If this leads to problems, it has to be created
2712 // synthetically or a class SbUnoNameAccessProperty,
2713 // witch checks the existence on access and which
2714 // is disposed if the name is not found anymore.
2715 pRes
= new SbxVariable( SbxVARIANT
);
2716 unoToSbxValue( pRes
, aAny
);
2719 catch( const NoSuchElementException
& e
)
2721 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2723 catch( const Exception
& )
2725 // Establish so that the exception error will not be overwritten
2727 pRes
= new SbxVariable( SbxVARIANT
);
2729 implHandleAnyException( ::cppu::getCaughtException() );
2733 if( !pRes
&& mxInvocation
.is() )
2735 if( mxExactNameInvocation
.is() )
2737 OUString aUExactName
= mxExactNameInvocation
->getExactName( aUName
);
2738 if( !aUExactName
.isEmpty() )
2740 aUName
= aUExactName
;
2746 if( mxInvocation
->hasProperty( aUName
) )
2748 // create a property and superimpose it
2749 SbxVariableRef xVarRef
= new SbUnoProperty( aUName
, SbxVARIANT
, SbxVARIANT
, aDummyProp
, 0, true, false );
2750 QuickInsert( (SbxVariable
*)xVarRef
);
2753 else if( mxInvocation
->hasMethod( aUName
) )
2755 // create SbUnoMethode and superimpose it
2756 SbxVariableRef xMethRef
= new SbUnoMethod( aUName
, SbxVARIANT
, xDummyMethod
, true );
2757 QuickInsert( (SbxVariable
*)xMethRef
);
2762 Reference
< XDirectInvocation
> xDirectInvoke( mxInvocation
, UNO_QUERY
);
2763 if ( xDirectInvoke
.is() && xDirectInvoke
->hasMember( aUName
) )
2765 SbxVariableRef xMethRef
= new SbUnoMethod( aUName
, SbxVARIANT
, xDummyMethod
, true, true );
2766 QuickInsert( (SbxVariable
*)xMethRef
);
2772 catch( const RuntimeException
& e
)
2774 // Establish so that the exception error will not be overwritten
2776 pRes
= new SbxVariable( SbxVARIANT
);
2778 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
, implGetExceptionMsg( e
) );
2783 // At the very end checking if the Dbg_-Properties are meant
2787 if( rName
.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES
) ||
2788 rName
.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES
) ||
2789 rName
.equalsIgnoreAsciiCase(ID_DBG_METHODS
) )
2792 implCreateDbgProperties();
2794 // Now they have to be found regular
2795 pRes
= SbxObject::Find( rName
, SbxCLASS_DONTCARE
);
2802 // help method to create the dbg_-Properties
2803 void SbUnoObject::implCreateDbgProperties()
2807 // Id == -1: display the implemented interfaces corresponding the ClassProvider
2808 SbxVariableRef xVarRef
= new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES
), SbxSTRING
, SbxSTRING
, aProp
, -1, false, false );
2809 QuickInsert( (SbxVariable
*)xVarRef
);
2811 // Id == -2: output the properties
2812 xVarRef
= new SbUnoProperty( OUString(ID_DBG_PROPERTIES
), SbxSTRING
, SbxSTRING
, aProp
, -2, false, false );
2813 QuickInsert( (SbxVariable
*)xVarRef
);
2815 // Id == -3: output the Methods
2816 xVarRef
= new SbUnoProperty( OUString(ID_DBG_METHODS
), SbxSTRING
, SbxSTRING
, aProp
, -3, false, false );
2817 QuickInsert( (SbxVariable
*)xVarRef
);
2820 void SbUnoObject::implCreateAll()
2822 // throw away all existing methods and properties
2823 pMethods
= new SbxArray
;
2824 pProps
= new SbxArray
;
2826 if( bNeedIntrospection
) doIntrospection();
2828 // get introspection
2829 Reference
< XIntrospectionAccess
> xAccess
= mxUnoAccess
;
2830 if( !xAccess
.is() || bNativeCOMObject
)
2832 if( mxInvocation
.is() )
2833 xAccess
= mxInvocation
->getIntrospection();
2834 else if( bNativeCOMObject
)
2840 // Establish properties
2841 Sequence
<Property
> props
= xAccess
->getProperties( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
2842 sal_uInt32 nPropCount
= props
.getLength();
2843 const Property
* pProps_
= props
.getConstArray();
2846 for( i
= 0 ; i
< nPropCount
; i
++ )
2848 const Property
& rProp
= pProps_
[ i
];
2850 // If the property could be void the type had to be set to Variant
2851 SbxDataType eSbxType
;
2852 if( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
)
2853 eSbxType
= SbxVARIANT
;
2855 eSbxType
= unoToSbxType( rProp
.Type
.getTypeClass() );
2857 SbxDataType eRealSbxType
= ( ( rProp
.Attributes
& PropertyAttribute::MAYBEVOID
) ? unoToSbxType( rProp
.Type
.getTypeClass() ) : eSbxType
);
2858 // Create property and superimpose it
2859 SbxVariableRef xVarRef
= new SbUnoProperty( rProp
.Name
, eSbxType
, eRealSbxType
, rProp
, i
, false, ( rProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
2860 QuickInsert( (SbxVariable
*)xVarRef
);
2863 // Create Dbg_-Properties
2864 implCreateDbgProperties();
2867 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods
2868 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
2869 sal_uInt32 nMethCount
= aMethodSeq
.getLength();
2870 const Reference
< XIdlMethod
>* pMethods_
= aMethodSeq
.getConstArray();
2871 for( i
= 0 ; i
< nMethCount
; i
++ )
2874 const Reference
< XIdlMethod
>& rxMethod
= pMethods_
[i
];
2876 // Create SbUnoMethod and superimpose it
2877 SbxVariableRef xMethRef
= new SbUnoMethod
2878 ( rxMethod
->getName(), unoToSbxType( rxMethod
->getReturnType() ), rxMethod
, false );
2879 QuickInsert( (SbxVariable
*)xMethRef
);
2885 Any
SbUnoObject::getUnoAny()
2888 if( bNeedIntrospection
) doIntrospection();
2889 if ( maStructInfo
.get() )
2890 aRetAny
= maTmpUnoObj
;
2891 else if( mxMaterialHolder
.is() )
2892 aRetAny
= mxMaterialHolder
->getMaterial();
2893 else if( mxInvocation
.is() )
2894 aRetAny
<<= mxInvocation
;
2898 // help method to create an Uno-Struct per CoreReflection
2899 SbUnoObject
* Impl_CreateUnoStruct( const OUString
& aClassName
)
2901 // get CoreReflection
2902 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
2903 if( !xCoreReflection
.is() )
2906 // search for the class
2907 Reference
< XIdlClass
> xClass
;
2908 Reference
< XHierarchicalNameAccess
> xHarryName
=
2909 getCoreReflection_HierarchicalNameAccess_Impl();
2910 if( xHarryName
.is() && xHarryName
->hasByHierarchicalName( aClassName
) )
2911 xClass
= xCoreReflection
->forName( aClassName
);
2915 // Is it really a struct?
2916 TypeClass eType
= xClass
->getTypeClass();
2917 if ( ( eType
!= TypeClass_STRUCT
) && ( eType
!= TypeClass_EXCEPTION
) )
2920 // create an instance
2922 xClass
->createObject( aNewAny
);
2923 // make a SbUnoObject out of it
2924 SbUnoObject
* pUnoObj
= new SbUnoObject( aClassName
, aNewAny
);
2929 // Factory-Class to create Uno-Structs per DIM AS NEW
2930 SbxBase
* SbUnoFactory::Create( sal_uInt16
, sal_uInt32
)
2932 // Via SbxId nothing works in Uno
2936 SbxObject
* SbUnoFactory::CreateObject( const OUString
& rClassName
)
2938 return Impl_CreateUnoStruct( rClassName
);
2942 // Provisional interface for the UNO-Connection
2943 // Deliver a SbxObject, that wrap an Uno-Interface
2944 SbxObjectRef
GetSbUnoObject( const OUString
& aName
, const Any
& aUnoObj_
)
2946 return new SbUnoObject( aName
, aUnoObj_
);
2949 // Force creation of all properties for debugging
2950 void createAllObjectProperties( SbxObject
* pObj
)
2955 SbUnoObject
* pUnoObj
= PTR_CAST(SbUnoObject
,pObj
);
2956 SbUnoStructRefObject
* pUnoStructObj
= PTR_CAST(SbUnoStructRefObject
,pObj
);
2959 pUnoObj
->createAllProperties();
2961 else if ( pUnoStructObj
)
2963 pUnoStructObj
->createAllProperties();
2968 void RTL_Impl_CreateUnoStruct( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
2973 // We need 1 parameter minimum
2974 if ( rPar
.Count() < 2 )
2976 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2980 // get the name of the class of the struct
2981 OUString aClassName
= rPar
.Get(1)->GetOUString();
2983 // try to create Struct with the same name
2984 SbUnoObjectRef xUnoObj
= Impl_CreateUnoStruct( aClassName
);
2989 // return the object
2990 SbxVariableRef refVar
= rPar
.Get(0);
2991 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
2994 void RTL_Impl_CreateUnoService( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
2999 // We need 1 Parameter minimum
3000 if ( rPar
.Count() < 2 )
3002 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3006 // get the name of the class of the struct
3007 OUString aServiceName
= rPar
.Get(1)->GetOUString();
3009 // search for the service and instatiate it
3010 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3011 Reference
< XInterface
> xInterface
;
3014 xInterface
= xFactory
->createInstance( aServiceName
);
3016 catch( const Exception
& )
3018 implHandleAnyException( ::cppu::getCaughtException() );
3021 SbxVariableRef refVar
= rPar
.Get(0);
3022 if( xInterface
.is() )
3025 aAny
<<= xInterface
;
3027 // Create a SbUnoObject out of it and return it
3028 SbUnoObjectRef xUnoObj
= new SbUnoObject( aServiceName
, aAny
);
3029 if( xUnoObj
->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID
)
3031 // return the object
3032 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3036 refVar
->PutObject( NULL
);
3041 refVar
->PutObject( NULL
);
3045 void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
3050 // We need 2 parameter minimum
3051 if ( rPar
.Count() < 3 )
3053 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3057 // get the name of the class of the struct
3058 OUString aServiceName
= rPar
.Get(1)->GetOUString();
3059 Any aArgAsAny
= sbxToUnoValue( rPar
.Get(2),
3060 cppu::UnoType
<Sequence
<Any
>>::get() );
3061 Sequence
< Any
> aArgs
;
3062 aArgAsAny
>>= aArgs
;
3064 // search for the service and instatiate it
3065 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3066 Reference
< XInterface
> xInterface
;
3069 xInterface
= xFactory
->createInstanceWithArguments( aServiceName
, aArgs
);
3071 catch( const Exception
& )
3073 implHandleAnyException( ::cppu::getCaughtException() );
3076 SbxVariableRef refVar
= rPar
.Get(0);
3077 if( xInterface
.is() )
3080 aAny
<<= xInterface
;
3082 // Create a SbUnoObject out of it and return it
3083 SbUnoObjectRef xUnoObj
= new SbUnoObject( aServiceName
, aAny
);
3084 if( xUnoObj
->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID
)
3086 // return the object
3087 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3091 refVar
->PutObject( NULL
);
3096 refVar
->PutObject( NULL
);
3100 void RTL_Impl_GetProcessServiceManager( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
3105 SbxVariableRef refVar
= rPar
.Get(0);
3107 // get the global service manager
3108 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory() );
3112 // Create a SbUnoObject out of it and return it
3113 SbUnoObjectRef xUnoObj
= new SbUnoObject( OUString( "ProcessServiceManager" ), aAny
);
3114 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
3117 void RTL_Impl_HasInterfaces( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
3122 // We need 2 parameter minimum
3123 sal_uInt16 nParCount
= rPar
.Count();
3126 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3130 // variable for the return value
3131 SbxVariableRef refVar
= rPar
.Get(0);
3132 refVar
->PutBool( false );
3134 // get the Uno-Object
3135 SbxBaseRef pObj
= rPar
.Get( 1 )->GetObject();
3136 if( !(pObj
&& pObj
->ISA(SbUnoObject
)) )
3140 Any aAny
= static_cast<SbUnoObject
*>((SbxBase
*)pObj
)->getUnoAny();
3141 TypeClass eType
= aAny
.getValueType().getTypeClass();
3142 if( eType
!= TypeClass_INTERFACE
)
3146 // get the interface out of the Any
3147 Reference
< XInterface
> x
= *static_cast<Reference
< XInterface
> const *>(aAny
.getValue());
3149 // get CoreReflection
3150 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
3151 if( !xCoreReflection
.is() )
3155 for( sal_uInt16 i
= 2 ; i
< nParCount
; i
++ )
3157 // get the name of the interface of the struct
3158 OUString aIfaceName
= rPar
.Get( i
)->GetOUString();
3160 // search for the class
3161 Reference
< XIdlClass
> xClass
= xCoreReflection
->forName( aIfaceName
);
3166 // check if the interface will be supported
3167 OUString aClassName
= xClass
->getName();
3168 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
3169 if( !x
->queryInterface( aClassType
).hasValue() )
3175 // Every thing works; then return TRUE
3176 refVar
->PutBool( true );
3179 void RTL_Impl_IsUnoStruct( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
3184 // We need 1 parameter minimum
3185 if ( rPar
.Count() < 2 )
3187 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3191 // variable for the return value
3192 SbxVariableRef refVar
= rPar
.Get(0);
3193 refVar
->PutBool( false );
3195 // get the Uno-Object
3196 SbxVariableRef xParam
= rPar
.Get( 1 );
3197 if( !xParam
->IsObject() )
3201 SbxBaseRef pObj
= rPar
.Get( 1 )->GetObject();
3202 if( !(pObj
&& pObj
->ISA(SbUnoObject
)) )
3206 Any aAny
= static_cast<SbUnoObject
*>((SbxBase
*)pObj
)->getUnoAny();
3207 TypeClass eType
= aAny
.getValueType().getTypeClass();
3208 if( eType
== TypeClass_STRUCT
)
3210 refVar
->PutBool( true );
3215 void RTL_Impl_EqualUnoObjects( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
3220 if ( rPar
.Count() < 3 )
3222 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3226 // variable for the return value
3227 SbxVariableRef refVar
= rPar
.Get(0);
3228 refVar
->PutBool( false );
3230 // get the Uno-Objects
3231 SbxVariableRef xParam1
= rPar
.Get( 1 );
3232 if( !xParam1
->IsObject() )
3236 SbxBaseRef pObj1
= xParam1
->GetObject();
3237 if( !(pObj1
&& pObj1
->ISA(SbUnoObject
)) )
3241 Any aAny1
= static_cast<SbUnoObject
*>((SbxBase
*)pObj1
)->getUnoAny();
3242 TypeClass eType1
= aAny1
.getValueType().getTypeClass();
3243 if( eType1
!= TypeClass_INTERFACE
)
3247 Reference
< XInterface
> x1
;
3250 SbxVariableRef xParam2
= rPar
.Get( 2 );
3251 if( !xParam2
->IsObject() )
3255 SbxBaseRef pObj2
= xParam2
->GetObject();
3256 if( !(pObj2
&& pObj2
->ISA(SbUnoObject
)) )
3260 Any aAny2
= static_cast<SbUnoObject
*>((SbxBase
*)pObj2
)->getUnoAny();
3261 TypeClass eType2
= aAny2
.getValueType().getTypeClass();
3262 if( eType2
!= TypeClass_INTERFACE
)
3266 Reference
< XInterface
> x2
;
3271 refVar
->PutBool( true );
3276 // helper wrapper function to interact with TypeProvider and
3277 // XTypeDescriptionEnumerationAccess.
3278 // if it fails for whatever reason
3279 // returned Reference<> be null e.g. .is() will be false
3281 Reference
< XTypeDescriptionEnumeration
> getTypeDescriptorEnumeration( const OUString
& sSearchRoot
,
3282 const Sequence
< TypeClass
>& types
,
3283 TypeDescriptionSearchDepth depth
)
3285 Reference
< XTypeDescriptionEnumeration
> xEnum
;
3286 Reference
< XTypeDescriptionEnumerationAccess
> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY
);
3287 if ( xTypeEnumAccess
.is() )
3291 xEnum
= xTypeEnumAccess
->createTypeDescriptionEnumeration(
3292 sSearchRoot
, types
, depth
);
3294 catch(const NoSuchTypeNameException
& /*nstne*/ ) {}
3295 catch(const InvalidTypeNameException
& /*nstne*/ ) {}
3300 typedef std::unordered_map
< OUString
, Any
, OUStringHash
, ::std::equal_to
< OUString
> > VBAConstantsHash
;
3303 VBAConstantHelper::instance()
3305 static VBAConstantHelper aHelper
;
3309 void VBAConstantHelper::init()
3313 Sequence
< TypeClass
> types(1);
3314 types
[ 0 ] = TypeClass_CONSTANTS
;
3315 Reference
< XTypeDescriptionEnumeration
> xEnum
= getTypeDescriptorEnumeration( OUString(defaultNameSpace
), types
, TypeDescriptionSearchDepth_INFINITE
);
3321 while ( xEnum
->hasMoreElements() )
3323 Reference
< XConstantsTypeDescription
> xConstants( xEnum
->nextElement(), UNO_QUERY
);
3324 if ( xConstants
.is() )
3326 // store constant group name
3327 OUString sFullName
= xConstants
->getName();
3328 sal_Int32 indexLastDot
= sFullName
.lastIndexOf('.');
3329 OUString
sLeafName( sFullName
);
3330 if ( indexLastDot
> -1 )
3332 sLeafName
= sFullName
.copy( indexLastDot
+ 1);
3334 aConstCache
.push_back( sLeafName
); // assume constant group names are unique
3335 Sequence
< Reference
< XConstantTypeDescription
> > aConsts
= xConstants
->getConstants();
3336 for (sal_Int32 i
= 0; i
!= aConsts
.getLength(); ++i
)
3338 // store constant member name
3339 sFullName
= aConsts
[i
]->getName();
3340 indexLastDot
= sFullName
.lastIndexOf('.');
3341 sLeafName
= sFullName
;
3342 if ( indexLastDot
> -1 )
3344 sLeafName
= sFullName
.copy( indexLastDot
+ 1);
3346 aConstHash
[ sLeafName
.toAsciiLowerCase() ] = aConsts
[i
]->getConstantValue();
3355 VBAConstantHelper::isVBAConstantType( const OUString
& rName
)
3358 bool bConstant
= false;
3359 OUString
sKey( rName
);
3360 VBAConstantsVector::const_iterator it
= aConstCache
.begin();
3362 for( ; it
!= aConstCache
.end(); ++it
)
3364 if( sKey
.equalsIgnoreAsciiCase( *it
) )
3374 VBAConstantHelper::getVBAConstant( const OUString
& rName
)
3376 SbxVariable
* pConst
= NULL
;
3379 OUString
sKey( rName
);
3381 VBAConstantsHash::const_iterator it
= aConstHash
.find( sKey
.toAsciiLowerCase() );
3383 if ( it
!= aConstHash
.end() )
3385 pConst
= new SbxVariable( SbxVARIANT
);
3386 pConst
->SetName( rName
);
3387 unoToSbxValue( pConst
, it
->second
);
3393 // Function to search for a global identifier in the
3394 // UnoScope and to wrap it for Sbx
3395 SbUnoClass
* findUnoClass( const OUString
& rName
)
3397 // #105550 Check if module exists
3398 SbUnoClass
* pUnoClass
= NULL
;
3400 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3401 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3403 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3404 Reference
< XTypeDescription
> xTypeDesc
;
3407 if( xTypeDesc
.is() )
3409 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3410 if( eTypeClass
== TypeClass_MODULE
|| eTypeClass
== TypeClass_CONSTANTS
)
3412 pUnoClass
= new SbUnoClass( rName
);
3419 SbxVariable
* SbUnoClass::Find( const OUString
& rName
, SbxClassType
)
3421 SbxVariable
* pRes
= SbxObject::Find( rName
, SbxCLASS_VARIABLE
);
3423 // If nothing were located the submodule isn't known yet
3426 // If it is already a class, ask for the field
3430 OUString
aUStr( rName
);
3431 Reference
< XIdlField
> xField
= m_xClass
->getField( aUStr
);
3432 Reference
< XIdlClass
> xClass
;
3438 aAny
= xField
->get( aAny
);
3441 pRes
= new SbxVariable( SbxVARIANT
);
3442 pRes
->SetName( rName
);
3443 unoToSbxValue( pRes
, aAny
);
3445 catch( const Exception
& )
3447 implHandleAnyException( ::cppu::getCaughtException() );
3453 // expand fully qualified name
3454 OUString aNewName
= GetName();
3458 // get CoreReflection
3459 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
3460 if( xCoreReflection
.is() )
3462 // Is it a constant?
3463 Reference
< XHierarchicalNameAccess
> xHarryName( xCoreReflection
, UNO_QUERY
);
3464 if( xHarryName
.is() )
3468 Any aValue
= xHarryName
->getByHierarchicalName( aNewName
);
3469 TypeClass eType
= aValue
.getValueType().getTypeClass();
3471 // Interface located? Then it is a class
3472 if( eType
== TypeClass_INTERFACE
)
3474 Reference
< XInterface
> xIface
= *static_cast<Reference
< XInterface
> const *>(aValue
.getValue());
3475 Reference
< XIdlClass
> xClass( xIface
, UNO_QUERY
);
3478 pRes
= new SbxVariable( SbxVARIANT
);
3479 SbxObjectRef xWrapper
= (SbxObject
*)new SbUnoClass( aNewName
, xClass
);
3480 pRes
->PutObject( xWrapper
);
3485 pRes
= new SbxVariable( SbxVARIANT
);
3486 unoToSbxValue( pRes
, aValue
);
3489 catch( const NoSuchElementException
& )
3494 // Otherwise take it again as class
3497 SbUnoClass
* pNewClass
= findUnoClass( aNewName
);
3500 pRes
= new SbxVariable( SbxVARIANT
);
3501 SbxObjectRef xWrapper
= (SbxObject
*)pNewClass
;
3502 pRes
->PutObject( xWrapper
);
3509 SbUnoService
* pUnoService
= findUnoService( aNewName
);
3512 pRes
= new SbxVariable( SbxVARIANT
);
3513 SbxObjectRef xWrapper
= (SbxObject
*)pUnoService
;
3514 pRes
->PutObject( xWrapper
);
3518 // An UNO singleton?
3521 SbUnoSingleton
* pUnoSingleton
= findUnoSingleton( aNewName
);
3524 pRes
= new SbxVariable( SbxVARIANT
);
3525 SbxObjectRef xWrapper
= (SbxObject
*)pUnoSingleton
;
3526 pRes
->PutObject( xWrapper
);
3534 pRes
->SetName( rName
);
3536 // Insert variable, so that it could be found later
3537 QuickInsert( pRes
);
3539 // Take us out as listener at once,
3540 // the values are all constant
3541 if( pRes
->IsBroadcaster() )
3542 EndListening( pRes
->GetBroadcaster(), true );
3549 SbUnoService
* findUnoService( const OUString
& rName
)
3551 SbUnoService
* pSbUnoService
= NULL
;
3553 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3554 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3556 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3557 Reference
< XTypeDescription
> xTypeDesc
;
3560 if( xTypeDesc
.is() )
3562 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3563 if( eTypeClass
== TypeClass_SERVICE
)
3565 Reference
< XServiceTypeDescription2
> xServiceTypeDesc( xTypeDesc
, UNO_QUERY
);
3566 if( xServiceTypeDesc
.is() )
3567 pSbUnoService
= new SbUnoService( rName
, xServiceTypeDesc
);
3571 return pSbUnoService
;
3574 SbxVariable
* SbUnoService::Find( const OUString
& rName
, SbxClassType
)
3576 SbxVariable
* pRes
= SbxObject::Find( rName
, SbxCLASS_METHOD
);
3580 // If it is already a class ask for a field
3581 if( m_bNeedsInit
&& m_xServiceTypeDesc
.is() )
3583 m_bNeedsInit
= false;
3585 Sequence
< Reference
< XServiceConstructorDescription
> > aSCDSeq
= m_xServiceTypeDesc
->getConstructors();
3586 const Reference
< XServiceConstructorDescription
>* pCtorSeq
= aSCDSeq
.getConstArray();
3587 int nCtorCount
= aSCDSeq
.getLength();
3588 for( int i
= 0 ; i
< nCtorCount
; ++i
)
3590 Reference
< XServiceConstructorDescription
> xCtor
= pCtorSeq
[i
];
3592 OUString
aName( xCtor
->getName() );
3593 if( aName
.isEmpty() )
3595 if( xCtor
->isDefaultConstructor() )
3601 if( !aName
.isEmpty() )
3603 // Create and insert SbUnoServiceCtor
3604 SbxVariableRef xSbCtorRef
= new SbUnoServiceCtor( aName
, xCtor
);
3605 QuickInsert( (SbxVariable
*)xSbCtorRef
);
3608 pRes
= SbxObject::Find( rName
, SbxCLASS_METHOD
);
3615 void SbUnoService::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
3616 const SfxHint
& rHint
, const TypeId
& rHintType
)
3618 const SbxHint
* pHint
= dynamic_cast<const SbxHint
*>(&rHint
);
3621 SbxVariable
* pVar
= pHint
->GetVar();
3622 SbxArray
* pParams
= pVar
->GetParameters();
3623 SbUnoServiceCtor
* pUnoCtor
= PTR_CAST(SbUnoServiceCtor
,pVar
);
3624 if( pUnoCtor
&& pHint
->GetId() == SBX_HINT_DATAWANTED
)
3626 // Parameter count -1 because of Param0 == this
3627 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
3630 Reference
< XServiceConstructorDescription
> xCtor
= pUnoCtor
->getServiceCtorDesc();
3631 Sequence
< Reference
< XParameter
> > aParameterSeq
= xCtor
->getParameters();
3632 const Reference
< XParameter
>* pParameterSeq
= aParameterSeq
.getConstArray();
3633 sal_uInt32 nUnoParamCount
= aParameterSeq
.getLength();
3635 // Default: Ignore not needed parameters
3636 bool bParameterError
= false;
3638 // Is the last parameter a rest parameter?
3639 bool bRestParameterMode
= false;
3640 if( nUnoParamCount
> 0 )
3642 Reference
< XParameter
> xLastParam
= pParameterSeq
[ nUnoParamCount
- 1 ];
3643 if( xLastParam
.is() )
3645 if( xLastParam
->isRestParameter() )
3646 bRestParameterMode
= true;
3650 // Too many parameters with context as first parameter?
3651 sal_uInt16 nSbxParameterOffset
= 1;
3652 sal_uInt16 nParameterOffsetByContext
= 0;
3653 Reference
< XComponentContext
> xFirstParamContext
;
3654 if( nParamCount
> nUnoParamCount
)
3656 // Check if first parameter is a context and use it
3657 // then in createInstanceWithArgumentsAndContext
3658 Any aArg0
= sbxToUnoValue( pParams
->Get( nSbxParameterOffset
) );
3659 if( (aArg0
>>= xFirstParamContext
) && xFirstParamContext
.is() )
3660 nParameterOffsetByContext
= 1;
3663 sal_uInt32 nEffectiveParamCount
= nParamCount
- nParameterOffsetByContext
;
3664 sal_uInt32 nAllocParamCount
= nEffectiveParamCount
;
3665 if( nEffectiveParamCount
> nUnoParamCount
)
3667 if( !bRestParameterMode
)
3669 nEffectiveParamCount
= nUnoParamCount
;
3670 nAllocParamCount
= nUnoParamCount
;
3673 // Not enough parameters?
3674 else if( nUnoParamCount
> nEffectiveParamCount
)
3676 // RestParameterMode only helps if one (the last) parameter is missing
3677 int nDiff
= nUnoParamCount
- nEffectiveParamCount
;
3678 if( !bRestParameterMode
|| nDiff
> 1 )
3680 bParameterError
= true;
3681 StarBASIC::Error( SbERR_NOT_OPTIONAL
);
3685 if( !bParameterError
)
3687 bool bOutParams
= false;
3688 if( nAllocParamCount
> 0 )
3690 args
.realloc( nAllocParamCount
);
3691 Any
* pAnyArgs
= args
.getArray();
3692 for( sal_uInt32 i
= 0 ; i
< nEffectiveParamCount
; i
++ )
3694 sal_uInt16 iSbx
= (sal_uInt16
)(i
+ nSbxParameterOffset
+ nParameterOffsetByContext
);
3696 // bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
3697 Reference
< XParameter
> xParam
;
3698 if( i
< nUnoParamCount
)
3700 xParam
= pParameterSeq
[i
];
3704 Reference
< XTypeDescription
> xParamTypeDesc
= xParam
->getType();
3705 if( !xParamTypeDesc
.is() )
3707 com::sun::star::uno::Type
aType( xParamTypeDesc
->getTypeClass(), xParamTypeDesc
->getName() );
3709 // sbx parameter needs offset 1
3710 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( iSbx
), aType
);
3712 // Check for out parameter if not already done
3715 if( xParam
->isOut() )
3721 pAnyArgs
[i
] = sbxToUnoValue( pParams
->Get( iSbx
) );
3726 // "Call" ctor using createInstanceWithArgumentsAndContext
3727 Reference
< XComponentContext
> xContext(
3728 xFirstParamContext
.is()
3729 ? xFirstParamContext
3730 : comphelper::getProcessComponentContext() );
3731 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
3734 OUString aServiceName
= GetName();
3735 Reference
< XInterface
> xRet
;
3738 xRet
= xServiceMgr
->createInstanceWithArgumentsAndContext( aServiceName
, args
, xContext
);
3740 catch( const Exception
& )
3742 implHandleAnyException( ::cppu::getCaughtException() );
3745 unoToSbxValue( pVar
, aRetAny
);
3747 // Copy back out parameters?
3750 const Any
* pAnyArgs
= args
.getConstArray();
3752 for( sal_uInt32 j
= 0 ; j
< nUnoParamCount
; j
++ )
3754 Reference
< XParameter
> xParam
= pParameterSeq
[j
];
3758 if( xParam
->isOut() )
3759 unoToSbxValue( pParams
->Get( (sal_uInt16
)(j
+1) ), pAnyArgs
[ j
] );
3765 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
3771 static SbUnoServiceCtor
* pFirstCtor
= NULL
;
3773 void clearUnoServiceCtors()
3775 SbUnoServiceCtor
* pCtor
= pFirstCtor
;
3778 pCtor
->SbxValue::Clear();
3779 pCtor
= pCtor
->pNext
;
3783 SbUnoServiceCtor::SbUnoServiceCtor( const OUString
& aName_
, Reference
< XServiceConstructorDescription
> xServiceCtorDesc
)
3784 : SbxMethod( aName_
, SbxOBJECT
)
3785 , m_xServiceCtorDesc( xServiceCtorDesc
)
3790 SbUnoServiceCtor::~SbUnoServiceCtor()
3794 SbxInfo
* SbUnoServiceCtor::GetInfo()
3796 SbxInfo
* pRet
= NULL
;
3802 SbUnoSingleton
* findUnoSingleton( const OUString
& rName
)
3804 SbUnoSingleton
* pSbUnoSingleton
= NULL
;
3806 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
3807 if( xTypeAccess
->hasByHierarchicalName( rName
) )
3809 Any aRet
= xTypeAccess
->getByHierarchicalName( rName
);
3810 Reference
< XTypeDescription
> xTypeDesc
;
3813 if( xTypeDesc
.is() )
3815 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
3816 if( eTypeClass
== TypeClass_SINGLETON
)
3818 Reference
< XSingletonTypeDescription
> xSingletonTypeDesc( xTypeDesc
, UNO_QUERY
);
3819 if( xSingletonTypeDesc
.is() )
3820 pSbUnoSingleton
= new SbUnoSingleton( rName
, xSingletonTypeDesc
);
3824 return pSbUnoSingleton
;
3827 SbUnoSingleton::SbUnoSingleton( const OUString
& aName_
,
3828 const Reference
< XSingletonTypeDescription
>& xSingletonTypeDesc
)
3829 : SbxObject( aName_
)
3830 , m_xSingletonTypeDesc( xSingletonTypeDesc
)
3832 SbxVariableRef xGetMethodRef
= new SbxMethod( OUString( "get" ), SbxOBJECT
);
3833 QuickInsert( (SbxVariable
*)xGetMethodRef
);
3836 void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
3837 const SfxHint
& rHint
, const TypeId
& rHintType
)
3839 const SbxHint
* pHint
= dynamic_cast<const SbxHint
*>(&rHint
);
3842 SbxVariable
* pVar
= pHint
->GetVar();
3843 SbxArray
* pParams
= pVar
->GetParameters();
3844 sal_uInt32 nParamCount
= pParams
? ((sal_uInt32
)pParams
->Count() - 1) : 0;
3845 sal_uInt32 nAllowedParamCount
= 1;
3847 Reference
< XComponentContext
> xContextToUse
;
3848 if( nParamCount
> 0 )
3850 // Check if first parameter is a context and use it then
3851 Reference
< XComponentContext
> xFirstParamContext
;
3852 Any aArg1
= sbxToUnoValue( pParams
->Get( 1 ) );
3853 if( (aArg1
>>= xFirstParamContext
) && xFirstParamContext
.is() )
3854 xContextToUse
= xFirstParamContext
;
3857 if( !xContextToUse
.is() )
3859 xContextToUse
= comphelper::getProcessComponentContext();
3860 --nAllowedParamCount
;
3863 if( nParamCount
> nAllowedParamCount
)
3865 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3870 if( xContextToUse
.is() )
3872 OUString
aSingletonName( "/singletons/" );
3873 aSingletonName
+= GetName();
3874 Reference
< XInterface
> xRet
;
3875 xContextToUse
->getValueByName( aSingletonName
) >>= xRet
;
3878 unoToSbxValue( pVar
, aRetAny
);
3882 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
3889 // Implementation of an EventAttacher-drawn AllListener, which
3890 // solely transmits several events to an general AllListener
3891 class BasicAllListener_Impl
: public BasicAllListenerHelper
3893 void firing_impl(const AllEventObject
& Event
, Any
* pRet
);
3896 SbxObjectRef xSbxObj
;
3897 OUString aPrefixName
;
3899 BasicAllListener_Impl( const OUString
& aPrefixName
);
3900 virtual ~BasicAllListener_Impl();
3902 // Methods of XAllListener
3903 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw ( RuntimeException
, std::exception
) SAL_OVERRIDE
;
3904 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw ( RuntimeException
, std::exception
) SAL_OVERRIDE
;
3906 // Methods of XEventListener
3907 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw ( RuntimeException
, std::exception
) SAL_OVERRIDE
;
3912 BasicAllListener_Impl::BasicAllListener_Impl(const OUString
& aPrefixName_
)
3913 : aPrefixName( aPrefixName_
)
3918 BasicAllListener_Impl::~BasicAllListener_Impl()
3924 void BasicAllListener_Impl::firing_impl( const AllEventObject
& Event
, Any
* pRet
)
3926 SolarMutexGuard guard
;
3930 OUString aMethodName
= aPrefixName
;
3931 aMethodName
= aMethodName
+ Event
.MethodName
;
3933 SbxVariable
* pP
= xSbxObj
;
3934 while( pP
->GetParent() )
3936 pP
= pP
->GetParent();
3937 StarBASIC
* pLib
= PTR_CAST(StarBASIC
,pP
);
3940 // Create in a Basic Array
3941 SbxArrayRef xSbxArray
= new SbxArray( SbxVARIANT
);
3942 const Any
* pArgs
= Event
.Arguments
.getConstArray();
3943 sal_Int32 nCount
= Event
.Arguments
.getLength();
3944 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
3947 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
3948 unoToSbxValue( (SbxVariable
*)xVar
, pArgs
[i
] );
3949 xSbxArray
->Put( xVar
, sal::static_int_cast
< sal_uInt16
>(i
+1) );
3952 pLib
->Call( aMethodName
, xSbxArray
);
3954 // get the return value from the Param-Array, if requested
3957 SbxVariable
* pVar
= xSbxArray
->Get( 0 );
3960 // #95792 Avoid a second call
3961 SbxFlagBits nFlags
= pVar
->GetFlags();
3962 pVar
->SetFlag( SBX_NO_BROADCAST
);
3963 *pRet
= sbxToUnoValueImpl( pVar
);
3964 pVar
->SetFlags( nFlags
);
3974 // Methods of Listener
3975 void BasicAllListener_Impl::firing( const AllEventObject
& Event
) throw ( RuntimeException
, std::exception
)
3977 firing_impl( Event
, NULL
);
3980 Any
BasicAllListener_Impl::approveFiring( const AllEventObject
& Event
) throw ( RuntimeException
, std::exception
)
3983 firing_impl( Event
, &aRetAny
);
3988 // Methods of XEventListener
3989 void BasicAllListener_Impl ::disposing(const EventObject
& ) throw ( RuntimeException
, std::exception
)
3991 SolarMutexGuard guard
;
3999 // class InvocationToAllListenerMapper
4000 // helper class to map XInvocation to XAllListener (also in project eventattacher!)
4002 class InvocationToAllListenerMapper
: public WeakImplHelper1
< XInvocation
>
4005 InvocationToAllListenerMapper( const Reference
< XIdlClass
>& ListenerType
,
4006 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
);
4009 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection() throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
4010 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
4011 throw( IllegalArgumentException
, CannotConvertException
, InvocationTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
4012 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
)
4013 throw( UnknownPropertyException
, CannotConvertException
, InvocationTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
4014 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) throw( UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
4015 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
4016 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
4019 Reference
< XIdlReflection
> m_xCoreReflection
;
4020 Reference
< XAllListener
> m_xAllListener
;
4021 Reference
< XIdlClass
> m_xListenerType
;
4026 // Function to replace AllListenerAdapterService::createAllListerAdapter
4027 Reference
< XInterface
> createAllListenerAdapter
4029 const Reference
< XInvocationAdapterFactory2
>& xInvocationAdapterFactory
,
4030 const Reference
< XIdlClass
>& xListenerType
,
4031 const Reference
< XAllListener
>& xListener
,
4035 Reference
< XInterface
> xAdapter
;
4036 if( xInvocationAdapterFactory
.is() && xListenerType
.is() && xListener
.is() )
4038 Reference
< XInvocation
> xInvocationToAllListenerMapper
=
4039 (XInvocation
*)new InvocationToAllListenerMapper( xListenerType
, xListener
, Helper
);
4040 Type
aListenerType( xListenerType
->getTypeClass(), xListenerType
->getName() );
4041 Sequence
<Type
> arg2(1);
4042 arg2
[0] = aListenerType
;
4043 xAdapter
= xInvocationAdapterFactory
->createAdapter( xInvocationToAllListenerMapper
, arg2
);
4050 // InvocationToAllListenerMapper
4051 InvocationToAllListenerMapper::InvocationToAllListenerMapper
4052 ( const Reference
< XIdlClass
>& ListenerType
, const Reference
< XAllListener
>& AllListener
, const Any
& Helper
)
4053 : m_xAllListener( AllListener
)
4054 , m_xListenerType( ListenerType
)
4055 , m_Helper( Helper
)
4060 Reference
< XIntrospectionAccess
> SAL_CALL
InvocationToAllListenerMapper::getIntrospection()
4061 throw( RuntimeException
, std::exception
)
4063 return Reference
< XIntrospectionAccess
>();
4067 Any SAL_CALL
InvocationToAllListenerMapper::invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
,
4068 Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
4069 throw( IllegalArgumentException
, CannotConvertException
,
4070 InvocationTargetException
, RuntimeException
, std::exception
)
4072 (void)OutParamIndex
;
4077 // Check if to firing or approveFiring has to be called
4078 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( FunctionName
);
4079 bool bApproveFiring
= false;
4082 Reference
< XIdlClass
> xReturnType
= xMethod
->getReturnType();
4083 Sequence
< Reference
< XIdlClass
> > aExceptionSeq
= xMethod
->getExceptionTypes();
4084 if( ( xReturnType
.is() && xReturnType
->getTypeClass() != TypeClass_VOID
) ||
4085 aExceptionSeq
.getLength() > 0 )
4087 bApproveFiring
= true;
4091 Sequence
< ParamInfo
> aParamSeq
= xMethod
->getParameterInfos();
4092 sal_uInt32 nParamCount
= aParamSeq
.getLength();
4093 if( nParamCount
> 1 )
4095 const ParamInfo
* pInfos
= aParamSeq
.getConstArray();
4096 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
4098 if( pInfos
[ i
].aMode
!= ParamMode_IN
)
4100 bApproveFiring
= true;
4107 AllEventObject aAllEvent
;
4108 aAllEvent
.Source
= (OWeakObject
*) this;
4109 aAllEvent
.Helper
= m_Helper
;
4110 aAllEvent
.ListenerType
= Type(m_xListenerType
->getTypeClass(), m_xListenerType
->getName() );
4111 aAllEvent
.MethodName
= FunctionName
;
4112 aAllEvent
.Arguments
= Params
;
4113 if( bApproveFiring
)
4114 aRet
= m_xAllListener
->approveFiring( aAllEvent
);
4116 m_xAllListener
->firing( aAllEvent
);
4121 void SAL_CALL
InvocationToAllListenerMapper::setValue(const OUString
& PropertyName
, const Any
& Value
)
4122 throw( UnknownPropertyException
, CannotConvertException
,
4123 InvocationTargetException
, RuntimeException
, std::exception
)
4130 Any SAL_CALL
InvocationToAllListenerMapper::getValue(const OUString
& PropertyName
)
4131 throw( UnknownPropertyException
, RuntimeException
, std::exception
)
4139 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasMethod(const OUString
& Name
)
4140 throw( RuntimeException
, std::exception
)
4142 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( Name
);
4143 return xMethod
.is();
4147 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasProperty(const OUString
& Name
)
4148 throw( RuntimeException
, std::exception
)
4150 Reference
< XIdlField
> xField
= m_xListenerType
->getField( Name
);
4155 // create Uno-Service
4156 // 1. Parameter == Prefix-Name of the macro
4157 // 2. Parameter == fully qualified name of the listener
4158 void SbRtl_CreateUnoListener( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
4159 //RTLFUNC(CreateUnoListener)
4163 // We need 2 parameters
4164 if ( rPar
.Count() != 3 )
4166 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
4170 // get the name of the class of the struct
4171 OUString aPrefixName
= rPar
.Get(1)->GetOUString();
4172 OUString aListenerClassName
= rPar
.Get(2)->GetOUString();
4174 // get the CoreReflection
4175 Reference
< XIdlReflection
> xCoreReflection
= getCoreReflection_Impl();
4176 if( !xCoreReflection
.is() )
4179 // get the AllListenerAdapterService
4180 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
4183 Reference
< XIdlClass
> xClass
= xCoreReflection
->forName( aListenerClassName
);
4187 // From 1999-11-30: get the InvocationAdapterFactory
4188 Reference
< XInvocationAdapterFactory2
> xInvocationAdapterFactory
=
4189 InvocationAdapterFactory::create( xContext
);
4191 BasicAllListener_Impl
* p
;
4192 Reference
< XAllListener
> xAllLst
= p
= new BasicAllListener_Impl( aPrefixName
);
4194 Reference
< XInterface
> xLst
= createAllListenerAdapter( xInvocationAdapterFactory
, xClass
, xAllLst
, aTmp
);
4198 OUString aClassName
= xClass
->getName();
4199 Type
aClassType( xClass
->getTypeClass(), aClassName
.getStr() );
4200 aTmp
= xLst
->queryInterface( aClassType
);
4201 if( !aTmp
.hasValue() )
4204 SbUnoObject
* pUnoObj
= new SbUnoObject( aListenerClassName
, aTmp
);
4205 p
->xSbxObj
= pUnoObj
;
4206 p
->xSbxObj
->SetParent( pBasic
);
4208 // #100326 Register listener object to set Parent NULL in Dtor
4209 SbxArrayRef xBasicUnoListeners
= pBasic
->getUnoListeners();
4210 xBasicUnoListeners
->Insert( pUnoObj
, xBasicUnoListeners
->Count() );
4212 // return the object
4213 SbxVariableRef refVar
= rPar
.Get(0);
4214 refVar
->PutObject( p
->xSbxObj
);
4218 // Represents the DefaultContext property of the ProcessServiceManager
4219 // in the Basic runtime system.
4220 void RTL_Impl_GetDefaultContext( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
4225 SbxVariableRef refVar
= rPar
.Get(0);
4227 Any
aContextAny( comphelper::getProcessComponentContext() );
4229 SbUnoObjectRef xUnoObj
= new SbUnoObject( OUString( "DefaultContext" ), aContextAny
);
4230 refVar
->PutObject( (SbUnoObject
*)xUnoObj
);
4234 // Creates a Basic wrapper object for a strongly typed Uno value
4235 // 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
4236 void RTL_Impl_CreateUnoValue( StarBASIC
* pBasic
, SbxArray
& rPar
, bool bWrite
)
4241 static const char aTypeTypeString
[] = "type";
4243 // 2 parameters needed
4244 if ( rPar
.Count() != 3 )
4246 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
4250 // get the name of the class of the struct
4251 OUString aTypeName
= rPar
.Get(1)->GetOUString();
4252 SbxVariable
* pVal
= rPar
.Get(2);
4254 if( aTypeName
== aTypeTypeString
)
4256 SbxDataType eBaseType
= pVal
->SbxValue::GetType();
4257 OUString aValTypeName
;
4258 if( eBaseType
== SbxSTRING
)
4260 aValTypeName
= pVal
->GetOUString();
4262 else if( eBaseType
== SbxOBJECT
)
4265 Reference
< XIdlClass
> xIdlClass
;
4267 SbxBaseRef pObj
= pVal
->GetObject();
4268 if( pObj
&& pObj
->ISA(SbUnoObject
) )
4270 Any aUnoAny
= static_cast<SbUnoObject
*>((SbxBase
*)pObj
)->getUnoAny();
4271 aUnoAny
>>= xIdlClass
;
4274 if( xIdlClass
.is() )
4276 aValTypeName
= xIdlClass
->getName();
4280 bool bSuccess
= implGetTypeByName( aValTypeName
, aType
);
4283 Any
aTypeAny( aType
);
4284 SbxVariableRef refVar
= rPar
.Get(0);
4285 SbxObjectRef xUnoAnyObject
= new SbUnoAnyObject( aTypeAny
);
4286 refVar
->PutObject( xUnoAnyObject
);
4292 Reference
< XHierarchicalNameAccess
> xTypeAccess
= getTypeProvider_Impl();
4296 aRet
= xTypeAccess
->getByHierarchicalName( aTypeName
);
4298 catch( const NoSuchElementException
& e1
)
4300 OUString
aNoSuchElementExceptionName( "com.sun.star.container.NoSuchElementException" );
4301 StarBASIC::Error( ERRCODE_BASIC_EXCEPTION
,
4302 implGetExceptionMsg( e1
, aNoSuchElementExceptionName
) );
4305 Reference
< XTypeDescription
> xTypeDesc
;
4307 TypeClass eTypeClass
= xTypeDesc
->getTypeClass();
4308 Type
aDestType( eTypeClass
, aTypeName
);
4312 Any aVal
= sbxToUnoValueImpl( pVal
);
4313 Any aConvertedVal
= convertAny( aVal
, aDestType
);
4315 SbxVariableRef refVar
= rPar
.Get(0);
4316 SbxObjectRef xUnoAnyObject
= new SbUnoAnyObject( aConvertedVal
);
4317 refVar
->PutObject( xUnoAnyObject
);
4326 // this mutex is necessary for OInterfaceContainerHelper
4327 ::osl::Mutex m_aMutex
;
4331 typedef WeakImplHelper2
< XInvocation
, XComponent
> ModuleInvocationProxyHelper
;
4333 class ModuleInvocationProxy
: public OMutexBasis
,
4334 public ModuleInvocationProxyHelper
4337 SbxObjectRef m_xScopeObj
;
4338 bool m_bProxyIsClassModuleObject
;
4340 ::cppu::OInterfaceContainerHelper m_aListeners
;
4343 ModuleInvocationProxy( const OUString
& aPrefix
, SbxObjectRef xScopeObj
);
4344 virtual ~ModuleInvocationProxy()
4348 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection() throw(std::exception
) SAL_OVERRIDE
;
4349 virtual void SAL_CALL
setValue( const OUString
& rProperty
, const Any
& rValue
)
4350 throw (UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
4351 virtual Any SAL_CALL
getValue( const OUString
& rProperty
)
4352 throw (UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
4353 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& rName
) throw(std::exception
) SAL_OVERRIDE
;
4354 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& rProp
) throw(std::exception
) SAL_OVERRIDE
;
4356 virtual Any SAL_CALL
invoke( const OUString
& rFunction
,
4357 const Sequence
< Any
>& rParams
,
4358 Sequence
< sal_Int16
>& rOutParamIndex
,
4359 Sequence
< Any
>& rOutParam
)
4360 throw (CannotConvertException
, InvocationTargetException
,
4361 RuntimeException
, std::exception
) SAL_OVERRIDE
;
4364 virtual void SAL_CALL
dispose() throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
4365 virtual void SAL_CALL
addEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
4366 virtual void SAL_CALL
removeEventListener( const Reference
< XEventListener
>& aListener
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
4369 ModuleInvocationProxy::ModuleInvocationProxy( const OUString
& aPrefix
, SbxObjectRef xScopeObj
)
4370 : m_aPrefix( aPrefix
+ "_" )
4371 , m_xScopeObj( xScopeObj
)
4372 , m_aListeners( m_aMutex
)
4374 m_bProxyIsClassModuleObject
= xScopeObj
.Is() && xScopeObj
->ISA(SbClassModuleObject
);
4377 Reference
< XIntrospectionAccess
> SAL_CALL
ModuleInvocationProxy::getIntrospection() throw(std::exception
)
4379 return Reference
< XIntrospectionAccess
>();
4382 void SAL_CALL
ModuleInvocationProxy::setValue(const OUString
& rProperty
, const Any
& rValue
)
4383 throw (UnknownPropertyException
, RuntimeException
, std::exception
)
4385 if( !m_bProxyIsClassModuleObject
)
4386 throw UnknownPropertyException();
4388 SolarMutexGuard guard
;
4390 OUString
aPropertyFunctionName( "Property Set " );
4391 aPropertyFunctionName
+= m_aPrefix
;
4392 aPropertyFunctionName
+= rProperty
;
4394 SbxVariable
* p
= m_xScopeObj
->Find( aPropertyFunctionName
, SbxCLASS_METHOD
);
4395 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4398 // TODO: Check vba behavior concernig missing function
4399 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4400 throw UnknownPropertyException();
4404 SbxArrayRef xArray
= new SbxArray
;
4405 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
4406 unoToSbxValue( (SbxVariable
*)xVar
, rValue
);
4407 xArray
->Put( xVar
, 1 );
4409 // Call property method
4410 SbxVariableRef xValue
= new SbxVariable
;
4411 pMeth
->SetParameters( xArray
);
4412 pMeth
->Call( xValue
);
4413 pMeth
->SetParameters( NULL
);
4415 // TODO: OutParameter?
4421 Any SAL_CALL
ModuleInvocationProxy::getValue(const OUString
& rProperty
)
4422 throw (UnknownPropertyException
, RuntimeException
, std::exception
)
4424 if( !m_bProxyIsClassModuleObject
)
4426 throw UnknownPropertyException();
4428 SolarMutexGuard guard
;
4430 OUString
aPropertyFunctionName( "Property Get " );
4431 aPropertyFunctionName
+= m_aPrefix
;
4432 aPropertyFunctionName
+= rProperty
;
4434 SbxVariable
* p
= m_xScopeObj
->Find( aPropertyFunctionName
, SbxCLASS_METHOD
);
4435 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4438 // TODO: Check vba behavior concernig missing function
4439 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4440 throw UnknownPropertyException();
4444 SbxVariableRef xValue
= new SbxVariable
;
4445 pMeth
->Call( xValue
);
4446 Any aRet
= sbxToUnoValue( xValue
);
4450 sal_Bool SAL_CALL
ModuleInvocationProxy::hasMethod( const OUString
& ) throw(std::exception
)
4455 sal_Bool SAL_CALL
ModuleInvocationProxy::hasProperty( const OUString
& ) throw(std::exception
)
4460 Any SAL_CALL
ModuleInvocationProxy::invoke( const OUString
& rFunction
,
4461 const Sequence
< Any
>& rParams
,
4462 Sequence
< sal_Int16
>&,
4464 throw (CannotConvertException
, InvocationTargetException
,
4465 RuntimeException
, std::exception
)
4467 SolarMutexGuard guard
;
4470 SbxObjectRef xScopeObj
= m_xScopeObj
;
4471 if( !xScopeObj
.Is() )
4475 OUString aFunctionName
= m_aPrefix
;
4476 aFunctionName
+= rFunction
;
4478 bool bSetRescheduleBack
= false;
4479 bool bOldReschedule
= true;
4480 SbiInstance
* pInst
= GetSbData()->pInst
;
4481 if( pInst
&& pInst
->IsCompatibility() )
4483 bOldReschedule
= pInst
->IsReschedule();
4484 if ( bOldReschedule
)
4486 pInst
->EnableReschedule( false );
4487 bSetRescheduleBack
= true;
4491 SbxVariable
* p
= xScopeObj
->Find( aFunctionName
, SbxCLASS_METHOD
);
4492 SbMethod
* pMeth
= p
!= NULL
? PTR_CAST(SbMethod
,p
) : NULL
;
4495 // TODO: Check vba behavior concernig missing function
4496 //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4502 sal_Int32 nParamCount
= rParams
.getLength();
4505 xArray
= new SbxArray
;
4506 const Any
*pArgs
= rParams
.getConstArray();
4507 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
4509 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
4510 unoToSbxValue( (SbxVariable
*)xVar
, pArgs
[i
] );
4511 xArray
->Put( xVar
, sal::static_int_cast
< sal_uInt16
>(i
+1) );
4516 SbxVariableRef xValue
= new SbxVariable
;
4518 pMeth
->SetParameters( xArray
);
4519 pMeth
->Call( xValue
);
4520 aRet
= sbxToUnoValue( xValue
);
4521 pMeth
->SetParameters( NULL
);
4523 if( bSetRescheduleBack
)
4524 pInst
->EnableReschedule( bOldReschedule
);
4526 // TODO: OutParameter?
4531 void SAL_CALL
ModuleInvocationProxy::dispose()
4532 throw(RuntimeException
, std::exception
)
4534 ::osl::MutexGuard
aGuard( m_aMutex
);
4536 EventObject
aEvent( (XComponent
*)this );
4537 m_aListeners
.disposeAndClear( aEvent
);
4542 void SAL_CALL
ModuleInvocationProxy::addEventListener( const Reference
< XEventListener
>& xListener
)
4543 throw (RuntimeException
, std::exception
)
4545 m_aListeners
.addInterface( xListener
);
4548 void SAL_CALL
ModuleInvocationProxy::removeEventListener( const Reference
< XEventListener
>& xListener
)
4549 throw (RuntimeException
, std::exception
)
4551 m_aListeners
.removeInterface( xListener
);
4555 Reference
< XInterface
> createComListener( const Any
& aControlAny
, const OUString
& aVBAType
,
4556 const OUString
& aPrefix
, SbxObjectRef xScopeObj
)
4558 Reference
< XInterface
> xRet
;
4560 Reference
< XComponentContext
> xContext(
4561 comphelper::getProcessComponentContext() );
4562 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
4564 Reference
< XInvocation
> xProxy
= new ModuleInvocationProxy( aPrefix
, xScopeObj
);
4566 Sequence
<Any
> args( 3 );
4567 args
[0] <<= aControlAny
;
4568 args
[1] <<= aVBAType
;
4573 xRet
= xServiceMgr
->createInstanceWithArgumentsAndContext(
4574 OUString( "com.sun.star.custom.UnoComListener"),
4577 catch( const Exception
& )
4579 implHandleAnyException( ::cppu::getCaughtException() );
4585 typedef std::vector
< WeakReference
< XComponent
> > ComponentRefVector
;
4587 struct StarBasicDisposeItem
4589 StarBASIC
* m_pBasic
;
4590 SbxArrayRef m_pRegisteredVariables
;
4591 ComponentRefVector m_vComImplementsObjects
;
4593 StarBasicDisposeItem( StarBASIC
* pBasic
)
4594 : m_pBasic( pBasic
)
4596 m_pRegisteredVariables
= new SbxArray();
4600 typedef std::vector
< StarBasicDisposeItem
* > DisposeItemVector
;
4602 static DisposeItemVector GaDisposeItemVector
;
4604 static DisposeItemVector::iterator
lcl_findItemForBasic( StarBASIC
* pBasic
)
4606 DisposeItemVector::iterator it
;
4607 for( it
= GaDisposeItemVector
.begin() ; it
!= GaDisposeItemVector
.end() ; ++it
)
4609 StarBasicDisposeItem
* pItem
= *it
;
4610 if( pItem
->m_pBasic
== pBasic
)
4613 return GaDisposeItemVector
.end();
4616 static StarBasicDisposeItem
* lcl_getOrCreateItemForBasic( StarBASIC
* pBasic
)
4618 DisposeItemVector::iterator it
= lcl_findItemForBasic( pBasic
);
4619 StarBasicDisposeItem
* pItem
= (it
!= GaDisposeItemVector
.end()) ? *it
: NULL
;
4622 pItem
= new StarBasicDisposeItem( pBasic
);
4623 GaDisposeItemVector
.push_back( pItem
);
4628 void registerComponentToBeDisposedForBasic
4629 ( Reference
< XComponent
> xComponent
, StarBASIC
* pBasic
)
4631 StarBasicDisposeItem
* pItem
= lcl_getOrCreateItemForBasic( pBasic
);
4632 pItem
->m_vComImplementsObjects
.push_back( xComponent
);
4635 void registerComListenerVariableForBasic( SbxVariable
* pVar
, StarBASIC
* pBasic
)
4637 StarBasicDisposeItem
* pItem
= lcl_getOrCreateItemForBasic( pBasic
);
4638 SbxArray
* pArray
= pItem
->m_pRegisteredVariables
;
4639 pArray
->Put( pVar
, pArray
->Count() );
4642 void disposeComVariablesForBasic( StarBASIC
* pBasic
)
4644 DisposeItemVector::iterator it
= lcl_findItemForBasic( pBasic
);
4645 if( it
!= GaDisposeItemVector
.end() )
4647 StarBasicDisposeItem
* pItem
= *it
;
4649 SbxArray
* pArray
= pItem
->m_pRegisteredVariables
;
4650 sal_uInt16 nCount
= pArray
->Count();
4651 for( sal_uInt16 i
= 0 ; i
< nCount
; ++i
)
4653 SbxVariable
* pVar
= pArray
->Get( i
);
4654 pVar
->ClearComListener();
4657 ComponentRefVector
& rv
= pItem
->m_vComImplementsObjects
;
4658 ComponentRefVector::iterator itCRV
;
4659 for( itCRV
= rv
.begin() ; itCRV
!= rv
.end() ; ++itCRV
)
4663 Reference
< XComponent
> xComponent( (*itCRV
).get(), UNO_QUERY_THROW
);
4664 xComponent
->dispose();
4666 catch(const Exception
& )
4671 GaDisposeItemVector
.erase( it
);
4676 // Handle module implements mechanism for OLE types
4677 bool SbModule::createCOMWrapperForIface( Any
& o_rRetAny
, SbClassModuleObject
* pProxyClassModuleObject
)
4679 // For now: Take first interface that allows to instantiate COM wrapper
4680 // TODO: Check if support for multiple interfaces is needed
4682 Reference
< XComponentContext
> xContext(
4683 comphelper::getProcessComponentContext() );
4684 Reference
< XMultiComponentFactory
> xServiceMgr( xContext
->getServiceManager() );
4685 Reference
< XSingleServiceFactory
> xComImplementsFactory
4687 xServiceMgr
->createInstanceWithContext(
4688 OUString( "com.sun.star.custom.ComImplementsFactory"), xContext
),
4691 if( !xComImplementsFactory
.is() )
4694 bool bSuccess
= false;
4696 SbxArray
* pModIfaces
= pClassData
->mxIfaces
;
4697 sal_uInt16 nCount
= pModIfaces
->Count();
4698 for( sal_uInt16 i
= 0 ; i
< nCount
; ++i
)
4700 SbxVariable
* pVar
= pModIfaces
->Get( i
);
4701 OUString aIfaceName
= pVar
->GetName();
4703 if( !aIfaceName
.isEmpty() )
4705 OUString aPureIfaceName
= aIfaceName
;
4706 sal_Int32 indexLastDot
= aIfaceName
.lastIndexOf('.');
4707 if ( indexLastDot
> -1 )
4709 aPureIfaceName
= aIfaceName
.copy( indexLastDot
+ 1 );
4711 Reference
< XInvocation
> xProxy
= new ModuleInvocationProxy( aPureIfaceName
, pProxyClassModuleObject
);
4713 Sequence
<Any
> args( 2 );
4714 args
[0] <<= aIfaceName
;
4717 Reference
< XInterface
> xRet
;
4721 xRet
= xComImplementsFactory
->createInstanceWithArguments( args
);
4724 catch( const Exception
& )
4726 implHandleAnyException( ::cppu::getCaughtException() );
4731 Reference
< XComponent
> xComponent( xProxy
, UNO_QUERY
);
4732 if( xComponent
.is() )
4734 StarBASIC
* pParentBasic
= NULL
;
4735 SbxObject
* pCurObject
= this;
4738 SbxObject
* pObjParent
= pCurObject
->GetParent();
4739 pParentBasic
= PTR_CAST( StarBASIC
, pObjParent
);
4740 pCurObject
= pObjParent
;
4742 while( pParentBasic
== NULL
&& pCurObject
!= NULL
);
4744 OSL_ASSERT( pParentBasic
!= NULL
);
4745 registerComponentToBeDisposedForBasic( xComponent
, pParentBasic
);
4758 // Due to an incorrect behavior IE returns an object instead of a string
4759 // in some scenarios. Calling toString at the object may correct this.
4760 // Helper function used in sbxvalue.cxx
4761 bool handleToStringForCOMObjects( SbxObject
* pObj
, SbxValue
* pVal
)
4763 bool bSuccess
= false;
4765 SbUnoObject
* pUnoObj
= NULL
;
4766 if( pObj
!= NULL
&& (pUnoObj
= PTR_CAST(SbUnoObject
,pObj
)) != NULL
)
4768 // Only for native COM objects
4769 if( pUnoObj
->isNativeCOMObject() )
4771 SbxVariableRef pMeth
= pObj
->Find( OUString( "toString" ), SbxCLASS_METHOD
);
4784 Any
StructRefInfo::getValue()
4788 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
4789 typelib_TypeDescription
* pTD
= 0;
4790 maType
.getDescription(&pTD
);
4792 &aRet
, getInst(), pTD
,
4793 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
4794 typelib_typedescription_release(pTD
);
4798 bool StructRefInfo::setValue( const Any
& rValue
)
4800 return uno_type_assignData( getInst(),
4801 maType
.getTypeLibType(),
4802 const_cast<void*>(rValue
.getValue()),
4803 rValue
.getValueTypeRef(),
4804 reinterpret_cast< uno_QueryInterfaceFunc
>(cpp_queryInterface
),
4805 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
4806 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
4809 OUString
StructRefInfo::getTypeName() const
4811 return maType
.getTypeName();
4814 void* StructRefInfo::getInst()
4816 return const_cast<char *>(static_cast<char const *>(maAny
.getValue()) + mnPos
);
4819 TypeClass
StructRefInfo::getTypeClass() const
4821 return maType
.getTypeClass();
4824 SbUnoStructRefObject::SbUnoStructRefObject( const OUString
& aName_
, const StructRefInfo
& rMemberInfo
) : SbxObject( aName_
), maMemberInfo( rMemberInfo
), mbMemberCacheInit( false )
4826 SetClassName( OUString( maMemberInfo
.getTypeName() ) );
4829 SbUnoStructRefObject::~SbUnoStructRefObject()
4831 for ( StructFieldInfo::iterator it
= maFields
.begin(), it_end
= maFields
.end(); it
!= it_end
; ++it
)
4835 void SbUnoStructRefObject::initMemberCache()
4837 if ( mbMemberCacheInit
)
4840 typelib_TypeDescription
* pTD
= 0;
4841 maMemberInfo
.getType().getDescription(&pTD
);
4842 typelib_CompoundTypeDescription
* pCompTypeDescr
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
);
4843 for ( ; pCompTypeDescr
; pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
4844 nAll
+= pCompTypeDescr
->nMembers
;
4845 for ( pCompTypeDescr
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
); pCompTypeDescr
;
4846 pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
4848 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompTypeDescr
->ppTypeRefs
;
4849 rtl_uString
** ppNames
= pCompTypeDescr
->ppMemberNames
;
4850 sal_Int32
* pMemberOffsets
= pCompTypeDescr
->pMemberOffsets
;
4851 for ( sal_Int32 nPos
= pCompTypeDescr
->nMembers
; nPos
--; )
4853 OUString
aName( ppNames
[nPos
] );
4854 maFields
[ aName
] = new StructRefInfo( maMemberInfo
.getRootAnyRef(), ppTypeRefs
[nPos
], maMemberInfo
.getPos() + pMemberOffsets
[nPos
] );
4857 typelib_typedescription_release(pTD
);
4858 mbMemberCacheInit
= true;
4861 SbxVariable
* SbUnoStructRefObject::Find( const OUString
& rName
, SbxClassType t
)
4863 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
4866 if ( !mbMemberCacheInit
)
4868 StructFieldInfo::iterator it
= maFields
.find( OUString( rName
).toAsciiUpperCase() );
4869 if ( it
!= maFields
.end() )
4871 SbxDataType eSbxType
;
4872 eSbxType
= unoToSbxType( it
->second
->getTypeClass() );
4873 SbxDataType eRealSbxType
= eSbxType
;
4876 aProp
.Type
= com::sun::star::uno::Type( it
->second
->getTypeClass(), it
->second
->getTypeName() );
4877 SbUnoProperty
* pProp
= new SbUnoProperty( rName
, eSbxType
, eRealSbxType
, aProp
, 0, false, ( aProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
4878 SbxVariableRef xVarRef
= pProp
;
4879 QuickInsert( (SbxVariable
*)xVarRef
);
4886 if( rName
.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES
) ||
4887 rName
.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES
) ||
4888 rName
.equalsIgnoreAsciiCase(ID_DBG_METHODS
) )
4891 implCreateDbgProperties();
4893 // Now they have to be found regular
4894 pRes
= SbxObject::Find( rName
, SbxCLASS_DONTCARE
);
4901 // help method to create the dbg_-Properties
4902 void SbUnoStructRefObject::implCreateDbgProperties()
4906 // Id == -1: display the implemented interfaces corresponding the ClassProvider
4907 SbxVariableRef xVarRef
= new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES
), SbxSTRING
, SbxSTRING
, aProp
, -1, false, false );
4908 QuickInsert( (SbxVariable
*)xVarRef
);
4910 // Id == -2: output the properties
4911 xVarRef
= new SbUnoProperty( OUString(ID_DBG_PROPERTIES
), SbxSTRING
, SbxSTRING
, aProp
, -2, false, false );
4912 QuickInsert( (SbxVariable
*)xVarRef
);
4914 // Id == -3: output the Methods
4915 xVarRef
= new SbUnoProperty( OUString(ID_DBG_METHODS
), SbxSTRING
, SbxSTRING
, aProp
, -3, false, false );
4916 QuickInsert( (SbxVariable
*)xVarRef
);
4919 void SbUnoStructRefObject::implCreateAll()
4921 // throw away all existing methods and properties
4922 pMethods
= new SbxArray
;
4923 pProps
= new SbxArray
;
4925 if (!mbMemberCacheInit
)
4928 for ( StructFieldInfo::iterator it
= maFields
.begin(), it_end
= maFields
.end(); it
!= it_end
; ++it
)
4930 const OUString
& rName
= it
->first
;
4931 SbxDataType eSbxType
;
4932 eSbxType
= unoToSbxType( it
->second
->getTypeClass() );
4933 SbxDataType eRealSbxType
= eSbxType
;
4936 aProp
.Type
= com::sun::star::uno::Type( it
->second
->getTypeClass(), it
->second
->getTypeName() );
4937 SbUnoProperty
* pProp
= new SbUnoProperty( rName
, eSbxType
, eRealSbxType
, aProp
, 0, false, ( aProp
.Type
.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT
) );
4938 SbxVariableRef xVarRef
= pProp
;
4939 QuickInsert( (SbxVariable
*)xVarRef
);
4942 // Create Dbg_-Properties
4943 implCreateDbgProperties();
4947 Any
SbUnoStructRefObject::getUnoAny()
4949 return maMemberInfo
.getValue();
4952 OUString
SbUnoStructRefObject::Impl_DumpProperties()
4954 OUStringBuffer aRet
;
4955 aRet
.appendAscii("Properties of object ");
4956 aRet
.append( getDbgObjectName() );
4958 sal_uInt16 nPropCount
= pProps
->Count();
4959 sal_uInt16 nPropsPerLine
= 1 + nPropCount
/ 30;
4960 for( sal_uInt16 i
= 0; i
< nPropCount
; i
++ )
4962 SbxVariable
* pVar
= pProps
->Get( i
);
4965 OUStringBuffer aPropStr
;
4966 if( (i
% nPropsPerLine
) == 0 )
4968 aPropStr
.appendAscii( "\n" );
4970 // output the type and name
4971 // Is it in Uno a sequence?
4972 SbxDataType eType
= pVar
->GetFullType();
4974 OUString
aName( pVar
->GetName() );
4975 StructFieldInfo::iterator it
= maFields
.find( aName
);
4977 if ( it
!= maFields
.end() )
4979 const StructRefInfo
& rPropInfo
= *it
->second
;
4981 if( eType
== SbxOBJECT
)
4983 if( rPropInfo
.getTypeClass() == TypeClass_SEQUENCE
)
4985 eType
= (SbxDataType
) ( SbxOBJECT
| SbxARRAY
);
4989 aPropStr
.append( Dbg_SbxDataType2String( eType
) );
4991 aPropStr
.appendAscii( " " );
4992 aPropStr
.append( pVar
->GetName() );
4994 if( i
== nPropCount
- 1 )
4996 aPropStr
.appendAscii( "\n" );
5000 aPropStr
.appendAscii( "; " );
5002 aRet
.append( aPropStr
.makeStringAndClear() );
5005 return aRet
.makeStringAndClear();
5008 void SbUnoStructRefObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
5009 const SfxHint
& rHint
, const TypeId
& rHintType
)
5011 if ( !mbMemberCacheInit
)
5013 const SbxHint
* pHint
= dynamic_cast<const SbxHint
*>(&rHint
);
5016 SbxVariable
* pVar
= pHint
->GetVar();
5017 SbUnoProperty
* pProp
= PTR_CAST(SbUnoProperty
,pVar
);
5020 StructFieldInfo::iterator it
= maFields
.find( pProp
->GetName() );
5021 // handle get/set of members of struct
5022 if( pHint
->GetId() == SBX_HINT_DATAWANTED
)
5025 sal_Int32 nId
= pProp
->nId
;
5028 // Id == -1: Display implemented interfaces according the ClassProvider
5029 if( nId
== -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
5031 OUStringBuffer aRet
;
5032 aRet
.appendAscii( ID_DBG_SUPPORTEDINTERFACES
);
5033 aRet
.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
5035 pVar
->PutString( aRet
.makeStringAndClear() );
5037 // Id == -2: output properties
5038 else if( nId
== -2 ) // Property ID_DBG_PROPERTIES
5040 // by now all properties must be established
5042 OUString aRetStr
= Impl_DumpProperties();
5043 pVar
->PutString( aRetStr
);
5045 // Id == -3: output the methods
5046 else if( nId
== -3 ) // Property ID_DBG_METHODS
5048 // by now all properties must be established
5050 OUStringBuffer aRet
;
5051 aRet
.appendAscii("Methods of object ");
5052 aRet
.append( getDbgObjectName() );
5053 aRet
.appendAscii( "\nNo methods found\n" );
5054 pVar
->PutString( aRet
.makeStringAndClear() );
5059 if ( it
!= maFields
.end() )
5061 Any aRetAny
= it
->second
->getValue();
5062 unoToSbxValue( pVar
, aRetAny
);
5065 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
5067 else if( pHint
->GetId() == SBX_HINT_DATACHANGED
)
5069 if ( it
!= maFields
.end() )
5071 // take over the value from Uno to Sbx
5072 Any aAnyValue
= sbxToUnoValue( pVar
, pProp
->aUnoProp
.Type
, &pProp
->aUnoProp
);
5073 it
->second
->setValue( aAnyValue
);
5076 StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND
);
5080 SbxObject::SFX_NOTIFY( rBC
, rBCType
, rHint
, rHintType
);
5084 StructRefInfo
SbUnoStructRefObject::getStructMember( const OUString
& rMemberName
)
5086 if (!mbMemberCacheInit
)
5090 StructFieldInfo::iterator it
= maFields
.find( rMemberName
);
5092 css::uno::Type aFoundType
;
5093 sal_Int32 nFoundPos
= -1;
5095 if ( it
!= maFields
.end() )
5097 aFoundType
= it
->second
->getType();
5098 nFoundPos
= it
->second
->getPos();
5100 StructRefInfo
aRet( maMemberInfo
.getRootAnyRef(), aFoundType
, nFoundPos
);
5104 OUString
SbUnoStructRefObject::getDbgObjectName()
5106 OUString aName
= GetClassName();
5107 if( aName
.isEmpty() )
5111 OUStringBuffer aRet
;
5112 if( aName
.getLength() > 20 )
5114 aRet
.appendAscii( "\n" );
5116 aRet
.appendAscii( "\"" );
5117 aRet
.append( aName
);
5118 aRet
.appendAscii( "\":" );
5119 return aRet
.makeStringAndClear();
5122 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */