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