1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scripting.hxx"
26 #include "dlgevtatt.hxx"
27 
28 #include "dlgprov.hxx"
29 
30 #include <sfx2/sfx.hrc>
31 #include <sfx2/app.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <tools/diagnose_ex.h>
34 
35 #include <com/sun/star/awt/XControl.hpp>
36 #include <com/sun/star/awt/XDialogEventHandler.hpp>
37 #include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
40 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
41 #include <com/sun/star/script/provider/XScriptProvider.hpp>
42 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
43 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
44 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
45 #include <com/sun/star/lang/NoSuchMethodException.hpp>
46 #include <com/sun/star/reflection/XIdlMethod.hpp>
47 #include <com/sun/star/beans/MethodConcept.hpp>
48 #include <com/sun/star/beans/XMaterialHolder.hpp>
49 
50 #include <ooo/vba/XVBAToOOEventDescGen.hpp>
51 
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::awt;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::script;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::script;
59 using namespace ::com::sun::star::reflection;
60 
61 
62 //.........................................................................
63 namespace dlgprov
64 {
65 
66   class DialogSFScriptListenerImpl : public DialogScriptListenerImpl
67     {
68         protected:
69         Reference< frame::XModel >  m_xModel;
70         virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet );
71         public:
DialogSFScriptListenerImpl(const Reference<XComponentContext> & rxContext,const Reference<frame::XModel> & rxModel)72         DialogSFScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel ) : DialogScriptListenerImpl( rxContext ), m_xModel( rxModel ) {}
73     };
74 
75   class DialogLegacyScriptListenerImpl : public DialogSFScriptListenerImpl
76     {
77         protected:
78         virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet );
79         public:
DialogLegacyScriptListenerImpl(const Reference<XComponentContext> & rxContext,const Reference<frame::XModel> & rxModel)80         DialogLegacyScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel ) : DialogSFScriptListenerImpl( rxContext, rxModel ){}
81     };
82 
83   class DialogUnoScriptListenerImpl : public DialogSFScriptListenerImpl
84     {
85 	Reference< awt::XControl > m_xControl;
86         Reference< XInterface >	m_xHandler;
87 	Reference< beans::XIntrospectionAccess > m_xIntrospectionAccess;
88 	bool m_bDialogProviderMode;
89 
90         virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet );
91 
92     public:
93         DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext,
94             const Reference< frame::XModel >& rxModel,
95 			const Reference< awt::XControl >& rxControl,
96 			const Reference< XInterface >& rxHandler,
97 			const Reference< beans::XIntrospectionAccess >& rxIntrospectionAccess,
98 			bool bDialogProviderMode );		// false: ContainerWindowProvider mode
99 
100     };
101 
102   class DialogVBAScriptListenerImpl : public DialogScriptListenerImpl
103     {
104         protected:
105         rtl::OUString msDialogCodeName;
106         Reference<  script::XScriptListener > mxListener;
107         virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet );
108         public:
109         DialogVBAScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< awt::XControl >& rxControl, const Reference< frame::XModel >& xModel );
110     };
111 
DialogVBAScriptListenerImpl(const Reference<XComponentContext> & rxContext,const Reference<awt::XControl> & rxControl,const Reference<frame::XModel> & xModel)112     DialogVBAScriptListenerImpl::DialogVBAScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< awt::XControl >& rxControl, const Reference< frame::XModel >& xModel ) : DialogScriptListenerImpl( rxContext )
113     {
114         Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
115         Sequence< Any > args(1);
116         if ( xSMgr.is() )
117         {
118             args[0] <<= xModel;
119             mxListener = Reference< XScriptListener >( xSMgr->createInstanceWithArgumentsAndContext( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.EventListener" ) ), args, m_xContext ), UNO_QUERY );
120         }
121         if ( rxControl.is() )
122         {
123             try
124             {
125                 Reference< XPropertySet > xProps( rxControl->getModel(), UNO_QUERY_THROW );
126                 xProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= msDialogCodeName;
127                 xProps.set( mxListener, UNO_QUERY_THROW );
128                 xProps->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ), args[ 0 ] );
129             }
130             catch( const Exception& )
131             {
132             	DBG_UNHANDLED_EXCEPTION();
133             }
134         }
135 
136     }
137 
firing_impl(const script::ScriptEvent & aScriptEvent,uno::Any *)138     void DialogVBAScriptListenerImpl::firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* )
139     {
140         if ( aScriptEvent.ScriptType.equals( rtl::OUString::createFromAscii("VBAInterop") ) && mxListener.is() )
141         {
142             ScriptEvent aScriptEventCopy( aScriptEvent );
143             aScriptEventCopy.ScriptCode = msDialogCodeName;
144             try
145             {
146                 mxListener->firing( aScriptEventCopy );
147             }
148             catch( const Exception& )
149             {
150             	DBG_UNHANDLED_EXCEPTION();
151             }
152         }
153     }
154 
155 //.........................................................................
156 
157     // =============================================================================
158     // DialogEventsAttacherImpl
159     // =============================================================================
160 
DialogEventsAttacherImpl(const Reference<XComponentContext> & rxContext,const Reference<frame::XModel> & rxModel,const Reference<awt::XControl> & rxControl,const Reference<XInterface> & rxHandler,const Reference<beans::XIntrospectionAccess> & rxIntrospect,bool bProviderMode,const Reference<script::XScriptListener> & rxRTLListener)161     DialogEventsAttacherImpl::DialogEventsAttacherImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel, const Reference< awt::XControl >& rxControl, const Reference< XInterface >& rxHandler, const Reference< beans::XIntrospectionAccess >& rxIntrospect, bool bProviderMode, const Reference< script::XScriptListener >& rxRTLListener   )
162         :mbUseFakeVBAEvents( false ), m_xContext( rxContext )
163     {
164         // key listeners by protocol when ScriptType = 'Script'
165         // otherwise key is the ScriptType e.g. StarBasic
166         if ( rxRTLListener.is() ) // set up handler for RTL_BASIC
167             listernersForTypes[ rtl::OUString::createFromAscii("StarBasic") ] = rxRTLListener;
168         else
169             listernersForTypes[ rtl::OUString::createFromAscii("StarBasic") ] = new DialogLegacyScriptListenerImpl( rxContext, rxModel );
170         // handler for Script & ::rtl::OUString::createFromAscii( "vnd.sun.star.UNO:" )
171         listernersForTypes[ rtl::OUString::createFromAscii("vnd.sun.star.UNO") ] = new DialogUnoScriptListenerImpl( rxContext, rxModel, rxControl, rxHandler, rxIntrospect, bProviderMode );
172         listernersForTypes[ rtl::OUString::createFromAscii("vnd.sun.star.script") ] = new DialogSFScriptListenerImpl( rxContext, rxModel );
173 
174         // determine the VBA compatibility mode from the Basic library container
175         try
176         {
177             uno::Reference< beans::XPropertySet > xModelProps( rxModel, uno::UNO_QUERY_THROW );
178             uno::Reference< script::vba::XVBACompatibility > xVBACompat(
179                 xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ), uno::UNO_QUERY_THROW );
180             mbUseFakeVBAEvents = xVBACompat->getVBACompatibilityMode();
181         }
182         catch( uno::Exception& )
183         {
184         }
185         if ( mbUseFakeVBAEvents )
186             listernersForTypes[ rtl::OUString::createFromAscii("VBAInterop") ] = new DialogVBAScriptListenerImpl( rxContext, rxControl, rxModel );
187     }
188 
189     // -----------------------------------------------------------------------------
190 
~DialogEventsAttacherImpl()191     DialogEventsAttacherImpl::~DialogEventsAttacherImpl()
192     {
193     }
194 
195     // -----------------------------------------------------------------------------
196     Reference< script::XScriptListener >
getScriptListenerForKey(const rtl::OUString & sKey)197     DialogEventsAttacherImpl::getScriptListenerForKey( const rtl::OUString& sKey ) throw ( RuntimeException )
198     {
199         ListenerHash::iterator it = listernersForTypes.find( sKey );
200         if ( it == listernersForTypes.end() )
201             throw RuntimeException(); // more text info here please
202         return it->second;
203     }
getFakeVbaEventsSupplier(const Reference<XControl> & xControl,rtl::OUString & sControlName)204     Reference< XScriptEventsSupplier > DialogEventsAttacherImpl::getFakeVbaEventsSupplier( const Reference< XControl >& xControl, rtl::OUString& sControlName )
205     {
206         Reference< XScriptEventsSupplier > xEventsSupplier;
207         Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
208         if ( xSMgr.is() )
209         {
210             Reference< ooo::vba::XVBAToOOEventDescGen > xVBAToOOEvtDesc( xSMgr->createInstanceWithContext( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAToOOEventDesc" ) ), m_xContext ), UNO_QUERY );
211             if ( xVBAToOOEvtDesc.is() )
212                 xEventsSupplier.set( xVBAToOOEvtDesc->getEventSupplier( xControl, sControlName ), UNO_QUERY );
213         }
214         return xEventsSupplier;
215     }
216 
217     // -----------------------------------------------------------------------------
attachEventsToControl(const Reference<XControl> & xControl,const Reference<XScriptEventsSupplier> & xEventsSupplier,const Any & Helper)218     void SAL_CALL DialogEventsAttacherImpl::attachEventsToControl( const Reference< XControl>& xControl, const Reference< XScriptEventsSupplier >& xEventsSupplier, const Any& Helper )
219     {
220         if ( xEventsSupplier.is() )
221         {
222             Reference< container::XNameContainer > xEventCont = xEventsSupplier->getEvents();
223 
224             Reference< XControlModel > xControlModel = xControl->getModel();
225             if ( xEventCont.is() )
226             {
227                 Sequence< ::rtl::OUString > aNames = xEventCont->getElementNames();
228                 const ::rtl::OUString* pNames = aNames.getConstArray();
229                 sal_Int32 nNameCount = aNames.getLength();
230 
231                 for ( sal_Int32 j = 0; j < nNameCount; ++j )
232                 {
233                     ScriptEventDescriptor aDesc;
234 
235                     Any aElement = xEventCont->getByName( pNames[ j ] );
236                     aElement >>= aDesc;
237                     rtl::OUString sKey = aDesc.ScriptType;
238                     if ( aDesc.ScriptType.equals( rtl::OUString::createFromAscii("Script" ) ) || aDesc.ScriptType.equals( rtl::OUString::createFromAscii("UNO" ) ) )
239                     {
240                         sal_Int32 nIndex = aDesc.ScriptCode.indexOf( ':' );
241                         sKey = aDesc.ScriptCode.copy( 0, nIndex );
242                     }
243                     Reference< XAllListener > xAllListener =
244                         new DialogAllListenerImpl( getScriptListenerForKey( sKey ), aDesc.ScriptType, aDesc.ScriptCode );
245 
246                     // try first to attach event to the ControlModel
247                     bool bSuccess = false;
248                     try
249                     {
250                         Reference< XEventListener > xListener_ = m_xEventAttacher->attachSingleEventListener(
251                             xControlModel, xAllListener, Helper, aDesc.ListenerType,
252                             aDesc.AddListenerParam, aDesc.EventMethod );
253 
254                         if ( xListener_.is() )
255                             bSuccess = true;
256                     }
257                     catch ( const Exception& )
258                     {
259                         DBG_UNHANDLED_EXCEPTION();
260                     }
261 
262                     try
263                     {
264                         // if we had no success, try to attach to the control
265                         if ( !bSuccess )
266                         {
267                             Reference< XEventListener > xListener_ = m_xEventAttacher->attachSingleEventListener(
268                                 xControl, xAllListener, Helper, aDesc.ListenerType,
269                                 aDesc.AddListenerParam, aDesc.EventMethod );
270                         }
271                     }
272                     catch ( const Exception& )
273                     {
274                         DBG_UNHANDLED_EXCEPTION();
275                     }
276                 }
277             }
278         }
279     }
280 
281     // -----------------------------------------------------------------------------
282     // XScriptEventsAttacher
283     // -----------------------------------------------------------------------------
284 
attachEvents(const Sequence<Reference<XInterface>> & Objects,const com::sun::star::uno::Reference<com::sun::star::script::XScriptListener> &,const Any & Helper)285     void SAL_CALL DialogEventsAttacherImpl::attachEvents( const Sequence< Reference< XInterface > >& Objects,
286         const com::sun::star::uno::Reference<com::sun::star::script::XScriptListener>&,
287         const Any& Helper )
288         throw (IllegalArgumentException, IntrospectionException, CannotCreateAdapterException,
289                ServiceNotRegisteredException, RuntimeException)
290     {
291         // get EventAttacher
292         {
293             ::osl::MutexGuard aGuard( getMutex() );
294 
295             if ( !m_xEventAttacher.is() )
296             {
297                 Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
298                 if ( xSMgr.is() )
299                 {
300                     m_xEventAttacher = Reference< XEventAttacher >( xSMgr->createInstanceWithContext(
301                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.EventAttacher" ) ), m_xContext ), UNO_QUERY );
302 
303                     if ( !m_xEventAttacher.is() )
304                         throw ServiceNotRegisteredException();
305                 }
306                 else
307                 {
308                     throw RuntimeException();
309                 }
310 
311             }
312         }
313 
314         // go over all objects
315         const Reference< XInterface >* pObjects = Objects.getConstArray();
316         sal_Int32 nObjCount = Objects.getLength();
317         Reference< awt::XControl > xDlgControl( Objects[ nObjCount - 1 ], uno::UNO_QUERY ); // last object is the dialog
318         rtl::OUString sDialogCodeName;
319         if ( xDlgControl.is() )
320         {
321             Reference< XPropertySet > xProps( xDlgControl->getModel(), UNO_QUERY );
322             try
323             {
324                 xProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= sDialogCodeName;
325             }
326             catch( Exception& ){}
327         }
328 
329         for ( sal_Int32 i = 0; i < nObjCount; ++i )
330         {
331             // We know that we have to do with instances of XControl.
332             // Otherwise this is not the right implementation for
333             // XScriptEventsAttacher and we have to give up.
334             Reference< XControl > xControl( pObjects[ i ], UNO_QUERY );
335             if ( !xControl.is() )
336                 throw IllegalArgumentException();
337 
338             // get XEventsSupplier from control model
339             Reference< XControlModel > xControlModel = xControl->getModel();
340             Reference< XScriptEventsSupplier > xEventsSupplier( xControlModel, UNO_QUERY );
341             attachEventsToControl( xControl, xEventsSupplier, Helper );
342             if ( mbUseFakeVBAEvents )
343             {
344                 xEventsSupplier.set( getFakeVbaEventsSupplier( xControl, sDialogCodeName ) );
345                 attachEventsToControl( xControl, xEventsSupplier, Helper );
346             }
347         }
348     }
349 
350 
351     // =============================================================================
352     // DialogAllListenerImpl
353     // =============================================================================
354 
DialogAllListenerImpl(const Reference<XScriptListener> & rxListener,const::rtl::OUString & rScriptType,const::rtl::OUString & rScriptCode)355     DialogAllListenerImpl::DialogAllListenerImpl( const Reference< XScriptListener >& rxListener,
356         const ::rtl::OUString& rScriptType, const ::rtl::OUString& rScriptCode )
357         :m_xScriptListener( rxListener )
358         ,m_sScriptType( rScriptType )
359         ,m_sScriptCode( rScriptCode )
360     {
361     }
362 
363     // -----------------------------------------------------------------------------
364 
~DialogAllListenerImpl()365     DialogAllListenerImpl::~DialogAllListenerImpl()
366     {
367     }
368 
369     // -----------------------------------------------------------------------------
370 
firing_impl(const AllEventObject & Event,Any * pRet)371     void DialogAllListenerImpl::firing_impl( const AllEventObject& Event, Any* pRet )
372     {
373         ScriptEvent aScriptEvent;
374         aScriptEvent.Source         = (OWeakObject *)this;  // get correct XInterface
375         aScriptEvent.ListenerType   = Event.ListenerType;
376         aScriptEvent.MethodName     = Event.MethodName;
377         aScriptEvent.Arguments      = Event.Arguments;
378         aScriptEvent.Helper         = Event.Helper;
379         aScriptEvent.ScriptType     = m_sScriptType;
380         aScriptEvent.ScriptCode     = m_sScriptCode;
381 
382         if ( m_xScriptListener.is() )
383         {
384             if ( pRet )
385                 *pRet = m_xScriptListener->approveFiring( aScriptEvent );
386             else
387                 m_xScriptListener->firing( aScriptEvent );
388         }
389     }
390 
391     // -----------------------------------------------------------------------------
392     // XEventListener
393     // -----------------------------------------------------------------------------
394 
disposing(const EventObject &)395     void DialogAllListenerImpl::disposing(const EventObject& ) throw ( RuntimeException )
396     {
397     }
398 
399     // -----------------------------------------------------------------------------
400     // XAllListener
401     // -----------------------------------------------------------------------------
402 
firing(const AllEventObject & Event)403     void DialogAllListenerImpl::firing( const AllEventObject& Event ) throw ( RuntimeException )
404     {
405         ::osl::MutexGuard aGuard( getMutex() );
406 
407         firing_impl( Event, NULL );
408     }
409 
410     // -----------------------------------------------------------------------------
411 
approveFiring(const AllEventObject & Event)412     Any DialogAllListenerImpl::approveFiring( const AllEventObject& Event )
413         throw ( reflection::InvocationTargetException, RuntimeException )
414     {
415         ::osl::MutexGuard aGuard( getMutex() );
416 
417         Any aReturn;
418         firing_impl( Event, &aReturn );
419         return aReturn;
420     }
421 
422 
423     // =============================================================================
424     // DialogScriptListenerImpl
425     // =============================================================================
426 
DialogUnoScriptListenerImpl(const Reference<XComponentContext> & rxContext,const Reference<::com::sun::star::frame::XModel> & rxModel,const Reference<::com::sun::star::awt::XControl> & rxControl,const Reference<::com::sun::star::uno::XInterface> & rxHandler,const Reference<::com::sun::star::beans::XIntrospectionAccess> & rxIntrospectionAccess,bool bDialogProviderMode)427     DialogUnoScriptListenerImpl::DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext,
428             const Reference< ::com::sun::star::frame::XModel >& rxModel,
429 			const Reference< ::com::sun::star::awt::XControl >& rxControl,
430 			const Reference< ::com::sun::star::uno::XInterface >& rxHandler,
431 			const Reference< ::com::sun::star::beans::XIntrospectionAccess >& rxIntrospectionAccess,
432 			bool bDialogProviderMode )
433         : DialogSFScriptListenerImpl( rxContext, rxModel )
434         ,m_xControl( rxControl )
435         ,m_xHandler( rxHandler )
436         ,m_xIntrospectionAccess( rxIntrospectionAccess )
437 		,m_bDialogProviderMode( bDialogProviderMode )
438     {
439     }
440 
441     // -----------------------------------------------------------------------------
442 
~DialogScriptListenerImpl()443     DialogScriptListenerImpl::~DialogScriptListenerImpl()
444     {
445     }
446 
447     // -----------------------------------------------------------------------------
firing_impl(const ScriptEvent & aScriptEvent,Any * pRet)448     void DialogSFScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
449     {
450         try
451         {
452             Reference< provider::XScriptProvider > xScriptProvider;
453             if ( m_xModel.is() )
454             {
455                 Reference< provider::XScriptProviderSupplier > xSupplier( m_xModel, UNO_QUERY );
456                 OSL_ENSURE( xSupplier.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider supplier" );
457                 if ( xSupplier.is() )
458                     xScriptProvider.set( xSupplier->getScriptProvider() );
459             }
460             else
461             {
462                 OSL_ASSERT( m_xContext.is() );
463                 if ( m_xContext.is() )
464                 {
465                     Reference< provider::XScriptProviderFactory > xFactory(
466                         m_xContext->getValueByName(
467                         ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory" ) ),
468                         UNO_QUERY );
469                     OSL_ENSURE( xFactory.is(), "SFURL_firing_impl: failed to get master script provider factory" );
470                     if ( xFactory.is() )
471                     {
472                         Any aCtx;
473                         aCtx <<= ::rtl::OUString::createFromAscii( "user" );
474                         xScriptProvider.set( xFactory->createScriptProvider( aCtx ), UNO_QUERY );
475                     }
476                 }
477             }
478 
479             OSL_ENSURE( xScriptProvider.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider" );
480 
481             if ( xScriptProvider.is() )
482             {
483                 Reference< provider::XScript > xScript = xScriptProvider->getScript( aScriptEvent.ScriptCode );
484                 OSL_ENSURE( xScript.is(), "DialogScriptListenerImpl::firing_impl: failed to get script" );
485 
486                 if ( xScript.is() )
487                 {
488                     Sequence< Any > aInParams;
489                     Sequence< sal_Int16 > aOutParamsIndex;
490                     Sequence< Any > aOutParams;
491 
492                     // get arguments for script
493                     aInParams = aScriptEvent.Arguments;
494 
495                     Any aResult = xScript->invoke( aInParams, aOutParamsIndex, aOutParams );
496                     if ( pRet )
497                         *pRet = aResult;
498                 }
499             }
500         }
501         catch ( const Exception& )
502         {
503             DBG_UNHANDLED_EXCEPTION();
504         }
505     }
506 
firing_impl(const ScriptEvent & aScriptEvent,Any * pRet)507     void DialogLegacyScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
508     {
509         ::rtl::OUString sScriptURL;
510         ::rtl::OUString sScriptCode( aScriptEvent.ScriptCode );
511 
512 	    if ( aScriptEvent.ScriptType.compareToAscii( "StarBasic" ) == 0 )
513 	    {
514 		    // StarBasic script: convert ScriptCode to scriptURL
515 		    sal_Int32 nIndex = sScriptCode.indexOf( ':' );
516 		    if ( nIndex >= 0 && nIndex < sScriptCode.getLength() )
517 		    {
518 			    sScriptURL = ::rtl::OUString::createFromAscii( "vnd.sun.star.script:" );
519 			    sScriptURL += sScriptCode.copy( nIndex + 1 );
520 			    sScriptURL += ::rtl::OUString::createFromAscii( "?language=Basic&location=" );
521 			    sScriptURL += sScriptCode.copy( 0, nIndex );
522 		    }
523 		    ScriptEvent aSFScriptEvent( aScriptEvent );
524 		    aSFScriptEvent.ScriptCode = sScriptURL;
525 		    DialogSFScriptListenerImpl::firing_impl( aSFScriptEvent, pRet );
526 	    }
527     }
528 
firing_impl(const ScriptEvent & aScriptEvent,Any * pRet)529 	void DialogUnoScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
530 	{
531 		static ::rtl::OUString sUnoURLScheme = ::rtl::OUString::createFromAscii( "vnd.sun.star.UNO:" );
532 
533         ::rtl::OUString sScriptCode( aScriptEvent.ScriptCode );
534 		::rtl::OUString aMethodName = aScriptEvent.ScriptCode.copy( sUnoURLScheme.getLength() );
535 
536 		const Any* pArguments = aScriptEvent.Arguments.getConstArray();
537 		Any aEventObject = pArguments[0];
538 
539 		bool bHandled = false;
540 		if( m_xHandler.is() )
541 		{
542 			if( m_bDialogProviderMode )
543 			{
544 				Reference< XDialogEventHandler > xDialogEventHandler( m_xHandler, UNO_QUERY );
545 				if( xDialogEventHandler.is() )
546 				{
547 					Reference< XDialog > xDialog( m_xControl, UNO_QUERY );
548 					bHandled = xDialogEventHandler->callHandlerMethod( xDialog, aEventObject, aMethodName );
549 				}
550 			}
551 			else
552 			{
553 				Reference< XContainerWindowEventHandler > xContainerWindowEventHandler( m_xHandler, UNO_QUERY );
554 				if( xContainerWindowEventHandler.is() )
555 				{
556 					Reference< XWindow > xWindow( m_xControl, UNO_QUERY );
557 					bHandled = xContainerWindowEventHandler->callHandlerMethod( xWindow, aEventObject, aMethodName );
558 				}
559 			}
560 		}
561 
562 		Any aRet;
563 		if( !bHandled && m_xIntrospectionAccess.is() )
564 		{
565 			try
566 			{
567 				// Methode ansprechen
568 				const Reference< XIdlMethod >& rxMethod = m_xIntrospectionAccess->
569 					getMethod( aMethodName, MethodConcept::ALL - MethodConcept::DANGEROUS );
570 
571 				Reference< XMaterialHolder > xMaterialHolder =
572 					Reference< XMaterialHolder >::query( m_xIntrospectionAccess );
573 				Any aHandlerObject = xMaterialHolder->getMaterial();
574 
575 				Sequence< Reference< XIdlClass > > aParamTypeSeq = rxMethod->getParameterTypes();
576 		        sal_Int32 nParamCount = aParamTypeSeq.getLength();
577 				if( nParamCount == 0 )
578 				{
579 					Sequence<Any> args;
580 					rxMethod->invoke( aHandlerObject, args );
581 					bHandled = true;
582 				}
583 				else if( nParamCount == 2 )
584 				{
585 					// Signature check automatically done by reflection
586 					Sequence<Any> Args(2);
587 					Any* pArgs = Args.getArray();
588 					if( m_bDialogProviderMode )
589 					{
590 						Reference< XDialog > xDialog( m_xControl, UNO_QUERY );
591 						pArgs[0] <<= xDialog;
592 					}
593 					else
594 					{
595 						Reference< XWindow > xWindow( m_xControl, UNO_QUERY );
596 						pArgs[0] <<= xWindow;
597 					}
598 					pArgs[1] = aEventObject;
599 					aRet = rxMethod->invoke( aHandlerObject, Args );
600 					bHandled = true;
601 				}
602 			}
603             catch( const Exception& )
604             {
605             	DBG_UNHANDLED_EXCEPTION();
606             }
607 		}
608 
609 		if( bHandled )
610 		{
611 			if( pRet )
612 				*pRet = aRet;
613 		}
614 		else
615 		{
616 			ResMgr* pResMgr = SFX_APP()->GetSfxResManager();
617 			if( pResMgr )
618 			{
619 			    String aRes( ResId(STR_ERRUNOEVENTBINDUNG, *pResMgr) );
620 				::rtl::OUString aQuoteChar( RTL_CONSTASCII_USTRINGPARAM( "\"" ) );
621 
622                 ::rtl::OUString aOURes = aRes;
623 				sal_Int32 nIndex = aOURes.indexOf( '%' );
624 
625                 ::rtl::OUString aOUFinal;
626 				aOUFinal += aOURes.copy( 0, nIndex );
627 				aOUFinal += aQuoteChar;
628 				aOUFinal += aMethodName;
629 				aOUFinal += aQuoteChar;
630 				aOUFinal += aOURes.copy( nIndex + 2 );
631 
632 				ErrorBox( NULL, WinBits( WB_OK ), aOUFinal ).Execute();
633 			}
634 		}
635 	}
636 
637     // -----------------------------------------------------------------------------
638     // XEventListener
639     // -----------------------------------------------------------------------------
640 
disposing(const EventObject &)641     void DialogScriptListenerImpl::disposing(const EventObject& ) throw ( RuntimeException )
642     {
643     }
644 
645     // -----------------------------------------------------------------------------
646     // XScriptListener
647     // -----------------------------------------------------------------------------
648 
firing(const ScriptEvent & aScriptEvent)649     void DialogScriptListenerImpl::firing( const ScriptEvent& aScriptEvent ) throw ( RuntimeException )
650     {
651         ::osl::MutexGuard aGuard( getMutex() );
652 
653         firing_impl( aScriptEvent, NULL );
654     }
655 
656     // -----------------------------------------------------------------------------
657 
approveFiring(const ScriptEvent & aScriptEvent)658     Any DialogScriptListenerImpl::approveFiring( const ScriptEvent& aScriptEvent )
659         throw ( reflection::InvocationTargetException, RuntimeException )
660     {
661         ::osl::MutexGuard aGuard( getMutex() );
662 
663         Any aReturn;
664         firing_impl( aScriptEvent, &aReturn );
665         return aReturn;
666     }
667 
668     // -----------------------------------------------------------------------------
669 
670 //.........................................................................
671 }	// namespace dlgprov
672 //.........................................................................
673