xref: /trunk/main/scripting/source/dlgprov/dlgevtatt.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 )
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     {
289         // get EventAttacher
290         {
291             ::osl::MutexGuard aGuard( getMutex() );
292 
293             if ( !m_xEventAttacher.is() )
294             {
295                 Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
296                 if ( xSMgr.is() )
297                 {
298                     m_xEventAttacher = Reference< XEventAttacher >( xSMgr->createInstanceWithContext(
299                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.EventAttacher" ) ), m_xContext ), UNO_QUERY );
300 
301                     if ( !m_xEventAttacher.is() )
302                         throw ServiceNotRegisteredException();
303                 }
304                 else
305                 {
306                     throw RuntimeException();
307                 }
308 
309             }
310         }
311 
312         // go over all objects
313         const Reference< XInterface >* pObjects = Objects.getConstArray();
314         sal_Int32 nObjCount = Objects.getLength();
315         Reference< awt::XControl > xDlgControl( Objects[ nObjCount - 1 ], uno::UNO_QUERY ); // last object is the dialog
316         rtl::OUString sDialogCodeName;
317         if ( xDlgControl.is() )
318         {
319             Reference< XPropertySet > xProps( xDlgControl->getModel(), UNO_QUERY );
320             try
321             {
322                 xProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= sDialogCodeName;
323             }
324             catch( Exception& ){}
325         }
326 
327         for ( sal_Int32 i = 0; i < nObjCount; ++i )
328         {
329             // We know that we have to do with instances of XControl.
330             // Otherwise this is not the right implementation for
331             // XScriptEventsAttacher and we have to give up.
332             Reference< XControl > xControl( pObjects[ i ], UNO_QUERY );
333             if ( !xControl.is() )
334                 throw IllegalArgumentException();
335 
336             // get XEventsSupplier from control model
337             Reference< XControlModel > xControlModel = xControl->getModel();
338             Reference< XScriptEventsSupplier > xEventsSupplier( xControlModel, UNO_QUERY );
339             attachEventsToControl( xControl, xEventsSupplier, Helper );
340             if ( mbUseFakeVBAEvents )
341             {
342                 xEventsSupplier.set( getFakeVbaEventsSupplier( xControl, sDialogCodeName ) );
343                 attachEventsToControl( xControl, xEventsSupplier, Helper );
344             }
345         }
346     }
347 
348 
349     // =============================================================================
350     // DialogAllListenerImpl
351     // =============================================================================
352 
DialogAllListenerImpl(const Reference<XScriptListener> & rxListener,const::rtl::OUString & rScriptType,const::rtl::OUString & rScriptCode)353     DialogAllListenerImpl::DialogAllListenerImpl( const Reference< XScriptListener >& rxListener,
354         const ::rtl::OUString& rScriptType, const ::rtl::OUString& rScriptCode )
355         :m_xScriptListener( rxListener )
356         ,m_sScriptType( rScriptType )
357         ,m_sScriptCode( rScriptCode )
358     {
359     }
360 
361     // -----------------------------------------------------------------------------
362 
~DialogAllListenerImpl()363     DialogAllListenerImpl::~DialogAllListenerImpl()
364     {
365     }
366 
367     // -----------------------------------------------------------------------------
368 
firing_impl(const AllEventObject & Event,Any * pRet)369     void DialogAllListenerImpl::firing_impl( const AllEventObject& Event, Any* pRet )
370     {
371         ScriptEvent aScriptEvent;
372         aScriptEvent.Source         = (OWeakObject *)this;  // get correct XInterface
373         aScriptEvent.ListenerType   = Event.ListenerType;
374         aScriptEvent.MethodName     = Event.MethodName;
375         aScriptEvent.Arguments      = Event.Arguments;
376         aScriptEvent.Helper         = Event.Helper;
377         aScriptEvent.ScriptType     = m_sScriptType;
378         aScriptEvent.ScriptCode     = m_sScriptCode;
379 
380         if ( m_xScriptListener.is() )
381         {
382             if ( pRet )
383                 *pRet = m_xScriptListener->approveFiring( aScriptEvent );
384             else
385                 m_xScriptListener->firing( aScriptEvent );
386         }
387     }
388 
389     // -----------------------------------------------------------------------------
390     // XEventListener
391     // -----------------------------------------------------------------------------
392 
disposing(const EventObject &)393     void DialogAllListenerImpl::disposing(const EventObject& )
394     {
395     }
396 
397     // -----------------------------------------------------------------------------
398     // XAllListener
399     // -----------------------------------------------------------------------------
400 
firing(const AllEventObject & Event)401     void DialogAllListenerImpl::firing( const AllEventObject& Event )
402     {
403         ::osl::MutexGuard aGuard( getMutex() );
404 
405         firing_impl( Event, NULL );
406     }
407 
408     // -----------------------------------------------------------------------------
409 
approveFiring(const AllEventObject & Event)410     Any DialogAllListenerImpl::approveFiring( const AllEventObject& Event )
411     {
412         ::osl::MutexGuard aGuard( getMutex() );
413 
414         Any aReturn;
415         firing_impl( Event, &aReturn );
416         return aReturn;
417     }
418 
419 
420     // =============================================================================
421     // DialogScriptListenerImpl
422     // =============================================================================
423 
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)424     DialogUnoScriptListenerImpl::DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext,
425             const Reference< ::com::sun::star::frame::XModel >& rxModel,
426             const Reference< ::com::sun::star::awt::XControl >& rxControl,
427             const Reference< ::com::sun::star::uno::XInterface >& rxHandler,
428             const Reference< ::com::sun::star::beans::XIntrospectionAccess >& rxIntrospectionAccess,
429             bool bDialogProviderMode )
430         : DialogSFScriptListenerImpl( rxContext, rxModel )
431         ,m_xControl( rxControl )
432         ,m_xHandler( rxHandler )
433         ,m_xIntrospectionAccess( rxIntrospectionAccess )
434         ,m_bDialogProviderMode( bDialogProviderMode )
435     {
436     }
437 
438     // -----------------------------------------------------------------------------
439 
~DialogScriptListenerImpl()440     DialogScriptListenerImpl::~DialogScriptListenerImpl()
441     {
442     }
443 
444     // -----------------------------------------------------------------------------
firing_impl(const ScriptEvent & aScriptEvent,Any * pRet)445     void DialogSFScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
446     {
447         try
448         {
449             Reference< provider::XScriptProvider > xScriptProvider;
450             if ( m_xModel.is() )
451             {
452                 Reference< provider::XScriptProviderSupplier > xSupplier( m_xModel, UNO_QUERY );
453                 OSL_ENSURE( xSupplier.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider supplier" );
454                 if ( xSupplier.is() )
455                     xScriptProvider.set( xSupplier->getScriptProvider() );
456             }
457             else
458             {
459                 OSL_ASSERT( m_xContext.is() );
460                 if ( m_xContext.is() )
461                 {
462                     Reference< provider::XScriptProviderFactory > xFactory(
463                         m_xContext->getValueByName(
464                         ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory" ) ),
465                         UNO_QUERY );
466                     OSL_ENSURE( xFactory.is(), "SFURL_firing_impl: failed to get master script provider factory" );
467                     if ( xFactory.is() )
468                     {
469                         Any aCtx;
470                         aCtx <<= ::rtl::OUString::createFromAscii( "user" );
471                         xScriptProvider.set( xFactory->createScriptProvider( aCtx ), UNO_QUERY );
472                     }
473                 }
474             }
475 
476             OSL_ENSURE( xScriptProvider.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider" );
477 
478             if ( xScriptProvider.is() )
479             {
480                 Reference< provider::XScript > xScript = xScriptProvider->getScript( aScriptEvent.ScriptCode );
481                 OSL_ENSURE( xScript.is(), "DialogScriptListenerImpl::firing_impl: failed to get script" );
482 
483                 if ( xScript.is() )
484                 {
485                     Sequence< Any > aInParams;
486                     Sequence< sal_Int16 > aOutParamsIndex;
487                     Sequence< Any > aOutParams;
488 
489                     // get arguments for script
490                     aInParams = aScriptEvent.Arguments;
491 
492                     Any aResult = xScript->invoke( aInParams, aOutParamsIndex, aOutParams );
493                     if ( pRet )
494                         *pRet = aResult;
495                 }
496             }
497         }
498         catch ( const Exception& )
499         {
500             DBG_UNHANDLED_EXCEPTION();
501         }
502     }
503 
firing_impl(const ScriptEvent & aScriptEvent,Any * pRet)504     void DialogLegacyScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
505     {
506         ::rtl::OUString sScriptURL;
507         ::rtl::OUString sScriptCode( aScriptEvent.ScriptCode );
508 
509         if ( aScriptEvent.ScriptType.compareToAscii( "StarBasic" ) == 0 )
510         {
511             // StarBasic script: convert ScriptCode to scriptURL
512             sal_Int32 nIndex = sScriptCode.indexOf( ':' );
513             if ( nIndex >= 0 && nIndex < sScriptCode.getLength() )
514             {
515                 sScriptURL = ::rtl::OUString::createFromAscii( "vnd.sun.star.script:" );
516                 sScriptURL += sScriptCode.copy( nIndex + 1 );
517                 sScriptURL += ::rtl::OUString::createFromAscii( "?language=Basic&location=" );
518                 sScriptURL += sScriptCode.copy( 0, nIndex );
519             }
520             ScriptEvent aSFScriptEvent( aScriptEvent );
521             aSFScriptEvent.ScriptCode = sScriptURL;
522             DialogSFScriptListenerImpl::firing_impl( aSFScriptEvent, pRet );
523         }
524     }
525 
firing_impl(const ScriptEvent & aScriptEvent,Any * pRet)526     void DialogUnoScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
527     {
528         static ::rtl::OUString sUnoURLScheme = ::rtl::OUString::createFromAscii( "vnd.sun.star.UNO:" );
529 
530         ::rtl::OUString sScriptCode( aScriptEvent.ScriptCode );
531         ::rtl::OUString aMethodName = aScriptEvent.ScriptCode.copy( sUnoURLScheme.getLength() );
532 
533         const Any* pArguments = aScriptEvent.Arguments.getConstArray();
534         Any aEventObject = pArguments[0];
535 
536         bool bHandled = false;
537         if( m_xHandler.is() )
538         {
539             if( m_bDialogProviderMode )
540             {
541                 Reference< XDialogEventHandler > xDialogEventHandler( m_xHandler, UNO_QUERY );
542                 if( xDialogEventHandler.is() )
543                 {
544                     Reference< XDialog > xDialog( m_xControl, UNO_QUERY );
545                     bHandled = xDialogEventHandler->callHandlerMethod( xDialog, aEventObject, aMethodName );
546                 }
547             }
548             else
549             {
550                 Reference< XContainerWindowEventHandler > xContainerWindowEventHandler( m_xHandler, UNO_QUERY );
551                 if( xContainerWindowEventHandler.is() )
552                 {
553                     Reference< XWindow > xWindow( m_xControl, UNO_QUERY );
554                     bHandled = xContainerWindowEventHandler->callHandlerMethod( xWindow, aEventObject, aMethodName );
555                 }
556             }
557         }
558 
559         Any aRet;
560         if( !bHandled && m_xIntrospectionAccess.is() )
561         {
562             try
563             {
564                 // Methode ansprechen
565                 const Reference< XIdlMethod >& rxMethod = m_xIntrospectionAccess->
566                     getMethod( aMethodName, MethodConcept::ALL - MethodConcept::DANGEROUS );
567 
568                 Reference< XMaterialHolder > xMaterialHolder =
569                     Reference< XMaterialHolder >::query( m_xIntrospectionAccess );
570                 Any aHandlerObject = xMaterialHolder->getMaterial();
571 
572                 Sequence< Reference< XIdlClass > > aParamTypeSeq = rxMethod->getParameterTypes();
573                 sal_Int32 nParamCount = aParamTypeSeq.getLength();
574                 if( nParamCount == 0 )
575                 {
576                     Sequence<Any> args;
577                     rxMethod->invoke( aHandlerObject, args );
578                     bHandled = true;
579                 }
580                 else if( nParamCount == 2 )
581                 {
582                     // Signature check automatically done by reflection
583                     Sequence<Any> Args(2);
584                     Any* pArgs = Args.getArray();
585                     if( m_bDialogProviderMode )
586                     {
587                         Reference< XDialog > xDialog( m_xControl, UNO_QUERY );
588                         pArgs[0] <<= xDialog;
589                     }
590                     else
591                     {
592                         Reference< XWindow > xWindow( m_xControl, UNO_QUERY );
593                         pArgs[0] <<= xWindow;
594                     }
595                     pArgs[1] = aEventObject;
596                     aRet = rxMethod->invoke( aHandlerObject, Args );
597                     bHandled = true;
598                 }
599             }
600             catch( const Exception& )
601             {
602                 DBG_UNHANDLED_EXCEPTION();
603             }
604         }
605 
606         if( bHandled )
607         {
608             if( pRet )
609                 *pRet = aRet;
610         }
611         else
612         {
613             ResMgr* pResMgr = SFX_APP()->GetSfxResManager();
614             if( pResMgr )
615             {
616                 String aRes( ResId(STR_ERRUNOEVENTBINDUNG, *pResMgr) );
617                 ::rtl::OUString aQuoteChar( RTL_CONSTASCII_USTRINGPARAM( "\"" ) );
618 
619                 ::rtl::OUString aOURes = aRes;
620                 sal_Int32 nIndex = aOURes.indexOf( '%' );
621 
622                 ::rtl::OUString aOUFinal;
623                 aOUFinal += aOURes.copy( 0, nIndex );
624                 aOUFinal += aQuoteChar;
625                 aOUFinal += aMethodName;
626                 aOUFinal += aQuoteChar;
627                 aOUFinal += aOURes.copy( nIndex + 2 );
628 
629                 ErrorBox( NULL, WinBits( WB_OK ), aOUFinal ).Execute();
630             }
631         }
632     }
633 
634     // -----------------------------------------------------------------------------
635     // XEventListener
636     // -----------------------------------------------------------------------------
637 
disposing(const EventObject &)638     void DialogScriptListenerImpl::disposing(const EventObject& )
639     {
640     }
641 
642     // -----------------------------------------------------------------------------
643     // XScriptListener
644     // -----------------------------------------------------------------------------
645 
firing(const ScriptEvent & aScriptEvent)646     void DialogScriptListenerImpl::firing( const ScriptEvent& aScriptEvent )
647     {
648         ::osl::MutexGuard aGuard( getMutex() );
649 
650         firing_impl( aScriptEvent, NULL );
651     }
652 
653     // -----------------------------------------------------------------------------
654 
approveFiring(const ScriptEvent & aScriptEvent)655     Any DialogScriptListenerImpl::approveFiring( const ScriptEvent& aScriptEvent )
656     {
657         ::osl::MutexGuard aGuard( getMutex() );
658 
659         Any aReturn;
660         firing_impl( aScriptEvent, &aReturn );
661         return aReturn;
662     }
663 
664     // -----------------------------------------------------------------------------
665 
666 //.........................................................................
667 }   // namespace dlgprov
668 //.........................................................................
669