diff options
Diffstat (limited to 'vcl/source/window/window.cxx')
-rw-r--r-- | vcl/source/window/window.cxx | 6539 |
1 files changed, 6539 insertions, 0 deletions
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx new file mode 100644 index 000000000000..af07c5df38c1 --- /dev/null +++ b/vcl/source/window/window.cxx @@ -0,0 +1,6539 @@ +/************************************************************************* + * + * $RCSfile: window.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * 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. + * + * 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. + * + * 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 + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#define _SV_WINDOW_CXX + +#ifndef REMOTE_APPSERVER +#ifndef _SV_SVSYS_HXX +#include <svsys.h> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _SV_SALOBJ_HXX +#include <salobj.hxx> +#endif +#ifndef _SV_SALINST_HXX +#include <salinst.hxx> +#endif +#ifndef _SV_SALGTYPE_HXX +#include <salgtype.hxx> +#endif +#ifndef _SV_SALGDI_HXX +#include <salgdi.hxx> +#endif +#endif + +#ifndef _DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef _SV_RC_H +#include <rc.h> +#endif +#ifndef _SV_SVDATA_HXX +#include <svdata.hxx> +#endif +#ifndef _SV_WINDATA_HXX +#include <windata.hxx> +#endif +#ifndef _SV_DBGGUI_HXX +#include <dbggui.hxx> +#endif +#ifndef _SV_ACCESS_HXX +#include <access.hxx> +#endif +#ifndef _SV_OUTFONT_HXX +#include <outfont.hxx> +#endif +#ifndef _SV_OUTDEV_H +#include <outdev.h> +#endif +#ifndef _SV_REGION_H +#include <region.h> +#endif +#ifndef _SV_EVENT_HXX +#include <event.hxx> +#endif +#ifndef _SV_HELP_HXX +#include <help.hxx> +#endif +#ifndef _SV_CURSOR_HXX +#include <cursor.hxx> +#endif +#ifndef _SV_SVAPP_HXX +#include <svapp.hxx> +#endif +#ifndef _SV_WINDOW_H +#include <window.h> +#endif +#ifndef _SV_WINDOW_HXX +#include <window.hxx> +#endif +#ifndef _SV_SYSWIN_HXX +#include <syswin.hxx> +#endif +#ifndef _SV_BRDWIN_HXX +#include <brdwin.hxx> +#endif +#ifndef _SV_HELPWIN_HXX +#include <helpwin.hxx> +#endif +#ifndef _SV_MENU_HXX +#include <menu.hxx> +#endif +#ifndef _SV_DRAG_HXX +#include <drag.hxx> +#endif + +#define SYSDATA_ONLY_BASETYPE +#include <sysdata.hxx> + +#include <com/sun/star/awt/XWindowPeer.hpp> + +#ifdef REMOTE_APPSERVER +#include "rmwindow.hxx" +#include "xevthdl.hxx" +#include "rmevents.hxx" +#include "rmoutdev.hxx" +#endif + +#include <unowrap.hxx> + +#pragma hdrstop + +// ======================================================================= + +DBG_NAME( Window ); + +// ======================================================================= + +#define IMPL_PAINT_PAINT ((USHORT)0x0001) +#define IMPL_PAINT_PAINTALL ((USHORT)0x0002) +#define IMPL_PAINT_PAINTALLCHILDS ((USHORT)0x0004) +#define IMPL_PAINT_PAINTCHILDS ((USHORT)0x0008) +#define IMPL_PAINT_ERASE ((USHORT)0x0010) + +// ----------------------------------------------------------------------- + +typedef Window* PWINDOW; + +// ----------------------------------------------------------------------- + +struct ImplCalcToTopData +{ + ImplCalcToTopData* mpNext; + Window* mpWindow; + Region* mpInvalidateRegion; +}; + +// ----------------------------------------------------------------------- + +#ifdef DBG_UTIL +const char* ImplDbgCheckWindow( const void* pObj ) +{ + DBG_TESTSOLARMUTEX(); + + const Window* pWindow = (Window*)pObj; + + if ( (pWindow->GetType() < WINDOW_FIRST) || (pWindow->GetType() > WINDOW_LAST) ) + return "Window data overwrite"; + + // Fenster-Verkettung ueberpruefen + Window* pChild = pWindow->mpFirstChild; + while ( pChild ) + { + if ( pChild->mpParent != pWindow ) + return "Child-Window-Parent wrong"; + pChild = pChild->mpNext; + } + + return NULL; +} +#endif + +// ======================================================================= + +static void ImplInitAppFontData( Window* pWindow ) +{ + ImplSVData* pSVData = ImplGetSVData(); + long nTextHeight = pWindow->GetTextHeight(); + long nTextWidth = pWindow->GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "aemnnxEM" ) ) ); + long nSymHeight = nTextHeight*4; + // Falls Font zu schmal ist, machen wir die Basis breiter, + // damit die Dialoge symetrisch aussehen und nicht zu schmal + // werden. Wenn der Dialog die gleiche breite hat, geben wir + // noch etwas Spielraum dazu, da etwas mehr Platz besser ist. + if ( nSymHeight > nTextWidth ) + nTextWidth = nSymHeight; + else if ( nSymHeight+5 > nTextWidth ) + nTextWidth = nSymHeight+5; + pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8; + pSVData->maGDIData.mnAppFontY = nTextHeight * 10; + + pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX; + if ( pSVData->maAppData.mnDialogScaleX ) + pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100; +} + +// ----------------------------------------------------------------------- + +MouseEvent ImplTranslateMouseEvent( const MouseEvent& rE, Window* pSource, Window* pDest ) +{ + Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() ); + aPos = pDest->ScreenToOutputPixel( aPos ); + return MouseEvent( aPos, rE.GetClicks(), rE.GetMode(), rE.GetButtons(), rE.GetModifier() ); +} + +// ======================================================================= + +void Window::ImplInitData( WindowType nType ) +{ + meOutDevType = OUTDEV_WINDOW; + + mpWinData = NULL; // Extra Window Data, that we dont need for all windows + mpOverlapData = NULL; // Overlap Data + mpFrameData = NULL; // Frame Data + mpFrame = NULL; // Pointer to frame window + mpSysObj = NULL; + mpFrameWindow = NULL; // window to top level parent (same as frame window) + mpOverlapWindow = NULL; // first overlap parent + mpBorderWindow = NULL; // Border-Window + mpClientWindow = NULL; // Client-Window of a FrameWindow + mpParent = NULL; // parent (inkl. BorderWindow) + mpRealParent = NULL; // real parent (exkl. BorderWindow) + mpFirstChild = NULL; // first child window + mpLastChild = NULL; // last child window + mpFirstOverlap = NULL; // first overlap window (only set in overlap windows) + mpLastOverlap = NULL; // last overlap window (only set in overlap windows) + mpPrev = NULL; // prev window + mpNext = NULL; // next window + mpNextOverlap = NULL; // next overlap window of frame + mpLastFocusWindow = NULL; // window for focus restore + mpDlgCtrlDownWindow = NULL; // window for dialog control + mpFirstDel = NULL; // Dtor notification list + mpUserData = NULL; // user data + mpCursor = NULL; // cursor + mpControlFont = NULL; // font propertie + mpVCLXWindow = NULL; + maControlForeground = Color( COL_TRANSPARENT ); // kein Foreground gesetzt + maControlBackground = Color( COL_TRANSPARENT ); // kein Background gesetzt + mnLeftBorder = 0; // left border + mnTopBorder = 0; // top border + mnRightBorder = 0; // right border + mnBottomBorder = 0; // bottom border + mnX = 0; // X-Position to Parent + mnY = 0; // Y-Position to Parent + mnHelpId = 0; // help id + mnUniqId = 0; // unique id + mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren + mpPaintRegion = NULL; // Paint-ClipRegion + mnStyle = 0; // style (init in ImplInitWindow) + mnPrevStyle = 0; // prevstyle (set in SetStyle) + mnExtendedStyle = 0; // extended style (init in ImplInitWindow) + mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle) + mnType = nType; // type + mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf + mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer) + mnPaintFlags = 0; // Flags for ImplCallPaint + mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode + mnActivateMode = 0; // Wird bei System/Overlap-Windows umgesetzt + mnDlgCtrlFlags = 0; // DialogControl-Flags + mbFrame = FALSE; // TRUE: Window is a frame window + mbBorderWin = FALSE; // TRUE: Window is a border window + mbOverlapWin = FALSE; // TRUE: Window is a overlap window + mbSysWin = FALSE; // TRUE: SystemWindow is the base class + mbDialog = FALSE; // TRUE: Dialog is the base class + mbDockWin = FALSE; // TRUE: DockingWindow is the base class + mbFloatWin = FALSE; // TRUE: FloatingWindow is the base class + mbPushButton = FALSE; // TRUE: PushButton is the base class + mbVisible = FALSE; // TRUE: Show( TRUE ) called + mbOverlapVisible = FALSE; // TRUE: Hide called for visible window from ImplHideAllOverlapWindow() + mbDisabled = FALSE; // TRUE: Enable( FALSE ) called + mbInputDisabled = FALSE; // TRUE: EnableInput( FALSE ) called + mbAlwaysEnableInput = FALSE; // TRUE: AlwaysEnableInput( TRUE ) called + mbDropDisabled = FALSE; // TRUE: Drop is enabled + mbNoUpdate = FALSE; // TRUE: SetUpdateMode( FALSE ) called + mbNoParentUpdate = FALSE; // TRUE: SetParentUpdateMode( FALSE ) called + mbActive = FALSE; // TRUE: Window Active + mbParentActive = FALSE; // TRUE: OverlapActive from Parent + mbReallyVisible = FALSE; // TRUE: this and all parents to an overlaped window are visible + mbReallyShown = FALSE; // TRUE: this and all parents to an overlaped window are shown + mbInInitShow = FALSE; // TRUE: we are in InitShow + mbChildNotify = FALSE; // TRUE: ChildNotify + mbChildPtrOverwrite = FALSE; // TRUE: PointerStyle overwrites Child-Pointer + mbNoPtrVisible = FALSE; // TRUE: ShowPointer( FALSE ) called + mbMouseMove = FALSE; // TRUE: BaseMouseMove called + mbPaintFrame = FALSE; // TRUE: Paint is visible, but not painted + mbInPaint = FALSE; // TRUE: Inside PaintHdl + mbMouseButtonDown = FALSE; // TRUE: BaseMouseButtonDown called + mbMouseButtonUp = FALSE; // TRUE: BaseMouseButtonUp called + mbKeyInput = FALSE; // TRUE: BaseKeyInput called + mbKeyUp = FALSE; // TRUE: BaseKeyUp called + mbCommand = FALSE; // TRUE: BaseCommand called + mbDefPos = TRUE; // TRUE: Position is not Set + mbDefSize = TRUE; // TRUE: Size is not Set + mbCallMove = TRUE; // TRUE: Move must be called by Show + mbCallResize = TRUE; // TRUE: Resize must be called by Show + mbWaitSystemResize = TRUE; // TRUE: Wait for System-Resize + mbInitWinClipRegion = TRUE; // TRUE: Calc Window Clip Region + mbInitChildRegion = FALSE; // TRUE: InitChildClipRegion + mbWinRegion = FALSE; // TRUE: Window Region + mbClipChildren = FALSE; // TRUE: Child-Fenster muessen evt. geclippt werden + mbClipSiblings = FALSE; // TRUE: Nebeneinanderliegende Child-Fenster muessen evt. geclippt werden + mbChildTransparent = FALSE; // TRUE: Child-Fenster duerfen transparent einschalten (inkl. Parent-CLIPCHILDREN) + mbPaintTransparent = FALSE; // TRUE: Paints muessen auf Parent ausgeloest werden + mbMouseTransparent = FALSE; // TRUE: Window is transparent for Mouse + mbDlgCtrlStart = FALSE; // TRUE: Ab hier eigenes Dialog-Control + mbFocusVisible = FALSE; // TRUE: Focus Visible + mbTrackVisible = FALSE; // TRUE: Tracking Visible + mbControlForeground = FALSE; // TRUE: Foreground-Property set + mbControlBackground = FALSE; // TRUE: Background-Property set + mbAlwaysOnTop = FALSE; // TRUE: immer vor allen anderen normalen Fenstern sichtbar + mbCompoundControl = FALSE; // TRUE: Zusammengesetztes Control => Listener... + mbCompoundControlHasFocus = FALSE; // TRUE: Zusammengesetztes Control hat irgendwo den Focus + mbPaintDisabled = FALSE; // TRUE: Paint soll nicht ausgefuehrt werden + mbAllResize = FALSE; // TRUE: Auch ResizeEvents mit 0,0 schicken + mbInDtor = FALSE; // TRUE: Wir befinden uns im Window-Dtor + mbExtTextInput = FALSE; // TRUE: ExtTextInput-Mode is active + mbInFocusHdl = FALSE; // TRUE: Innerhalb vom GetFocus-Handler + mbCreatedWithToolkit = FALSE; + +#ifdef REMOTE_APPSERVER + mpRmEvents = NULL; + + Font aFont = maInputContext.GetFont(); + aFont.SetCharSet( gsl_getSystemTextEncoding() ); + maInputContext.SetFont( aFont ); +#endif +} + +// ----------------------------------------------------------------------- + +#ifdef REMOTE_APPSERVER +void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData ) +{ + static ::com::sun::star::uno::Any aVoid; + ImplInit( pParent, nStyle, aVoid ); +} +#else +void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& aSystemWorkWindowToken ) +{ + ImplInit( pParent, nStyle, NULL ); +} +#endif + +// ----------------------------------------------------------------------- + +#ifndef REMOTE_APPSERVER +void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData ) +#else +void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& aSystemWorkWindowToken ) +#endif +{ + DBG_ASSERT( mbFrame || pParent, "Window::Window(): pParent == NULL" ); + + ImplSVData* pSVData = ImplGetSVData(); + Window* pRealParent = pParent; + + // 3D-Look vererben + if ( !mbOverlapWin && (pParent->GetStyle() & WB_3DLOOK) ) + nStyle |= WB_3DLOOK; + + // Wenn wir einen Border haben, muessen wir ein BorderWindow anlegen + if ( !mbFrame && !mbBorderWin && !mpBorderWindow && (nStyle & WB_BORDER) ) + { + ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL) ); + ((Window*)pBorderWin)->mpClientWindow = this; + pBorderWin->GetBorder( mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder ); + mpBorderWindow = pBorderWin; + pParent = mpBorderWindow; + } + + // insert window in list + ImplInsertWindow( pParent ); + mnStyle = nStyle; + + // Overlap-Window-Daten + if ( mbOverlapWin ) + { + mpOverlapData = new ImplOverlapData; + mpOverlapData->mpSaveBackDev = NULL; + mpOverlapData->mpSaveBackRgn = NULL; + mpOverlapData->mpNextBackWin = NULL; + mpOverlapData->mnSaveBackSize = 0; + mpOverlapData->mbSaveBack = FALSE; + mpOverlapData->mnTopLevel = 1; + } + + // test for frame creation + if ( mbFrame ) + { + // create frame +#ifndef REMOTE_APPSERVER + ULONG nFrameStyle = 0; + + if ( nStyle & WB_MOVEABLE ) + nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE; + if ( nStyle & WB_SIZEABLE ) + { + nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE | + SAL_FRAME_STYLE_MINABLE | + SAL_FRAME_STYLE_MAXABLE; + } + if ( nStyle & WB_CLOSEABLE ) + nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE; + if ( nStyle & WB_APP ) + nFrameStyle |= SAL_FRAME_STYLE_DEFAULT; + + SalFrame* pParentFrame = NULL; + if ( pParent ) + pParentFrame = pParent->mpFrame; + SalFrame* pFrame; + if ( pSystemParentData ) + pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_CHILD ); + else + pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle ); + if ( !pFrame ) + GetpApp()->Exception( EXC_SYSOBJNOTCREATED ); + pFrame->SetCallback( this, ImplWindowFrameProc ); + + // initialize system-Drag&Drop-interface + DragManager::SystemEnableDrop( pFrame, TRUE ); +#else + RmFrameWindow* pParentFrame = pParent ? pParent->mpFrame : NULL;; + RmFrameWindow* pFrame = new RmFrameWindow( this ); + if ( !pFrame->IsValid() ) + { + delete pFrame, pFrame = NULL; + GetpApp()->Exception( EXC_SYSOBJNOTCREATED ); + } + else + { + pFrame->Create( nStyle, pFrame->GetEventHdlInterface(), + aSystemWorkWindowToken, + pParentFrame ? pParentFrame->GetFrameInterface() : REF( NMSP_CLIENT::XRmFrameWindow )() ); + } +#endif + + // set window frame data + mpFrameData = new ImplFrameData; + mpFrame = pFrame; + mpFrameWindow = this; + mpOverlapWindow = this; + + // set frame data + mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame; + pSVData->maWinData.mpFirstFrame = this; + mpFrameData->mpFirstOverlap = NULL; + mpFrameData->mpFocusWin = NULL; + mpFrameData->mpMouseMoveWin = NULL; + mpFrameData->mpMouseDownWin = NULL; + mpFrameData->mpFirstBackWin = NULL; + mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList; + mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache; + mpFrameData->mnAllSaveBackSize = 0; + mpFrameData->mnFocusId = 0; + mpFrameData->mnMouseMoveId = 0; + mpFrameData->mnLastMouseX = -1; + mpFrameData->mnLastMouseY = -1; + mpFrameData->mnFirstMouseX = -1; + mpFrameData->mnFirstMouseY = -1; + mpFrameData->mnLastMouseWinX = -1; + mpFrameData->mnLastMouseWinY = -1; + mpFrameData->mnMouseDownTime = 0; + mpFrameData->mnClickCount = 0; + mpFrameData->mnFirstMouseCode = 0; + mpFrameData->mnMouseCode = 0; + mpFrameData->mnMouseMode = 0; + mpFrameData->meMapUnit = MAP_PIXEL; + mpFrameData->mbHasFocus = FALSE; + mpFrameData->mbInMouseMove = FALSE; + mpFrameData->mbMouseIn = FALSE; + mpFrameData->mbStartDragCalled = FALSE; + mpFrameData->mbNeedSysWindow = FALSE; + mpFrameData->mbMinimized = FALSE; + mpFrameData->mbStartFocusState = FALSE; + mpFrameData->mbInSysObjFocusHdl = FALSE; + mpFrameData->mbInSysObjToTopHdl = FALSE; + mpFrameData->mbSysObjFocus = FALSE; + + mpFrameData->mpDragTimer = NULL; + mpFrameData->maPaintTimer.SetTimeout( 30 ); + mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) ); + +#ifndef REMOTE_APPSERVER + // Muessen Application-Settings noch upgedatet werden + if ( !pSVData->maAppData.mbSettingsInit ) + { + mpFrame->UpdateSettings( *pSVData->maAppData.mpSettings ); + GetpApp()->SystemSettingsChanging( *pSVData->maAppData.mpSettings, this ); +#ifdef DBG_UTIL + // Evt. AppFont auf Fett schalten, damit man feststellen kann, + // ob fuer die Texte auf anderen Systemen genuegend Platz + // vorhanden ist + if ( DbgIsBoldAppFont() ) + { + StyleSettings aStyleSettings = pSVData->maAppData.mpSettings->GetStyleSettings(); + Font aFont = aStyleSettings.GetAppFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetAppFont( aFont ); + aFont = aStyleSettings.GetGroupFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetGroupFont( aFont ); + aFont = aStyleSettings.GetLabelFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetLabelFont( aFont ); + aFont = aStyleSettings.GetRadioCheckFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetRadioCheckFont( aFont ); + aFont = aStyleSettings.GetPushButtonFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetPushButtonFont( aFont ); + aFont = aStyleSettings.GetFieldFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetFieldFont( aFont ); + aFont = aStyleSettings.GetIconFont(); + aFont.SetWeight( WEIGHT_BOLD ); + aStyleSettings.SetIconFont( aFont ); + pSVData->maAppData.mpSettings->SetStyleSettings( aStyleSettings ); + } +#endif + OutputDevice::SetSettings( *pSVData->maAppData.mpSettings ); + pSVData->maAppData.mbSettingsInit = TRUE; + } +#endif + } + + // init data + mpRealParent = pRealParent; + + if ( mbFrame ) + { +#ifndef REMOTE_APPSERVER + if ( pParent ) + { + mpFrameData->mnDPIX = pParent->mpFrameData->mnDPIX; + mpFrameData->mnDPIY = pParent->mpFrameData->mnDPIY; + mpFrameData->mnFontDPIX = pParent->mpFrameData->mnFontDPIX; + mpFrameData->mnFontDPIY = pParent->mpFrameData->mnFontDPIY; + } + else + { + if ( ImplGetGraphics() ) + { + mpGraphics->GetResolution( mpFrameData->mnDPIX, mpFrameData->mnDPIY ); + mpGraphics->GetScreenFontResolution( mpFrameData->mnFontDPIX, mpFrameData->mnFontDPIY ); + if ( !mpFrameData->mpFontList->Count() ) + { + mpGraphics->GetDevFontList( mpFrameData->mpFontList ); + mpFrameData->mpFontList->InitStdFonts(); + } + } + } +#else + const REF( NMSP_CLIENT::XRmFrameWindow )& rxWindow = mpFrame->GetFrameInterface(); + REF( NMSP_CLIENT::XRmOutputDevice ) xOutDev( mpFrame->GetOutdevInterface() ); + + if ( rxWindow.is() && xOutDev.is() ) + { + mpGraphics = new ImplServerGraphics; + mpGraphics->SetInterface( xOutDev ); + if ( pParent ) + { + mpFrameData->mnDPIX = pParent->mpFrameData->mnDPIX; + mpFrameData->mnDPIY = pParent->mpFrameData->mnDPIY; + mpFrameData->mnFontDPIX = pParent->mpFrameData->mnFontDPIX; + mpFrameData->mnFontDPIY = pParent->mpFrameData->mnFontDPIY; + } + else + { + // We currently assume, that we have only one display + static NMSP_CLIENT::RmFrameResolutions aResl = mpFrame->GetFrameResolutions(); + mpFrameData->mnDPIX = aResl.DPIx; + mpFrameData->mnDPIY = aResl.DPIy; + mpFrameData->mnFontDPIX = aResl.FontDPIx; + mpFrameData->mnFontDPIY = aResl.FontDPIy; + mpGraphics->SetWindowResolution( aResl.DPIx, aResl.DPIy, aResl.Depth ); + if ( !mpFrameData->mpFontList->Count() ) + { + mpGraphics->GetDevFontList( mpFrameData->mpFontList ); + mpFrameData->mpFontList->InitStdFonts(); + } + } + } +#endif + + // If we create a Window with default size, query this + // size directly, because we want resize all Controls to + // the correct size before we display the window + if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) ) + mpFrame->GetClientSize( mnOutWidth, mnOutHeight ); + } + else + { + if ( pParent ) + { + if ( !ImplIsOverlapWindow() ) + { + mbDisabled = pParent->mbDisabled; + mbInputDisabled = pParent->mbInputDisabled; + mbAlwaysEnableInput = pParent->mbAlwaysEnableInput; + } + + OutputDevice::SetSettings( pParent->GetSettings() ); + } + } + + const StyleSettings& rStyleSettings = maSettings.GetStyleSettings(); + USHORT nScreenZoom = rStyleSettings.GetScreenZoom(); + mnDPIX = (mpFrameData->mnDPIX*nScreenZoom)/100; + mnDPIY = (mpFrameData->mnDPIY*nScreenZoom)/100; + mpFontList = mpFrameData->mpFontList; + mpFontCache = mpFrameData->mpFontCache; + maFont = rStyleSettings.GetAppFont(); + ImplPointToLogic( maFont ); + + if ( nStyle & WB_3DLOOK ) + { + SetTextColor( rStyleSettings.GetButtonTextColor() ); + SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) ); + } + else + { + SetTextColor( rStyleSettings.GetWindowTextColor() ); + SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) ); + } + + ImplUpdatePos(); + + // AppFont-Aufloesung berechnen + if ( mbFrame && !pSVData->maGDIData.mnAppFontX ) + ImplInitAppFontData( this ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplInsertWindow( Window* pParent ) +{ + mpParent = pParent; + mpRealParent = pParent; + + if ( pParent && !mbFrame ) + { + // search frame window and set window frame data + Window* pFrameParent = pParent->mpFrameWindow; + mpFrameData = pFrameParent->mpFrameData; + mpFrame = pFrameParent->mpFrame; + mpFrameWindow = pFrameParent; + mbFrame = FALSE; +#ifdef REMOTE_APPSERVER + mpGraphics = mpFrameWindow->mpGraphics; +#endif + + // search overlap window and insert window in list + if ( ImplIsOverlapWindow() ) + { + Window* pFirstOverlapParent = pParent; + while ( !pFirstOverlapParent->ImplIsOverlapWindow() ) + pFirstOverlapParent = pFirstOverlapParent->ImplGetParent(); + mpOverlapWindow = pFirstOverlapParent; + + mpNextOverlap = mpFrameData->mpFirstOverlap; + mpFrameData->mpFirstOverlap = this; + + // Overlap-Windows sind per default die obersten + mpNext = pFirstOverlapParent->mpFirstOverlap; + pFirstOverlapParent->mpFirstOverlap = this; + if ( !pFirstOverlapParent->mpLastOverlap ) + pFirstOverlapParent->mpLastOverlap = this; + else + mpNext->mpPrev = this; + } + else + { + if ( pParent->ImplIsOverlapWindow() ) + mpOverlapWindow = pParent; + else + mpOverlapWindow = pParent->mpOverlapWindow; + mpPrev = pParent->mpLastChild; + pParent->mpLastChild = this; + if ( !pParent->mpFirstChild ) + pParent->mpFirstChild = this; + else + mpPrev->mpNext = this; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplRemoveWindow( BOOL bRemoveFrameData ) +{ + // Fenster aus den Listen austragen + if ( !mbFrame ) + { + if ( ImplIsOverlapWindow() ) + { + if ( mpFrameData->mpFirstOverlap == this ) + mpFrameData->mpFirstOverlap = mpNextOverlap; + else + { + Window* pTempWin = mpFrameData->mpFirstOverlap; + while ( pTempWin->mpNextOverlap != this ) + pTempWin = pTempWin->mpNextOverlap; + pTempWin->mpNextOverlap = mpNextOverlap; + } + + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpOverlapWindow->mpFirstOverlap = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpOverlapWindow->mpLastOverlap = mpPrev; + } + else + { + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpParent->mpFirstChild = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpParent->mpLastChild = mpPrev; + } + + mpPrev = NULL; + mpNext = NULL; + } + + if ( bRemoveFrameData ) + { + // Graphic freigeben +#ifndef REMOTE_APPSERVER + ImplReleaseGraphics(); +#else + ImplReleaseServerGraphics(); +#endif + } +} + +// ----------------------------------------------------------------------- + +static ULONG ImplAutoHelpID() +{ + if ( !Application::IsAutoHelpIdEnabled() ) + return 0; + + ULONG nHID = 0; + + ResMgr *pResMgr = Resource::GetResManager(); + + DBG_ASSERT( pResMgr, "MM hat gesagt, dass wir immer einen haben" ); + DBG_ASSERT( pResMgr->nTopRes, "MM hat gesagt, dass der Stack nie leer ist" ); + if( !pResMgr || pResMgr->nTopRes < 1 || pResMgr->nTopRes > 2 ) + return 0; + + const ImpRCStack *pRC = pResMgr->StackTop( pResMgr->nTopRes==1 ? 0 : 1 ); + + DBG_ASSERT( pRC->pResource, "MM hat gesagt, dass der immer einen hat" ); + ULONG nGID = pRC->pResource->GetId(); + + if( !nGID || nGID > 32767 ) + return 0; + + // GGGg gggg::gggg gggg::ggLL LLLl::llll llll + switch( pRC->pResource->GetRT() ) { // maximal 7 + case RSC_DOCKINGWINDOW: + nHID += 0x20000000L; + case RSC_WORKWIN: + nHID += 0x20000000L; + case RSC_MODELESSDIALOG: + nHID += 0x20000000L; + case RSC_FLOATINGWINDOW: + nHID += 0x20000000L; + case RSC_MODALDIALOG: + nHID += 0x20000000L; + case RSC_TABPAGE: + nHID += 0x20000000L; + + if( pResMgr->nTopRes == 2 ) { + pRC = pResMgr->StackTop(); + ULONG nLID = pRC->pResource->GetId(); + + if( !nLID || nLID > 511 ) + return 0; + + switch( pRC->pResource->GetRT() ) { // maximal 32 + case RSC_TABCONTROL: nHID |= 0x0000; break; + case RSC_RADIOBUTTON: nHID |= 0x0200; break; + case RSC_CHECKBOX: nHID |= 0x0400; break; + case RSC_TRISTATEBOX: nHID |= 0x0600; break; + case RSC_EDIT: nHID |= 0x0800; break; + case RSC_MULTILINEEDIT: nHID |= 0x0A00; break; + case RSC_MULTILISTBOX: nHID |= 0x0C00; break; + case RSC_LISTBOX: nHID |= 0x0E00; break; + case RSC_COMBOBOX: nHID |= 0x1000; break; + case RSC_PUSHBUTTON: nHID |= 0x1200; break; + case RSC_SPINFIELD: nHID |= 0x1400; break; + case RSC_PATTERNFIELD: nHID |= 0x1600; break; + case RSC_NUMERICFIELD: nHID |= 0x1800; break; + case RSC_METRICFIELD: nHID |= 0x1A00; break; + case RSC_CURRENCYFIELD: nHID |= 0x1C00; break; + case RSC_DATEFIELD: nHID |= 0x1E00; break; + case RSC_TIMEFIELD: nHID |= 0x2000; break; + case RSC_IMAGERADIOBUTTON: nHID |= 0x2200; break; + case RSC_NUMERICBOX: nHID |= 0x2400; break; + case RSC_METRICBOX: nHID |= 0x2600; break; + case RSC_CURRENCYBOX: nHID |= 0x2800; break; + case RSC_DATEBOX: nHID |= 0x2A00; break; + case RSC_TIMEBOX: nHID |= 0x2C00; break; + case RSC_IMAGEBUTTON: nHID |= 0x2E00; break; + case RSC_MENUBUTTON: nHID |= 0x3000; break; + case RSC_MOREBUTTON: nHID |= 0x3200; break; + default: + return 0; + } // of switch + nHID |= nLID; + } // of if + break; + default: + return 0; + } // of switch + nHID |= nGID << 14; + return nHID; +} + +// ----------------------------------------------------------------------- + +WinBits Window::ImplInitRes( const ResId& rResId ) +{ + GetRes( rResId ); + + char* pRes = (char*)GetClassRes(); + pRes += 4; + ULONG nStyle = GetLongRes( (void*)pRes ); + ((ResId&)rResId).aWinBits = nStyle; + return nStyle; +} + +// ----------------------------------------------------------------------- + +void Window::ImplLoadRes( const ResId& rResId ) +{ + // newer move this line after IncrementRes + char* pRes = (char*)GetClassRes(); + pRes += 8; + ULONG nHelpId = (ULONG)GetLongRes( (void*)pRes ); + if ( !nHelpId ) + nHelpId = ImplAutoHelpID(); + SetHelpId( nHelpId ); + + USHORT nObjMask = (USHORT)ReadShortRes(); + + // ResourceStyle + USHORT nRSStyle = ReadShortRes(); + // WinBits + ReadLongRes(); + // HelpId + ReadLongRes(); + + BOOL bPos = FALSE; + BOOL bSize = FALSE; + Point aPos; + Size aSize; + + if ( nObjMask & (WINDOW_XYMAPMODE | WINDOW_X | WINDOW_Y) ) + { + // Groessenangabe aus der Resource verwenden + MapUnit ePosMap = MAP_PIXEL; + + bPos = TRUE; + + if ( nObjMask & WINDOW_XYMAPMODE ) + ePosMap = (MapUnit)(USHORT)ReadShortRes(); + if ( nObjMask & WINDOW_X ) + aPos.X() = ImplLogicUnitToPixelX( ReadLongRes(), ePosMap ); + if ( nObjMask & WINDOW_Y ) + aPos.Y() = ImplLogicUnitToPixelY( ReadLongRes(), ePosMap ); + } + + if ( nObjMask & (WINDOW_WHMAPMODE | WINDOW_WIDTH | WINDOW_HEIGHT) ) + { + // Groessenangabe aus der Resource verwenden + MapUnit eSizeMap = MAP_PIXEL; + + bSize = TRUE; + + if ( nObjMask & WINDOW_WHMAPMODE ) + eSizeMap = (MapUnit)(USHORT)ReadShortRes(); + if ( nObjMask & WINDOW_WIDTH ) + aSize.Width() = ImplLogicUnitToPixelX( ReadLongRes(), eSizeMap ); + if ( nObjMask & WINDOW_HEIGHT ) + aSize.Height() = ImplLogicUnitToPixelY( ReadLongRes(), eSizeMap ); + } + + // Wegen Optimierung so schlimm aussehend + if ( nRSStyle & RSWND_CLIENTSIZE ) + { + if ( bPos ) + SetPosPixel( aPos ); + if ( bSize ) + SetOutputSizePixel( aSize ); + } + else if ( bPos && bSize ) + SetPosSizePixel( aPos, aSize ); + else if ( bPos ) + SetPosPixel( aPos ); + else if ( bSize ) + SetSizePixel( aSize ); + + if ( nRSStyle & RSWND_DISABLED ) + Enable( FALSE ); + + if ( nObjMask & WINDOW_TEXT ) + SetText( ReadStringRes() ); + if ( nObjMask & WINDOW_HELPTEXT ) + SetHelpText( ReadStringRes() ); + if ( nObjMask & WINDOW_QUICKTEXT ) + SetQuickHelpText( ReadStringRes() ); + if ( nObjMask & WINDOW_EXTRALONG ) + SetData( (void*)ReadLongRes() ); + if ( nObjMask & WINDOW_UNIQUEID ) + SetUniqueId( (ULONG)ReadLongRes() ); +} + +// ----------------------------------------------------------------------- + +ImplWinData* Window::ImplGetWinData() const +{ + if ( !mpWinData ) + { + ((Window*)this)->mpWinData = new ImplWinData; + mpWinData->mpExtPosAry = NULL; + mpWinData->mnExtPosStart = 0; + mpWinData->mnExtPosCount = 0; + mpWinData->mnExtOldTextLen = 0; + mpWinData->mpFocusRect = NULL; + mpWinData->mpTrackRect = NULL; + mpWinData->mnTrackFlags = 0; + } + + return mpWinData; +} + +// ----------------------------------------------------------------------- + +#ifndef REMOTE_APPSERVER +SalGraphics* Window::ImplGetFrameGraphics() const +{ + if ( mpFrameWindow->mpGraphics ) + mpFrameWindow->mbInitClipRegion = TRUE; + else + mpFrameWindow->ImplGetGraphics(); + mpFrameWindow->mpGraphics->ResetClipRegion(); + return mpFrameWindow->mpGraphics; +} +#endif + +// ----------------------------------------------------------------------- + +Window* Window::ImplFindWindow( const Point& rFramePos ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Window* pTempWindow; + Window* pFindWindow; + + // Zuerst alle ueberlappenden Fenster ueberpruefen + pTempWindow = mpFirstOverlap; + while ( pTempWindow ) + { + pFindWindow = pTempWindow->ImplFindWindow( rFramePos ); + if ( pFindWindow ) + return pFindWindow; + pTempWindow = pTempWindow->mpNext; + } + + // dann testen wir unser Fenster + if ( !mbVisible ) + return NULL; + + USHORT nHitTest = ImplHitTest( rFramePos ); + if ( nHitTest & WINDOW_HITTEST_INSIDE ) + { + // und danach gehen wir noch alle Child-Fenster durch + pTempWindow = mpFirstChild; + while ( pTempWindow ) + { + pFindWindow = pTempWindow->ImplFindWindow( rFramePos ); + if ( pFindWindow ) + return pFindWindow; + pTempWindow = pTempWindow->mpNext; + } + + if ( nHitTest & WINDOW_HITTEST_TRANSPARENT ) + return NULL; + else + return this; + } + + return NULL; +} + +// ----------------------------------------------------------------------- + +USHORT Window::ImplHitTest( const Point& rFramePos ) +{ + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + if ( !aRect.IsInside( rFramePos ) ) + return 0; + if ( mbWinRegion ) + { + Point aTempPos = rFramePos; + aTempPos.X() -= mnOutOffX; + aTempPos.Y() -= mnOutOffY; + if ( !maWinRegion.IsInside( aTempPos ) ) + return 0; + } + + USHORT nHitTest = WINDOW_HITTEST_INSIDE; + if ( mbMouseTransparent ) + nHitTest |= WINDOW_HITTEST_TRANSPARENT; + return nHitTest; +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplIsRealParentPath( const Window* pWindow ) const +{ + pWindow = pWindow->GetParent(); + while ( pWindow ) + { + if ( pWindow == this ) + return TRUE; + pWindow = pWindow->GetParent(); + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplIsChild( const Window* pWindow, BOOL bSystemWindow ) const +{ + do + { + if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() ) + break; + + pWindow = pWindow->ImplGetParent(); + + if ( pWindow == this ) + return TRUE; + } + while ( pWindow ); + + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplIsWindowOrChild( const Window* pWindow, BOOL bSystemWindow ) const +{ + if ( this == pWindow ) + return TRUE; + return ImplIsChild( pWindow, bSystemWindow ); +} + +// ----------------------------------------------------------------------- + +Window* Window::ImplGetSameParent( const Window* pWindow ) const +{ + if ( mpFrameWindow != pWindow->mpFrameWindow ) + return NULL; + else + { + if ( pWindow->ImplIsChild( this ) ) + return (Window*)pWindow; + else + { + Window* pTestWindow = (Window*)this; + while ( (pTestWindow == pWindow) || pTestWindow->ImplIsChild( pWindow ) ) + pTestWindow = pTestWindow->ImplGetParent(); + return pTestWindow; + } + } +} + +// ----------------------------------------------------------------------- + +int Window::ImplTestMousePointerSet() +{ + // Wenn Mouse gecaptured ist, dann soll MousePointer umgeschaltet werden + if ( IsMouseCaptured() ) + return TRUE; + + // Wenn sich Mouse ueber dem Fenster befindet, dann soll MousePointer + // umgeschaltet werden + Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() ); + if ( aClientRect.IsInside( GetPointerPosPixel() ) ) + return TRUE; + + return FALSE; +} + +// ----------------------------------------------------------------------- + +PointerStyle Window::ImplGetMousePointer() const +{ + PointerStyle ePointerStyle; + BOOL bWait = FALSE; + + if ( IsEnabled() && IsInputEnabled() ) + ePointerStyle = GetPointer().GetStyle(); + else + ePointerStyle = POINTER_ARROW; + + const Window* pWindow = this; + do + { + // Wenn Pointer nicht sichtbar, dann wird suche abgebrochen, da + // dieser Status nicht ueberschrieben werden darf + if ( pWindow->mbNoPtrVisible ) + return POINTER_NULL; + + if ( !bWait ) + { + if ( pWindow->mnWaitCount ) + { + ePointerStyle = POINTER_WAIT; + bWait = TRUE; + } + else + { + if ( pWindow->mbChildPtrOverwrite ) + ePointerStyle = pWindow->GetPointer().GetStyle(); + } + } + + if ( pWindow->ImplIsOverlapWindow() ) + break; + + pWindow = pWindow->ImplGetParent(); + } + while ( pWindow ); + + return ePointerStyle; +} + +// ----------------------------------------------------------------------- + +void Window::ImplResetReallyVisible() +{ + mbDevOutput = FALSE; + mbReallyVisible = FALSE; + mbReallyShown = FALSE; + + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + pWindow->ImplResetReallyVisible(); + pWindow = pWindow->mpNext; + } + + pWindow = mpFirstChild; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + pWindow->ImplResetReallyVisible(); + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplSetReallyVisible() +{ + mbDevOutput = TRUE; + mbReallyVisible = TRUE; + mbReallyShown = TRUE; + + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + if ( pWindow->mbVisible ) + pWindow->ImplSetReallyVisible(); + pWindow = pWindow->mpNext; + } + + pWindow = mpFirstChild; + while ( pWindow ) + { + if ( pWindow->mbVisible ) + pWindow->ImplSetReallyVisible(); + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallInitShow() +{ + mbReallyShown = TRUE; + mbInInitShow = TRUE; + StateChanged( STATE_CHANGE_INITSHOW ); + mbInInitShow = FALSE; + + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + if ( pWindow->mbVisible ) + pWindow->ImplCallInitShow(); + pWindow = pWindow->mpNext; + } + + pWindow = mpFirstChild; + while ( pWindow ) + { + if ( pWindow->mbVisible ) + pWindow->ImplCallInitShow(); + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplAddDel( ImplDelData* pDel ) +{ + pDel->mpNext = mpFirstDel; + mpFirstDel = pDel; +} + +// ----------------------------------------------------------------------- + +void Window::ImplRemoveDel( ImplDelData* pDel ) +{ + if ( mpFirstDel == pDel ) + mpFirstDel = pDel->mpNext; + else + { + ImplDelData* pData = mpFirstDel; + while ( pData->mpNext != pDel ) + pData = pData->mpNext; + pData->mpNext = pDel->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplInitResolutionSettings() +{ + // AppFont-Aufloesung und DPI-Aufloesung neu berechnen + if ( mbFrame ) + { + const StyleSettings& rStyleSettings = maSettings.GetStyleSettings(); + USHORT nScreenZoom = rStyleSettings.GetScreenZoom(); + mnDPIX = (mpFrameData->mnDPIX*nScreenZoom)/100; + mnDPIY = (mpFrameData->mnDPIY*nScreenZoom)/100; + SetPointFont( rStyleSettings.GetAppFont() ); + + if ( !ImplGetSVData()->maGDIData.mnAppFontX ) + ImplInitAppFontData( this ); + } + else if ( mpParent ) + { + mnDPIX = mpParent->mnDPIX; + mnDPIY = mpParent->mnDPIY; + } + + // Vorberechnete Werte fuer logische Einheiten updaten und auch + // die entsprechenden Tools dazu + if ( IsMapMode() ) + { + MapMode aMapMode = GetMapMode(); + SetMapMode(); + SetMapMode( aMapMode ); + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplPointToLogic( Font& rFont ) const +{ + Size aSize = rFont.GetSize(); + USHORT nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom(); + + if ( aSize.Width() ) + { + aSize.Width() *= mpFrameData->mnFontDPIX; + aSize.Width() += 72/2; + aSize.Width() /= 72; + aSize.Width() *= nScreenFontZoom; + aSize.Width() /= 100; + } + aSize.Height() *= mpFrameData->mnFontDPIY; + aSize.Height() += 72/2; + aSize.Height() /= 72; + aSize.Height() *= nScreenFontZoom; + aSize.Height() /= 100; + + if ( IsMapModeEnabled() ) + aSize = PixelToLogic( aSize ); + + rFont.SetSize( aSize ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplLogicToPoint( Font& rFont ) const +{ + Size aSize = rFont.GetSize(); + USHORT nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom(); + + if ( IsMapModeEnabled() ) + aSize = LogicToPixel( aSize ); + + if ( aSize.Width() ) + { + aSize.Width() *= 100; + aSize.Width() /= nScreenFontZoom; + aSize.Width() *= 72; + aSize.Width() += mpFrameData->mnFontDPIX/2; + aSize.Width() /= mpFrameData->mnFontDPIX; + } + aSize.Height() *= 100; + aSize.Height() /= nScreenFontZoom; + aSize.Height() *= 72; + aSize.Height() += mpFrameData->mnFontDPIY/2; + aSize.Height() /= mpFrameData->mnFontDPIY; + + rFont.SetSize( aSize ); +} + +// ----------------------------------------------------------------------- + +#ifndef REMOTE_APPSERVER +BOOL Window::ImplSysObjClip( const Region* pOldRegion ) +{ + BOOL bUpdate = TRUE; + + if ( mpSysObj ) + { + BOOL bVisibleState = mbReallyVisible; + + if ( bVisibleState ) + { + Region* pWinChildClipRegion = ImplGetWinChildClipRegion(); + + if ( !pWinChildClipRegion->IsEmpty() ) + { + if ( pOldRegion ) + { + Region aNewRegion = *pWinChildClipRegion; + pWinChildClipRegion->Intersect( *pOldRegion ); + bUpdate = aNewRegion == *pWinChildClipRegion; + } + + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + Region aRegion = *pWinChildClipRegion; + Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Region aWinRectRegion( aWinRect ); + USHORT nClipFlags = mpSysObj->GetClipRegionType(); + + if ( aRegion == aWinRectRegion ) + mpSysObj->ResetClipRegion(); + else + { + if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS ) + { + aWinRectRegion.Exclude( aRegion ); + aRegion = aWinRectRegion; + } + if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) ) + aRegion.Move( -mnOutOffX, -mnOutOffY ); + + // ClipRegion setzen/updaten + long nX; + long nY; + long nWidth; + long nHeight; + ULONG nRectCount; + ImplRegionInfo aInfo; + BOOL bRegionRect; + + nRectCount = aRegion.GetRectCount(); + mpSysObj->BeginSetClipRegion( nRectCount ); + bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight ); + while ( bRegionRect ) + { + mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight ); + bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight ); + } + mpSysObj->EndSetClipRegion(); + } + } + else + bVisibleState = FALSE; + } + + // Visible-Status updaten + mpSysObj->Show( bVisibleState ); + } + + return bUpdate; +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateSysObjChildsClip() +{ + if ( mpSysObj && mbInitWinClipRegion ) + ImplSysObjClip( NULL ); + + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + pWindow->ImplUpdateSysObjChildsClip(); + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateSysObjOverlapsClip() +{ + ImplUpdateSysObjChildsClip(); + + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + pWindow->ImplUpdateSysObjOverlapsClip(); + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateSysObjClip() +{ + if ( !ImplIsOverlapWindow() ) + { + ImplUpdateSysObjChildsClip(); + + // Schwestern muessen ihre ClipRegion auch neu berechnen + if ( mbClipSiblings ) + { + Window* pWindow = mpNext; + while ( pWindow ) + { + pWindow->ImplUpdateSysObjChildsClip(); + pWindow = pWindow->mpNext; + } + } + } + else + mpFrameWindow->ImplUpdateSysObjOverlapsClip(); +} + +#endif + +// ----------------------------------------------------------------------- + +BOOL Window::ImplSetClipFlagChilds( BOOL bSysObjOnlySmaller ) +{ + BOOL bUpdate = TRUE; +#ifndef REMOTE_APPSERVER + if ( mpSysObj ) + { + Region* pOldRegion = NULL; + if ( bSysObjOnlySmaller && !mbInitWinClipRegion ) + pOldRegion = new Region( maWinClipRegion ); + + mbInitClipRegion = TRUE; + mbInitWinClipRegion = TRUE; + + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) ) + bUpdate = FALSE; + pWindow = pWindow->mpNext; + } + + if ( !ImplSysObjClip( pOldRegion ) ) + { + mbInitClipRegion = TRUE; + mbInitWinClipRegion = TRUE; + bUpdate = FALSE; + } + + if ( pOldRegion ) + delete pOldRegion; + } + else +#endif + { + mbInitClipRegion = TRUE; + mbInitWinClipRegion = TRUE; + + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) ) + bUpdate = FALSE; + pWindow = pWindow->mpNext; + } + } + return bUpdate; +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplSetClipFlagOverlapWindows( BOOL bSysObjOnlySmaller ) +{ + BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller ); + + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) ) + bUpdate = FALSE; + pWindow = pWindow->mpNext; + } + + return bUpdate; +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplSetClipFlag( BOOL bSysObjOnlySmaller ) +{ + if ( !ImplIsOverlapWindow() ) + { + BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller ); + + Window* pParent = ImplGetParent(); + if ( pParent && + ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mnParentClipMode & PARENTCLIPMODE_CLIP)) ) + { + pParent->mbInitClipRegion = TRUE; + pParent->mbInitChildRegion = TRUE; + } + + // Schwestern muessen ihre ClipRegion auch neu berechnen + if ( mbClipSiblings ) + { + Window* pWindow = mpNext; + while ( pWindow ) + { + if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) ) + bUpdate = FALSE; + pWindow = pWindow->mpNext; + } + } + + return bUpdate; + } + else + return mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplIntersectWindowClipRegion( Region& rRegion ) +{ + if ( mbInitWinClipRegion ) + ImplInitWinClipRegion(); + + rRegion.Intersect( maWinClipRegion ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplIntersectWindowRegion( Region& rRegion ) +{ + rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ), + Size( mnOutWidth, mnOutHeight ) ) ); + if ( mbWinRegion ) + rRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplExcludeWindowRegion( Region& rRegion ) +{ + if ( mbWinRegion ) + { + Point aPoint( mnOutOffX, mnOutOffY ); + Region aRegion( Rectangle( aPoint, + Size( mnOutWidth, mnOutHeight ) ) ); + aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + rRegion.Exclude( aRegion ); + } + else + { + Point aPoint( mnOutOffX, mnOutOffY ); + rRegion.Exclude( Rectangle( aPoint, + Size( mnOutWidth, mnOutHeight ) ) ); + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplExcludeOverlapWindows( Region& rRegion ) +{ + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + { + pWindow->ImplExcludeWindowRegion( rRegion ); + pWindow->ImplExcludeOverlapWindows( rRegion ); + } + + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplExcludeOverlapWindows2( Region& rRegion ) +{ + if ( mbReallyVisible ) + ImplExcludeWindowRegion( rRegion ); + + ImplExcludeOverlapWindows( rRegion ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplClipBoundaries( Region& rRegion, BOOL bThis, BOOL bOverlaps ) +{ + if ( bThis ) + ImplIntersectWindowClipRegion( rRegion ); + else if ( ImplIsOverlapWindow() ) + { + // Evt. noch am Frame clippen + if ( !mbFrame ) + rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpFrameWindow->mnOutWidth, mpFrameWindow->mnOutHeight ) ) ); + + if ( bOverlaps && !rRegion.IsEmpty() ) + { + // Clip Overlap Siblings + Window* pStartOverlapWindow = this; + while ( !pStartOverlapWindow->mbFrame ) + { + Window* pOverlapWindow = pStartOverlapWindow->mpOverlapWindow->mpFirstOverlap; + while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) ) + { + pOverlapWindow->ImplExcludeOverlapWindows2( rRegion ); + pOverlapWindow = pOverlapWindow->mpNext; + } + pStartOverlapWindow = pStartOverlapWindow->mpOverlapWindow; + } + + // Clip Child Overlap Windows + ImplExcludeOverlapWindows( rRegion ); + } + } + else + ImplGetParent()->ImplIntersectWindowClipRegion( rRegion ); +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplClipChilds( Region& rRegion ) +{ + BOOL bOtherClip = FALSE; + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + { + // ParentClipMode-Flags auswerten + USHORT nClipMode = pWindow->GetParentClipMode(); + if ( !(nClipMode & PARENTCLIPMODE_NOCLIP) && + ((nClipMode & PARENTCLIPMODE_CLIP) || (GetStyle() & WB_CLIPCHILDREN)) ) + pWindow->ImplExcludeWindowRegion( rRegion ); + else + bOtherClip = TRUE; + } + + pWindow = pWindow->mpNext; + } + + return bOtherClip; +} + +// ----------------------------------------------------------------------- + +void Window::ImplClipAllChilds( Region& rRegion ) +{ + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + pWindow->ImplExcludeWindowRegion( rRegion ); + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplClipSiblings( Region& rRegion ) +{ + Window* pWindow = ImplGetParent()->mpFirstChild; + while ( pWindow ) + { + if ( pWindow == this ) + break; + + if ( pWindow->mbReallyVisible ) + pWindow->ImplExcludeWindowRegion( rRegion ); + + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplInitWinClipRegion() +{ + // Build Window Region + maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ), + Size( mnOutWidth, mnOutHeight ) ); + if ( mbWinRegion ) + maWinClipRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + + // ClipSiblings + if ( mbClipSiblings && !ImplIsOverlapWindow() ) + ImplClipSiblings( maWinClipRegion ); + + // Clip Parent Boundaries + ImplClipBoundaries( maWinClipRegion, FALSE, TRUE ); + + // Clip Children + if ( (GetStyle() & WB_CLIPCHILDREN) || mbClipChildren ) + mbInitChildRegion = TRUE; + + mbInitWinClipRegion = FALSE; +} + +// ----------------------------------------------------------------------- + +void Window::ImplInitWinChildClipRegion() +{ + if ( !mpFirstChild ) + { + if ( mpChildClipRegion ) + { + delete mpChildClipRegion; + mpChildClipRegion = NULL; + } + } + else + { + if ( !mpChildClipRegion ) + mpChildClipRegion = new Region( maWinClipRegion ); + else + *mpChildClipRegion = maWinClipRegion; + + ImplClipChilds( *mpChildClipRegion ); + } + + mbInitChildRegion = FALSE; +} + +// ----------------------------------------------------------------------- + +Region* Window::ImplGetWinChildClipRegion() +{ + if ( mbInitWinClipRegion ) + ImplInitWinClipRegion(); + if ( mbInitChildRegion ) + ImplInitWinChildClipRegion(); + if ( mpChildClipRegion ) + return mpChildClipRegion; + else + return &maWinClipRegion; +} + +// ----------------------------------------------------------------------- + +void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion ) +{ + Window* pWindow = mpFirstOverlap; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + { + Region aTempRegion( rInterRegion ); + pWindow->ImplIntersectWindowRegion( aTempRegion ); + rRegion.Union( aTempRegion ); + pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); + } + + pWindow = pWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion ) +{ + if ( mbReallyVisible ) + { + Region aTempRegion( rInterRegion ); + ImplIntersectWindowRegion( aTempRegion ); + rRegion.Union( aTempRegion ); + } + + ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplCalcOverlapRegionOverlaps( const Region& rInterRegion, Region& rRegion ) +{ + // Clip Overlap Siblings + Window* pStartOverlapWindow; + if ( !ImplIsOverlapWindow() ) + pStartOverlapWindow = mpOverlapWindow; + else + pStartOverlapWindow = this; + while ( !pStartOverlapWindow->mbFrame ) + { + Window* pOverlapWindow = pStartOverlapWindow->mpOverlapWindow->mpFirstOverlap; + while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) ) + { + pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion ); + pOverlapWindow = pOverlapWindow->mpNext; + } + pStartOverlapWindow = pStartOverlapWindow->mpOverlapWindow; + } + + // Clip Child Overlap Windows + if ( !ImplIsOverlapWindow() ) + mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); + else + ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, Region& rRegion, + BOOL bChilds, BOOL bParent, BOOL bSiblings ) +{ + Region aRegion( rSourceRect ); + if ( mbWinRegion ) + rRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + Region aTempRegion; + Window* pWindow; + + ImplCalcOverlapRegionOverlaps( aRegion, rRegion ); + + // Parent-Boundaries + if ( bParent ) + { + pWindow = this; + if ( !ImplIsOverlapWindow() ) + { + pWindow = ImplGetParent(); + do + { + aTempRegion = aRegion; + pWindow->ImplExcludeWindowRegion( aTempRegion ); + rRegion.Union( aTempRegion ); + if ( pWindow->ImplIsOverlapWindow() ) + break; + pWindow = pWindow->ImplGetParent(); + } + while ( pWindow ); + } + if ( !pWindow->mbFrame ) + { + aTempRegion = aRegion; + aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpFrameWindow->mnOutWidth, mpFrameWindow->mnOutHeight ) ) ); + rRegion.Union( aTempRegion ); + } + } + + // Siblings + if ( bSiblings && !ImplIsOverlapWindow() ) + { + pWindow = mpParent->mpFirstChild; + do + { + if ( pWindow->mbReallyVisible && (pWindow != this) ) + { + aTempRegion = aRegion; + pWindow->ImplIntersectWindowRegion( aTempRegion ); + rRegion.Union( aTempRegion ); + } + pWindow = pWindow->mpNext; + } + while ( pWindow ); + } + + // Childs + if ( bChilds ) + { + pWindow = mpFirstChild; + while ( pWindow ) + { + if ( pWindow->mbReallyVisible ) + { + aTempRegion = aRegion; + pWindow->ImplIntersectWindowRegion( aTempRegion ); + rRegion.Union( aTempRegion ); + } + pWindow = pWindow->mpNext; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallPaint( const Region* pRegion, USHORT nPaintFlags ) +{ + mbPaintFrame = FALSE; + + if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) + mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDS | (nPaintFlags & IMPL_PAINT_PAINTALL); + if ( nPaintFlags & IMPL_PAINT_PAINTCHILDS ) + mnPaintFlags |= IMPL_PAINT_PAINTCHILDS; + if ( nPaintFlags & IMPL_PAINT_ERASE ) + mnPaintFlags |= IMPL_PAINT_ERASE; + if ( !mpFirstChild ) + mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDS; + + if ( mbPaintDisabled ) + { + if ( mnPaintFlags & IMPL_PAINT_PAINTALL ) + Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN ); + else if ( pRegion ) + Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN ); + return; + } + + nPaintFlags = mnPaintFlags & ~(IMPL_PAINT_PAINT); + + Region* pChildRegion = NULL; + if ( mnPaintFlags & IMPL_PAINT_PAINT ) + { + Region* pWinChildClipRegion = ImplGetWinChildClipRegion(); + if ( mnPaintFlags & IMPL_PAINT_PAINTALL ) + maInvalidateRegion = *pWinChildClipRegion; + else + { + if ( pRegion ) + maInvalidateRegion.Union( *pRegion ); + if ( mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) + pChildRegion = new Region( maInvalidateRegion ); + maInvalidateRegion.Intersect( *pWinChildClipRegion ); + } + mnPaintFlags = 0; + if ( !maInvalidateRegion.IsEmpty() ) + { + if ( mpCursor ) + mpCursor->ImplHide(); + + mbInitClipRegion = TRUE; + mbInPaint = TRUE; + + // Paint-Region zuruecksetzen + Region aPaintRegion( maInvalidateRegion ); + Rectangle aPaintRect = ImplDevicePixelToLogic( aPaintRegion.GetBoundRect() ); + mpPaintRegion = &aPaintRegion; + maInvalidateRegion.SetEmpty(); + + if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() ) + { + if ( IsClipRegion() ) + { + Region aOldRegion = GetClipRegion(); + SetClipRegion(); + Erase(); + SetClipRegion( aOldRegion ); + } + else + Erase(); + } + Paint( aPaintRect ); + + if ( mpWinData ) + { + if ( mbFocusVisible ) + ImplInvertFocus( *(mpWinData->mpFocusRect) ); + if ( mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) ) + InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags ); + } + mbInPaint = FALSE; + mbInitClipRegion = TRUE; + mpPaintRegion = NULL; + if ( mpCursor ) + mpCursor->ImplShow( FALSE ); + } + } + else + mnPaintFlags = 0; + + if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDS | IMPL_PAINT_PAINTCHILDS) ) + { + // die Childfenster ausgeben + Window* pTempWindow = mpFirstChild; + while ( pTempWindow ) + { + if ( pTempWindow->mbVisible ) + pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags ); + pTempWindow = pTempWindow->mpNext; + } + } + + if ( pChildRegion ) + delete pChildRegion; +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallOverlapPaint() +{ + // Zuerst geben wir die ueberlappenden Fenster aus + Window* pTempWindow = mpFirstOverlap; + while ( pTempWindow ) + { + if ( pTempWindow->mbReallyVisible ) + pTempWindow->ImplCallOverlapPaint(); + pTempWindow = pTempWindow->mpNext; + } + + // und dann erst uns selber + if ( mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) ) + ImplCallPaint( NULL, mnPaintFlags ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplPostPaint() +{ + if ( !mpFrameData->maPaintTimer.IsActive() ) + mpFrameData->maPaintTimer.Start(); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( Window, ImplHandlePaintHdl, void*, EMPTYARG ) +{ + if ( mbReallyVisible ) + ImplCallOverlapPaint(); + return 0; +} + +// ----------------------------------------------------------------------- + +void Window::ImplInvalidateFrameRegion( const Region* pRegion, USHORT nFlags ) +{ + // PAINTCHILDS bei allen Parent-Fenster bis zum ersten OverlapWindow + // setzen + if ( !ImplIsOverlapWindow() ) + { + Window* pTempWindow = this; + do + { + pTempWindow = pTempWindow->ImplGetParent(); + if ( pTempWindow->mnPaintFlags & IMPL_PAINT_PAINTCHILDS ) + break; + pTempWindow->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS; + } + while ( !pTempWindow->ImplIsOverlapWindow() ); + } + + // Paint-Flags setzen + mnPaintFlags |= IMPL_PAINT_PAINT; + if ( nFlags & INVALIDATE_CHILDREN ) + mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDS; + if ( !(nFlags & INVALIDATE_NOERASE) ) + mnPaintFlags |= IMPL_PAINT_ERASE; + if ( !pRegion ) + mnPaintFlags |= IMPL_PAINT_PAINTALL; + + // Wenn nicht alles neu ausgegeben werden muss, dann die Region + // dazupacken + if ( !(mnPaintFlags & IMPL_PAINT_PAINTALL) ) + maInvalidateRegion.Union( *pRegion ); + + ImplPostPaint(); +} + +// ----------------------------------------------------------------------- + +void Window::ImplInvalidateOverlapFrameRegion( const Region& rRegion ) +{ + Region aRegion = rRegion; + ImplClipBoundaries( aRegion, TRUE, TRUE ); + if ( !aRegion.IsEmpty() ) + ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN ); + + // Dann invalidieren wir die ueberlappenden Fenster + Window* pTempWindow = mpFirstOverlap; + while ( pTempWindow ) + { + if ( pTempWindow->IsVisible() ) + pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion ); + + pTempWindow = pTempWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplInvalidateParentFrameRegion( Region& rRegion ) +{ + if ( mbOverlapWin ) + mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion ); + else + ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplInvalidate( const Region* pRegion, USHORT nFlags ) +{ + // Hintergrund-Sicherung zuruecksetzen + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + // Feststellen, was neu ausgegeben werden muss + BOOL bInvalidateAll = !pRegion; + + // Transparent-Invalidate beruecksichtigen + Window* pWindow = this; + if ( (mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) ) + { + Window* pTempWindow = pWindow->ImplGetParent(); + while ( pTempWindow ) + { + if ( !pTempWindow->IsPaintTransparent() ) + { + pWindow = pTempWindow; + nFlags |= INVALIDATE_CHILDREN; + bInvalidateAll = FALSE; + break; + } + + if ( pTempWindow->ImplIsOverlapWindow() ) + break; + + pTempWindow = pTempWindow->ImplGetParent(); + } + } + + // Region zusammenbauen + USHORT nOrgFlags = nFlags; + if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) ) + { + if ( pWindow->GetStyle() & WB_CLIPCHILDREN ) + nFlags |= INVALIDATE_NOCHILDREN; + else + nFlags |= INVALIDATE_CHILDREN; + } + if ( (nFlags & INVALIDATE_NOCHILDREN) && pWindow->mpFirstChild ) + bInvalidateAll = FALSE; + if ( bInvalidateAll ) + pWindow->ImplInvalidateFrameRegion( NULL, nFlags ); + else + { + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Region aRegion( aRect ); + if ( pRegion ) + aRegion.Intersect( *pRegion ); + pWindow->ImplClipBoundaries( aRegion, TRUE, TRUE ); + if ( nFlags & INVALIDATE_NOCHILDREN ) + { + nFlags &= ~INVALIDATE_CHILDREN; + if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) ) + { + if ( nOrgFlags & INVALIDATE_NOCHILDREN ) + pWindow->ImplClipAllChilds( aRegion ); + else + { + if ( pWindow->ImplClipChilds( aRegion ) ) + nFlags |= INVALIDATE_CHILDREN; + } + } + } + if ( !aRegion.IsEmpty() ) + pWindow->ImplInvalidateFrameRegion( &aRegion, nFlags ); + } + + if ( nFlags & INVALIDATE_UPDATE ) + pWindow->Update(); +} + +// ----------------------------------------------------------------------- + +void Window::ImplMoveInvalidateRegion( const Rectangle& rRect, + long nHorzScroll, long nVertScroll, + BOOL bChilds ) +{ + if ( (mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT ) + { + Region aTempRegion = maInvalidateRegion; + aTempRegion.Intersect( rRect ); + aTempRegion.Move( nHorzScroll, nVertScroll ); + maInvalidateRegion.Union( aTempRegion ); + } + + if ( bChilds && (mnPaintFlags & IMPL_PAINT_PAINTCHILDS) ) + { + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, TRUE ); + pWindow = pWindow->mpNext; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect, + long nHorzScroll, long nVertScroll, + BOOL bChilds ) +{ + // Paint-Region auch verschieben, wenn noch Paints anstehen + ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChilds ); + // Paint-Region muss bei uns verschoben gesetzt werden, die durch + // die Parents gezeichnet werden + if ( !ImplIsOverlapWindow() ) + { + Region aPaintAllRegion; + Window* pPaintAllWindow = this; + do + { + pPaintAllWindow = pPaintAllWindow->ImplGetParent(); + if ( pPaintAllWindow->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) + { + if ( pPaintAllWindow->mnPaintFlags & IMPL_PAINT_PAINTALL ) + { + aPaintAllRegion.SetEmpty(); + break; + } + else + aPaintAllRegion.Union( pPaintAllWindow->maInvalidateRegion ); + } + } + while ( !pPaintAllWindow->ImplIsOverlapWindow() ); + if ( !aPaintAllRegion.IsEmpty() ) + { + aPaintAllRegion.Move( nHorzScroll, nVertScroll ); + USHORT nPaintFlags = 0; + if ( bChilds ) + mnPaintFlags |= INVALIDATE_CHILDREN; + ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags ); + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplValidateFrameRegion( const Region* pRegion, USHORT nFlags ) +{ + if ( !pRegion ) + maInvalidateRegion.SetEmpty(); + else + { + // Wenn alle Childfenster neu ausgegeben werden muessen, + // dann invalidieren wir diese vorher + if ( (mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS) && mpFirstChild ) + { + Region aChildRegion = maInvalidateRegion; + if ( mnPaintFlags & IMPL_PAINT_PAINTALL ) + { + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + aChildRegion = aRect; + } + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); + pChild = pChild->mpNext; + } + } + if ( mnPaintFlags & IMPL_PAINT_PAINTALL ) + { + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + maInvalidateRegion = aRect; + } + maInvalidateRegion.Exclude( *pRegion ); + } + mnPaintFlags &= ~IMPL_PAINT_PAINTALL; + + if ( nFlags & VALIDATE_CHILDREN ) + { + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->ImplValidateFrameRegion( pRegion, nFlags ); + pChild = pChild->mpNext; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplValidate( const Region* pRegion, USHORT nFlags ) +{ + // Region zusammenbauen + BOOL bValidateAll = !pRegion; + USHORT nOrgFlags = nFlags; + if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) ) + { + if ( GetStyle() & WB_CLIPCHILDREN ) + nFlags |= VALIDATE_NOCHILDREN; + else + nFlags |= VALIDATE_CHILDREN; + } + if ( (nFlags & VALIDATE_NOCHILDREN) && mpFirstChild ) + bValidateAll = FALSE; + if ( bValidateAll ) + ImplValidateFrameRegion( NULL, nFlags ); + else + { + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Region aRegion( aRect ); + if ( pRegion ) + aRegion.Intersect( *pRegion ); + ImplClipBoundaries( aRegion, TRUE, TRUE ); + if ( nFlags & VALIDATE_NOCHILDREN ) + { + nFlags &= ~VALIDATE_CHILDREN; + if ( nOrgFlags & VALIDATE_NOCHILDREN ) + ImplClipAllChilds( aRegion ); + else + { + if ( ImplClipChilds( aRegion ) ) + nFlags |= VALIDATE_CHILDREN; + } + } + if ( !aRegion.IsEmpty() ) + ImplValidateFrameRegion( &aRegion, nFlags ); + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplScroll( const Rectangle& rRect, + long nHorzScroll, long nVertScroll, USHORT nFlags ) +{ + if ( !IsDeviceOutputNecessary() ) + return; + + nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll ); + nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll ); + + if ( !nHorzScroll && !nVertScroll ) + return; + + // Hintergrund-Sicherung zuruecksetzen + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + if ( mpCursor ) + mpCursor->ImplHide(); + + USHORT nOrgFlags = nFlags; + if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) ) + { + if ( GetStyle() & WB_CLIPCHILDREN ) + nFlags |= SCROLL_NOCHILDREN; + else + nFlags |= SCROLL_CHILDREN; + } + + Region aInvalidateRegion; + BOOL bScrollChilds = (nFlags & SCROLL_CHILDREN) != 0; + BOOL bErase = (nFlags & SCROLL_NOERASE) == 0; + + if ( !mpFirstChild ) + bScrollChilds = FALSE; + + // Paint-Bereiche anpassen + ImplMoveAllInvalidateRegions( rRect, nHorzScroll, nVertScroll, bScrollChilds ); + + if ( !(nFlags & SCROLL_NOINVALIDATE) ) + { + ImplCalcOverlapRegion( rRect, aInvalidateRegion, !bScrollChilds, TRUE, FALSE ); + if ( !aInvalidateRegion.IsEmpty() ) + { + aInvalidateRegion.Move( nHorzScroll, nVertScroll ); + bErase = TRUE; + } + if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) ) + { + Rectangle aDestRect( rRect ); + aDestRect.Move( nHorzScroll, nVertScroll ); + Region aWinInvalidateRegion( rRect ); + aWinInvalidateRegion.Exclude( aDestRect ); + aInvalidateRegion.Union( aWinInvalidateRegion ); + } + } + + Point aPoint( mnOutOffX, mnOutOffY ); + Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) ); + if ( nFlags & SCROLL_CLIP ) + aRegion.Intersect( rRect ); + if ( mbWinRegion ) + aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + aRegion.Exclude( aInvalidateRegion ); + ImplClipBoundaries( aRegion, FALSE, TRUE ); + if ( !bScrollChilds ) + { + if ( nOrgFlags & SCROLL_NOCHILDREN ) + ImplClipAllChilds( aRegion ); + else + ImplClipChilds( aRegion ); + } + if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) ) + aRegion.Intersect( maRegion ); + if ( !aRegion.IsEmpty() ) + { + if ( mpWinData ) + { + if ( mbFocusVisible ) + ImplInvertFocus( *(mpWinData->mpFocusRect) ); + if ( mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) ) + InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags ); + } + +#ifndef REMOTE_APPSERVER + SalGraphics* pGraphics = ImplGetFrameGraphics(); + if ( pGraphics ) + { + ImplSelectClipRegion( pGraphics, aRegion ); + pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll, + rRect.Left(), rRect.Top(), + rRect.GetWidth(), rRect.GetHeight(), + SAL_COPYAREA_WINDOWINVALIDATE ); + } +#else + ImplServerGraphics* pGraphics = ImplGetServerGraphics( TRUE ); + if ( pGraphics ) + { + pGraphics->SetClipRegion( aRegion ); + pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll, + rRect.Left(), rRect.Top(), + rRect.GetWidth(), rRect.GetHeight(), + COPYAREA_WINDOWINVALIDATE ); + } +#endif + + if ( mpWinData ) + { + if ( mbFocusVisible ) + ImplInvertFocus( *(mpWinData->mpFocusRect) ); + if ( mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) ) + InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags ); + } + } + + if ( !aInvalidateRegion.IsEmpty() ) + { + USHORT nPaintFlags = INVALIDATE_CHILDREN; + if ( !bErase ) + nPaintFlags |= INVALIDATE_NOERASE; + if ( !bScrollChilds ) + { + if ( nOrgFlags & SCROLL_NOCHILDREN ) + ImplClipAllChilds( aInvalidateRegion ); + else + ImplClipChilds( aInvalidateRegion ); + } + ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags ); + } + + if ( bScrollChilds ) + { + Rectangle aDestRect( rRect ); + Window* pWindow = mpFirstChild; + while ( pWindow ) + { + Rectangle aWinRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), + Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); + if ( aDestRect.IsOver( aWinRect ) ) + { + pWindow->mnX += nHorzScroll; + pWindow->maPos.X() += nHorzScroll; + pWindow->mnY += nVertScroll; + pWindow->maPos.Y() += nVertScroll; +#ifndef REMOTE_APPSERVER + if ( pWindow->ImplUpdatePos() ) + pWindow->ImplUpdateSysObjPos(); +#else + pWindow->ImplUpdatePos(); +#endif + if ( pWindow->IsReallyVisible() ) + pWindow->ImplSetClipFlag(); + if ( pWindow->mpClientWindow ) + pWindow->mpClientWindow->maPos = pWindow->maPos; + if ( pWindow->IsVisible() ) + { + pWindow->mbCallMove = FALSE; + pWindow->Move(); + } + else + pWindow->mbCallMove = TRUE; + } + pWindow = pWindow->mpNext; + } + } + + if ( nFlags & SCROLL_UPDATE ) + Update(); + + if ( mpCursor ) + mpCursor->ImplShow( FALSE ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateAll( BOOL bOverlapWindows ) +{ + if ( !mbReallyVisible ) + return; + + BOOL bFlush = FALSE; + if ( mpFrameWindow->mbPaintFrame ) + { + Point aPoint( 0, 0 ); + Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) ); + ImplInvalidateOverlapFrameRegion( aRegion ); + if ( mbFrame || (mpBorderWindow && mpBorderWindow->mbFrame) ) + bFlush = TRUE; + } + + // Ein Update wirkt immer auf das OverlapWindow, damit bei spaeteren + // Paints nicht zuviel gemalt wird, wenn dort ALLCHILDREN usw. gesetzt + // ist + Window* pWindow = ImplGetFirstOverlapWindow(); + if ( bOverlapWindows ) + pWindow->ImplCallOverlapPaint(); + else + { + if ( pWindow->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) ) + pWindow->ImplCallPaint( NULL, pWindow->mnPaintFlags ); + } + + if ( bFlush ) + Flush(); +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateWindowPtr( Window* pWindow ) +{ + if ( mpFrameWindow != pWindow->mpFrameWindow ) + { + // Graphic freigeben +#ifndef REMOTE_APPSERVER + ImplReleaseGraphics(); +#else + ImplReleaseServerGraphics(); + mpGraphics = pWindow->mpFrameWindow->mpGraphics; +#endif + } + + mpFrameData = pWindow->mpFrameData; + mpFrame = pWindow->mpFrame; + mpFrameWindow = pWindow->mpFrameWindow; + if ( pWindow->ImplIsOverlapWindow() ) + mpOverlapWindow = pWindow; + else + mpOverlapWindow = pWindow->mpOverlapWindow; + + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->ImplUpdateWindowPtr( pWindow ); + pChild = pChild->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateWindowPtr() +{ + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->ImplUpdateWindowPtr( this ); + pChild = pChild->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplUpdateOverlapWindowPtr( BOOL bNewFrame ) +{ + BOOL bVisible = IsVisible(); + Show( FALSE ); + ImplRemoveWindow( bNewFrame ); + Window* pRealParent = mpRealParent; + ImplInsertWindow( ImplGetParent() ); + mpRealParent = pRealParent; + ImplUpdateWindowPtr(); +#ifndef REMOTE_APPSERVER + if ( ImplUpdatePos() ) + ImplUpdateSysObjPos(); +#else + ImplUpdatePos(); +#endif + + if ( bNewFrame ) + { + Window* pOverlapWindow = mpFirstOverlap; + while ( pOverlapWindow ) + { + Window* pNextOverlapWindow = pOverlapWindow->mpNext; + pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame ); + pOverlapWindow = pNextOverlapWindow; + } + } + + if ( bVisible ) + Show( TRUE ); +} + +// ----------------------------------------------------------------------- + +BOOL Window::ImplUpdatePos() +{ + BOOL bSysChild = FALSE; + + if ( ImplIsOverlapWindow() ) + { + mnOutOffX = mnX; + mnOutOffY = mnY; + } + else + { + Window* pParent = ImplGetParent(); + mnOutOffX = mnX+pParent->mnOutOffX; + mnOutOffY = mnY+pParent->mnOutOffY; + } + + Window* pChild = mpFirstChild; + while ( pChild ) + { + if ( pChild->ImplUpdatePos() ) + bSysChild = TRUE; + pChild = pChild->mpNext; + } + +#ifndef REMOTE_APPSERVER + if ( mpSysObj ) + bSysChild = TRUE; +#endif + + return bSysChild; +} + +// ----------------------------------------------------------------------- + +#ifndef REMOTE_APPSERVER +void Window::ImplUpdateSysObjPos() +{ + if ( mpSysObj ) + mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ); + + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->ImplUpdateSysObjPos(); + pChild = pChild->mpNext; + } +} +#endif + +// ----------------------------------------------------------------------- + +/* --- RTL --- +void Window::ImplAlignChilds() +{ + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->ImplPosSizeWindow( pChild->maPos.X(), 0, 0, 0, WINDOW_POSSIZE_X ); + pChild = pChild->mpNext; + } +} +*/ + +// ----------------------------------------------------------------------- + +void Window::ImplPosSizeWindow( long nX, long nY, + long nWidth, long nHeight, USHORT nFlags ) +{ + BOOL bNewPos = FALSE; + BOOL bNewSize = FALSE; + BOOL bNewWidth = FALSE; + BOOL bCopyBits = FALSE; + long nOldOutOffX = mnOutOffX; + long nOldOutOffY = mnOutOffY; + long nOldOutWidth = mnOutWidth; + long nOldOutHeight = mnOutHeight; + Region* pOverlapRegion = NULL; + Region* pOldRegion = NULL; + + if ( IsReallyVisible() ) + { + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ), + Size( nOldOutWidth, nOldOutHeight ) ); + pOldRegion = new Region( aOldWinRect ); + if ( mbWinRegion ) + pOldRegion->Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + + if ( mnOutWidth && mnOutHeight && !mbPaintTransparent && + !mbInitWinClipRegion && !maWinClipRegion.IsEmpty() && + !HasPaintEvent() ) + bCopyBits = TRUE; + } + + if ( nFlags & WINDOW_POSSIZE_WIDTH ) + { + if ( nWidth < 0 ) + nWidth = 0; + if ( nWidth != mnOutWidth ) + { +/* --- RTL --- + if ( !ImplIsOverlapWindow() ) + { + if ( !(nFlags & WINDOW_POSSIZE_X) ) + { + nFlags |= WINDOW_POSSIZE_X; + nX = mnX; + } + } +*/ + mnOutWidth = nWidth; + bNewSize = TRUE; + bCopyBits = FALSE; + bNewWidth = TRUE; + } + } + if ( nFlags & WINDOW_POSSIZE_HEIGHT ) + { + if ( nHeight < 0 ) + nHeight = 0; + if ( nHeight != mnOutHeight ) + { + mnOutHeight = nHeight; + bNewSize = TRUE; + bCopyBits = FALSE; + } + } + + if ( nFlags & WINDOW_POSSIZE_X ) + { + if ( nX != mnX ) + { + long nOrgX = nX; +/* --- RTL --- + if ( !ImplIsOverlapWindow() ) + nX = mpParent->mnOutWidth-mnOutWidth-nX; +*/ + + if ( bCopyBits && !pOverlapRegion ) + { + pOverlapRegion = new Region(); + ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ), + Size( mnOutWidth, mnOutHeight ) ), + *pOverlapRegion, FALSE, TRUE, TRUE ); + } + mnX = nX; + maPos.X() = nOrgX; + bNewPos = TRUE; + } + } + if ( nFlags & WINDOW_POSSIZE_Y ) + { + if ( nY != mnY ) + { + if ( bCopyBits && !pOverlapRegion ) + { + pOverlapRegion = new Region(); + ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ), + Size( mnOutWidth, mnOutHeight ) ), + *pOverlapRegion, FALSE, TRUE, TRUE ); + } + mnY = nY; + maPos.Y() = nY; + bNewPos = TRUE; + } + } + + if ( bNewPos || bNewSize ) + { +#ifndef REMOTE_APPSERVER + BOOL bUpdateSysObjPos = FALSE; + if ( bNewPos ) + bUpdateSysObjPos = ImplUpdatePos(); +#else + if ( bNewPos ) + ImplUpdatePos(); +#endif + + if ( mpClientWindow ) + { + mpClientWindow->ImplPosSizeWindow( mpClientWindow->mnLeftBorder, + mpClientWindow->mnTopBorder, + mnOutWidth-mpClientWindow->mnLeftBorder-mpClientWindow->mnRightBorder, + mnOutHeight-mpClientWindow->mnTopBorder-mpClientWindow->mnBottomBorder, + WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y | + WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT ); + // Wenn wir ein ClientWindow haben, dann hat dieses fuer die + // Applikation auch die Position des FloatingWindows + mpClientWindow->maPos = maPos; + if ( bNewPos ) + { + if ( mpClientWindow->IsVisible() ) + { + mpClientWindow->mbCallMove = FALSE; + mpClientWindow->Move(); + } + else + mpClientWindow->mbCallMove = TRUE; + } + } + else + { + if ( mpBorderWindow ) + maPos = mpBorderWindow->maPos; + } + +/* --- RTL --- + if ( bNewWidth && !ImplIsOverlapWindow() ) + ImplAlignChilds(); +*/ + + // Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor + // einem Show() kommt + if ( IsVisible() ) + { + if ( bNewPos ) + { + mbCallMove = FALSE; + Move(); + } + if ( bNewSize ) + { + mbCallResize = FALSE; + Resize(); + } + } + else + { + if ( bNewPos ) + mbCallMove = TRUE; + if ( bNewSize ) + mbCallResize = TRUE; + } + +#ifndef REMOTE_APPSERVER + BOOL bUpdateSysObjClip = FALSE; +#endif + if ( IsReallyVisible() ) + { + if ( bNewPos || bNewSize ) + { + // Hintergrund-Sicherung zuruecksetzen + if ( mpOverlapData && mpOverlapData->mpSaveBackDev ) + ImplDeleteOverlapBackground(); + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + // Clip-Flag neu setzen +#ifndef REMOTE_APPSERVER + bUpdateSysObjClip = !ImplSetClipFlag( TRUE ); +#else + ImplSetClipFlag(); +#endif + } + + // Fensterinhalt invalidieren ? + if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) ) + { + if ( bNewPos ) + { + BOOL bInvalidate = FALSE; + BOOL bParentPaint = TRUE; + if ( !ImplIsOverlapWindow() ) + bParentPaint = mpParent->IsPaintEnabled(); + if ( bCopyBits && bParentPaint && !HasPaintEvent() ) + { + Point aPoint( mnOutOffX, mnOutOffY ); + Region aRegion( Rectangle( aPoint, + Size( mnOutWidth, mnOutHeight ) ) ); + if ( mbWinRegion ) + aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + ImplClipBoundaries( aRegion, FALSE, TRUE ); + if ( !pOverlapRegion->IsEmpty() ) + { + pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY ); + aRegion.Exclude( *pOverlapRegion ); + } + if ( !aRegion.IsEmpty() ) + { + // Paint-Bereiche anpassen + ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX, nOldOutOffY ), + Size( nOldOutWidth, nOldOutHeight ) ), + mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY, + TRUE ); +#ifndef REMOTE_APPSERVER + SalGraphics* pGraphics = ImplGetFrameGraphics(); + if ( pGraphics ) + { + BOOL bSelectClipRegion = ImplSelectClipRegion( pGraphics, aRegion ); + if ( bSelectClipRegion ) + { + pGraphics->CopyArea( mnOutOffX, mnOutOffY, + nOldOutOffX, nOldOutOffY, + nOldOutWidth, nOldOutHeight, + SAL_COPYAREA_WINDOWINVALIDATE ); + } + else + bInvalidate = TRUE; + } + else + bInvalidate = TRUE; +#else + ImplServerGraphics* pGraphics = ImplGetServerGraphics( TRUE ); + if ( pGraphics ) + { + pGraphics->SetClipRegion( aRegion ); + pGraphics->CopyArea( mnOutOffX, mnOutOffY, + nOldOutOffX, nOldOutOffY, + nOldOutWidth, nOldOutHeight, + COPYAREA_WINDOWINVALIDATE ); + } + else + bInvalidate = TRUE; +#endif + if ( !bInvalidate ) + { + if ( !pOverlapRegion->IsEmpty() ) + ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN ); + } + } + } + else + bInvalidate = TRUE; + if ( bInvalidate ) + ImplInvalidateFrameRegion( NULL, INVALIDATE_CHILDREN ); + } + else + { + Point aPoint( mnOutOffX, mnOutOffY ); + Region aRegion( Rectangle( aPoint, + Size( mnOutWidth, mnOutHeight ) ) ); + aRegion.Exclude( *pOldRegion ); + if ( mbWinRegion ) + aRegion.Intersect( ImplPixelToDevicePixel( maWinRegion ) ); + ImplClipBoundaries( aRegion, FALSE, TRUE ); + if ( !aRegion.IsEmpty() ) + ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN ); + } + } + + // Parent oder Overlaps invalidieren + if ( bNewPos || + (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) ) + { + Region aRegion( *pOldRegion ); + if ( !mbPaintTransparent ) + ImplExcludeWindowRegion( aRegion ); + ImplClipBoundaries( aRegion, FALSE, TRUE ); + if ( !aRegion.IsEmpty() && !mpBorderWindow ) + ImplInvalidateParentFrameRegion( aRegion ); + } + } + +#ifndef REMOTE_APPSERVER + // System-Objekte anpassen + if ( bUpdateSysObjClip ) + ImplUpdateSysObjClip(); + if ( bUpdateSysObjPos ) + ImplUpdateSysObjPos(); + if ( bNewSize && mpSysObj ) + mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ); +#endif + } + + if ( pOverlapRegion ) + delete pOverlapRegion; + if ( pOldRegion ) + delete pOldRegion; +} + +// ----------------------------------------------------------------------- + +void Window::ImplToBottomChild() +{ + if ( !ImplIsOverlapWindow() && !mbReallyVisible && (mpParent->mpLastChild != this) ) + { + // Fenster an das Ende der Liste setzen + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpParent->mpFirstChild = mpNext; + mpNext->mpPrev = mpPrev; + mpPrev = mpParent->mpLastChild; + mpParent->mpLastChild = this; + mpPrev->mpNext = this; + mpNext = NULL; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData ) +{ + DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" ); + + if ( !mbFrame ) + { + if ( IsReallyVisible() ) + { + // Region berechnen, wo das Fenster mit anderen Fenstern ueberlappt + Point aPoint( mnOutOffX, mnOutOffY ); + Region aRegion( Rectangle( aPoint, + Size( mnOutWidth, mnOutHeight ) ) ); + Region aInvalidateRegion; + ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion ); + + if ( !aInvalidateRegion.IsEmpty() ) + { + ImplCalcToTopData* pData = new ImplCalcToTopData; + pPrevData->mpNext = pData; + pData->mpNext = NULL; + pData->mpWindow = this; + pData->mpInvalidateRegion = new Region( aInvalidateRegion ); + } + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplCalcChildOverlapToTop( ImplCalcToTopData* pPrevData ) +{ + DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcChildOverlapToTop(): Is not a OverlapWindow" ); + + ImplCalcToTop( pPrevData ); + if ( pPrevData->mpNext ) + pPrevData = pPrevData->mpNext; + + Window* pOverlap = mpFirstOverlap; + while ( pOverlap ) + { + pOverlap->ImplCalcToTop( pPrevData ); + if ( pPrevData->mpNext ) + pPrevData = pPrevData->mpNext; + pOverlap = pOverlap->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplToTop( USHORT nFlags ) +{ + DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" ); + + if ( mbFrame ) + { + // Wenn in das externe Fenster geklickt wird, ist dieses + // dafuer zustaendig dafuer zu sorgen, das unser Frame + // nach vorne kommt + if ( !mpFrameData->mbHasFocus && + !mpFrameData->mbSysObjFocus && + !mpFrameData->mbInSysObjFocusHdl && + !mpFrameData->mbInSysObjToTopHdl ) + { +#ifndef REMOTE_APPSERVER + USHORT nSysFlags = 0; + if ( nFlags & TOTOP_RESTOREWHENMIN ) + nSysFlags = SAL_FRAME_TOTOP_RESTOREWHENMIN; + if ( nFlags & TOTOP_FOREGROUNDTASK ) + nSysFlags = SAL_FRAME_TOTOP_FOREGROUNDTASK; + mpFrame->ToTop( nSysFlags ); +#else + mpFrame->ToTop( nFlags ); +#endif + } + } + else + { + if ( mpOverlapWindow->mpFirstOverlap != this ) + { + // Fenster aus der Liste entfernen + mpPrev->mpNext = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpOverlapWindow->mpLastOverlap = mpPrev; + + // AlwaysOnTop beruecksichtigen + BOOL bOnTop = IsAlwaysOnTopEnabled(); + Window* pNextWin = mpOverlapWindow->mpFirstOverlap; + if ( !bOnTop ) + { + while ( pNextWin ) + { + if ( !pNextWin->IsAlwaysOnTopEnabled() ) + break; + pNextWin = pNextWin->mpNext; + } + } + + // TopLevel abpruefen + BYTE nTopLevel = mpOverlapData->mnTopLevel; + while ( pNextWin ) + { + if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) || + (nTopLevel <= pNextWin->mpOverlapData->mnTopLevel) ) + break; + pNextWin = pNextWin->mpNext; + } + + // Fenster in die Liste wieder eintragen + mpNext = pNextWin; + if ( pNextWin ) + { + mpPrev = pNextWin->mpPrev; + pNextWin->mpPrev = this; + } + else + { + mpPrev = mpOverlapWindow->mpLastOverlap; + mpOverlapWindow->mpLastOverlap = this; + } + if ( mpPrev ) + mpPrev->mpNext = this; + else + mpOverlapWindow->mpFirstOverlap = this; + + // ClipRegion muss von diesem Fenster und allen weiteren + // ueberlappenden Fenstern neu berechnet werden. + if ( IsReallyVisible() ) + { + // Hintergrund-Sicherung zuruecksetzen + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + mpOverlapWindow->ImplSetClipFlagOverlapWindows(); + } + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplStartToTop( USHORT nFlags ) +{ + ImplCalcToTopData aStartData; + ImplCalcToTopData* pCurData; + ImplCalcToTopData* pNextData; + Window* pOverlapWindow; + if ( ImplIsOverlapWindow() ) + pOverlapWindow = this; + else + pOverlapWindow = mpOverlapWindow; + + // Zuerst die Paint-Bereiche berechnen + Window* pTempOverlapWindow = pOverlapWindow; + aStartData.mpNext = NULL; + pCurData = &aStartData; + do + { + pTempOverlapWindow->ImplCalcToTop( pCurData ); + if ( pCurData->mpNext ) + pCurData = pCurData->mpNext; + pTempOverlapWindow = pTempOverlapWindow->mpOverlapWindow; + } + while ( !pTempOverlapWindow->mbFrame ); + // Dann die Paint-Bereiche der ChildOverlap-Windows berechnen + pTempOverlapWindow = mpFirstOverlap; + while ( pTempOverlapWindow ) + { + pTempOverlapWindow->ImplCalcToTop( pCurData ); + if ( pCurData->mpNext ) + pCurData = pCurData->mpNext; + pTempOverlapWindow = pTempOverlapWindow->mpNext; + } + + // Dann die Fenster-Verkettung aendern + pTempOverlapWindow = pOverlapWindow; + do + { + pTempOverlapWindow->ImplToTop( nFlags ); + pTempOverlapWindow = pTempOverlapWindow->mpOverlapWindow; + } + while ( !pTempOverlapWindow->mbFrame ); + // Und zum Schluss invalidieren wir die ungueltigen Bereiche + pCurData = aStartData.mpNext; + while ( pCurData ) + { + pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN ); + pNextData = pCurData->mpNext; + delete pCurData->mpInvalidateRegion; + delete pCurData; + pCurData = pNextData; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplFocusToTop( USHORT nFlags, BOOL bReallyVisible ) +{ + // Soll Focus auch geholt werden? + if ( !(nFlags & TOTOP_NOGRABFOCUS) ) + { + // Erstes Fenster mit GrabFocus-Activate bekommt den Focus + Window* pFocusWindow = this; + while ( !pFocusWindow->ImplIsOverlapWindow() ) + { + // Nur wenn Fenster kein Border-Fenster hat, da wir + // immer das dazugehoerende BorderFenster finden wollen + if ( !pFocusWindow->mpBorderWindow ) + { + if ( pFocusWindow->mnActivateMode & ACTIVATE_MODE_GRABFOCUS ) + break; + } + pFocusWindow = pFocusWindow->ImplGetParent(); + } + if ( (pFocusWindow->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) && + !pFocusWindow->HasChildPathFocus( TRUE ) ) + pFocusWindow->GrabFocus(); + } + + if ( bReallyVisible ) + ImplGenerateMouseMove(); +} + +// ----------------------------------------------------------------------- + +void Window::ImplShowAllOverlaps() +{ + Window* pOverlapWindow = mpFirstOverlap; + while ( pOverlapWindow ) + { + if ( pOverlapWindow->mbOverlapVisible ) + { + pOverlapWindow->Show( TRUE, SHOW_NOACTIVATE ); + pOverlapWindow->mbOverlapVisible = FALSE; + } + + pOverlapWindow = pOverlapWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplHideAllOverlaps() +{ + Window* pOverlapWindow = mpFirstOverlap; + while ( pOverlapWindow ) + { + if ( pOverlapWindow->IsVisible() ) + { + pOverlapWindow->mbOverlapVisible = TRUE; + pOverlapWindow->Show( FALSE ); + } + + pOverlapWindow = pOverlapWindow->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallMouseMove( USHORT nMouseCode, BOOL bModChanged ) +{ + if ( mpFrameData->mbMouseIn && mpFrameWindow->mbReallyVisible ) + { + ULONG nTime = Time::GetSystemTicks(); + long nX = mpFrameData->mnLastMouseX; + long nY = mpFrameData->mnLastMouseY; + USHORT nCode = nMouseCode; + USHORT nMode = mpFrameData->mnMouseMode; + BOOL bLeave; + // Auf MouseLeave testen + if ( ((nX < 0) || (nY < 0) || + (nX >= mpFrameWindow->mnOutWidth) || + (nY >= mpFrameWindow->mnOutHeight)) && + !ImplGetSVData()->maWinData.mpCaptureWin ) + bLeave = TRUE; + else + bLeave = FALSE; + nMode |= MOUSE_SYNTHETIC; + if ( bModChanged ) + nMode |= MOUSE_MODIFIERCHANGED; + ImplHandleMouseEvent( mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode ); + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplGenerateMouseMove() +{ + if ( !mpFrameData->mnMouseMoveId ) + Application::PostUserEvent( mpFrameData->mnMouseMoveId, LINK( mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) ); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( Window, ImplGenerateMouseMoveHdl, void*, EMPTYARG ) +{ + mpFrameData->mnMouseMoveId = 0; + ImplCallMouseMove( mpFrameData->mnMouseCode ); + return 0; +} + +// ----------------------------------------------------------------------- + +void Window::ImplInvertFocus( const Rectangle& rRect ) +{ + InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow, + Window* pOldOverlapWindow ) +{ + ImplSVData* pSVData = ImplGetSVData(); + Window* pNewRealWindow; + Window* pOldRealWindow; + Window* pLastRealWindow; + BOOL bCallActivate = TRUE; + BOOL bCallDeactivate = TRUE; + + pOldRealWindow = pOldOverlapWindow->ImplGetWindow(); + pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); + if ( (pOldRealWindow->GetType() != WINDOW_FLOATINGWINDOW) || + pOldRealWindow->GetActivateMode() ) + { + if ( (pNewRealWindow->GetType() == WINDOW_FLOATINGWINDOW) && + !pNewRealWindow->GetActivateMode() ) + { + pSVData->maWinData.mpLastDeacWin = pOldOverlapWindow; + bCallDeactivate = FALSE; + } + } + else if ( (pNewRealWindow->GetType() != WINDOW_FLOATINGWINDOW) || + pNewRealWindow->GetActivateMode() ) + { + if ( pSVData->maWinData.mpLastDeacWin ) + { + if ( pSVData->maWinData.mpLastDeacWin == pNewOverlapWindow ) + bCallActivate = FALSE; + else + { + pLastRealWindow = pSVData->maWinData.mpLastDeacWin->ImplGetWindow(); + pSVData->maWinData.mpLastDeacWin->mbActive = FALSE; + pSVData->maWinData.mpLastDeacWin->Deactivate(); + if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin ) + { + pLastRealWindow->mbActive = TRUE; + pLastRealWindow->Activate(); + } + } + pSVData->maWinData.mpLastDeacWin = NULL; + } + } + + if ( bCallDeactivate ) + { + pOldOverlapWindow->mbActive = FALSE; + pOldOverlapWindow->Deactivate(); + if ( pOldRealWindow != pOldOverlapWindow ) + { + pOldRealWindow->mbActive = FALSE; + pOldRealWindow->Deactivate(); + } + } + if ( bCallActivate ) + { + pNewOverlapWindow->mbActive = TRUE; + pNewOverlapWindow->Activate(); + if ( pNewRealWindow != pNewOverlapWindow ) + { + pNewRealWindow->mbActive = TRUE; + pNewRealWindow->Activate(); + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplGrabFocus( USHORT nFlags ) +{ + // Es soll immer das Client-Fenster den Focus bekommen. Falls + // wir mal auch Border-Fenstern den Focus geben wollen, + // muessten wir bei allen GrabFocus()-Aufrufen in VCL dafuer + // sorgen, das es an der Stelle gemacht wird. Dies wuerde + // beispielsweise bei ToTop() der Fall sein. + if ( mpClientWindow ) + { + // Wegen nicht ganz durchdachtem Konzept muessen wir hier + // leider noch einen Hack einbauen, damit wenn Dialoge + // geschlossen werden der Focus wieder auf das richtige + // Fenster zurueckgesetzt wird + if ( mpLastFocusWindow && (mpLastFocusWindow != this) && + !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) && + mpLastFocusWindow->IsEnabled() ) + mpLastFocusWindow->GrabFocus(); + else + mpClientWindow->GrabFocus(); + return; + } + else if ( mbFrame ) + { + // Wegen nicht ganz durchdachtem Konzept muessen wir hier + // leider noch einen Hack einbauen, damit wenn Dialoge + // geschlossen werden der Focus wieder auf das richtige + // Fenster zurueckgesetzt wird + if ( mpLastFocusWindow && (mpLastFocusWindow != this) && + !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) && + mpLastFocusWindow->IsEnabled() ) + { + mpLastFocusWindow->GrabFocus(); + return; + } + } + + // Wir brauchen Focus nur setzen, wenn es diesen noch nicht hat + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maWinData.mpFocusWin != this ) + { + // Dieses Fenster als letztes FocusWindow merken + Window* pOverlapWindow = ImplGetFirstOverlapWindow(); + pOverlapWindow->mpLastFocusWindow = this; + mpFrameData->mpFocusWin = this; + +#ifndef REMOTE_APPSERVER + if ( !mpSysObj && !mpFrameData->mbHasFocus ) +#else + if ( !mpFrameData->mbHasFocus ) +#endif + { + // Hier setzen wir schon den Focus um, da ToTop() den Focus + // nicht auf ein anderes Fenster setzen darf + DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" ); + mpFrame->ToTop( 0 ); + return; + } + + Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin; + pSVData->maWinData.mpFocusWin = this; + + if ( pOldFocusWindow ) + { + // Cursor hiden + if ( pOldFocusWindow->mpCursor ) + pOldFocusWindow->mpCursor->ImplHide(); + } + + // !!!!! Wegen altem SV-Office Activate/Deavtivate Handling + // !!!!! erstmal so wie frueher + if ( pOldFocusWindow ) + { + // Focus merken + Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow(); + Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); + if ( pOldOverlapWindow != pNewOverlapWindow ) + ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow ); + } + else + { + Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); + Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); + pNewOverlapWindow->mbActive = TRUE; + pNewOverlapWindow->Activate(); + if ( pNewRealWindow != pNewOverlapWindow ) + { + pNewRealWindow->mbActive = TRUE; + pNewRealWindow->Activate(); + } + } +/* + // call Deactivate and Activate + Window* pDeactivateParent; + Window* pActivateParent; + Window* pParent; + Window* pLastParent; + pDeactivateParent = pOldFocusWindow; + while ( pDeactivateParent ) + { + pParent = pDeactivateParent; + if ( pParent->ImplIsChild( this ) ) + break; + + if ( pDeactivateParent->ImplIsOverlapWindow() ) + { + if ( !pDeactivateParent->mbParentActive ) + break; + } + + pDeactivateParent = pDeactivateParent->ImplGetParent(); + } + if ( pOldFocusWindow ) + { + pActivateParent = this; + while ( pActivateParent ) + { + pParent = pActivateParent; + if ( pParent->ImplIsChild( pOldFocusWindow ) ) + break; + + if ( pActivateParent->ImplIsOverlapWindow() ) + { + if ( !pActivateParent->mbParentActive ) + break; + } + + pActivateParent = pActivateParent->ImplGetParent(); + } + } + else + { + if ( ImplIsOverlapWindow() ) + pActivateParent = this; + else + pActivateParent = mpOverlapWindow; + while ( pActivateParent ) + { + if ( pActivateParent->ImplIsOverlapWindow() ) + { + if ( !pActivateParent->mbParentActive ) + break; + } + + pActivateParent = pActivateParent->ImplGetParent(); + } + } + if ( pDeactivateParent ) + { + do + { + pLastParent = pOldFocusWindow; + if ( pLastParent != pDeactivateParent ) + { + pParent = pLastParent->ImplGetParent(); + while ( pParent ) + { + if ( pParent == pDeactivateParent ) + break; + pLastParent = pParent; + pParent = pParent->ImplGetParent(); + } + } + else + pParent = pLastParent; + + pParent->mbActive = FALSE; + pParent->Deactivate(); + pDeactivateParent = pLastParent; + } + while ( pDeactivateParent != pOldFocusWindow ); + } + do + { + pLastParent = this; + if ( pLastParent != pActivateParent ) + { + pParent = pLastParent->ImplGetParent(); + while ( pParent ) + { + if ( pParent == pActivateParent ) + break; + pLastParent = pParent; + pParent = pParent->ImplGetParent(); + } + } + else + pParent = pLastParent; + + pParent->mbActive = TRUE; + pParent->Activate(); + pActivateParent = pLastParent; + } + while ( pActivateParent != this ); +*/ + // call Get- and LoseFocus + if ( pOldFocusWindow ) + { + if ( pOldFocusWindow->IsTracking() && + (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) ) + pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS ); + pOldFocusWindow->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE ); + NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow ); + if ( !ImplCallPreNotify( aNEvt ) ) + pOldFocusWindow->LoseFocus(); + pOldFocusWindow->ImplCallDeactivateListeners( this ); + } + + if ( pSVData->maWinData.mpFocusWin == this ) + { +#ifndef REMOTE_APPSERVER + if ( mpSysObj ) + { + mpFrameData->mpFocusWin = this; + if ( !mpFrameData->mbInSysObjFocusHdl ) + mpSysObj->GrabFocus(); + } +#endif + + if ( pSVData->maWinData.mpFocusWin == this ) + { + if ( mpCursor ) + mpCursor->ImplShow(); + mbInFocusHdl = TRUE; + mnGetFocusFlags = nFlags; + NotifyEvent aNEvt( EVENT_GETFOCUS, this ); + if ( !ImplCallPreNotify( aNEvt ) ) + GetFocus(); + ImplCallActivateListeners( pOldFocusWindow ); + mnGetFocusFlags = 0; + mbInFocusHdl = FALSE; + } + } + + GetpApp()->FocusChanged(); + ImplNewInputContext(); + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplNewInputContext() +{ +#ifndef REMOTE_APPSERVER + SalInputContext aNewContext; + const InputContext& rInputContext = GetInputContext(); + const Font& rFont = rInputContext.GetFont(); + const XubString& rFontName = rFont.GetName(); + ImplFontEntry* pFontEntry = NULL; + if ( rFontName.Len() ) + { + Size aSize = ImplLogicToDevicePixel( rFont.GetSize() ); + if ( !aSize.Height() ) + { + // Nur dann Defaultgroesse setzen, wenn Fonthoehe auch in logischen + // Koordinaaten 0 ist + if ( rFont.GetSize().Height() ) + aSize.Height() = 1; + else + aSize.Height() = (12*mnDPIY)/72; + } + pFontEntry = mpFontCache->Get( mpFontList, rFont, aSize ); + aNewContext.mpFont = &(mpFontEntry->maFontSelData); + } + else + aNewContext.mpFont = NULL; + aNewContext.meCharSet = rFont.GetCharSet(); + aNewContext.meLanguage = rFont.GetLanguage(); + aNewContext.mnOptions = rInputContext.GetOptions(); + ImplGetFrame()->SetInputContext( &aNewContext ); + + if ( pFontEntry ) + mpFontCache->Release( pFontEntry ); +#endif +} + +// ----------------------------------------------------------------------- + +Window::Window( WindowType nType ) : + maZoom( 1, 1 ), + maWinRegion( REGION_NULL ), + maWinClipRegion( REGION_NULL ) +{ + DBG_CTOR( Window, ImplDbgCheckWindow ); + + ImplInitData( nType ); +} + +// ----------------------------------------------------------------------- + +Window::Window( Window* pParent, WinBits nStyle ) : + maZoom( 1, 1 ), + maWinRegion( REGION_NULL ), + maWinClipRegion( REGION_NULL ) +{ + DBG_CTOR( Window, ImplDbgCheckWindow ); + + ImplInitData( WINDOW_WINDOW ); + ImplInit( pParent, nStyle, NULL ); +} + +// ----------------------------------------------------------------------- + +Window::Window( Window* pParent, const ResId& rResId ) : + maZoom( 1, 1 ), + maWinRegion( REGION_NULL ), + maWinClipRegion( REGION_NULL ) +{ + DBG_CTOR( Window, ImplDbgCheckWindow ); + + ImplInitData( WINDOW_WINDOW ); + rResId.SetRT( RSC_WINDOW ); + WinBits nStyle = ImplInitRes( rResId ); + ImplInit( pParent, nStyle, NULL ); + ImplLoadRes( rResId ); + + if ( !(nStyle & WB_HIDE) ) + Show(); +} + +// ----------------------------------------------------------------------- + +Window::~Window() +{ + DBG_DTOR( Window, ImplDbgCheckWindow ); + + mbInDtor = TRUE; + + UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); + if ( pWrapper ) + pWrapper->WindowDestroyed( this ); + + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) ) + ImplDestroyHelpWindow( FALSE ); + + DBG_ASSERT( pSVData->maWinData.mpTrackWin != this, + "Window::~Window(): Window is in TrackingMode" ); + DBG_ASSERT( pSVData->maWinData.mpCaptureWin != this, + "Window::~Window(): Window has the mouse captured" ); + DBG_ASSERT( pSVData->maWinData.mpDefDialogParent != this, + "Window::~Window(): Window is DefModalDialogParent" ); + + // Wegen alter kompatibilitaet + if ( pSVData->maWinData.mpTrackWin == this ) + EndTracking(); + if ( pSVData->maWinData.mpCaptureWin == this ) + ReleaseMouse(); + if ( pSVData->maWinData.mpDefDialogParent == this ) + pSVData->maWinData.mpDefDialogParent = NULL; + +#ifdef DBG_UTIL + if ( DbgIsAssert() ) + { + ByteString aErrorStr; + BOOL bError = FALSE; + Window* pTempWin = mpFrameData->mpFirstOverlap; + while ( pTempWin ) + { + if ( ImplIsRealParentPath( pTempWin ) ) + { + bError = TRUE; + if ( aErrorStr.Len() ) + aErrorStr += "; "; + aErrorStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 ); + } + pTempWin = pTempWin->mpNextOverlap; + } + if ( bError ) + { + ByteString aTempStr( "Window (" ); + aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); + aTempStr += ") with living SystemWindow(s) destroyed: "; + aTempStr += aErrorStr; + DBG_ERROR( aTempStr.GetBuffer() ); + } + + if ( mpFirstChild ) + { + ByteString aTempStr( "Window (" ); + aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); + aTempStr += ") with living Child(s) destroyed: "; + Window* pTempWin = mpFirstChild; + while ( pTempWin ) + { + aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 ); + pTempWin = pTempWin->mpNext; + if ( pTempWin ) + aTempStr += "; "; + } + DBG_ERROR( aTempStr.GetBuffer() ); + } + + if ( mpFirstOverlap ) + { + ByteString aTempStr( "Window (" ); + aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); + aTempStr += ") with living SystemWindow(s) destroyed: "; + Window* pTempWin = mpFirstOverlap; + while ( pTempWin ) + { + aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 ); + pTempWin = pTempWin->mpNext; + if ( pTempWin ) + aTempStr += "; "; + } + DBG_ERROR( aTempStr.GetBuffer() ); + } + } +#endif + + // Fenster hiden, um das entsprechende Paint-Handling auszuloesen + Hide(); + + // Mitteilen, das Fenster zerstoert wird + { + NotifyEvent aNEvt( EVENT_DESTROY, this ); + Notify( aNEvt ); + } + + // Wenn wir den Focus haben, dann den Focus auf ein anderes Fenster setzen + Window* pOverlapWindow = ImplGetFirstOverlapWindow(); + if ( pSVData->maWinData.mpFocusWin == this ) + { + if ( mbFrame ) + { + pSVData->maWinData.mpFocusWin = NULL; + pOverlapWindow->mpLastFocusWindow = NULL; + GetpApp()->FocusChanged(); + } + else + { + Window* pParent = GetParent(); + Window* pBorderWindow = mpBorderWindow; + // Bei ueberlappenden Fenstern wird der Focus auf den + // Parent vom naechsten FrameWindow gesetzt + if ( pBorderWindow ) + { + if ( pBorderWindow->ImplIsOverlapWindow() ) + pParent = pBorderWindow->mpOverlapWindow; + } + else if ( ImplIsOverlapWindow() ) + pParent = mpOverlapWindow; + if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() ) + pParent->GrabFocus(); + else + mpFrameWindow->GrabFocus(); + // Falls der Focus wieder auf uns gesetzt wurde, dann wird er + // auf nichts gesetzt + if ( pSVData->maWinData.mpFocusWin == this ) + { + pSVData->maWinData.mpFocusWin = NULL; + pOverlapWindow->mpLastFocusWindow = NULL; + GetpApp()->FocusChanged(); + } + } + } + if ( pOverlapWindow->mpLastFocusWindow == this ) + pOverlapWindow->mpLastFocusWindow = NULL; + + // gemerkte Fenster zuruecksetzen + if ( mpFrameData->mpFocusWin == this ) + mpFrameData->mpFocusWin = NULL; + if ( mpFrameData->mpMouseMoveWin == this ) + mpFrameData->mpMouseMoveWin = NULL; + if ( mpFrameData->mpMouseDownWin == this ) + mpFrameData->mpMouseDownWin = NULL; + + // Deactivate-Window zuruecksetzen + if ( pSVData->maWinData.mpLastDeacWin == this ) + pSVData->maWinData.mpLastDeacWin = NULL; + +#ifdef REMOTE_APPSERVER + { + // Events als ungueltig markieren... + VOS_NAMESPACE(OGuard,vos) aGuard( pSVData->mpWindowObjectMutex ); + if ( mpRmEvents ) + { + ExtRmEvent* p = mpRmEvents; + while ( p ) + { + p->MarkInvalid(); + p = p->GetNextWindowEvent(); + } + } + } +#endif + + if ( mbFrame ) + { +#ifndef REMOTE_APPSERVER + DragManager::SystemEnableDrop( mpFrame, FALSE); +#endif + if ( mpFrameData->mnFocusId ) + Application::RemoveUserEvent( mpFrameData->mnFocusId ); + if ( mpFrameData->mnMouseMoveId ) + Application::RemoveUserEvent( mpFrameData->mnMouseMoveId ); + } + + // Graphic freigeben +#ifndef REMOTE_APPSERVER + ImplReleaseGraphics(); +#else + ImplReleaseServerGraphics(); +#endif + + // Evt. anderen Funktion mitteilen, das das Fenster geloescht + // wurde + ImplDelData* pDelData = mpFirstDel; + while ( pDelData ) + { + pDelData->mbDel = TRUE; + pDelData = pDelData->mpNext; + } + + // Fenster aus den Listen austragen + ImplRemoveWindow( TRUE ); + + // Extra Window Daten loeschen + if ( mpWinData ) + { + if ( mpWinData->mpExtPosAry ) + delete [] mpWinData->mpExtPosAry; + if ( mpWinData->mpFocusRect ) + delete mpWinData->mpFocusRect; + if ( mpWinData->mpTrackRect ) + delete mpWinData->mpTrackRect; + delete mpWinData; + } + + // Overlap-Window-Daten loeschen + if ( mpOverlapData ) + { + delete mpOverlapData; + } + + // Evt. noch BorderWindow oder Frame zerstoeren + if ( mpBorderWindow ) + delete mpBorderWindow; + else if ( mbFrame ) + { + if ( pSVData->maWinData.mpFirstFrame == this ) + pSVData->maWinData.mpFirstFrame = mpFrameData->mpNextFrame; + else + { + Window* pSysWin = pSVData->maWinData.mpFirstFrame; + while ( pSysWin->mpFrameData->mpNextFrame != this ) + pSysWin = pSysWin->mpFrameData->mpNextFrame; + pSysWin->mpFrameData->mpNextFrame = mpFrameData->mpNextFrame; + } +#ifndef REMOTE_APPSERVER + mpFrame->SetCallback( NULL, NULL ); + pSVData->mpDefInst->DestroyFrame( mpFrame ); +#else + mpGraphics->SetInterface( REF( NMSP_CLIENT::XRmOutputDevice )() ); + delete mpFrame; +#endif + if ( mpFrameData->mpDragTimer ) + delete mpFrameData->mpDragTimer; + delete mpFrameData; +#ifdef REMOTE_APPSERVER + delete mpGraphics; +#endif + } + + if ( mpChildClipRegion ) + delete mpChildClipRegion; +} + +// ----------------------------------------------------------------------- + +void Window::MouseMove( const MouseEvent& rMEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt ); + if ( !Notify( aNEvt ) ) + mbMouseMove = TRUE; +} + +// ----------------------------------------------------------------------- + +void Window::MouseButtonDown( const MouseEvent& rMEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt ); + if ( !Notify( aNEvt ) ) + mbMouseButtonDown = TRUE; +} + +// ----------------------------------------------------------------------- + +void Window::MouseButtonUp( const MouseEvent& rMEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt ); + if ( !Notify( aNEvt ) ) + mbMouseButtonUp = TRUE; +} + +// ----------------------------------------------------------------------- + +void Window::KeyInput( const KeyEvent& rKEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_KEYINPUT, this, &rKEvt ); + if ( !Notify( aNEvt ) ) + mbKeyInput = TRUE; +} + +// ----------------------------------------------------------------------- + +void Window::KeyUp( const KeyEvent& rKEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_KEYUP, this, &rKEvt ); + if ( !Notify( aNEvt ) ) + mbKeyUp = TRUE; +} + +// ----------------------------------------------------------------------- + +void Window::Paint( const Rectangle& rRect ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + if ( mxWindowPeer.is() ) + Application::GetUnoWrapper()->WindowEvent_Paint( this, rRect ); +} + +// ----------------------------------------------------------------------- + +void Window::Draw( OutputDevice*, const Point&, const Size&, ULONG ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); +} + +// ----------------------------------------------------------------------- + +void Window::Move() +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + if ( mxWindowPeer.is() ) + Application::GetUnoWrapper()->WindowEvent_Move( this ); +} + +// ----------------------------------------------------------------------- + +void Window::Resize() +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + if ( mxWindowPeer.is() ) + Application::GetUnoWrapper()->WindowEvent_Resize( this ); +} + +// ----------------------------------------------------------------------- + +void Window::Activate() +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } +} + +// ----------------------------------------------------------------------- + +void Window::Deactivate() +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } +} + +// ----------------------------------------------------------------------- + +void Window::GetFocus() +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + if ( HasFocus() && mpLastFocusWindow && !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) ) + mpLastFocusWindow->GrabFocus(); + + NotifyEvent aNEvt( EVENT_GETFOCUS, this ); + Notify( aNEvt ); + + if ( Application::GetAccessHdlCount() ) + Application::AccessNotify( AccessNotification( ACCESS_EVENT_GETFOCUS, this ) ); +} + +// ----------------------------------------------------------------------- + +void Window::LoseFocus() +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_LOSEFOCUS, this ); + Notify( aNEvt ); + + if ( Application::GetAccessHdlCount() ) + Application::AccessNotify( AccessNotification( ACCESS_EVENT_LOSEFOCUS, this ) ); +} + +// ----------------------------------------------------------------------- + +void Window::RequestHelp( const HelpEvent& rHEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + // Wenn Balloon-Help angefordert wird, dann den Balloon mit dem + // gesetzten Hilfetext anzeigen + if ( rHEvt.GetMode() & HELPMODE_BALLOON ) + { + const XubString* pStr = &(GetHelpText()); + if ( !pStr->Len() ) + pStr = &(GetQuickHelpText()); + if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() ) + ImplGetParent()->RequestHelp( rHEvt ); + else + Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), *pStr ); + } + else if ( rHEvt.GetMode() & HELPMODE_QUICK ) + { + const XubString* pStr = &(GetQuickHelpText()); + if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() ) + ImplGetParent()->RequestHelp( rHEvt ); + else + { + Point aPos = GetPosPixel(); + if ( ImplGetParent() && !ImplIsOverlapWindow() ) + aPos = ImplGetParent()->OutputToScreenPixel( aPos ); + Rectangle aRect( aPos, GetSizePixel() ); + String aHelpText; + if ( pStr->Len() ) + aHelpText = GetHelpText(); + Help::ShowQuickHelp( this, aRect, *pStr, aHelpText, QUICKHELP_CTRLTEXT ); + } + } + else + { + ULONG nStartHelpId = GetHelpId(); + + if ( !nStartHelpId && ImplGetParent() ) + ImplGetParent()->RequestHelp( rHEvt ); + else + { + if ( !nStartHelpId ) + nStartHelpId = HELP_INDEX; + + Help* pHelp = Application::GetHelp(); + if ( pHelp ) + pHelp->Start( nStartHelpId ); + } + } +} + +// ----------------------------------------------------------------------- + +void Window::Command( const CommandEvent& rCEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + if ( mxWindowPeer.is() ) + Application::GetUnoWrapper()->WindowEvent_Command( this, rCEvt ); + + NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt ); + if ( !Notify( aNEvt ) ) + mbCommand = TRUE; +} + +// ----------------------------------------------------------------------- + +void Window::Tracking( const TrackingEvent& ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); +} + +// ----------------------------------------------------------------------- + +BOOL Window::QueryDrop( DropEvent& rDEvt ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + NotifyEvent aNEvt( EVENT_QUERYDROP, this, &rDEvt, FALSE ); + Notify( aNEvt ); + return (BOOL)aNEvt.GetReturnValue(); +} + +// ----------------------------------------------------------------------- + +BOOL Window::Drop( const DropEvent& rDEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + NotifyEvent aNEvt( EVENT_DROP, this, &rDEvt, FALSE ); + Notify( aNEvt ); + return (BOOL)aNEvt.GetReturnValue(); +} + +// ----------------------------------------------------------------------- + +void Window::UserEvent( ULONG, void* ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); +} + +// ----------------------------------------------------------------------- + +void Window::StateChanged( StateChangedType ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); +} + +// ----------------------------------------------------------------------- + +void Window::DataChanged( const DataChangedEvent& ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); +} + +// ----------------------------------------------------------------------- + +long Window::PreNotify( NotifyEvent& rNEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + BOOL bDone = FALSE; + if ( mpParent && !ImplIsOverlapWindow() ) + bDone = mpParent->PreNotify( rNEvt ); + + if ( !bDone ) + { + if( rNEvt.GetType() == EVENT_GETFOCUS ) + { + BOOL bCompoundFocusChanged = FALSE; + if ( mbCompoundControl && !mbCompoundControlHasFocus && HasChildPathFocus() ) + { + mbCompoundControlHasFocus = TRUE; + bCompoundFocusChanged = TRUE; + } + + if ( mxWindowPeer.is() && ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) ) ) + Application::GetUnoWrapper()->WindowEvent_GetFocus( this ); + } + else if( rNEvt.GetType() == EVENT_LOSEFOCUS ) + { + BOOL bCompoundFocusChanged = FALSE; + if ( mbCompoundControl && mbCompoundControlHasFocus && !HasChildPathFocus() ) + { + mbCompoundControlHasFocus = FALSE ; + bCompoundFocusChanged = TRUE; + } + + if ( mxWindowPeer.is() && ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) ) ) + Application::GetUnoWrapper()->WindowEvent_LoseFocus( this ); + } + else if( rNEvt.GetType() == EVENT_MOUSEMOVE ) + { + if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) ) + { + if ( rNEvt.GetWindow() == this ) + Application::GetUnoWrapper()->WindowEvent_MouseMove( this, *rNEvt.GetMouseEvent() ); + else + Application::GetUnoWrapper()->WindowEvent_MouseMove( this, ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) ); + } + } + else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP ) + { + if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) ) + { + if ( rNEvt.GetWindow() == this ) + Application::GetUnoWrapper()->WindowEvent_MouseButtonUp( this, *rNEvt.GetMouseEvent() ); + else + Application::GetUnoWrapper()->WindowEvent_MouseButtonUp( this, ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) ); + } + } + else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) + { + if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) ) + { + if ( rNEvt.GetWindow() == this ) + Application::GetUnoWrapper()->WindowEvent_MouseButtonDown( this, *rNEvt.GetMouseEvent() ); + else + Application::GetUnoWrapper()->WindowEvent_MouseButtonDown( this, ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) ); + } + } + else if( rNEvt.GetType() == EVENT_KEYINPUT ) + { + if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) ) + Application::GetUnoWrapper()->WindowEvent_KeyInput( this, *rNEvt.GetKeyEvent() ); + } + else if( rNEvt.GetType() == EVENT_KEYUP ) + { + if ( mxWindowPeer.is() && ( mbCompoundControl || ( rNEvt.GetWindow() == this ) ) ) + Application::GetUnoWrapper()->WindowEvent_KeyUp( this, *rNEvt.GetKeyEvent() ); + } + } + + return bDone; +} + +// ----------------------------------------------------------------------- + +long Window::Notify( NotifyEvent& rNEvt ) +{ + { // Klammerung, da in diesem Handler das Window zerstoert werden darf + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + } + + long nRet = FALSE; + + // Dialog-Steuerung + if ( (GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL ) + { + // Wenn Parent auch DialogSteuerung aktiviert hat, uebernimmt dieser die Steuerung + if ( (rNEvt.GetType() == EVENT_KEYINPUT) || (rNEvt.GetType() == EVENT_KEYUP) ) + { + if ( ImplIsOverlapWindow() || + ((ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) ) + { + nRet = ImplDlgCtrl( *rNEvt.GetKeyEvent(), rNEvt.GetType() == EVENT_KEYINPUT ); + } + } + else if ( (rNEvt.GetType() == EVENT_GETFOCUS) || (rNEvt.GetType() == EVENT_LOSEFOCUS) ) + { + ImplDlgCtrlFocusChanged( rNEvt.GetWindow(), rNEvt.GetType() == EVENT_GETFOCUS ); + if ( (rNEvt.GetWindow() == this) && (rNEvt.GetType() == EVENT_GETFOCUS) && + !(GetStyle() & WB_TABSTOP) && !(mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) ) + { + USHORT n = 0; + Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST ); + if ( pFirstChild ) + pFirstChild->ImplControlFocus(); + } + } + } + + if ( !nRet ) + { + if ( mpParent && !ImplIsOverlapWindow() ) + nRet = mpParent->Notify( rNEvt ); + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +ULONG Window::PostUserEvent( ULONG nEvent, void* pEventData ) +{ + ULONG nEventId; + PostUserEvent( nEventId, nEvent, pEventData ); + return nEventId; +} + +// ----------------------------------------------------------------------- + +ULONG Window::PostUserEvent( const Link& rLink, void* pCaller ) +{ + ULONG nEventId; + PostUserEvent( nEventId, rLink, pCaller ); + return nEventId; +} + +// ----------------------------------------------------------------------- + +BOOL Window::PostUserEvent( ULONG& rEventId, ULONG nEvent, void* pEventData ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplSVEvent* pSVEvent = new ImplSVEvent; + pSVEvent->mnEvent = nEvent; + pSVEvent->mpData = pEventData; + pSVEvent->mpLink = NULL; + pSVEvent->mpWindow = this; + pSVEvent->mbCall = TRUE; + ImplAddDel( &(pSVEvent->maDelData) ); + rEventId = (ULONG)pSVEvent; +#ifndef REMOTE_APPSERVER + if ( mpFrame->PostEvent( pSVEvent ) ) + return TRUE; + else + { + rEventId = 0; + ImplRemoveDel( &(pSVEvent->maDelData) ); + delete pSVEvent; + return FALSE; + } +#else + ExtRmEvent* pEvt = new ExtRmEvent( RMEVENT_USEREVENT, NULL, pSVEvent ); + ImplPostEvent( pEvt ); + return TRUE; +#endif +} + +// ----------------------------------------------------------------------- + +BOOL Window::PostUserEvent( ULONG& rEventId, const Link& rLink, void* pCaller ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplSVEvent* pSVEvent = new ImplSVEvent; + pSVEvent->mnEvent = 0; + pSVEvent->mpData = pCaller; + pSVEvent->mpLink = new Link( rLink ); + pSVEvent->mpWindow = this; + pSVEvent->mbCall = TRUE; + ImplAddDel( &(pSVEvent->maDelData) ); + rEventId = (ULONG)pSVEvent; +#ifndef REMOTE_APPSERVER + if ( mpFrame->PostEvent( pSVEvent ) ) + return TRUE; + else + { + rEventId = 0; + ImplRemoveDel( &(pSVEvent->maDelData) ); + delete pSVEvent; + return FALSE; + } +#else + ExtRmEvent* pEvt = new ExtRmEvent( RMEVENT_USEREVENT, NULL, pSVEvent ); + ImplPostEvent( pEvt ); + return TRUE; +#endif +} + +// ----------------------------------------------------------------------- + +void Window::RemoveUserEvent( ULONG nUserEvent ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent; + + DBG_ASSERT( pSVEvent->mpWindow == this, + "Window::RemoveUserEvent(): Event doesn't send to this window or is already removed" ); + DBG_ASSERT( pSVEvent->mbCall, + "Window::RemoveUserEvent(): Event is already removed" ); + + if ( pSVEvent->mpWindow ) + { + pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) ); + pSVEvent->mpWindow = NULL; + } + + pSVEvent->mbCall = FALSE; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( Window, ImplAsyncStateChangedHdl, void*, pState ) +{ + StateChanged( (StateChangedType)(ULONG)pState ); + return 0; +} + +// ----------------------------------------------------------------------- + +void Window::PostStateChanged( StateChangedType nState ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + PostUserEvent( LINK( this, Window, ImplAsyncStateChangedHdl ), (void*)(ULONG)nState ); +} + +// ----------------------------------------------------------------------- + +void Window::SetStyle( WinBits nStyle ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mnStyle != nStyle ) + { + mnPrevStyle = mnStyle; + mnStyle = nStyle; + StateChanged( STATE_CHANGE_STYLE ); + } +} + +// ----------------------------------------------------------------------- + +void Window::SetExtendedStyle( WinBits nExtendedStyle ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mnExtendedStyle != nExtendedStyle ) + { + mnPrevExtendedStyle = mnExtendedStyle; + mnExtendedStyle = nExtendedStyle; + StateChanged( STATE_CHANGE_EXTENDEDSTYLE ); + } +} + +// ----------------------------------------------------------------------- + +SystemWindow* Window::GetSystemWindow() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + const Window* pWin = this; + while ( !pWin->IsSystemWindow() ) + pWin = pWin->GetParent(); + return (SystemWindow*)pWin; +} + +// ----------------------------------------------------------------------- + +void Window::SetBorderStyle( USHORT nBorderStyle ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + if ( mpBorderWindow->GetType() == WINDOW_BORDERWINDOW ) + ((ImplBorderWindow*)mpBorderWindow)->SetBorderStyle( nBorderStyle ); + else + mpBorderWindow->SetBorderStyle( nBorderStyle ); + } +} + +// ----------------------------------------------------------------------- + +USHORT Window::GetBorderStyle() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + if ( mpBorderWindow->GetType() == WINDOW_BORDERWINDOW ) + return ((ImplBorderWindow*)mpBorderWindow)->GetBorderStyle(); + else + return mpBorderWindow->GetBorderStyle(); + } + + return 0; +} + +// ----------------------------------------------------------------------- + +long Window::CalcTitleWidth() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + if ( mpBorderWindow->GetType() == WINDOW_BORDERWINDOW ) + return ((ImplBorderWindow*)mpBorderWindow)->CalcTitleWidth(); + else + return mpBorderWindow->CalcTitleWidth(); + } + else if ( mbFrame && (mnStyle & WB_MOVEABLE) ) + { + // Fuer Frame-Fenster raten wir die Breite, da wir den Border fuer + // externe Dialoge nicht kennen + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + Font aFont = GetFont(); + ((Window*)this)->SetPointFont( rStyleSettings.GetTitleFont() ); + long nTitleWidth = GetTextWidth( GetText() ); + ((Window*)this)->SetFont( aFont ); + nTitleWidth += rStyleSettings.GetTitleHeight() * 3; + nTitleWidth += rStyleSettings.GetBorderSize() * 2; + nTitleWidth += 10; + return nTitleWidth; + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void Window::EnableClipSiblings( BOOL bClipSiblings ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->EnableClipSiblings( bClipSiblings ); + + mbClipSiblings = bClipSiblings; +} + +// ----------------------------------------------------------------------- + +void Window::SetMouseTransparent( BOOL bTransparent ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->SetMouseTransparent( bTransparent ); + + mbMouseTransparent = bTransparent; +} + +// ----------------------------------------------------------------------- + +void Window::SetPaintTransparent( BOOL bTransparent ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->SetPaintTransparent( bTransparent ); + + mbPaintTransparent = bTransparent; +} + +// ----------------------------------------------------------------------- + +void Window::SetInputContext( const InputContext& rInputContext ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + maInputContext = rInputContext; + if ( !mbInFocusHdl && HasFocus() ) + ImplNewInputContext(); +} + +// ----------------------------------------------------------------------- + +void Window::UpdateExtTextInputArea() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + +#ifndef REMOTE_APPSERVER + if ( mbExtTextInput ) + ImplGetFrame()->UpdateExtTextInputArea(); +#endif +} + +// ----------------------------------------------------------------------- + +void Window::EndExtTextInput( USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + +#ifndef REMOTE_APPSERVER + if ( mbExtTextInput ) + ImplGetFrame()->EndExtTextInput( nFlags ); +#endif +} + +// ----------------------------------------------------------------------- + +void Window::SetExtTextInputPos( USHORT nStart, USHORT nCount, const Rectangle* pPosAry ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplWinData* pWinData = ImplGetWinData(); + + if ( pWinData->mpExtPosAry ) + delete [] pWinData->mpExtPosAry; + if ( nCount ) + { + pWinData->mpExtPosAry = new Rectangle[nCount]; + pWinData->mnExtPosStart = nStart; + pWinData->mnExtPosCount = nCount; + memcpy( pWinData->mpExtPosAry, pPosAry, nCount*sizeof( Rectangle ) ); + } + else + pWinData->mpExtPosAry = NULL; +} + +// ----------------------------------------------------------------------- + +const Rectangle* Window::GetExtTextInputPosAry() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplWinData* pWinData = ImplGetWinData(); + return pWinData->mpExtPosAry; +} + +// ----------------------------------------------------------------------- + +USHORT Window::GetExtTextInputPosStart() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplWinData* pWinData = ImplGetWinData(); + return pWinData->mnExtPosStart; +} + +// ----------------------------------------------------------------------- + +USHORT Window::GetExtTextInputPosCount() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplWinData* pWinData = ImplGetWinData(); + return pWinData->mnExtPosCount; +} + +// ----------------------------------------------------------------------- + +void Window::SetSettings( const AllSettings& rSettings, BOOL bChild ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + mpBorderWindow->SetSettings( rSettings, FALSE ); + if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow ) + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, TRUE ); + } + + AllSettings aOldSettings = maSettings; + OutputDevice::SetSettings( rSettings ); + ULONG nChangeFlags = aOldSettings.GetChangeFlags( rSettings ); + if ( nChangeFlags ) + { + DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags ); + DataChanged( aDCEvt ); + } + + // AppFont-Aufloesung und DPI-Aufloesung neu berechnen + ImplInitResolutionSettings(); + + if ( bChild || mbChildNotify ) + { + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->SetSettings( rSettings, bChild ); + pChild = pChild->mpNext; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::UpdateSettings( const AllSettings& rSettings, BOOL bChild ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + mpBorderWindow->UpdateSettings( rSettings, FALSE ); + if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow ) + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, TRUE ); + } + + AllSettings aOldSettings = maSettings; + ULONG nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings ); + if ( nChangeFlags ) + { + DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags ); + DataChanged( aDCEvt ); + } + + // AppFont-Aufloesung und DPI-Aufloesung neu berechnen + ImplInitResolutionSettings(); + + if ( bChild || mbChildNotify ) + { + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->UpdateSettings( rSettings, bChild ); + pChild = pChild->mpNext; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::NotifyAllChilds( DataChangedEvent& rDCEvt ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + DataChanged( rDCEvt ); + + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->NotifyAllChilds( rDCEvt ); + pChild = pChild->mpNext; + } +} + +// ----------------------------------------------------------------------- + +void Window::SetPointFont( const Font& rFont ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Font aFont = rFont; + ImplPointToLogic( aFont ); + SetFont( aFont ); +} + +// ----------------------------------------------------------------------- + +Font Window::GetPointFont() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Font aFont = GetFont(); + ImplLogicToPoint( aFont ); + return aFont; +} + +// ----------------------------------------------------------------------- + +void Window::GetFontResolution( long& nDPIX, long& nDPIY ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + nDPIX = mpFrameData->mnFontDPIX; + nDPIY = mpFrameData->mnFontDPIY; +} + +// ----------------------------------------------------------------------- + +void Window::SetParentClipMode( USHORT nMode ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->SetParentClipMode( nMode ); + else + { + if ( !ImplIsOverlapWindow() ) + { + mnParentClipMode = nMode; + if ( nMode & PARENTCLIPMODE_CLIP ) + mpParent->mbClipChildren = TRUE; + } + } +} + +// ----------------------------------------------------------------------- + +USHORT Window::GetParentClipMode() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + return mpBorderWindow->GetParentClipMode(); + else + return mnParentClipMode; +} + +// ----------------------------------------------------------------------- + +void Window::SetWindowRegionPixel() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->SetWindowRegionPixel(); + else + { + if ( mbWinRegion ) + { + maWinRegion = Region( REGION_NULL ); + mbWinRegion = FALSE; + ImplSetClipFlag(); + + if ( IsReallyVisible() ) + { + // Hintergrund-Sicherung zuruecksetzen + if ( mpOverlapData && mpOverlapData->mpSaveBackDev ) + ImplDeleteOverlapBackground(); + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Region aRegion( aRect ); + ImplInvalidateParentFrameRegion( aRegion ); + } + } + } +} + +// ----------------------------------------------------------------------- + +void Window::SetWindowRegionPixel( const Region& rRegion ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->SetWindowRegionPixel( rRegion ); + else + { + BOOL bInvalidate = FALSE; + + if ( rRegion.GetType() == REGION_NULL ) + { + if ( mbWinRegion ) + { + maWinRegion = Region( REGION_NULL ); + mbWinRegion = FALSE; + ImplSetClipFlag(); + bInvalidate = TRUE; + } + } + else + { + maWinRegion = rRegion; + mbWinRegion = TRUE; + ImplSetClipFlag(); + bInvalidate = TRUE; + } + + if ( IsReallyVisible() ) + { + // Hintergrund-Sicherung zuruecksetzen + if ( mpOverlapData && mpOverlapData->mpSaveBackDev ) + ImplDeleteOverlapBackground(); + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Region aRegion( aRect ); + ImplInvalidateParentFrameRegion( aRegion ); + } + } +} + +// ----------------------------------------------------------------------- + +const Region& Window::GetWindowRegionPixel() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + return mpBorderWindow->GetWindowRegionPixel(); + else + return maWinRegion; +} + +// ----------------------------------------------------------------------- + +BOOL Window::IsWindowRegionPixel() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + return mpBorderWindow->IsWindowRegionPixel(); + else + return mbWinRegion; +} + +// ----------------------------------------------------------------------- + +Region Window::GetWindowClipRegionPixel( USHORT nFlags ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Region aWinClipRegion; + + if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN ) + { + if ( mbInitWinClipRegion ) + ((Window*)this)->ImplInitWinClipRegion(); + aWinClipRegion = maWinClipRegion; + } + else + { + Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion(); + aWinClipRegion = *pWinChildClipRegion; + } + + if ( nFlags & WINDOW_GETCLIPREGION_NULL ) + { + Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Region aWinRegion( aWinRect ); + + if ( aWinRegion == aWinClipRegion ) + aWinClipRegion.SetNull(); + } + + aWinClipRegion.Move( -mnOutOffX, -mnOutOffY ); + + return aWinClipRegion; +} + +// ----------------------------------------------------------------------- + +Region Window::GetPaintRegion() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpPaintRegion ) + { + Region aRegion = *mpPaintRegion; + aRegion.Move( -mnOutOffX, -mnOutOffY ); + return PixelToLogic( aRegion ); + } + else + { + Region aPaintRegion( REGION_NULL ); + return aPaintRegion; + } +} + +// ----------------------------------------------------------------------- + +void Window::SetParent( Window* pNewParent ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" ); + + if ( mbFrame ) + return; + + if ( mpBorderWindow ) + { + mpRealParent = pNewParent; + mpBorderWindow->SetParent( pNewParent ); + return; + } + + if ( mpParent == pNewParent ) + return; + + BOOL bVisible = IsVisible(); + Show( FALSE, SHOW_NOFOCUSCHANGE ); + + // Testen, ob sich das Overlap-Window aendert + Window* pOldOverlapWindow; + Window* pNewOverlapWindow; + if ( ImplIsOverlapWindow() ) + pOldOverlapWindow = NULL; + else + { + pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow(); + if ( mpOverlapWindow != pNewOverlapWindow ) + pOldOverlapWindow = mpOverlapWindow; + else + pOldOverlapWindow = NULL; + } + + // Fenster in der Hirachie umsetzen + BOOL bFocusOverlapWin = HasChildPathFocus( TRUE ); + BOOL bFocusWin = HasChildPathFocus(); + BOOL bNewFrame = pNewParent->mpFrameWindow != mpFrameWindow; + if ( bNewFrame ) + { + if ( mpFrameData->mpFocusWin ) + { + if ( IsWindowOrChild( mpFrameData->mpFocusWin ) ) + mpFrameData->mpFocusWin = NULL; + } + if ( mpFrameData->mpMouseMoveWin ) + { + if ( IsWindowOrChild( mpFrameData->mpMouseMoveWin ) ) + mpFrameData->mpMouseMoveWin = NULL; + } + if ( mpFrameData->mpMouseDownWin ) + { + if ( IsWindowOrChild( mpFrameData->mpMouseDownWin ) ) + mpFrameData->mpMouseDownWin = NULL; + } + } + ImplRemoveWindow( bNewFrame ); + ImplInsertWindow( pNewParent ); + if ( mnParentClipMode & PARENTCLIPMODE_CLIP ) + pNewParent->mbClipChildren = TRUE; + ImplUpdateWindowPtr(); +#ifndef REMOTE_APPSERVER + if ( ImplUpdatePos() ) + ImplUpdateSysObjPos(); +#else + ImplUpdatePos(); +#endif + + // Wenn sich das Overlap-Window geaendert hat, dann muss getestet werden, + // ob auch OverlapWindow die das Child-Fenster als Parent gehabt haben + // in der Window-Hirachie umgesetzt werden muessen + if ( ImplIsOverlapWindow() ) + { + if ( bNewFrame ) + { + Window* pOverlapWindow = mpFirstOverlap; + while ( pOverlapWindow ) + { + Window* pNextOverlapWindow = pOverlapWindow->mpNext; + pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame ); + pOverlapWindow = pNextOverlapWindow; + } + } + } + else if ( pOldOverlapWindow ) + { + // Focus-Save zuruecksetzen + if ( bFocusWin || + (pOldOverlapWindow->mpLastFocusWindow && + IsWindowOrChild( pOldOverlapWindow->mpLastFocusWindow )) ) + pOldOverlapWindow->mpLastFocusWindow = NULL; + + Window* pOverlapWindow = pOldOverlapWindow->mpFirstOverlap; + while ( pOverlapWindow ) + { + Window* pNextOverlapWindow = pOverlapWindow->mpNext; + if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) ) + pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame ); + pOverlapWindow = pNextOverlapWindow; + } + + // Activate-Status beim naechsten Overlap-Window updaten + if ( HasChildPathFocus( TRUE ) ) + ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow ); + } + + // Activate-Status mit umsetzen + if ( bNewFrame ) + { + if ( (GetType() == WINDOW_BORDERWINDOW) && + (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) ) + ((ImplBorderWindow*)this)->SetDisplayActive( mpFrameData->mbHasFocus ); + } + + // Focus evtl. auf den neuen Frame umsetzen, wenn FocusWindow mit + // SetParent() umgesetzt wird + if ( bFocusOverlapWin ) + { + mpFrameData->mpFocusWin = Application::GetFocusWindow(); + if ( !mpFrameData->mbHasFocus ) + { + mpFrame->ToTop( 0 ); + } + } + + if ( bVisible ) + Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); +} + +// ----------------------------------------------------------------------- + +void Window::Show( BOOL bVisible, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mbVisible == bVisible ) + return; + + mbVisible = bVisible != 0; + + if ( !bVisible ) + { + ImplHideAllOverlaps(); + + if ( mpBorderWindow ) + { + BOOL bOldUpdate = mpBorderWindow->mbNoParentUpdate; + if ( mbNoParentUpdate ) + mpBorderWindow->mbNoParentUpdate = TRUE; + mpBorderWindow->Show( FALSE, nFlags ); + mpBorderWindow->mbNoParentUpdate = bOldUpdate; + } + else if ( mbFrame ) + mpFrame->Show( FALSE ); + + StateChanged( STATE_CHANGE_VISIBLE ); + + if ( mbReallyVisible ) + { + Region aInvRegion( REGION_EMPTY ); + BOOL bSaveBack = FALSE; + + if ( ImplIsOverlapWindow() && !mbFrame ) + { + if ( ImplRestoreOverlapBackground( aInvRegion ) ) + bSaveBack = TRUE; + } + + if ( !bSaveBack ) + { + if ( mbInitWinClipRegion ) + ImplInitWinClipRegion(); + aInvRegion = maWinClipRegion; + } + + ImplResetReallyVisible(); + ImplSetClipFlag(); + + if ( ImplIsOverlapWindow() && !mbFrame ) + { + // Focus umsetzen + if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() ) + { + if ( mpOverlapWindow->IsEnabled() && mpOverlapWindow->IsInputEnabled() ) + mpOverlapWindow->GrabFocus(); + } + } + + if ( !mbFrame ) + { + if ( !mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) ) + { + if ( !aInvRegion.IsEmpty() ) + ImplInvalidateParentFrameRegion( aInvRegion ); + } + ImplGenerateMouseMove(); + } + } + } + else + { + if ( mbCallMove ) + { + mbCallMove = FALSE; + Move(); + } + if ( mbCallResize ) + { + mbCallResize = FALSE; + Resize(); + } + + StateChanged( STATE_CHANGE_VISIBLE ); + + Window* pTestParent; + if ( ImplIsOverlapWindow() ) + pTestParent = mpOverlapWindow; + else + pTestParent = ImplGetParent(); + if ( mbFrame || pTestParent->mbReallyVisible ) + { + // Wenn ein Window gerade sichtbar wird, schicken wir allen + // Child-Fenstern ein StateChanged, damit diese sich + // initialisieren koennen + ImplCallInitShow(); + + // Wenn es ein SystemWindow ist, dann kommt es auch automatisch + // nach vorne, wenn es gewuenscht ist + if ( ImplIsOverlapWindow() && !(nFlags & SHOW_NOACTIVATE) ) + { + ImplStartToTop( 0 ); + ImplFocusToTop( 0, FALSE ); + } + + // Hintergrund sichern + if ( mpOverlapData && mpOverlapData->mbSaveBack ) + ImplSaveOverlapBackground(); + // Dafuer sorgen, das Clip-Rechtecke neu berechnet werden + ImplSetReallyVisible(); + ImplSetClipFlag(); + + if ( !mbFrame ) + { + ImplInvalidate( NULL, INVALIDATE_NOTRANSPARENT | INVALIDATE_CHILDREN ); + ImplGenerateMouseMove(); + } + } + + if ( mpBorderWindow ) + mpBorderWindow->Show( TRUE, nFlags ); + else if ( mbFrame ) + { + mbPaintFrame = TRUE; + mpFrame->Show( TRUE ); + + // Query the correct size of the window, if we are waiting for + // a system resize + if ( mbWaitSystemResize ) + { + long nOutWidth; + long nOutHeight; + mpFrame->GetClientSize( nOutWidth, nOutHeight ); + ImplHandleResize( this, nOutWidth, nOutHeight ); + } + } + +#ifdef DBG_UTIL + if ( IsDialog() || (GetType() == WINDOW_TABPAGE) ) + { + DBG_DIALOGTEST( this ); + } +#endif + + ImplShowAllOverlaps(); + } + + // Hintergrund-Sicherung zuruecksetzen + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + if ( mxWindowPeer.is() ) + Application::GetUnoWrapper()->WindowEvent_Show( this, mbVisible ); +} + +// ----------------------------------------------------------------------- + +void Window::Enable( BOOL bEnable, BOOL bChild ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !bEnable ) + { + // Wenn ein Fenster disablte wird, wird automatisch der Tracking-Modus + // beendet oder der Capture geklaut + if ( IsTracking() ) + EndTracking( ENDTRACK_CANCEL ); + if ( IsMouseCaptured() ) + ReleaseMouse(); + // Wenn Fenster den Focus hat und in der Dialog-Steuerung enthalten, + // wird versucht, den Focus auf das naechste Control weiterzuschalten + // mbDisabled darf erst nach Aufruf von ImplDlgCtrlNextWindow() gesetzt + // werden. Ansonsten muss ImplDlgCtrlNextWindow() umgestellt werden + if ( HasFocus() ) + ImplDlgCtrlNextWindow(); + } + + if ( mpBorderWindow ) + { + mpBorderWindow->Enable( bEnable, FALSE ); + if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow ) + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, TRUE ); + } + + if ( mbDisabled != !bEnable ) + { + mbDisabled = !bEnable; +#ifndef REMOTE_APPSERVER + if ( mpSysObj ) + mpSysObj->Enable( bEnable && !mbInputDisabled ); +#endif +// if ( mbFrame ) +// mpFrame->Enable( bEnable && !mbInputDisabled ); + StateChanged( STATE_CHANGE_ENABLE ); + } + + if ( bChild || mbChildNotify ) + { + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->Enable( bEnable, bChild ); + pChild = pChild->mpNext; + } + } + + if ( IsReallyVisible() ) + ImplGenerateMouseMove(); +} + +// ----------------------------------------------------------------------- + +void Window::EnableInput( BOOL bEnable, BOOL bChild ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + mpBorderWindow->EnableInput( bEnable, FALSE ); + if ( (mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow ) + ((ImplBorderWindow*)mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, TRUE ); + } + + if ( !mbAlwaysEnableInput || bEnable ) + { + // Wenn ein Fenster disablte wird, wird automatisch der + // Tracking-Modus beendet oder der Capture geklaut + if ( !bEnable ) + { + if ( IsTracking() ) + EndTracking( ENDTRACK_CANCEL ); + if ( IsMouseCaptured() ) + ReleaseMouse(); + } + + if ( mbInputDisabled != !bEnable ) + { + mbInputDisabled = !bEnable; +#ifndef REMOTE_APPSERVER + if ( mpSysObj ) + mpSysObj->Enable( !mbDisabled && bEnable ); +#endif +// if ( mbFrame ) +// mpFrame->Enable( !mbDisabled && bEnable ); + } + } + + if ( bChild || mbChildNotify ) + { + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->EnableInput( bEnable, bChild ); + pChild = pChild->mpNext; + } + } + + if ( IsReallyVisible() ) + ImplGenerateMouseMove(); +} + +// ----------------------------------------------------------------------- + +void Window::EnableInput( BOOL bEnable, BOOL bChild, BOOL bSysWin, + const Window* pExcludeWindow ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + EnableInput( bEnable, bChild ); + if ( bSysWin ) + { + // pExculeWindow is the first Overlap-Frame --> if this + // shouldn't be the case, than this must be changed in dialog.cxx + pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow(); + Window* pSysWin = mpFrameWindow->mpFrameData->mpFirstOverlap; + while ( pSysWin ) + { + // Is Window in the path from this window + if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, TRUE ) ) + { + // Is Window not in the exclude window path or not the + // exclude window, than change the status + if ( !pExcludeWindow->ImplIsWindowOrChild( pSysWin, TRUE ) ) + pSysWin->EnableInput( bEnable, bChild ); + } + pSysWin = pSysWin->mpNextOverlap; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::AlwaysEnableInput( BOOL bAlways, BOOL bChild ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->AlwaysEnableInput( bAlways, FALSE ); + + if ( mbAlwaysEnableInput != bAlways ) + { + mbAlwaysEnableInput = bAlways; + + if ( bAlways ) + EnableInput( TRUE, FALSE ); + } + + if ( bChild || mbChildNotify ) + { + Window* pChild = mpFirstChild; + while ( pChild ) + { + pChild->AlwaysEnableInput( bAlways, bChild ); + pChild = pChild->mpNext; + } + } +} + +// ----------------------------------------------------------------------- + +void Window::SetActivateMode( USHORT nMode ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + mpBorderWindow->SetActivateMode( nMode ); + + if ( mnActivateMode != nMode ) + { + mnActivateMode = nMode; + + // Evtl. ein Decativate/Activate ausloesen + if ( mnActivateMode ) + { + if ( (mbActive || (GetType() == WINDOW_BORDERWINDOW)) && + !HasChildPathFocus( TRUE ) ) + { + mbActive = FALSE; + Deactivate(); + } + } + else + { + if ( !mbActive || (GetType() == WINDOW_BORDERWINDOW) ) + { + mbActive = TRUE; + Activate(); + } + } + } +} + +// ----------------------------------------------------------------------- + +void Window::ToTop( USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplStartToTop( nFlags ); + ImplFocusToTop( nFlags, IsReallyVisible() ); +} + +// ----------------------------------------------------------------------- + +void Window::SetZOrder( Window* pRefWindow, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + mpBorderWindow->SetZOrder( pRefWindow, nFlags ); + return; + } + + if ( nFlags & WINDOW_ZORDER_FIRST ) + { + if ( ImplIsOverlapWindow() ) + pRefWindow = mpOverlapWindow->mpFirstOverlap; + else + pRefWindow = mpParent->mpFirstChild; + nFlags |= WINDOW_ZORDER_BEFOR; + } + else if ( nFlags & WINDOW_ZORDER_LAST ) + { + if ( ImplIsOverlapWindow() ) + pRefWindow = mpOverlapWindow->mpLastOverlap; + else + pRefWindow = mpParent->mpLastChild; + nFlags |= WINDOW_ZORDER_BEHIND; + } + + while ( pRefWindow->mpBorderWindow ) + pRefWindow = pRefWindow->mpBorderWindow; + if ( (pRefWindow == this) || mbFrame ) + return; + + DBG_ASSERT( pRefWindow->mpParent == mpParent, "Window::SetZOrder() - pRefWindow has other parent" ); + if ( nFlags & WINDOW_ZORDER_BEFOR ) + { + if ( pRefWindow->mpPrev == this ) + return; + + if ( ImplIsOverlapWindow() ) + { + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpOverlapWindow->mpFirstOverlap = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpOverlapWindow->mpLastOverlap = mpPrev; + if ( !pRefWindow->mpPrev ) + mpOverlapWindow->mpFirstOverlap = this; + } + else + { + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpParent->mpFirstChild = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpParent->mpLastChild = mpPrev; + if ( !pRefWindow->mpPrev ) + mpParent->mpFirstChild = this; + } + + mpPrev = pRefWindow->mpPrev; + mpNext = pRefWindow; + if ( mpPrev ) + mpPrev->mpNext = this; + mpNext->mpPrev = this; + } + else if ( nFlags & WINDOW_ZORDER_BEHIND ) + { + if ( pRefWindow->mpNext == this ) + return; + + if ( ImplIsOverlapWindow() ) + { + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpOverlapWindow->mpFirstOverlap = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpOverlapWindow->mpLastOverlap = mpPrev; + if ( !pRefWindow->mpNext ) + mpOverlapWindow->mpLastOverlap = this; + } + else + { + if ( mpPrev ) + mpPrev->mpNext = mpNext; + else + mpParent->mpFirstChild = mpNext; + if ( mpNext ) + mpNext->mpPrev = mpPrev; + else + mpParent->mpLastChild = mpPrev; + if ( !pRefWindow->mpNext ) + mpParent->mpLastChild = this; + } + + mpPrev = pRefWindow; + mpNext = pRefWindow->mpNext; + if ( mpNext ) + mpNext->mpPrev = this; + mpPrev->mpNext = this; + } + + if ( IsReallyVisible() ) + { + // Hintergrund-Sicherung zuruecksetzen + if ( mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + if ( mbInitWinClipRegion || !maWinClipRegion.IsEmpty() ) + { + BOOL bInitWinClipRegion = mbInitWinClipRegion; + ImplSetClipFlag(); + + // Wenn ClipRegion noch nicht initalisiert wurde, dann + // gehen wir davon aus, das das Fenster noch nicht + // ausgegeben wurde und loesen somit auch keine + // Invalidates aus. Dies ist eine Optimierung fuer + // HTML-Dokumenten mit vielen Controls. Wenn es mal + // Probleme mit dieser Abfrage gibt, sollte man ein + // Flag einfuehren, ob das Fenster nach Show schon + // einmal ausgegeben wurde. + if ( !bInitWinClipRegion ) + { + // Alle nebeneinanderliegen Fenster invalidieren + // Noch nicht komplett implementiert !!! + Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Window* pWindow = NULL; + if ( ImplIsOverlapWindow() ) + { + if ( mpOverlapWindow ) + pWindow = mpOverlapWindow->mpFirstOverlap; + } + else + pWindow = ImplGetParent()->mpFirstChild; + // Alle Fenster, die vor uns liegen und von uns verdeckt wurden, + // invalidieren + while ( pWindow ) + { + if ( pWindow == this ) + break; + Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), + Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); + if ( aWinRect.IsOver( aCompRect ) ) + pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); + pWindow = pWindow->mpNext; + } + // Wenn uns ein Fenster welches im Hinterund liegt verdeckt hat, + // dann muessen wir uns neu ausgeben + while ( pWindow ) + { + if ( pWindow != this ) + { + Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), + Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); + if ( aWinRect.IsOver( aCompRect ) ) + { + Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); + break; + } + } + pWindow = pWindow->mpNext; + } + } + } + } +} + +// ----------------------------------------------------------------------- + +void Window::EnableAlwaysOnTop( BOOL bEnable ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + mbAlwaysOnTop = bEnable; + + if ( mpBorderWindow ) + mpBorderWindow->EnableAlwaysOnTop( bEnable ); + else if ( bEnable && IsReallyVisible() ) + ToTop(); + + if ( mbFrame ) + mpFrame->SetAlwaysOnTop( bEnable ); +} + +// ----------------------------------------------------------------------- + +void Window::SetPosSizePixel( long nX, long nY, + long nWidth, long nHeight, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( nFlags & WINDOW_POSSIZE_POS ) + mbDefPos = FALSE; + if ( nFlags & WINDOW_POSSIZE_SIZE ) + mbDefSize = FALSE; + + // Oberstes BorderWindow ist das Window, welches positioniert werden soll + Window* pWindow = this; + while ( pWindow->mpBorderWindow ) + pWindow = pWindow->mpBorderWindow; + + if ( pWindow->mbFrame ) + { + // Nur Groessenaenderungen werden beruecksichtig + if ( (nFlags & WINDOW_POSSIZE_SIZE) == WINDOW_POSSIZE_SIZE ) + { + if ( !(nFlags & WINDOW_POSSIZE_WIDTH) ) + nWidth = pWindow->mnOutWidth; + if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) ) + nHeight = pWindow->mnOutHeight; + + pWindow->mpFrame->SetClientSize( nWidth, nHeight ); + // Resize should be called directly. If we havn't + // set the correct size, we get a second resize from + // the system with the correct size. This can be happend + // if the size is to small or to lare. + ImplHandleResize( pWindow, nWidth, nHeight ); + } + } + else + { + pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags ); + if ( IsReallyVisible() ) + ImplGenerateMouseMove(); + } +} + +// ----------------------------------------------------------------------- + +Point Window::OutputToScreenPixel( const Point& rPos ) const +{ + return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY ); +} + +// ----------------------------------------------------------------------- + +Point Window::ScreenToOutputPixel( const Point& rPos ) const +{ + return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY ); +} + +// ----------------------------------------------------------------------- + +void Window::Scroll( long nHorzScroll, long nVertScroll, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplScroll( Rectangle( Point( mnOutOffX, mnOutOffY ), + Size( mnOutWidth, mnOutHeight ) ), + nHorzScroll, nVertScroll, nFlags & ~SCROLL_CLIP ); +} + +// ----------------------------------------------------------------------- + +void Window::Scroll( long nHorzScroll, long nVertScroll, + const Rectangle& rRect, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Rectangle aRect = ImplLogicToDevicePixel( rRect ); + aRect.Intersection( Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) ); + if ( !aRect.IsEmpty() ) + ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags ); +} + +// ----------------------------------------------------------------------- + +void Window::Invalidate( USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) + return; + + ImplInvalidate( NULL, nFlags ); +} + +// ----------------------------------------------------------------------- + +void Window::Invalidate( const Rectangle& rRect, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) + return; + + Rectangle aRect = ImplLogicToDevicePixel( rRect ); + if ( !aRect.IsEmpty() ) + { + Region aRegion( aRect ); + ImplInvalidate( &aRegion, nFlags ); + } +} + +// ----------------------------------------------------------------------- + +void Window::Invalidate( const Region& rRegion, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) + return; + + if ( rRegion.IsNull() ) + ImplInvalidate( NULL, nFlags ); + else + { + Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) ); + if ( !aRegion.IsEmpty() ) + ImplInvalidate( &aRegion, nFlags ); + } +} + +// ----------------------------------------------------------------------- + +void Window::Validate( USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) + return; + + ImplValidate( NULL, nFlags ); +} + +// ----------------------------------------------------------------------- + +void Window::Validate( const Rectangle& rRect, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) + return; + + Rectangle aRect = ImplLogicToDevicePixel( rRect ); + if ( !aRect.IsEmpty() ) + { + Region aRegion( aRect ); + ImplValidate( &aRegion, nFlags ); + } +} + +// ----------------------------------------------------------------------- + +void Window::Validate( const Region& rRegion, USHORT nFlags ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) + return; + + if ( rRegion.IsNull() ) + ImplValidate( NULL, nFlags ); + else + { + Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) ); + if ( !aRegion.IsEmpty() ) + ImplValidate( &aRegion, nFlags ); + } +} + +// ----------------------------------------------------------------------- + +BOOL Window::HasPaintEvent() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !mbReallyVisible ) + return FALSE; + + if ( mpFrameWindow->mbPaintFrame ) + return TRUE; + + if ( mnPaintFlags & IMPL_PAINT_PAINT ) + return TRUE; + + if ( !ImplIsOverlapWindow() ) + { + const Window* pTempWindow = this; + do + { + pTempWindow = pTempWindow->ImplGetParent(); + if ( pTempWindow->mnPaintFlags & (IMPL_PAINT_PAINTCHILDS | IMPL_PAINT_PAINTALLCHILDS) ) + return TRUE; + } + while ( !pTempWindow->ImplIsOverlapWindow() ); + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Window::Update() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpBorderWindow ) + { + mpBorderWindow->Update(); + return; + } + + if ( !mbReallyVisible ) + return; + + BOOL bFlush = FALSE; + if ( mpFrameWindow->mbPaintFrame ) + { + Point aPoint( 0, 0 ); + Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) ); + ImplInvalidateOverlapFrameRegion( aRegion ); + if ( mbFrame || (mpBorderWindow && mpBorderWindow->mbFrame) ) + bFlush = TRUE; + } + + // Zuerst muessen wir alle Fenster ueberspringen, die Paint-Transparent + // sind + Window* pUpdateWindow = this; + Window* pWindow = pUpdateWindow; + while ( !pWindow->ImplIsOverlapWindow() ) + { + if ( !pWindow->mbPaintTransparent ) + { + pUpdateWindow = pWindow; + break; + } + pWindow = pWindow->ImplGetParent(); + } + // Ein Update wirkt immer auf das Window, wo PAINTALLCHILDS gesetzt + // ist, damit nicht zuviel gemalt wird + pWindow = pUpdateWindow; + do + { + if ( pWindow->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) + pUpdateWindow = pWindow; + if ( pWindow->ImplIsOverlapWindow() ) + break; + pWindow = pWindow->ImplGetParent(); + } + while ( pWindow ); + + // Wenn es etwas zu malen gibt, dann ein Paint ausloesen + if ( pUpdateWindow->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) ) + { + // und fuer alle ueber uns stehende System-Fenster auch ein Update + // ausloesen, damit nicht die ganze Zeit luecken stehen bleiben + Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpFirstOverlap; + while ( pUpdateOverlapWindow ) + { + pUpdateOverlapWindow->Update(); + pUpdateOverlapWindow = pUpdateOverlapWindow->mpNext; + } + + pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mnPaintFlags ); + } + + if ( bFlush ) + Flush(); +} + +// ----------------------------------------------------------------------- + +void Window::Flush() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + +#ifdef REMOTE_APPSERVER + // !!!!! +#else + mpFrame->Flush(); +#endif +} + +// ----------------------------------------------------------------------- + +void Window::Sync() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + +#ifdef REMOTE_APPSERVER + // Wir rufen eine syncrone Funktion, um uns zu syncronisieren + long nDummy; + mpFrame->GetClientSize( nDummy, nDummy ); +#else + mpFrame->Sync(); +#endif +} + +// ----------------------------------------------------------------------- + +void Window::SetUpdateMode( BOOL bUpdate ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + mbNoUpdate = !bUpdate; + StateChanged( STATE_CHANGE_UPDATEMODE ); +} + +// ----------------------------------------------------------------------- + +void Window::GrabFocus() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplGrabFocus( 0 ); +} + +// ----------------------------------------------------------------------- + +BOOL Window::HasFocus() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + return (this == ImplGetSVData()->maWinData.mpFocusWin); +} + +// ----------------------------------------------------------------------- + +BOOL Window::HasChildPathFocus( BOOL bSystemWindow ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Window* pWindow = ImplGetSVData()->maWinData.mpFocusWin; + if ( pWindow ) + return ImplIsWindowOrChild( pWindow, bSystemWindow ); + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Window::CaptureMouse() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplSVData* pSVData = ImplGetSVData(); + + // Tracking evt. beenden + if ( pSVData->maWinData.mpTrackWin != this ) + { + if ( pSVData->maWinData.mpTrackWin ) + pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL ); + } + + if ( pSVData->maWinData.mpCaptureWin != this ) + { + pSVData->maWinData.mpCaptureWin = this; + mpFrame->CaptureMouse( TRUE ); + } +} + +// ----------------------------------------------------------------------- + +void Window::ReleaseMouse() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + ImplSVData* pSVData = ImplGetSVData(); + + DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this, + "Window::ReleaseMouse(): window doesn't have the mouse capture" ); + + if ( pSVData->maWinData.mpCaptureWin == this ) + { + pSVData->maWinData.mpCaptureWin = NULL; + mpFrame->CaptureMouse( FALSE ); + ImplGenerateMouseMove(); + } +} + +// ----------------------------------------------------------------------- + +BOOL Window::IsMouseCaptured() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + return (this == ImplGetSVData()->maWinData.mpCaptureWin); +} + +// ----------------------------------------------------------------------- + +void Window::SetPointer( const Pointer& rPointer ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( maPointer == rPointer ) + return; + + maPointer = rPointer; + + // Pointer evt. direkt umsetzen + if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) + mpFrame->SetPointer( ImplGetMousePointer() ); +} + +// ----------------------------------------------------------------------- + +void Window::EnableChildPointerOverwrite( BOOL bOverwrite ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mbChildPtrOverwrite == bOverwrite ) + return; + + mbChildPtrOverwrite = bOverwrite; + + // Pointer evt. direkt umsetzen + if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) + mpFrame->SetPointer( ImplGetMousePointer() ); +} + +// ----------------------------------------------------------------------- + +void Window::SetPointerPosPixel( const Point& rPos ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Point aPos = ImplOutputToFrame( rPos ); + mpFrame->SetPointerPos( aPos.X(), aPos.Y() ); +} + +// ----------------------------------------------------------------------- + +Point Window::GetPointerPosPixel() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + return ImplFrameToOutput( Point( mpFrameData->mnLastMouseX, mpFrameData->mnLastMouseY ) ); +} + +// ----------------------------------------------------------------------- + +void Window::ShowPointer( BOOL bVisible ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mbNoPtrVisible != !bVisible ) + { + mbNoPtrVisible = !bVisible; + + // Pointer evt. direkt umsetzen + if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) + mpFrame->SetPointer( ImplGetMousePointer() ); + } +} + +// ----------------------------------------------------------------------- + +void Window::EnterWait() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + mnWaitCount++; + + if ( mnWaitCount == 1 ) + { + // Pointer evt. direkt umsetzen + if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) + mpFrame->SetPointer( ImplGetMousePointer() ); + } +} + +// ----------------------------------------------------------------------- + +void Window::LeaveWait() +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mnWaitCount ) + { + mnWaitCount--; + + if ( !mnWaitCount ) + { + // Pointer evt. direkt umsetzen + if ( !mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) + mpFrame->SetPointer( ImplGetMousePointer() ); + } + } +} + +// ----------------------------------------------------------------------- + +void Window::SetCursor( Cursor* pCursor ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( mpCursor != pCursor ) + { + if ( mpCursor ) + mpCursor->ImplHide(); + mpCursor = pCursor; + if ( pCursor ) + pCursor->ImplShow(); + } +} + +// ----------------------------------------------------------------------- + +void Window::SetText( const XubString& rStr ) +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + maText = rStr; + + if ( mpBorderWindow ) + mpBorderWindow->SetText( rStr ); + else if ( mbFrame ) + mpFrame->SetTitle( rStr ); + + StateChanged( STATE_CHANGE_TEXT ); +} + +// ----------------------------------------------------------------------- + +XubString Window::GetText() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + return maText; +} + +// ----------------------------------------------------------------------- + +const XubString& Window::GetHelpText() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + if ( !maHelpText.Len() && mnHelpId ) + { + if ( !IsDialog() && (mnType != WINDOW_TABPAGE) && (mnType != WINDOW_FLOATINGWINDOW) ) + { + Help* pHelp = Application::GetHelp(); + if ( pHelp ) + ((Window*)this)->maHelpText = pHelp->GetHelpText( GetHelpId() ); + } + } + + return maHelpText; +} + +// ----------------------------------------------------------------------- + +Window* Window::FindWindow( const Point& rPos ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + Point aPos = OutputToScreenPixel( rPos ); + return ((Window*)this)->ImplFindWindow( aPos ); +} + +// ----------------------------------------------------------------------- + +USHORT Window::GetChildCount() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + USHORT nChildCount = 0; + Window* pChild = mpFirstChild; + while ( pChild ) + { + nChildCount++; + pChild = pChild->mpNext; + } + + return nChildCount; +} + +// ----------------------------------------------------------------------- + +Window* Window::GetChild( USHORT nChild ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + USHORT nChildCount = 0; + Window* pChild = mpFirstChild; + while ( pChild ) + { + if ( nChild == nChildCount ) + return pChild; + pChild = pChild->mpNext; + nChildCount++; + } + + return NULL; +} + +// ----------------------------------------------------------------------- + +Window* Window::GetWindow( USHORT nType ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + + switch ( nType ) + { + case WINDOW_PARENT: + return mpRealParent; + + case WINDOW_FIRSTCHILD: + return mpFirstChild; + + case WINDOW_LASTCHILD: + return mpLastChild; + + case WINDOW_PREV: + return mpPrev; + + case WINDOW_NEXT: + return mpNext; + + case WINDOW_FIRSTOVERLAP: + return mpFirstOverlap; + + case WINDOW_LASTOVERLAP: + return mpLastOverlap; + + case WINDOW_OVERLAP: + if ( ImplIsOverlapWindow() ) + return (Window*)this; + else + return mpOverlapWindow; + + case WINDOW_PARENTOVERLAP: + if ( ImplIsOverlapWindow() ) + return mpOverlapWindow; + else + return mpOverlapWindow->mpOverlapWindow; + + case WINDOW_CLIENT: + return ((Window*)this)->ImplGetWindow(); + + case WINDOW_REALPARENT: + return ImplGetParent(); + + case WINDOW_FRAME: + return mpFrameWindow; + + case WINDOW_BORDER: + if ( mpBorderWindow ) + return mpBorderWindow->GetWindow( WINDOW_BORDER ); + return (Window*)this; + } + + return NULL; +} + +// ----------------------------------------------------------------------- + +BOOL Window::IsChild( const Window* pWindow, BOOL bSystemWindow ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow ); + + do + { + if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() ) + break; + + pWindow = pWindow->ImplGetParent(); + + if ( pWindow == this ) + return TRUE; + } + while ( pWindow ); + + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Window::IsWindowOrChild( const Window* pWindow, BOOL bSystemWindow ) const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow ); + + if ( this == pWindow ) + return TRUE; + return ImplIsChild( pWindow, bSystemWindow ); +} + +// ----------------------------------------------------------------------- + +const SystemEnvData* Window::GetSystemData() const +{ + DBG_CHKTHIS( Window, ImplDbgCheckWindow ); + +#ifndef REMOTE_APPSERVER + return mpFrame->GetSystemData(); +#else + return NULL; +#endif +} + +::com::sun::star::uno::Any Window::GetSystemDataAny() const +{ + ::com::sun::star::uno::Any aRet; + const SystemEnvData* pSysData = GetSystemData(); + if( pSysData ) + { + ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)pSysData, pSysData->nSize ); + aRet <<= aSeq; + } + return aRet; +} + +// ----------------------------------------------------------------------- + +void Window::SetWindowPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer, VCLXWindow* pVCLXWindow ) +{ + mxWindowPeer = xPeer; + mpVCLXWindow = pVCLXWindow; +} + +// ----------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( BOOL bCreate ) +{ + if ( !mxWindowPeer.is() && bCreate ) + { + UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); + if ( pWrapper ) + mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True ); + } + return mxWindowPeer; +} + +// ----------------------------------------------------------------------- + +void Window::SetComponentInterface( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xIFace ) +{ + UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); + DBG_ASSERT( pWrapper, "SetComponentInterface: No Wrapper!" ); + if ( pWrapper ) + pWrapper->SetWindowInterface( this, xIFace ); +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallDeactivateListeners( Window *pNew ) +{ + // Ich werde nicht deaktiviert, wenn das neu aktivierte Window ein Child von mir ist + if ( !pNew || !ImplIsChild( pNew ) ) + { + if ( mxWindowPeer.is() ) + Application::GetUnoWrapper()->WindowEvent_Activate( this, FALSE ); + if ( ImplGetParent() ) + ImplGetParent()->ImplCallDeactivateListeners( pNew ); + } +} + +// ----------------------------------------------------------------------- + +void Window::ImplCallActivateListeners( Window *pOld ) +{ + // Ich werde nicht aktiviert, wenn das alte aktive Fenster ein Child von mir ist + if ( !pOld || !ImplIsChild( pOld ) ) + { + if ( mxWindowPeer.is() ) + // Hier muss noch irgendwie pOld mitgeschickt werden! + Application::GetUnoWrapper()->WindowEvent_Activate( this, TRUE ); + if ( ImplGetParent() ) + ImplGetParent()->ImplCallActivateListeners( pOld ); + } +} |