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