1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef VBAHELPER_VBAEVENTSHELPERBASE_HXX 25 #define VBAHELPER_VBAEVENTSHELPERBASE_HXX 26 27 #include <deque> 28 #include <hash_map> 29 #include <map> 30 #include <com/sun/star/document/XEventListener.hpp> 31 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> 32 #include <com/sun/star/util/XChangesListener.hpp> 33 #include <cppuhelper/implbase3.hxx> 34 #include "vbahelper/vbahelper.hxx" 35 36 namespace com { namespace sun { namespace star { 37 namespace script { namespace vba { class XVBAModuleInfo; } } 38 namespace uno { class XComponentContext; } 39 } } } 40 41 // ============================================================================ 42 43 typedef ::cppu::WeakImplHelper3< 44 css::script::vba::XVBAEventProcessor, 45 css::document::XEventListener, 46 css::util::XChangesListener > VbaEventsHelperBase_BASE; 47 48 class VBAHELPER_DLLPUBLIC VbaEventsHelperBase : public VbaEventsHelperBase_BASE 49 { 50 public: 51 VbaEventsHelperBase( 52 const css::uno::Sequence< css::uno::Any >& rArgs, 53 const css::uno::Reference< css::uno::XComponentContext >& xContext ); 54 virtual ~VbaEventsHelperBase(); 55 56 // script::vba::XVBAEventProcessor 57 virtual sal_Bool SAL_CALL hasVbaEventHandler( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); 58 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); 59 60 // document::XEventListener 61 virtual void SAL_CALL notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException); 62 63 // util::XChangesListener 64 virtual void SAL_CALL changesOccurred( const css::util::ChangesEvent& rEvent ) throw (css::uno::RuntimeException); 65 66 // lang::XEventListener 67 virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) throw (css::uno::RuntimeException); 68 69 // little helpers --------------------------------------------------------- 70 71 /** Helper to execute event handlers without throwing any exceptions. */ 72 void processVbaEventNoThrow( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ); 73 74 /** Throws, if the passed sequence does not contain a value at the specified index. */ checkArgument(const css::uno::Sequence<css::uno::Any> & rArgs,sal_Int32 nIndex)75 static inline void checkArgument( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException) 76 { if( (nIndex < 0) || (nIndex >= rArgs.getLength()) ) throw css::lang::IllegalArgumentException(); } 77 78 /** Throws, if the passed sequence does not contain a value of a specific at the specified index. */ 79 template< typename Type > checkArgumentType(const css::uno::Sequence<css::uno::Any> & rArgs,sal_Int32 nIndex)80 static inline void checkArgumentType( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException) 81 { checkArgument( rArgs, nIndex ); if( !rArgs[ nIndex ].has< Type >() ) throw css::lang::IllegalArgumentException(); } 82 83 protected: 84 // ------------------------------------------------------------------------ 85 86 struct EventHandlerInfo 87 { 88 sal_Int32 mnEventId; 89 sal_Int32 mnModuleType; 90 ::rtl::OUString maMacroName; 91 sal_Int32 mnCancelIndex; 92 css::uno::Any maUserData; 93 }; 94 95 /** Registers a supported event handler. 96 97 @param nEventId Event identifier from com.sun.star.script.vba.VBAEventId. 98 @param nModuleType Type of the module containing the event handler. 99 @param pcMacroName Name of the associated VBA event handler macro. 100 @param nCancelIndex 0-based index of Cancel parameter, or -1. 101 @param rUserData User data for free usage in derived implementations. */ 102 void registerEventHandler( 103 sal_Int32 nEventId, 104 sal_Int32 nModuleType, 105 const sal_Char* pcMacroName, 106 sal_Int32 nCancelIndex = -1, 107 const css::uno::Any& rUserData = css::uno::Any() ); 108 109 // ------------------------------------------------------------------------ 110 111 struct EventQueueEntry 112 { 113 sal_Int32 mnEventId; 114 css::uno::Sequence< css::uno::Any > maArgs; EventQueueEntryVbaEventsHelperBase::EventQueueEntry115 inline /*implicit*/ EventQueueEntry( sal_Int32 nEventId ) : mnEventId( nEventId ) {} EventQueueEntryVbaEventsHelperBase::EventQueueEntry116 inline EventQueueEntry( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& rArgs ) : mnEventId( nEventId ), maArgs( rArgs ) {} 117 }; 118 typedef ::std::deque< EventQueueEntry > EventQueue; 119 120 /** Derived classes do additional prpeparations and return whether the 121 event handler has to be called. */ 122 virtual bool implPrepareEvent( 123 EventQueue& rEventQueue, 124 const EventHandlerInfo& rInfo, 125 const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException) = 0; 126 127 /** Derived classes have to return the argument list for the specified VBA event handler. */ 128 virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( 129 const EventHandlerInfo& rInfo, 130 const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException) = 0; 131 132 /** Derived classes may do additional postprocessing. Called even if the 133 event handler does not exist, or if an error occurred during execution. */ 134 virtual void implPostProcessEvent( 135 EventQueue& rEventQueue, 136 const EventHandlerInfo& rInfo, 137 bool bCancel ) throw (css::uno::RuntimeException) = 0; 138 139 /** Derived classes have to return the name of the Basic document module. */ 140 virtual ::rtl::OUString implGetDocumentModuleName( 141 const EventHandlerInfo& rInfo, 142 const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException) = 0; 143 144 private: 145 typedef ::std::map< sal_Int32, ::rtl::OUString > ModulePathMap; 146 147 /** Starts listening at the document model. */ 148 void startListening(); 149 /** Stops listening at the document model. */ 150 void stopListening(); 151 152 /** Returns the event handler info struct for the specified event, or throws. */ 153 const EventHandlerInfo& getEventHandlerInfo( sal_Int32 nEventId ) const throw (css::lang::IllegalArgumentException); 154 155 /** Searches the event handler in the document and returns its full script path. */ 156 ::rtl::OUString getEventHandlerPath( 157 const EventHandlerInfo& rInfo, 158 const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); 159 160 /** On first call, accesses the Basic library containing the VBA source code. */ 161 void ensureVBALibrary() throw (css::uno::RuntimeException); 162 163 /** Returns the type of the Basic module with the specified name. */ 164 sal_Int32 getModuleType( const ::rtl::OUString& rModuleName ) throw (css::uno::RuntimeException); 165 166 /** Updates the map containing paths to event handlers for a Basic module. */ 167 ModulePathMap& updateModulePathMap( const ::rtl::OUString& rModuleName ) throw (css::uno::RuntimeException); 168 169 protected: 170 css::uno::Reference< css::frame::XModel > mxModel; 171 SfxObjectShell* mpShell; 172 173 private: 174 typedef ::std::map< sal_Int32, EventHandlerInfo > EventHandlerInfoMap; 175 typedef ::std::hash_map< ::rtl::OUString, ModulePathMap, ::rtl::OUStringHash > EventHandlerPathMap; 176 177 EventHandlerInfoMap maEventInfos; 178 EventHandlerPathMap maEventPaths; 179 css::uno::Reference< css::script::vba::XVBAModuleInfo > mxModuleInfos; 180 ::rtl::OUString maLibraryName; 181 bool mbDisposed; 182 }; 183 184 // ============================================================================ 185 186 #endif 187