Files
libreoffice/vcl/source/window/winproc.cxx

2528 lines
92 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 16:07:07 +00:00
*
* $RCSfile: winproc.cxx,v $
2000-09-18 16:07:07 +00:00
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
2000-09-18 16:07:07 +00:00
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
2000-09-18 16:07:07 +00:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
2000-09-18 16:07:07 +00:00
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
2000-09-18 16:07:07 +00:00
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
2000-09-18 16:07:07 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
2000-09-18 16:07:07 +00:00
#ifndef _SV_SVSYS_HXX
#include <svsys.h>
#endif
#ifndef _SV_SALWTYPE_HXX
#include <vcl/salwtype.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_SALFRAME_HXX
#include <vcl/salframe.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _INTN_HXX
//#include <tools/intn.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _VCL_I18NHELP_HXX
#include <vcl/i18nhelp.hxx>
#endif
#include <vcl/unohelp.hxx>
#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif
2000-09-18 16:07:07 +00:00
#ifndef _SV_SVDATA_HXX
#include <vcl/svdata.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_DBGGUI_HXX
#include <dbggui.hxx>
#endif
#ifndef _SV_WINDATA_HXX
#include <windata.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_EVENT_HXX
#include <vcl/event.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_SOUND_HXX
#include <vcl/sound.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_SETTINGS_HXX
#include <vcl/settings.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_CURSOR_HXX
#include <vcl/cursor.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_ACCMGR_HXX
#include <accmgr.hxx>
#endif
#ifndef _SV_PRINT_H
#include <vcl/print.h>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_WINDOW_H
#include <window.h>
#endif
#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_FLOATWIN_HXX
#include <vcl/floatwin.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
2000-09-18 16:07:07 +00:00
#ifndef _SV_HELP_HXX
#include <vcl/help.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_HELPWIN_HXX
#include <helpwin.hxx>
#endif
#ifndef _SV_BRDWIN_HXX
#include <brdwin.hxx>
#endif
#ifndef _SV_DOCKWIN_HXX
#include <vcl/dockwin.hxx>
#endif
2002-08-29 14:42:38 +00:00
#ifndef _SV_SALGDI_HXX
#include <vcl/salgdi.hxx>
2002-08-29 14:42:38 +00:00
#endif
#ifndef _SV_MENU_HXX
#include <vcl/menu.hxx>
#endif
2000-09-18 16:07:07 +00:00
2001-02-05 08:45:05 +00:00
#include <dndlcon.hxx>
#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGSOURCE_HPP_
#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
#endif
2001-02-09 14:59:18 +00:00
#ifndef _COM_SUN_STAR_AWT_MOUSEEVENT_HPP_
#include <com/sun/star/awt/MouseEvent.hpp>
#endif
2001-02-05 08:45:05 +00:00
#if OSL_DEBUG_LEVEL > 1
char dbgbuffer[1024];
#ifndef WNT
#include <stdio.h>
#define MyOutputDebugString(s) (fprintf(stderr, s ))
#else
extern void MyOutputDebugString( char *s);
#endif
#endif
2000-09-18 16:07:07 +00:00
//#define USE_NEW_RTL_IMPLEMENTATION
2000-09-18 16:07:07 +00:00
// =======================================================================
#define IMPL_MIN_NEEDSYSWIN 49
// =======================================================================
long ImplCallPreNotify( NotifyEvent& rEvt )
{
long nRet = Application::CallEventHooks( rEvt );
if ( !nRet )
nRet = rEvt.GetWindow()->PreNotify( rEvt );
return nRet;
}
// =======================================================================
long ImplCallEvent( NotifyEvent& rEvt )
{
long nRet = ImplCallPreNotify( rEvt );
if ( !nRet )
{
Window* pWindow = rEvt.GetWindow();
switch ( rEvt.GetType() )
{
case EVENT_MOUSEBUTTONDOWN:
pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
break;
case EVENT_MOUSEBUTTONUP:
pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
break;
case EVENT_MOUSEMOVE:
pWindow->MouseMove( *rEvt.GetMouseEvent() );
break;
case EVENT_KEYINPUT:
pWindow->KeyInput( *rEvt.GetKeyEvent() );
break;
case EVENT_KEYUP:
pWindow->KeyUp( *rEvt.GetKeyEvent() );
break;
case EVENT_GETFOCUS:
pWindow->GetFocus();
break;
case EVENT_LOSEFOCUS:
pWindow->LoseFocus();
break;
case EVENT_COMMAND:
pWindow->Command( *rEvt.GetCommandEvent() );
break;
}
}
return nRet;
}
// =======================================================================
static BOOL ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
USHORT nCode, USHORT nSVEvent,
BOOL bMouseLeave )
{
ImplSVData* pSVData = ImplGetSVData();
if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
!pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
{
/*
* #93895# since floats are system windows, coordinates have
* to be converted to float relative for the hittest
*/
USHORT nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
2000-09-18 16:07:07 +00:00
FloatingWindow* pLastLevelFloat;
ULONG nPopupFlags;
if ( nSVEvent == EVENT_MOUSEMOVE )
{
if ( bMouseLeave )
return TRUE;
if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
{
2002-04-24 11:12:05 +00:00
if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
2000-09-18 16:07:07 +00:00
ImplDestroyHelpWindow();
pChild->ImplGetFrame()->SetPointer( POINTER_ARROW );
2000-09-18 16:07:07 +00:00
return TRUE;
}
}
else
{
if ( nCode & MOUSE_LEFT )
{
if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
{
if ( !pFloat )
{
pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
// Erstmal ausgebaut als Hack fuer Bug 53378
// if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
// return FALSE;
// else
return TRUE;
}
else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
{
if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
pFloat->ImplSetMouseDown();
return TRUE;
}
}
else
{
if ( pFloat )
{
if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
{
if ( pFloat->ImplIsMouseDown() )
pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
return TRUE;
}
}
else
{
pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
{
pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
return TRUE;
}
}
}
}
else
{
if ( !pFloat )
{
pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
{
if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
(nSVEvent == EVENT_MOUSEBUTTONUP) )
2000-09-18 16:07:07 +00:00
return TRUE;
pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
return FALSE;
else
return TRUE;
}
else
return TRUE;
}
}
}
}
return FALSE;
}
// -----------------------------------------------------------------------
static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
{
ImplSVData* pSVData = ImplGetSVData();
if ( !pSVData->maHelpData.mpHelpWin ||
!( pSVData->maHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
pChild->IsWindowOrChild( pSVData->maHelpData.mpHelpWin ) ) )
2000-09-18 16:07:07 +00:00
{
USHORT nHelpMode = 0;
if ( pSVData->maHelpData.mbQuickHelp )
nHelpMode = HELPMODE_QUICK;
if ( pSVData->maHelpData.mbBalloonHelp )
nHelpMode |= HELPMODE_BALLOON;
if ( nHelpMode )
{
if ( pChild->IsInputEnabled() )
{
HelpEvent aHelpEvent( rMousePos, nHelpMode );
pSVData->maHelpData.mbRequestingHelp = TRUE;
pChild->RequestHelp( aHelpEvent );
pSVData->maHelpData.mbRequestingHelp = FALSE;
}
2002-10-14 12:20:36 +00:00
// #104172# do not kill keyboard activated tooltips
else if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp)
2000-09-18 16:07:07 +00:00
{
ImplDestroyHelpWindow();
2000-09-18 16:07:07 +00:00
}
}
}
}
// -----------------------------------------------------------------------
static void ImplSetMousePointer( Window* pChild )
{
2001-07-06 15:07:09 +00:00
ImplSVData* pSVData = ImplGetSVData();
2001-02-14 07:32:01 +00:00
if ( pSVData->maHelpData.mbExtHelpMode )
pChild->ImplGetFrame()->SetPointer( POINTER_HELP );
2000-09-18 16:07:07 +00:00
else
pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2000-11-06 19:38:47 +00:00
static BOOL ImplCallCommand( Window* pChild, USHORT nEvt, void* pData = NULL,
BOOL bMouse = FALSE, Point* pPos = NULL )
{
Point aPos;
if ( pPos )
aPos = *pPos;
else
{
if( bMouse )
aPos = pChild->GetPointerPosPixel();
else
{
// simulate mouseposition at center of window
Size aSize = pChild->GetOutputSize();
aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
}
}
2000-11-06 19:38:47 +00:00
CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
ImplDelData aDelData( pChild );
BOOL bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
if ( aDelData.IsDelete() )
return FALSE;
if ( !bPreNotify )
2000-11-06 19:38:47 +00:00
{
pChild->ImplGetWindowImpl()->mbCommand = FALSE;
2000-11-06 19:38:47 +00:00
pChild->Command( aCEvt );
if( aDelData.IsDelete() )
return FALSE;
pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
if ( aDelData.IsDelete() )
return FALSE;
if ( pChild->ImplGetWindowImpl()->mbCommand )
return TRUE;
2000-11-06 19:38:47 +00:00
}
return FALSE;
}
// -----------------------------------------------------------------------
/* #i34277# delayed context menu activation;
* necessary if there already was a popup menu running.
*/
struct ContextMenuEvent
{
Window* pWindow;
ImplDelData aDelData;
Point aChildPos;
};
static long ContextMenuEventLink( void* pCEvent, void* )
{
ContextMenuEvent* pEv = (ContextMenuEvent*)pCEvent;
if( ! pEv->aDelData.IsDelete() )
{
pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
ImplCallCommand( pEv->pWindow, COMMAND_CONTEXTMENU, NULL, TRUE, &pEv->aChildPos );
}
delete pEv;
return 0;
}
2000-09-18 16:07:07 +00:00
long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave,
long nX, long nY, ULONG nMsgTime,
USHORT nCode, USHORT nMode )
{
ImplSVData* pSVData = ImplGetSVData();
Point aMousePos( nX, nY );
Window* pChild;
long nRet;
USHORT nClicks;
ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
USHORT nOldCode = pWinFrameData->mnMouseCode;
2000-09-18 16:07:07 +00:00
// we need a mousemove event, befor we get a mousebuttondown or a
// mousebuttonup event
if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
(nSVEvent == EVENT_MOUSEBUTTONUP) )
{
if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
Help::EndExtHelp();
if ( pSVData->maHelpData.mpHelpWin )
2002-10-14 12:20:36 +00:00
{
if( pWindow->ImplGetWindow() == pSVData->maHelpData.mpHelpWin )
{
ImplDestroyHelpWindow();
return 1; // pWindow is dead now - avoid crash!
}
else
ImplDestroyHelpWindow();
}
2000-09-18 16:07:07 +00:00
if ( (pWinFrameData->mnLastMouseX != nX) ||
(pWinFrameData->mnLastMouseY != nY) )
2000-09-18 16:07:07 +00:00
{
ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE, nX, nY, nMsgTime, nCode, nMode );
}
}
// update frame data
pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
pWinFrameData->mnLastMouseX = nX;
pWinFrameData->mnLastMouseY = nY;
pWinFrameData->mnMouseCode = nCode;
pWinFrameData->mnMouseMode = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
2000-09-18 16:07:07 +00:00
if ( bMouseLeave )
{
pWinFrameData->mbMouseIn = FALSE;
2002-04-24 11:12:05 +00:00
if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
{
ImplDelData aDelData( pWindow );
2000-09-18 16:07:07 +00:00
ImplDestroyHelpWindow();
if ( aDelData.IsDelete() )
return 1; // pWindow is dead now - avoid crash! (#122045#)
}
2000-09-18 16:07:07 +00:00
}
else
pWinFrameData->mbMouseIn = TRUE;
2000-09-18 16:07:07 +00:00
DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
(pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
"ImplHandleMouseEvent: TrackWin != CaptureWin" );
// AutoScrollMode
if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
{
pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
return 1;
}
// find mouse window
if ( pSVData->maWinData.mpCaptureWin )
{
pChild = pSVData->maWinData.mpCaptureWin;
DBG_ASSERT( pWindow == pChild->ImplGetFrameWindow(),
2000-09-18 16:07:07 +00:00
"ImplHandleMouseEvent: mouse event is not sent to capture window" );
// java client cannot capture mouse correctly
if ( pWindow != pChild->ImplGetFrameWindow() )
return 0;
2000-09-18 16:07:07 +00:00
if ( bMouseLeave )
return 0;
}
else
{
if ( bMouseLeave )
pChild = NULL;
else
pChild = pWindow->ImplFindWindow( aMousePos );
}
// test this because mouse events are buffered in the remote version
// and size may not be in sync
if ( !pChild && !bMouseLeave )
return 0;
// Ein paar Test ausfuehren und Message abfangen oder Status umsetzen
if ( pChild )
{
2002-08-29 14:42:38 +00:00
if( pChild->ImplHasMirroredGraphics() && !pChild->IsRTLEnabled() )
{
// - RTL - re-mirror frame pos at pChild
#ifdef USE_NEW_RTL_IMPLEMENTATION
Window *pRefWindow = (Window*) pChild->mpDummy4;
pRefWindow->ImplReMirror( aMousePos );
#else
pChild->ImplReMirror( aMousePos );
#endif
2002-08-29 14:42:38 +00:00
}
// no mouse messages to system object windows ?
// !!!KA: Is it OK to comment this out? !!!
// if ( pChild->ImplGetWindowImpl()->mpSysObj )
// return 0;
2000-09-18 16:07:07 +00:00
// no mouse messages to disabled windows
// #106845# if the window was disabed during capturing we have to pass the mouse events to release capturing
if ( pSVData->maWinData.mpCaptureWin != pChild && (!pChild->IsEnabled() || !pChild->IsInputEnabled()) )
2000-09-18 16:07:07 +00:00
{
ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
if ( nSVEvent == EVENT_MOUSEMOVE )
ImplHandleMouseHelpRequest( pChild, aMousePos );
// Call the hook also, if Window is disabled
Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
Application::CallEventHooks( aNEvt );
2000-09-18 16:07:07 +00:00
if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
{
Sound::Beep( SOUND_DISABLE, pChild );
return 1;
}
else
{
// Set normal MousePointer for disabled windows
2000-09-18 16:07:07 +00:00
if ( nSVEvent == EVENT_MOUSEMOVE )
ImplSetMousePointer( pChild );
2000-09-18 16:07:07 +00:00
return 0;
}
}
// End ExtTextInput-Mode, if the user click in the same TopLevel Window
if ( pSVData->maWinData.mpExtTextInputWin &&
((nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
(nSVEvent == EVENT_MOUSEBUTTONUP)) )
pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
2000-09-18 16:07:07 +00:00
}
// determine mouse event data
if ( nSVEvent == EVENT_MOUSEMOVE )
{
// Testen, ob MouseMove an das gleiche Fenster geht und sich der
// Status nicht geaendert hat
if ( pChild )
{
Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
if ( !bMouseLeave &&
(pChild == pWinFrameData->mpMouseMoveWin) &&
(aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
(aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
(nOldCode == pWinFrameData->mnMouseCode) )
2000-09-18 16:07:07 +00:00
{
// Mouse-Pointer neu setzen, da er sich geaendet haben
// koennte, da ein Modus umgesetzt wurde
ImplSetMousePointer( pChild );
return 0;
}
pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
2000-09-18 16:07:07 +00:00
}
// mouse click
nClicks = pWinFrameData->mnClickCount;
2000-09-18 16:07:07 +00:00
// Gegebenenfalls den Start-Drag-Handler rufen.
// Achtung: Muss vor Move gerufen werden, da sonst bei schnellen
// Mausbewegungen die Applikationen in den Selektionszustand gehen.
Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
2000-09-18 16:07:07 +00:00
if ( pMouseDownWin )
{
// Testen, ob StartDrag-Modus uebereinstimmt. Wir vergleichen nur
// den Status der Maustasten, damit man mit Mod1 z.B. sofort
// in den Kopiermodus gehen kann.
const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
(rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
{
if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
2000-09-18 16:07:07 +00:00
{
long nDragW = rMSettings.GetStartDragWidth();
long nDragH = rMSettings.GetStartDragWidth();
2002-12-12 15:46:10 +00:00
//long nMouseX = nX;
//long nMouseY = nY;
long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
long nMouseY = aMousePos.Y();
if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
!(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
2000-09-18 16:07:07 +00:00
{
pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = TRUE;
2001-02-09 14:59:18 +00:00
// Check if drag source provides it's own recognizer
if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
2001-02-05 08:45:05 +00:00
{
// query DropTarget from child window
::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > ( pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
::com::sun::star::uno::UNO_QUERY );
if( xDragGestureRecognizer.is() )
{
// retrieve mouse position relative to mouse down window
Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
// create a uno mouse event out of the available data
::com::sun::star::awt::MouseEvent aMouseEvent(
static_cast < ::com::sun::star::uno::XInterface * > ( 0 ),
#ifdef MACOSX
nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD5),
#else
nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
#endif
nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
nMouseX,
nMouseY,
nClicks,
sal_False );
ULONG nCount = Application::ReleaseSolarMutex();
// FIXME: where do I get Action from ?
::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
if( xDragSource.is() )
{
static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
relLoc.X(), relLoc.Y(), xDragSource, ::com::sun::star::uno::makeAny( aMouseEvent ) );
}
Application::AcquireSolarMutex( nCount );
}
2001-02-05 08:45:05 +00:00
}
2000-09-18 16:07:07 +00:00
}
}
}
else
pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = TRUE;
2000-09-18 16:07:07 +00:00
}
// test for mouseleave and mouseenter
Window* pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
2000-09-18 16:07:07 +00:00
if ( pChild != pMouseMoveWin )
{
if ( pMouseMoveWin )
{
Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
ImplDelData aDelData;
ImplDelData aDelData2;
pWinFrameData->mbInMouseMove = TRUE;
pMouseMoveWin->ImplGetWinData()->mbMouseOver = FALSE;
2000-09-18 16:07:07 +00:00
pMouseMoveWin->ImplAddDel( &aDelData );
// Durch MouseLeave kann auch dieses Fenster zerstoert
// werden
if ( pChild )
pChild->ImplAddDel( &aDelData2 );
if ( !ImplCallPreNotify( aNLeaveEvt ) )
{
2001-07-06 15:07:09 +00:00
pMouseMoveWin->MouseMove( aMLeaveEvt );
// #82968#
if( !aDelData.IsDelete() )
aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
}
2000-09-18 16:07:07 +00:00
pWinFrameData->mpMouseMoveWin = NULL;
pWinFrameData->mbInMouseMove = FALSE;
2000-09-18 16:07:07 +00:00
if ( pChild )
{
if ( aDelData2.IsDelete() )
pChild = NULL;
else
pChild->ImplRemoveDel( &aDelData2 );
}
if ( aDelData.IsDelete() )
return 1;
pMouseMoveWin->ImplRemoveDel( &aDelData );
}
nMode |= MOUSE_ENTERWINDOW;
}
pWinFrameData->mpMouseMoveWin = pChild;
if( pChild )
pChild->ImplGetWinData()->mbMouseOver = TRUE;
2000-09-18 16:07:07 +00:00
// MouseLeave
if ( !pChild )
return 0;
}
else
{
// mouse click
if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
{
const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
ULONG nDblClkTime = rMSettings.GetDoubleClickTime();
long nDblClkW = rMSettings.GetDoubleClickWidth();
long nDblClkH = rMSettings.GetDoubleClickHeight();
2002-12-12 15:46:10 +00:00
//long nMouseX = nX;
//long nMouseY = nY;
long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
long nMouseY = aMousePos.Y();
2000-09-18 16:07:07 +00:00
if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
(nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
2000-09-18 16:07:07 +00:00
{
pChild->ImplGetFrameData()->mnClickCount++;
pChild->ImplGetFrameData()->mbStartDragCalled = TRUE;
2000-09-18 16:07:07 +00:00
}
else
{
pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
pChild->ImplGetFrameData()->mnClickCount = 1;
pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
pChild->ImplGetFrameData()->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
2000-09-18 16:07:07 +00:00
(rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
}
pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
2000-09-18 16:07:07 +00:00
}
nClicks = pChild->ImplGetFrameData()->mnClickCount;
2000-09-18 16:07:07 +00:00
pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
}
DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
// create mouse event
Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
// tracking window gets the mouse events
if ( pSVData->maWinData.mpTrackWin )
pChild = pSVData->maWinData.mpTrackWin;
// handle FloatingMode
if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
{
ImplDelData aDelData;
pChild->ImplAddDel( &aDelData );
if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
{
if ( !aDelData.IsDelete() )
{
pChild->ImplRemoveDel( &aDelData );
pChild->ImplGetFrameData()->mbStartDragCalled = TRUE;
2000-09-18 16:07:07 +00:00
}
return 1;
}
else
pChild->ImplRemoveDel( &aDelData );
}
// call handler
BOOL bDrag = FALSE;
BOOL bCallHelpRequest = TRUE;
DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
ImplDelData aDelData;
NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
pChild->ImplAddDel( &aDelData );
if ( nSVEvent == EVENT_MOUSEMOVE )
pChild->ImplGetFrameData()->mbInMouseMove = TRUE;
2001-07-06 15:07:09 +00:00
// bring window into foreground on mouseclick
2001-07-06 15:07:09 +00:00
if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
2000-09-18 16:07:07 +00:00
{
if( !pSVData->maWinData.mpFirstFloat && // totop for floating windows in popup would change the focus and would close them immediately
!(pChild->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION) ) // ownerdrawdecorated windows must never grab focus
2001-10-24 07:57:18 +00:00
pChild->ToTop();
2001-07-06 15:07:09 +00:00
if ( aDelData.IsDelete() )
return 1;
2000-09-18 16:07:07 +00:00
}
2001-07-06 15:07:09 +00:00
if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDelete() )
nRet = 1;
2000-09-18 16:07:07 +00:00
else
{
2001-07-06 15:07:09 +00:00
nRet = 0;
if ( nSVEvent == EVENT_MOUSEMOVE )
2000-09-18 16:07:07 +00:00
{
2001-07-06 15:07:09 +00:00
if ( pSVData->maWinData.mpTrackWin )
2000-09-18 16:07:07 +00:00
{
2001-07-06 15:07:09 +00:00
TrackingEvent aTEvt( aMEvt );
pChild->Tracking( aTEvt );
if ( !aDelData.IsDelete() )
2000-09-18 16:07:07 +00:00
{
2001-07-06 15:07:09 +00:00
// When ScrollRepeat, we restart the timer
if ( pSVData->maWinData.mpTrackTimer &&
(pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
pSVData->maWinData.mpTrackTimer->Start();
2000-09-18 16:07:07 +00:00
}
2001-07-06 15:07:09 +00:00
bCallHelpRequest = FALSE;
nRet = 1;
2000-09-18 16:07:07 +00:00
}
2001-07-06 15:07:09 +00:00
else
2000-09-18 16:07:07 +00:00
{
2001-07-06 15:07:09 +00:00
// Auto-ToTop
if ( !pSVData->maWinData.mpCaptureWin &&
(pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
pChild->ToTop( TOTOP_NOGRABFOCUS );
if( aDelData.IsDelete() )
2001-07-06 15:07:09 +00:00
bCallHelpRequest = FALSE;
else
{
// if the MouseMove handler changes the help window's visibility
// the HelpRequest handler should not be called anymore
Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
pChild->ImplGetWindowImpl()->mbMouseMove = FALSE;
pChild->MouseMove( aMEvt );
if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
bCallHelpRequest = FALSE;
}
2000-09-18 16:07:07 +00:00
}
2001-07-06 15:07:09 +00:00
}
else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
{
if ( pSVData->maWinData.mpTrackWin &&
!(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
nRet = 1;
2000-09-18 16:07:07 +00:00
else
{
pChild->ImplGetWindowImpl()->mbMouseButtonDown = FALSE;
2001-07-06 15:07:09 +00:00
pChild->MouseButtonDown( aMEvt );
}
}
else
{
if ( pSVData->maWinData.mpTrackWin )
{
pChild->EndTracking();
nRet = 1;
}
else
{
pChild->ImplGetWindowImpl()->mbMouseButtonUp = FALSE;
2001-07-06 15:07:09 +00:00
pChild->MouseButtonUp( aMEvt );
2000-09-18 16:07:07 +00:00
}
}
// #82968#
if ( !aDelData.IsDelete() )
aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
2000-09-18 16:07:07 +00:00
}
if ( aDelData.IsDelete() )
return 1;
2000-09-18 16:07:07 +00:00
if ( nSVEvent == EVENT_MOUSEMOVE )
pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = FALSE;
2000-09-18 16:07:07 +00:00
if ( nSVEvent == EVENT_MOUSEMOVE )
{
2002-04-24 11:12:05 +00:00
if ( bCallHelpRequest && !pSVData->maHelpData.mbKeyboardHelp )
2000-09-18 16:07:07 +00:00
ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
nRet = 1;
}
else if ( !nRet )
{
if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
{
if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
2000-09-18 16:07:07 +00:00
nRet = 1;
}
else
{
if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
2000-09-18 16:07:07 +00:00
nRet = 1;
}
}
pChild->ImplRemoveDel( &aDelData );
2000-11-06 19:38:47 +00:00
if ( nSVEvent == EVENT_MOUSEMOVE )
2000-09-18 16:07:07 +00:00
{
2000-11-06 19:38:47 +00:00
// set new mouse pointer
if ( !bMouseLeave )
ImplSetMousePointer( pChild );
}
else if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP) )
{
if ( !bDrag )
2000-09-18 16:07:07 +00:00
{
2001-04-25 15:30:26 +00:00
// Command-Events
2000-11-06 19:38:47 +00:00
if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
(nCode == MOUSE_MIDDLE) )
2001-04-25 15:30:26 +00:00
{
USHORT nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
if ( nMiddleAction == MOUSE_MIDDLE_AUTOSCROLL )
nRet = !ImplCallCommand( pChild, COMMAND_STARTAUTOSCROLL, NULL, TRUE, &aChildPos );
else if ( nMiddleAction == MOUSE_MIDDLE_PASTESELECTION )
nRet = !ImplCallCommand( pChild, COMMAND_PASTESELECTION, NULL, TRUE, &aChildPos );
}
2000-09-18 16:07:07 +00:00
else
{
2000-11-06 19:38:47 +00:00
// ContextMenu
const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
if ( (nCode == rMSettings.GetContextMenuCode()) &&
(nClicks == rMSettings.GetContextMenuClicks()) )
2000-09-18 16:07:07 +00:00
{
2000-11-06 19:38:47 +00:00
BOOL bContextMenu;
if ( rMSettings.GetContextMenuDown() )
bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
2000-09-18 16:07:07 +00:00
else
2000-11-06 19:38:47 +00:00
bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
if ( bContextMenu )
{
if( pSVData->maAppData.mpActivePopupMenu )
{
/* #i34277# there already is a context menu open
* that was probably just closed with EndPopupMode.
* We need to give the eventual corresponding
* PopupMenu::Execute a chance to end properly.
* Therefore delay context menu command and
* issue only after popping one frame of the
* Yield stack.
*/
ContextMenuEvent* pEv = new ContextMenuEvent;
pEv->pWindow = pChild;
pEv->aChildPos = aChildPos;
pChild->ImplAddDel( &pEv->aDelData );
Application::PostUserEvent( Link( pEv, ContextMenuEventLink ) );
}
else
nRet = ! ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, TRUE, &aChildPos );
}
2000-09-18 16:07:07 +00:00
}
}
}
}
return nRet;
}
// -----------------------------------------------------------------------
static Window* ImplGetKeyInputWindow( Window* pWindow )
{
ImplSVData* pSVData = ImplGetSVData();
// determine last input time
pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
// #127104# workaround for destroyed windows
if( pWindow->ImplGetWindowImpl() == NULL )
return 0;
// find window - is every time the window which has currently the
// focus or the last time the focus.
2001-10-24 07:57:18 +00:00
// the first floating window always has the focus
Window* pChild = pSVData->maWinData.mpFirstFloat;
if( !pChild || ( pChild->ImplGetWindowImpl()->mbFloatWin && !((FloatingWindow *)pChild)->GrabsFocus() ) )
pChild = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
else
{
// allow floaters to forward keyinput to some member
pChild = pChild->GetPreferredKeyInputWindow();
}
2000-09-18 16:07:07 +00:00
// no child - than no input
if ( !pChild )
2000-09-18 16:07:07 +00:00
return 0;
// We call also KeyInput if we haven't the focus, because on Unix
// system this is often the case when a Lookup Choise Window has
// the focus - because this windows send the KeyInput directly to
// the window without resetting the focus
DBG_ASSERTWARNING( pChild == pSVData->maWinData.mpFocusWin,
"ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
2000-09-18 16:07:07 +00:00
// no keyinput to disabled windows
if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
return 0;
return pChild;
}
// -----------------------------------------------------------------------
static long ImplHandleKey( Window* pWindow, USHORT nSVEvent,
USHORT nKeyCode, USHORT nCharCode, USHORT nRepeat, BOOL bForward )
2000-09-18 16:07:07 +00:00
{
ImplSVData* pSVData = ImplGetSVData();
KeyCode aKeyCode( nKeyCode, nKeyCode );
USHORT nEvCode = aKeyCode.GetCode();
2000-09-18 16:07:07 +00:00
// allow application key listeners to remove the key event
// but make sure we're not forwarding external KeyEvents, (ie where bForward is FALSE)
// becasue those are coming back from the listener itself and MUST be processed
KeyEvent aKeyEvent( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
if( bForward )
2002-08-23 09:05:47 +00:00
{
USHORT nVCLEvent;
switch( nSVEvent )
{
case EVENT_KEYINPUT:
nVCLEvent = VCLEVENT_WINDOW_KEYINPUT;
break;
case EVENT_KEYUP:
nVCLEvent = VCLEVENT_WINDOW_KEYUP;
break;
default:
nVCLEvent = 0;
break;
}
if( nVCLEvent && pSVData->mpApp->HandleKey( nVCLEvent, pWindow, &aKeyEvent ) )
return 1;
2002-08-23 09:05:47 +00:00
}
// #i1820# use locale specific decimal separator
if( nEvCode == KEY_DECIMAL )
{
if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
{
String aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
nCharCode = (USHORT) aSep.GetChar(0);
}
}
2002-04-18 14:04:39 +00:00
BOOL bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
2000-09-18 16:07:07 +00:00
// determine last input time
pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
// handle tracking window
if ( nSVEvent == EVENT_KEYINPUT )
{
#ifdef DBG_UTIL
// #105224# use Ctrl-Alt-Shift-D, Ctrl-Shift-D must be useable by app
if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && aKeyCode.IsMod2() && (aKeyCode.GetCode() == KEY_D) )
2000-09-18 16:07:07 +00:00
{
DBGGUI_START();
return 1;
}
#endif
if ( pSVData->maHelpData.mbExtHelpMode )
{
Help::EndExtHelp();
if ( nEvCode == KEY_ESCAPE )
2000-09-18 16:07:07 +00:00
return 1;
}
if ( pSVData->maHelpData.mpHelpWin )
ImplDestroyHelpWindow();
// AutoScrollMode
if ( pSVData->maWinData.mpAutoScrollWin )
{
pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
if ( nEvCode == KEY_ESCAPE )
2000-09-18 16:07:07 +00:00
return 1;
}
if ( pSVData->maWinData.mpTrackWin )
{
USHORT nOrigCode = aKeyCode.GetCode();
2000-09-18 16:07:07 +00:00
if ( (nOrigCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
2000-09-18 16:07:07 +00:00
{
pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
if ( pSVData->maWinData.mpFirstFloat )
{
FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
{
USHORT nEscCode = aKeyCode.GetCode();
2000-09-18 16:07:07 +00:00
if ( nEscCode == KEY_ESCAPE )
2000-09-18 16:07:07 +00:00
pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
}
}
return 1;
}
else if ( nOrigCode == KEY_RETURN )
2000-09-18 16:07:07 +00:00
{
pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
return 1;
}
else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
return 1;
}
// handle FloatingMode
if ( pSVData->maWinData.mpFirstFloat )
{
FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
{
USHORT nCode = aKeyCode.GetCode();
2002-04-18 14:04:39 +00:00
if ( (nCode == KEY_ESCAPE) || bCtrlF6)
2000-09-18 16:07:07 +00:00
{
pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
2002-04-18 14:04:39 +00:00
if( !bCtrlF6 )
return 1;
2000-09-18 16:07:07 +00:00
}
}
}
// test for accel
if ( pSVData->maAppData.mpAccelMgr )
{
if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
return 1;
}
}
// find window
Window* pChild = ImplGetKeyInputWindow( pWindow );
if ( !pChild )
2000-09-18 16:07:07 +00:00
return 0;
// --- RTL --- mirror cursor keys
if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
pChild->ImplHasMirroredGraphics() && pChild->IsRTLEnabled() )
aKeyCode = KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
2000-09-18 16:07:07 +00:00
// call handler
ImplDelData aDelData;
pChild->ImplAddDel( &aDelData );
KeyEvent aKeyEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
BOOL bKeyPreNotify = (ImplCallPreNotify( aNotifyEvt ) != 0);
2000-09-18 16:07:07 +00:00
long nRet = 1;
if ( !bKeyPreNotify && !aDelData.IsDelete() )
2000-09-18 16:07:07 +00:00
{
if ( nSVEvent == EVENT_KEYINPUT )
{
pChild->ImplGetWindowImpl()->mbKeyInput = FALSE;
pChild->KeyInput( aKeyEvt );
2000-09-18 16:07:07 +00:00
}
else
{
pChild->ImplGetWindowImpl()->mbKeyUp = FALSE;
pChild->KeyUp( aKeyEvt );
2000-09-18 16:07:07 +00:00
}
// #82968#
if( !aDelData.IsDelete() )
aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
2000-09-18 16:07:07 +00:00
}
if ( aDelData.IsDelete() )
return 1;
pChild->ImplRemoveDel( &aDelData );
if ( nSVEvent == EVENT_KEYINPUT )
{
if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
2000-09-18 16:07:07 +00:00
{
USHORT nCode = aKeyCode.GetCode();
// #101999# is focus in or below toolbox
BOOL bToolboxFocus=FALSE;
if( (nCode == KEY_F1) && aKeyCode.IsShift() )
{
Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
while( pWin )
{
if( pWin->ImplGetWindowImpl()->mbToolBox )
{
bToolboxFocus = TRUE;
break;
}
else
pWin = pWin->GetParent();
}
}
2000-09-18 16:07:07 +00:00
// ContextMenu
if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
2000-11-06 19:38:47 +00:00
nRet = !ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, FALSE );
else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
// #101999# no active help when focus in toolbox, simulate BallonHelp instead
( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
2002-08-30 11:28:43 +00:00
{
// TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
// simulate mouseposition at center of window
2002-10-14 12:20:36 +00:00
2002-08-30 11:28:43 +00:00
Size aSize = pChild->GetOutputSize();
Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
aPos = pChild->OutputToScreenPixel( aPos );
HelpEvent aHelpEvent( aPos, HELPMODE_BALLOON );
aHelpEvent.SetKeyboardActivated( TRUE );
pSVData->maHelpData.mbSetKeyboardHelp = TRUE;
2002-08-30 11:28:43 +00:00
pChild->RequestHelp( aHelpEvent );
pSVData->maHelpData.mbSetKeyboardHelp = FALSE;
2002-08-30 11:28:43 +00:00
}
2000-09-18 16:07:07 +00:00
else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
{
if ( !aKeyCode.GetModifier() )
{
if ( pSVData->maHelpData.mbContextHelp )
{
Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
pChild->RequestHelp( aHelpEvent );
}
else
nRet = 0;
}
else if ( aKeyCode.IsShift() )
{
if ( pSVData->maHelpData.mbExtHelp )
Help::StartExtHelp();
else
nRet = 0;
}
}
else
{
if ( ImplCallHotKey( aKeyCode ) )
nRet = 1;
else
nRet = 0;
}
}
}
else
{
if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
2000-09-18 16:07:07 +00:00
nRet = 0;
}
// #105591# send keyinput to parent if we are a floating window and the key was not pocessed yet
if( !nRet && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
{
pChild = pWindow->GetParent();
// call handler
ImplDelData aChildDelData( pChild );
KeyEvent aKEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
BOOL bPreNotify = (ImplCallPreNotify( aNEvt ) != 0);
if ( aChildDelData.IsDelete() )
return 1;
if ( !bPreNotify )
{
if ( nSVEvent == EVENT_KEYINPUT )
{
pChild->ImplGetWindowImpl()->mbKeyInput = FALSE;
pChild->KeyInput( aKEvt );
}
else
{
pChild->ImplGetWindowImpl()->mbKeyUp = FALSE;
pChild->KeyUp( aKEvt );
}
// #82968#
if( !aChildDelData.IsDelete() )
aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
if ( aChildDelData.IsDelete() )
return 1;
}
if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
nRet = 1;
}
2000-09-18 16:07:07 +00:00
return nRet;
}
// -----------------------------------------------------------------------
static long ImplHandleExtTextInput( Window* pWindow,
2000-11-03 08:04:36 +00:00
const XubString& rText,
const USHORT* pTextAttr,
2000-11-06 19:38:47 +00:00
ULONG nCursorPos, USHORT nCursorFlags )
2000-09-18 16:07:07 +00:00
{
ImplSVData* pSVData = ImplGetSVData();
Window* pChild = NULL;
2000-11-03 08:04:36 +00:00
int nTries = 200;
while( nTries-- )
2000-11-03 08:04:36 +00:00
{
pChild = pSVData->maWinData.mpExtTextInputWin;
2000-11-03 08:04:36 +00:00
if ( !pChild )
{
pChild = ImplGetKeyInputWindow( pWindow );
if ( !pChild )
return 0;
}
if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
break;
Application::Yield();
2000-11-03 08:04:36 +00:00
}
2000-11-06 19:38:47 +00:00
// If it is the first ExtTextInput call, we inform the information
// and allocate the data, which we must store in this mode
ImplWinData* pWinData = pChild->ImplGetWinData();
if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
2000-09-18 16:07:07 +00:00
{
pChild->ImplGetWindowImpl()->mbExtTextInput = TRUE;
2000-11-06 19:38:47 +00:00
if ( !pWinData->mpExtOldText )
pWinData->mpExtOldText = new UniString;
else
pWinData->mpExtOldText->Erase();
if ( pWinData->mpExtOldAttrAry )
{
delete [] pWinData->mpExtOldAttrAry;
2000-11-06 19:38:47 +00:00
pWinData->mpExtOldAttrAry = NULL;
}
pSVData->maWinData.mpExtTextInputWin = pChild;
2000-11-06 19:38:47 +00:00
ImplCallCommand( pChild, COMMAND_STARTEXTTEXTINPUT );
2000-09-18 16:07:07 +00:00
}
2000-11-03 08:04:36 +00:00
// be aware of being recursively called in StartExtTextInput
if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
return 0;
2000-11-06 19:38:47 +00:00
// Test for changes
BOOL bOnlyCursor = FALSE;
xub_StrLen nMinLen = Min( pWinData->mpExtOldText->Len(), rText.Len() );
xub_StrLen nDeltaStart = 0;
while ( nDeltaStart < nMinLen )
{
if ( pWinData->mpExtOldText->GetChar( nDeltaStart ) != rText.GetChar( nDeltaStart ) )
break;
nDeltaStart++;
}
if ( pWinData->mpExtOldAttrAry || pTextAttr )
{
if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
nDeltaStart = 0;
else
{
xub_StrLen i = 0;
while ( i < nDeltaStart )
{
if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
{
nDeltaStart = i;
break;
}
i++;
}
}
}
if ( (nDeltaStart >= nMinLen) &&
(pWinData->mpExtOldText->Len() == rText.Len()) )
bOnlyCursor = TRUE;
// Call Event and store the information
2000-11-03 08:04:36 +00:00
CommandExtTextInputData aData( rText, pTextAttr,
2000-11-06 19:38:47 +00:00
(xub_StrLen)nCursorPos, nCursorFlags,
nDeltaStart, pWinData->mpExtOldText->Len(),
2000-11-03 08:04:36 +00:00
bOnlyCursor );
2000-11-06 19:38:47 +00:00
*pWinData->mpExtOldText = rText;
if ( pWinData->mpExtOldAttrAry )
{
delete [] pWinData->mpExtOldAttrAry;
2000-11-06 19:38:47 +00:00
pWinData->mpExtOldAttrAry = NULL;
}
if ( pTextAttr )
{
pWinData->mpExtOldAttrAry = new USHORT[rText.Len()];
memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.Len()*sizeof( USHORT ) );
}
return !ImplCallCommand( pChild, COMMAND_EXTTEXTINPUT, &aData );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
static long ImplHandleEndExtTextInput( Window* /* pWindow */ )
2000-09-18 16:07:07 +00:00
{
ImplSVData* pSVData = ImplGetSVData();
Window* pChild = pSVData->maWinData.mpExtTextInputWin;
long nRet = 0;
2000-11-03 08:04:36 +00:00
2000-09-18 16:07:07 +00:00
if ( pChild )
{
pChild->ImplGetWindowImpl()->mbExtTextInput = FALSE;
pSVData->maWinData.mpExtTextInputWin = NULL;
2000-11-06 19:38:47 +00:00
ImplWinData* pWinData = pChild->ImplGetWinData();
if ( pWinData->mpExtOldText )
{
delete pWinData->mpExtOldText;
pWinData->mpExtOldText = NULL;
}
if ( pWinData->mpExtOldAttrAry )
{
delete [] pWinData->mpExtOldAttrAry;
2000-11-06 19:38:47 +00:00
pWinData->mpExtOldAttrAry = NULL;
}
nRet = !ImplCallCommand( pChild, COMMAND_ENDEXTTEXTINPUT );
2000-09-18 16:07:07 +00:00
}
2000-11-03 08:04:36 +00:00
2000-09-18 16:07:07 +00:00
return nRet;
}
// -----------------------------------------------------------------------
2000-11-03 08:04:36 +00:00
static void ImplHandleExtTextInputPos( Window* pWindow,
Rectangle& rRect, long& rInputWidth,
bool * pVertical )
2000-09-18 16:07:07 +00:00
{
ImplSVData* pSVData = ImplGetSVData();
Window* pChild = pSVData->maWinData.mpExtTextInputWin;
2000-11-03 08:04:36 +00:00
if ( !pChild )
pChild = ImplGetKeyInputWindow( pWindow );
else
{
// Test, if the Window is related to the frame
if ( !pWindow->ImplIsWindowOrChild( pChild ) )
pChild = ImplGetKeyInputWindow( pWindow );
}
2000-11-03 08:04:36 +00:00
2000-09-18 16:07:07 +00:00
if ( pChild )
{
2000-11-06 19:38:47 +00:00
ImplCallCommand( pChild, COMMAND_CURSORPOS );
2000-11-03 08:04:36 +00:00
const Rectangle* pRect = pChild->GetCursorRect();
if ( pRect )
rRect = pChild->ImplLogicToDevicePixel( *pRect );
else
2000-09-18 16:07:07 +00:00
{
2000-11-03 08:04:36 +00:00
Cursor* pCursor = pChild->GetCursor();
if ( pCursor )
2000-09-18 16:07:07 +00:00
{
2000-11-03 08:04:36 +00:00
Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
if ( !aSize.Width() )
aSize.Width() = pChild->GetSettings().GetStyleSettings().GetCursorSize();
rRect = Rectangle( aPos, aSize );
2000-09-18 16:07:07 +00:00
}
else
rRect = Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
2000-09-18 16:07:07 +00:00
}
2000-11-03 08:04:36 +00:00
rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
if ( !rInputWidth )
rInputWidth = rRect.GetWidth();
2000-09-18 16:07:07 +00:00
}
if (pVertical != 0)
*pVertical
= pChild != 0 && pChild->GetInputContext().GetFont().IsVertical();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2000-11-03 08:04:36 +00:00
static long ImplHandleInputContextChange( Window* pWindow, LanguageType eNewLang )
2000-09-18 16:07:07 +00:00
{
2000-11-06 19:38:47 +00:00
Window* pChild = ImplGetKeyInputWindow( pWindow );
CommandInputContextData aData( eNewLang );
return !ImplCallCommand( pChild, COMMAND_INPUTCONTEXTCHANGE, &aData );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
static BOOL ImplCallWheelCommand( Window* pWindow, const Point& rPos,
const CommandWheelData* pWheelData )
{
Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
CommandEvent aCEvt( aCmdMousePos, COMMAND_WHEEL, TRUE, pWheelData );
NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
ImplDelData aDelData( pWindow );
BOOL bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
if ( aDelData.IsDelete() )
return FALSE;
if ( !bPreNotify )
2000-09-18 16:07:07 +00:00
{
pWindow->ImplGetWindowImpl()->mbCommand = FALSE;
2000-09-18 16:07:07 +00:00
pWindow->Command( aCEvt );
if ( aDelData.IsDelete() )
return FALSE;
if ( pWindow->ImplGetWindowImpl()->mbCommand )
return TRUE;
2000-09-18 16:07:07 +00:00
}
return FALSE;
}
// -----------------------------------------------------------------------
static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEvt )
2000-09-18 16:07:07 +00:00
{
ImplDelData aDogTag( pWindow );
2000-09-18 16:07:07 +00:00
ImplSVData* pSVData = ImplGetSVData();
if ( pSVData->maWinData.mpAutoScrollWin )
pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
2000-09-18 16:07:07 +00:00
if ( pSVData->maHelpData.mpHelpWin )
ImplDestroyHelpWindow();
if( aDogTag.IsDelete() )
return 0;
2000-09-18 16:07:07 +00:00
USHORT nMode;
USHORT nCode = rEvt.mnCode;
2000-09-18 16:07:07 +00:00
if ( nCode & KEY_MOD1 )
nMode = COMMAND_WHEEL_ZOOM;
else if ( nCode & KEY_SHIFT )
nMode = COMMAND_WHEEL_DATAZOOM;
else
nMode = COMMAND_WHEEL_SCROLL;
CommandWheelData aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, rEvt.mbHorz );
Point aMousePos( rEvt.mnX, rEvt.mnY );
2000-09-18 16:07:07 +00:00
BOOL bRet = TRUE;
// first check any floating window ( eg. drop down listboxes)
Window *pMouseWindow = NULL;
if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
!pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pWindow ) )
{
USHORT nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
pMouseWindow = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pWindow, aMousePos, nHitTest );
}
// then try the window directly beneath the mouse
if( !pMouseWindow )
pMouseWindow = pWindow->ImplFindWindow( aMousePos );
else
// transform coordinates to float window frame coordinates
pMouseWindow = pMouseWindow->ImplFindWindow(
pMouseWindow->OutputToScreenPixel(
pMouseWindow->AbsoluteScreenToOutputPixel(
pWindow->OutputToAbsoluteScreenPixel(
pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
2000-09-18 16:07:07 +00:00
if ( pMouseWindow &&
pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() )
{
// transform coordinates to float window frame coordinates
Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
pMouseWindow->AbsoluteScreenToOutputPixel(
pWindow->OutputToAbsoluteScreenPixel(
pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
bRet = ImplCallWheelCommand( pMouseWindow, aRelMousePos, &aWheelData );
}
2000-09-18 16:07:07 +00:00
// if the commad was not handled try the focus window
2000-09-18 16:07:07 +00:00
if ( bRet )
{
Window* pFocusWindow = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
2000-09-18 16:07:07 +00:00
if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
(pFocusWindow == pSVData->maWinData.mpFocusWin) )
{
// no wheel-messages to disabled windows
if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() )
{
// transform coordinates to focus window frame coordinates
Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
pFocusWindow->AbsoluteScreenToOutputPixel(
pWindow->OutputToAbsoluteScreenPixel(
pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
bRet = ImplCallWheelCommand( pFocusWindow, aRelMousePos, &aWheelData );
}
2000-09-18 16:07:07 +00:00
}
}
return !bRet;
}
// -----------------------------------------------------------------------
2002-08-29 14:42:38 +00:00
#define IMPL_PAINT_CHECKRTL ((USHORT)0x0020)
2000-09-18 16:07:07 +00:00
static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect )
{
2002-08-29 14:42:38 +00:00
// give up background save when sytem paints arrive
Window* pSaveBackWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFirstBackWin;
2000-09-18 16:07:07 +00:00
while ( pSaveBackWin )
{
Window* pNext = pSaveBackWin->ImplGetWindowImpl()->mpOverlapData->mpNextBackWin;
Rectangle aRect( Point( pSaveBackWin->GetOutOffXPixel(), pSaveBackWin->GetOutOffYPixel() ),
Size( pSaveBackWin->GetOutputWidthPixel(), pSaveBackWin->GetOutputHeightPixel() ) );
2000-09-18 16:07:07 +00:00
if ( aRect.IsOver( rBoundRect ) )
pSaveBackWin->ImplDeleteOverlapBackground();
pSaveBackWin = pNext;
}
2002-08-29 14:42:38 +00:00
// system paint events must be checked for re-mirroring
pWindow->ImplGetWindowImpl()->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
2002-08-29 14:42:38 +00:00
// trigger paint for all windows that live in the new paint region
2000-09-18 16:07:07 +00:00
Region aRegion( rBoundRect );
pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
}
// -----------------------------------------------------------------------
2002-03-21 17:35:44 +00:00
static void KillOwnPopups( Window* pWindow )
2001-10-31 18:36:53 +00:00
{
ImplSVData* pSVData = ImplGetSVData();
Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
Window *pChild = pSVData->maWinData.mpFirstFloat;
if ( pChild && pParent->ImplIsWindowOrChild( pChild, TRUE ) )
2001-10-31 18:36:53 +00:00
{
if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
}
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
{
if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
2002-10-14 12:20:36 +00:00
{
KillOwnPopups( pWindow );
2002-10-14 12:20:36 +00:00
if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
ImplDestroyHelpWindow();
}
2001-10-31 18:36:53 +00:00
2000-09-18 16:07:07 +00:00
if ( (nNewWidth > 0) && (nNewHeight > 0) ||
pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize )
2000-09-18 16:07:07 +00:00
{
if ( (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel()) )
2000-09-18 16:07:07 +00:00
{
pWindow->mnOutWidth = nNewWidth;
pWindow->mnOutHeight = nNewHeight;
pWindow->ImplGetWindowImpl()->mbWaitSystemResize = FALSE;
2000-09-18 16:07:07 +00:00
if ( pWindow->IsReallyVisible() )
pWindow->ImplSetClipFlag();
if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
{
bool bStartTimer = true;
// use resize buffering for user resizes
// ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
&& !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
&& !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
{
if( pWindow->ImplGetWindowImpl()->mpClientWindow )
{
// #i42750# presentation wants to be informed about resize
// as early as possible
WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow);
if( pWorkWindow && pWorkWindow->IsPresentationMode() )
bStartTimer = false;
}
}
else
bStartTimer = false;
if( bStartTimer )
pWindow->ImplGetWindowImpl()->mpFrameData->maResizeTimer.Start();
else
pWindow->ImplCallResize(); // otherwise menues cannot be positioned
}
2000-09-18 16:07:07 +00:00
else
pWindow->ImplGetWindowImpl()->mbCallResize = TRUE;
2000-09-18 16:07:07 +00:00
}
}
pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
2000-09-18 16:07:07 +00:00
(nNewHeight < IMPL_MIN_NEEDSYSWIN);
BOOL bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
static void ImplHandleMove( Window* pWindow )
2001-10-24 07:57:18 +00:00
{
if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
{
static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
pWindow->ImplCallMove();
}
if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
2002-10-14 12:20:36 +00:00
{
KillOwnPopups( pWindow );
2002-10-14 12:20:36 +00:00
if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
ImplDestroyHelpWindow();
}
2001-11-23 11:39:27 +00:00
if ( pWindow->IsVisible() )
pWindow->ImplCallMove();
else
pWindow->ImplGetWindowImpl()->mbCallMove = TRUE; // make sure the framepos will be updated on the next Show()
if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
2001-11-23 11:39:27 +00:00
2001-10-24 07:57:18 +00:00
}
// -----------------------------------------------------------------------
static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight )
2001-10-24 07:57:18 +00:00
{
ImplHandleMove( pWindow );
2001-10-24 07:57:18 +00:00
ImplHandleResize( pWindow, nNewWidth, nNewHeight );
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
static void ImplActivateFloatingWindows( Window* pWindow, BOOL bActive )
{
// Zuerst alle ueberlappenden Fenster ueberpruefen
Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
2000-09-18 16:07:07 +00:00
while ( pTempWindow )
{
if ( !pTempWindow->GetActivateMode() )
{
if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
(pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
}
ImplActivateFloatingWindows( pTempWindow, bActive );
pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
2000-09-18 16:07:07 +00:00
}
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
IMPL_LINK( Window, ImplAsyncFocusHdl, void*, EMPTYARG )
{
ImplGetWindowImpl()->mpFrameData->mnFocusId = 0;
2000-09-18 16:07:07 +00:00
// Wenn Status erhalten geblieben ist, weil wir den Focus in der
// zwischenzeit schon wiederbekommen haben, brauchen wir auch
// nichts machen
BOOL bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
2000-09-18 16:07:07 +00:00
// Dann die zeitverzoegerten Funktionen ausfuehren
if ( bHasFocus )
{
// Alle FloatingFenster deaktiv zeichnen
if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
2000-09-18 16:07:07 +00:00
ImplActivateFloatingWindows( this, bHasFocus );
if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
2000-09-18 16:07:07 +00:00
{
BOOL bHandled = FALSE;
if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() )
{
if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
{
ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
bHandled = TRUE;
}
else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
{
// #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
// try to move it to the next control
ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
bHandled = TRUE;
}
}
if ( !bHandled )
{
ImplSVData* pSVData = ImplGetSVData();
Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
if ( !pTopLevelWindow->IsInputEnabled() && pSVData->maWinData.mpLastExecuteDlg )
pSVData->maWinData.mpLastExecuteDlg->ToTop( TOTOP_RESTOREWHENMIN | TOTOP_GRABFOCUSONLY);
else
pTopLevelWindow->GrabFocus();
}
2000-09-18 16:07:07 +00:00
}
else
GrabFocus();
}
else
{
Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
2000-09-18 16:07:07 +00:00
if ( pFocusWin )
{
ImplSVData* pSVData = ImplGetSVData();
if ( pSVData->maWinData.mpFocusWin == pFocusWin )
{
// FocusWindow umsetzen
Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
2000-09-18 16:07:07 +00:00
pSVData->maWinData.mpFocusWin = NULL;
if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
2000-09-18 16:07:07 +00:00
// Deaktivate rufen
Window* pOldFocusWindow = pFocusWin;
if ( pOldFocusWindow )
{
Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
pOldOverlapWindow->ImplGetWindowImpl()->mbActive = FALSE;
2000-09-18 16:07:07 +00:00
pOldOverlapWindow->Deactivate();
if ( pOldRealWindow != pOldOverlapWindow )
{
pOldRealWindow->ImplGetWindowImpl()->mbActive = FALSE;
2000-09-18 16:07:07 +00:00
pOldRealWindow->Deactivate();
}
}
// TrackingMode is ended in ImplHandleLoseFocus
2000-11-03 08:04:36 +00:00
// To avoid problems with the Unix IME
// pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
// XXX #102010# hack for accessibility: do not close the menu,
// even after focus lost
static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE");
if( !(pEnv && *pEnv) )
{
NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
if ( !ImplCallPreNotify( aNEvt ) )
pFocusWin->LoseFocus();
pFocusWin->ImplCallDeactivateListeners( NULL );
GetpApp()->FocusChanged();
}
// XXX
2000-09-18 16:07:07 +00:00
}
}
// Alle FloatingFenster deaktiv zeichnen
if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
2000-09-18 16:07:07 +00:00
ImplActivateFloatingWindows( this, bHasFocus );
}
return 0;
}
// -----------------------------------------------------------------------
static void ImplHandleGetFocus( Window* pWindow )
{
pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = TRUE;
2000-09-18 16:07:07 +00:00
// Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
// nicht alles flackert, wenn diese den Focus bekommen
if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
2000-09-18 16:07:07 +00:00
{
pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
static void ImplHandleLoseFocus( Window* pWindow )
{
ImplSVData* pSVData = ImplGetSVData();
// Wenn Frame den Focus verliert, brechen wir auch ein AutoScroll ab
if ( pSVData->maWinData.mpAutoScrollWin )
pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
// Wenn Frame den Focus verliert, brechen wir auch ein Tracking ab
if ( pSVData->maWinData.mpTrackWin )
{
if ( pSVData->maWinData.mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow )
2000-09-18 16:07:07 +00:00
pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
}
// handle FloatingMode
// hier beenden wir immer den PopupModus, auch dann, wenn NOFOCUSCLOSE
// gesetzt ist, damit wir nicht beim Wechsel noch Fenster stehen lassen
if ( pSVData->maWinData.mpFirstFloat )
{
if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
}
pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = FALSE;
2000-09-18 16:07:07 +00:00
// Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
// nicht alles flackert, wenn diese den Focus bekommen
if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
2000-09-18 16:07:07 +00:00
{
pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
2000-09-18 16:07:07 +00:00
}
Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
struct DelayedCloseEvent
{
Window* pWindow;
ImplDelData aDelData;
};
static long DelayedCloseEventLink( void* pCEvent, void* )
{
DelayedCloseEvent* pEv = (DelayedCloseEvent*)pCEvent;
if( ! pEv->aDelData.IsDelete() )
{
pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
// dispatch to correct window type
if( pEv->pWindow->IsSystemWindow() )
((SystemWindow*)pEv->pWindow)->Close();
else if( pEv->pWindow->ImplIsDockingWindow() )
((DockingWindow*)pEv->pWindow)->Close();
}
delete pEv;
return 0;
}
2000-09-18 16:07:07 +00:00
void ImplHandleClose( Window* pWindow )
{
ImplSVData* pSVData = ImplGetSVData();
2002-03-21 17:35:44 +00:00
bool bWasPopup = false;
if( pWindow->ImplIsFloatingWindow() &&
static_cast<FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
2002-03-21 17:35:44 +00:00
{
bWasPopup = true;
}
// on Close stop all floating modes and end popups
2000-09-18 16:07:07 +00:00
if ( pSVData->maWinData.mpFirstFloat )
{
FloatingWindow* pLastLevelFloat;
pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
}
if ( pSVData->maHelpData.mbExtHelpMode )
Help::EndExtHelp();
if ( pSVData->maHelpData.mpHelpWin )
ImplDestroyHelpWindow();
// AutoScrollMode
if ( pSVData->maWinData.mpAutoScrollWin )
pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
2001-07-06 15:07:09 +00:00
2000-09-18 16:07:07 +00:00
if ( pSVData->maWinData.mpTrackWin )
pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
2002-03-21 17:35:44 +00:00
if( ! bWasPopup )
{
Window *pWin = pWindow->ImplGetWindow();
// check whether close is allowed
if ( !pWin->IsEnabled() || !pWin->IsInputEnabled() )
Sound::Beep( SOUND_DISABLE, pWin );
else
{
DelayedCloseEvent* pEv = new DelayedCloseEvent;
pEv->pWindow = pWin;
pWin->ImplAddDel( &pEv->aDelData );
Application::PostUserEvent( Link( pEv, DelayedCloseEventLink ) );
}
2002-03-21 17:35:44 +00:00
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
{
if ( pSVEvent )
{
if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDelete() )
{
if ( pSVEvent->mpWindow )
{
pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
if ( pSVEvent->mpLink )
pSVEvent->mpLink->Call( pSVEvent->mpData );
else
pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
}
else
{
if ( pSVEvent->mpLink )
pSVEvent->mpLink->Call( pSVEvent->mpData );
else
GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
}
}
delete pSVEvent->mpLink;
delete pSVEvent;
}
}
// =======================================================================
static USHORT ImplGetMouseMoveMode( SalMouseEvent* pEvent )
{
USHORT nMode = 0;
if ( !pEvent->mnCode )
nMode |= MOUSE_SIMPLEMOVE;
if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
nMode |= MOUSE_DRAGMOVE;
if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
nMode |= MOUSE_DRAGCOPY;
return nMode;
}
// -----------------------------------------------------------------------
static USHORT ImplGetMouseButtonMode( SalMouseEvent* pEvent )
{
USHORT nMode = 0;
if ( pEvent->mnButton == MOUSE_LEFT )
nMode |= MOUSE_SIMPLECLICK;
if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
nMode |= MOUSE_SELECT;
if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
!(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
nMode |= MOUSE_MULTISELECT;
if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
!(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
nMode |= MOUSE_RANGESELECT;
return nMode;
}
// -----------------------------------------------------------------------
inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
{
return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, TRUE,
pEvent->mnX, pEvent->mnY,
pEvent->mnTime, pEvent->mnCode,
ImplGetMouseMoveMode( pEvent ) );
}
// -----------------------------------------------------------------------
inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
{
return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE,
pEvent->mnX, pEvent->mnY,
pEvent->mnTime, pEvent->mnCode,
ImplGetMouseMoveMode( pEvent ) );
}
// -----------------------------------------------------------------------
inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
{
return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, FALSE,
pEvent->mnX, pEvent->mnY,
pEvent->mnTime,
#ifdef MACOSX
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD5)),
#else
2000-09-18 16:07:07 +00:00
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
#endif
2000-09-18 16:07:07 +00:00
ImplGetMouseButtonMode( pEvent ) );
}
// -----------------------------------------------------------------------
inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
{
return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, FALSE,
pEvent->mnX, pEvent->mnY,
pEvent->mnTime,
#ifdef MACOSX
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD5)),
#else
2000-09-18 16:07:07 +00:00
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
#endif
2000-09-18 16:07:07 +00:00
ImplGetMouseButtonMode( pEvent ) );
}
// -----------------------------------------------------------------------
static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ )
2000-09-18 16:07:07 +00:00
{
return FALSE;
}
// -----------------------------------------------------------------------
static long ImplHandleMenuEvent( Window* pWindow, SalMenuEvent* pEvent, USHORT nEvent )
{
// Find SystemWindow and its Menubar and let it dispatch the command
long nRet = 0;
Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
while ( pWin )
{
if ( pWin->ImplGetWindowImpl()->mbSysWin )
break;
pWin = pWin->ImplGetWindowImpl()->mpNext;
}
if( pWin )
{
MenuBar *pMenuBar = ((SystemWindow*) pWin)->GetMenuBar();
if( pMenuBar )
{
switch( nEvent )
{
case SALEVENT_MENUACTIVATE:
nRet = pMenuBar->HandleMenuActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
break;
case SALEVENT_MENUDEACTIVATE:
nRet = pMenuBar->HandleMenuDeActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
break;
case SALEVENT_MENUHIGHLIGHT:
nRet = pMenuBar->HandleMenuHighlightEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
break;
case SALEVENT_MENUCOMMAND:
nRet = pMenuBar->HandleMenuCommandEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
break;
default:
break;
}
}
}
return nRet;
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
{
ImplSVData* pSVData = ImplGetSVData();
Window* pTrackWin = pSVData->maWinData.mpTrackWin;
if ( pTrackWin )
pWindow = pTrackWin;
#ifdef MACOSX
USHORT nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD5);
#else
USHORT nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
#endif
2000-09-18 16:07:07 +00:00
USHORT nNewCode = pEvent->mnCode;
if ( nOldCode != nNewCode )
{
#ifdef MACOSX
nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD5);
#else
nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
#endif
pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, TRUE );
2000-09-18 16:07:07 +00:00
}
// #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
// find window
Window* pChild = ImplGetKeyInputWindow( pWindow );
if ( !pChild )
return;
// send modkey events only if useful data is available
if( pEvent->mnModKeyCode != 0 )
{
CommandModKeyData data( pEvent->mnModKeyCode );
ImplCallCommand( pChild, COMMAND_MODKEYCHANGE, &data );
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
static void ImplHandleInputLanguageChange( Window* pWindow )
{
// find window
Window* pChild = ImplGetKeyInputWindow( pWindow );
if ( !pChild )
return;
ImplCallCommand( pChild, COMMAND_INPUTLANGUAGECHANGE );
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
static void ImplHandleSalSettings( Window* pWindow, USHORT nEvent )
{
// Application Notification werden nur fuer das erste Window ausgeloest
ImplSVData* pSVData = ImplGetSVData();
if ( pWindow != pSVData->maWinData.mpFirstFrame )
2000-09-18 16:07:07 +00:00
return;
Application* pApp = GetpApp();
if ( !pApp )
return;
2000-09-18 16:07:07 +00:00
if ( nEvent == SALEVENT_SETTINGSCHANGED )
{
AllSettings aSettings = pApp->GetSettings();
pApp->MergeSystemSettings( aSettings );
pApp->SystemSettingsChanging( aSettings, pWindow );
2000-09-18 16:07:07 +00:00
pApp->SetSettings( aSettings );
}
else
{
USHORT nType;
switch ( nEvent )
{
case SALEVENT_VOLUMECHANGED:
nType = 0;
break;
case SALEVENT_PRINTERCHANGED:
ImplDeletePrnQueueList();
nType = DATACHANGED_PRINTER;
break;
case SALEVENT_DISPLAYCHANGED:
nType = DATACHANGED_DISPLAY;
break;
case SALEVENT_FONTCHANGED:
OutputDevice::ImplUpdateAllFontData( TRUE );
nType = DATACHANGED_FONTS;
break;
case SALEVENT_DATETIMECHANGED:
nType = DATACHANGED_DATETIME;
break;
case SALEVENT_KEYBOARDCHANGED:
nType = 0;
break;
default:
nType = 0;
break;
}
if ( nType )
{
DataChangedEvent aDCEvt( nType );
pApp->DataChanged( aDCEvt );
pApp->NotifyAllWindows( aDCEvt );
}
}
}
// -----------------------------------------------------------------------
static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
{
2000-11-03 08:04:36 +00:00
Rectangle aCursorRect;
ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
2000-11-03 08:04:36 +00:00
if ( aCursorRect.IsEmpty() )
2000-09-18 16:07:07 +00:00
{
2000-11-03 08:04:36 +00:00
pEvt->mnX = -1;
pEvt->mnY = -1;
pEvt->mnWidth = -1;
pEvt->mnHeight = -1;
}
else
{
pEvt->mnX = aCursorRect.Left();
pEvt->mnY = aCursorRect.Top();
pEvt->mnWidth = aCursorRect.GetWidth();
pEvt->mnHeight = aCursorRect.GetHeight();
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
long ImplWindowFrameProc( void* pInst, SalFrame* /*pFrame*/,
2000-09-18 16:07:07 +00:00
USHORT nEvent, const void* pEvent )
{
DBG_TESTSOLARMUTEX();
long nRet = 0;
Window* pWindow = reinterpret_cast<Window*>( pInst );
// #119709# for some unknown reason it is possible to receive events (in this case key events)
// although the corresponding VCL window must have been destroyed already
// at least ImplGetWindowImpl() was NULL in these cases, so check this here
if( pWindow->ImplGetWindowImpl() == NULL )
return 0;
2000-09-18 16:07:07 +00:00
switch ( nEvent )
{
case SALEVENT_MOUSEMOVE:
nRet = ImplHandleSalMouseMove( pWindow, (SalMouseEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_EXTERNALMOUSEMOVE:
{
MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
SalMouseEvent aSalMouseEvent;
aSalMouseEvent.mnTime = Time::GetSystemTicks();
aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
aSalMouseEvent.mnButton = 0;
aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
nRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
}
break;
2000-09-18 16:07:07 +00:00
case SALEVENT_MOUSELEAVE:
nRet = ImplHandleSalMouseLeave( pWindow, (SalMouseEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_MOUSEBUTTONDOWN:
nRet = ImplHandleSalMouseButtonDown( pWindow, (SalMouseEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_EXTERNALMOUSEBUTTONDOWN:
{
MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
SalMouseEvent aSalMouseEvent;
aSalMouseEvent.mnTime = Time::GetSystemTicks();
aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
nRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
}
break;
2000-09-18 16:07:07 +00:00
case SALEVENT_MOUSEBUTTONUP:
nRet = ImplHandleSalMouseButtonUp( pWindow, (SalMouseEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_EXTERNALMOUSEBUTTONUP:
{
MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
SalMouseEvent aSalMouseEvent;
aSalMouseEvent.mnTime = Time::GetSystemTicks();
aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
nRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
}
break;
2000-09-18 16:07:07 +00:00
case SALEVENT_MOUSEACTIVATE:
nRet = ImplHandleSalMouseActivate( pWindow, (SalMouseActivateEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_KEYINPUT:
{
SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, TRUE );
}
break;
case SALEVENT_EXTERNALKEYINPUT:
{
KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), FALSE );
2000-09-18 16:07:07 +00:00
}
break;
case SALEVENT_KEYUP:
{
SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, TRUE );
}
break;
case SALEVENT_EXTERNALKEYUP:
{
KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), FALSE );
2000-09-18 16:07:07 +00:00
}
break;
case SALEVENT_KEYMODCHANGE:
ImplHandleSalKeyMod( pWindow, (SalKeyModEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_INPUTLANGUAGECHANGE:
ImplHandleInputLanguageChange( pWindow );
break;
case SALEVENT_MENUACTIVATE:
case SALEVENT_MENUDEACTIVATE:
case SALEVENT_MENUHIGHLIGHT:
case SALEVENT_MENUCOMMAND:
nRet = ImplHandleMenuEvent( pWindow, (SalMenuEvent*)pEvent, nEvent );
break;
2000-09-18 16:07:07 +00:00
case SALEVENT_WHEELMOUSE:
nRet = ImplHandleWheelEvent( pWindow, *(const SalWheelMouseEvent*)pEvent);
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_PAINT:
{
SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
if( Application::GetSettings().GetLayoutRTL() )
{
// --- RTL --- (mirror paint rect)
Window* pWin = (Window*)pInst;
SalFrame* pSalFrame = pWin->ImplGetWindowImpl()->mpFrame;
pPaintEvt->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
}
2000-09-18 16:07:07 +00:00
Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
ImplHandlePaint( pWindow, aBoundRect );
2000-09-18 16:07:07 +00:00
}
break;
2001-10-24 07:57:18 +00:00
case SALEVENT_MOVE:
ImplHandleMove( pWindow );
2001-10-24 07:57:18 +00:00
break;
2000-09-18 16:07:07 +00:00
case SALEVENT_RESIZE:
{
long nNewWidth;
long nNewHeight;
pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
ImplHandleResize( pWindow, nNewWidth, nNewHeight );
2000-09-18 16:07:07 +00:00
}
break;
2001-10-24 07:57:18 +00:00
case SALEVENT_MOVERESIZE:
{
SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
2001-10-24 07:57:18 +00:00
}
break;
2002-03-21 17:35:44 +00:00
case SALEVENT_CLOSEPOPUPS:
{
KillOwnPopups( pWindow );
2002-03-21 17:35:44 +00:00
}
break;
2000-09-18 16:07:07 +00:00
case SALEVENT_GETFOCUS:
ImplHandleGetFocus( pWindow );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_LOSEFOCUS:
ImplHandleLoseFocus( pWindow );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_CLOSE:
ImplHandleClose( pWindow );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_SHUTDOWN:
{
2001-12-07 12:14:08 +00:00
static bool bInQueryExit = false;
if( !bInQueryExit )
2000-09-18 16:07:07 +00:00
{
2001-12-07 12:14:08 +00:00
bInQueryExit = true;
if ( GetpApp()->QueryExit() )
{
// Message-Schleife beenden
Application::Quit();
return FALSE;
}
else
{
bInQueryExit = false;
return TRUE;
}
2000-09-18 16:07:07 +00:00
}
return FALSE;
2000-09-18 16:07:07 +00:00
}
case SALEVENT_SETTINGSCHANGED:
case SALEVENT_VOLUMECHANGED:
case SALEVENT_PRINTERCHANGED:
case SALEVENT_DISPLAYCHANGED:
case SALEVENT_FONTCHANGED:
case SALEVENT_DATETIMECHANGED:
case SALEVENT_KEYBOARDCHANGED:
ImplHandleSalSettings( pWindow, nEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_USEREVENT:
ImplHandleUserEvent( (ImplSVEvent*)pEvent );
break;
case SALEVENT_EXTTEXTINPUT:
{
SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
nRet = ImplHandleExtTextInput( pWindow,
2000-11-03 08:04:36 +00:00
pEvt->maText, pEvt->mpTextAttr,
2000-11-06 19:38:47 +00:00
pEvt->mnCursorPos, pEvt->mnCursorFlags );
2000-09-18 16:07:07 +00:00
}
break;
case SALEVENT_ENDEXTTEXTINPUT:
nRet = ImplHandleEndExtTextInput( pWindow );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_EXTTEXTINPUTPOS:
ImplHandleSalExtTextInputPos( pWindow, (SalExtTextInputPosEvent*)pEvent );
2000-09-18 16:07:07 +00:00
break;
case SALEVENT_INPUTCONTEXTCHANGE:
nRet = ImplHandleInputContextChange( pWindow, ((SalInputContextChangeEvent*)pEvent)->meLanguage );
2000-09-18 16:07:07 +00:00
break;
#ifdef DBG_UTIL
default:
DBG_ERROR1( "ImplWindowFrameProc(): unknown event (%lu)", (ULONG)nEvent );
break;
#endif
}
return nRet;
}