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]

Reply via email to