28#include <ooo/vba/XVBAToOOEventDescGen.hpp>
30#include <com/sun/star/beans/XPropertySet.hpp>
31#include <com/sun/star/beans/theIntrospection.hpp>
32#include <com/sun/star/beans/PropertyAttribute.hpp>
34#include <com/sun/star/lang/XMultiComponentFactory.hpp>
35#include <com/sun/star/lang/XServiceInfo.hpp>
36#include <com/sun/star/lang/XInitialization.hpp>
38#include <com/sun/star/util/XCloseListener.hpp>
39#include <com/sun/star/util/XCloseBroadcaster.hpp>
41#include <com/sun/star/frame/XModel.hpp>
43#include <com/sun/star/script/ScriptEventDescriptor.hpp>
44#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
46#include <com/sun/star/container/XNamed.hpp>
48#include <com/sun/star/drawing/XControlShape.hpp>
50#include <com/sun/star/awt/XControl.hpp>
51#include <com/sun/star/awt/XDialog.hpp>
52#include <com/sun/star/awt/KeyEvent.hpp>
53#include <com/sun/star/awt/MouseEvent.hpp>
54#include <com/sun/star/awt/XFixedText.hpp>
55#include <com/sun/star/awt/XTextComponent.hpp>
56#include <com/sun/star/awt/XComboBox.hpp>
57#include <com/sun/star/awt/XRadioButton.hpp>
58#include <com/sun/star/awt/XListBox.hpp>
65#include <com/sun/star/script/XScriptListener.hpp>
71#include <unordered_map>
79constexpr std::u16string_view
DELIM =
u"::";
82static bool isKeyEventOk( awt::KeyEvent& evt,
const Sequence< Any >& params )
84 return params.hasElements() && ( params[ 0 ] >>= evt );
87static bool isMouseEventOk( awt::MouseEvent& evt,
const Sequence< Any >& params )
89 return params.hasElements() && ( params[ 0 ] >>= evt );
97 (evt.ClickCount != 2) )
98 return Sequence< Any >();
108 return Sequence< Any >();
110 Sequence< Any > translatedParams{
Any(evt.Buttons),
114 return translatedParams;
122 return Sequence< Any >();
124 Reference< msforms::XReturnInteger> xKeyCode =
new ReturnInteger( sal_Int32( evt.KeyCode ) );
125 Sequence< Any > translatedParams{
Any(xKeyCode) };
126 return translatedParams;
134 return Sequence< Any >();
136 Reference< msforms::XReturnInteger> xKeyCode =
new ReturnInteger( evt.KeyCode );
137 sal_Int8 shift = sal::static_int_cast<sal_Int8>( evt.Modifiers );
140 Sequence< Any > translatedParams{
Any(xKeyCode),
Any(
shift) };
141 return translatedParams;
144typedef Sequence< Any > (*
Translator)(
const Sequence< Any >&);
153 bool (*ApproveRule)(
const ScriptEvent& evt,
void const * pPara);
159typedef std::unordered_map<
165struct TranslatePropMap
168 TranslateInfo aTransInfo;
173static bool ApproveAll(
const ScriptEvent& evt,
void const * pPara);
174static bool ApproveType(
const ScriptEvent& evt,
void const * pPara);
175static bool DenyType(
const ScriptEvent& evt,
void const * pPara);
204 { OUString(
"actionPerformed"), { OUString(
"_Change"),
nullptr,
DenyType,
static_cast<void const *
>(&
radioButtonList) } },
206 { OUString(
"actionPerformed"), { OUString(
"_Click"),
nullptr,
ApproveAll,
nullptr } },
209 { OUString(
"itemStateChanged"), { OUString(
"_Click"),
nullptr,
ApproveType,
static_cast<void const *
>(&
comboBoxList) } },
211 { OUString(
"itemStateChanged"), { OUString(
"_Click"),
nullptr,
ApproveType,
static_cast<void const *
>(&
listBoxList) } },
213 { OUString(
"changed"), { OUString(
"_Change"),
nullptr,
ApproveAll,
nullptr } },
216 { OUString(
"focusGained"), { OUString(
"_GotFocus"),
nullptr,
ApproveAll,
nullptr } },
219 { OUString(
"focusLost"), { OUString(
"_LostFocus"),
nullptr,
ApproveAll,
nullptr } },
220 { OUString(
"focusLost"), { OUString(
"_Exit"),
nullptr,
ApproveType,
static_cast<void const *
>(&
textCompList) } },
223 { OUString(
"adjustmentValueChanged"), { OUString(
"_Scroll"),
nullptr,
ApproveAll,
nullptr } },
224 { OUString(
"adjustmentValueChanged"), { OUString(
"_Change"),
nullptr,
ApproveAll,
nullptr } },
227 { OUString(
"textChanged"), { OUString(
"_Change"),
nullptr,
ApproveAll,
nullptr } },
261 sEventInfo = pTransProp->sEventInfo;
262 std::vector< TranslateInfo > infoList;
265 infoList.push_back( pTransProp->aTransInfo );
268 }
while(i < nCount && sEventInfo == pTransProp->sEventInfo);
269 tmp[sEventInfo] = std::move(infoList);
273 return eventTransInfo;
281class ScriptEventHelper
284 explicit ScriptEventHelper(
const Reference< XInterface >& xControl );
285 explicit ScriptEventHelper(
const OUString& sCntrlServiceName );
286 ~ScriptEventHelper();
287 Sequence< ScriptEventDescriptor > createEvents(
const OUString& sCodeName );
290 Reference< XComponentContext >
m_xCtx;
304 OUString sMethodName;
306 size_t nDelimPos = rEventMethod.find(
DELIM );
307 if ( nDelimPos == std::u16string_view::npos )
311 sMethodName = rEventMethod.substr( nDelimPos +
DELIMLEN );
312 sTypeName = rEventMethod.substr( 0, nDelimPos );
318 if ( !sMethodName.isEmpty()
319 && !sTypeName.isEmpty()
320 && ( infos.find( sMethodName ) != infos.end() ) )
325 evtDesc.ScriptCode = sCodeName;
326 evtDesc.ListenerType = sTypeName;
327 evtDesc.EventMethod = sMethodName;
331 evtDesc.ScriptType =
"VBAInterop";
338ScriptEventHelper::ScriptEventHelper(
const Reference< XInterface >& xControl ) :
344ScriptEventHelper::ScriptEventHelper(
const OUString& sCntrlServiceName ) :
348 m_xControl.set(
m_xCtx->getServiceManager()->createInstanceWithContext( sCntrlServiceName,
m_xCtx ), uno::UNO_QUERY );
351ScriptEventHelper::~ScriptEventHelper()
362 catch( uno::Exception& )
369ScriptEventHelper::getEventListeners()
const
371 std::vector< OUString > eventMethods;
375 Reference< beans::XIntrospectionAccess > xIntrospectionAccess =
377 const Sequence< Type > aControlListeners =
378 xIntrospectionAccess->getSupportedListeners();
379 for (
const Type& listType : aControlListeners )
381 OUString sFullTypeName = listType.getTypeName();
384 std::transform(sMeths.begin(), sMeths.end(), std::back_inserter(eventMethods),
385 [&sFullTypeName](
const OUString& rMeth) -> OUString { return sFullTypeName + DELIM + rMeth; });
391Sequence< ScriptEventDescriptor >
392ScriptEventHelper::createEvents(
const OUString& sCodeName )
395 sal_Int32
nLength = aControlListeners.getLength();
397 Sequence< ScriptEventDescriptor > aDest( nLength );
399 for ( OUString
const & i : aControlListeners)
405 ScriptEventDescriptor evtDesc;
408 sal_Int32 dIndex = nEvts;
410 if ( nEvts > aDest.getLength() )
411 aDest.realloc( nEvts );
412 aDest.getArray()[ dIndex ] = evtDesc;
415 aDest.realloc( nEvts );
428 ReadOnlyEventsNameContainer(
const Sequence< OUString >& eventMethods,
const OUString& sCodeName );
431 virtual void SAL_CALL insertByName(
const OUString&,
const Any& )
override
436 virtual void SAL_CALL removeByName(
const OUString& )
override
442 virtual void SAL_CALL replaceByName(
const OUString&,
const Any& )
override
449 virtual Any SAL_CALL getByName(
const OUString&
aName )
override;
451 virtual sal_Bool SAL_CALL hasByName(
const OUString&
aName )
override;
454 virtual Type SAL_CALL getElementType( )
override
456 virtual sal_Bool SAL_CALL hasElements( )
override
457 {
return !m_hEvents.empty(); }
460typedef std::unordered_map< OUString, Any > EventSupplierHash;
462 EventSupplierHash m_hEvents;
467ReadOnlyEventsNameContainer::ReadOnlyEventsNameContainer(
const Sequence< OUString >& eventMethods,
const OUString& sCodeName )
469 for (
const OUString& rSrc : eventMethods )
472 ScriptEventDescriptor evtDesc;
476 m_hEvents[ rSrc ] = aDesc;
482ReadOnlyEventsNameContainer::getByName(
const OUString& aName ){
483 EventSupplierHash::const_iterator it = m_hEvents.find( aName );
484 if ( it == m_hEvents.end() )
485 throw container::NoSuchElementException();
490ReadOnlyEventsNameContainer::getElementNames( )
496ReadOnlyEventsNameContainer::hasByName(
const OUString& aName )
498 EventSupplierHash::const_iterator it = m_hEvents.find( aName );
499 if ( it == m_hEvents.end() )
506class ReadOnlyEventsSupplier :
public ::cppu::WeakImplHelper< XScriptEventsSupplier >
510 { m_xNameContainer =
new ReadOnlyEventsNameContainer( eventMethods, sCodeName ); }
520typedef ::cppu::WeakImplHelper< XScriptListener, util::XCloseListener, lang::XInitialization, css::lang::XServiceInfo >
EventListener_BASE;
522#define EVENTLSTNR_PROPERTY_ID_MODEL 1
536 virtual void SAL_CALL disposing(
const lang::EventObject&
Source)
override;
540 virtual void SAL_CALL firing(
const ScriptEvent& evt)
override;
541 virtual Any SAL_CALL approveFiring(
const ScriptEvent& evt)
override;
543 virtual void SAL_CALL queryClosing(
const lang::EventObject&
Source,
sal_Bool GetsOwnership )
override;
544 virtual void SAL_CALL notifyClosing(
const lang::EventObject&
Source )
override;
546 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( )
override;
548 virtual void SAL_CALL initialize(
const Sequence< Any >&
aArguments )
override;
563 if (xCloseBroadcaster.is())
565 xCloseBroadcaster->removeCloseListener(
this );
568 xCloseBroadcaster.set(
xModel, uno::UNO_QUERY );
569 if (xCloseBroadcaster.is())
571 xCloseBroadcaster->addCloseListener(
this );
582 return "ooo.vba.EventListener";
597 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( )
override;
603 void setShellFromModel();
605 void firing_Impl(
const ScriptEvent& evt,
Any *pSyncRet );
614EventListener::EventListener() :
615OPropertyContainer(GetBroadcastHelper()), m_bDocClosed(false), mpShell( nullptr )
622EventListener::setShellFromModel()
640EventListener::disposing(
const lang::EventObject&)
647EventListener::firing(
const ScriptEvent& evt)
649 firing_Impl( evt,
nullptr );
653EventListener::approveFiring(
const ScriptEvent& evt)
656 firing_Impl( evt, &ret );
662EventListener::queryClosing(
const lang::EventObject& ,
sal_Bool )
668EventListener::notifyClosing(
const lang::EventObject& )
672 if (xCloseBroadcaster.is())
674 xCloseBroadcaster->removeCloseListener(
this );
680EventListener::initialize(
const Sequence< Any >& aArguments )
699::
cppu::IPropertyArrayHelper&
700EventListener::getInfoHelper( )
702 return *getArrayHelper();
708EventListener::createArrayHelper( )
const
711 describeProperties( aProps );
712 return new ::cppu::OPropertyArrayHelper( aProps );
717EventListener::getPropertySetInfo( )
725bool ApproveAll(SAL_UNUSED_PARAMETER
const ScriptEvent&, SAL_UNUSED_PARAMETER
void const * )
731static bool FindControl(
const ScriptEvent& evt,
void const * pPara)
734 evt.Arguments[ 0 ] >>=
aEvent;
737 TypeList
const * pTypeListInfo =
static_cast<TypeList
const *
>(pPara);
738 Type const * pType = pTypeListInfo->pTypeList;
739 int nLen = pTypeListInfo->nListLength;
741 for (
int i = 0;
i < nLen;
i++)
743 if ( xInterface->queryInterface( *pType ).hasValue() )
760bool DenyType(
const ScriptEvent& evt,
void const * pPara)
768bool DenyMouseDrag(
const ScriptEvent& evt, SAL_UNUSED_PARAMETER
void const * )
771 evt.Arguments[ 0 ] >>=
aEvent;
772 return aEvent.Buttons == 0;
779EventListener::firing_Impl(
const ScriptEvent& evt, Any* pRet )
782 if ( evt.ScriptType !=
"VBAInterop" )
785 evt.Arguments[ 0 ] >>=
aEvent;
786 OUString
sName =
"UserForm";
798 if ( xCntrlShape.is() )
806 sName = xName->getName();
812 xProps.set( xControl->getModel(), uno::UNO_QUERY_THROW );
813 xProps->getPropertyValue(
"Name") >>=
sName;
818 EventInfoHash::const_iterator eventInfo_it = infos.find( evt.MethodName );
819 EventInfoHash::const_iterator it_end = infos.end();
820 if ( eventInfo_it == it_end )
822 SAL_WARN(
"scripting",
"Bogus event for " << evt.ScriptType );
830 xScriptProvider = xSPS->getScriptProvider();
832 if ( !(xScriptProvider.is() && mpShell) )
835 BasicManager* pBasicManager = mpShell->GetBasicManager();
837 OUString sScriptCode( evt.ScriptCode );
839 if ( sScriptCode.indexOf(
'.' ) == -1 )
843 sProject =
"Standard";
845 if (!pBasicManager->
GetName().isEmpty())
847 sProject = pBasicManager->
GetName();
852 sal_Int32
nIndex = sScriptCode.indexOf(
'.' );
853 sProject = sScriptCode.copy( 0, nIndex );
854 sScriptCode = sScriptCode.copy( nIndex + 1 );
856 OUString sMacroLoc = sProject +
"." + sScriptCode +
".";
858 for (
const auto& rTxInfo : eventInfo_it->second)
868 OUString sToResolve = sMacroLoc +
sName + rTxInfo.sVBAName;
871 if ( aMacroResolvedInfo.
mbFound )
874 if (! rTxInfo.ApproveRule(evt, rTxInfo.pPara) )
897 uno::Any aDummyCaller( OUString(
"Error") );
908 catch (
const uno::Exception& )
919class VBAToOOEventDescGen :
public ::cppu::WeakImplHelper< XVBAToOOEventDescGen, css::lang::XServiceInfo >
922 VBAToOOEventDescGen();
925 virtual Sequence< ScriptEventDescriptor > SAL_CALL getEventDescriptions(
const OUString& sCtrlServiceName,
const OUString& sCodeName )
override;
926 virtual Reference< XScriptEventsSupplier > SAL_CALL getEventSupplier(
const Reference< XInterface >& xControl,
const OUString& sCodeName )
override;
930 return "ooo.vba.VBAToOOEventDesc";
947VBAToOOEventDescGen::VBAToOOEventDescGen() {}
949Sequence< ScriptEventDescriptor > SAL_CALL
950VBAToOOEventDescGen::getEventDescriptions(
const OUString& sCntrlServiceName,
const OUString& sCodeName )
952 ScriptEventHelper evntHelper( sCntrlServiceName );
953 return evntHelper.createEvents( sCodeName );
956Reference< XScriptEventsSupplier > SAL_CALL
957VBAToOOEventDescGen::getEventSupplier(
const Reference< XInterface >& xControl,
const OUString& sCodeName )
959 ScriptEventHelper evntHelper( xControl );
960 Reference< XScriptEventsSupplier > xSupplier =
961 new ReadOnlyEventsSupplier(
962 evntHelper.getEventListeners(), sCodeName ) ;
966extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
968 css::uno::Sequence<css::uno::Any>
const &)
970 return cppu::acquire(
new EventListener);
974extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
976 css::uno::Sequence<css::uno::Any>
const &)
978 return cppu::acquire(
new VBAToOOEventDescGen);
Reference< XComponentContext > m_xCtx
const OUString & GetName() const
static SAL_WARN_UNUSED_RESULT SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
css::uno::Reference< css::frame::XModel3 > GetModel() const
static SAL_WARN_UNUSED_RESULT SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
virtual ::cppu::IPropertyArrayHelper * createArrayHelper() const=0
virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const css::uno::Any &rValue) override final
void SAL_CALL disposing()
css::uno::Type const & get()
const ScContentId pTypeList[int(ScContentId::LAST)+1]
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< frame::XModel > m_xModel
Reference< awt::XControl > m_xControl
::cppu::WeakImplHelper< XScriptListener, util::XCloseListener, lang::XInitialization, css::lang::XServiceInfo > EventListener_BASE
TypeList const comboBoxList
static bool DenyType(const ScriptEvent &evt, void const *pPara)
TypeList const radioButtonList
std::unordered_map< OUString, std::vector< TranslateInfo > > EventInfoHash
static bool ApproveAll(const ScriptEvent &evt, void const *pPara)
static EventInfoHash & getEventTransInfo()
static bool FindControl(const ScriptEvent &evt, void const *pPara)
static bool eventMethodToDescriptor(std::u16string_view rEventMethod, ScriptEventDescriptor &evtDesc, const OUString &sCodeName)
constexpr OUStringLiteral EVENTLSTNR_PROPERTY_MODEL
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * ooo_vba_EventListener_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
static Sequence< Any > ooKeyPressedToVBAKeyPressed(const Sequence< Any > ¶ms)
Type const typeXTextComponent
#define EVENTLSTNR_PROPERTY_ID_MODEL
static bool isKeyEventOk(awt::KeyEvent &evt, const Sequence< Any > ¶ms)
static bool DenyMouseDrag(const ScriptEvent &evt, void const *pPara)
::cppu::WeakImplHelper< container::XNameContainer > NameContainer_BASE
TypeList const textCompList
static Sequence< Any > ooMouseEvtToVBADblClick(const Sequence< Any > ¶ms)
constexpr sal_Int32 DELIMLEN
constexpr std::u16string_view DELIM
Type const typeXRadioButton
Sequence< Any >(* Translator)(const Sequence< Any > &)
TypeList const fixedTextList
static bool isMouseEventOk(awt::MouseEvent &evt, const Sequence< Any > ¶ms)
Type const typeXFixedText
static Sequence< Any > ooKeyPressedToVBAKeyUpDown(const Sequence< Any > ¶ms)
static bool ApproveType(const ScriptEvent &evt, void const *pPara)
TypeList const listBoxList
static Sequence< Any > ooMouseEvtToVBAMouseEvt(const Sequence< Any > ¶ms)
static TranslatePropMap aTranslatePropMap_Impl[]
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * ooo_vba_VBAToOOEventDesc_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Sequence< PropertyValue > aArguments
Reference< XIntrospection > xIntrospection
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
::cppu::WeakImplHelper< css::container::XNameContainer, css::container::XContainer, css::util::XChangesNotifier > NameContainer_BASE
Sequence< OUString > getEventMethodsForType(const Type &type)
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
bool executeMacro(SfxObjectShell *pShell, const OUString &sMacroName, uno::Sequence< uno::Any > &aArgs, uno::Any &aRet, const uno::Any &)
OUString resolveVBAMacro(SfxObjectShell const *pShell, const OUString &rLibName, const OUString &rModuleName, const OUString &rMacroName, bool bOnlyPublic, const OUString &sSkipModule)
IMPLEMENT_FORWARD_XTYPEPROVIDER2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
IMPLEMENT_FORWARD_XINTERFACE2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
Reference< XModel > xModel
#define DECLARE_XTYPEPROVIDER()
#define DECLARE_XINTERFACE()