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 <comphelper/processfactory.hxx>
27 #include <comphelper/uno3.hxx>
28 #include <comphelper/proparrhlp.hxx>
29 #include <comphelper/propertycontainer.hxx>
30
31 #include <ooo/vba/XVBAToOOEventDescGen.hpp>
32
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/XIntrospection.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36
37 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
38 #include <com/sun/star/lang/XServiceName.hpp>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/lang/XInitialization.hpp>
41
42 #include <com/sun/star/util/XCloseListener.hpp>
43 #include <com/sun/star/util/XCloseBroadcaster.hpp>
44
45 #include <com/sun/star/frame/XModel.hpp>
46
47 #include <com/sun/star/script/XLibraryContainer.hpp>
48 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
49 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
50
51 #include <com/sun/star/drawing/XControlShape.hpp>
52
53 #include <com/sun/star/awt/XControl.hpp>
54 #include <com/sun/star/awt/XDialog.hpp>
55 #include <com/sun/star/awt/KeyEvent.hpp>
56 #include <com/sun/star/awt/MouseEvent.hpp>
57 #include <com/sun/star/awt/XFixedText.hpp> //liuchen 2009-6-5
58 #include <com/sun/star/awt/XTextComponent.hpp> //liuchen 2009-6-5
59 #include <com/sun/star/awt/XComboBox.hpp> //liuchen 2009-6-18
60 #include <com/sun/star/awt/XRadioButton.hpp> //liuchen 2009-7-30
61
62 #include <msforms/ReturnInteger.hpp>
63
64 #include <sfx2/objsh.hxx>
65 #include <basic/sbstar.hxx>
66 #include <basic/basmgr.hxx>
67 #include <basic/sbmeth.hxx>
68 #include <basic/sbmod.hxx>
69 #include <basic/sbx.hxx>
70
71
72
73
74 // for debug
75 #include <comphelper/anytostring.hxx>
76
77
78 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
79 #include <com/sun/star/script/XScriptListener.hpp>
80 #include <cppuhelper/implbase1.hxx>
81 #include <cppuhelper/implbase3.hxx>
82 #include <comphelper/evtmethodhelper.hxx>
83
84 #include <set>
85 #include <list>
86 #include <hash_map>
87
88 using namespace ::com::sun::star;
89 using namespace ::com::sun::star::script;
90 using namespace ::com::sun::star::uno;
91 using namespace ::ooo::vba;
92
93 #define MAP_CHAR_LEN(x) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x))//liuchen 2009-6-8
94 #define GET_TYPE(x) ::getCppuType((uno::Reference< x > *)0);
95
96 // Some constants
97 const static rtl::OUString DELIM = rtl::OUString::createFromAscii( "::" );
98 const static sal_Int32 DELIMLEN = DELIM.getLength();
99
100 #if 0
101 void dumpListeners( const Reference< beans::XIntrospection >& xIntrospection, const Reference<XInterface>& xIfc)
102 {
103 Reference< beans::XIntrospectionAccess > xIntrospectionAccess;
104 if ( xIntrospection.is() )
105 {
106 xIntrospectionAccess = xIntrospection->inspect(
107 makeAny( xIfc ) );
108 Sequence< Type > aControlListeners =
109 xIntrospectionAccess->getSupportedListeners();
110 sal_Int32 nLength = aControlListeners.getLength();
111
112 for ( sal_Int32 i = 0; i< nLength; ++i )
113 {
114 Type& listType = aControlListeners[ i ];
115 rtl::OUString sFullTypeName = listType.getTypeName();
116 rtl::OUString sTypeName = listType.getTypeName();
117 sal_Int32 lastDotIndex = -1;
118 if ( ( lastDotIndex = sFullTypeName.lastIndexOf( '.' ) ) > -1 )
119 {
120 sTypeName = sFullTypeName.copy( lastDotIndex + 1 );
121 }
122 Sequence< ::rtl::OUString > sMeths = comphelper::getEventMethodsForType( listType );
123 sal_Int32 sMethLen = sMeths.getLength();
124 for ( sal_Int32 j=0 ; j < sMethLen; ++j )
125 {
126 OSL_TRACE("**Listener [%d] Type[%s] Method[%s]",j,
127 rtl::OUStringToOString( sTypeName,
128 RTL_TEXTENCODING_UTF8 ).getStr(),
129 rtl::OUStringToOString( sMeths[ j ],
130 RTL_TEXTENCODING_UTF8 ).getStr() );
131 }
132 }
133
134 }
135 }
136
137 void dumpEvent( const ScriptEvent& evt )
138 {
139 OSL_TRACE("dumpEvent: Source %s",
140 rtl::OUStringToOString( comphelper::anyToString( makeAny(evt.Source)),
141 RTL_TEXTENCODING_UTF8 ).getStr() );
142
143 OSL_TRACE("dumpEvent: ScriptType %s",
144 rtl::OUStringToOString( evt.ScriptType,
145 RTL_TEXTENCODING_UTF8 ).getStr() );
146
147 OSL_TRACE("dumpEvent: ScriptCode %s",
148 rtl::OUStringToOString( evt.ScriptCode,
149 RTL_TEXTENCODING_UTF8 ).getStr() );
150
151 OSL_TRACE("dumpEvent: ListenerType %s",
152 rtl::OUStringToOString( evt.ListenerType.getTypeName(),
153 RTL_TEXTENCODING_UTF8 ).getStr() );
154
155 OSL_TRACE("dumpEvent: Listener methodname %s",
156 rtl::OUStringToOString( evt.MethodName,
157 RTL_TEXTENCODING_UTF8 ).getStr() );
158
159 OSL_TRACE("dumpEvent: arguments;");
160 sal_Int32 nLen = evt.Arguments.getLength();
161 for ( sal_Int32 index=0; index < nLen; ++index )
162 {
163 OSL_TRACE("\t [%d] %s", index,
164 rtl::OUStringToOString( comphelper::anyToString( evt.Arguments[ index ] ),
165 RTL_TEXTENCODING_UTF8 ).getStr() );
166
167 }
168 }
169
170 #endif
171
isKeyEventOk(awt::KeyEvent & evt,const Sequence<Any> & params)172 bool isKeyEventOk( awt::KeyEvent& evt, const Sequence< Any >& params )
173 {
174 if ( !( params.getLength() > 0 ) ||
175 !( params[ 0 ] >>= evt ) )
176 return false;
177 return true;
178 }
179
isMouseEventOk(awt::MouseEvent & evt,const Sequence<Any> & params)180 bool isMouseEventOk( awt::MouseEvent& evt, const Sequence< Any >& params )
181 {
182 if ( !( params.getLength() > 0 ) ||
183 !( params[ 0 ] >>= evt ) )
184 return false;
185 return true;
186 }
187
ooMouseEvtToVBADblClick(const Sequence<Any> & params)188 Sequence< Any > ooMouseEvtToVBADblClick( const Sequence< Any >& params )
189 {
190 Sequence< Any > translatedParams;
191 awt::MouseEvent evt;
192
193 if ( !( isMouseEventOk(evt, params)) ||
194 (evt.ClickCount != 2) )
195 return Sequence< Any >();
196 // give back orig params, this will signal that the event is good
197 return params;
198 }
199
ooMouseEvtToVBAMouseEvt(const Sequence<Any> & params)200 Sequence< Any > ooMouseEvtToVBAMouseEvt( const Sequence< Any >& params )
201 {
202 Sequence< Any > translatedParams;
203 awt::MouseEvent evt;
204
205 if ( !isMouseEventOk(evt, params) )
206 return Sequence< Any >();
207
208 translatedParams.realloc(4);
209
210 // Buttons
211 translatedParams[ 0 ] <<= evt.Buttons;
212 // Shift
213 translatedParams[ 1 ] <<= evt.Modifiers;
214 // X
215 translatedParams[ 2 ] <<= evt.X;
216 // Y
217 translatedParams[ 3 ] <<= evt.Y;
218 return translatedParams;
219 }
220
ooKeyPressedToVBAKeyPressed(const Sequence<Any> & params)221 Sequence< Any > ooKeyPressedToVBAKeyPressed( const Sequence< Any >& params )
222 {
223 Sequence< Any > translatedParams;
224 awt::KeyEvent evt;
225
226 if ( !isKeyEventOk( evt, params ) )
227 return Sequence< Any >();
228
229 translatedParams.realloc(1);
230
231 msforms::ReturnInteger keyCode;
232 keyCode.Value = evt.KeyCode;
233 translatedParams[0] <<= keyCode;
234 return translatedParams;
235 }
236
ooKeyPressedToVBAKeyUpDown(const Sequence<Any> & params)237 Sequence< Any > ooKeyPressedToVBAKeyUpDown( const Sequence< Any >& params )
238 {
239 Sequence< Any > translatedParams;
240 awt::KeyEvent evt;
241
242 if ( !isKeyEventOk( evt, params ) )
243 return Sequence< Any >();
244
245 translatedParams.realloc(2);
246
247 msforms::ReturnInteger keyCode;
248 sal_Int8 shift = sal::static_int_cast<sal_Int8>( evt.Modifiers );
249
250 // #TODO check whether values from OOO conform to values generated from vba
251 keyCode.Value = evt.KeyCode;
252 translatedParams[0] <<= keyCode;
253 translatedParams[1] <<= shift;
254 return translatedParams;
255 }
256
257 typedef Sequence< Any > (*Translator)(const Sequence< Any >&);
258
259 //liuchen 2009-6-23
260 //expand the "TranslateInfo" struct to support more kinds of events
261 struct TranslateInfo
262 {
263 rtl::OUString sVBAName; //vba event name
264 Translator toVBA; //the method to convert OO event parameters to VBA event parameters
265 bool (*ApproveRule)(const ScriptEvent& evt, void* pPara); //this method is used to determine which types of controls should execute the event
266 void *pPara; //Parameters for the above approve method
267 };
268
269
270 typedef std::hash_map< rtl::OUString,
271 std::list< TranslateInfo >,
272 ::rtl::OUStringHash,
273 ::std::equal_to< ::rtl::OUString > > EventInfoHash;
274
275 //liuchen 2009-6-23
276 struct TranslatePropMap
277 {
278 rtl::OUString sEventInfo; //OO event name
279 TranslateInfo aTransInfo;
280 };
281
282 bool ApproveAll(const ScriptEvent& evt, void* pPara); //allow all types of controls to execute the event
283 bool ApproveType(const ScriptEvent& evt, void* pPara); //certain types of controls should execute the event, those types are given by pPara
284 bool DenyType(const ScriptEvent& evt, void* pPara); //certain types of controls should not execute the event, those types are given by pPara
285 bool DenyMouseDrag(const ScriptEvent& evt, void* pPara); //used for VBA MouseMove event when "Shift" key is pressed
286
287 struct TypeList
288 {
289 uno::Type* pTypeList;
290 int nListLength;
291 };
292
293 Type typeXFixedText = GET_TYPE(awt::XFixedText)
294 Type typeXTextComponent = GET_TYPE(awt::XTextComponent)
295 Type typeXComboBox = GET_TYPE(awt::XComboBox)
296 Type typeXRadioButton = GET_TYPE(awt::XRadioButton)
297
298
299 TypeList fixedTextList = {&typeXFixedText, 1};
300 TypeList textCompList = {&typeXTextComponent, 1};
301 TypeList radioButtonList = {&typeXRadioButton, 1};
302 TypeList comboBoxList = {&typeXComboBox, 1};
303
304 //this array stores the OO event to VBA event translation info
305 static TranslatePropMap aTranslatePropMap_Impl[] =
306 {
307 // actionPerformed ooo event
308 { MAP_CHAR_LEN("actionPerformed"), { MAP_CHAR_LEN("_Click"), NULL, ApproveAll, NULL } },
309 { MAP_CHAR_LEN("actionPerformed"), { MAP_CHAR_LEN("_Change"), NULL, DenyType, (void*)(&radioButtonList) } }, //liuchen 2009-7-30, OptionalButton_Change event is not the same as OptionalButton_Click event
310
311 // itemStateChanged ooo event
312 { MAP_CHAR_LEN("itemStateChanged"), { MAP_CHAR_LEN("_Click"), NULL, ApproveType, (void*)(&comboBoxList) } }, //liuchen, add to support VBA ComboBox_Click event
313 { MAP_CHAR_LEN("itemStateChanged"), { MAP_CHAR_LEN("_Change"), NULL, ApproveType, (void*)(&radioButtonList) } }, //liuchen 2009-7-30, OptionalButton_Change event should be triggered when the button state is changed
314
315 // changed ooo event
316 { MAP_CHAR_LEN("changed"), { MAP_CHAR_LEN("_Change"), NULL, ApproveAll, NULL } },
317
318 // focusGained ooo event
319 { MAP_CHAR_LEN("focusGained"), { MAP_CHAR_LEN("_GotFocus"), NULL, ApproveAll, NULL } },
320
321 // focusLost ooo event
322 { MAP_CHAR_LEN("focusLost"), { MAP_CHAR_LEN("_LostFocus"), NULL, ApproveAll, NULL } },
323 { MAP_CHAR_LEN("focusLost"), { MAP_CHAR_LEN("_Exit"), NULL, ApproveType, (void*)(&textCompList) } }, //liuchen, add to support VBA TextBox_Exit event
324
325 // adjustmentValueChanged ooo event
326 { MAP_CHAR_LEN("adjustmentValueChanged"), { MAP_CHAR_LEN("_Scroll"), NULL, ApproveAll, NULL } },
327 { MAP_CHAR_LEN("adjustmentValueChanged"), { MAP_CHAR_LEN("_Change"), NULL, ApproveAll, NULL } },
328
329 // textChanged ooo event
330 { MAP_CHAR_LEN("textChanged"), { MAP_CHAR_LEN("_Change"), NULL, ApproveAll, NULL } },
331
332 // keyReleased ooo event
333 { MAP_CHAR_LEN("keyReleased"), { MAP_CHAR_LEN("_KeyUp"), ooKeyPressedToVBAKeyUpDown, ApproveAll, NULL } },
334
335 // mouseReleased ooo event
336 { MAP_CHAR_LEN("mouseReleased"), { MAP_CHAR_LEN("_Click"), ooMouseEvtToVBAMouseEvt, ApproveType, (void*)(&fixedTextList) } }, //liuchen, add to support VBA Label_Click event
337 { MAP_CHAR_LEN("mouseReleased"), { MAP_CHAR_LEN("_MouseUp"), ooMouseEvtToVBAMouseEvt, ApproveAll, NULL } },
338
339 // mousePressed ooo event
340 { MAP_CHAR_LEN("mousePressed"), { MAP_CHAR_LEN("_MouseDown"), ooMouseEvtToVBAMouseEvt, ApproveAll, NULL } },
341 { MAP_CHAR_LEN("mousePressed"), { MAP_CHAR_LEN("_DblClick"), ooMouseEvtToVBADblClick, ApproveAll, NULL } },
342
343 // mouseMoved ooo event
344 { MAP_CHAR_LEN("mouseMoved"), { MAP_CHAR_LEN("_MouseMove"), ooMouseEvtToVBAMouseEvt, ApproveAll, NULL } },
345 { MAP_CHAR_LEN("mouseDragged"), { MAP_CHAR_LEN("_MouseMove"), ooMouseEvtToVBAMouseEvt, DenyMouseDrag, NULL } }, //liuchen, add to support VBA MouseMove event when the "Shift" key is pressed
346
347 // keyPressed ooo event
348 { MAP_CHAR_LEN("keyPressed"), { MAP_CHAR_LEN("_KeyDown"), ooKeyPressedToVBAKeyPressed, ApproveAll, NULL } },
349 { MAP_CHAR_LEN("keyPressed"), { MAP_CHAR_LEN("_KeyPress"), ooKeyPressedToVBAKeyPressed, ApproveAll, NULL } }
350 };
351
getEventTransInfo()352 EventInfoHash& getEventTransInfo()
353 {
354 static bool initialised = false;
355 static EventInfoHash eventTransInfo;
356 if ( !initialised )
357 {
358 rtl::OUString sEventInfo = MAP_CHAR_LEN("");
359 TranslatePropMap* pTransProp = aTranslatePropMap_Impl;
360 int nCount = sizeof(aTranslatePropMap_Impl) / sizeof(aTranslatePropMap_Impl[0]);
361
362 int i = 0;
363 while (i < nCount)
364 {
365 sEventInfo = pTransProp->sEventInfo;
366 std::list< TranslateInfo > infoList;
367 do
368 {
369 infoList.push_back( pTransProp->aTransInfo );
370 pTransProp++;
371 i++;
372 }while(i < nCount && sEventInfo == pTransProp->sEventInfo);
373 eventTransInfo[sEventInfo] = infoList;
374 }
375 initialised = true;
376 }
377 return eventTransInfo;
378 }
379 //liuchen 2009-6-23 end
380
381 // Helper class
382
383 class ScriptEventHelper
384 {
385 public:
386 ScriptEventHelper( const Reference< XInterface >& xControl );
387 Sequence< ScriptEventDescriptor > createEvents( const rtl::OUString& sCodeName );
388 Sequence< rtl::OUString > getEventListeners();
389 private:
390 Reference< XComponentContext > m_xCtx;
391 Reference< XInterface > m_xControl;
392 };
393
394 bool
eventMethodToDescriptor(const::rtl::OUString & rEventMethod,ScriptEventDescriptor & evtDesc,const::rtl::OUString & sCodeName)395 eventMethodToDescriptor( const ::rtl::OUString& rEventMethod, ScriptEventDescriptor& evtDesc, const ::rtl::OUString& sCodeName )
396 {
397 // format of ControlListener is TypeName::methodname e.g.
398 // "com.sun.star.awt.XActionListener::actionPerformed" or
399 // "XActionListener::actionPerformed
400
401 ::rtl::OUString sMethodName;
402 ::rtl::OUString sTypeName;
403 sal_Int32 nDelimPos = rEventMethod.indexOf( DELIM );
404 if ( nDelimPos == -1 )
405 {
406 return false;
407 }
408 sMethodName = rEventMethod.copy( nDelimPos + DELIMLEN );
409 sTypeName = rEventMethod.copy( 0, nDelimPos );
410
411 EventInfoHash& infos = getEventTransInfo();
412
413 // Only create an ScriptEventDescriptor for an event we can translate
414 // or emulate
415 if ( sMethodName.getLength()
416 && sTypeName.getLength()
417 && ( infos.find( sMethodName ) != infos.end() ) )
418 {
419 // just fill in CodeName, when the event fires the other
420 // info is gathered from the event source to determine what
421 // event handler we try to call
422 evtDesc.ScriptCode = sCodeName;
423 evtDesc.ListenerType = sTypeName;
424 evtDesc.EventMethod = sMethodName;
425
426 // set this it VBAInterop, ensures that it doesn't
427 // get persisted or shown in property editors
428 evtDesc.ScriptType = rtl::OUString::createFromAscii(
429 "VBAInterop" );
430 return true;
431 }
432 return false;
433
434 }
435
ScriptEventHelper(const Reference<XInterface> & xControl)436 ScriptEventHelper::ScriptEventHelper( const Reference< XInterface >& xControl ) : m_xControl( xControl )
437 {
438 Reference < beans::XPropertySet > xProps(
439 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
440 m_xCtx.set( xProps->getPropertyValue( rtl::OUString(
441 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))),
442 uno::UNO_QUERY_THROW );
443 }
444
445 Sequence< rtl::OUString >
getEventListeners()446 ScriptEventHelper::getEventListeners()
447 {
448 Reference< lang::XMultiComponentFactory > xMFac(
449 m_xCtx->getServiceManager(), UNO_QUERY );
450 std::list< rtl::OUString > eventMethods;
451
452 if ( xMFac.is() )
453 {
454 Reference< beans::XIntrospection > xIntrospection(
455 xMFac->createInstanceWithContext( rtl::OUString(
456 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ), m_xCtx ), UNO_QUERY );
457 #if 0
458 dumpListeners( xIntrospection, m_xControl );
459 dumpListeners( xIntrospection, m_xControl->getModel() );
460 #endif
461 Reference< beans::XIntrospectionAccess > xIntrospectionAccess;
462 if ( xIntrospection.is() )
463 {
464 xIntrospectionAccess = xIntrospection->inspect(
465 makeAny( m_xControl ) );
466 Sequence< Type > aControlListeners =
467 xIntrospectionAccess->getSupportedListeners();
468 sal_Int32 nLength = aControlListeners.getLength();
469 for ( sal_Int32 i = 0; i< nLength; ++i )
470 {
471 Type& listType = aControlListeners[ i ];
472 rtl::OUString sFullTypeName = listType.getTypeName();
473 Sequence< ::rtl::OUString > sMeths =
474 comphelper::getEventMethodsForType( listType );
475 sal_Int32 sMethLen = sMeths.getLength();
476 for ( sal_Int32 j=0 ; j < sMethLen; ++j )
477 {
478 rtl::OUString sEventMethod = sFullTypeName;
479 sEventMethod += DELIM;
480 sEventMethod += sMeths[ j ];
481 eventMethods.push_back( sEventMethod );
482 }
483 }
484
485 }
486 }
487
488 Sequence< rtl::OUString > sEventMethodNames( eventMethods.size() );
489 std::list< rtl::OUString >::const_iterator it = eventMethods.begin();
490 rtl::OUString* pDest = sEventMethodNames.getArray();
491
492 for ( ; it != eventMethods.end(); ++it, ++pDest )
493 *pDest = *it;
494
495 return sEventMethodNames;
496 }
497
498 Sequence< ScriptEventDescriptor >
createEvents(const rtl::OUString & sCodeName)499 ScriptEventHelper::createEvents( const rtl::OUString& sCodeName )
500 {
501 Sequence< rtl::OUString > aControlListeners = getEventListeners();
502 rtl::OUString* pSrc = aControlListeners.getArray();
503 sal_Int32 nLength = aControlListeners.getLength();
504
505 Sequence< ScriptEventDescriptor > aDest( nLength );
506 sal_Int32 nEvts = 0;
507 for ( sal_Int32 i = 0; i< nLength; ++i, ++pSrc )
508 {
509 // from getListeners eventName is of form
510 // "com.sun.star.awt.XActionListener::actionPerformed"
511 // we need to strip "com.sun.star.awt." from that for form
512 // controls
513 ScriptEventDescriptor evtDesc;
514 if ( eventMethodToDescriptor( *pSrc, evtDesc, sCodeName ) )
515 {
516 sal_Int32 dIndex = nEvts;
517 ++nEvts;
518 if ( nEvts > aDest.getLength() )
519 aDest.realloc( nEvts );// should never happen
520 aDest[ dIndex ] = evtDesc;
521 }
522 }
523 aDest.realloc( nEvts );
524
525 return aDest;
526 }
527
528
529 typedef ::cppu::WeakImplHelper1< container::XNameContainer > NameContainer_BASE;
530
531 class ReadOnlyEventsNameContainer : public NameContainer_BASE
532 {
533 public:
534 ReadOnlyEventsNameContainer( const Sequence< rtl::OUString >& eventMethods, const rtl::OUString& sCodeName );
535 // XNameContainer
536
insertByName(const::rtl::OUString &,const Any &)537 virtual void SAL_CALL insertByName( const ::rtl::OUString&, const Any& ) throw (lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, RuntimeException)
538 {
539 throw RuntimeException( rtl::OUString::createFromAscii( "ReadOnly container" ), Reference< XInterface >() );
540
541 }
removeByName(const::rtl::OUString &)542 virtual void SAL_CALL removeByName( const ::rtl::OUString& ) throw (::com::sun::star::container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
543 {
544 throw RuntimeException( rtl::OUString::createFromAscii( "ReadOnly container" ), Reference< XInterface >() );
545 }
546
547 // XNameReplace
replaceByName(const::rtl::OUString &,const Any &)548 virtual void SAL_CALL replaceByName( const ::rtl::OUString&, const Any& ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
549 {
550 throw RuntimeException( rtl::OUString::createFromAscii( "ReadOnly container" ), Reference< XInterface >() );
551
552 }
553
554 // XNameAccess
555 virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException);
556 virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (RuntimeException);
557 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (RuntimeException);
558
559 // XElementAccess
getElementType()560 virtual Type SAL_CALL getElementType( ) throw (RuntimeException)
561 { return getCppuType(static_cast< const rtl::OUString * >(0) ); }
hasElements()562 virtual ::sal_Bool SAL_CALL hasElements( ) throw (RuntimeException)
563 { return ( ( m_hEvents.size() > 0 ? sal_True : sal_False ) ); }
564 private:
565
566 typedef std::hash_map< rtl::OUString, Any, ::rtl::OUStringHash,
567 ::std::equal_to< ::rtl::OUString > > EventSupplierHash;
568
569 EventSupplierHash m_hEvents;
570 };
571
ReadOnlyEventsNameContainer(const Sequence<rtl::OUString> & eventMethods,const rtl::OUString & sCodeName)572 ReadOnlyEventsNameContainer::ReadOnlyEventsNameContainer( const Sequence< rtl::OUString >& eventMethods, const rtl::OUString& sCodeName )
573 {
574 const rtl::OUString* pSrc = eventMethods.getConstArray();
575 sal_Int32 nLen = eventMethods.getLength();
576 for ( sal_Int32 index = 0; index < nLen; ++index, ++pSrc )
577 {
578 Any aDesc;
579 ScriptEventDescriptor evtDesc;
580 if ( eventMethodToDescriptor( *pSrc, evtDesc, sCodeName ) )
581 {
582 aDesc <<= evtDesc;
583 m_hEvents[ *pSrc ] = aDesc;
584 }
585 }
586 }
587
588 Any SAL_CALL
getByName(const::rtl::OUString & aName)589 ReadOnlyEventsNameContainer::getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException){
590 EventSupplierHash::const_iterator it = m_hEvents.find( aName );
591 if ( it == m_hEvents.end() )
592 throw container::NoSuchElementException();
593 return it->second;
594 }
595
596 Sequence< ::rtl::OUString > SAL_CALL
getElementNames()597 ReadOnlyEventsNameContainer::getElementNames( ) throw (RuntimeException)
598 {
599 Sequence< ::rtl::OUString > names(m_hEvents.size());
600 rtl::OUString* pDest = names.getArray();
601 EventSupplierHash::const_iterator it = m_hEvents.begin();
602 EventSupplierHash::const_iterator it_end = m_hEvents.end();
603 for ( sal_Int32 index = 0; it != it_end; ++index, ++pDest, ++it )
604 *pDest = it->first;
605 return names;
606 }
607
608 sal_Bool SAL_CALL
hasByName(const::rtl::OUString & aName)609 ReadOnlyEventsNameContainer::hasByName( const ::rtl::OUString& aName ) throw (RuntimeException)
610 {
611 EventSupplierHash::const_iterator it = m_hEvents.find( aName );
612 if ( it == m_hEvents.end() )
613 return sal_False;
614 return sal_True;
615 }
616
617 typedef ::cppu::WeakImplHelper1< XScriptEventsSupplier > EventsSupplier_BASE;
618
619 class ReadOnlyEventsSupplier : public EventsSupplier_BASE
620 {
621 public:
ReadOnlyEventsSupplier(const Sequence<::rtl::OUString> & eventMethods,const rtl::OUString & sCodeName)622 ReadOnlyEventsSupplier( const Sequence< ::rtl::OUString >& eventMethods, const rtl::OUString& sCodeName )
623 { m_xNameContainer = new ReadOnlyEventsNameContainer( eventMethods, sCodeName ); }
624
625 // XScriptEventSupplier
getEvents()626 virtual Reference< container::XNameContainer > SAL_CALL getEvents( ) throw (RuntimeException){ return m_xNameContainer; }
627 private:
628 Reference< container::XNameContainer > m_xNameContainer;
629 };
630
631 typedef ::cppu::WeakImplHelper3< XScriptListener, util::XCloseListener, lang::XInitialization > EventListener_BASE;
632
633 #define EVENTLSTNR_PROPERTY_ID_MODEL 1
634 #define EVENTLSTNR_PROPERTY_MODEL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Model" ) )
635
636 class EventListener : public EventListener_BASE
637 ,public ::comphelper::OMutexAndBroadcastHelper
638 ,public ::comphelper::OPropertyContainer
639 ,public ::comphelper::OPropertyArrayUsageHelper< EventListener >
640
641 {
642
643 public:
644 EventListener( const Reference< XComponentContext >& rxContext );
645 // XEventListener
646 virtual void SAL_CALL disposing(const lang::EventObject& Source) throw( RuntimeException );
647 using cppu::OPropertySetHelper::disposing;
648
649 // XScriptListener
650 virtual void SAL_CALL firing(const ScriptEvent& evt) throw(RuntimeException);
651 virtual Any SAL_CALL approveFiring(const ScriptEvent& evt) throw(reflection::InvocationTargetException, RuntimeException);
652 // XCloseListener
653 virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException);
654 virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException);
655 // XPropertySet
656 virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException);
657 // XInitialization
658 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
659 // XInterface
660 DECLARE_XINTERFACE()
661
662 // XTypeProvider
DECLARE_XTYPEPROVIDER()663 DECLARE_XTYPEPROVIDER()
664 virtual void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
665 {
666 if ( nHandle == EVENTLSTNR_PROPERTY_ID_MODEL )
667 {
668 uno::Reference< frame::XModel > xModel( rValue, uno::UNO_QUERY );
669 if( xModel != m_xModel)
670 {
671 // Remove the listener from the old XCloseBroadcaster.
672 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xModel, uno::UNO_QUERY );
673 if (xCloseBroadcaster.is())
674 {
675 xCloseBroadcaster->removeCloseListener( this );
676 }
677 // Add the listener into the new XCloseBroadcaster.
678 xCloseBroadcaster = uno::Reference< util::XCloseBroadcaster >( xModel, uno::UNO_QUERY );
679 if (xCloseBroadcaster.is())
680 {
681 xCloseBroadcaster->addCloseListener( this );
682 }
683 }
684 }
685 OPropertyContainer::setFastPropertyValue( nHandle, rValue );
686 if ( nHandle == EVENTLSTNR_PROPERTY_ID_MODEL )
687 setShellFromModel();
688 }
689
690 protected:
691 // OPropertySetHelper
692 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( );
693
694 // OPropertyArrayUsageHelper
695 virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
696
697 private:
698 void setShellFromModel();
699 void firing_Impl( const ScriptEvent& evt, Any *pSyncRet=NULL ) throw( RuntimeException );
700
701 Reference< XComponentContext > m_xContext;
702 Reference< frame::XModel > m_xModel;
703 sal_Bool m_bDocClosed;
704 SfxObjectShell* mpShell;
705
706 };
707
EventListener(const Reference<XComponentContext> & rxContext)708 EventListener::EventListener( const Reference< XComponentContext >& rxContext ) :
709 OPropertyContainer(GetBroadcastHelper()), m_xContext( rxContext ), m_bDocClosed(sal_False), mpShell( 0 )
710 {
711 registerProperty( EVENTLSTNR_PROPERTY_MODEL, EVENTLSTNR_PROPERTY_ID_MODEL,
712 beans::PropertyAttribute::TRANSIENT, &m_xModel, ::getCppuType( &m_xModel ) );
713
714 }
715
716 void
setShellFromModel()717 EventListener::setShellFromModel()
718 {
719 // reset mpShell
720 mpShell = 0;
721 SfxObjectShell* pShell = SfxObjectShell::GetFirst();
722 while ( m_xModel.is() && pShell )
723 {
724 if ( pShell->GetModel() == m_xModel )
725 {
726 mpShell = pShell;
727 break;
728 }
729 pShell = SfxObjectShell::GetNext( *pShell );
730 }
731 }
732
733 //XEventListener
734 void
disposing(const lang::EventObject &)735 EventListener::disposing(const lang::EventObject&) throw( RuntimeException )
736 {
737 }
738
739 //XScriptListener
740
741 void SAL_CALL
firing(const ScriptEvent & evt)742 EventListener::firing(const ScriptEvent& evt) throw(RuntimeException)
743 {
744 firing_Impl( evt );
745 }
746
747 Any SAL_CALL
approveFiring(const ScriptEvent & evt)748 EventListener::approveFiring(const ScriptEvent& evt) throw(reflection::InvocationTargetException, RuntimeException)
749 {
750 Any ret;
751 firing_Impl( evt, &ret );
752 return ret;
753 }
754
755 // XCloseListener
756 void SAL_CALL
queryClosing(const lang::EventObject & Source,::sal_Bool GetsOwnership)757 EventListener::queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException)
758 {
759 //Nothing to do
760 }
761
762 void SAL_CALL
notifyClosing(const lang::EventObject & Source)763 EventListener::notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException)
764 {
765 m_bDocClosed = sal_True;
766 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xModel, uno::UNO_QUERY );
767 if (xCloseBroadcaster.is())
768 {
769 xCloseBroadcaster->removeCloseListener( this );
770 }
771 }
772
773 // XInitialization
774 void SAL_CALL
initialize(const Sequence<Any> & aArguments)775 EventListener::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
776 {
777 if ( aArguments.getLength() == 1 )
778 aArguments[0] >>= m_xModel;
779 OSL_TRACE("EventListener::initialize() args %d m_xModel %d", aArguments.getLength(), m_xModel.is() );
780 }
781
782 // XInterface
783
IMPLEMENT_FORWARD_XINTERFACE2(EventListener,EventListener_BASE,OPropertyContainer)784 IMPLEMENT_FORWARD_XINTERFACE2( EventListener, EventListener_BASE, OPropertyContainer )
785
786 // XTypeProvider
787
788 IMPLEMENT_FORWARD_XTYPEPROVIDER2( EventListener, EventListener_BASE, OPropertyContainer )
789
790 // OPropertySetHelper
791
792 ::cppu::IPropertyArrayHelper&
793 EventListener::getInfoHelper( )
794 {
795 return *getArrayHelper();
796 }
797
798 // OPropertyArrayUsageHelper
799
800 ::cppu::IPropertyArrayHelper*
createArrayHelper() const801 EventListener::createArrayHelper( ) const
802 {
803 Sequence< beans::Property > aProps;
804 describeProperties( aProps );
805 return new ::cppu::OPropertyArrayHelper( aProps );
806 }
807
808 // XPropertySet
809 Reference< beans::XPropertySetInfo >
getPropertySetInfo()810 EventListener::getPropertySetInfo( ) throw (RuntimeException)
811 {
812 Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
813 return xInfo;
814 }
815
816 //liuchen 2009-6-23
817 //decide if the control should execute the event
ApproveAll(const ScriptEvent &,void *)818 bool ApproveAll(const ScriptEvent&, void* )
819 {
820 return true;
821 }
822
823 //for the given control type in evt.Arguments[0], look for if it appears in the type list in pPara
FindControl(const ScriptEvent & evt,void * pPara)824 bool FindControl(const ScriptEvent& evt, void* pPara)
825 {
826 lang::EventObject aEvent;
827 evt.Arguments[ 0 ] >>= aEvent;
828 uno::Reference< uno::XInterface > xInterface( aEvent.Source, uno::UNO_QUERY );
829
830 TypeList* pTypeListInfo = static_cast<TypeList*>(pPara);
831 Type* pType = pTypeListInfo->pTypeList;
832 int nLen = pTypeListInfo->nListLength;
833
834 for (int i = 0; i < nLen; i++)
835 {
836 if ( xInterface->queryInterface( *pType ).hasValue() )
837 {
838 return true;
839 }
840 pType++;
841 }
842
843 return false;
844 }
845
846 //if the given control type in evt.Arguments[0] appears in the type list in pPara, then approve the execution
ApproveType(const ScriptEvent & evt,void * pPara)847 bool ApproveType(const ScriptEvent& evt, void* pPara)
848 {
849 return FindControl(evt, pPara);
850 }
851
852 //if the given control type in evt.Arguments[0] appears in the type list in pPara, then deny the execution
DenyType(const ScriptEvent & evt,void * pPara)853 bool DenyType(const ScriptEvent& evt, void* pPara)
854 {
855 return !FindControl(evt, pPara);
856 }
857
858 //when mouse is moving, either the mouse button is pressed or some key is pressed can trigger the OO mouseDragged event,
859 //the former should be denyed, and the latter allowed, only by doing so can the VBA MouseMove event when the "Shift" key is
860 //pressed can be correctly triggered
DenyMouseDrag(const ScriptEvent & evt,void *)861 bool DenyMouseDrag(const ScriptEvent& evt, void* )
862 {
863 awt::MouseEvent aEvent;
864 evt.Arguments[ 0 ] >>= aEvent;
865 if (aEvent.Buttons == 0 )
866 {
867 return true;
868 }
869 else
870 {
871 return false;
872 }
873 }
874
875
876
877 //liuchen 2009-6-23
878 // EventListener
879
880 void
firing_Impl(const ScriptEvent & evt,Any *)881 EventListener::firing_Impl(const ScriptEvent& evt, Any* /*pRet*/ ) throw(RuntimeException)
882 {
883 OSL_TRACE("EventListener::firing_Impl( FAKE VBA_EVENTS )");
884 static const ::rtl::OUString vbaInterOp =
885 ::rtl::OUString::createFromAscii("VBAInterop");
886
887 // let default handlers deal with non vba stuff
888 if ( !evt.ScriptType.equals( vbaInterOp ) )
889 return;
890 lang::EventObject aEvent;
891 evt.Arguments[ 0 ] >>= aEvent;
892 OSL_TRACE("Argument[0] is %s", rtl::OUStringToOString( comphelper::anyToString( evt.Arguments[0] ), RTL_TEXTENCODING_UTF8 ).getStr() );
893 OSL_TRACE("Getting Control");
894 uno::Reference< awt::XControl > xControl( aEvent.Source, uno::UNO_QUERY_THROW );
895 OSL_TRACE("Getting properties");
896 uno::Reference< beans::XPropertySet > xProps( xControl->getModel(), uno::UNO_QUERY_THROW );
897
898 rtl::OUString sName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm") );
899 OSL_TRACE("Getting Name");
900
901 uno::Reference< awt::XDialog > xDlg( aEvent.Source, uno::UNO_QUERY );
902 if ( !xDlg.is() )
903 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= sName;
904 //dumpEvent( evt );
905 EventInfoHash& infos = getEventTransInfo();
906 EventInfoHash::const_iterator eventInfo_it = infos.find( evt.MethodName );
907 EventInfoHash::const_iterator it_end = infos.end();
908 if ( eventInfo_it == it_end )
909 {
910 OSL_TRACE("Bogus event for %s",
911 rtl::OUStringToOString( evt.ScriptType, RTL_TEXTENCODING_UTF8 ).getStr() );
912 return;
913 }
914
915 uno::Reference< script::provider::XScriptProviderSupplier > xSPS( m_xModel, uno::UNO_QUERY );
916 uno::Reference< script::provider::XScriptProvider > xScriptProvider;
917 if ( xSPS.is() )
918 xScriptProvider = xSPS->getScriptProvider();
919 if ( xScriptProvider.is() && mpShell )
920 {
921 std::list< TranslateInfo > matchingMethods;
922 std::list< TranslateInfo >::const_iterator txInfo =
923 eventInfo_it->second.begin();
924 std::list< TranslateInfo >::const_iterator txInfo_end = eventInfo_it->second.end();
925 rtl::OUString sMacroLoc = rtl::OUString::createFromAscii("Standard.").concat( evt.ScriptCode ).concat( rtl::OUString::createFromAscii(".") );
926
927 StarBASIC* pBasic = mpShell->GetBasic();
928 SbModule* pModule = pBasic->FindModule( evt.ScriptCode );
929 for ( ; pModule && txInfo != txInfo_end; ++txInfo )
930 {
931 // #i106270#: If the document is closed, we should not execute macro.
932 if (m_bDocClosed)
933 {
934 break;
935 }
936 // see if we have a match for the handlerextension
937 // where ScriptCode is methodname_handlerextension
938 rtl::OUString sTemp = sName.concat( (*txInfo).sVBAName );
939
940 OSL_TRACE("*** trying to invoke %s ",
941 rtl::OUStringToOString( sTemp, RTL_TEXTENCODING_UTF8 ).getStr() );
942 SbMethod* pMeth = static_cast< SbMethod* >( pModule->Find( sTemp, SbxCLASS_METHOD ) );
943 if ( pMeth )
944 {
945 //liuchen 2009-6-8
946 if (! txInfo->ApproveRule(evt, txInfo->pPara) )
947 {
948 continue;
949 }
950 //liuchen 2009-6-8
951 // !! translate arguments & emulate events where necessary
952 Sequence< Any > aArguments;
953 if ( (*txInfo).toVBA )
954 aArguments = (*txInfo).toVBA( evt.Arguments );
955 else
956 aArguments = evt.Arguments;
957 if ( aArguments.getLength() )
958 {
959 // call basic event handlers for event
960
961 static rtl::OUString part1 = rtl::OUString::createFromAscii( "vnd.sun.star.script:");
962 static rtl::OUString part2 = rtl::OUString::createFromAscii("?language=Basic&location=document");
963
964 // create script url
965 rtl::OUString url = part1 + sMacroLoc + sTemp + part2;
966
967 OSL_TRACE("script url = %s",
968 rtl::OUStringToOString( url,
969 RTL_TEXTENCODING_UTF8 ).getStr() );
970 Sequence< sal_Int16 > aOutArgsIndex;
971 Sequence< Any > aOutArgs;
972 try
973 {
974 if ( mpShell )
975 {
976 uno::Any aRet;
977 mpShell->CallXScript( url,
978 aArguments, aRet, aOutArgsIndex, aOutArgs, ::rtl::OUString(), false );
979 }
980 }
981 catch ( uno::Exception& e )
982 {
983 OSL_TRACE("event script raised %s", rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
984 }
985 }
986 }
987 }
988 }
989 }
990
991 typedef ::cppu::WeakImplHelper1< XVBAToOOEventDescGen > VBAToOOEventDescGen_BASE;
992
993
994 class VBAToOOEventDescGen : public VBAToOOEventDescGen_BASE
995 {
996 public:
997 VBAToOOEventDescGen( const Reference< XComponentContext >& rxContext );
998
999 // XVBAToOOEventDescGen
1000 virtual Sequence< ScriptEventDescriptor > SAL_CALL getEventDescriptions( const Reference< XInterface >& control, const rtl::OUString& sCodeName ) throw (RuntimeException);
1001 virtual Reference< XScriptEventsSupplier > SAL_CALL getEventSupplier( const Reference< XInterface >& xControl, const rtl::OUString& sCodeName ) throw (::com::sun::star::uno::RuntimeException);
1002 private:
1003 Reference< XComponentContext > m_xContext;
1004
1005 };
1006
VBAToOOEventDescGen(const Reference<XComponentContext> & rxContext)1007 VBAToOOEventDescGen::VBAToOOEventDescGen( const Reference< XComponentContext >& rxContext ):m_xContext( rxContext ) {}
1008
1009 Sequence< ScriptEventDescriptor > SAL_CALL
getEventDescriptions(const Reference<XInterface> & xControl,const rtl::OUString & sCodeName)1010 VBAToOOEventDescGen::getEventDescriptions( const Reference< XInterface >& xControl, const rtl::OUString& sCodeName ) throw (RuntimeException)
1011 {
1012 ScriptEventHelper evntHelper( xControl );
1013 return evntHelper.createEvents( sCodeName );
1014 }
1015
1016 Reference< XScriptEventsSupplier > SAL_CALL
getEventSupplier(const Reference<XInterface> & xControl,const rtl::OUString & sCodeName)1017 VBAToOOEventDescGen::getEventSupplier( const Reference< XInterface >& xControl, const rtl::OUString& sCodeName ) throw (::com::sun::star::uno::RuntimeException)
1018 {
1019 ScriptEventHelper evntHelper( xControl );
1020 Reference< XScriptEventsSupplier > xSupplier =
1021 new ReadOnlyEventsSupplier(
1022 evntHelper.getEventListeners(), sCodeName ) ;
1023 return xSupplier;
1024 }
1025
1026 // Component related
1027
1028 namespace evtlstner
1029 {
getImplementationName()1030 ::rtl::OUString SAL_CALL getImplementationName()
1031 {
1032 static ::rtl::OUString* pImplName = 0;
1033 if ( !pImplName )
1034 {
1035 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1036 if ( !pImplName )
1037 {
1038 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.EventListener" ) );
1039 pImplName = &aImplName;
1040 }
1041 }
1042 return *pImplName;
1043 }
1044
create(Reference<XComponentContext> const & xContext)1045 uno::Reference< XInterface > SAL_CALL create(
1046 Reference< XComponentContext > const & xContext )
1047 SAL_THROW( () )
1048 {
1049 return static_cast< lang::XTypeProvider * >( new EventListener( xContext ) );
1050 }
1051
getSupportedServiceNames()1052 Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
1053 {
1054 const ::rtl::OUString strName( ::evtlstner::getImplementationName() );
1055 return Sequence< ::rtl::OUString >( &strName, 1 );
1056 }
1057 }
1058 namespace ooevtdescgen
1059 {
getImplementationName()1060 ::rtl::OUString SAL_CALL getImplementationName()
1061 {
1062 static ::rtl::OUString* pImplName = 0;
1063 if ( !pImplName )
1064 {
1065 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1066 if ( !pImplName )
1067 {
1068 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAToOOEventDesc" ) );
1069 pImplName = &aImplName;
1070 }
1071 }
1072 return *pImplName;
1073 }
1074
create(Reference<XComponentContext> const & xContext)1075 uno::Reference< XInterface > SAL_CALL create(
1076 Reference< XComponentContext > const & xContext )
1077 SAL_THROW( () )
1078 {
1079 return static_cast< lang::XTypeProvider * >( new VBAToOOEventDescGen( xContext ) );
1080 }
1081
getSupportedServiceNames()1082 Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
1083 {
1084 const ::rtl::OUString strName( ::ooevtdescgen::getImplementationName() );
1085 return Sequence< ::rtl::OUString >( &strName, 1 );
1086 }
1087 }
1088