INTEGRATION: CWS dba23 (1.49.28); FILE MERGED

2005/02/11 12:41:04 oj 1.49.28.4: RESYNC: (1.50-1.51); FILE MERGED
2005/01/26 11:29:41 fs 1.49.28.3: RESYNC: (1.49-1.50); FILE MERGED
2005/01/18 15:44:43 fs 1.49.28.2: #i40647# +mnDrawingOntoParent: prevent recursive calls to certain branches of ::draw
2005/01/13 14:53:50 fs 1.49.28.1: #i40583# notify all events to XMouseListeners asynchronously
This commit is contained in:
Vladimir Glazounov 2005-02-17 09:21:18 +00:00
parent 7a2c344ab9
commit 44b0b7035b

View file

@ -2,9 +2,9 @@
*
* $RCSfile: vclxwindow.cxx,v $
*
* $Revision: 1.51 $
* $Revision: 1.52 $
*
* last change: $Author: rt $ $Date: 2005-01-31 08:58:15 $
* last change: $Author: vg $ $Date: 2005-02-17 10:21:18 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@ -152,12 +152,127 @@
#include <vcl/dockwin.hxx>
#endif
#ifndef COMPHELPER_ASYNCNOTIFICATION_HXX
#include <comphelper/asyncnotification.hxx>
#endif
using ::com::sun::star::style::VerticalAlignment;
using ::com::sun::star::style::VerticalAlignment_TOP;
using ::com::sun::star::style::VerticalAlignment_MIDDLE;
using ::com::sun::star::style::VerticalAlignment_BOTTOM;
using ::com::sun::star::style::VerticalAlignment_MAKE_FIXED_SIZE;
//====================================================================
//= VCLXWindowImpl
//====================================================================
#define EVENT_MOUSE_PRESSED 0
#define EVENT_MOUSE_RELEASED 1
#define EVENT_MOUSE_ENTERED 2
#define EVENT_MOUSE_EXITED 3
class SAL_DLLPRIVATE VCLXWindowImpl : public ::comphelper::IEventProcessor
{
private:
typedef ::comphelper::EventObjectHolder< ::com::sun::star::awt::MouseEvent >
MouseEventType;
typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
ComponentReference;
private:
VCLXWindow& mrAntiImpl;
::vos::IMutex& mrMutex;
::comphelper::AsyncEventNotifier* mpAsyncNotifier;
public:
/** ctor
@param _pAntiImpl
the <type>VCLXWindow</type> instance which the object belongs to. Must
live longer then the object just being constructed.
*/
VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex );
/** asynchronously notifies a mousePressed event to the VCLXWindow's XMouseListeners
*/
void notifyMouseEvent( const ::com::sun::star::awt::MouseEvent& _rMouseEvent, sal_uInt16 _nType );
/** notifies the object that its VCLXWindow is being disposed
*/
void disposing();
protected:
// IEventProcessor
virtual void processEvent( const ::comphelper::EventDescription& _rEvent );
virtual ComponentReference getComponent();
};
//--------------------------------------------------------------------
VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex )
:mrAntiImpl( _rAntiImpl )
,mrMutex( _rMutex )
,mpAsyncNotifier( NULL )
{
}
//--------------------------------------------------------------------
void VCLXWindowImpl::disposing()
{
::vos::OGuard aGuard( mrMutex );
if ( mpAsyncNotifier )
{
mpAsyncNotifier->release();
mpAsyncNotifier = NULL;
}
}
//--------------------------------------------------------------------
void VCLXWindowImpl::notifyMouseEvent( const ::com::sun::star::awt::MouseEvent& _rMouseEvent, sal_uInt16 _nType )
{
::vos::OGuard aGuard( mrMutex );
if ( mrAntiImpl.GetMouseListeners().getLength() )
{
if ( !mpAsyncNotifier )
{
mpAsyncNotifier = new ::comphelper::AsyncEventNotifier( this );
mpAsyncNotifier->acquire();
mpAsyncNotifier->create();
}
mpAsyncNotifier->addEvent( new MouseEventType( _rMouseEvent, _nType ) );
}
}
//--------------------------------------------------------------------
void VCLXWindowImpl::processEvent( const ::comphelper::EventDescription& _rEvent )
{
const MouseEventType aEventDescriptor( static_cast< const MouseEventType& >( _rEvent ) );
const ::com::sun::star::awt::MouseEvent& rEvent( aEventDescriptor.getEventObject() );
switch ( aEventDescriptor.getEventType() )
{
case EVENT_MOUSE_PRESSED:
mrAntiImpl.GetMouseListeners().mousePressed( rEvent );
break;
case EVENT_MOUSE_RELEASED:
mrAntiImpl.GetMouseListeners().mouseReleased( rEvent );
break;
case EVENT_MOUSE_ENTERED:
mrAntiImpl.GetMouseListeners().mouseEntered( rEvent );
break;
case EVENT_MOUSE_EXITED:
mrAntiImpl.GetMouseListeners().mouseExited( rEvent );
break;
default:
DBG_ERROR( "VCLXWindowImpl::processEvent: what kind of event *is* this?" );
}
}
//--------------------------------------------------------------------
VCLXWindowImpl::ComponentReference VCLXWindowImpl::getComponent()
{
return static_cast< ::com::sun::star::awt::XWindow* >( &mrAntiImpl );
}
//====================================================================
//====================================================================
// Mit Out-Parameter besser als Rueckgabewert, wegen Ref-Objekt...
void ImplInitWindowEvent( ::com::sun::star::awt::WindowEvent& rEvent, Window* pWindow )
@ -229,10 +344,14 @@ VCLXWindow::VCLXWindow()
maPaintListeners( *this ),
maContainerListeners( *this ),
maTopWindowListeners( *this ),
mnListenerLockLevel( 0 )
mnListenerLockLevel( 0 ),
mpImpl( NULL ),
mbDrawingOntoParent( false )
{
DBG_CTOR( VCLXWindow, 0 );
mpImpl = new VCLXWindowImpl( *this, GetMutex() );
mbDisposing = sal_False;
mbDesignMode = sal_False;
mbSynthesizingVCLEvent = sal_False;
@ -248,6 +367,8 @@ VCLXWindow::~VCLXWindow()
GetWindow()->SetWindowPeer( NULL, NULL );
GetWindow()->SetAccessible( NULL );
}
DELETEZ( mpImpl );
}
void VCLXWindow::SetWindow( Window* pWindow )
@ -524,7 +645,7 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, aMEvt );
aEvent.PopupTrigger = sal_True;
GetMouseListeners().mousePressed( aEvent );
mpImpl->notifyMouseEvent( aEvent, EVENT_MOUSE_PRESSED );
}
}
break;
@ -537,10 +658,10 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, *pMouseEvt );
if ( pMouseEvt->IsEnterWindow() )
GetMouseListeners().mouseEntered( aEvent );
else
GetMouseListeners().mouseExited( aEvent );
mpImpl->notifyMouseEvent(
aEvent,
pMouseEvt->IsEnterWindow() ? EVENT_MOUSE_ENTERED : EVENT_MOUSE_EXITED
);
}
if ( GetMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
@ -564,7 +685,7 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
::com::sun::star::awt::MouseEvent aEvent;
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, *(MouseEvent*)rVclWindowEvent.GetData() );
GetMouseListeners().mousePressed( aEvent );
mpImpl->notifyMouseEvent( aEvent, EVENT_MOUSE_PRESSED );
}
}
break;
@ -575,7 +696,7 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
::com::sun::star::awt::MouseEvent aEvent;
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, *(MouseEvent*)rVclWindowEvent.GetData() );
GetMouseListeners().mouseReleased( aEvent );
mpImpl->notifyMouseEvent( aEvent, EVENT_MOUSE_RELEASED );
}
}
break;
@ -797,6 +918,8 @@ void VCLXWindow::dispose( ) throw(::com::sun::star::uno::RuntimeException)
{
mbDisposing = sal_True;
mpImpl->disposing();
::com::sun::star::lang::EventObject aObj;
aObj.Source = static_cast< ::cppu::OWeakObject* >( this );
@ -1857,32 +1980,44 @@ void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno:
if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent() == pDev ) )
{
BOOL bWasVisible = pWindow->IsVisible();
Point aOldPos( pWindow->GetPosPixel() );
if ( bWasVisible && aOldPos == aPos )
// #i40647# don't draw here if this is a recursive call
// sometimes this is called recursively, because the Update call on the parent
// (strangely) triggers another paint. Prevent a stack overflow here
// Yes, this is only fixing symptoms for the moment ....
// #i40647# / 2005-01-18 / frank.schoenheit@sun.com
if ( !mbDrawingOntoParent )
{
mbDrawingOntoParent = true;
BOOL bWasVisible = pWindow->IsVisible();
Point aOldPos( pWindow->GetPosPixel() );
if ( bWasVisible && aOldPos == aPos )
{
pWindow->Update();
return;
}
pWindow->SetPosPixel( aPos );
// Erstmal ein Update auf den Parent, damit nicht beim Update
// auf dieses Fenster noch ein Paint vom Parent abgearbeitet wird,
// wo dann ggf. dieses Fenster sofort wieder gehidet wird.
if( pWindow->GetParent() )
pWindow->GetParent()->Update();
pWindow->Show();
pWindow->Update();
return;
pWindow->SetParentUpdateMode( sal_False );
pWindow->Hide();
pWindow->SetParentUpdateMode( sal_True );
pWindow->SetPosPixel( aOldPos );
if ( bWasVisible )
pWindow->Show( TRUE );
mbDrawingOntoParent = false;
}
pWindow->SetPosPixel( aPos );
// Erstmal ein Update auf den Parent, damit nicht beim Update
// auf dieses Fenster noch ein Paint vom Parent abgearbeitet wird,
// wo dann ggf. dieses Fenster sofort wieder gehidet wird.
if( pWindow->GetParent() )
pWindow->GetParent()->Update();
pWindow->Show();
pWindow->Update();
pWindow->SetParentUpdateMode( sal_False );
pWindow->Hide();
pWindow->SetParentUpdateMode( sal_True );
pWindow->SetPosPixel( aOldPos );
if ( bWasVisible )
pWindow->Show( TRUE );
}
else if ( pDev )
{