diff options
author | Andreas Schlüns <as@openoffice.org> | 2001-11-28 10:23:58 +0000 |
---|---|---|
committer | Andreas Schlüns <as@openoffice.org> | 2001-11-28 10:23:58 +0000 |
commit | ed53aaf5842e82f9a8d4d053b39e7db61c6d62ce (patch) | |
tree | 84ac3d67335772ceb222ca86a91571eb822a13e8 | |
parent | f005623a0ef0c60fd9a317c2d33cb049d54007a4 (diff) |
#89611# react for (Beamer!)Frame->dispose() from outside
-rw-r--r-- | sfx2/source/appl/childwin.cxx | 71 | ||||
-rw-r--r-- | sfx2/source/dialog/dockwin.cxx | 13 | ||||
-rw-r--r-- | sfx2/source/dialog/partwnd.cxx | 66 |
3 files changed, 122 insertions, 28 deletions
diff --git a/sfx2/source/appl/childwin.cxx b/sfx2/source/appl/childwin.cxx index 9cb0e88f0428..d610eed6f751 100644 --- a/sfx2/source/appl/childwin.cxx +++ b/sfx2/source/appl/childwin.cxx @@ -2,9 +2,9 @@ * * $RCSfile: childwin.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: mba $ $Date: 2001-11-15 15:17:57 $ + * last change: $Author: as $ $Date: 2001-11-28 11:21:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -76,6 +76,10 @@ #include <com/sun/star/frame/XFrame.hpp> #endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif + #pragma hdrstop #include "childwin.hxx" @@ -97,6 +101,7 @@ SV_IMPL_PTRARR( SfxChildWinContextArr_Impl, SfxChildWinContextFactory* ); struct SfxChildWindow_Impl { ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > xListener; SfxChildWinFactory* pFact; sal_Bool bHideNotDelete; sal_Bool bVisible; @@ -107,6 +112,45 @@ struct SfxChildWindow_Impl // ----------------------------------------------------------------------- +class DisposeListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener > +{ + public: + DisposeListener( SfxChildWindow* pOwner , + SfxChildWindow_Impl* pData ) + : m_pOwner( pOwner ) + , m_pData ( pData ) + {} + + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aSource ) throw (::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > xSelfHold( this ); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( aSource.Source, ::com::sun::star::uno::UNO_QUERY ); + if( xComp.is() ) + xComp->removeEventListener( this ); + + if( m_pOwner && m_pData ) + { + m_pData->xListener = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >(); + m_pData->xFrame = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >(); + + // Attention: Do nothing after "Toogle" call with pOwner & pData! + // They will die insteandly ... We should forget these pointers only!!! + if( m_pData->pWorkWin ) + m_pData->pWorkWin->GetBindings().Execute( m_pOwner->GetType() ); + + m_pOwner = NULL; + m_pData = NULL; + } + } + + private: + SfxChildWindow* m_pOwner; + SfxChildWindow_Impl* m_pData ; +}; + +// ----------------------------------------------------------------------- + sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize ) { if ( rStr.GetTokenCount('/') != 4 ) @@ -150,7 +194,8 @@ SfxChildWindow::~SfxChildWindow() DBG_DTOR(SfxChildWindow,0); if ( pContext ) delete pContext; - delete pWindow; + if ( pWindow ) + delete pWindow; delete pImp; } @@ -728,7 +773,25 @@ sal_Bool SfxChildWindow::QueryClose() void SfxChildWindow::SetFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > & rFrame ) { - pImp->xFrame = rFrame; + // Do nothing if nothing will be changed ... + if( pImp->xFrame != rFrame ) + { + // ... but stop listening on old frame, if connection exist! + if( pImp->xFrame.is() ) + pImp->xFrame->removeEventListener( pImp->xListener ); + + // If new frame isnt NULL -> we must guarantee valid listener for disposing events. + // Use already existing or create new one. + if( rFrame.is() ) + if( !pImp->xListener.is() ) + pImp->xListener = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >( new DisposeListener( this, pImp ) ); + + // Set new frame in data container + // and build new listener connection, if neccessary. + pImp->xFrame = rFrame; + if( pImp->xFrame.is() ) + pImp->xFrame->addEventListener( pImp->xListener ); + } } sal_Bool SfxChildWindow::CanGetFocus() const diff --git a/sfx2/source/dialog/dockwin.cxx b/sfx2/source/dialog/dockwin.cxx index 493f3e5a2e4c..33cafc5a897a 100644 --- a/sfx2/source/dialog/dockwin.cxx +++ b/sfx2/source/dialog/dockwin.cxx @@ -2,9 +2,9 @@ * * $RCSfile: dockwin.cxx,v $ * - * $Revision: 1.13 $ + * $Revision: 1.14 $ * - * last change: $Author: mba $ $Date: 2001-11-21 12:44:07 $ + * last change: $Author: as $ $Date: 2001-11-28 11:23:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -829,12 +829,19 @@ void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const SfxDockingWindow::~SfxDockingWindow() { + ReleaseChildWindow_Impl(); + delete pImp; +} + +void SfxDockingWindow::ReleaseChildWindow_Impl() +{ if ( pMgr && pMgr->GetFrame() == pBindings->GetActiveFrame() ) pBindings->SetActiveFrame( NULL ); if ( pMgr && pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) ) pImp->pSplitWin->RemoveWindow(this); - delete pImp; + + pMgr=NULL; } //------------------------------------------------------------------------- diff --git a/sfx2/source/dialog/partwnd.cxx b/sfx2/source/dialog/partwnd.cxx index 971fee32ead7..fc311857c0ab 100644 --- a/sfx2/source/dialog/partwnd.cxx +++ b/sfx2/source/dialog/partwnd.cxx @@ -2,9 +2,9 @@ * * $RCSfile: partwnd.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: mba $ $Date: 2000-12-18 09:08:26 $ + * last change: $Author: as $ $Date: 2001-11-28 11:22:48 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -197,10 +197,23 @@ SfxPartChildWnd_Impl::SfxPartChildWnd_Impl SfxPartChildWnd_Impl::~SfxPartChildWnd_Impl() { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame = GetFrame(); + + // If xFrame=NULL release pMgr! Because this window lives longer then the manager! + // In these case we got a xFrame->dispose() call from outside ... and has release our + // frame reference in our own DisposingListener. + // But don't do it, if xFrame already exist. Then dispose() must come from inside ... + // and we need a valid pMgr for further operations ... SfxPartDockWnd_Impl* pWin = (SfxPartDockWnd_Impl*) pWindow; - ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame = pWin->ForgetFrame(); + if( pWin != NULL && !xFrame.is() ) + pWin->ReleaseChildWindow_Impl(); + + // Release frame and window. + // If frame reference is valid here ... start dieing from inside by calling dispose(). + SetFrame( NULL ); pWindow = NULL; - xFrame->dispose(); + if( xFrame.is() ) + xFrame->dispose(); } sal_Bool SfxPartChildWnd_Impl::QueryClose() @@ -221,17 +234,17 @@ SfxPartDockWnd_Impl::SfxPartDockWnd_Impl ) : SfxDockingWindow( pBindings, pChildWin, pParent, nBits ) { - m_xFrame = ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > ( + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.frame.Frame") ), ::com::sun::star::uno::UNO_QUERY ); - m_xFrame->initialize( VCLUnoHelper::GetInterface ( this ) ); - pChildWin->SetFrame( m_xFrame ); + xFrame->initialize( VCLUnoHelper::GetInterface ( this ) ); + pChildWin->SetFrame( xFrame ); if ( pBindings->GetDispatcher() ) { ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFramesSupplier > xSupp ( pBindings->GetDispatcher()->GetFrame()->GetFrame()->GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY ); if ( xSupp.is() ) - xSupp->getFrames()->append( m_xFrame ); + xSupp->getFrames()->append( xFrame ); } else DBG_ERROR("Bindings without Dispatcher!"); @@ -243,13 +256,6 @@ SfxPartDockWnd_Impl::~SfxPartDockWnd_Impl() { } -::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > SfxPartDockWnd_Impl::ForgetFrame() -{ - ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xRet( m_xFrame ); - m_xFrame = ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > (); - return xRet; -} - //**************************************************************************** Rectangle impl_Rectangle_Struct2Object( const ::com::sun::star::awt::Rectangle& aRectangleStruct ) @@ -272,18 +278,36 @@ void SfxPartDockWnd_Impl::Resize() sal_Bool SfxPartDockWnd_Impl::QueryClose() { sal_Bool bClose = sal_True; - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > xCtrl = m_xFrame->getController(); - if ( xCtrl.is() ) - bClose = xCtrl->suspend( sal_True ); - return bClose;; + SfxChildWindow* pChild = GetChildWindow_Impl(); + if( pChild ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame = pChild->GetFrame(); + if( xFrame.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > xCtrl = xFrame->getController(); + if( xCtrl.is() ) + bClose = xCtrl->suspend( sal_True ); + } + } + + return bClose; } //**************************************************************************** long SfxPartDockWnd_Impl::Notify( NotifyEvent& rEvt ) { - if ( rEvt.GetType() == EVENT_GETFOCUS && m_xFrame.is() ) - m_xFrame->activate(); + if( rEvt.GetType() == EVENT_GETFOCUS ) + { + SfxChildWindow* pChild = GetChildWindow_Impl(); + if( pChild ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame = pChild->GetFrame(); + if( xFrame.is() ) + xFrame->activate(); + } + } + return SfxDockingWindow::Notify( rEvt ); } |