1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef VBAHELPER_VBAEVENTSHELPERBASE_HXX 29 #define VBAHELPER_VBAEVENTSHELPERBASE_HXX 30 31 #include <deque> 32 #include <hash_map> 33 #include <map> 34 #include <com/sun/star/document/XEventListener.hpp> 35 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> 36 #include <com/sun/star/util/XChangesListener.hpp> 37 #include <cppuhelper/implbase3.hxx> 38 #include "vbahelper/vbahelper.hxx" 39 40 namespace com { namespace sun { namespace star { 41 namespace script { namespace vba { class XVBAModuleInfo; } } 42 namespace uno { class XComponentContext; } 43 } } } 44 45 // ============================================================================ 46 47 typedef ::cppu::WeakImplHelper3< 48 css::script::vba::XVBAEventProcessor, 49 css::document::XEventListener, 50 css::util::XChangesListener > VbaEventsHelperBase_BASE; 51 52 class VBAHELPER_DLLPUBLIC VbaEventsHelperBase : public VbaEventsHelperBase_BASE 53 { 54 public: 55 VbaEventsHelperBase( 56 const css::uno::Sequence< css::uno::Any >& rArgs, 57 const css::uno::Reference< css::uno::XComponentContext >& xContext ); 58 virtual ~VbaEventsHelperBase(); 59 60 // script::vba::XVBAEventProcessor 61 virtual sal_Bool SAL_CALL hasVbaEventHandler( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); 62 virtual sal_Bool SAL_CALL processVbaEvent( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::util::VetoException, css::uno::RuntimeException); 63 64 // document::XEventListener 65 virtual void SAL_CALL notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException); 66 67 // util::XChangesListener 68 virtual void SAL_CALL changesOccurred( const css::util::ChangesEvent& rEvent ) throw (css::uno::RuntimeException); 69 70 // lang::XEventListener 71 virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) throw (css::uno::RuntimeException); 72 73 // little helpers --------------------------------------------------------- 74 75 /** Helper to execute event handlers without throwing any exceptions. */ 76 void processVbaEventNoThrow( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ); 77 78 /** Throws, if the passed sequence does not contain a value at the specified index. */ 79 static inline void checkArgument( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException) 80 { if( (nIndex < 0) || (nIndex >= rArgs.getLength()) ) throw css::lang::IllegalArgumentException(); } 81 82 /** Throws, if the passed sequence does not contain a value of a specific at the specified index. */ 83 template< typename Type > 84 static inline void checkArgumentType( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException) 85 { checkArgument( rArgs, nIndex ); if( !rArgs[ nIndex ].has< Type >() ) throw css::lang::IllegalArgumentException(); } 86 87 protected: 88 // ------------------------------------------------------------------------ 89 90 struct EventHandlerInfo 91 { 92 sal_Int32 mnEventId; 93 sal_Int32 mnModuleType; 94 ::rtl::OUString maMacroName; 95 sal_Int32 mnCancelIndex; 96 css::uno::Any maUserData; 97 }; 98 99 /** Registers a supported event handler. 100 101 @param nEventId Event identifier from com.sun.star.script.vba.VBAEventId. 102 @param nModuleType Type of the module containing the event handler. 103 @param pcMacroName Name of the associated VBA event handler macro. 104 @param nCancelIndex 0-based index of Cancel parameter, or -1. 105 @param rUserData User data for free usage in derived implementations. */ 106 void registerEventHandler( 107 sal_Int32 nEventId, 108 sal_Int32 nModuleType, 109 const sal_Char* pcMacroName, 110 sal_Int32 nCancelIndex = -1, 111 const css::uno::Any& rUserData = css::uno::Any() ); 112 113 // ------------------------------------------------------------------------ 114 115 struct EventQueueEntry 116 { 117 sal_Int32 mnEventId; 118 css::uno::Sequence< css::uno::Any > maArgs; 119 inline /*implicit*/ EventQueueEntry( sal_Int32 nEventId ) : mnEventId( nEventId ) {} 120 inline EventQueueEntry( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) : mnEventId( nEventId ), maArgs( rArgs ) {} 121 }; 122 typedef ::std::deque< EventQueueEntry > EventQueue; 123 124 /** Derived classes do additional prpeparations and return whether the 125 event handler has to be called. */ 126 virtual bool implPrepareEvent( 127 EventQueue& rEventQueue, 128 const EventHandlerInfo& rInfo, 129 const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException) = 0; 130 131 /** Derived classes have to return the argument list for the specified VBA event handler. */ 132 virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( 133 const EventHandlerInfo& rInfo, 134 const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException) = 0; 135 136 /** Derived classes may do additional postprocessing. Called even if the 137 event handler does not exist, or if an error occured during execution. */ 138 virtual void implPostProcessEvent( 139 EventQueue& rEventQueue, 140 const EventHandlerInfo& rInfo, 141 bool bCancel ) throw (css::uno::RuntimeException) = 0; 142 143 /** Derived classes have to return the name of the Basic document module. */ 144 virtual ::rtl::OUString implGetDocumentModuleName( 145 const EventHandlerInfo& rInfo, 146 const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException) = 0; 147 148 private: 149 typedef ::std::map< sal_Int32, ::rtl::OUString > ModulePathMap; 150 151 /** Starts listening at the document model. */ 152 void startListening(); 153 /** Stops listening at the document model. */ 154 void stopListening(); 155 156 /** Returns the event handler info struct for the specified event, or throws. */ 157 const EventHandlerInfo& getEventHandlerInfo( sal_Int32 nEventId ) const throw (css::lang::IllegalArgumentException); 158 159 /** Searches the event handler in the document and returns its full script path. */ 160 ::rtl::OUString getEventHandlerPath( 161 const EventHandlerInfo& rInfo, 162 const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); 163 164 /** On first call, accesses the Basic library containing the VBA source code. */ 165 void ensureVBALibrary() throw (css::uno::RuntimeException); 166 167 /** Returns the type of the Basic module with the specified name. */ 168 sal_Int32 getModuleType( const ::rtl::OUString& rModuleName ) throw (css::uno::RuntimeException); 169 170 /** Updates the map containing paths to event handlers for a Basic module. */ 171 ModulePathMap& updateModulePathMap( const ::rtl::OUString& rModuleName ) throw (css::uno::RuntimeException); 172 173 protected: 174 css::uno::Reference< css::frame::XModel > mxModel; 175 SfxObjectShell* mpShell; 176 177 private: 178 typedef ::std::map< sal_Int32, EventHandlerInfo > EventHandlerInfoMap; 179 typedef ::std::hash_map< ::rtl::OUString, ModulePathMap, ::rtl::OUStringHash > EventHandlerPathMap; 180 181 EventHandlerInfoMap maEventInfos; 182 EventHandlerPathMap maEventPaths; 183 css::uno::Reference< css::script::vba::XVBAModuleInfo > mxModuleInfos; 184 ::rtl::OUString maLibraryName; 185 bool mbDisposed; 186 }; 187 188 // ============================================================================ 189 190 #endif 191