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