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