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 <boost/unordered_map.hpp>
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 63142 : TYPEINIT1(SbUnoMethod,SbxMethod)
101 103808 : TYPEINIT1(SbUnoProperty,SbxProperty)
102 1078074 : TYPEINIT1(SbUnoObject,SbxObject)
103 1124 : TYPEINIT1(SbUnoStructRefObject,SbxObject)
104 84 : 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 4020 : bool SbUnoObject::getDefaultPropName( SbUnoObject* pUnoObj, OUString& sDfltProp )
124 : {
125 4020 : bool result = false;
126 4020 : Reference< XDefaultProperty> xDefaultProp( pUnoObj->maTmpUnoObj, UNO_QUERY );
127 4020 : if ( xDefaultProp.is() )
128 : {
129 2420 : sDfltProp = xDefaultProp->getDefaultPropertyName();
130 2420 : if ( !sDfltProp.isEmpty() )
131 2420 : result = true;
132 : }
133 4020 : return result;
134 : }
135 :
136 206 : SbxVariable* getDefaultProp( SbxVariable* pRef )
137 : {
138 206 : SbxVariable* pDefaultProp = NULL;
139 206 : if ( pRef->GetType() == SbxOBJECT )
140 : {
141 206 : SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pRef);
142 206 : if ( !pObj )
143 : {
144 198 : SbxBase* pObjVarObj = pRef->GetObject();
145 198 : pObj = PTR_CAST(SbxObject,pObjVarObj);
146 : }
147 206 : if ( pObj && pObj->ISA(SbUnoObject) )
148 : {
149 192 : SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)pObj);
150 192 : pDefaultProp = pUnoObj->GetDfltProperty();
151 : }
152 : }
153 206 : return pDefaultProp;
154 : }
155 :
156 0 : void SetSbUnoObjectDfltPropName( SbxObject* pObj )
157 : {
158 0 : SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*) 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 22544 : Reference< XIdlReflection > getCoreReflection_Impl( void )
173 : {
174 : return css::reflection::theCoreReflection::get(
175 22544 : comphelper::getProcessComponentContext());
176 : }
177 :
178 : // save CoreReflection statically
179 114 : Reference< XHierarchicalNameAccess > getCoreReflection_HierarchicalNameAccess_Impl( void )
180 : {
181 114 : static Reference< XHierarchicalNameAccess > xCoreReflection_HierarchicalNameAccess;
182 :
183 114 : if( !xCoreReflection_HierarchicalNameAccess.is() )
184 : {
185 8 : Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
186 8 : if( xCoreReflection.is() )
187 : {
188 16 : xCoreReflection_HierarchicalNameAccess =
189 8 : Reference< XHierarchicalNameAccess >( xCoreReflection, UNO_QUERY );
190 8 : }
191 : }
192 114 : return xCoreReflection_HierarchicalNameAccess;
193 : }
194 :
195 : // Hold TypeProvider statically
196 230 : Reference< XHierarchicalNameAccess > getTypeProvider_Impl( void )
197 : {
198 230 : static Reference< XHierarchicalNameAccess > xAccess;
199 :
200 : // Do we have already CoreReflection; if not obtain it
201 230 : if( !xAccess.is() )
202 : {
203 : Reference< XComponentContext > xContext(
204 8 : comphelper::getProcessComponentContext() );
205 8 : if( xContext.is() )
206 : {
207 8 : xContext->getValueByName(
208 8 : OUString( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) )
209 8 : >>= xAccess;
210 : OSL_ENSURE( xAccess.is(), "### TypeDescriptionManager singleton not accessible!?" );
211 : }
212 8 : if( !xAccess.is() )
213 : {
214 : throw DeploymentException(
215 0 : "/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessible" );
216 8 : }
217 : }
218 230 : return xAccess;
219 : }
220 :
221 : // Hold TypeConverter statically
222 0 : Reference< XTypeConverter > getTypeConverter_Impl( void )
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 40 : SbUnoObject* createOLEObject_Impl( const OUString& aType )
247 : {
248 40 : static Reference< XMultiServiceFactory > xOLEFactory;
249 : static bool bNeedsInit = true;
250 :
251 40 : if( bNeedsInit )
252 : {
253 8 : bNeedsInit = false;
254 :
255 : Reference< XComponentContext > xContext(
256 8 : comphelper::getProcessComponentContext() );
257 8 : if( xContext.is() )
258 : {
259 8 : Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
260 16 : xOLEFactory = Reference<XMultiServiceFactory>(
261 8 : xSMgr->createInstanceWithContext(
262 : OUString( "com.sun.star.bridge.OleObjectFactory"),
263 24 : xContext ), UNO_QUERY );
264 8 : }
265 : }
266 :
267 40 : SbUnoObject* pUnoObj = NULL;
268 40 : 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 40 : return pUnoObj;
289 : }
290 :
291 :
292 : namespace
293 : {
294 12 : void lcl_indent( OUStringBuffer& _inout_rBuffer, sal_Int32 _nLevel )
295 : {
296 24 : while ( _nLevel-- > 0 )
297 : {
298 0 : _inout_rBuffer.appendAscii( " " );
299 : }
300 12 : }
301 : }
302 :
303 6 : void implAppendExceptionMsg( OUStringBuffer& _inout_rBuffer, const Exception& _e, const OUString& _rExceptionType, sal_Int32 _nLevel )
304 : {
305 6 : _inout_rBuffer.appendAscii( "\n" );
306 6 : lcl_indent( _inout_rBuffer, _nLevel );
307 6 : _inout_rBuffer.appendAscii( "Type: " );
308 :
309 6 : if ( _rExceptionType.isEmpty() )
310 0 : _inout_rBuffer.appendAscii( "Unknown" );
311 : else
312 6 : _inout_rBuffer.append( _rExceptionType );
313 :
314 6 : _inout_rBuffer.appendAscii( "\n" );
315 6 : lcl_indent( _inout_rBuffer, _nLevel );
316 6 : _inout_rBuffer.appendAscii( "Message: " );
317 6 : _inout_rBuffer.append( _e.Message );
318 :
319 6 : }
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 82598 : TYPEINIT1(SbUnoAnyObject,SbxObject)
366 :
367 :
368 : // TODO: source out later
369 22392 : Reference<XIdlClass> TypeToIdlClass( const Type& rType )
370 : {
371 22392 : 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, ::getCppuType( &e ).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 6 : void implHandleWrappedTargetException( const Any& _rWrappedTargetException )
388 : {
389 6 : 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 12 : InvocationTargetException aInvocationError;
394 6 : if ( aExamine >>= aInvocationError )
395 6 : aExamine = aInvocationError.TargetException;
396 :
397 12 : BasicErrorException aBasicError;
398 :
399 6 : SbError nError( ERRCODE_BASIC_EXCEPTION );
400 12 : OUStringBuffer aMessageBuf;
401 :
402 : // strip any other WrappedTargetException instances, but this time preserve the error messages.
403 12 : WrappedTargetException aWrapped;
404 6 : sal_Int32 nLevel = 0;
405 12 : 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 6 : if ( aExamine.getValueTypeClass() == TypeClass_EXCEPTION )
428 : {
429 : // the last element in the chain is still an exception, but no WrappedTargetException
430 6 : implAppendExceptionMsg( aMessageBuf, *static_cast< const Exception* >( aExamine.getValue() ), aExamine.getValueTypeName(), nLevel );
431 : }
432 :
433 12 : StarBASIC::Error( nError, aMessageBuf.makeStringAndClear() );
434 6 : }
435 :
436 6 : static void implHandleAnyException( const Any& _rCaughtException )
437 : {
438 6 : BasicErrorException aBasicError;
439 12 : WrappedTargetException aWrappedError;
440 :
441 6 : if ( _rCaughtException >>= aBasicError )
442 : {
443 0 : implHandleBasicErrorException( aBasicError );
444 : }
445 6 : else if ( _rCaughtException >>= aWrappedError )
446 : {
447 6 : implHandleWrappedTargetException( _rCaughtException );
448 : }
449 : else
450 : {
451 0 : StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( _rCaughtException ) );
452 6 : }
453 6 : }
454 :
455 : // NativeObjectWrapper handling
456 0 : struct ObjectItem
457 : {
458 : SbxObjectRef m_xNativeObj;
459 :
460 0 : 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 132 : void clearNativeObjectWrapperVector( void )
469 : {
470 132 : GaNativeObjectWrapperVector::get().clear();
471 132 : }
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 11226 : SbxDataType unoToSbxType( TypeClass eType )
495 : {
496 11226 : SbxDataType eRetType = SbxVOID;
497 :
498 11226 : switch( eType )
499 : {
500 : case TypeClass_INTERFACE:
501 : case TypeClass_TYPE:
502 : case TypeClass_STRUCT:
503 814 : case TypeClass_EXCEPTION: eRetType = SbxOBJECT; break;
504 :
505 0 : case TypeClass_ENUM: eRetType = SbxLONG; break;
506 : case TypeClass_SEQUENCE:
507 6 : eRetType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
508 6 : break;
509 :
510 :
511 8724 : case TypeClass_ANY: eRetType = SbxVARIANT; break;
512 244 : case TypeClass_BOOLEAN: eRetType = SbxBOOL; break;
513 0 : case TypeClass_CHAR: eRetType = SbxCHAR; break;
514 616 : case TypeClass_STRING: eRetType = SbxSTRING; break;
515 0 : case TypeClass_FLOAT: eRetType = SbxSINGLE; break;
516 72 : case TypeClass_DOUBLE: eRetType = SbxDOUBLE; break;
517 0 : case TypeClass_BYTE: eRetType = SbxINTEGER; break;
518 30 : case TypeClass_SHORT: eRetType = SbxINTEGER; break;
519 254 : 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 466 : default: break;
525 : }
526 11226 : return eRetType;
527 : }
528 :
529 1980 : SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass )
530 : {
531 1980 : SbxDataType eRetType = SbxVOID;
532 1980 : if( xIdlClass.is() )
533 : {
534 1980 : TypeClass eType = xIdlClass->getTypeClass();
535 1980 : eRetType = unoToSbxType( eType );
536 : }
537 1980 : return eRetType;
538 : }
539 :
540 7100 : 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 7100 : Type aType = aValue.getValueType();
543 7100 : TypeClass eTypeClass = aType.getTypeClass();
544 :
545 7100 : sal_Int32 dimCopy = dimension;
546 :
547 7100 : if ( eTypeClass == TypeClass_SEQUENCE )
548 : {
549 288 : Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
550 576 : Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
551 288 : typelib_TypeDescription * pTD = 0;
552 288 : aType.getDescription( &pTD );
553 576 : Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
554 288 : ::typelib_typedescription_release( pTD );
555 :
556 288 : sal_Int32 nLen = xIdlArray->getLen( aValue );
557 7326 : for ( sal_Int32 index = 0; index < nLen; ++index )
558 : {
559 7038 : Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)index );
560 : // This detects the dimension were currently processing
561 7038 : if ( dimCopy == dimension )
562 : {
563 288 : ++dimCopy;
564 288 : if ( sizes.getLength() < dimCopy )
565 : {
566 124 : sizes.realloc( sizes.getLength() + 1 );
567 124 : sizes[ sizes.getLength() - 1 ] = nLen;
568 124 : indices.realloc( indices.getLength() + 1 );
569 : }
570 : }
571 :
572 7038 : if ( bIsZeroIndex )
573 0 : indices[ dimCopy - 1 ] = index;
574 : else
575 7038 : indices[ dimCopy - 1] = index + 1;
576 :
577 7038 : implSequenceToMultiDimArray( pArray, indices, sizes, aElementAny, dimCopy, bIsZeroIndex, &aElementType );
578 7326 : }
579 :
580 : }
581 : else
582 : {
583 6812 : 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 7100 : return;
591 : }
592 :
593 6812 : SbxDataType eSbxElementType = unoToSbxType( pType ? pType->getTypeClass() : aValue.getValueTypeClass() );
594 6812 : if ( !pArray )
595 : {
596 62 : pArray = new SbxDimArray( eSbxElementType );
597 62 : sal_Int32 nIndexLen = indices.getLength();
598 :
599 : // Dimension the array
600 186 : for ( sal_Int32 index = 0; index < nIndexLen; ++index )
601 : {
602 124 : if ( bIsZeroIndex )
603 0 : pArray->unoAddDim32( 0, sizes[ index ] - 1);
604 : else
605 124 : pArray->unoAddDim32( 1, sizes[ index ] );
606 :
607 : }
608 : }
609 :
610 6812 : if ( pArray )
611 : {
612 6812 : SbxVariableRef xVar = new SbxVariable( eSbxElementType );
613 6812 : unoToSbxValue( (SbxVariable*)xVar, aValue );
614 :
615 6812 : sal_Int32* pIndices = indices.getArray();
616 6812 : pArray->Put32( (SbxVariable*)xVar, pIndices );
617 :
618 : }
619 7100 : }
620 : }
621 :
622 14664 : void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
623 : {
624 14664 : Type aType = aValue.getValueType();
625 14664 : TypeClass eTypeClass = aType.getTypeClass();
626 14664 : 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 = (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 4082 : if( eTypeClass == TypeClass_STRUCT )
659 : {
660 146 : ArrayWrapper aWrap;
661 230 : NativeObjectWrapper aNativeObjectWrapper;
662 146 : if ( (aValue >>= aWrap) )
663 : {
664 62 : SbxDimArray* pArray = NULL;
665 62 : Sequence< sal_Int32 > indices;
666 124 : Sequence< sal_Int32 > sizes;
667 62 : sal_Int32 dimension = 0;
668 62 : implSequenceToMultiDimArray( pArray, indices, sizes, aWrap.Array, dimension, aWrap.IsZeroIndex );
669 62 : if ( pArray )
670 : {
671 62 : SbxDimArrayRef xArray = pArray;
672 62 : SbxFlagBits nFlags = pVar->GetFlags();
673 62 : pVar->ResetFlag( SBX_FIXED );
674 62 : pVar->PutObject( (SbxDimArray*)xArray );
675 62 : pVar->SetFlags( nFlags );
676 : }
677 : else
678 0 : pVar->PutEmpty();
679 124 : break;
680 : }
681 84 : 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 84 : SbiInstance* pInst = GetSbData()->pInst;
696 84 : if( pInst && pInst->IsCompatibility() )
697 : {
698 20 : oleautomation::Date aDate;
699 20 : if( (aValue >>= aDate) )
700 : {
701 0 : pVar->PutDate( aDate.Value );
702 0 : break;
703 : }
704 : else
705 : {
706 20 : oleautomation::Decimal aDecimal;
707 20 : if( (aValue >>= aDecimal) )
708 : {
709 0 : pVar->PutDecimal( aDecimal );
710 0 : break;
711 : }
712 : else
713 : {
714 20 : oleautomation::Currency aCurrency;
715 20 : if( (aValue >>= aCurrency) )
716 : {
717 0 : pVar->PutCurrency( aCurrency.Value );
718 0 : break;
719 : }
720 : }
721 : }
722 : }
723 84 : }
724 : }
725 : // instantiate a SbUnoObject
726 4020 : OUString aName;
727 4020 : 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 4020 : OUString sDfltPropName;
735 :
736 4020 : if ( SbUnoObject::getDefaultPropName( pSbUnoObject, sDfltPropName ) )
737 : {
738 2420 : pSbUnoObject->SetDfltProperty( sDfltPropName );
739 4020 : }
740 : }
741 8040 : SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
742 :
743 : // If the object is invalid deliver null
744 4020 : if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
745 : {
746 24 : pVar->PutObject( NULL );
747 : }
748 : else
749 : {
750 3996 : pVar->PutObject( xWrapper );
751 4020 : }
752 : }
753 4020 : 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 16 : Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
767 32 : Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
768 16 : sal_Int32 i, nLen = xIdlArray->getLen( aValue );
769 :
770 16 : typelib_TypeDescription * pTD = 0;
771 16 : aType.getDescription( &pTD );
772 : OSL_ASSERT( pTD && pTD->eTypeClass == typelib_TypeClass_SEQUENCE );
773 32 : Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
774 16 : ::typelib_typedescription_release( pTD );
775 :
776 : // build an Array in Basic
777 32 : SbxDimArrayRef xArray;
778 16 : SbxDataType eSbxElementType = unoToSbxType( aElementType.getTypeClass() );
779 16 : xArray = new SbxDimArray( eSbxElementType );
780 16 : if( nLen > 0 )
781 : {
782 14 : xArray->unoAddDim32( 0, nLen - 1 );
783 :
784 : // register the elements as variables
785 58 : for( i = 0 ; i < nLen ; i++ )
786 : {
787 : // convert elements
788 44 : Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)i );
789 88 : SbxVariableRef xVar = new SbxVariable( eSbxElementType );
790 44 : unoToSbxValue( (SbxVariable*)xVar, aElementAny );
791 :
792 : // put into the Array
793 44 : xArray->Put32( (SbxVariable*)xVar, &i );
794 44 : }
795 : }
796 : else
797 : {
798 2 : xArray->unoAddDim( 0, -1 );
799 : }
800 :
801 : // return the Array
802 16 : SbxFlagBits nFlags = pVar->GetFlags();
803 16 : pVar->ResetFlag( SBX_FIXED );
804 16 : pVar->PutObject( (SbxDimArray*)xArray );
805 32 : pVar->SetFlags( nFlags );
806 :
807 : }
808 16 : break;
809 :
810 :
811 564 : case TypeClass_BOOLEAN: pVar->PutBool( *(sal_Bool*)aValue.getValue() ); break;
812 : case TypeClass_CHAR:
813 : {
814 0 : pVar->PutChar( *(sal_Unicode*)aValue.getValue() );
815 0 : break;
816 : }
817 1076 : case TypeClass_STRING: { OUString val; aValue >>= val; pVar->PutString( val ); } break;
818 4 : case TypeClass_FLOAT: { float val = 0; aValue >>= val; pVar->PutSingle( val ); } break;
819 4968 : 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 80 : case TypeClass_SHORT: { sal_Int16 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
822 814 : 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 3060 : default: pVar->PutEmpty(); break;
828 14664 : }
829 14664 : }
830 :
831 : // Deliver the reflection for Sbx types
832 3644 : Type getUnoTypeForSbxBaseType( SbxDataType eType )
833 : {
834 3644 : Type aRetType = getCppuVoidType();
835 3644 : switch( eType )
836 : {
837 0 : case SbxNULL: aRetType = cppu::UnoType<XInterface>::get(); break;
838 948 : case SbxINTEGER: aRetType = cppu::UnoType<sal_Int16>::get(); break;
839 168 : case SbxLONG: aRetType = cppu::UnoType<sal_Int32>::get(); break;
840 0 : case SbxSINGLE: aRetType = cppu::UnoType<float>::get(); break;
841 54 : 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 2018 : case SbxSTRING: aRetType = cppu::UnoType<OUString>::get(); break;
853 146 : case SbxBOOL: aRetType = cppu::UnoType<sal_Bool>::get(); break;
854 20 : 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 290 : default: break;
863 : }
864 3644 : return aRetType;
865 : }
866 :
867 : // Converting of Sbx to Uno without a know target class for TypeClass_ANY
868 44446 : Type getUnoTypeForSbxValue( const SbxValue* pVal )
869 : {
870 44446 : Type aRetType = getCppuVoidType();
871 44446 : if( !pVal )
872 0 : return aRetType;
873 :
874 : // convert SbxType to Uno
875 44446 : SbxDataType eBaseType = pVal->SbxValue::GetType();
876 44446 : if( eBaseType == SbxOBJECT )
877 : {
878 40822 : SbxBaseRef xObj = (SbxBase*)pVal->GetObject();
879 40822 : if( !xObj )
880 : {
881 0 : aRetType = cppu::UnoType<XInterface>::get();
882 0 : return aRetType;
883 : }
884 :
885 40822 : if( xObj->ISA(SbxDimArray) )
886 : {
887 20 : SbxBase* pObj = static_cast<SbxBase*>(xObj);
888 20 : SbxDimArray* pArray = static_cast<SbxDimArray*>(pObj);
889 :
890 20 : short nDims = pArray->GetDims();
891 20 : Type aElementType = getUnoTypeForSbxBaseType( (SbxDataType)(pArray->GetType() & 0xfff) );
892 20 : TypeClass eElementTypeClass = aElementType.getTypeClass();
893 :
894 : // Normal case: One dimensional array
895 : sal_Int32 nLower, nUpper;
896 20 : if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
897 : {
898 16 : 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 16 : bool bNeedsInit = true;
903 :
904 16 : sal_Int32 nSize = nUpper - nLower + 1;
905 16 : sal_Int32 nIdx = nLower;
906 60 : for( sal_Int32 i = 0 ; i < nSize ; i++,nIdx++ )
907 : {
908 : // coverity[array_vs_singleton]
909 50 : SbxVariableRef xVar = pArray->Get32( &nIdx );
910 94 : Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
911 50 : if( bNeedsInit )
912 : {
913 16 : 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 16 : aElementType = aType;
921 16 : bNeedsInit = false;
922 : }
923 34 : else if( aElementType != aType )
924 : {
925 : // different types -> AnySequence
926 6 : aElementType = cppu::UnoType<Any>::get();
927 6 : break;
928 : }
929 44 : }
930 : }
931 :
932 16 : OUString aSeqTypeName = aSeqLevelStr + aElementType.getTypeName();
933 16 : aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
934 : }
935 : // #i33795 Map also multi dimensional arrays to corresponding sequences
936 4 : else if( nDims > 1 )
937 : {
938 4 : if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
939 : {
940 : // For this check the array's dim structure does not matter
941 4 : sal_uInt32 nFlatArraySize = pArray->Count32();
942 :
943 4 : bool bNeedsInit = true;
944 52 : for( sal_uInt32 i = 0 ; i < nFlatArraySize ; i++ )
945 : {
946 48 : SbxVariableRef xVar = pArray->SbxArray::Get32( i );
947 96 : Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
948 48 : if( bNeedsInit )
949 : {
950 4 : 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 4 : aElementType = aType;
958 4 : bNeedsInit = false;
959 : }
960 44 : else if( aElementType != aType )
961 : {
962 : // different types -> AnySequence
963 0 : aElementType = cppu::UnoType<Any>::get();
964 0 : break;
965 : }
966 48 : }
967 : }
968 :
969 4 : OUStringBuffer aSeqTypeName;
970 12 : for( short iDim = 0 ; iDim < nDims ; iDim++ )
971 : {
972 8 : aSeqTypeName.appendAscii(aSeqLevelStr);
973 : }
974 4 : aSeqTypeName.append(aElementType.getTypeName());
975 4 : aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName.makeStringAndClear() );
976 20 : }
977 : }
978 : // No array, but ...
979 40802 : else if( xObj->ISA(SbUnoObject) )
980 : {
981 40802 : aRetType = static_cast<SbUnoObject*>((SbxBase*)xObj)->getUnoAny().getValueType();
982 : }
983 : // SbUnoAnyObject?
984 0 : else if( xObj->ISA(SbUnoAnyObject) )
985 : {
986 0 : aRetType = static_cast<SbUnoAnyObject*>((SbxBase*)xObj)->getValue().getValueType();
987 40822 : }
988 : // Otherwise it is a No-Uno-Basic-Object -> default==deliver void
989 : }
990 : // No object, convert basic type
991 : else
992 : {
993 3624 : aRetType = getUnoTypeForSbxBaseType( eBaseType );
994 : }
995 44446 : return aRetType;
996 : }
997 :
998 : // converting of Sbx to Uno without known target class for TypeClass_ANY
999 44348 : Any sbxToUnoValueImpl( const SbxValue* pVar, bool bBlockConversionToSmallestType = false )
1000 : {
1001 44348 : SbxDataType eBaseType = pVar->SbxValue::GetType();
1002 44348 : if( eBaseType == SbxOBJECT )
1003 : {
1004 40814 : SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
1005 40814 : if( xObj.Is() )
1006 : {
1007 40814 : if( xObj->ISA(SbUnoAnyObject) )
1008 0 : return static_cast<SbUnoAnyObject*>((SbxBase*)xObj)->getValue();
1009 40814 : if( xObj->ISA(SbClassModuleObject) )
1010 : {
1011 0 : Any aRetAny;
1012 0 : SbClassModuleObject* pClassModuleObj = static_cast<SbClassModuleObject*>((SbxBase*)xObj);
1013 0 : SbModule* pClassModule = pClassModuleObj->getClassModule();
1014 0 : if( pClassModule->createCOMWrapperForIface( aRetAny, pClassModuleObj ) )
1015 0 : return aRetAny;
1016 : }
1017 40814 : if( !xObj->ISA(SbUnoObject) )
1018 : {
1019 : // Create NativeObjectWrapper to identify object in case of callbacks
1020 20 : SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
1021 20 : 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 40814 : }
1032 : }
1033 :
1034 44348 : Type aType = getUnoTypeForSbxValue( pVar );
1035 44348 : TypeClass eType = aType.getTypeClass();
1036 :
1037 44348 : if( !bBlockConversionToSmallestType )
1038 : {
1039 : // #79615 Choose "smallest" represention for int values
1040 : // because up cast is allowed, downcast not
1041 44348 : switch( eType )
1042 : {
1043 : case TypeClass_FLOAT:
1044 : case TypeClass_DOUBLE:
1045 : {
1046 30 : double d = pVar->GetDouble();
1047 30 : if( d == floor( d ) )
1048 : {
1049 26 : if( d >= -128 && d <= 127 )
1050 24 : aType = ::cppu::UnoType<sal_Int8>::get();
1051 2 : else if( d >= SbxMININT && d <= SbxMAXINT )
1052 0 : aType = ::cppu::UnoType<sal_Int16>::get();
1053 2 : else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
1054 2 : aType = ::cppu::UnoType<sal_Int32>::get();
1055 : }
1056 30 : break;
1057 : }
1058 : case TypeClass_SHORT:
1059 : {
1060 884 : sal_Int16 n = pVar->GetInteger();
1061 884 : if( n >= -128 && n <= 127 )
1062 880 : aType = ::cppu::UnoType<sal_Int8>::get();
1063 884 : break;
1064 : }
1065 : case TypeClass_LONG:
1066 : {
1067 168 : sal_Int32 n = pVar->GetLong();
1068 168 : if( n >= -128 && n <= 127 )
1069 78 : aType = ::cppu::UnoType<sal_Int8>::get();
1070 90 : else if( n >= SbxMININT && n <= SbxMAXINT )
1071 88 : aType = ::cppu::UnoType<sal_Int16>::get();
1072 168 : 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 43266 : default: break;
1092 : }
1093 : }
1094 :
1095 44348 : return sbxToUnoValue( pVar, aType );
1096 : }
1097 :
1098 :
1099 :
1100 : // Helper function for StepREDIMP
1101 16 : 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 16 : sal_Int32 nSeqLevel = nMaxDimIndex - nActualDim + 1;
1106 16 : OUStringBuffer aSeqTypeName;
1107 : sal_Int32 i;
1108 36 : for( i = 0 ; i < nSeqLevel ; i++ )
1109 : {
1110 20 : aSeqTypeName.appendAscii(aSeqLevelStr);
1111 : }
1112 16 : aSeqTypeName.append(aElemType.getTypeName());
1113 32 : Type aSeqType( TypeClass_SEQUENCE, aSeqTypeName.makeStringAndClear() );
1114 :
1115 : // Create Sequence instance
1116 16 : Any aRetVal;
1117 32 : Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aSeqType );
1118 16 : xIdlTargetClass->createObject( aRetVal );
1119 :
1120 : // Alloc sequence according to array bounds
1121 16 : sal_Int32 nUpper = pUpperBounds[nActualDim];
1122 16 : sal_Int32 nLower = pLowerBounds[nActualDim];
1123 16 : sal_Int32 nSeqSize = nUpper - nLower + 1;
1124 32 : Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
1125 16 : xArray->realloc( aRetVal, nSeqSize );
1126 :
1127 16 : sal_Int32& ri = pActualIndices[nActualDim];
1128 :
1129 76 : for( ri = nLower,i = 0 ; ri <= nUpper ; ri++,i++ )
1130 : {
1131 60 : Any aElementVal;
1132 :
1133 60 : if( nActualDim < nMaxDimIndex )
1134 : {
1135 24 : aElementVal = implRekMultiDimArrayToSequence( pArray, aElemType,
1136 12 : nMaxDimIndex, nActualDim + 1, pActualIndices, pLowerBounds, pUpperBounds );
1137 : }
1138 : else
1139 : {
1140 48 : SbxVariable* pSource = pArray->Get32( pActualIndices );
1141 48 : aElementVal = sbxToUnoValue( pSource, aElemType );
1142 : }
1143 :
1144 : try
1145 : {
1146 : // transfer to the sequence
1147 60 : 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 60 : }
1159 32 : return aRetVal;
1160 : }
1161 :
1162 : // Map old interface
1163 40890 : Any sbxToUnoValue( const SbxValue* pVar )
1164 : {
1165 40890 : 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 48814 : Any sbxToUnoValue( const SbxValue* pVar, const Type& rType, Property* pUnoProperty )
1193 : {
1194 48814 : Any aRetVal;
1195 :
1196 : // #94560 No conversion of empty/void for MAYBE_VOID properties
1197 48814 : if( pUnoProperty && pUnoProperty->Attributes & PropertyAttribute::MAYBEVOID )
1198 : {
1199 2 : if( pVar->IsEmpty() )
1200 0 : return aRetVal;
1201 : }
1202 :
1203 48814 : SbxDataType eBaseType = pVar->SbxValue::GetType();
1204 48814 : if( eBaseType == SbxOBJECT )
1205 : {
1206 41122 : SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
1207 41122 : if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
1208 : {
1209 0 : return static_cast<SbUnoAnyObject*>((SbxBase*)xObj)->getValue();
1210 41122 : }
1211 : }
1212 :
1213 48814 : TypeClass eType = rType.getTypeClass();
1214 48814 : switch( eType )
1215 : {
1216 : case TypeClass_INTERFACE:
1217 : case TypeClass_STRUCT:
1218 : case TypeClass_EXCEPTION:
1219 : {
1220 21726 : Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
1221 :
1222 : // null reference?
1223 21726 : 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 21726 : if( eType == TypeClass_STRUCT )
1234 : {
1235 82 : SbiInstance* pInst = GetSbData()->pInst;
1236 82 : if( pInst && pInst->IsCompatibility() )
1237 : {
1238 4 : 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 4 : 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 4 : 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 21726 : SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
1262 21726 : if( pObj && pObj->ISA(SbUnoObject) )
1263 : {
1264 21722 : aRetVal = static_cast<SbUnoObject*>((SbxBase*)pObj)->getUnoAny();
1265 : }
1266 4 : else if( pObj && pObj->ISA(SbUnoStructRefObject) )
1267 : {
1268 0 : aRetVal = static_cast<SbUnoStructRefObject*>((SbxBase*)pObj)->getUnoAny();
1269 : }
1270 : else
1271 : {
1272 : // null object -> null XInterface
1273 4 : Reference<XInterface> xInt;
1274 4 : aRetVal <<= xInt;
1275 21726 : }
1276 21726 : }
1277 : }
1278 21726 : break;
1279 :
1280 : case TypeClass_TYPE:
1281 : {
1282 2 : if( eBaseType == SbxOBJECT )
1283 : {
1284 : // XIdlClass?
1285 2 : Reference< XIdlClass > xIdlClass;
1286 :
1287 4 : SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
1288 2 : if( pObj && pObj->ISA(SbUnoObject) )
1289 : {
1290 0 : Any aUnoAny = static_cast<SbUnoObject*>((SbxBase*)pObj)->getUnoAny();
1291 0 : aUnoAny >>= xIdlClass;
1292 : }
1293 :
1294 2 : if( xIdlClass.is() )
1295 : {
1296 0 : OUString aClassName = xIdlClass->getName();
1297 0 : Type aType( xIdlClass->getTypeClass(), aClassName.getStr() );
1298 0 : aRetVal <<= aType;
1299 2 : }
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 2 : 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 78 : SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
1324 78 : if( xObj && xObj->ISA(SbxDimArray) )
1325 : {
1326 78 : SbxBase* pObj = static_cast<SbxBase*>(xObj);
1327 78 : SbxDimArray* pArray = static_cast<SbxDimArray*>(pObj);
1328 :
1329 78 : short nDims = pArray->GetDims();
1330 :
1331 : // Normal case: One dimensional array
1332 : sal_Int32 nLower, nUpper;
1333 78 : if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
1334 : {
1335 74 : sal_Int32 nSeqSize = nUpper - nLower + 1;
1336 :
1337 : // create the instance of the required sequence
1338 74 : Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
1339 74 : xIdlTargetClass->createObject( aRetVal );
1340 148 : Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
1341 74 : xArray->realloc( aRetVal, nSeqSize );
1342 :
1343 : // Element-Type
1344 148 : OUString aClassName = xIdlTargetClass->getName();
1345 74 : typelib_TypeDescription * pSeqTD = 0;
1346 74 : typelib_typedescription_getByName( &pSeqTD, aClassName.pData );
1347 : OSL_ASSERT( pSeqTD );
1348 148 : Type aElemType( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
1349 :
1350 : // convert all array member and register them
1351 74 : sal_Int32 nIdx = nLower;
1352 176 : for( sal_Int32 i = 0 ; i < nSeqSize ; i++,nIdx++ )
1353 : {
1354 : // coverity[array_vs_singleton]
1355 102 : SbxVariableRef xVar = pArray->Get32( &nIdx );
1356 :
1357 : // Convert the value of Sbx to Uno
1358 204 : Any aAnyValue = sbxToUnoValue( (SbxVariable*)xVar, aElemType );
1359 :
1360 : try
1361 : {
1362 : // insert in the sequence
1363 102 : 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 176 : }
1375 : }
1376 : // #i33795 Map also multi dimensional arrays to corresponding sequences
1377 4 : else if( nDims > 1 )
1378 : {
1379 : // Element-Type
1380 4 : typelib_TypeDescription * pSeqTD = 0;
1381 4 : Type aCurType( rType );
1382 4 : sal_Int32 nSeqLevel = 0;
1383 8 : Type aElemType;
1384 : do
1385 : {
1386 12 : OUString aTypeName = aCurType.getTypeName();
1387 12 : typelib_typedescription_getByName( &pSeqTD, aTypeName.pData );
1388 : OSL_ASSERT( pSeqTD );
1389 12 : if( pSeqTD->eTypeClass == typelib_TypeClass_SEQUENCE )
1390 : {
1391 8 : aCurType = Type( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
1392 8 : nSeqLevel++;
1393 : }
1394 : else
1395 : {
1396 4 : aElemType = aCurType;
1397 4 : break;
1398 8 : }
1399 : }
1400 : while( true );
1401 :
1402 4 : if( nSeqLevel == nDims )
1403 : {
1404 4 : boost::scoped_array<sal_Int32> pLowerBounds(new sal_Int32[nDims]);
1405 8 : boost::scoped_array<sal_Int32> pUpperBounds(new sal_Int32[nDims]);
1406 8 : boost::scoped_array<sal_Int32> pActualIndices(new sal_Int32[nDims]);
1407 12 : for( short i = 1 ; i <= nDims ; i++ )
1408 : {
1409 : sal_Int32 lBound, uBound;
1410 8 : pArray->GetDim32( i, lBound, uBound );
1411 :
1412 8 : short j = i - 1;
1413 8 : pActualIndices[j] = pLowerBounds[j] = lBound;
1414 8 : pUpperBounds[j] = uBound;
1415 : }
1416 :
1417 8 : aRetVal = implRekMultiDimArrayToSequence( pArray, aElemType,
1418 8 : nDims - 1, 0, pActualIndices.get(), pLowerBounds.get(), pUpperBounds.get() );
1419 4 : }
1420 : }
1421 78 : }
1422 : }
1423 78 : break;
1424 :
1425 :
1426 : // for Any use the class independent converting routine
1427 : case TypeClass_ANY:
1428 : {
1429 3434 : aRetVal = sbxToUnoValueImpl( pVar );
1430 : }
1431 3434 : break;
1432 :
1433 : case TypeClass_BOOLEAN:
1434 : {
1435 348 : sal_Bool b = pVar->GetBool();
1436 348 : aRetVal.setValue( &b, getBooleanCppuType() );
1437 348 : break;
1438 : }
1439 : case TypeClass_CHAR:
1440 : {
1441 0 : sal_Unicode c = pVar->GetChar();
1442 0 : aRetVal.setValue( &c , getCharCppuType() );
1443 0 : break;
1444 : }
1445 2288 : case TypeClass_STRING: aRetVal <<= pVar->GetOUString(); break;
1446 0 : case TypeClass_FLOAT: aRetVal <<= pVar->GetSingle(); break;
1447 96 : case TypeClass_DOUBLE: aRetVal <<= pVar->GetDouble(); break;
1448 :
1449 : case TypeClass_BYTE:
1450 : {
1451 982 : sal_Int16 nVal = pVar->GetInteger();
1452 982 : bool bOverflow = false;
1453 982 : if( nVal < -128 )
1454 : {
1455 0 : bOverflow = true;
1456 0 : nVal = -128;
1457 : }
1458 982 : else if( nVal > 127 )
1459 : {
1460 0 : bOverflow = true;
1461 0 : nVal = 127;
1462 : }
1463 982 : if( bOverflow )
1464 0 : StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW );
1465 :
1466 982 : sal_Int8 nByteVal = (sal_Int8)nVal;
1467 982 : aRetVal <<= nByteVal;
1468 982 : break;
1469 : }
1470 182 : case TypeClass_SHORT: aRetVal <<= (sal_Int16)( pVar->GetInteger() ); break;
1471 154 : 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 19524 : default: break;
1477 : }
1478 :
1479 48814 : 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( (SbxVariable*)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 = *(Reference< XInterface >*)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 288 : bool checkUnoObjectType( SbUnoObject* pUnoObj, const OUString& rClass )
1671 : {
1672 288 : Any aToInspectObj = pUnoObj->getUnoAny();
1673 288 : TypeClass eType = aToInspectObj.getValueType().getTypeClass();
1674 288 : if( eType != TypeClass_INTERFACE )
1675 : {
1676 0 : return false;
1677 : }
1678 576 : const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();
1679 :
1680 : // Return true for XInvocation based objects as interface type names don't count then
1681 576 : Reference< XInvocation > xInvocation( x, UNO_QUERY );
1682 288 : if( xInvocation.is() )
1683 : {
1684 16 : return true;
1685 : }
1686 272 : bool result = false;
1687 544 : Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
1688 272 : 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 272 : OUString aClassName;
1699 272 : if ( SbiRuntime::isVBAEnabled() )
1700 : {
1701 272 : aClassName = ".";
1702 272 : sal_Int32 nClassNameDot = rClass.lastIndexOf( '.' );
1703 272 : if( nClassNameDot >= 0 )
1704 : {
1705 0 : aClassName += rClass.copy( 0, nClassNameDot + 1 ) + OUString( 'X' ) + rClass.copy( nClassNameDot + 1 );
1706 : }
1707 : else
1708 : {
1709 272 : aClassName += OUString( '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 544 : Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
1717 272 : const Type* pTypeArray = aTypeSeq.getConstArray();
1718 272 : sal_uInt32 nIfaceCount = aTypeSeq.getLength();
1719 272 : for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
1720 : {
1721 272 : const Type& rType = pTypeArray[j];
1722 :
1723 272 : Reference<XIdlClass> xClass = TypeToIdlClass( rType );
1724 272 : if( !xClass.is() )
1725 : {
1726 : OSL_FAIL("failed to get XIdlClass for type");
1727 0 : break;
1728 : }
1729 272 : OUString aInterfaceName = xClass->getName();
1730 272 : 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 544 : if ( (aClassName.getLength() <= aInterfaceName.getLength()) &&
1755 272 : aInterfaceName.endsWithIgnoreAsciiCase( aClassName ) )
1756 : {
1757 272 : result = true;
1758 272 : break;
1759 : }
1760 272 : }
1761 : }
1762 560 : 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 = *(Reference< XInterface >*)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_uInt16 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 8698 : void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
2030 : const SfxHint& rHint, const TypeId& rHintType )
2031 : {
2032 8698 : if( bNeedIntrospection )
2033 0 : doIntrospection();
2034 :
2035 8698 : const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
2036 8698 : if( pHint )
2037 : {
2038 8698 : SbxVariable* pVar = pHint->GetVar();
2039 8698 : SbxArray* pParams = pVar->GetParameters();
2040 8698 : SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
2041 8698 : SbUnoMethod* pMeth = PTR_CAST(SbUnoMethod,pVar);
2042 8698 : if( pProp )
2043 : {
2044 4484 : bool bInvocation = pProp->isInvocationBased();
2045 4484 : if( pHint->GetId() == SBX_HINT_DATAWANTED )
2046 : {
2047 : // Test-Properties
2048 3318 : sal_Int32 nId = pProp->nId;
2049 3318 : 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 3318 : if( !bInvocation && mxUnoAccess.is() )
2077 : {
2078 : try
2079 : {
2080 3096 : if ( maStructInfo.get() )
2081 : {
2082 98 : StructRefInfo aMember = maStructInfo->getStructMember( pProp->GetName() );
2083 98 : if ( aMember.isEmpty() )
2084 : {
2085 0 : StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
2086 : }
2087 : else
2088 : {
2089 98 : if ( pProp->isUnoStruct() )
2090 : {
2091 46 : SbUnoStructRefObject* pSbUnoObject = new SbUnoStructRefObject( pProp->GetName(), aMember );
2092 46 : SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
2093 46 : pVar->PutObject( xWrapper );
2094 : }
2095 : else
2096 : {
2097 52 : Any aRetAny = aMember.getValue();
2098 : // take over the value from Uno to Sbx
2099 52 : unoToSbxValue( pVar, aRetAny );
2100 : }
2101 98 : return;
2102 0 : }
2103 : }
2104 : // get the value
2105 2998 : Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()), UNO_QUERY );
2106 5996 : 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 posible to use FastPropertySet
2110 :
2111 : // take over the value from Uno to Sbx
2112 5996 : unoToSbxValue( pVar, aRetAny );
2113 : }
2114 0 : catch( const Exception& )
2115 : {
2116 0 : implHandleAnyException( ::cppu::getCaughtException() );
2117 : }
2118 : }
2119 222 : else if( bInvocation && mxInvocation.is() )
2120 : {
2121 : try
2122 : {
2123 222 : sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
2124 222 : bool bCanBeConsideredAMethod = mxInvocation->hasMethod( pProp->GetName() );
2125 222 : Any aRetAny;
2126 222 : 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 222 : aRetAny = mxInvocation->getValue( pProp->GetName() );
2136 : // take over the value from Uno to Sbx
2137 222 : unoToSbxValue( pVar, aRetAny );
2138 222 : 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 1166 : else if( pHint->GetId() == SBX_HINT_DATACHANGED )
2149 : {
2150 1166 : if( !bInvocation && mxUnoAccess.is() )
2151 : {
2152 1166 : if( pProp->aUnoProp.Attributes & PropertyAttribute::READONLY )
2153 : {
2154 0 : StarBASIC::Error( SbERR_PROP_READONLY );
2155 154 : return;
2156 : }
2157 1166 : if ( maStructInfo.get() )
2158 : {
2159 154 : StructRefInfo aMember = maStructInfo->getStructMember( pProp->GetName() );
2160 154 : if ( aMember.isEmpty() )
2161 : {
2162 0 : StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
2163 : }
2164 : else
2165 : {
2166 154 : Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
2167 154 : aMember.setValue( aAnyValue );
2168 : }
2169 154 : return;
2170 : }
2171 : // take over the value from Uno to Sbx
2172 1012 : Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
2173 : try
2174 : {
2175 : // set the value
2176 1012 : Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()), UNO_QUERY );
2177 1012 : 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 posible to use FastPropertySet
2181 : }
2182 0 : catch( const Exception& )
2183 : {
2184 0 : implHandleAnyException( ::cppu::getCaughtException() );
2185 1012 : }
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 4214 : else if( pMeth )
2204 : {
2205 4214 : bool bInvocation = pMeth->isInvocationBased();
2206 4214 : if( pHint->GetId() == SBX_HINT_DATAWANTED )
2207 : {
2208 : // number of Parameter -1 because of Param0 == this
2209 4196 : sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
2210 4196 : Sequence<Any> args;
2211 4196 : bool bOutParams = false;
2212 : sal_uInt32 i;
2213 :
2214 4196 : if( !bInvocation && mxUnoAccess.is() )
2215 : {
2216 : // get info
2217 4196 : const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
2218 4196 : const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
2219 4196 : sal_uInt32 nUnoParamCount = rInfoSeq.getLength();
2220 4196 : sal_uInt32 nAllocParamCount = nParamCount;
2221 :
2222 : // ignore surplus parameter; alternative: throw an error
2223 4196 : if( nParamCount > nUnoParamCount )
2224 : {
2225 0 : nParamCount = nUnoParamCount;
2226 0 : nAllocParamCount = nParamCount;
2227 : }
2228 4196 : else if( nParamCount < nUnoParamCount )
2229 : {
2230 2728 : SbiInstance* pInst = GetSbData()->pInst;
2231 2728 : if( pInst && pInst->IsCompatibility() )
2232 : {
2233 : // Check types
2234 2728 : bool bError = false;
2235 8106 : for( i = nParamCount ; i < nUnoParamCount ; i++ )
2236 : {
2237 5378 : const ParamInfo& rInfo = pParamInfos[i];
2238 5378 : const Reference< XIdlClass >& rxClass = rInfo.aType;
2239 5378 : if( rxClass->getTypeClass() != TypeClass_ANY )
2240 : {
2241 0 : bError = true;
2242 0 : StarBASIC::Error( SbERR_NOT_OPTIONAL );
2243 : }
2244 : }
2245 2728 : if( !bError )
2246 2728 : nAllocParamCount = nUnoParamCount;
2247 : }
2248 : }
2249 :
2250 4196 : if( nAllocParamCount > 0 )
2251 : {
2252 3422 : args.realloc( nAllocParamCount );
2253 3422 : Any* pAnyArgs = args.getArray();
2254 6568 : for( i = 0 ; i < nParamCount ; i++ )
2255 : {
2256 3146 : const ParamInfo& rInfo = pParamInfos[i];
2257 3146 : const Reference< XIdlClass >& rxClass = rInfo.aType;
2258 :
2259 3146 : com::sun::star::uno::Type aType( rxClass->getTypeClass(), rxClass->getName() );
2260 :
2261 : // ATTENTION: Don't forget for Sbx-Parameter the offset!
2262 3146 : 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 3146 : if( !bOutParams )
2266 : {
2267 3146 : ParamMode aParamMode = rInfo.aMode;
2268 3146 : if( aParamMode != ParamMode_IN )
2269 16 : bOutParams = true;
2270 : }
2271 3146 : }
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 4196 : GetSbData()->bBlockCompilerError = true; // #106433 Block compiler errors for API calls
2282 : try
2283 : {
2284 4196 : if( !bInvocation && mxUnoAccess.is() )
2285 : {
2286 4202 : Any aRetAny = pMeth->m_xUnoMethod->invoke( getUnoAny(), args );
2287 :
2288 : // take over the value from Uno to Sbx
2289 4190 : unoToSbxValue( pVar, aRetAny );
2290 :
2291 : // Did we to copy back the Out-Parameter?
2292 4190 : if( bOutParams )
2293 : {
2294 16 : const Any* pAnyArgs = args.getConstArray();
2295 :
2296 : // get info
2297 16 : const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
2298 16 : const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
2299 :
2300 : sal_uInt32 j;
2301 32 : for( j = 0 ; j < nParamCount ; j++ )
2302 : {
2303 16 : const ParamInfo& rInfo = pParamInfos[j];
2304 16 : ParamMode aParamMode = rInfo.aMode;
2305 16 : if( aParamMode != ParamMode_IN )
2306 16 : unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
2307 : }
2308 4190 : }
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 4190 : if( pParams )
2319 2630 : pVar->SetParameters( NULL );
2320 : }
2321 6 : catch( const Exception& )
2322 : {
2323 6 : implHandleAnyException( ::cppu::getCaughtException() );
2324 : }
2325 4196 : 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 42856 : SbUnoObject::SbUnoObject( const OUString& aName_, const Any& aUnoObj_ )
2335 : : SbxObject( aName_ )
2336 : , bNeedIntrospection( true )
2337 42856 : , bNativeCOMObject( false )
2338 : {
2339 42856 : static Reference< XIntrospection > xIntrospection;
2340 :
2341 : // beat out again the default properties of Sbx
2342 42856 : Remove( OUString("Name"), SbxCLASS_DONTCARE );
2343 42856 : Remove( OUString("Parent"), SbxCLASS_DONTCARE );
2344 :
2345 : // check the type of the ojekts
2346 42856 : TypeClass eType = aUnoObj_.getValueType().getTypeClass();
2347 42856 : Reference< XInterface > x;
2348 42856 : if( eType == TypeClass_INTERFACE )
2349 : {
2350 : // get the interface from the Any
2351 42520 : x = *(Reference< XInterface >*)aUnoObj_.getValue();
2352 42520 : if( !x.is() )
2353 16132 : return;
2354 : }
2355 :
2356 53448 : Reference< XTypeProvider > xTypeProvider;
2357 : // Did the object have an invocation itself?
2358 26724 : mxInvocation = Reference< XInvocation >( x, UNO_QUERY );
2359 :
2360 26724 : xTypeProvider = Reference< XTypeProvider >( x, UNO_QUERY );
2361 :
2362 26724 : if( mxInvocation.is() )
2363 : {
2364 :
2365 : // get the ExactName
2366 896 : mxExactNameInvocation = Reference< XExactName >::query( mxInvocation );
2367 :
2368 : // The remainder refers only to the introspection
2369 896 : 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 896 : Reference< oleautomation::XAutomationObject > xAutomationObject( aUnoObj_, UNO_QUERY );
2378 896 : if( xAutomationObject.is() )
2379 0 : bNativeCOMObject = true;
2380 : }
2381 :
2382 26724 : maTmpUnoObj = aUnoObj_;
2383 :
2384 :
2385 : //*** Define the name ***
2386 26724 : bool bFatalError = true;
2387 :
2388 : // Is it an interface or a struct?
2389 26724 : bool bSetClassName = false;
2390 53448 : OUString aClassName_;
2391 26724 : if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
2392 : {
2393 : // Struct is Ok
2394 336 : bFatalError = false;
2395 :
2396 : // insert the real name of the class
2397 336 : if( aName_.isEmpty() )
2398 : {
2399 86 : aClassName_ = aUnoObj_.getValueType().getTypeName();
2400 86 : bSetClassName = true;
2401 : }
2402 336 : StructRefInfo aThisStruct( maTmpUnoObj, maTmpUnoObj.getValueType(), 0 );
2403 336 : maStructInfo.reset( new SbUnoStructRefObject( GetName(), aThisStruct ) );
2404 : }
2405 26388 : else if( eType == TypeClass_INTERFACE )
2406 : {
2407 : // Interface works always through the type in the Any
2408 26388 : bFatalError = false;
2409 : }
2410 26724 : if( bSetClassName )
2411 86 : SetClassName( aClassName_ );
2412 :
2413 : // Neither interface nor Struct -> FatalError
2414 26724 : if( bFatalError )
2415 : {
2416 0 : StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
2417 0 : return;
2418 26724 : }
2419 :
2420 : // pass the introspection primal on demand
2421 : }
2422 :
2423 84686 : SbUnoObject::~SbUnoObject()
2424 : {
2425 84686 : }
2426 :
2427 :
2428 : // pass the introspection on Demand
2429 31230 : void SbUnoObject::doIntrospection( void )
2430 : {
2431 31230 : if( !bNeedIntrospection )
2432 15804 : return;
2433 :
2434 31230 : Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
2435 :
2436 31230 : if (!xContext.is())
2437 0 : return;
2438 :
2439 :
2440 : // get the introspection service
2441 46656 : Reference<XIntrospection> xIntrospection;
2442 :
2443 : try
2444 : {
2445 31230 : xIntrospection = theIntrospection::get(xContext);
2446 : }
2447 0 : catch ( const css::uno::DeploymentException& )
2448 : {
2449 : }
2450 :
2451 31230 : if (!xIntrospection.is())
2452 0 : return;
2453 :
2454 31230 : bNeedIntrospection = false;
2455 :
2456 : // pass the introspection
2457 : try
2458 : {
2459 31230 : mxUnoAccess = xIntrospection->inspect( maTmpUnoObj );
2460 : }
2461 0 : catch( const RuntimeException& e )
2462 : {
2463 0 : StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
2464 : }
2465 :
2466 31230 : if( !mxUnoAccess.is() )
2467 : {
2468 : // #51475 mark to indicate an invalid object (no mxMaterialHolder)
2469 15804 : return;
2470 : }
2471 :
2472 : // get MaterialHolder from access
2473 15426 : mxMaterialHolder = Reference< XMaterialHolder >::query( mxUnoAccess );
2474 :
2475 : // get ExactName from access
2476 30852 : 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 4416 : void clearUnoMethodsForBasic( StarBASIC* pBasic )
2486 : {
2487 4416 : SbUnoMethod* pMeth = pFirst;
2488 9484 : while( pMeth )
2489 : {
2490 652 : SbxObject* pObject = dynamic_cast< SbxObject* >( pMeth->GetParent() );
2491 652 : if ( pObject )
2492 : {
2493 652 : StarBASIC* pModBasic = dynamic_cast< StarBASIC* >( pObject->GetParent() );
2494 652 : 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 106 : if( pMeth == pFirst )
2503 64 : pFirst = pMeth->pNext;
2504 42 : else if( pMeth->pPrev )
2505 42 : pMeth->pPrev->pNext = pMeth->pNext;
2506 106 : if( pMeth->pNext )
2507 58 : pMeth->pNext->pPrev = pMeth->pPrev;
2508 :
2509 106 : pMeth->pPrev = NULL;
2510 106 : pMeth->pNext = NULL;
2511 :
2512 106 : pMeth->SbxValue::Clear();
2513 106 : pObject->SbxValue::Clear();
2514 :
2515 : // start from the beginning after object clearing, the cycle will end since the method is removed each time
2516 106 : pMeth = pFirst;
2517 : }
2518 : else
2519 546 : pMeth = pMeth->pNext;
2520 : }
2521 : else
2522 0 : pMeth = pMeth->pNext;
2523 : }
2524 4416 : }
2525 :
2526 132 : void clearUnoMethods( void )
2527 : {
2528 132 : SbUnoMethod* pMeth = pFirst;
2529 650 : while( pMeth )
2530 : {
2531 386 : pMeth->SbxValue::Clear();
2532 386 : pMeth = pMeth->pNext;
2533 : }
2534 132 : }
2535 :
2536 :
2537 1980 : 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 1980 : , mbDirectInvocation( bDirect )
2548 : {
2549 1980 : m_xUnoMethod = xUnoMethod_;
2550 1980 : pParamInfoSeq = NULL;
2551 :
2552 : // enregister the method in a list
2553 1980 : pNext = pFirst;
2554 1980 : pPrev = NULL;
2555 1980 : pFirst = this;
2556 1980 : if( pNext )
2557 1900 : pNext->pPrev = this;
2558 1980 : }
2559 :
2560 5940 : SbUnoMethod::~SbUnoMethod()
2561 : {
2562 1980 : delete pParamInfoSeq;
2563 :
2564 1980 : if( this == pFirst )
2565 980 : pFirst = pNext;
2566 1000 : else if( pPrev )
2567 894 : pPrev->pNext = pNext;
2568 1980 : if( pNext )
2569 1756 : pNext->pPrev = pPrev;
2570 3960 : }
2571 :
2572 148 : SbxInfo* SbUnoMethod::GetInfo()
2573 : {
2574 148 : if( !pInfo && m_xUnoMethod.is() )
2575 : {
2576 116 : SbiInstance* pInst = GetSbData()->pInst;
2577 116 : if( pInst && pInst->IsCompatibility() )
2578 : {
2579 116 : pInfo = new SbxInfo();
2580 :
2581 116 : const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
2582 116 : const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
2583 116 : sal_uInt32 nParamCount = rInfoSeq.getLength();
2584 :
2585 618 : for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
2586 : {
2587 502 : const ParamInfo& rInfo = pParamInfos[i];
2588 502 : OUString aParamName = rInfo.aName;
2589 :
2590 502 : SbxDataType t = SbxVARIANT;
2591 502 : SbxFlagBits nFlags_ = SBX_READ;
2592 502 : pInfo->AddParam( aParamName, t, nFlags_ );
2593 502 : }
2594 : }
2595 : }
2596 148 : return pInfo;
2597 : }
2598 :
2599 4328 : const Sequence<ParamInfo>& SbUnoMethod::getParamInfos( void )
2600 : {
2601 4328 : if (!pParamInfoSeq)
2602 : {
2603 1980 : Sequence<ParamInfo> aTmp;
2604 1980 : if (m_xUnoMethod.is())
2605 1980 : aTmp = m_xUnoMethod->getParameterInfos();
2606 1980 : pParamInfoSeq = new Sequence<ParamInfo>(aTmp);
2607 : }
2608 4328 : return *pParamInfoSeq;
2609 : }
2610 :
2611 2442 : 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 2442 : , mbUnoStruct( bUnoStruct )
2627 : {
2628 : // as needed establish an dummy array so that SbiRuntime::CheckArray() works
2629 2442 : static SbxArrayRef xDummyArray = new SbxArray( SbxVARIANT );
2630 2442 : if( eSbxType & SbxARRAY )
2631 4 : PutObject( xDummyArray );
2632 2442 : }
2633 :
2634 4884 : SbUnoProperty::~SbUnoProperty()
2635 4884 : {}
2636 :
2637 :
2638 6380 : SbxVariable* SbUnoObject::Find( const OUString& rName, SbxClassType t )
2639 : {
2640 6380 : static Reference< XIdlMethod > xDummyMethod;
2641 6380 : static Property aDummyProp;
2642 :
2643 6380 : SbxVariable* pRes = SbxObject::Find( rName, t );
2644 :
2645 6380 : if( bNeedIntrospection )
2646 132 : 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 6380 : if( !pRes )
2651 : {
2652 4708 : OUString aUName( rName );
2653 4708 : if( mxUnoAccess.is() && !bNativeCOMObject )
2654 : {
2655 4708 : if( mxExactName.is() )
2656 : {
2657 4708 : OUString aUExactName = mxExactName->getExactName( aUName );
2658 4708 : if( !aUExactName.isEmpty() )
2659 : {
2660 4386 : aUName = aUExactName;
2661 4708 : }
2662 : }
2663 4708 : if( mxUnoAccess->hasProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ) )
2664 : {
2665 2406 : const Property& rProp = mxUnoAccess->
2666 2406 : 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 2406 : if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
2671 2 : eSbxType = SbxVARIANT;
2672 : else
2673 2404 : eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
2674 :
2675 2406 : SbxDataType eRealSbxType = ( ( rProp.Attributes & PropertyAttribute::MAYBEVOID ) ? unoToSbxType( rProp.Type.getTypeClass() ) : eSbxType );
2676 : // create the property and superimpose it
2677 2406 : SbUnoProperty* pProp = new SbUnoProperty( rProp.Name, eSbxType, eRealSbxType, rProp, 0, false, ( rProp.Type.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT ) );
2678 4812 : SbxVariableRef xVarRef = pProp;
2679 2406 : QuickInsert( (SbxVariable*)xVarRef );
2680 4812 : pRes = xVarRef;
2681 : }
2682 4604 : else if( mxUnoAccess->hasMethod( aUName,
2683 2302 : MethodConcept::ALL - MethodConcept::DANGEROUS ) )
2684 : {
2685 : // address the method
2686 1980 : const Reference< XIdlMethod >& rxMethod = mxUnoAccess->
2687 1980 : getMethod( aUName, MethodConcept::ALL - MethodConcept::DANGEROUS );
2688 :
2689 : // create SbUnoMethod and superimpose it
2690 3960 : SbxVariableRef xMethRef = new SbUnoMethod( rxMethod->getName(),
2691 5940 : unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
2692 1980 : QuickInsert( (SbxVariable*)xMethRef );
2693 3960 : pRes = xMethRef;
2694 : }
2695 :
2696 : // If nothing was found check via XNameAccess
2697 4708 : if( !pRes )
2698 : {
2699 : try
2700 : {
2701 322 : Reference< XNameAccess > xNameAccess( mxUnoAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()), UNO_QUERY );
2702 644 : OUString aUName2( rName );
2703 :
2704 322 : 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 322 : }
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 exeption error will not be overwriten
2726 0 : if( !pRes )
2727 0 : pRes = new SbxVariable( SbxVARIANT );
2728 :
2729 0 : implHandleAnyException( ::cppu::getCaughtException() );
2730 : }
2731 : }
2732 : }
2733 4708 : if( !pRes && mxInvocation.is() )
2734 : {
2735 38 : 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 38 : if( mxInvocation->hasProperty( aUName ) )
2747 : {
2748 : // create a property and superimpose it
2749 24 : SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, SbxVARIANT, aDummyProp, 0, true, false );
2750 24 : QuickInsert( (SbxVariable*)xVarRef );
2751 24 : pRes = xVarRef;
2752 : }
2753 14 : 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( (SbxVariable*)xMethRef );
2758 0 : pRes = xMethRef;
2759 : }
2760 : else
2761 : {
2762 14 : Reference< XDirectInvocation > xDirectInvoke( mxInvocation, UNO_QUERY );
2763 14 : if ( xDirectInvoke.is() && xDirectInvoke->hasMember( aUName ) )
2764 : {
2765 0 : SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true, true );
2766 0 : QuickInsert( (SbxVariable*)xMethRef );
2767 0 : pRes = xMethRef;
2768 14 : }
2769 :
2770 : }
2771 : }
2772 0 : catch( const RuntimeException& e )
2773 : {
2774 : // Establish so that the exeption error will not be overwriten
2775 0 : if( !pRes )
2776 0 : pRes = new SbxVariable( SbxVARIANT );
2777 :
2778 0 : StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
2779 : }
2780 4708 : }
2781 : }
2782 :
2783 : // At the very end checking if the Dbg_-Properties are meant
2784 :
2785 6380 : if( !pRes )
2786 : {
2787 894 : if( rName.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES) ||
2788 596 : rName.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES) ||
2789 298 : 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 6380 : return pRes;
2799 : }
2800 :
2801 :
2802 : // help method to create the dbg_-Properties
2803 0 : void SbUnoObject::implCreateDbgProperties( void )
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( (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( (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( (SbxVariable*)xVarRef );
2818 0 : }
2819 :
2820 0 : void SbUnoObject::implCreateAll( void )
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( (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( (SbxVariable*)xMethRef );
2880 0 : }
2881 : }
2882 :
2883 :
2884 : // output the value
2885 78616 : Any SbUnoObject::getUnoAny( void )
2886 : {
2887 78616 : Any aRetAny;
2888 78616 : if( bNeedIntrospection ) doIntrospection();
2889 78616 : if ( maStructInfo.get() )
2890 332 : aRetAny = maTmpUnoObj;
2891 78284 : else if( mxMaterialHolder.is() )
2892 53074 : aRetAny = mxMaterialHolder->getMaterial();
2893 25210 : else if( mxInvocation.is() )
2894 0 : aRetAny <<= mxInvocation;
2895 78616 : return aRetAny;
2896 : }
2897 :
2898 : // help method to create an Uno-Struct per CoreReflection
2899 114 : SbUnoObject* Impl_CreateUnoStruct( const OUString& aClassName )
2900 : {
2901 : // get CoreReflection
2902 114 : Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
2903 114 : if( !xCoreReflection.is() )
2904 0 : return NULL;
2905 :
2906 : // search for the class
2907 228 : Reference< XIdlClass > xClass;
2908 : Reference< XHierarchicalNameAccess > xHarryName =
2909 228 : getCoreReflection_HierarchicalNameAccess_Impl();
2910 114 : if( xHarryName.is() && xHarryName->hasByHierarchicalName( aClassName ) )
2911 114 : xClass = xCoreReflection->forName( aClassName );
2912 114 : if( !xClass.is() )
2913 0 : return NULL;
2914 :
2915 : // Is it really a struct?
2916 114 : TypeClass eType = xClass->getTypeClass();
2917 114 : if ( ( eType != TypeClass_STRUCT ) && ( eType != TypeClass_EXCEPTION ) )
2918 0 : return NULL;
2919 :
2920 : // create an instance
2921 228 : Any aNewAny;
2922 114 : xClass->createObject( aNewAny );
2923 : // make a SbUnoObject out of it
2924 114 : SbUnoObject* pUnoObj = new SbUnoObject( aClassName, aNewAny );
2925 228 : 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 40 : SbxObject* SbUnoFactory::CreateObject( const OUString& rClassName )
2937 : {
2938 40 : return Impl_CreateUnoStruct( rClassName );
2939 : }
2940 :
2941 :
2942 : // Provisional interface for the UNO-Connection
2943 : // Deliver a SbxObject, that wrap an Uno-Interface
2944 38288 : SbxObjectRef GetSbUnoObject( const OUString& aName, const Any& aUnoObj_ )
2945 : {
2946 38288 : 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 : else
2966 : {
2967 0 : pObj->GetAll( SbxCLASS_DONTCARE );
2968 : }
2969 : }
2970 :
2971 :
2972 74 : void RTL_Impl_CreateUnoStruct( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
2973 : {
2974 : (void)pBasic;
2975 : (void)bWrite;
2976 :
2977 : // We need 1 parameter minimum
2978 74 : if ( rPar.Count() < 2 )
2979 : {
2980 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2981 0 : return;
2982 : }
2983 :
2984 : // get the name of the class of the struct
2985 74 : OUString aClassName = rPar.Get(1)->GetOUString();
2986 :
2987 : // try to create Struct with the same name
2988 148 : SbUnoObjectRef xUnoObj = Impl_CreateUnoStruct( aClassName );
2989 74 : if( !xUnoObj )
2990 : {
2991 0 : return;
2992 : }
2993 : // return the object
2994 148 : SbxVariableRef refVar = rPar.Get(0);
2995 148 : refVar->PutObject( (SbUnoObject*)xUnoObj );
2996 : }
2997 :
2998 62 : void RTL_Impl_CreateUnoService( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
2999 : {
3000 : (void)pBasic;
3001 : (void)bWrite;
3002 :
3003 : // We need 1 Parameter minimum
3004 62 : if ( rPar.Count() < 2 )
3005 : {
3006 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3007 62 : return;
3008 : }
3009 :
3010 : // get the name of the class of the struct
3011 62 : OUString aServiceName = rPar.Get(1)->GetOUString();
3012 :
3013 : // search for the service and instatiate it
3014 124 : Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
3015 124 : Reference< XInterface > xInterface;
3016 : try
3017 : {
3018 62 : xInterface = xFactory->createInstance( aServiceName );
3019 : }
3020 0 : catch( const Exception& )
3021 : {
3022 0 : implHandleAnyException( ::cppu::getCaughtException() );
3023 : }
3024 :
3025 124 : SbxVariableRef refVar = rPar.Get(0);
3026 62 : if( xInterface.is() )
3027 : {
3028 60 : Any aAny;
3029 60 : aAny <<= xInterface;
3030 :
3031 : // Create a SbUnoObject out of it and return it
3032 120 : SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
3033 60 : if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
3034 : {
3035 : // return the object
3036 60 : refVar->PutObject( (SbUnoObject*)xUnoObj );
3037 : }
3038 : else
3039 : {
3040 0 : refVar->PutObject( NULL );
3041 60 : }
3042 : }
3043 : else
3044 : {
3045 2 : refVar->PutObject( NULL );
3046 62 : }
3047 : }
3048 :
3049 0 : void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
3050 : {
3051 : (void)pBasic;
3052 : (void)bWrite;
3053 :
3054 : // We need 2 parameter minimum
3055 0 : if ( rPar.Count() < 3 )
3056 : {
3057 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3058 0 : return;
3059 : }
3060 :
3061 : // get the name of the class of the struct
3062 0 : OUString aServiceName = rPar.Get(1)->GetOUString();
3063 0 : Any aArgAsAny = sbxToUnoValue( rPar.Get(2),
3064 0 : getCppuType( (Sequence<Any>*)0 ) );
3065 0 : Sequence< Any > aArgs;
3066 0 : aArgAsAny >>= aArgs;
3067 :
3068 : // search for the service and instatiate it
3069 0 : Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
3070 0 : Reference< XInterface > xInterface;
3071 : try
3072 : {
3073 0 : xInterface = xFactory->createInstanceWithArguments( aServiceName, aArgs );
3074 : }
3075 0 : catch( const Exception& )
3076 : {
3077 0 : implHandleAnyException( ::cppu::getCaughtException() );
3078 : }
3079 :
3080 0 : SbxVariableRef refVar = rPar.Get(0);
3081 0 : if( xInterface.is() )
3082 : {
3083 0 : Any aAny;
3084 0 : aAny <<= xInterface;
3085 :
3086 : // Create a SbUnoObject out of it and return it
3087 0 : SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
3088 0 : if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
3089 : {
3090 : // return the object
3091 0 : refVar->PutObject( (SbUnoObject*)xUnoObj );
3092 : }
3093 : else
3094 : {
3095 0 : refVar->PutObject( NULL );
3096 0 : }
3097 : }
3098 : else
3099 : {
3100 0 : refVar->PutObject( NULL );
3101 0 : }
3102 : }
3103 :
3104 0 : void RTL_Impl_GetProcessServiceManager( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
3105 : {
3106 : (void)pBasic;
3107 : (void)bWrite;
3108 :
3109 0 : SbxVariableRef refVar = rPar.Get(0);
3110 :
3111 : // get the global service manager
3112 0 : Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
3113 0 : Any aAny;
3114 0 : aAny <<= xFactory;
3115 :
3116 : // Create a SbUnoObject out of it and return it
3117 0 : SbUnoObjectRef xUnoObj = new SbUnoObject( OUString( "ProcessServiceManager" ), aAny );
3118 0 : refVar->PutObject( (SbUnoObject*)xUnoObj );
3119 0 : }
3120 :
3121 0 : void RTL_Impl_HasInterfaces( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
3122 : {
3123 : (void)pBasic;
3124 : (void)bWrite;
3125 :
3126 : // We need 2 parameter minimum
3127 0 : sal_uInt16 nParCount = rPar.Count();
3128 0 : if( nParCount < 3 )
3129 : {
3130 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3131 0 : return;
3132 : }
3133 :
3134 : // variable for the return value
3135 0 : SbxVariableRef refVar = rPar.Get(0);
3136 0 : refVar->PutBool( false );
3137 :
3138 : // get the Uno-Object
3139 0 : SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
3140 0 : if( !(pObj && pObj->ISA(SbUnoObject)) )
3141 : {
3142 0 : return;
3143 : }
3144 0 : Any aAny = static_cast<SbUnoObject*>((SbxBase*)pObj)->getUnoAny();
3145 0 : TypeClass eType = aAny.getValueType().getTypeClass();
3146 0 : if( eType != TypeClass_INTERFACE )
3147 : {
3148 0 : return;
3149 : }
3150 : // get the interface out of the Any
3151 0 : Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
3152 :
3153 : // get CoreReflection
3154 0 : Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
3155 0 : if( !xCoreReflection.is() )
3156 : {
3157 0 : return;
3158 : }
3159 0 : for( sal_uInt16 i = 2 ; i < nParCount ; i++ )
3160 : {
3161 : // get the name of the interface of the struct
3162 0 : OUString aIfaceName = rPar.Get( i )->GetOUString();
3163 :
3164 : // search for the class
3165 0 : Reference< XIdlClass > xClass = xCoreReflection->forName( aIfaceName );
3166 0 : if( !xClass.is() )
3167 : {
3168 0 : return;
3169 : }
3170 : // check if the interface will be supported
3171 0 : OUString aClassName = xClass->getName();
3172 0 : Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
3173 0 : if( !x->queryInterface( aClassType ).hasValue() )
3174 : {
3175 0 : return;
3176 : }
3177 0 : }
3178 :
3179 : // Every thing works; then return TRUE
3180 0 : refVar->PutBool( true );
3181 : }
3182 :
3183 0 : void RTL_Impl_IsUnoStruct( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
3184 : {
3185 : (void)pBasic;
3186 : (void)bWrite;
3187 :
3188 : // We need 1 parameter minimum
3189 0 : if ( rPar.Count() < 2 )
3190 : {
3191 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3192 0 : return;
3193 : }
3194 :
3195 : // variable for the return value
3196 0 : SbxVariableRef refVar = rPar.Get(0);
3197 0 : refVar->PutBool( false );
3198 :
3199 : // get the Uno-Object
3200 0 : SbxVariableRef xParam = rPar.Get( 1 );
3201 0 : if( !xParam->IsObject() )
3202 : {
3203 0 : return;
3204 : }
3205 0 : SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
3206 0 : if( !(pObj && pObj->ISA(SbUnoObject)) )
3207 : {
3208 0 : return;
3209 : }
3210 0 : Any aAny = static_cast<SbUnoObject*>((SbxBase*)pObj)->getUnoAny();
3211 0 : TypeClass eType = aAny.getValueType().getTypeClass();
3212 0 : if( eType == TypeClass_STRUCT )
3213 : {
3214 0 : refVar->PutBool( true );
3215 0 : }
3216 : }
3217 :
3218 :
3219 0 : void RTL_Impl_EqualUnoObjects( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
3220 : {
3221 : (void)pBasic;
3222 : (void)bWrite;
3223 :
3224 0 : if ( rPar.Count() < 3 )
3225 : {
3226 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3227 0 : return;
3228 : }
3229 :
3230 : // variable for the return value
3231 0 : SbxVariableRef refVar = rPar.Get(0);
3232 0 : refVar->PutBool( false );
3233 :
3234 : // get the Uno-Objects
3235 0 : SbxVariableRef xParam1 = rPar.Get( 1 );
3236 0 : if( !xParam1->IsObject() )
3237 : {
3238 0 : return;
3239 : }
3240 0 : SbxBaseRef pObj1 = (SbxBase*)xParam1->GetObject();
3241 0 : if( !(pObj1 && pObj1->ISA(SbUnoObject)) )
3242 : {
3243 0 : return;
3244 : }
3245 0 : Any aAny1 = static_cast<SbUnoObject*>((SbxBase*)pObj1)->getUnoAny();
3246 0 : TypeClass eType1 = aAny1.getValueType().getTypeClass();
3247 0 : if( eType1 != TypeClass_INTERFACE )
3248 : {
3249 0 : return;
3250 : }
3251 0 : Reference< XInterface > x1;
3252 0 : aAny1 >>= x1;
3253 :
3254 0 : SbxVariableRef xParam2 = rPar.Get( 2 );
3255 0 : if( !xParam2->IsObject() )
3256 : {
3257 0 : return;
3258 : }
3259 0 : SbxBaseRef pObj2 = (SbxBase*)xParam2->GetObject();
3260 0 : if( !(pObj2 && pObj2->ISA(SbUnoObject)) )
3261 : {
3262 0 : return;
3263 : }
3264 0 : Any aAny2 = static_cast<SbUnoObject*>((SbxBase*)pObj2)->getUnoAny();
3265 0 : TypeClass eType2 = aAny2.getValueType().getTypeClass();
3266 0 : if( eType2 != TypeClass_INTERFACE )
3267 : {
3268 0 : return;
3269 : }
3270 0 : Reference< XInterface > x2;
3271 0 : aAny2 >>= x2;
3272 :
3273 0 : if( x1 == x2 )
3274 : {
3275 0 : refVar->PutBool( true );
3276 0 : }
3277 : }
3278 :
3279 :
3280 : // helper wrapper function to interact with TypeProvider and
3281 : // XTypeDescriptionEnumerationAccess.
3282 : // if it fails for whatever reason
3283 : // returned Reference<> be null e.g. .is() will be false
3284 :
3285 4 : Reference< XTypeDescriptionEnumeration > getTypeDescriptorEnumeration( const OUString& sSearchRoot,
3286 : const Sequence< TypeClass >& types,
3287 : TypeDescriptionSearchDepth depth )
3288 : {
3289 4 : Reference< XTypeDescriptionEnumeration > xEnum;
3290 8 : Reference< XTypeDescriptionEnumerationAccess> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY );
3291 4 : if ( xTypeEnumAccess.is() )
3292 : {
3293 : try
3294 : {
3295 12 : xEnum = xTypeEnumAccess->createTypeDescriptionEnumeration(
3296 8 : sSearchRoot, types, depth );
3297 : }
3298 0 : catch(const NoSuchTypeNameException& /*nstne*/ ) {}
3299 0 : catch(const InvalidTypeNameException& /*nstne*/ ) {}
3300 : }
3301 8 : return xEnum;
3302 : }
3303 :
3304 : typedef boost::unordered_map< OUString, Any, OUStringHash, ::std::equal_to< OUString > > VBAConstantsHash;
3305 :
3306 : VBAConstantHelper&
3307 514 : VBAConstantHelper::instance()
3308 : {
3309 514 : static VBAConstantHelper aHelper;
3310 514 : return aHelper;
3311 : }
3312 :
3313 514 : void VBAConstantHelper::init()
3314 : {
3315 514 : if ( !isInited )
3316 : {
3317 4 : Sequence< TypeClass > types(1);
3318 4 : types[ 0 ] = TypeClass_CONSTANTS;
3319 8 : Reference< XTypeDescriptionEnumeration > xEnum = getTypeDescriptorEnumeration( OUString(defaultNameSpace), types, TypeDescriptionSearchDepth_INFINITE );
3320 :
3321 4 : if ( !xEnum.is())
3322 : {
3323 514 : return; //NULL;
3324 : }
3325 3336 : while ( xEnum->hasMoreElements() )
3326 : {
3327 3328 : Reference< XConstantsTypeDescription > xConstants( xEnum->nextElement(), UNO_QUERY );
3328 3328 : if ( xConstants.is() )
3329 : {
3330 : // store constant group name
3331 3328 : OUString sFullName = xConstants->getName();
3332 3328 : sal_Int32 indexLastDot = sFullName.lastIndexOf('.');
3333 6656 : OUString sLeafName( sFullName );
3334 3328 : if ( indexLastDot > -1 )
3335 : {
3336 3328 : sLeafName = sFullName.copy( indexLastDot + 1);
3337 : }
3338 3328 : aConstCache.push_back( sLeafName ); // assume constant group names are unique
3339 6656 : Sequence< Reference< XConstantTypeDescription > > aConsts = xConstants->getConstants();
3340 37164 : for (sal_Int32 i = 0; i != aConsts.getLength(); ++i)
3341 : {
3342 : // store constant member name
3343 33836 : sFullName = aConsts[i]->getName();
3344 33836 : indexLastDot = sFullName.lastIndexOf('.');
3345 33836 : sLeafName = sFullName;
3346 33836 : if ( indexLastDot > -1 )
3347 : {
3348 33836 : sLeafName = sFullName.copy( indexLastDot + 1);
3349 : }
3350 33836 : aConstHash[ sLeafName.toAsciiLowerCase() ] = aConsts[i]->getConstantValue();
3351 3328 : }
3352 : }
3353 3328 : }
3354 8 : isInited = true;
3355 : }
3356 : }
3357 :
3358 : bool
3359 220 : VBAConstantHelper::isVBAConstantType( const OUString& rName )
3360 : {
3361 220 : init();
3362 220 : bool bConstant = false;
3363 220 : OUString sKey( rName );
3364 220 : VBAConstantsVector::const_iterator it = aConstCache.begin();
3365 :
3366 183260 : for( ; it != aConstCache.end(); ++it )
3367 : {
3368 183040 : if( sKey.equalsIgnoreAsciiCase( *it ) )
3369 : {
3370 0 : bConstant = true;
3371 0 : break;
3372 : }
3373 : }
3374 220 : return bConstant;
3375 : }
3376 :
3377 : SbxVariable*
3378 294 : VBAConstantHelper::getVBAConstant( const OUString& rName )
3379 : {
3380 294 : SbxVariable* pConst = NULL;
3381 294 : init();
3382 :
3383 294 : OUString sKey( rName );
3384 :
3385 294 : VBAConstantsHash::const_iterator it = aConstHash.find( sKey.toAsciiLowerCase() );
3386 :
3387 294 : if ( it != aConstHash.end() )
3388 : {
3389 158 : pConst = new SbxVariable( SbxVARIANT );
3390 158 : pConst->SetName( rName );
3391 158 : unoToSbxValue( pConst, it->second );
3392 : }
3393 :
3394 294 : return pConst;
3395 : }
3396 :
3397 : // Function to search for a global identifier in the
3398 : // UnoScope and to wrap it for Sbx
3399 226 : SbUnoClass* findUnoClass( const OUString& rName )
3400 : {
3401 : // #105550 Check if module exists
3402 226 : SbUnoClass* pUnoClass = NULL;
3403 :
3404 226 : Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
3405 226 : if( xTypeAccess->hasByHierarchicalName( rName ) )
3406 : {
3407 18 : Any aRet = xTypeAccess->getByHierarchicalName( rName );
3408 36 : Reference< XTypeDescription > xTypeDesc;
3409 18 : aRet >>= xTypeDesc;
3410 :
3411 18 : if( xTypeDesc.is() )
3412 : {
3413 18 : TypeClass eTypeClass = xTypeDesc->getTypeClass();
3414 18 : if( eTypeClass == TypeClass_MODULE || eTypeClass == TypeClass_CONSTANTS )
3415 : {
3416 18 : pUnoClass = new SbUnoClass( rName );
3417 : }
3418 18 : }
3419 : }
3420 226 : return pUnoClass;
3421 : }
3422 :
3423 18 : SbxVariable* SbUnoClass::Find( const OUString& rName, SbxClassType )
3424 : {
3425 18 : SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_VARIABLE );
3426 :
3427 : // If nothing were located the submodule isn't known yet
3428 18 : if( !pRes )
3429 : {
3430 : // If it is already a class, ask for the field
3431 18 : if( m_xClass.is() )
3432 : {
3433 : // Is it a field(?)
3434 0 : OUString aUStr( rName );
3435 0 : Reference< XIdlField > xField = m_xClass->getField( aUStr );
3436 0 : Reference< XIdlClass > xClass;
3437 0 : if( xField.is() )
3438 : {
3439 : try
3440 : {
3441 0 : Any aAny;
3442 0 : aAny = xField->get( aAny );
3443 :
3444 : // Convert to Sbx
3445 0 : pRes = new SbxVariable( SbxVARIANT );
3446 0 : pRes->SetName( rName );
3447 0 : unoToSbxValue( pRes, aAny );
3448 : }
3449 0 : catch( const Exception& )
3450 : {
3451 0 : implHandleAnyException( ::cppu::getCaughtException() );
3452 : }
3453 0 : }
3454 : }
3455 : else
3456 : {
3457 : // expand fully qualified name
3458 18 : OUString aNewName = GetName();
3459 18 : aNewName += ".";
3460 18 : aNewName += rName;
3461 :
3462 : // get CoreReflection
3463 36 : Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
3464 18 : if( xCoreReflection.is() )
3465 : {
3466 : // Is it a constant?
3467 18 : Reference< XHierarchicalNameAccess > xHarryName( xCoreReflection, UNO_QUERY );
3468 18 : if( xHarryName.is() )
3469 : {
3470 : try
3471 : {
3472 18 : Any aValue = xHarryName->getByHierarchicalName( aNewName );
3473 4 : TypeClass eType = aValue.getValueType().getTypeClass();
3474 :
3475 : // Interface located? Then it is a class
3476 4 : if( eType == TypeClass_INTERFACE )
3477 : {
3478 2 : Reference< XInterface > xIface = *(Reference< XInterface >*)aValue.getValue();
3479 4 : Reference< XIdlClass > xClass( xIface, UNO_QUERY );
3480 2 : if( xClass.is() )
3481 : {
3482 2 : pRes = new SbxVariable( SbxVARIANT );
3483 2 : SbxObjectRef xWrapper = (SbxObject*)new SbUnoClass( aNewName, xClass );
3484 2 : pRes->PutObject( xWrapper );
3485 2 : }
3486 : }
3487 : else
3488 : {
3489 2 : pRes = new SbxVariable( SbxVARIANT );
3490 2 : unoToSbxValue( pRes, aValue );
3491 4 : }
3492 : }
3493 14 : catch( const NoSuchElementException& )
3494 : {
3495 : }
3496 : }
3497 :
3498 : // Otherwise take it again as class
3499 18 : if( !pRes )
3500 : {
3501 14 : SbUnoClass* pNewClass = findUnoClass( aNewName );
3502 14 : if( pNewClass )
3503 : {
3504 14 : pRes = new SbxVariable( SbxVARIANT );
3505 14 : SbxObjectRef xWrapper = (SbxObject*)pNewClass;
3506 14 : pRes->PutObject( xWrapper );
3507 : }
3508 : }
3509 :
3510 : // An UNO service?
3511 18 : if( !pRes )
3512 : {
3513 0 : SbUnoService* pUnoService = findUnoService( aNewName );
3514 0 : if( pUnoService )
3515 : {
3516 0 : pRes = new SbxVariable( SbxVARIANT );
3517 0 : SbxObjectRef xWrapper = (SbxObject*)pUnoService;
3518 0 : pRes->PutObject( xWrapper );
3519 : }
3520 : }
3521 :
3522 : // An UNO singleton?
3523 18 : if( !pRes )
3524 : {
3525 0 : SbUnoSingleton* pUnoSingleton = findUnoSingleton( aNewName );
3526 0 : if( pUnoSingleton )
3527 : {
3528 0 : pRes = new SbxVariable( SbxVARIANT );
3529 0 : SbxObjectRef xWrapper = (SbxObject*)pUnoSingleton;
3530 0 : pRes->PutObject( xWrapper );
3531 : }
3532 18 : }
3533 18 : }
3534 : }
3535 :
3536 18 : if( pRes )
3537 : {
3538 18 : pRes->SetName( rName );
3539 :
3540 : // Insert variable, so that it could be found later
3541 18 : QuickInsert( pRes );
3542 :
3543 : // Take us out as listener at once,
3544 : // the values are all constant
3545 18 : if( pRes->IsBroadcaster() )
3546 18 : EndListening( pRes->GetBroadcaster(), true );
3547 : }
3548 : }
3549 18 : return pRes;
3550 : }
3551 :
3552 :
3553 0 : SbUnoService* findUnoService( const OUString& rName )
3554 : {
3555 0 : SbUnoService* pSbUnoService = NULL;
3556 :
3557 0 : Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
3558 0 : if( xTypeAccess->hasByHierarchicalName( rName ) )
3559 : {
3560 0 : Any aRet = xTypeAccess->getByHierarchicalName( rName );
3561 0 : Reference< XTypeDescription > xTypeDesc;
3562 0 : aRet >>= xTypeDesc;
3563 :
3564 0 : if( xTypeDesc.is() )
3565 : {
3566 0 : TypeClass eTypeClass = xTypeDesc->getTypeClass();
3567 0 : if( eTypeClass == TypeClass_SERVICE )
3568 : {
3569 0 : Reference< XServiceTypeDescription2 > xServiceTypeDesc( xTypeDesc, UNO_QUERY );
3570 0 : if( xServiceTypeDesc.is() )
3571 0 : pSbUnoService = new SbUnoService( rName, xServiceTypeDesc );
3572 : }
3573 0 : }
3574 : }
3575 0 : return pSbUnoService;
3576 : }
3577 :
3578 0 : SbxVariable* SbUnoService::Find( const OUString& rName, SbxClassType )
3579 : {
3580 0 : SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
3581 :
3582 0 : if( !pRes )
3583 : {
3584 : // If it is already a class ask for a field
3585 0 : if( m_bNeedsInit && m_xServiceTypeDesc.is() )
3586 : {
3587 0 : m_bNeedsInit = false;
3588 :
3589 0 : Sequence< Reference< XServiceConstructorDescription > > aSCDSeq = m_xServiceTypeDesc->getConstructors();
3590 0 : const Reference< XServiceConstructorDescription >* pCtorSeq = aSCDSeq.getConstArray();
3591 0 : int nCtorCount = aSCDSeq.getLength();
3592 0 : for( int i = 0 ; i < nCtorCount ; ++i )
3593 : {
3594 0 : Reference< XServiceConstructorDescription > xCtor = pCtorSeq[i];
3595 :
3596 0 : OUString aName( xCtor->getName() );
3597 0 : if( aName.isEmpty() )
3598 : {
3599 0 : if( xCtor->isDefaultConstructor() )
3600 : {
3601 0 : aName = "create";
3602 : }
3603 : }
3604 :
3605 0 : if( !aName.isEmpty() )
3606 : {
3607 : // Create and insert SbUnoServiceCtor
3608 0 : SbxVariableRef xSbCtorRef = new SbUnoServiceCtor( aName, xCtor );
3609 0 : QuickInsert( (SbxVariable*)xSbCtorRef );
3610 : }
3611 0 : }
3612 0 : pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
3613 : }
3614 : }
3615 :
3616 0 : return pRes;
3617 : }
3618 :
3619 0 : void SbUnoService::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
3620 : const SfxHint& rHint, const TypeId& rHintType )
3621 : {
3622 0 : const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
3623 0 : if( pHint )
3624 : {
3625 0 : SbxVariable* pVar = pHint->GetVar();
3626 0 : SbxArray* pParams = pVar->GetParameters();
3627 0 : SbUnoServiceCtor* pUnoCtor = PTR_CAST(SbUnoServiceCtor,pVar);
3628 0 : if( pUnoCtor && pHint->GetId() == SBX_HINT_DATAWANTED )
3629 : {
3630 : // Parameter count -1 because of Param0 == this
3631 0 : sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
3632 0 : Sequence<Any> args;
3633 0 : bool bOutParams = false;
3634 :
3635 0 : Reference< XServiceConstructorDescription > xCtor = pUnoCtor->getServiceCtorDesc();
3636 0 : Sequence< Reference< XParameter > > aParameterSeq = xCtor->getParameters();
3637 0 : const Reference< XParameter >* pParameterSeq = aParameterSeq.getConstArray();
3638 0 : sal_uInt32 nUnoParamCount = aParameterSeq.getLength();
3639 :
3640 : // Default: Ignore not needed parameters
3641 0 : bool bParameterError = false;
3642 :
3643 : // Is the last parameter a rest parameter?
3644 0 : bool bRestParameterMode = false;
3645 0 : if( nUnoParamCount > 0 )
3646 : {
3647 0 : Reference< XParameter > xLastParam = pParameterSeq[ nUnoParamCount - 1 ];
3648 0 : if( xLastParam.is() )
3649 : {
3650 0 : if( xLastParam->isRestParameter() )
3651 0 : bRestParameterMode = true;
3652 0 : }
3653 : }
3654 :
3655 : // Too many parameters with context as first parameter?
3656 0 : sal_uInt16 nSbxParameterOffset = 1;
3657 0 : sal_uInt16 nParameterOffsetByContext = 0;
3658 0 : Reference < XComponentContext > xFirstParamContext;
3659 0 : if( nParamCount > nUnoParamCount )
3660 : {
3661 : // Check if first parameter is a context and use it
3662 : // then in createInstanceWithArgumentsAndContext
3663 0 : Any aArg0 = sbxToUnoValue( pParams->Get( nSbxParameterOffset ) );
3664 0 : if( (aArg0 >>= xFirstParamContext) && xFirstParamContext.is() )
3665 0 : nParameterOffsetByContext = 1;
3666 : }
3667 :
3668 0 : sal_uInt32 nEffectiveParamCount = nParamCount - nParameterOffsetByContext;
3669 0 : sal_uInt32 nAllocParamCount = nEffectiveParamCount;
3670 0 : if( nEffectiveParamCount > nUnoParamCount )
3671 : {
3672 0 : if( !bRestParameterMode )
3673 : {
3674 0 : nEffectiveParamCount = nUnoParamCount;
3675 0 : nAllocParamCount = nUnoParamCount;
3676 : }
3677 : }
3678 : // Not enough parameters?
3679 0 : else if( nUnoParamCount > nEffectiveParamCount )
3680 : {
3681 : // RestParameterMode only helps if one (the last) parameter is missing
3682 0 : int nDiff = nUnoParamCount - nEffectiveParamCount;
3683 0 : if( !bRestParameterMode || nDiff > 1 )
3684 : {
3685 0 : bParameterError = true;
3686 0 : StarBASIC::Error( SbERR_NOT_OPTIONAL );
3687 : }
3688 : }
3689 :
3690 0 : if( !bParameterError )
3691 : {
3692 0 : if( nAllocParamCount > 0 )
3693 : {
3694 0 : args.realloc( nAllocParamCount );
3695 0 : Any* pAnyArgs = args.getArray();
3696 0 : for( sal_uInt32 i = 0 ; i < nEffectiveParamCount ; i++ )
3697 : {
3698 0 : sal_uInt16 iSbx = (sal_uInt16)(i + nSbxParameterOffset + nParameterOffsetByContext);
3699 :
3700 : // bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
3701 0 : Reference< XParameter > xParam;
3702 0 : if( i < nUnoParamCount )
3703 : {
3704 0 : xParam = pParameterSeq[i];
3705 0 : if( !xParam.is() )
3706 0 : continue;
3707 :
3708 0 : Reference< XTypeDescription > xParamTypeDesc = xParam->getType();
3709 0 : if( !xParamTypeDesc.is() )
3710 0 : continue;
3711 0 : com::sun::star::uno::Type aType( xParamTypeDesc->getTypeClass(), xParamTypeDesc->getName() );
3712 :
3713 : // sbx parameter needs offset 1
3714 0 : pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ), aType );
3715 :
3716 : // Check for out parameter if not already done
3717 0 : if( !bOutParams )
3718 : {
3719 0 : if( xParam->isOut() )
3720 0 : bOutParams = true;
3721 0 : }
3722 : }
3723 : else
3724 : {
3725 0 : pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ) );
3726 : }
3727 0 : }
3728 : }
3729 :
3730 : // "Call" ctor using createInstanceWithArgumentsAndContext
3731 : Reference < XComponentContext > xContext(
3732 0 : xFirstParamContext.is()
3733 : ? xFirstParamContext
3734 0 : : comphelper::getProcessComponentContext() );
3735 0 : Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
3736 :
3737 0 : Any aRetAny;
3738 0 : OUString aServiceName = GetName();
3739 0 : Reference < XInterface > xRet;
3740 : try
3741 : {
3742 0 : xRet = xServiceMgr->createInstanceWithArgumentsAndContext( aServiceName, args, xContext );
3743 : }
3744 0 : catch( const Exception& )
3745 : {
3746 0 : implHandleAnyException( ::cppu::getCaughtException() );
3747 : }
3748 0 : aRetAny <<= xRet;
3749 0 : unoToSbxValue( pVar, aRetAny );
3750 :
3751 : // Copy back out parameters?
3752 0 : if( bOutParams )
3753 : {
3754 0 : const Any* pAnyArgs = args.getConstArray();
3755 :
3756 0 : for( sal_uInt32 j = 0 ; j < nUnoParamCount ; j++ )
3757 : {
3758 0 : Reference< XParameter > xParam = pParameterSeq[j];
3759 0 : if( !xParam.is() )
3760 0 : continue;
3761 :
3762 0 : if( xParam->isOut() )
3763 0 : unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
3764 0 : }
3765 0 : }
3766 0 : }
3767 : }
3768 : else
3769 0 : SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
3770 : }
3771 0 : }
3772 :
3773 :
3774 :
3775 : static SbUnoServiceCtor* pFirstCtor = NULL;
3776 :
3777 132 : void clearUnoServiceCtors( void )
3778 : {
3779 132 : SbUnoServiceCtor* pCtor = pFirstCtor;
3780 264 : while( pCtor )
3781 : {
3782 0 : pCtor->SbxValue::Clear();
3783 0 : pCtor = pCtor->pNext;
3784 : }
3785 132 : }
3786 :
3787 0 : SbUnoServiceCtor::SbUnoServiceCtor( const OUString& aName_, Reference< XServiceConstructorDescription > xServiceCtorDesc )
3788 : : SbxMethod( aName_, SbxOBJECT )
3789 : , m_xServiceCtorDesc( xServiceCtorDesc )
3790 0 : , pNext(0)
3791 : {
3792 0 : }
3793 :
3794 0 : SbUnoServiceCtor::~SbUnoServiceCtor()
3795 : {
3796 0 : }
3797 :
3798 0 : SbxInfo* SbUnoServiceCtor::GetInfo()
3799 : {
3800 0 : SbxInfo* pRet = NULL;
3801 :
3802 0 : return pRet;
3803 : }
3804 :
3805 :
3806 0 : SbUnoSingleton* findUnoSingleton( const OUString& rName )
3807 : {
3808 0 : SbUnoSingleton* pSbUnoSingleton = NULL;
3809 :
3810 0 : Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
3811 0 : if( xTypeAccess->hasByHierarchicalName( rName ) )
3812 : {
3813 0 : Any aRet = xTypeAccess->getByHierarchicalName( rName );
3814 0 : Reference< XTypeDescription > xTypeDesc;
3815 0 : aRet >>= xTypeDesc;
3816 :
3817 0 : if( xTypeDesc.is() )
3818 : {
3819 0 : TypeClass eTypeClass = xTypeDesc->getTypeClass();
3820 0 : if( eTypeClass == TypeClass_SINGLETON )
3821 : {
3822 0 : Reference< XSingletonTypeDescription > xSingletonTypeDesc( xTypeDesc, UNO_QUERY );
3823 0 : if( xSingletonTypeDesc.is() )
3824 0 : pSbUnoSingleton = new SbUnoSingleton( rName, xSingletonTypeDesc );
3825 : }
3826 0 : }
3827 : }
3828 0 : return pSbUnoSingleton;
3829 : }
3830 :
3831 0 : SbUnoSingleton::SbUnoSingleton( const OUString& aName_,
3832 : const Reference< XSingletonTypeDescription >& xSingletonTypeDesc )
3833 : : SbxObject( aName_ )
3834 0 : , m_xSingletonTypeDesc( xSingletonTypeDesc )
3835 : {
3836 0 : SbxVariableRef xGetMethodRef = new SbxMethod( OUString( "get" ), SbxOBJECT );
3837 0 : QuickInsert( (SbxVariable*)xGetMethodRef );
3838 0 : }
3839 :
3840 0 : void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
3841 : const SfxHint& rHint, const TypeId& rHintType )
3842 : {
3843 0 : const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
3844 0 : if( pHint )
3845 : {
3846 0 : SbxVariable* pVar = pHint->GetVar();
3847 0 : SbxArray* pParams = pVar->GetParameters();
3848 0 : sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
3849 0 : sal_uInt32 nAllowedParamCount = 1;
3850 :
3851 0 : Reference < XComponentContext > xContextToUse;
3852 0 : if( nParamCount > 0 )
3853 : {
3854 : // Check if first parameter is a context and use it then
3855 0 : Reference < XComponentContext > xFirstParamContext;
3856 0 : Any aArg1 = sbxToUnoValue( pParams->Get( 1 ) );
3857 0 : if( (aArg1 >>= xFirstParamContext) && xFirstParamContext.is() )
3858 0 : xContextToUse = xFirstParamContext;
3859 : }
3860 :
3861 0 : if( !xContextToUse.is() )
3862 : {
3863 0 : xContextToUse = comphelper::getProcessComponentContext();
3864 0 : --nAllowedParamCount;
3865 : }
3866 :
3867 0 : if( nParamCount > nAllowedParamCount )
3868 : {
3869 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3870 0 : return;
3871 : }
3872 :
3873 0 : Any aRetAny;
3874 0 : if( xContextToUse.is() )
3875 : {
3876 0 : OUString aSingletonName( "/singletons/" );
3877 0 : aSingletonName += GetName();
3878 0 : Reference < XInterface > xRet;
3879 0 : xContextToUse->getValueByName( aSingletonName ) >>= xRet;
3880 0 : aRetAny <<= xRet;
3881 : }
3882 0 : unoToSbxValue( pVar, aRetAny );
3883 : }
3884 : else
3885 : {
3886 0 : SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
3887 : }
3888 : }
3889 :
3890 :
3891 :
3892 :
3893 : // Implementation of an EventAttacher-drawn AllListener, which
3894 : // solely transmits several events to an general AllListener
3895 : class BasicAllListener_Impl : public BasicAllListenerHelper
3896 : {
3897 : virtual void firing_impl(const AllEventObject& Event, Any* pRet);
3898 :
3899 : public:
3900 : SbxObjectRef xSbxObj;
3901 : OUString aPrefixName;
3902 :
3903 : BasicAllListener_Impl( const OUString& aPrefixName );
3904 : virtual ~BasicAllListener_Impl();
3905 :
3906 : // Methods of XAllListener
3907 : virtual void SAL_CALL firing(const AllEventObject& Event) throw ( RuntimeException, std::exception ) SAL_OVERRIDE;
3908 : virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw ( RuntimeException, std::exception ) SAL_OVERRIDE;
3909 :
3910 : // Methods of XEventListener
3911 : virtual void SAL_CALL disposing(const EventObject& Source) throw ( RuntimeException, std::exception ) SAL_OVERRIDE;
3912 : };
3913 :
3914 :
3915 :
3916 12 : BasicAllListener_Impl::BasicAllListener_Impl(const OUString& aPrefixName_)
3917 12 : : aPrefixName( aPrefixName_ )
3918 : {
3919 12 : }
3920 :
3921 :
3922 0 : BasicAllListener_Impl::~BasicAllListener_Impl()
3923 : {
3924 0 : }
3925 :
3926 :
3927 :
3928 36 : void BasicAllListener_Impl::firing_impl( const AllEventObject& Event, Any* pRet )
3929 : {
3930 36 : SolarMutexGuard guard;
3931 :
3932 36 : if( xSbxObj.Is() )
3933 : {
3934 36 : OUString aMethodName = aPrefixName;
3935 36 : aMethodName = aMethodName + Event.MethodName;
3936 :
3937 36 : SbxVariable * pP = xSbxObj;
3938 36 : while( pP->GetParent() )
3939 : {
3940 36 : pP = pP->GetParent();
3941 36 : StarBASIC * pLib = PTR_CAST(StarBASIC,pP);
3942 36 : if( pLib )
3943 : {
3944 : // Create in a Basic Array
3945 36 : SbxArrayRef xSbxArray = new SbxArray( SbxVARIANT );
3946 36 : const Any * pArgs = Event.Arguments.getConstArray();
3947 36 : sal_Int32 nCount = Event.Arguments.getLength();
3948 84 : for( sal_Int32 i = 0; i < nCount; i++ )
3949 : {
3950 : // Convert elements
3951 48 : SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
3952 48 : unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
3953 48 : xSbxArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
3954 48 : }
3955 :
3956 36 : pLib->Call( aMethodName, xSbxArray );
3957 :
3958 : // get the return value from the Param-Array, if requested
3959 36 : if( pRet )
3960 : {
3961 24 : SbxVariable* pVar = xSbxArray->Get( 0 );
3962 24 : if( pVar )
3963 : {
3964 : // #95792 Avoid a second call
3965 24 : SbxFlagBits nFlags = pVar->GetFlags();
3966 24 : pVar->SetFlag( SBX_NO_BROADCAST );
3967 24 : *pRet = sbxToUnoValueImpl( pVar );
3968 24 : pVar->SetFlags( nFlags );
3969 : }
3970 : }
3971 36 : break;
3972 : }
3973 36 : }
3974 36 : }
3975 36 : }
3976 :
3977 :
3978 : // Methods of Listener
3979 12 : void BasicAllListener_Impl::firing( const AllEventObject& Event ) throw ( RuntimeException, std::exception )
3980 : {
3981 12 : firing_impl( Event, NULL );
3982 12 : }
3983 :
3984 24 : Any BasicAllListener_Impl::approveFiring( const AllEventObject& Event ) throw ( RuntimeException, std::exception )
3985 : {
3986 24 : Any aRetAny;
3987 24 : firing_impl( Event, &aRetAny );
3988 24 : return aRetAny;
3989 : }
3990 :
3991 :
3992 : // Methods of XEventListener
3993 0 : void BasicAllListener_Impl ::disposing(const EventObject& ) throw ( RuntimeException, std::exception )
3994 : {
3995 0 : SolarMutexGuard guard;
3996 :
3997 0 : xSbxObj.Clear();
3998 0 : }
3999 :
4000 :
4001 :
4002 :
4003 : // class InvocationToAllListenerMapper
4004 : // helper class to map XInvocation to XAllListener (also in project eventattacher!)
4005 :
4006 0 : class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
4007 : {
4008 : public:
4009 : InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
4010 : const Reference< XAllListener >& AllListener, const Any& Helper );
4011 :
4012 : // XInvocation
4013 : virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
4014 : virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
4015 : throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
4016 : virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value)
4017 : throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
4018 : virtual Any SAL_CALL getValue(const OUString& PropertyName) throw( UnknownPropertyException, RuntimeException, std::exception ) SAL_OVERRIDE;
4019 : virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
4020 : virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
4021 :
4022 : private:
4023 : Reference< XIdlReflection > m_xCoreReflection;
4024 : Reference< XAllListener > m_xAllListener;
4025 : Reference< XIdlClass > m_xListenerType;
4026 : Any m_Helper;
4027 : };
4028 :
4029 :
4030 : // Function to replace AllListenerAdapterService::createAllListerAdapter
4031 12 : Reference< XInterface > createAllListenerAdapter
4032 : (
4033 : const Reference< XInvocationAdapterFactory2 >& xInvocationAdapterFactory,
4034 : const Reference< XIdlClass >& xListenerType,
4035 : const Reference< XAllListener >& xListener,
4036 : const Any& Helper
4037 : )
4038 : {
4039 12 : Reference< XInterface > xAdapter;
4040 12 : if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
4041 : {
4042 : Reference< XInvocation > xInvocationToAllListenerMapper =
4043 12 : (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
4044 24 : Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName() );
4045 24 : Sequence<Type> arg2(1);
4046 12 : arg2[0] = aListenerType;
4047 24 : xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, arg2 );
4048 : }
4049 12 : return xAdapter;
4050 : }
4051 :
4052 :
4053 :
4054 : // InvocationToAllListenerMapper
4055 12 : InvocationToAllListenerMapper::InvocationToAllListenerMapper
4056 : ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
4057 : : m_xAllListener( AllListener )
4058 : , m_xListenerType( ListenerType )
4059 12 : , m_Helper( Helper )
4060 : {
4061 12 : }
4062 :
4063 :
4064 0 : Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
4065 : throw( RuntimeException, std::exception )
4066 : {
4067 0 : return Reference< XIntrospectionAccess >();
4068 : }
4069 :
4070 :
4071 36 : Any SAL_CALL InvocationToAllListenerMapper::invoke(const OUString& FunctionName, const Sequence< Any >& Params,
4072 : Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
4073 : throw( IllegalArgumentException, CannotConvertException,
4074 : InvocationTargetException, RuntimeException, std::exception )
4075 : {
4076 : (void)OutParamIndex;
4077 : (void)OutParam ;
4078 :
4079 36 : Any aRet;
4080 :
4081 : // Check if to firing or approveFiring has to be called
4082 72 : Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
4083 36 : bool bApproveFiring = false;
4084 36 : if( !xMethod.is() )
4085 0 : return aRet;
4086 72 : Reference< XIdlClass > xReturnType = xMethod->getReturnType();
4087 72 : Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
4088 72 : if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
4089 36 : aExceptionSeq.getLength() > 0 )
4090 : {
4091 24 : bApproveFiring = true;
4092 : }
4093 : else
4094 : {
4095 12 : Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
4096 12 : sal_uInt32 nParamCount = aParamSeq.getLength();
4097 12 : if( nParamCount > 1 )
4098 : {
4099 0 : const ParamInfo* pInfos = aParamSeq.getConstArray();
4100 0 : for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
4101 : {
4102 0 : if( pInfos[ i ].aMode != ParamMode_IN )
4103 : {
4104 0 : bApproveFiring = true;
4105 0 : break;
4106 : }
4107 : }
4108 12 : }
4109 : }
4110 :
4111 72 : AllEventObject aAllEvent;
4112 36 : aAllEvent.Source = (OWeakObject*) this;
4113 36 : aAllEvent.Helper = m_Helper;
4114 36 : aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName() );
4115 36 : aAllEvent.MethodName = FunctionName;
4116 36 : aAllEvent.Arguments = Params;
4117 36 : if( bApproveFiring )
4118 24 : aRet = m_xAllListener->approveFiring( aAllEvent );
4119 : else
4120 12 : m_xAllListener->firing( aAllEvent );
4121 36 : return aRet;
4122 : }
4123 :
4124 :
4125 0 : void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& PropertyName, const Any& Value)
4126 : throw( UnknownPropertyException, CannotConvertException,
4127 : InvocationTargetException, RuntimeException, std::exception )
4128 : {
4129 : (void)PropertyName;
4130 : (void)Value;
4131 0 : }
4132 :
4133 :
4134 0 : Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& PropertyName)
4135 : throw( UnknownPropertyException, RuntimeException, std::exception )
4136 : {
4137 : (void)PropertyName;
4138 :
4139 0 : return Any();
4140 : }
4141 :
4142 :
4143 0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name)
4144 : throw( RuntimeException, std::exception )
4145 : {
4146 0 : Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
4147 0 : return xMethod.is();
4148 : }
4149 :
4150 :
4151 0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name)
4152 : throw( RuntimeException, std::exception )
4153 : {
4154 0 : Reference< XIdlField > xField = m_xListenerType->getField( Name );
4155 0 : return xField.is();
4156 : }
4157 :
4158 :
4159 : // create Uno-Service
4160 : // 1. Parameter == Prefix-Name of the macro
4161 : // 2. Parameter == fully qualified name of the listener
4162 12 : void SbRtl_CreateUnoListener( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
4163 : //RTLFUNC(CreateUnoListener)
4164 : {
4165 : (void)bWrite;
4166 :
4167 : // We need 2 parameters
4168 12 : if ( rPar.Count() != 3 )
4169 : {
4170 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
4171 0 : return;
4172 : }
4173 :
4174 : // get the name of the class of the struct
4175 12 : OUString aPrefixName = rPar.Get(1)->GetOUString();
4176 24 : OUString aListenerClassName = rPar.Get(2)->GetOUString();
4177 :
4178 : // get the CoreReflection
4179 24 : Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
4180 12 : if( !xCoreReflection.is() )
4181 0 : return;
4182 :
4183 : // get the AllListenerAdapterService
4184 24 : Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
4185 :
4186 : // search the class
4187 24 : Reference< XIdlClass > xClass = xCoreReflection->forName( aListenerClassName );
4188 12 : if( !xClass.is() )
4189 0 : return;
4190 :
4191 : // From 1999-11-30: get the InvocationAdapterFactory
4192 : Reference< XInvocationAdapterFactory2 > xInvocationAdapterFactory =
4193 24 : InvocationAdapterFactory::create( xContext );
4194 :
4195 : BasicAllListener_Impl * p;
4196 24 : Reference< XAllListener > xAllLst = p = new BasicAllListener_Impl( aPrefixName );
4197 24 : Any aTmp;
4198 24 : Reference< XInterface > xLst = createAllListenerAdapter( xInvocationAdapterFactory, xClass, xAllLst, aTmp );
4199 12 : if( !xLst.is() )
4200 0 : return;
4201 :
4202 24 : OUString aClassName = xClass->getName();
4203 24 : Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
4204 12 : aTmp = xLst->queryInterface( aClassType );
4205 12 : if( !aTmp.hasValue() )
4206 0 : return;
4207 :
4208 12 : SbUnoObject* pUnoObj = new SbUnoObject( aListenerClassName, aTmp );
4209 12 : p->xSbxObj = pUnoObj;
4210 12 : p->xSbxObj->SetParent( pBasic );
4211 :
4212 : // #100326 Register listener object to set Parent NULL in Dtor
4213 24 : SbxArrayRef xBasicUnoListeners = pBasic->getUnoListeners();
4214 12 : xBasicUnoListeners->Insert( pUnoObj, xBasicUnoListeners->Count() );
4215 :
4216 : // return the object
4217 24 : SbxVariableRef refVar = rPar.Get(0);
4218 24 : refVar->PutObject( p->xSbxObj );
4219 : }
4220 :
4221 :
4222 : // Represents the DefaultContext property of the ProcessServiceManager
4223 : // in the Basic runtime system.
4224 2 : void RTL_Impl_GetDefaultContext( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
4225 : {
4226 : (void)pBasic;
4227 : (void)bWrite;
4228 :
4229 2 : SbxVariableRef refVar = rPar.Get(0);
4230 :
4231 4 : Any aContextAny( comphelper::getProcessComponentContext() );
4232 :
4233 4 : SbUnoObjectRef xUnoObj = new SbUnoObject( OUString( "DefaultContext" ), aContextAny );
4234 4 : refVar->PutObject( (SbUnoObject*)xUnoObj );
4235 2 : }
4236 :
4237 :
4238 : // Creates a Basic wrapper object for a strongly typed Uno value
4239 : // 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
4240 0 : void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, bool bWrite )
4241 : {
4242 : (void)pBasic;
4243 : (void)bWrite;
4244 :
4245 0 : static OUString aTypeTypeString( "type" );
4246 :
4247 : // 2 parameters needed
4248 0 : if ( rPar.Count() != 3 )
4249 : {
4250 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
4251 0 : return;
4252 : }
4253 :
4254 : // get the name of the class of the struct
4255 0 : OUString aTypeName = rPar.Get(1)->GetOUString();
4256 0 : SbxVariable* pVal = rPar.Get(2);
4257 :
4258 0 : if( aTypeName == aTypeTypeString )
4259 : {
4260 0 : SbxDataType eBaseType = pVal->SbxValue::GetType();
4261 0 : OUString aValTypeName;
4262 0 : if( eBaseType == SbxSTRING )
4263 : {
4264 0 : aValTypeName = pVal->GetOUString();
4265 : }
4266 0 : else if( eBaseType == SbxOBJECT )
4267 : {
4268 : // XIdlClass?
4269 0 : Reference< XIdlClass > xIdlClass;
4270 :
4271 0 : SbxBaseRef pObj = (SbxBase*)pVal->GetObject();
4272 0 : if( pObj && pObj->ISA(SbUnoObject) )
4273 : {
4274 0 : Any aUnoAny = static_cast<SbUnoObject*>((SbxBase*)pObj)->getUnoAny();
4275 0 : aUnoAny >>= xIdlClass;
4276 : }
4277 :
4278 0 : if( xIdlClass.is() )
4279 : {
4280 0 : aValTypeName = xIdlClass->getName();
4281 0 : }
4282 : }
4283 0 : Type aType;
4284 0 : bool bSuccess = implGetTypeByName( aValTypeName, aType );
4285 0 : if( bSuccess )
4286 : {
4287 0 : Any aTypeAny( aType );
4288 0 : SbxVariableRef refVar = rPar.Get(0);
4289 0 : SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aTypeAny );
4290 0 : refVar->PutObject( xUnoAnyObject );
4291 : }
4292 0 : return;
4293 : }
4294 :
4295 : // Check the type
4296 0 : Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
4297 0 : Any aRet;
4298 : try
4299 : {
4300 0 : aRet = xTypeAccess->getByHierarchicalName( aTypeName );
4301 : }
4302 0 : catch( const NoSuchElementException& e1 )
4303 : {
4304 0 : OUString aNoSuchElementExceptionName( "com.sun.star.container.NoSuchElementException" );
4305 : StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
4306 0 : implGetExceptionMsg( e1, aNoSuchElementExceptionName ) );
4307 0 : return;
4308 : }
4309 0 : Reference< XTypeDescription > xTypeDesc;
4310 0 : aRet >>= xTypeDesc;
4311 0 : TypeClass eTypeClass = xTypeDesc->getTypeClass();
4312 0 : Type aDestType( eTypeClass, aTypeName );
4313 :
4314 :
4315 : // Preconvert value
4316 0 : Any aVal = sbxToUnoValueImpl( pVal );
4317 0 : Any aConvertedVal = convertAny( aVal, aDestType );
4318 :
4319 0 : SbxVariableRef refVar = rPar.Get(0);
4320 0 : SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aConvertedVal );
4321 0 : refVar->PutObject( xUnoAnyObject );
4322 : }
4323 :
4324 :
4325 :
4326 : namespace {
4327 0 : class OMutexBasis
4328 : {
4329 : protected:
4330 : // this mutex is necessary for OInterfaceContainerHelper
4331 : ::osl::Mutex m_aMutex;
4332 : };
4333 : } // namespace
4334 :
4335 : typedef WeakImplHelper2< XInvocation, XComponent > ModuleInvocationProxyHelper;
4336 :
4337 : class ModuleInvocationProxy : public OMutexBasis,
4338 : public ModuleInvocationProxyHelper
4339 : {
4340 : OUString m_aPrefix;
4341 : SbxObjectRef m_xScopeObj;
4342 : bool m_bProxyIsClassModuleObject;
4343 :
4344 : ::cppu::OInterfaceContainerHelper m_aListeners;
4345 :
4346 : public:
4347 : ModuleInvocationProxy( const OUString& aPrefix, SbxObjectRef xScopeObj );
4348 0 : virtual ~ModuleInvocationProxy()
4349 0 : {}
4350 :
4351 : // XInvocation
4352 : virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw(std::exception) SAL_OVERRIDE;
4353 : virtual void SAL_CALL setValue( const OUString& rProperty, const Any& rValue )
4354 : throw (UnknownPropertyException, RuntimeException, std::exception) SAL_OVERRIDE;
4355 : virtual Any SAL_CALL getValue( const OUString& rProperty )
4356 : throw (UnknownPropertyException, RuntimeException, std::exception) SAL_OVERRIDE;
4357 : virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw(std::exception) SAL_OVERRIDE;
4358 : virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw(std::exception) SAL_OVERRIDE;
4359 :
4360 : virtual Any SAL_CALL invoke( const OUString& rFunction,
4361 : const Sequence< Any >& rParams,
4362 : Sequence< sal_Int16 >& rOutParamIndex,
4363 : Sequence< Any >& rOutParam )
4364 : throw (CannotConvertException, InvocationTargetException,
4365 : RuntimeException, std::exception ) SAL_OVERRIDE;
4366 :
4367 : // XComponent
4368 : virtual void SAL_CALL dispose() throw(RuntimeException, std::exception) SAL_OVERRIDE;
4369 : virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
4370 : virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
4371 : };
4372 :
4373 0 : ModuleInvocationProxy::ModuleInvocationProxy( const OUString& aPrefix, SbxObjectRef xScopeObj )
4374 0 : : m_aPrefix( aPrefix + OUString( "_" ) )
4375 : , m_xScopeObj( xScopeObj )
4376 0 : , m_aListeners( m_aMutex )
4377 : {
4378 0 : m_bProxyIsClassModuleObject = xScopeObj.Is() && xScopeObj->ISA(SbClassModuleObject);
4379 0 : }
4380 :
4381 0 : Reference< XIntrospectionAccess > SAL_CALL ModuleInvocationProxy::getIntrospection() throw(std::exception)
4382 : {
4383 0 : return Reference< XIntrospectionAccess >();
4384 : }
4385 :
4386 0 : void SAL_CALL ModuleInvocationProxy::setValue(const OUString& rProperty, const Any& rValue)
4387 : throw (UnknownPropertyException, RuntimeException, std::exception)
4388 : {
4389 0 : if( !m_bProxyIsClassModuleObject )
4390 0 : throw UnknownPropertyException();
4391 :
4392 0 : SolarMutexGuard guard;
4393 :
4394 0 : OUString aPropertyFunctionName( "Property Set " );
4395 0 : aPropertyFunctionName += m_aPrefix;
4396 0 : aPropertyFunctionName += rProperty;
4397 :
4398 0 : SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
4399 0 : SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
4400 0 : if( pMeth == NULL )
4401 : {
4402 : // TODO: Check vba behavior concernig missing function
4403 : //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4404 0 : throw UnknownPropertyException();
4405 : }
4406 :
4407 : // Setup parameter
4408 0 : SbxArrayRef xArray = new SbxArray;
4409 0 : SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
4410 0 : unoToSbxValue( (SbxVariable*)xVar, rValue );
4411 0 : xArray->Put( xVar, 1 );
4412 :
4413 : // Call property method
4414 0 : SbxVariableRef xValue = new SbxVariable;
4415 0 : pMeth->SetParameters( xArray );
4416 0 : pMeth->Call( xValue );
4417 0 : pMeth->SetParameters( NULL );
4418 :
4419 : // TODO: OutParameter?
4420 :
4421 :
4422 :
4423 0 : }
4424 :
4425 0 : Any SAL_CALL ModuleInvocationProxy::getValue(const OUString& rProperty)
4426 : throw (UnknownPropertyException, RuntimeException, std::exception)
4427 : {
4428 0 : if( !m_bProxyIsClassModuleObject )
4429 : {
4430 0 : throw UnknownPropertyException();
4431 : }
4432 0 : SolarMutexGuard guard;
4433 :
4434 0 : OUString aPropertyFunctionName( "Property Get " );
4435 0 : aPropertyFunctionName += m_aPrefix;
4436 0 : aPropertyFunctionName += rProperty;
4437 :
4438 0 : SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
4439 0 : SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
4440 0 : if( pMeth == NULL )
4441 : {
4442 : // TODO: Check vba behavior concernig missing function
4443 : //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4444 0 : throw UnknownPropertyException();
4445 : }
4446 :
4447 : // Call method
4448 0 : SbxVariableRef xValue = new SbxVariable;
4449 0 : pMeth->Call( xValue );
4450 0 : Any aRet = sbxToUnoValue( xValue );
4451 0 : return aRet;
4452 : }
4453 :
4454 0 : sal_Bool SAL_CALL ModuleInvocationProxy::hasMethod( const OUString& ) throw(std::exception)
4455 : {
4456 0 : return sal_False;
4457 : }
4458 :
4459 0 : sal_Bool SAL_CALL ModuleInvocationProxy::hasProperty( const OUString& ) throw(std::exception)
4460 : {
4461 0 : return sal_False;
4462 : }
4463 :
4464 0 : Any SAL_CALL ModuleInvocationProxy::invoke( const OUString& rFunction,
4465 : const Sequence< Any >& rParams,
4466 : Sequence< sal_Int16 >&,
4467 : Sequence< Any >& )
4468 : throw (CannotConvertException, InvocationTargetException,
4469 : RuntimeException, std::exception)
4470 : {
4471 0 : SolarMutexGuard guard;
4472 :
4473 0 : Any aRet;
4474 0 : SbxObjectRef xScopeObj = m_xScopeObj;
4475 0 : if( !xScopeObj.Is() )
4476 : {
4477 0 : return aRet;
4478 : }
4479 0 : OUString aFunctionName = m_aPrefix;
4480 0 : aFunctionName += rFunction;
4481 :
4482 0 : bool bSetRescheduleBack = false;
4483 0 : bool bOldReschedule = true;
4484 0 : SbiInstance* pInst = GetSbData()->pInst;
4485 0 : if( pInst && pInst->IsCompatibility() )
4486 : {
4487 0 : bOldReschedule = pInst->IsReschedule();
4488 0 : if ( bOldReschedule )
4489 : {
4490 0 : pInst->EnableReschedule( false );
4491 0 : bSetRescheduleBack = true;
4492 : }
4493 : }
4494 :
4495 0 : SbxVariable* p = xScopeObj->Find( aFunctionName, SbxCLASS_METHOD );
4496 0 : SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
4497 0 : if( pMeth == NULL )
4498 : {
4499 : // TODO: Check vba behavior concernig missing function
4500 : //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
4501 0 : return aRet;
4502 : }
4503 :
4504 : // Setup parameters
4505 0 : SbxArrayRef xArray;
4506 0 : sal_Int32 nParamCount = rParams.getLength();
4507 0 : if( nParamCount )
4508 : {
4509 0 : xArray = new SbxArray;
4510 0 : const Any *pArgs = rParams.getConstArray();
4511 0 : for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
4512 : {
4513 0 : SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
4514 0 : unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
4515 0 : xArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
4516 0 : }
4517 : }
4518 :
4519 : // Call method
4520 0 : SbxVariableRef xValue = new SbxVariable;
4521 0 : if( xArray.Is() )
4522 0 : pMeth->SetParameters( xArray );
4523 0 : pMeth->Call( xValue );
4524 0 : aRet = sbxToUnoValue( xValue );
4525 0 : pMeth->SetParameters( NULL );
4526 :
4527 0 : if( bSetRescheduleBack )
4528 0 : pInst->EnableReschedule( bOldReschedule );
4529 :
4530 : // TODO: OutParameter?
4531 :
4532 0 : return aRet;
4533 : }
4534 :
4535 0 : void SAL_CALL ModuleInvocationProxy::dispose()
4536 : throw(RuntimeException, std::exception)
4537 : {
4538 0 : ::osl::MutexGuard aGuard( m_aMutex );
4539 :
4540 0 : EventObject aEvent( (XComponent*)this );
4541 0 : m_aListeners.disposeAndClear( aEvent );
4542 :
4543 0 : m_xScopeObj = NULL;
4544 0 : }
4545 :
4546 0 : void SAL_CALL ModuleInvocationProxy::addEventListener( const Reference< XEventListener >& xListener )
4547 : throw (RuntimeException, std::exception)
4548 : {
4549 0 : m_aListeners.addInterface( xListener );
4550 0 : }
4551 :
4552 0 : void SAL_CALL ModuleInvocationProxy::removeEventListener( const Reference< XEventListener >& xListener )
4553 : throw (RuntimeException, std::exception)
4554 : {
4555 0 : m_aListeners.removeInterface( xListener );
4556 0 : }
4557 :
4558 :
4559 0 : Reference< XInterface > createComListener( const Any& aControlAny, const OUString& aVBAType,
4560 : const OUString& aPrefix, SbxObjectRef xScopeObj )
4561 : {
4562 0 : Reference< XInterface > xRet;
4563 :
4564 : Reference< XComponentContext > xContext(
4565 0 : comphelper::getProcessComponentContext() );
4566 0 : Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
4567 :
4568 0 : Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPrefix, xScopeObj );
4569 :
4570 0 : Sequence<Any> args( 3 );
4571 0 : args[0] <<= aControlAny;
4572 0 : args[1] <<= aVBAType;
4573 0 : args[2] <<= xProxy;
4574 :
4575 : try
4576 : {
4577 0 : xRet = xServiceMgr->createInstanceWithArgumentsAndContext(
4578 : OUString( "com.sun.star.custom.UnoComListener"),
4579 0 : args, xContext );
4580 : }
4581 0 : catch( const Exception& )
4582 : {
4583 0 : implHandleAnyException( ::cppu::getCaughtException() );
4584 : }
4585 :
4586 0 : return xRet;
4587 : }
4588 :
4589 : typedef std::vector< WeakReference< XComponent > > ComponentRefVector;
4590 :
4591 4 : struct StarBasicDisposeItem
4592 : {
4593 : StarBASIC* m_pBasic;
4594 : SbxArrayRef m_pRegisteredVariables;
4595 : ComponentRefVector m_vComImplementsObjects;
4596 :
4597 4 : StarBasicDisposeItem( StarBASIC* pBasic )
4598 4 : : m_pBasic( pBasic )
4599 : {
4600 4 : m_pRegisteredVariables = new SbxArray();
4601 4 : }
4602 : };
4603 :
4604 : typedef std::vector< StarBasicDisposeItem* > DisposeItemVector;
4605 :
4606 401 : static DisposeItemVector GaDisposeItemVector;
4607 :
4608 4420 : static DisposeItemVector::iterator lcl_findItemForBasic( StarBASIC* pBasic )
4609 : {
4610 4420 : DisposeItemVector::iterator it;
4611 4424 : for( it = GaDisposeItemVector.begin() ; it != GaDisposeItemVector.end() ; ++it )
4612 : {
4613 8 : StarBasicDisposeItem* pItem = *it;
4614 8 : if( pItem->m_pBasic == pBasic )
4615 4 : return it;
4616 : }
4617 4416 : return GaDisposeItemVector.end();
4618 : }
4619 :
4620 4 : static StarBasicDisposeItem* lcl_getOrCreateItemForBasic( StarBASIC* pBasic )
4621 : {
4622 4 : DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
4623 4 : StarBasicDisposeItem* pItem = (it != GaDisposeItemVector.end()) ? *it : NULL;
4624 4 : if( pItem == NULL )
4625 : {
4626 4 : pItem = new StarBasicDisposeItem( pBasic );
4627 4 : GaDisposeItemVector.push_back( pItem );
4628 : }
4629 4 : return pItem;
4630 : }
4631 :
4632 4 : void registerComponentToBeDisposedForBasic
4633 : ( Reference< XComponent > xComponent, StarBASIC* pBasic )
4634 : {
4635 4 : StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
4636 4 : pItem->m_vComImplementsObjects.push_back( xComponent );
4637 4 : }
4638 :
4639 0 : void registerComListenerVariableForBasic( SbxVariable* pVar, StarBASIC* pBasic )
4640 : {
4641 0 : StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
4642 0 : SbxArray* pArray = pItem->m_pRegisteredVariables;
4643 0 : pArray->Put( pVar, pArray->Count() );
4644 0 : }
4645 :
4646 4416 : void disposeComVariablesForBasic( StarBASIC* pBasic )
4647 : {
4648 4416 : DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
4649 4416 : if( it != GaDisposeItemVector.end() )
4650 : {
4651 4 : StarBasicDisposeItem* pItem = *it;
4652 :
4653 4 : SbxArray* pArray = pItem->m_pRegisteredVariables;
4654 4 : sal_uInt16 nCount = pArray->Count();
4655 4 : for( sal_uInt16 i = 0 ; i < nCount ; ++i )
4656 : {
4657 0 : SbxVariable* pVar = pArray->Get( i );
4658 0 : pVar->ClearComListener();
4659 : }
4660 :
4661 4 : ComponentRefVector& rv = pItem->m_vComImplementsObjects;
4662 4 : ComponentRefVector::iterator itCRV;
4663 8 : for( itCRV = rv.begin() ; itCRV != rv.end() ; ++itCRV )
4664 : {
4665 : try
4666 : {
4667 4 : Reference< XComponent > xComponent( (*itCRV).get(), UNO_QUERY_THROW );
4668 4 : xComponent->dispose();
4669 : }
4670 0 : catch(const Exception& )
4671 : {}
4672 : }
4673 :
4674 4 : delete pItem;
4675 4 : GaDisposeItemVector.erase( it );
4676 : }
4677 4416 : }
4678 :
4679 :
4680 : // Handle module implements mechanism for OLE types
4681 0 : bool SbModule::createCOMWrapperForIface( Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject )
4682 : {
4683 : // For now: Take first interface that allows to instantiate COM wrapper
4684 : // TODO: Check if support for multiple interfaces is needed
4685 :
4686 : Reference< XComponentContext > xContext(
4687 0 : comphelper::getProcessComponentContext() );
4688 0 : Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
4689 : Reference< XSingleServiceFactory > xComImplementsFactory
4690 : (
4691 0 : xServiceMgr->createInstanceWithContext(
4692 0 : OUString( "com.sun.star.custom.ComImplementsFactory"), xContext ),
4693 : UNO_QUERY
4694 0 : );
4695 0 : if( !xComImplementsFactory.is() )
4696 0 : return false;
4697 :
4698 0 : bool bSuccess = false;
4699 :
4700 0 : SbxArray* pModIfaces = pClassData->mxIfaces;
4701 0 : sal_uInt16 nCount = pModIfaces->Count();
4702 0 : for( sal_uInt16 i = 0 ; i < nCount ; ++i )
4703 : {
4704 0 : SbxVariable* pVar = pModIfaces->Get( i );
4705 0 : OUString aIfaceName = pVar->GetName();
4706 :
4707 0 : if( !aIfaceName.isEmpty() )
4708 : {
4709 0 : OUString aPureIfaceName = aIfaceName;
4710 0 : sal_Int32 indexLastDot = aIfaceName.lastIndexOf('.');
4711 0 : if ( indexLastDot > -1 )
4712 : {
4713 0 : aPureIfaceName = aIfaceName.copy( indexLastDot + 1 );
4714 : }
4715 0 : Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPureIfaceName, pProxyClassModuleObject );
4716 :
4717 0 : Sequence<Any> args( 2 );
4718 0 : args[0] <<= aIfaceName;
4719 0 : args[1] <<= xProxy;
4720 :
4721 0 : Reference< XInterface > xRet;
4722 0 : bSuccess = false;
4723 : try
4724 : {
4725 0 : xRet = xComImplementsFactory->createInstanceWithArguments( args );
4726 0 : bSuccess = true;
4727 : }
4728 0 : catch( const Exception& )
4729 : {
4730 0 : implHandleAnyException( ::cppu::getCaughtException() );
4731 : }
4732 :
4733 0 : if( bSuccess )
4734 : {
4735 0 : Reference< XComponent > xComponent( xProxy, UNO_QUERY );
4736 0 : if( xComponent.is() )
4737 : {
4738 0 : StarBASIC* pParentBasic = NULL;
4739 0 : SbxObject* pCurObject = this;
4740 0 : do
4741 : {
4742 0 : SbxObject* pObjParent = pCurObject->GetParent();
4743 0 : pParentBasic = PTR_CAST( StarBASIC, pObjParent );
4744 0 : pCurObject = pObjParent;
4745 : }
4746 0 : while( pParentBasic == NULL && pCurObject != NULL );
4747 :
4748 : OSL_ASSERT( pParentBasic != NULL );
4749 0 : registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
4750 : }
4751 :
4752 0 : o_rRetAny <<= xRet;
4753 0 : break;
4754 0 : }
4755 : }
4756 0 : }
4757 :
4758 0 : return bSuccess;
4759 : }
4760 :
4761 :
4762 : // Due to an incorrect behavior IE returns an object instead of a string
4763 : // in some scenarios. Calling toString at the object may correct this.
4764 : // Helper function used in sbxvalue.cxx
4765 0 : bool handleToStringForCOMObjects( SbxObject* pObj, SbxValue* pVal )
4766 : {
4767 0 : bool bSuccess = false;
4768 :
4769 0 : SbUnoObject* pUnoObj = NULL;
4770 0 : if( pObj != NULL && (pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)pObj)) != NULL )
4771 : {
4772 : // Only for native COM objects
4773 0 : if( pUnoObj->isNativeCOMObject() )
4774 : {
4775 0 : SbxVariableRef pMeth = pObj->Find( OUString( "toString" ), SbxCLASS_METHOD );
4776 0 : if ( pMeth.Is() )
4777 : {
4778 0 : SbxValues aRes;
4779 0 : pMeth->Get( aRes );
4780 0 : pVal->Put( aRes );
4781 0 : bSuccess = true;
4782 0 : }
4783 : }
4784 : }
4785 0 : return bSuccess;
4786 : }
4787 :
4788 72 : Any StructRefInfo::getValue()
4789 : {
4790 72 : Any aRet;
4791 : uno_any_destruct(
4792 72 : &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
4793 72 : typelib_TypeDescription * pTD = 0;
4794 72 : maType.getDescription(&pTD);
4795 : uno_any_construct(
4796 : &aRet, getInst(), pTD,
4797 72 : reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
4798 72 : typelib_typedescription_release(pTD);
4799 72 : return aRet;
4800 : }
4801 :
4802 172 : bool StructRefInfo::setValue( const Any& rValue )
4803 : {
4804 : return uno_type_assignData( getInst(),
4805 : maType.getTypeLibType(),
4806 172 : (void*)rValue.getValue(),
4807 : rValue.getValueTypeRef(),
4808 : reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
4809 : reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
4810 344 : reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
4811 : }
4812 :
4813 394 : OUString StructRefInfo::getTypeName() const
4814 : {
4815 394 : return maType.getTypeName();
4816 : }
4817 :
4818 244 : void* StructRefInfo::getInst()
4819 : {
4820 244 : return ((char*)maAny.getValue() + mnPos );
4821 : }
4822 :
4823 24 : TypeClass StructRefInfo::getTypeClass() const
4824 : {
4825 24 : return maType.getTypeClass();
4826 : }
4827 :
4828 382 : SbUnoStructRefObject::SbUnoStructRefObject( const OUString& aName_, const StructRefInfo& rMemberInfo ) : SbxObject( aName_ ), maMemberInfo( rMemberInfo ), mbMemberCacheInit( false )
4829 : {
4830 382 : SetClassName( OUString( maMemberInfo.getTypeName() ) );
4831 382 : }
4832 :
4833 1146 : SbUnoStructRefObject::~SbUnoStructRefObject()
4834 : {
4835 1484 : for ( StructFieldInfo::iterator it = maFields.begin(), it_end = maFields.end(); it != it_end; ++it )
4836 1102 : delete it->second;
4837 764 : }
4838 :
4839 142 : void SbUnoStructRefObject::initMemberCache()
4840 : {
4841 142 : if ( mbMemberCacheInit )
4842 142 : return;
4843 142 : sal_Int32 nAll = 0;
4844 142 : typelib_TypeDescription * pTD = 0;
4845 142 : maMemberInfo.getType().getDescription(&pTD);
4846 142 : typelib_CompoundTypeDescription * pCompTypeDescr = (typelib_CompoundTypeDescription *)pTD;
4847 292 : for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
4848 150 : nAll += pCompTypeDescr->nMembers;
4849 292 : for ( pCompTypeDescr = (typelib_CompoundTypeDescription *)pTD; pCompTypeDescr;
4850 : pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
4851 : {
4852 150 : typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs;
4853 150 : rtl_uString ** ppNames = pCompTypeDescr->ppMemberNames;
4854 150 : sal_Int32 * pMemberOffsets = pCompTypeDescr->pMemberOffsets;
4855 1402 : for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; )
4856 : {
4857 1102 : OUString aName( ppNames[nPos] );
4858 1102 : maFields[ aName ] = new StructRefInfo( maMemberInfo.getRootAnyRef(), ppTypeRefs[nPos], maMemberInfo.getPos() + pMemberOffsets[nPos] );
4859 1102 : }
4860 : }
4861 142 : typelib_typedescription_release(pTD);
4862 142 : mbMemberCacheInit = true;
4863 : }
4864 :
4865 12 : SbxVariable* SbUnoStructRefObject::Find( const OUString& rName, SbxClassType t )
4866 : {
4867 12 : SbxVariable* pRes = SbxObject::Find( rName, t );
4868 12 : if ( !pRes )
4869 : {
4870 12 : if ( !mbMemberCacheInit )
4871 12 : initMemberCache();
4872 12 : StructFieldInfo::iterator it = maFields.find( OUString( rName ).toAsciiUpperCase() );
4873 12 : if ( it != maFields.end() )
4874 : {
4875 : SbxDataType eSbxType;
4876 12 : eSbxType = unoToSbxType( it->second->getTypeClass() );
4877 12 : SbxDataType eRealSbxType = eSbxType;
4878 12 : Property aProp;
4879 12 : aProp.Name = rName;
4880 12 : aProp.Type = com::sun::star::uno::Type( it->second->getTypeClass(), it->second->getTypeName() );
4881 12 : SbUnoProperty* pProp = new SbUnoProperty( rName, eSbxType, eRealSbxType, aProp, 0, false, ( aProp.Type.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT) );
4882 24 : SbxVariableRef xVarRef = pProp;
4883 12 : QuickInsert( (SbxVariable*)xVarRef );
4884 24 : pRes = xVarRef;
4885 : }
4886 : }
4887 :
4888 12 : if( !pRes )
4889 : {
4890 0 : if( rName.equalsIgnoreAsciiCase(ID_DBG_SUPPORTEDINTERFACES) ||
4891 0 : rName.equalsIgnoreAsciiCase(ID_DBG_PROPERTIES) ||
4892 0 : rName.equalsIgnoreAsciiCase(ID_DBG_METHODS) )
4893 : {
4894 : // Create
4895 0 : implCreateDbgProperties();
4896 :
4897 : // Now they have to be found regular
4898 0 : pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
4899 : }
4900 : }
4901 :
4902 12 : return pRes;
4903 : }
4904 :
4905 : // help method to create the dbg_-Properties
4906 0 : void SbUnoStructRefObject::implCreateDbgProperties( void )
4907 : {
4908 0 : Property aProp;
4909 :
4910 : // Id == -1: display the implemented interfaces corresponding the ClassProvider
4911 0 : SbxVariableRef xVarRef = new SbUnoProperty( OUString(ID_DBG_SUPPORTEDINTERFACES), SbxSTRING, SbxSTRING, aProp, -1, false, false );
4912 0 : QuickInsert( (SbxVariable*)xVarRef );
4913 :
4914 : // Id == -2: output the properties
4915 0 : xVarRef = new SbUnoProperty( OUString(ID_DBG_PROPERTIES), SbxSTRING, SbxSTRING, aProp, -2, false, false );
4916 0 : QuickInsert( (SbxVariable*)xVarRef );
4917 :
4918 : // Id == -3: output the Methods
4919 0 : xVarRef = new SbUnoProperty( OUString(ID_DBG_METHODS), SbxSTRING, SbxSTRING, aProp, -3, false, false );
4920 0 : QuickInsert( (SbxVariable*)xVarRef );
4921 0 : }
4922 :
4923 0 : void SbUnoStructRefObject::implCreateAll()
4924 : {
4925 : // throw away all existing methods and properties
4926 0 : pMethods = new SbxArray;
4927 0 : pProps = new SbxArray;
4928 :
4929 0 : if (!mbMemberCacheInit)
4930 0 : initMemberCache();
4931 :
4932 0 : for ( StructFieldInfo::iterator it = maFields.begin(), it_end = maFields.end(); it != it_end; ++it )
4933 : {
4934 0 : const OUString& rName = it->first;
4935 : SbxDataType eSbxType;
4936 0 : eSbxType = unoToSbxType( it->second->getTypeClass() );
4937 0 : SbxDataType eRealSbxType = eSbxType;
4938 0 : Property aProp;
4939 0 : aProp.Name = rName;
4940 0 : aProp.Type = com::sun::star::uno::Type( it->second->getTypeClass(), it->second->getTypeName() );
4941 0 : SbUnoProperty* pProp = new SbUnoProperty( rName, eSbxType, eRealSbxType, aProp, 0, false, ( aProp.Type.getTypeClass() == com::sun::star::uno::TypeClass_STRUCT) );
4942 0 : SbxVariableRef xVarRef = pProp;
4943 0 : QuickInsert( (SbxVariable*)xVarRef );
4944 0 : }
4945 :
4946 : // Create Dbg_-Properties
4947 0 : implCreateDbgProperties();
4948 0 : }
4949 :
4950 : // output the value
4951 12 : Any SbUnoStructRefObject::getUnoAny( void )
4952 : {
4953 12 : return maMemberInfo.getValue();
4954 : }
4955 :
4956 0 : OUString SbUnoStructRefObject::Impl_DumpProperties()
4957 : {
4958 0 : OUStringBuffer aRet;
4959 0 : aRet.appendAscii("Properties of object ");
4960 0 : aRet.append( getDbgObjectName() );
4961 :
4962 0 : sal_uInt16 nPropCount = pProps->Count();
4963 0 : sal_uInt16 nPropsPerLine = 1 + nPropCount / 30;
4964 0 : for( sal_uInt16 i = 0; i < nPropCount; i++ )
4965 : {
4966 0 : SbxVariable* pVar = pProps->Get( i );
4967 0 : if( pVar )
4968 : {
4969 0 : OUStringBuffer aPropStr;
4970 0 : if( (i % nPropsPerLine) == 0 )
4971 : {
4972 0 : aPropStr.appendAscii( "\n" );
4973 : }
4974 : // output the type and name
4975 : // Is it in Uno a sequence?
4976 0 : SbxDataType eType = pVar->GetFullType();
4977 :
4978 0 : OUString aName( pVar->GetName() );
4979 0 : StructFieldInfo::iterator it = maFields.find( aName );
4980 :
4981 0 : if ( it != maFields.end() )
4982 : {
4983 0 : const StructRefInfo& rPropInfo = *it->second;
4984 :
4985 0 : if( eType == SbxOBJECT )
4986 : {
4987 0 : if( rPropInfo.getTypeClass() == TypeClass_SEQUENCE )
4988 : {
4989 0 : eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
4990 : }
4991 : }
4992 : }
4993 0 : aPropStr.append( Dbg_SbxDataType2String( eType ) );
4994 :
4995 0 : aPropStr.appendAscii( " " );
4996 0 : aPropStr.append( pVar->GetName() );
4997 :
4998 0 : if( i == nPropCount - 1 )
4999 : {
5000 0 : aPropStr.appendAscii( "\n" );
5001 : }
5002 : else
5003 : {
5004 0 : aPropStr.appendAscii( "; " );
5005 : }
5006 0 : aRet.append( aPropStr.makeStringAndClear() );
5007 : }
5008 : }
5009 0 : return aRet.makeStringAndClear();
5010 : }
5011 :
5012 12 : void SbUnoStructRefObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
5013 : const SfxHint& rHint, const TypeId& rHintType )
5014 : {
5015 12 : if ( !mbMemberCacheInit )
5016 0 : initMemberCache();
5017 12 : const SbxHint* pHint = dynamic_cast<const SbxHint*>(&rHint);
5018 12 : if( pHint )
5019 : {
5020 12 : SbxVariable* pVar = pHint->GetVar();
5021 12 : SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
5022 12 : if( pProp )
5023 : {
5024 12 : StructFieldInfo::iterator it = maFields.find( pProp->GetName() );
5025 : // handle get/set of members of struct
5026 12 : if( pHint->GetId() == SBX_HINT_DATAWANTED )
5027 : {
5028 : // Test-Properties
5029 8 : sal_Int32 nId = pProp->nId;
5030 8 : if( nId < 0 )
5031 : {
5032 : // Id == -1: Display implemented interfaces according the ClassProvider
5033 0 : if( nId == -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
5034 : {
5035 0 : OUStringBuffer aRet;
5036 0 : aRet.appendAscii( ID_DBG_SUPPORTEDINTERFACES );
5037 0 : aRet.appendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
5038 :
5039 0 : pVar->PutString( aRet.makeStringAndClear() );
5040 : }
5041 : // Id == -2: output properties
5042 0 : else if( nId == -2 ) // Property ID_DBG_PROPERTIES
5043 : {
5044 : // by now all properties must be established
5045 0 : implCreateAll();
5046 0 : OUString aRetStr = Impl_DumpProperties();
5047 0 : pVar->PutString( aRetStr );
5048 : }
5049 : // Id == -3: output the methods
5050 0 : else if( nId == -3 ) // Property ID_DBG_METHODS
5051 : {
5052 : // by now all properties must be established
5053 0 : implCreateAll();
5054 0 : OUStringBuffer aRet;
5055 0 : aRet.appendAscii("Methods of object ");
5056 0 : aRet.append( getDbgObjectName() );
5057 0 : aRet.appendAscii( "\nNo methods found\n" );
5058 0 : pVar->PutString( aRet.makeStringAndClear() );
5059 : }
5060 12 : return;
5061 : }
5062 :
5063 8 : if ( it != maFields.end() )
5064 : {
5065 8 : Any aRetAny = it->second->getValue();
5066 8 : unoToSbxValue( pVar, aRetAny );
5067 : }
5068 : else
5069 0 : StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
5070 : }
5071 4 : else if( pHint->GetId() == SBX_HINT_DATACHANGED )
5072 : {
5073 4 : if ( it != maFields.end() )
5074 : {
5075 : // take over the value from Uno to Sbx
5076 4 : Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
5077 4 : it->second->setValue( aAnyValue );
5078 : }
5079 : else
5080 0 : StarBASIC::Error( SbERR_PROPERTY_NOT_FOUND );
5081 : }
5082 : }
5083 : else
5084 0 : SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
5085 : }
5086 : }
5087 :
5088 252 : StructRefInfo SbUnoStructRefObject::getStructMember( const OUString& rMemberName )
5089 : {
5090 252 : if (!mbMemberCacheInit)
5091 : {
5092 130 : initMemberCache();
5093 : }
5094 252 : StructFieldInfo::iterator it = maFields.find( rMemberName );
5095 :
5096 252 : css::uno::Type aFoundType;
5097 252 : sal_Int32 nFoundPos = -1;
5098 :
5099 252 : if ( it != maFields.end() )
5100 : {
5101 252 : aFoundType = it->second->getType();
5102 252 : nFoundPos = it->second->getPos();
5103 : }
5104 252 : StructRefInfo aRet( maMemberInfo.getRootAnyRef(), aFoundType, nFoundPos );
5105 252 : return aRet;
5106 : }
5107 :
5108 0 : OUString SbUnoStructRefObject::getDbgObjectName()
5109 : {
5110 0 : OUString aName = GetClassName();
5111 0 : if( aName.isEmpty() )
5112 : {
5113 0 : aName += "Unknown";
5114 : }
5115 0 : OUStringBuffer aRet;
5116 0 : if( aName.getLength() > 20 )
5117 : {
5118 0 : aRet.appendAscii( "\n" );
5119 : }
5120 0 : aRet.appendAscii( "\"" );
5121 0 : aRet.append( aName );
5122 0 : aRet.appendAscii( "\":" );
5123 0 : return aRet.makeStringAndClear();
5124 1203 : }
5125 :
5126 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|