| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sfx2.hxx" |
| |
| #include "sfx2/userinputinterception.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/awt/MouseButton.hpp> |
| #include <com/sun/star/awt/KeyModifier.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <cppuhelper/interfacecontainer.hxx> |
| #include <cppuhelper/weak.hxx> |
| #include <vcl/event.hxx> |
| #include <vcl/window.hxx> |
| |
| //........................................................................ |
| namespace sfx2 |
| { |
| //........................................................................ |
| |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::XInterface; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::UNO_SET_THROW; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::awt::MouseEvent; |
| using ::com::sun::star::awt::KeyEvent; |
| using ::com::sun::star::awt::InputEvent; |
| using ::com::sun::star::awt::XKeyHandler; |
| using ::com::sun::star::awt::XMouseClickHandler; |
| using ::com::sun::star::lang::DisposedException; |
| /** === end UNO using === **/ |
| namespace MouseButton = ::com::sun::star::awt::MouseButton; |
| namespace KeyModifier = ::com::sun::star::awt::KeyModifier; |
| |
| struct UserInputInterception_Data |
| { |
| public: |
| ::cppu::OWeakObject& m_rControllerImpl; |
| ::cppu::OInterfaceContainerHelper m_aKeyHandlers; |
| ::cppu::OInterfaceContainerHelper m_aMouseClickHandlers; |
| |
| public: |
| UserInputInterception_Data( ::cppu::OWeakObject& _rControllerImpl, ::osl::Mutex& _rMutex ) |
| :m_rControllerImpl( _rControllerImpl ) |
| ,m_aKeyHandlers( _rMutex ) |
| ,m_aMouseClickHandlers( _rMutex ) |
| { |
| } |
| }; |
| |
| namespace |
| { |
| template< class VLCEVENT > |
| void lcl_initModifiers( InputEvent& _rEvent, const VLCEVENT& _rVclEvent ) |
| { |
| _rEvent.Modifiers = 0; |
| |
| if ( _rVclEvent.IsShift() ) |
| _rEvent.Modifiers |= KeyModifier::SHIFT; |
| if ( _rVclEvent.IsMod1() ) |
| _rEvent.Modifiers |= KeyModifier::MOD1; |
| if ( _rVclEvent.IsMod2() ) |
| _rEvent.Modifiers |= KeyModifier::MOD2; |
| if ( _rVclEvent.IsMod3() ) |
| _rEvent.Modifiers |= KeyModifier::MOD3; |
| } |
| |
| void lcl_initKeyEvent( KeyEvent& rEvent, const ::KeyEvent& rEvt ) |
| { |
| lcl_initModifiers( rEvent, rEvt.GetKeyCode() ); |
| |
| rEvent.KeyCode = rEvt.GetKeyCode().GetCode(); |
| rEvent.KeyChar = rEvt.GetCharCode(); |
| rEvent.KeyFunc = sal::static_int_cast< sal_Int16 >( rEvt.GetKeyCode().GetFunction()); |
| } |
| |
| void lcl_initMouseEvent( MouseEvent& rEvent, const ::MouseEvent& rEvt ) |
| { |
| lcl_initModifiers( rEvent, rEvt ); |
| |
| rEvent.Buttons = 0; |
| if ( rEvt.IsLeft() ) |
| rEvent.Buttons |= MouseButton::LEFT; |
| if ( rEvt.IsRight() ) |
| rEvent.Buttons |= MouseButton::RIGHT; |
| if ( rEvt.IsMiddle() ) |
| rEvent.Buttons |= MouseButton::MIDDLE; |
| |
| rEvent.X = rEvt.GetPosPixel().X(); |
| rEvent.Y = rEvt.GetPosPixel().Y(); |
| rEvent.ClickCount = rEvt.GetClicks(); |
| rEvent.PopupTrigger = sal_False; |
| } |
| |
| } |
| |
| //==================================================================== |
| //= UserInputInterception |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| UserInputInterception::UserInputInterception( ::cppu::OWeakObject& _rControllerImpl, ::osl::Mutex& _rMutex ) |
| :m_pData( new UserInputInterception_Data( _rControllerImpl, _rMutex ) ) |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| UserInputInterception::~UserInputInterception() |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| void UserInputInterception::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| if ( _rxHandler.is() ) |
| m_pData->m_aKeyHandlers.addInterface( _rxHandler ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void UserInputInterception::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| m_pData->m_aKeyHandlers.removeInterface( _rxHandler ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void UserInputInterception::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| if ( _rxHandler.is() ) |
| m_pData->m_aMouseClickHandlers.addInterface( _rxHandler ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void UserInputInterception::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) |
| { |
| m_pData->m_aMouseClickHandlers.removeInterface( _rxHandler ); |
| } |
| |
| //-------------------------------------------------------------------- |
| bool UserInputInterception::hasKeyHandlers() const |
| { |
| return m_pData->m_aKeyHandlers.getLength() > 0; |
| } |
| |
| //-------------------------------------------------------------------- |
| bool UserInputInterception::hasMouseClickListeners() const |
| { |
| return m_pData->m_aMouseClickHandlers.getLength() > 0; |
| } |
| |
| //-------------------------------------------------------------------- |
| bool UserInputInterception::handleNotifyEvent( const NotifyEvent& _rEvent ) |
| { |
| Reference < XInterface > xHoldAlive( m_pData->m_rControllerImpl ); |
| |
| sal_uInt16 nType = _rEvent.GetType(); |
| bool bHandled = false; |
| |
| switch ( nType ) |
| { |
| case EVENT_KEYINPUT: |
| case EVENT_KEYUP: |
| { |
| KeyEvent aEvent; |
| lcl_initKeyEvent( aEvent, *_rEvent.GetKeyEvent() ); |
| if ( _rEvent.GetWindow() ) |
| aEvent.Source = _rEvent.GetWindow()->GetComponentInterface(); |
| |
| ::cppu::OInterfaceIteratorHelper aIterator( m_pData->m_aKeyHandlers ); |
| while ( aIterator.hasMoreElements() ) |
| { |
| Reference< XKeyHandler > xHandler( static_cast< XKeyHandler* >( aIterator.next() ) ); |
| if ( !xHandler.is() ) |
| continue; |
| |
| try |
| { |
| if ( nType == EVENT_KEYINPUT ) |
| bHandled = xHandler->keyPressed( aEvent ); |
| else |
| bHandled = xHandler->keyReleased( aEvent ); |
| } |
| catch( const DisposedException& e ) |
| { |
| if ( e.Context == xHandler ) |
| aIterator.remove(); |
| } |
| catch( const RuntimeException& ) |
| { |
| throw; |
| } |
| catch( const Exception& ) |
| { |
| } |
| } |
| } |
| break; |
| |
| case EVENT_MOUSEBUTTONDOWN: |
| case EVENT_MOUSEBUTTONUP: |
| { |
| MouseEvent aEvent; |
| lcl_initMouseEvent( aEvent, *_rEvent.GetMouseEvent() ); |
| if ( _rEvent.GetWindow() ) |
| aEvent.Source = _rEvent.GetWindow()->GetComponentInterface(); |
| |
| ::cppu::OInterfaceIteratorHelper aIterator( m_pData->m_aMouseClickHandlers ); |
| while ( aIterator.hasMoreElements() ) |
| { |
| Reference< XMouseClickHandler > xHandler( static_cast< XMouseClickHandler* >( aIterator.next() ) ); |
| if ( !xHandler.is() ) |
| continue; |
| |
| try |
| { |
| if ( nType == EVENT_MOUSEBUTTONDOWN ) |
| bHandled = xHandler->mousePressed( aEvent ); |
| else |
| bHandled = xHandler->mouseReleased( aEvent ); |
| } |
| catch( const DisposedException& e ) |
| { |
| if ( e.Context == xHandler ) |
| aIterator.remove(); |
| } |
| catch( const RuntimeException& ) |
| { |
| throw; |
| } |
| catch( const Exception& ) |
| { |
| } |
| } |
| } |
| break; |
| |
| default: |
| OSL_ENSURE( false, "UserInputInterception::handleNotifyEvent: illegal event type!" ); |
| break; |
| } |
| |
| return bHandled; |
| } |
| |
| //........................................................................ |
| } // namespace sfx2 |
| //........................................................................ |