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