2010-10-12 15:53:47 +02:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2009-08-04 07:35:29 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* Copyright 2008 by Sun Microsystems , Inc .
*
* OpenOffice . org - a multi - platform office productivity suite
*
* This file is part of OpenOffice . org .
*
* OpenOffice . org is free software : you can redistribute it and / or modify
* it under the terms of the GNU Lesser General Public License version 3
* only , as published by the Free Software Foundation .
*
* OpenOffice . org is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Lesser General Public License version 3 for more details
* ( a copy is included in the LICENSE file that accompanied this code ) .
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice . org . If not , see
* < http : //www.openoffice.org/license.html>
* for a copy of the LGPLv3 License .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-14 22:33:33 +01:00
# include <sal/macros.h>
2009-06-17 13:32:41 +00:00
# include <comphelper/processfactory.hxx>
# include <comphelper/uno3.hxx>
# include <comphelper/proparrhlp.hxx>
# include <comphelper/propertycontainer.hxx>
# include <ooo/vba/XVBAToOOEventDescGen.hpp>
# include <com/sun/star/beans/XPropertySet.hpp>
# include <com/sun/star/beans/XIntrospection.hpp>
# include <com/sun/star/beans/PropertyAttribute.hpp>
# include <com/sun/star/lang/XMultiComponentFactory.hpp>
# include <com/sun/star/lang/XServiceName.hpp>
# include <com/sun/star/lang/XServiceInfo.hpp>
# include <com/sun/star/lang/XInitialization.hpp>
2010-10-06 10:16:27 +01:00
# include <com/sun/star/util/XCloseListener.hpp>
# include <com/sun/star/util/XCloseBroadcaster.hpp>
2009-06-17 13:32:41 +00:00
# include <com/sun/star/frame/XModel.hpp>
# include <com/sun/star/script/XLibraryContainer.hpp>
# include <com/sun/star/script/ScriptEventDescriptor.hpp>
# include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
2010-11-02 16:22:07 +00:00
# include <com/sun/star/script/vba/XVBACompatibility.hpp>
2009-06-17 13:32:41 +00:00
2010-10-06 10:16:27 +01:00
# include <com/sun/star/container/XNamed.hpp>
2009-06-17 13:32:41 +00:00
# include <com/sun/star/drawing/XControlShape.hpp>
# include <com/sun/star/awt/XControl.hpp>
# include <com/sun/star/awt/XDialog.hpp>
# include <com/sun/star/awt/KeyEvent.hpp>
# include <com/sun/star/awt/MouseEvent.hpp>
2010-10-19 23:45:24 -05:00
# include <com/sun/star/awt/XFixedText.hpp>
# include <com/sun/star/awt/XTextComponent.hpp>
# include <com/sun/star/awt/XComboBox.hpp>
# include <com/sun/star/awt/XRadioButton.hpp>
2010-10-06 10:16:27 +01:00
# include <com/sun/star/awt/XListBox.hpp>
2009-06-17 13:32:41 +00:00
2010-10-06 10:16:27 +01:00
# include "vbamsformreturntypes.hxx"
2009-06-17 13:32:41 +00:00
# include <sfx2/objsh.hxx>
# include <basic/sbstar.hxx>
# include <basic/basmgr.hxx>
# include <basic/sbmeth.hxx>
# include <basic/sbmod.hxx>
# include <basic/sbx.hxx>
2010-10-06 10:16:27 +01:00
# include <filter/msfilter/msvbahelper.hxx>
2009-06-17 13:32:41 +00:00
// for debug
# include <comphelper/anytostring.hxx>
# include <com/sun/star/lang/XMultiComponentFactory.hpp>
# include <com/sun/star/script/XScriptListener.hpp>
# include <cppuhelper/implbase1.hxx>
2010-10-06 10:16:27 +01:00
# include <cppuhelper/implbase3.hxx>
2009-06-17 13:32:41 +00:00
# include <cppuhelper/implbase2.hxx>
# include <comphelper/evtmethodhelper.hxx>
# include <set>
# include <list>
2011-02-05 13:18:52 +01:00
# include <boost/unordered_map.hpp>
2010-10-06 10:16:27 +01:00
# define ASYNC 0
// primitive support for asynchronous handling of
// events from controls ( all event will be processed asynchronously
// in the application thread )
# if ASYNC
# include <vcl/svapp.hxx>
# endif
2009-06-17 13:32:41 +00:00
using namespace : : com : : sun : : star ;
using namespace : : com : : sun : : star : : script ;
using namespace : : com : : sun : : star : : uno ;
using namespace : : ooo : : vba ;
2012-06-02 20:19:28 -05:00
# define MAP_CHAR_LEN(x) ::rtl::OUString(x)
2009-11-04 14:54:23 +00:00
# define GET_TYPE(x) ::getCppuType((uno::Reference< x > *)0);
2009-06-17 13:32:41 +00:00
// Some constants
2012-06-02 20:19:28 -05:00
const static rtl : : OUString DELIM ( " :: " ) ;
2009-06-17 13:32:41 +00:00
const static sal_Int32 DELIMLEN = DELIM . getLength ( ) ;
bool isKeyEventOk ( awt : : KeyEvent & evt , const Sequence < Any > & params )
{
if ( ! ( params . getLength ( ) > 0 ) | |
! ( params [ 0 ] > > = evt ) )
return false ;
return true ;
}
bool isMouseEventOk ( awt : : MouseEvent & evt , const Sequence < Any > & params )
{
if ( ! ( params . getLength ( ) > 0 ) | |
! ( params [ 0 ] > > = evt ) )
return false ;
return true ;
}
2010-10-06 10:16:27 +01:00
bool isFocusEventOk ( awt : : FocusEvent & evt , const Sequence < Any > & params )
{
if ( ! ( params . getLength ( ) > 0 ) | |
! ( params [ 0 ] > > = evt ) )
return false ;
return true ;
}
2009-06-17 13:32:41 +00:00
Sequence < Any > ooMouseEvtToVBADblClick ( const Sequence < Any > & params )
{
Sequence < Any > translatedParams ;
awt : : MouseEvent evt ;
if ( ! ( isMouseEventOk ( evt , params ) ) | |
( evt . ClickCount ! = 2 ) )
return Sequence < Any > ( ) ;
// give back orig params, this will signal that the event is good
return params ;
}
Sequence < Any > ooMouseEvtToVBAMouseEvt ( const Sequence < Any > & params )
{
Sequence < Any > translatedParams ;
awt : : MouseEvent evt ;
if ( ! isMouseEventOk ( evt , params ) )
return Sequence < Any > ( ) ;
translatedParams . realloc ( 4 ) ;
// Buttons
translatedParams [ 0 ] < < = evt . Buttons ;
// Shift
translatedParams [ 1 ] < < = evt . Modifiers ;
// X
translatedParams [ 2 ] < < = evt . X ;
// Y
translatedParams [ 3 ] < < = evt . Y ;
return translatedParams ;
}
Sequence < Any > ooKeyPressedToVBAKeyPressed ( const Sequence < Any > & params )
{
Sequence < Any > translatedParams ;
awt : : KeyEvent evt ;
if ( ! isKeyEventOk ( evt , params ) )
return Sequence < Any > ( ) ;
translatedParams . realloc ( 1 ) ;
2010-10-06 10:16:27 +01:00
//The VBA events such as ComboBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) may cause an error because
//the original input parameter data structure -- msforms::ReturnInteger -- is a struct, it cannot support default value.
//So the newly defined VbaReturnIntege class is used here to support default value.
VbaReturnInteger * pKeyCode = new VbaReturnInteger ( ) ;
pKeyCode - > Value = evt . KeyChar ;
: : uno : : Reference < msforms : : XReturnInteger > xInteger =
static_cast < : : uno : : Reference < msforms : : XReturnInteger > > ( pKeyCode ) ;
translatedParams [ 0 ] < < = xInteger ;
2009-06-17 13:32:41 +00:00
return translatedParams ;
}
Sequence < Any > ooKeyPressedToVBAKeyUpDown ( const Sequence < Any > & params )
{
Sequence < Any > translatedParams ;
awt : : KeyEvent evt ;
if ( ! isKeyEventOk ( evt , params ) )
return Sequence < Any > ( ) ;
translatedParams . realloc ( 2 ) ;
2010-10-06 10:16:27 +01:00
//The VBA events such as ComboBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) may cause an error because
//the original input parameter data structure -- msforms::ReturnInteger -- is a struct, it cannot support default value.
//So the newly defined VbaReturnIntege class is used here to support default value.
VbaReturnInteger * pKeyCode = new VbaReturnInteger ( ) ;
sal_Int8 shift = evt . Modifiers ;
2009-06-17 13:32:41 +00:00
2010-10-06 10:16:27 +01:00
pKeyCode - > Value = evt . KeyChar ;
: : uno : : Reference < msforms : : XReturnInteger > xInteger = static_cast < : : uno : : Reference < msforms : : XReturnInteger > > ( pKeyCode ) ;
translatedParams [ 0 ] < < = xInteger ;
2009-06-17 13:32:41 +00:00
translatedParams [ 1 ] < < = shift ;
return translatedParams ;
}
2010-10-06 10:16:27 +01:00
Sequence < Any > ooFocusLostToVBAExit ( const Sequence < Any > & params )
{
Sequence < Any > translatedParams ;
awt : : FocusEvent evt ;
if ( ! isFocusEventOk ( evt , params ) )
return Sequence < Any > ( ) ;
translatedParams . realloc ( 1 ) ;
VbaReturnBoolean * pCancel = new VbaReturnBoolean ( ) ;
: : uno : : Reference < msforms : : XReturnBoolean > xBoolean =
static_cast < : : uno : : Reference < msforms : : XReturnBoolean > > ( pCancel ) ;
translatedParams [ 0 ] < < = xBoolean ;
return translatedParams ;
}
2009-06-17 13:32:41 +00:00
typedef Sequence < Any > ( * Translator ) ( const Sequence < Any > & ) ;
2010-10-19 23:45:24 -05:00
2009-11-04 14:54:23 +00:00
//expand the "TranslateInfo" struct to support more kinds of events
2009-06-17 13:32:41 +00:00
struct TranslateInfo
{
2009-11-04 14:54:23 +00:00
rtl : : OUString sVBAName ; //vba event name
Translator toVBA ; //the method to convert OO event parameters to VBA event parameters
bool ( * ApproveRule ) ( const ScriptEvent & evt , void * pPara ) ; //this method is used to determine which types of controls should execute the event
void * pPara ; //Parameters for the above approve method
2009-06-17 13:32:41 +00:00
} ;
2011-02-05 13:18:52 +01:00
typedef boost : : unordered_map < rtl : : OUString ,
2009-06-17 13:32:41 +00:00
std : : list < TranslateInfo > ,
: : rtl : : OUStringHash ,
: : std : : equal_to < : : rtl : : OUString > > EventInfoHash ;
2010-10-19 23:45:24 -05:00
2009-11-04 14:54:23 +00:00
struct TranslatePropMap
{
rtl : : OUString sEventInfo ; //OO event name
TranslateInfo aTransInfo ;
} ;
bool ApproveAll ( const ScriptEvent & evt , void * pPara ) ; //allow all types of controls to execute the event
bool ApproveType ( const ScriptEvent & evt , void * pPara ) ; //certain types of controls should execute the event, those types are given by pPara
bool DenyType ( const ScriptEvent & evt , void * pPara ) ; //certain types of controls should not execute the event, those types are given by pPara
bool DenyMouseDrag ( const ScriptEvent & evt , void * pPara ) ; //used for VBA MouseMove event when "Shift" key is pressed
2010-10-06 10:16:27 +01:00
bool DenyKeys ( const ScriptEvent & evt , void * pPara ) ; //For some keys, press them will cause Symphony keyPressed event, but will not cause any events in Excel, so deny these key events
2009-11-04 14:54:23 +00:00
struct TypeList
{
uno : : Type * pTypeList ;
int nListLength ;
} ;
2010-10-06 10:16:27 +01:00
Type typeXFixedText = GET_TYPE ( awt : : XFixedText ) ;
Type typeXTextComponent = GET_TYPE ( awt : : XTextComponent ) ;
Type typeXComboBox = GET_TYPE ( awt : : XComboBox ) ;
Type typeXRadioButton = GET_TYPE ( awt : : XRadioButton ) ;
Type typeXListBox = GET_TYPE ( awt : : XListBox ) ;
2009-11-04 14:54:23 +00:00
TypeList fixedTextList = { & typeXFixedText , 1 } ;
TypeList textCompList = { & typeXTextComponent , 1 } ;
TypeList radioButtonList = { & typeXRadioButton , 1 } ;
TypeList comboBoxList = { & typeXComboBox , 1 } ;
2010-10-06 10:16:27 +01:00
TypeList listBoxList = { & typeXListBox , 1 } ;
2009-11-04 14:54:23 +00:00
//this array stores the OO event to VBA event translation info
static TranslatePropMap aTranslatePropMap_Impl [ ] =
{
2010-10-19 23:45:24 -05:00
{ MAP_CHAR_LEN ( " actionPerformed " ) , { MAP_CHAR_LEN ( " _Change " ) , NULL , DenyType , ( void * ) ( & radioButtonList ) } } ,
2009-11-04 14:54:23 +00:00
// actionPerformed ooo event
{ MAP_CHAR_LEN ( " actionPerformed " ) , { MAP_CHAR_LEN ( " _Click " ) , NULL , ApproveAll , NULL } } ,
2010-10-19 23:45:24 -05:00
{ MAP_CHAR_LEN ( " itemStateChanged " ) , { MAP_CHAR_LEN ( " _Change " ) , NULL , ApproveType , ( void * ) ( & radioButtonList ) } } ,
2009-11-04 14:54:23 +00:00
// itemStateChanged ooo event
2010-10-19 23:45:24 -05:00
{ MAP_CHAR_LEN ( " itemStateChanged " ) , { MAP_CHAR_LEN ( " _Click " ) , NULL , ApproveType , ( void * ) ( & comboBoxList ) } } ,
2009-11-04 14:54:23 +00:00
2010-10-06 10:16:27 +01:00
{ MAP_CHAR_LEN ( " itemStateChanged " ) , { MAP_CHAR_LEN ( " _Click " ) , NULL , ApproveType , ( void * ) ( & listBoxList ) } } ,
2009-11-04 14:54:23 +00:00
// changed ooo event
{ MAP_CHAR_LEN ( " changed " ) , { MAP_CHAR_LEN ( " _Change " ) , NULL , ApproveAll , NULL } } ,
// focusGained ooo event
{ MAP_CHAR_LEN ( " focusGained " ) , { MAP_CHAR_LEN ( " _GotFocus " ) , NULL , ApproveAll , NULL } } ,
// focusLost ooo event
{ MAP_CHAR_LEN ( " focusLost " ) , { MAP_CHAR_LEN ( " _LostFocus " ) , NULL , ApproveAll , NULL } } ,
2010-10-19 23:45:24 -05:00
{ MAP_CHAR_LEN ( " focusLost " ) , { MAP_CHAR_LEN ( " _Exit " ) , ooFocusLostToVBAExit , ApproveType , ( void * ) ( & textCompList ) } } ,
2009-11-04 14:54:23 +00:00
// adjustmentValueChanged ooo event
{ MAP_CHAR_LEN ( " adjustmentValueChanged " ) , { MAP_CHAR_LEN ( " _Scroll " ) , NULL , ApproveAll , NULL } } ,
{ MAP_CHAR_LEN ( " adjustmentValueChanged " ) , { MAP_CHAR_LEN ( " _Change " ) , NULL , ApproveAll , NULL } } ,
// textChanged ooo event
{ MAP_CHAR_LEN ( " textChanged " ) , { MAP_CHAR_LEN ( " _Change " ) , NULL , ApproveAll , NULL } } ,
// keyReleased ooo event
{ MAP_CHAR_LEN ( " keyReleased " ) , { MAP_CHAR_LEN ( " _KeyUp " ) , ooKeyPressedToVBAKeyUpDown , ApproveAll , NULL } } ,
// mouseReleased ooo event
2010-10-19 23:45:24 -05:00
{ MAP_CHAR_LEN ( " mouseReleased " ) , { MAP_CHAR_LEN ( " _Click " ) , ooMouseEvtToVBAMouseEvt , ApproveType , ( void * ) ( & fixedTextList ) } } ,
2009-11-04 14:54:23 +00:00
{ MAP_CHAR_LEN ( " mouseReleased " ) , { MAP_CHAR_LEN ( " _MouseUp " ) , ooMouseEvtToVBAMouseEvt , ApproveAll , NULL } } ,
// mousePressed ooo event
{ MAP_CHAR_LEN ( " mousePressed " ) , { MAP_CHAR_LEN ( " _MouseDown " ) , ooMouseEvtToVBAMouseEvt , ApproveAll , NULL } } ,
{ MAP_CHAR_LEN ( " mousePressed " ) , { MAP_CHAR_LEN ( " _DblClick " ) , ooMouseEvtToVBADblClick , ApproveAll , NULL } } ,
// mouseMoved ooo event
{ MAP_CHAR_LEN ( " mouseMoved " ) , { MAP_CHAR_LEN ( " _MouseMove " ) , ooMouseEvtToVBAMouseEvt , ApproveAll , NULL } } ,
2010-10-19 23:45:24 -05:00
{ MAP_CHAR_LEN ( " mouseDragged " ) , { MAP_CHAR_LEN ( " _MouseMove " ) , ooMouseEvtToVBAMouseEvt , DenyMouseDrag , NULL } } ,
2009-11-04 14:54:23 +00:00
// keyPressed ooo event
2010-10-06 10:16:27 +01:00
{ MAP_CHAR_LEN ( " keyPressed " ) , { MAP_CHAR_LEN ( " _KeyDown " ) , ooKeyPressedToVBAKeyUpDown , ApproveAll , NULL } } ,
{ MAP_CHAR_LEN ( " keyPressed " ) , { MAP_CHAR_LEN ( " _KeyPress " ) , ooKeyPressedToVBAKeyUpDown , DenyKeys , NULL } }
2009-11-04 14:54:23 +00:00
} ;
2009-06-17 13:32:41 +00:00
EventInfoHash & getEventTransInfo ( )
{
static bool initialised = false ;
static EventInfoHash eventTransInfo ;
if ( ! initialised )
{
2009-11-04 14:54:23 +00:00
rtl : : OUString sEventInfo = MAP_CHAR_LEN ( " " ) ;
TranslatePropMap * pTransProp = aTranslatePropMap_Impl ;
2012-05-29 17:23:51 +01:00
int nCount = sizeof ( aTranslatePropMap_Impl ) / sizeof ( aTranslatePropMap_Impl [ 0 ] ) ;
2009-11-04 14:54:23 +00:00
int i = 0 ;
while ( i < nCount )
{
sEventInfo = pTransProp - > sEventInfo ;
std : : list < TranslateInfo > infoList ;
do
{
infoList . push_back ( pTransProp - > aTransInfo ) ;
pTransProp + + ;
i + + ;
} while ( i < nCount & & sEventInfo = = pTransProp - > sEventInfo ) ;
eventTransInfo [ sEventInfo ] = infoList ;
}
2009-06-17 13:32:41 +00:00
initialised = true ;
}
return eventTransInfo ;
}
2010-10-19 23:45:24 -05:00
2009-06-17 13:32:41 +00:00
// Helper class
class ScriptEventHelper
{
public :
ScriptEventHelper ( const Reference < XInterface > & xControl ) ;
Sequence < ScriptEventDescriptor > createEvents ( const rtl : : OUString & sCodeName ) ;
Sequence < rtl : : OUString > getEventListeners ( ) ;
private :
Reference < XComponentContext > m_xCtx ;
Reference < XInterface > m_xControl ;
} ;
bool
eventMethodToDescriptor ( const : : rtl : : OUString & rEventMethod , ScriptEventDescriptor & evtDesc , const : : rtl : : OUString & sCodeName )
{
// format of ControlListener is TypeName::methodname e.g.
// "com.sun.star.awt.XActionListener::actionPerformed" or
// "XActionListener::actionPerformed
: : rtl : : OUString sMethodName ;
: : rtl : : OUString sTypeName ;
sal_Int32 nDelimPos = rEventMethod . indexOf ( DELIM ) ;
if ( nDelimPos = = - 1 )
{
return false ;
}
sMethodName = rEventMethod . copy ( nDelimPos + DELIMLEN ) ;
sTypeName = rEventMethod . copy ( 0 , nDelimPos ) ;
EventInfoHash & infos = getEventTransInfo ( ) ;
// Only create an ScriptEventDescriptor for an event we can translate
// or emulate
2012-01-05 14:15:36 -02:00
if ( ! sMethodName . isEmpty ( )
& & ! sTypeName . isEmpty ( )
2009-06-17 13:32:41 +00:00
& & ( infos . find ( sMethodName ) ! = infos . end ( ) ) )
{
// just fill in CodeName, when the event fires the other
// info is gathered from the event source to determine what
// event handler we try to call
evtDesc . ScriptCode = sCodeName ;
evtDesc . ListenerType = sTypeName ;
evtDesc . EventMethod = sMethodName ;
// set this it VBAInterop, ensures that it doesn't
// get persisted or shown in property editors
2012-06-02 20:19:28 -05:00
evtDesc . ScriptType = rtl : : OUString (
" VBAInterop " ) ;
2009-06-17 13:32:41 +00:00
return true ;
}
return false ;
}
ScriptEventHelper : : ScriptEventHelper ( const Reference < XInterface > & xControl ) : m_xControl ( xControl )
{
Reference < beans : : XPropertySet > xProps (
: : comphelper : : getProcessServiceFactory ( ) , UNO_QUERY_THROW ) ;
m_xCtx . set ( xProps - > getPropertyValue ( rtl : : OUString (
2012-06-02 20:19:28 -05:00
" DefaultContext " ) ) ,
2009-06-17 13:32:41 +00:00
uno : : UNO_QUERY_THROW ) ;
}
Sequence < rtl : : OUString >
ScriptEventHelper : : getEventListeners ( )
{
Reference < lang : : XMultiComponentFactory > xMFac (
m_xCtx - > getServiceManager ( ) , UNO_QUERY ) ;
std : : list < rtl : : OUString > eventMethods ;
if ( xMFac . is ( ) )
{
Reference < beans : : XIntrospection > xIntrospection (
xMFac - > createInstanceWithContext ( rtl : : OUString (
2012-06-02 20:19:28 -05:00
" com.sun.star.beans.Introspection " ) , m_xCtx ) , UNO_QUERY ) ;
2010-10-18 19:37:48 +01:00
2009-06-17 13:32:41 +00:00
Reference < beans : : XIntrospectionAccess > xIntrospectionAccess ;
if ( xIntrospection . is ( ) )
{
xIntrospectionAccess = xIntrospection - > inspect (
makeAny ( m_xControl ) ) ;
Sequence < Type > aControlListeners =
xIntrospectionAccess - > getSupportedListeners ( ) ;
sal_Int32 nLength = aControlListeners . getLength ( ) ;
for ( sal_Int32 i = 0 ; i < nLength ; + + i )
{
Type & listType = aControlListeners [ i ] ;
rtl : : OUString sFullTypeName = listType . getTypeName ( ) ;
Sequence < : : rtl : : OUString > sMeths =
comphelper : : getEventMethodsForType ( listType ) ;
sal_Int32 sMethLen = sMeths . getLength ( ) ;
for ( sal_Int32 j = 0 ; j < sMethLen ; + + j )
{
rtl : : OUString sEventMethod = sFullTypeName ;
sEventMethod + = DELIM ;
sEventMethod + = sMeths [ j ] ;
eventMethods . push_back ( sEventMethod ) ;
}
}
}
}
Sequence < rtl : : OUString > sEventMethodNames ( eventMethods . size ( ) ) ;
std : : list < rtl : : OUString > : : const_iterator it = eventMethods . begin ( ) ;
rtl : : OUString * pDest = sEventMethodNames . getArray ( ) ;
for ( ; it ! = eventMethods . end ( ) ; + + it , + + pDest )
* pDest = * it ;
return sEventMethodNames ;
}
Sequence < ScriptEventDescriptor >
ScriptEventHelper : : createEvents ( const rtl : : OUString & sCodeName )
{
Sequence < rtl : : OUString > aControlListeners = getEventListeners ( ) ;
rtl : : OUString * pSrc = aControlListeners . getArray ( ) ;
sal_Int32 nLength = aControlListeners . getLength ( ) ;
Sequence < ScriptEventDescriptor > aDest ( nLength ) ;
sal_Int32 nEvts = 0 ;
for ( sal_Int32 i = 0 ; i < nLength ; + + i , + + pSrc )
{
// from getListeners eventName is of form
// "com.sun.star.awt.XActionListener::actionPerformed"
// we need to strip "com.sun.star.awt." from that for form
// controls
ScriptEventDescriptor evtDesc ;
if ( eventMethodToDescriptor ( * pSrc , evtDesc , sCodeName ) )
{
sal_Int32 dIndex = nEvts ;
+ + nEvts ;
if ( nEvts > aDest . getLength ( ) )
aDest . realloc ( nEvts ) ; // should never happen
aDest [ dIndex ] = evtDesc ;
}
}
aDest . realloc ( nEvts ) ;
return aDest ;
}
typedef : : cppu : : WeakImplHelper1 < container : : XNameContainer > NameContainer_BASE ;
class ReadOnlyEventsNameContainer : public NameContainer_BASE
{
public :
ReadOnlyEventsNameContainer ( const Sequence < rtl : : OUString > & eventMethods , const rtl : : OUString & sCodeName ) ;
// XNameContainer
virtual void SAL_CALL insertByName ( const : : rtl : : OUString & , const Any & ) throw ( lang : : IllegalArgumentException , container : : ElementExistException , lang : : WrappedTargetException , RuntimeException )
{
2012-06-02 20:19:28 -05:00
throw RuntimeException ( rtl : : OUString ( " ReadOnly container " ) , Reference < XInterface > ( ) ) ;
2009-06-17 13:32:41 +00:00
}
virtual void SAL_CALL removeByName ( const : : rtl : : OUString & ) throw ( : : com : : sun : : star : : container : : NoSuchElementException , lang : : WrappedTargetException , RuntimeException )
{
2012-06-02 20:19:28 -05:00
throw RuntimeException ( rtl : : OUString ( " ReadOnly container " ) , Reference < XInterface > ( ) ) ;
2009-06-17 13:32:41 +00:00
}
// XNameReplace
virtual void SAL_CALL replaceByName ( const : : rtl : : OUString & , const Any & ) throw ( lang : : IllegalArgumentException , container : : NoSuchElementException , lang : : WrappedTargetException , RuntimeException )
{
2012-06-02 20:19:28 -05:00
throw RuntimeException ( rtl : : OUString ( " ReadOnly container " ) , Reference < XInterface > ( ) ) ;
2009-06-17 13:32:41 +00:00
}
// XNameAccess
virtual Any SAL_CALL getByName ( const : : rtl : : OUString & aName ) throw ( container : : NoSuchElementException , lang : : WrappedTargetException , RuntimeException ) ;
virtual Sequence < : : rtl : : OUString > SAL_CALL getElementNames ( ) throw ( RuntimeException ) ;
virtual : : sal_Bool SAL_CALL hasByName ( const : : rtl : : OUString & aName ) throw ( RuntimeException ) ;
// XElementAccess
virtual Type SAL_CALL getElementType ( ) throw ( RuntimeException )
{ return getCppuType ( static_cast < const rtl : : OUString * > ( 0 ) ) ; }
virtual : : sal_Bool SAL_CALL hasElements ( ) throw ( RuntimeException )
{ return ( ( m_hEvents . size ( ) > 0 ? sal_True : sal_False ) ) ; }
private :
2011-02-05 13:18:52 +01:00
typedef boost : : unordered_map < rtl : : OUString , Any , : : rtl : : OUStringHash ,
2009-06-17 13:32:41 +00:00
: : std : : equal_to < : : rtl : : OUString > > EventSupplierHash ;
EventSupplierHash m_hEvents ;
} ;
ReadOnlyEventsNameContainer : : ReadOnlyEventsNameContainer ( const Sequence < rtl : : OUString > & eventMethods , const rtl : : OUString & sCodeName )
{
const rtl : : OUString * pSrc = eventMethods . getConstArray ( ) ;
sal_Int32 nLen = eventMethods . getLength ( ) ;
for ( sal_Int32 index = 0 ; index < nLen ; + + index , + + pSrc )
{
Any aDesc ;
ScriptEventDescriptor evtDesc ;
if ( eventMethodToDescriptor ( * pSrc , evtDesc , sCodeName ) )
{
aDesc < < = evtDesc ;
m_hEvents [ * pSrc ] = aDesc ;
}
}
}
Any SAL_CALL
ReadOnlyEventsNameContainer : : getByName ( const : : rtl : : OUString & aName ) throw ( container : : NoSuchElementException , lang : : WrappedTargetException , RuntimeException ) {
EventSupplierHash : : const_iterator it = m_hEvents . find ( aName ) ;
if ( it = = m_hEvents . end ( ) )
throw container : : NoSuchElementException ( ) ;
return it - > second ;
}
Sequence < : : rtl : : OUString > SAL_CALL
ReadOnlyEventsNameContainer : : getElementNames ( ) throw ( RuntimeException )
{
Sequence < : : rtl : : OUString > names ( m_hEvents . size ( ) ) ;
rtl : : OUString * pDest = names . getArray ( ) ;
EventSupplierHash : : const_iterator it = m_hEvents . begin ( ) ;
EventSupplierHash : : const_iterator it_end = m_hEvents . end ( ) ;
for ( sal_Int32 index = 0 ; it ! = it_end ; + + index , + + pDest , + + it )
* pDest = it - > first ;
return names ;
}
sal_Bool SAL_CALL
ReadOnlyEventsNameContainer : : hasByName ( const : : rtl : : OUString & aName ) throw ( RuntimeException )
{
EventSupplierHash : : const_iterator it = m_hEvents . find ( aName ) ;
if ( it = = m_hEvents . end ( ) )
return sal_False ;
return sal_True ;
}
typedef : : cppu : : WeakImplHelper1 < XScriptEventsSupplier > EventsSupplier_BASE ;
class ReadOnlyEventsSupplier : public EventsSupplier_BASE
{
public :
ReadOnlyEventsSupplier ( const Sequence < : : rtl : : OUString > & eventMethods , const rtl : : OUString & sCodeName )
{ m_xNameContainer = new ReadOnlyEventsNameContainer ( eventMethods , sCodeName ) ; }
// XScriptEventSupplier
virtual Reference < container : : XNameContainer > SAL_CALL getEvents ( ) throw ( RuntimeException ) { return m_xNameContainer ; }
private :
Reference < container : : XNameContainer > m_xNameContainer ;
} ;
2010-10-06 10:16:27 +01:00
typedef : : cppu : : WeakImplHelper3 < XScriptListener , util : : XCloseListener , lang : : XInitialization > EventListener_BASE ;
2009-06-17 13:32:41 +00:00
# define EVENTLSTNR_PROPERTY_ID_MODEL 1
2012-06-02 20:19:28 -05:00
# define EVENTLSTNR_PROPERTY_MODEL ::rtl::OUString( "Model" )
2009-06-17 13:32:41 +00:00
class EventListener : public EventListener_BASE
, public : : comphelper : : OMutexAndBroadcastHelper
, public : : comphelper : : OPropertyContainer
, public : : comphelper : : OPropertyArrayUsageHelper < EventListener >
{
public :
EventListener ( const Reference < XComponentContext > & rxContext ) ;
// XEventListener
virtual void SAL_CALL disposing ( const lang : : EventObject & Source ) throw ( RuntimeException ) ;
2009-12-15 10:22:25 +00:00
using cppu : : OPropertySetHelper : : disposing ;
2009-06-17 13:32:41 +00:00
// XScriptListener
virtual void SAL_CALL firing ( const ScriptEvent & evt ) throw ( RuntimeException ) ;
virtual Any SAL_CALL approveFiring ( const ScriptEvent & evt ) throw ( reflection : : InvocationTargetException , RuntimeException ) ;
2010-10-06 10:16:27 +01:00
// XCloseListener
virtual void SAL_CALL queryClosing ( const lang : : EventObject & Source , : : sal_Bool GetsOwnership ) throw ( util : : CloseVetoException , uno : : RuntimeException ) ;
virtual void SAL_CALL notifyClosing ( const lang : : EventObject & Source ) throw ( uno : : RuntimeException ) ;
2009-06-17 13:32:41 +00:00
// XPropertySet
virtual : : com : : sun : : star : : uno : : Reference < : : com : : sun : : star : : beans : : XPropertySetInfo > SAL_CALL getPropertySetInfo ( ) throw ( : : com : : sun : : star : : uno : : RuntimeException ) ;
// XInitialization
virtual void SAL_CALL initialize ( const Sequence < Any > & aArguments ) throw ( Exception , RuntimeException ) ;
// XInterface
DECLARE_XINTERFACE ( )
// XTypeProvider
DECLARE_XTYPEPROVIDER ( )
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 )
{
2010-10-06 10:16:27 +01:00
if ( nHandle = = EVENTLSTNR_PROPERTY_ID_MODEL )
{
uno : : Reference < frame : : XModel > xModel ( rValue , uno : : UNO_QUERY ) ;
if ( xModel ! = m_xModel )
{
// Remove the listener from the old XCloseBroadcaster.
uno : : Reference < util : : XCloseBroadcaster > xCloseBroadcaster ( m_xModel , uno : : UNO_QUERY ) ;
if ( xCloseBroadcaster . is ( ) )
{
xCloseBroadcaster - > removeCloseListener ( this ) ;
}
// Add the listener into the new XCloseBroadcaster.
xCloseBroadcaster = uno : : Reference < util : : XCloseBroadcaster > ( xModel , uno : : UNO_QUERY ) ;
if ( xCloseBroadcaster . is ( ) )
{
xCloseBroadcaster - > addCloseListener ( this ) ;
}
}
}
2009-06-17 13:32:41 +00:00
OPropertyContainer : : setFastPropertyValue ( nHandle , rValue ) ;
if ( nHandle = = EVENTLSTNR_PROPERTY_ID_MODEL )
setShellFromModel ( ) ;
}
protected :
// OPropertySetHelper
virtual : : cppu : : IPropertyArrayHelper & SAL_CALL getInfoHelper ( ) ;
// OPropertyArrayUsageHelper
virtual : : cppu : : IPropertyArrayHelper * createArrayHelper ( ) const ;
private :
2010-10-06 10:16:27 +01:00
# if ASYNC
DECL_LINK ( OnAsyncScriptEvent , ScriptEvent * ) ;
# endif
2009-06-17 13:32:41 +00:00
void setShellFromModel ( ) ;
void firing_Impl ( const ScriptEvent & evt , Any * pSyncRet = NULL ) throw ( RuntimeException ) ;
Reference < XComponentContext > m_xContext ;
Reference < frame : : XModel > m_xModel ;
2010-10-06 10:16:27 +01:00
sal_Bool m_bDocClosed ;
2010-11-02 16:22:07 +00:00
SfxObjectShell * mpShell ;
rtl : : OUString msProject ;
2009-06-17 13:32:41 +00:00
} ;
EventListener : : EventListener ( const Reference < XComponentContext > & rxContext ) :
2010-10-06 10:16:27 +01:00
OPropertyContainer ( GetBroadcastHelper ( ) ) , m_xContext ( rxContext ) , m_bDocClosed ( sal_False ) , mpShell ( 0 )
2009-06-17 13:32:41 +00:00
{
registerProperty ( EVENTLSTNR_PROPERTY_MODEL , EVENTLSTNR_PROPERTY_ID_MODEL ,
beans : : PropertyAttribute : : TRANSIENT , & m_xModel , : : getCppuType ( & m_xModel ) ) ;
2012-06-02 20:19:28 -05:00
msProject = rtl : : OUString ( " Standard " ) ;
2009-06-17 13:32:41 +00:00
}
void
EventListener : : setShellFromModel ( )
{
// reset mpShell
mpShell = 0 ;
SfxObjectShell * pShell = SfxObjectShell : : GetFirst ( ) ;
while ( m_xModel . is ( ) & & pShell )
{
if ( pShell - > GetModel ( ) = = m_xModel )
{
mpShell = pShell ;
break ;
}
pShell = SfxObjectShell : : GetNext ( * pShell ) ;
}
2010-11-02 16:22:07 +00:00
// set ProjectName from model
try
{
uno : : Reference < beans : : XPropertySet > xProps ( m_xModel , UNO_QUERY_THROW ) ;
2012-06-02 20:19:28 -05:00
uno : : Reference < script : : vba : : XVBACompatibility > xVBAMode ( xProps - > getPropertyValue ( rtl : : OUString ( " BasicLibraries " ) ) , uno : : UNO_QUERY_THROW ) ;
2010-11-02 16:22:07 +00:00
msProject = xVBAMode - > getProjectName ( ) ;
}
catch ( uno : : Exception & ) { }
2009-06-17 13:32:41 +00:00
}
//XEventListener
void
EventListener : : disposing ( const lang : : EventObject & ) throw ( RuntimeException )
{
}
//XScriptListener
void SAL_CALL
EventListener : : firing ( const ScriptEvent & evt ) throw ( RuntimeException )
{
2010-10-06 10:16:27 +01:00
# if ASYNC
// needs some logic to check if the event handler is oneway or not
// if not oneway then firing_Impl otherwise... as below
acquire ( ) ;
Application : : PostUserEvent ( LINK ( this , EventListener , OnAsyncScriptEvent ) , new ScriptEvent ( evt ) ) ;
# else
2009-06-17 13:32:41 +00:00
firing_Impl ( evt ) ;
2010-10-06 10:16:27 +01:00
# endif
2009-06-17 13:32:41 +00:00
}
2010-10-06 10:16:27 +01:00
# if ASYNC
IMPL_LINK ( EventListener , OnAsyncScriptEvent , ScriptEvent * , _pEvent )
{
if ( ! _pEvent )
return 1L ;
{
// #FIXME if we enable ASYNC we probably need something like
// below
//::osl::ClearableMutexGuard aGuard( m_aMutex );
//if ( !impl_isDisposed_nothrow() )
// impl_doFireScriptEvent_nothrow( aGuard, *_pEvent, NULL );
firing_Impl ( * _pEvent , NULL ) ;
}
delete _pEvent ;
// we acquired ourself immediately before posting the event
release ( ) ;
return 0L ;
}
# endif
2009-06-17 13:32:41 +00:00
Any SAL_CALL
EventListener : : approveFiring ( const ScriptEvent & evt ) throw ( reflection : : InvocationTargetException , RuntimeException )
{
Any ret ;
firing_Impl ( evt , & ret ) ;
return ret ;
}
2010-10-06 10:16:27 +01:00
// XCloseListener
void SAL_CALL
2010-11-02 16:22:07 +00:00
EventListener : : queryClosing ( const lang : : EventObject & /*Source*/ , : : sal_Bool /*GetsOwnership*/ ) throw ( util : : CloseVetoException , uno : : RuntimeException )
2010-10-06 10:16:27 +01:00
{
//Nothing to do
}
void SAL_CALL
2010-11-02 16:22:07 +00:00
EventListener : : notifyClosing ( const lang : : EventObject & /*Source*/ ) throw ( uno : : RuntimeException )
2010-10-06 10:16:27 +01:00
{
m_bDocClosed = sal_True ;
uno : : Reference < util : : XCloseBroadcaster > xCloseBroadcaster ( m_xModel , uno : : UNO_QUERY ) ;
if ( xCloseBroadcaster . is ( ) )
{
xCloseBroadcaster - > removeCloseListener ( this ) ;
}
}
2009-06-17 13:32:41 +00:00
// XInitialization
void SAL_CALL
EventListener : : initialize ( const Sequence < Any > & aArguments ) throw ( Exception , RuntimeException )
{
if ( aArguments . getLength ( ) = = 1 )
aArguments [ 0 ] > > = m_xModel ;
OSL_TRACE ( " EventListener::initialize() args %d m_xModel %d " , aArguments . getLength ( ) , m_xModel . is ( ) ) ;
}
// XInterface
IMPLEMENT_FORWARD_XINTERFACE2 ( EventListener , EventListener_BASE , OPropertyContainer )
// XTypeProvider
IMPLEMENT_FORWARD_XTYPEPROVIDER2 ( EventListener , EventListener_BASE , OPropertyContainer )
// OPropertySetHelper
: : cppu : : IPropertyArrayHelper &
EventListener : : getInfoHelper ( )
{
return * getArrayHelper ( ) ;
}
// OPropertyArrayUsageHelper
: : cppu : : IPropertyArrayHelper *
EventListener : : createArrayHelper ( ) const
{
Sequence < beans : : Property > aProps ;
describeProperties ( aProps ) ;
return new : : cppu : : OPropertyArrayHelper ( aProps ) ;
}
// XPropertySet
Reference < beans : : XPropertySetInfo >
EventListener : : getPropertySetInfo ( ) throw ( RuntimeException )
{
Reference < beans : : XPropertySetInfo > xInfo ( createPropertySetInfo ( getInfoHelper ( ) ) ) ;
return xInfo ;
}
2010-10-19 23:45:24 -05:00
2009-11-04 14:54:23 +00:00
//decide if the control should execute the event
bool ApproveAll ( const ScriptEvent & , void * )
{
return true ;
}
2009-06-17 13:32:41 +00:00
2009-11-04 14:54:23 +00:00
//for the given control type in evt.Arguments[0], look for if it appears in the type list in pPara
bool FindControl ( const ScriptEvent & evt , void * pPara )
{
lang : : EventObject aEvent ;
evt . Arguments [ 0 ] > > = aEvent ;
uno : : Reference < uno : : XInterface > xInterface ( aEvent . Source , uno : : UNO_QUERY ) ;
TypeList * pTypeListInfo = static_cast < TypeList * > ( pPara ) ;
Type * pType = pTypeListInfo - > pTypeList ;
int nLen = pTypeListInfo - > nListLength ;
for ( int i = 0 ; i < nLen ; i + + )
{
if ( xInterface - > queryInterface ( * pType ) . hasValue ( ) )
{
return true ;
}
pType + + ;
}
return false ;
}
//if the the given control type in evt.Arguments[0] appears in the type list in pPara, then approve the execution
bool ApproveType ( const ScriptEvent & evt , void * pPara )
{
return FindControl ( evt , pPara ) ;
}
//if the the given control type in evt.Arguments[0] appears in the type list in pPara, then deny the execution
bool DenyType ( const ScriptEvent & evt , void * pPara )
{
return ! FindControl ( evt , pPara ) ;
}
//when mouse is moving, either the mouse button is pressed or some key is pressed can trigger the OO mouseDragged event,
//the former should be denyed, and the latter allowed, only by doing so can the VBA MouseMove event when the "Shift" key is
//pressed can be correctly triggered
bool DenyMouseDrag ( const ScriptEvent & evt , void * )
{
awt : : MouseEvent aEvent ;
evt . Arguments [ 0 ] > > = aEvent ;
if ( aEvent . Buttons = = 0 )
{
return true ;
}
else
{
return false ;
}
}
2010-10-06 10:16:27 +01:00
//For some keys, press them will cause Symphony keyPressed event, but will not cause any events in Excel, so deny these key events
bool DenyKeys ( const ScriptEvent & evt , void * /*pPara*/ )
{
awt : : KeyEvent aEvent ;
evt . Arguments [ 0 ] > > = aEvent ;
if ( aEvent . KeyChar = = 0 | | aEvent . KeyChar = = 8 )
{
return false ;
}
else
{
return true ;
}
}
2009-11-04 14:54:23 +00:00
2010-10-19 23:45:24 -05:00
2009-06-17 13:32:41 +00:00
// EventListener
void
2010-10-06 10:16:27 +01:00
EventListener : : firing_Impl ( const ScriptEvent & evt , Any * pRet ) throw ( RuntimeException )
2009-06-17 13:32:41 +00:00
{
OSL_TRACE ( " EventListener::firing_Impl( FAKE VBA_EVENTS ) " ) ;
static const : : rtl : : OUString vbaInterOp =
2012-06-02 20:19:28 -05:00
: : rtl : : OUString ( " VBAInterop " ) ;
2009-06-17 13:32:41 +00:00
// let default handlers deal with non vba stuff
if ( ! evt . ScriptType . equals ( vbaInterOp ) )
return ;
lang : : EventObject aEvent ;
evt . Arguments [ 0 ] > > = aEvent ;
2010-10-06 10:16:27 +01:00
OSL_TRACE ( " evt.MethodName is %s " , rtl : : OUStringToOString ( evt . MethodName , RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
2009-06-17 13:32:41 +00:00
OSL_TRACE ( " Argument[0] is %s " , rtl : : OUStringToOString ( comphelper : : anyToString ( evt . Arguments [ 0 ] ) , RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
OSL_TRACE ( " Getting Control " ) ;
2012-06-02 20:19:28 -05:00
rtl : : OUString sName = rtl : : OUString ( " UserForm " ) ;
2009-06-17 13:32:41 +00:00
OSL_TRACE ( " Getting Name " ) ;
uno : : Reference < awt : : XDialog > xDlg ( aEvent . Source , uno : : UNO_QUERY ) ;
if ( ! xDlg . is ( ) )
2010-10-06 10:16:27 +01:00
{
2010-11-02 16:22:07 +00:00
OSL_TRACE ( " Getting Control " ) ;
2010-10-06 10:16:27 +01:00
// evt.Source is
// a) Dialog
// b) xShapeControl ( from api (sheet control) )
// c) eventmanager ( I guess )
// d) vba control ( from api also )
2010-11-02 16:22:07 +00:00
uno : : Reference < drawing : : XControlShape > xCntrlShape ( evt . Source , uno : : UNO_QUERY ) ;
uno : : Reference < awt : : XControl > xControl ( aEvent . Source , uno : : UNO_QUERY ) ;
if ( xCntrlShape . is ( ) )
2010-10-06 10:16:27 +01:00
{
2010-11-02 16:22:07 +00:00
// for sheet controls ( that fire from the api ) we don't
// have the real control ( thats only available from the view )
// api code creates just a control instance that is transferred
// via aEvent.Arguments[ 0 ] that control though has no
// info like name etc.
OSL_TRACE ( " Got control shape " ) ;
uno : : Reference < container : : XNamed > xName ( xCntrlShape - > getControl ( ) , uno : : UNO_QUERY_THROW ) ;
OSL_TRACE ( " Got xnamed " ) ;
sName = xName - > getName ( ) ;
}
else
{
// Userform control ( fired from the api or from event manager )
uno : : Reference < beans : : XPropertySet > xProps ;
OSL_TRACE ( " Getting properties " ) ;
xProps . set ( xControl - > getModel ( ) , uno : : UNO_QUERY_THROW ) ;
2012-06-02 20:19:28 -05:00
xProps - > getPropertyValue ( rtl : : OUString ( " Name " ) ) > > = sName ;
2010-11-02 16:22:07 +00:00
}
2010-10-06 10:16:27 +01:00
}
2009-06-17 13:32:41 +00:00
//dumpEvent( evt );
EventInfoHash & infos = getEventTransInfo ( ) ;
EventInfoHash : : const_iterator eventInfo_it = infos . find ( evt . MethodName ) ;
EventInfoHash : : const_iterator it_end = infos . end ( ) ;
if ( eventInfo_it = = it_end )
{
OSL_TRACE ( " Bogus event for %s " ,
rtl : : OUStringToOString ( evt . ScriptType , RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
return ;
}
uno : : Reference < script : : provider : : XScriptProviderSupplier > xSPS ( m_xModel , uno : : UNO_QUERY ) ;
uno : : Reference < script : : provider : : XScriptProvider > xScriptProvider ;
if ( xSPS . is ( ) )
xScriptProvider = xSPS - > getScriptProvider ( ) ;
if ( xScriptProvider . is ( ) & & mpShell )
{
std : : list < TranslateInfo > matchingMethods ;
std : : list < TranslateInfo > : : const_iterator txInfo =
eventInfo_it - > second . begin ( ) ;
std : : list < TranslateInfo > : : const_iterator txInfo_end = eventInfo_it - > second . end ( ) ;
2010-10-06 10:16:27 +01:00
BasicManager * pBasicManager = mpShell - > GetBasicManager ( ) ;
rtl : : OUString sProject ;
rtl : : OUString sScriptCode ( evt . ScriptCode ) ;
// dialogs pass their own library, presence of Dot determines that
if ( sScriptCode . indexOf ( ' . ' ) = = - 1 )
{
2010-10-13 10:51:50 +01:00
//'Project' is a better default but I want to force failures
2012-06-02 20:19:28 -05:00
//rtl::OUString sMacroLoc("Project");
sProject = rtl : : OUString ( " Standard " ) ;
2010-10-06 10:16:27 +01:00
2010-10-13 10:51:50 +01:00
if ( pBasicManager - > GetName ( ) . Len ( ) > 0 )
sProject = pBasicManager - > GetName ( ) ;
2010-10-06 10:16:27 +01:00
}
else
{
sal_Int32 nIndex = sScriptCode . indexOf ( ' . ' ) ;
sProject = sScriptCode . copy ( 0 , nIndex ) ;
2010-10-13 10:51:50 +01:00
sScriptCode = sScriptCode . copy ( nIndex + 1 ) ;
2010-10-06 10:16:27 +01:00
}
rtl : : OUString sMacroLoc = sProject ;
2012-06-02 20:19:28 -05:00
sMacroLoc = sMacroLoc . concat ( rtl : : OUString ( " . " ) ) ;
sMacroLoc = sMacroLoc . concat ( sScriptCode ) . concat ( rtl : : OUString ( " . " ) ) ;
2010-10-06 10:16:27 +01:00
OSL_TRACE ( " sMacroLoc is %s " , rtl : : OUStringToOString ( sMacroLoc , RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
for ( ; txInfo ! = txInfo_end ; + + txInfo )
2009-06-17 13:32:41 +00:00
{
2010-10-06 10:16:27 +01:00
// If the document is closed, we should not execute macro.
if ( m_bDocClosed )
{
break ;
}
rtl : : OUString sTemp = sName . concat ( ( * txInfo ) . sVBAName ) ;
2009-06-17 13:32:41 +00:00
// see if we have a match for the handlerextension
// where ScriptCode is methodname_handlerextension
2010-10-06 10:16:27 +01:00
rtl : : OUString sToResolve = sMacroLoc . concat ( sTemp ) ;
2009-06-17 13:32:41 +00:00
OSL_TRACE ( " *** trying to invoke %s " ,
2010-10-06 10:16:27 +01:00
rtl : : OUStringToOString ( sToResolve , RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
2011-03-15 00:23:23 -05:00
ooo : : vba : : MacroResolvedInfo aMacroResolvedInfo = ooo : : vba : : resolveVBAMacro ( mpShell , sToResolve ) ;
if ( aMacroResolvedInfo . mbFound )
2009-06-17 13:32:41 +00:00
{
2010-10-19 23:45:24 -05:00
2009-11-04 14:54:23 +00:00
if ( ! txInfo - > ApproveRule ( evt , txInfo - > pPara ) )
{
continue ;
}
2010-10-19 23:45:24 -05:00
2009-06-17 13:32:41 +00:00
// !! translate arguments & emulate events where necessary
Sequence < Any > aArguments ;
if ( ( * txInfo ) . toVBA )
aArguments = ( * txInfo ) . toVBA ( evt . Arguments ) ;
else
aArguments = evt . Arguments ;
if ( aArguments . getLength ( ) )
{
// call basic event handlers for event
// create script url
2011-03-15 00:23:23 -05:00
rtl : : OUString url = aMacroResolvedInfo . msResolvedMacro ;
2009-06-17 13:32:41 +00:00
2010-10-06 10:16:27 +01:00
OSL_TRACE ( " resolved script = %s " ,
2009-06-17 13:32:41 +00:00
rtl : : OUStringToOString ( url ,
RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
try
{
2012-06-02 20:19:28 -05:00
uno : : Any aDummyCaller = uno : : makeAny ( rtl : : OUString ( " Error " ) ) ;
2010-10-06 10:16:27 +01:00
if ( pRet )
ooo : : vba : : executeMacro ( mpShell , url , aArguments , * pRet , aDummyCaller ) ;
else
2010-03-01 12:29:56 +00:00
{
uno : : Any aRet ;
2010-10-06 10:16:27 +01:00
ooo : : vba : : executeMacro ( mpShell , url , aArguments , aRet , aDummyCaller ) ;
2010-03-01 12:29:56 +00:00
}
2009-06-17 13:32:41 +00:00
}
catch ( uno : : Exception & e )
{
OSL_TRACE ( " event script raised %s " , rtl : : OUStringToOString ( e . Message , RTL_TEXTENCODING_UTF8 ) . getStr ( ) ) ;
}
}
}
}
}
}
typedef : : cppu : : WeakImplHelper1 < XVBAToOOEventDescGen > VBAToOOEventDescGen_BASE ;
class VBAToOOEventDescGen : public VBAToOOEventDescGen_BASE
{
public :
VBAToOOEventDescGen ( const Reference < XComponentContext > & rxContext ) ;
// XVBAToOOEventDescGen
virtual Sequence < ScriptEventDescriptor > SAL_CALL getEventDescriptions ( const Reference < XInterface > & control , const rtl : : OUString & sCodeName ) throw ( RuntimeException ) ;
virtual Reference < XScriptEventsSupplier > SAL_CALL getEventSupplier ( const Reference < XInterface > & xControl , const rtl : : OUString & sCodeName ) throw ( : : com : : sun : : star : : uno : : RuntimeException ) ;
private :
Reference < XComponentContext > m_xContext ;
} ;
VBAToOOEventDescGen : : VBAToOOEventDescGen ( const Reference < XComponentContext > & rxContext ) : m_xContext ( rxContext ) { }
Sequence < ScriptEventDescriptor > SAL_CALL
VBAToOOEventDescGen : : getEventDescriptions ( const Reference < XInterface > & xControl , const rtl : : OUString & sCodeName ) throw ( RuntimeException )
{
ScriptEventHelper evntHelper ( xControl ) ;
return evntHelper . createEvents ( sCodeName ) ;
}
Reference < XScriptEventsSupplier > SAL_CALL
VBAToOOEventDescGen : : getEventSupplier ( const Reference < XInterface > & xControl , const rtl : : OUString & sCodeName ) throw ( : : com : : sun : : star : : uno : : RuntimeException )
{
ScriptEventHelper evntHelper ( xControl ) ;
Reference < XScriptEventsSupplier > xSupplier =
new ReadOnlyEventsSupplier (
evntHelper . getEventListeners ( ) , sCodeName ) ;
return xSupplier ;
}
// Component related
namespace evtlstner
{
: : rtl : : OUString SAL_CALL getImplementationName ( )
{
static : : rtl : : OUString * pImplName = 0 ;
if ( ! pImplName )
{
: : osl : : MutexGuard aGuard ( : : osl : : Mutex : : getGlobalMutex ( ) ) ;
if ( ! pImplName )
{
2012-06-02 20:19:28 -05:00
static : : rtl : : OUString aImplName ( " ooo.vba.EventListener " ) ;
2009-06-17 13:32:41 +00:00
pImplName = & aImplName ;
}
}
return * pImplName ;
}
uno : : Reference < XInterface > SAL_CALL create (
Reference < XComponentContext > const & xContext )
2012-01-26 16:00:09 +01:00
SAL_THROW ( ( ) )
2009-06-17 13:32:41 +00:00
{
return static_cast < lang : : XTypeProvider * > ( new EventListener ( xContext ) ) ;
}
Sequence < : : rtl : : OUString > SAL_CALL getSupportedServiceNames ( )
{
const : : rtl : : OUString strName ( : : evtlstner : : getImplementationName ( ) ) ;
return Sequence < : : rtl : : OUString > ( & strName , 1 ) ;
}
}
namespace ooevtdescgen
{
: : rtl : : OUString SAL_CALL getImplementationName ( )
{
static : : rtl : : OUString * pImplName = 0 ;
if ( ! pImplName )
{
: : osl : : MutexGuard aGuard ( : : osl : : Mutex : : getGlobalMutex ( ) ) ;
if ( ! pImplName )
{
2012-06-02 20:19:28 -05:00
static : : rtl : : OUString aImplName ( " ooo.vba.VBAToOOEventDesc " ) ;
2009-06-17 13:32:41 +00:00
pImplName = & aImplName ;
}
}
return * pImplName ;
}
uno : : Reference < XInterface > SAL_CALL create (
Reference < XComponentContext > const & xContext )
2012-01-26 16:00:09 +01:00
SAL_THROW ( ( ) )
2009-06-17 13:32:41 +00:00
{
return static_cast < lang : : XTypeProvider * > ( new VBAToOOEventDescGen ( xContext ) ) ;
}
Sequence < : : rtl : : OUString > SAL_CALL getSupportedServiceNames ( )
{
const : : rtl : : OUString strName ( : : ooevtdescgen : : getImplementationName ( ) ) ;
return Sequence < : : rtl : : OUString > ( & strName , 1 ) ;
}
}
2010-10-12 15:53:47 +02:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */