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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 27 #include "sfx2/userinputinterception.hxx" 28 29 /** === begin UNO includes === **/ 30 #include <com/sun/star/awt/MouseButton.hpp> 31 #include <com/sun/star/awt/KeyModifier.hpp> 32 /** === end UNO includes === **/ 33 34 #include <cppuhelper/interfacecontainer.hxx> 35 #include <cppuhelper/weak.hxx> 36 #include <vcl/event.hxx> 37 #include <vcl/window.hxx> 38 39 //........................................................................ 40 namespace sfx2 41 { 42 //........................................................................ 43 44 /** === begin UNO using === **/ 45 using ::com::sun::star::uno::Reference; 46 using ::com::sun::star::uno::XInterface; 47 using ::com::sun::star::uno::UNO_QUERY; 48 using ::com::sun::star::uno::UNO_QUERY_THROW; 49 using ::com::sun::star::uno::UNO_SET_THROW; 50 using ::com::sun::star::uno::Exception; 51 using ::com::sun::star::uno::RuntimeException; 52 using ::com::sun::star::uno::Any; 53 using ::com::sun::star::uno::makeAny; 54 using ::com::sun::star::awt::MouseEvent; 55 using ::com::sun::star::awt::KeyEvent; 56 using ::com::sun::star::awt::InputEvent; 57 using ::com::sun::star::awt::XKeyHandler; 58 using ::com::sun::star::awt::XMouseClickHandler; 59 using ::com::sun::star::lang::DisposedException; 60 /** === end UNO using === **/ 61 namespace MouseButton = ::com::sun::star::awt::MouseButton; 62 namespace KeyModifier = ::com::sun::star::awt::KeyModifier; 63 64 struct UserInputInterception_Data 65 { 66 public: 67 ::cppu::OWeakObject& m_rControllerImpl; 68 ::cppu::OInterfaceContainerHelper m_aKeyHandlers; 69 ::cppu::OInterfaceContainerHelper m_aMouseClickHandlers; 70 71 public: UserInputInterception_Datasfx2::UserInputInterception_Data72 UserInputInterception_Data( ::cppu::OWeakObject& _rControllerImpl, ::osl::Mutex& _rMutex ) 73 :m_rControllerImpl( _rControllerImpl ) 74 ,m_aKeyHandlers( _rMutex ) 75 ,m_aMouseClickHandlers( _rMutex ) 76 { 77 } 78 }; 79 80 namespace 81 { 82 template< class VLCEVENT > lcl_initModifiers(InputEvent & _rEvent,const VLCEVENT & _rVclEvent)83 void lcl_initModifiers( InputEvent& _rEvent, const VLCEVENT& _rVclEvent ) 84 { 85 _rEvent.Modifiers = 0; 86 87 if ( _rVclEvent.IsShift() ) 88 _rEvent.Modifiers |= KeyModifier::SHIFT; 89 if ( _rVclEvent.IsMod1() ) 90 _rEvent.Modifiers |= KeyModifier::MOD1; 91 if ( _rVclEvent.IsMod2() ) 92 _rEvent.Modifiers |= KeyModifier::MOD2; 93 if ( _rVclEvent.IsMod3() ) 94 _rEvent.Modifiers |= KeyModifier::MOD3; 95 } 96 lcl_initKeyEvent(KeyEvent & rEvent,const::KeyEvent & rEvt)97 void lcl_initKeyEvent( KeyEvent& rEvent, const ::KeyEvent& rEvt ) 98 { 99 lcl_initModifiers( rEvent, rEvt.GetKeyCode() ); 100 101 rEvent.KeyCode = rEvt.GetKeyCode().GetCode(); 102 rEvent.KeyChar = rEvt.GetCharCode(); 103 rEvent.KeyFunc = sal::static_int_cast< sal_Int16 >( rEvt.GetKeyCode().GetFunction()); 104 } 105 lcl_initMouseEvent(MouseEvent & rEvent,const::MouseEvent & rEvt)106 void lcl_initMouseEvent( MouseEvent& rEvent, const ::MouseEvent& rEvt ) 107 { 108 lcl_initModifiers( rEvent, rEvt ); 109 110 rEvent.Buttons = 0; 111 if ( rEvt.IsLeft() ) 112 rEvent.Buttons |= MouseButton::LEFT; 113 if ( rEvt.IsRight() ) 114 rEvent.Buttons |= MouseButton::RIGHT; 115 if ( rEvt.IsMiddle() ) 116 rEvent.Buttons |= MouseButton::MIDDLE; 117 118 rEvent.X = rEvt.GetPosPixel().X(); 119 rEvent.Y = rEvt.GetPosPixel().Y(); 120 rEvent.ClickCount = rEvt.GetClicks(); 121 rEvent.PopupTrigger = sal_False; 122 } 123 124 } 125 126 //==================================================================== 127 //= UserInputInterception 128 //==================================================================== 129 //-------------------------------------------------------------------- UserInputInterception(::cppu::OWeakObject & _rControllerImpl,::osl::Mutex & _rMutex)130 UserInputInterception::UserInputInterception( ::cppu::OWeakObject& _rControllerImpl, ::osl::Mutex& _rMutex ) 131 :m_pData( new UserInputInterception_Data( _rControllerImpl, _rMutex ) ) 132 { 133 } 134 135 //-------------------------------------------------------------------- ~UserInputInterception()136 UserInputInterception::~UserInputInterception() 137 { 138 } 139 140 //-------------------------------------------------------------------- addKeyHandler(const Reference<XKeyHandler> & _rxHandler)141 void UserInputInterception::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) 142 { 143 if ( _rxHandler.is() ) 144 m_pData->m_aKeyHandlers.addInterface( _rxHandler ); 145 } 146 147 //-------------------------------------------------------------------- removeKeyHandler(const Reference<XKeyHandler> & _rxHandler)148 void UserInputInterception::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) 149 { 150 m_pData->m_aKeyHandlers.removeInterface( _rxHandler ); 151 } 152 153 //-------------------------------------------------------------------- addMouseClickHandler(const Reference<XMouseClickHandler> & _rxHandler)154 void UserInputInterception::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) 155 { 156 if ( _rxHandler.is() ) 157 m_pData->m_aMouseClickHandlers.addInterface( _rxHandler ); 158 } 159 160 //-------------------------------------------------------------------- removeMouseClickHandler(const Reference<XMouseClickHandler> & _rxHandler)161 void UserInputInterception::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) 162 { 163 m_pData->m_aMouseClickHandlers.removeInterface( _rxHandler ); 164 } 165 166 //-------------------------------------------------------------------- hasKeyHandlers() const167 bool UserInputInterception::hasKeyHandlers() const 168 { 169 return m_pData->m_aKeyHandlers.getLength() > 0; 170 } 171 172 //-------------------------------------------------------------------- hasMouseClickListeners() const173 bool UserInputInterception::hasMouseClickListeners() const 174 { 175 return m_pData->m_aMouseClickHandlers.getLength() > 0; 176 } 177 178 //-------------------------------------------------------------------- handleNotifyEvent(const NotifyEvent & _rEvent)179 bool UserInputInterception::handleNotifyEvent( const NotifyEvent& _rEvent ) 180 { 181 Reference < XInterface > xHoldAlive( m_pData->m_rControllerImpl ); 182 183 sal_uInt16 nType = _rEvent.GetType(); 184 bool bHandled = false; 185 186 switch ( nType ) 187 { 188 case EVENT_KEYINPUT: 189 case EVENT_KEYUP: 190 { 191 KeyEvent aEvent; 192 lcl_initKeyEvent( aEvent, *_rEvent.GetKeyEvent() ); 193 if ( _rEvent.GetWindow() ) 194 aEvent.Source = _rEvent.GetWindow()->GetComponentInterface(); 195 196 ::cppu::OInterfaceIteratorHelper aIterator( m_pData->m_aKeyHandlers ); 197 while ( aIterator.hasMoreElements() ) 198 { 199 Reference< XKeyHandler > xHandler( static_cast< XKeyHandler* >( aIterator.next() ) ); 200 if ( !xHandler.is() ) 201 continue; 202 203 try 204 { 205 if ( nType == EVENT_KEYINPUT ) 206 bHandled = xHandler->keyPressed( aEvent ); 207 else 208 bHandled = xHandler->keyReleased( aEvent ); 209 } 210 catch( const DisposedException& e ) 211 { 212 if ( e.Context == xHandler ) 213 aIterator.remove(); 214 } 215 catch( const RuntimeException& ) 216 { 217 throw; 218 } 219 catch( const Exception& ) 220 { 221 } 222 } 223 } 224 break; 225 226 case EVENT_MOUSEBUTTONDOWN: 227 case EVENT_MOUSEBUTTONUP: 228 { 229 MouseEvent aEvent; 230 lcl_initMouseEvent( aEvent, *_rEvent.GetMouseEvent() ); 231 if ( _rEvent.GetWindow() ) 232 aEvent.Source = _rEvent.GetWindow()->GetComponentInterface(); 233 234 ::cppu::OInterfaceIteratorHelper aIterator( m_pData->m_aMouseClickHandlers ); 235 while ( aIterator.hasMoreElements() ) 236 { 237 Reference< XMouseClickHandler > xHandler( static_cast< XMouseClickHandler* >( aIterator.next() ) ); 238 if ( !xHandler.is() ) 239 continue; 240 241 try 242 { 243 if ( nType == EVENT_MOUSEBUTTONDOWN ) 244 bHandled = xHandler->mousePressed( aEvent ); 245 else 246 bHandled = xHandler->mouseReleased( aEvent ); 247 } 248 catch( const DisposedException& e ) 249 { 250 if ( e.Context == xHandler ) 251 aIterator.remove(); 252 } 253 catch( const RuntimeException& ) 254 { 255 throw; 256 } 257 catch( const Exception& ) 258 { 259 } 260 } 261 } 262 break; 263 264 default: 265 OSL_ENSURE( false, "UserInputInterception::handleNotifyEvent: illegal event type!" ); 266 break; 267 } 268 269 return bHandled; 270 } 271 272 //........................................................................ 273 } // namespace sfx2 274 //........................................................................ 275