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