LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/scripting/source/vbaevents - eventhelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 309 393 78.6 %
Date: 2013-07-09 Functions: 51 71 71.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10