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

Generated by: LCOV version 1.11