Tag: cws_src680_odbmacros2 User: fs Date: 2008-01-02 20:27:41+0000 Modified: dba/dbaccess/source/ui/misc/controllerframe.cxx
Log: #i49133# don't rely on frame notifications for activity: window events seem to be more reliable File Changes: Directory: /dba/dbaccess/source/ui/misc/ ======================================== File [changed]: controllerframe.cxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/ui/misc/controllerframe.cxx?r1=1.1.2.6&r2=1.1.2.7 Delta lines: +228 -40 ---------------------- --- controllerframe.cxx 2007-12-22 13:35:53+0000 1.1.2.6 +++ controllerframe.cxx 2008-01-02 20:27:38+0000 1.1.2.7 @@ -4,9 +4,9 @@ * * $RCSfile: controllerframe.cxx,v $ * - * $Revision: 1.1.2.6 $ + * $Revision: 1.1.2.7 $ * - * last change: $Author: fs $ $Date: 2007/12/22 13:35:53 $ + * last change: $Author: fs $ $Date: 2008/01/02 20:27:38 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -38,8 +38,13 @@ /** === begin UNO includes === **/ #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/lang/DisposedException.hpp> /** === end UNO includes === **/ +#include <cppuhelper/implbase1.hxx> +#include <rtl/ref.hxx> #include <sfx2/objsh.hxx> #include <tools/diagnose_ex.h> @@ -68,9 +73,49 @@ using ::com::sun::star::frame::XController; using ::com::sun::star::frame::XFramesSupplier; using ::com::sun::star::sdb::XOfficeDatabaseDocument; + using ::com::sun::star::awt::XTopWindow; + using ::com::sun::star::awt::XTopWindowListener; + using ::com::sun::star::awt::XWindow2; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::lang::EventObject; /** === end UNO using === **/ //==================================================================== + //= FrameWindowActivationListener + //==================================================================== + typedef ::cppu::WeakImplHelper1 < XTopWindowListener + > FrameWindowActivationListener_Base; + class FrameWindowActivationListener : public FrameWindowActivationListener_Base + { + public: + FrameWindowActivationListener( ControllerFrame_Data& _rData ); + + void dispose(); + + protected: + ~FrameWindowActivationListener(); + + // XTopWindowListener + virtual void SAL_CALL windowOpened( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL windowClosing( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL windowClosed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL windowMinimized( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL windowNormalized( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL windowActivated( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL windowDeactivated( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + private: + void impl_checkDisposed_throw() const; + void impl_actOnFrameWindow_nothrow( bool _bRegister ); + + private: + ControllerFrame_Data* m_pData; + }; + + //==================================================================== //= ControllerFrame_Data //==================================================================== struct ControllerFrame_Data @@ -78,18 +123,57 @@ ControllerFrame_Data( IController& _rController ) :m_rController( _rController ) ,m_xFrame() + ,m_pListener() ,m_bActive( false ) { } IController& m_rController; Reference< XFrame > m_xFrame; + ::rtl::Reference< FrameWindowActivationListener > m_pListener; bool m_bActive; }; + //==================================================================== + //= helper + //==================================================================== + //-------------------------------------------------------------------- + static void lcl_setFrame_nothrow( ControllerFrame_Data& _rData, const Reference< XFrame >& _rxFrame ) + { + // release old listener + if ( _rData.m_pListener.get() ) + { + _rData.m_pListener->dispose(); + _rData.m_pListener = NULL; + } + // remember new frame + _rData.m_xFrame = _rxFrame; + // create new listener + if ( _rData.m_xFrame.is() ) + _rData.m_pListener = new FrameWindowActivationListener( _rData ); + } + //-------------------------------------------------------------------- - namespace + static bool lcl_isActive_nothrow( const Reference< XFrame >& _rxFrame ) + { + bool bIsActive = false; + try + { + if ( _rxFrame.is() ) + { + Reference< XWindow2 > xWindow( _rxFrame->getContainerWindow(), UNO_QUERY_THROW ); + bIsActive = xWindow->isActive(); + } + + } + catch( const Exception& ) { + DBG_UNHANDLED_EXCEPTION(); + } + return bIsActive; + } + + //-------------------------------------------------------------------- /** updates various global and local states with a new active component In particular, the following are updated @@ -123,6 +207,112 @@ DBG_UNHANDLED_EXCEPTION(); } } + + //-------------------------------------------------------------------- + static void lcl_updateActive_nothrow( ControllerFrame_Data& _rData, bool _bActive ) + { + if ( _rData.m_bActive == _bActive ) + return; + _rData.m_bActive = _bActive; + + lcl_updateActiveComponents_nothrow( _rData ); + } + + //-------------------------------------------------------------------- + FrameWindowActivationListener::FrameWindowActivationListener( ControllerFrame_Data& _rData ) + :m_pData( &_rData ) + { + impl_actOnFrameWindow_nothrow( true ); + } + + //-------------------------------------------------------------------- + FrameWindowActivationListener::~FrameWindowActivationListener() + { + } + + //-------------------------------------------------------------------- + void FrameWindowActivationListener::dispose() + { + impl_actOnFrameWindow_nothrow( false ); + m_pData = NULL; + } + + //-------------------------------------------------------------------- + void FrameWindowActivationListener::impl_actOnFrameWindow_nothrow( bool _bRegister ) + { + OSL_ENSURE( m_pData && m_pData->m_xFrame.is(), "FrameWindowActivationListener::impl_actOnFrameWindow_nothrow: no frame!" ); + if ( !m_pData || !m_pData->m_xFrame.is() ) + return; + + try + { + void ( SAL_CALL XTopWindow::*pListenerAction )( const Reference< XTopWindowListener >& ) = + _bRegister ? &XTopWindow::addTopWindowListener : &XTopWindow::removeTopWindowListener; + + Reference< XTopWindow > xFrameContainer( m_pData->m_xFrame->getContainerWindow(), UNO_QUERY_THROW ); + (xFrameContainer.get()->*pListenerAction)( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void FrameWindowActivationListener::impl_checkDisposed_throw() const + { + if ( !m_pData ) + throw DisposedException( ::rtl::OUString(), *const_cast< FrameWindowActivationListener* >( this ) ); + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowOpened( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowClosing( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowClosed( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowMinimized( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowNormalized( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowActivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + impl_checkDisposed_throw(); + lcl_updateActive_nothrow( *m_pData, true ); + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::windowDeactivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + impl_checkDisposed_throw(); + lcl_updateActive_nothrow( *m_pData, false ); + } + + //-------------------------------------------------------------------- + void SAL_CALL FrameWindowActivationListener::disposing( const EventObject& /*_rEvent*/ ) throw (RuntimeException) + { + dispose(); } //==================================================================== @@ -142,11 +332,13 @@ //-------------------------------------------------------------------- const Reference< XFrame >& ControllerFrame::attachFrame( const Reference< XFrame >& _rxFrame ) { - m_pData->m_xFrame = _rxFrame; + // set new frame, including listener handling + lcl_setFrame_nothrow( *m_pData, _rxFrame ); - m_pData->m_bActive = m_pData->m_xFrame.is() - && m_pData->m_xFrame->isActive(); + // determine whether we're active + m_pData->m_bActive = lcl_isActive_nothrow( m_pData->m_xFrame ); + // update active component if ( m_pData->m_bActive ) lcl_updateActiveComponents_nothrow( *m_pData ); @@ -186,11 +378,7 @@ break; } - if ( m_pData->m_bActive == bActive ) - return; - m_pData->m_bActive = bActive; - - lcl_updateActiveComponents_nothrow( *m_pData ); + lcl_updateActive_nothrow( *m_pData, bActive ); } //........................................................................ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
