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