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