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

8200 lines
256 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* $RCSfile: window.cxx,v $
*
* $Revision: 1.123 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: sb $ $Date: 2002-08-14 10:11:17 $
2000-09-18 16:07:07 +00:00
*
* 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
#include <unohelp.hxx>
2000-09-18 16:07:07 +00:00
#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
2002-07-12 14:50:22 +00:00
#ifndef _SV_WRKWIN_HXX
#include <wrkwin.hxx>
#endif
#ifndef _SV_WALL_HXX
#include <wall.hxx>
#endif
#ifndef _VCL_FONTCFG_HXX
#include <fontcfg.hxx>
#endif
2000-09-18 16:07:07 +00:00
#define SYSDATA_ONLY_BASETYPE
#include <sysdata.hxx>
2002-07-11 06:31:51 +00:00
#ifndef _SV_SALLAYOUT_HXX
#include <sallayout.hxx>
#endif
2000-09-18 16:07:07 +00:00
#include <com/sun/star/awt/XWindowPeer.hpp>
2001-02-09 14:59:18 +00:00
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGSOURCE_HPP_
#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDROPTARGET_HPP_
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
#endif
2001-02-19 08:18:59 +00:00
#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBOARD_XCLIPBOARD_HPP_
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_BRIDGE_XACCESSIBLETOPWINDOWMAP_HPP_
#include <drafts/com/sun/star/accessibility/bridge/XAccessibleTopWindowMap.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
#include <com/sun/star/awt/XTopWindow.hpp>
#endif
2001-02-09 14:59:18 +00:00
#ifndef _COM_SUN_STAR_AWT_XDISPLAYCONNECTION_HPP_
#include <com/sun/star/awt/XDisplayConnection.hpp>
#endif
2001-05-07 10:07:24 +00:00
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HDL_
#include <drafts/com/sun/star/accessibility/XAccessible.hpp>
#endif
2002-02-05 07:13:10 +00:00
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp>
#endif
2001-02-09 14:59:18 +00:00
2000-09-18 16:07:07 +00:00
#ifdef REMOTE_APPSERVER
#include "rmwindow.hxx"
#include "xevthdl.hxx"
#include "rmevents.hxx"
#include "rmoutdev.hxx"
2001-06-22 13:15:50 +00:00
#ifndef _ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
2002-07-12 14:50:22 +00:00
#include "com/sun/star/portal/client/XRmFrameWindow.hpp"
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
2000-09-18 16:07:07 +00:00
#endif
#include <unowrap.hxx>
2001-02-05 08:45:05 +00:00
#include <dndlcon.hxx>
2001-02-09 14:59:18 +00:00
#include <dndevdis.hxx>
#include <frameacc.hxx>
2000-09-18 16:07:07 +00:00
2000-09-18 16:07:07 +00:00
#pragma hdrstop
2001-02-09 14:59:18 +00:00
using namespace rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
2001-02-19 08:18:59 +00:00
using namespace ::com::sun::star::datatransfer::clipboard;
2001-02-09 14:59:18 +00:00
using namespace ::com::sun::star::datatransfer::dnd;
using namespace ::drafts::com::sun::star::accessibility::bridge;
using namespace com::sun;
2001-02-09 14:59:18 +00:00
using ::com::sun::star::awt::XTopWindow;
2000-09-18 16:07:07 +00:00
// =======================================================================
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;
};
2002-02-08 07:55:12 +00:00
struct ImplAccessibleInfos
{
USHORT nAccessibleRole;
String* pAccessibleName;
String* pAccessibleDescription;
ImplAccessibleInfos()
{
nAccessibleRole = 0xFFFF;
pAccessibleName = NULL;
pAccessibleDescription = NULL;
}
~ImplAccessibleInfos()
{
delete pAccessibleName;
delete pAccessibleDescription;
}
};
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
#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;
}
// -----------------------------------------------------------------------
2001-07-06 15:06:48 +00:00
void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, BOOL bCallHdl )
{
// Verify availability of the configured UI font, otherwise choose "Andale Sans UI"
String aUserInterfaceFont;
if ( !rSettings.GetStyleSettings().GetUseSystemUIFonts() )
{
String aConfigFont = vcl::DefaultFontConfigItem::get()->getUserInterfaceFont();
xub_StrLen nIndex = 0;
while( nIndex != STRING_NOTFOUND )
{
String aName( aConfigFont.GetToken( 0, ';', nIndex ) );
if ( aName.Len() && mpFrameData->mpFontList->FindFont (aName) )
{
aUserInterfaceFont = aConfigFont;
break;
}
}
if ( ! aUserInterfaceFont.Len() )
{
String aFallbackFont (RTL_CONSTASCII_USTRINGPARAM( "Andale Sans UI" ));
if ( mpFrameData->mpFontList->FindFont( aFallbackFont ) )
aUserInterfaceFont = aFallbackFont;
}
}
if ( !rSettings.GetStyleSettings().GetUseSystemUIFonts() && aUserInterfaceFont.Len() )
2001-07-06 15:06:48 +00:00
{
StyleSettings aStyleSettings = rSettings.GetStyleSettings();
Font aFont = aStyleSettings.GetAppFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetAppFont( aFont );
aFont = aStyleSettings.GetHelpFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetHelpFont( aFont );
aFont = aStyleSettings.GetTitleFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetTitleFont( aFont );
aFont = aStyleSettings.GetFloatTitleFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetFloatTitleFont( aFont );
aFont = aStyleSettings.GetMenuFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetMenuFont( aFont );
aFont = aStyleSettings.GetToolFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetToolFont( aFont );
aFont = aStyleSettings.GetLabelFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetLabelFont( aFont );
aFont = aStyleSettings.GetInfoFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetInfoFont( aFont );
aFont = aStyleSettings.GetRadioCheckFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetRadioCheckFont( aFont );
aFont = aStyleSettings.GetPushButtonFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetPushButtonFont( aFont );
aFont = aStyleSettings.GetFieldFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetFieldFont( aFont );
aFont = aStyleSettings.GetIconFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetIconFont( aFont );
aFont = aStyleSettings.GetGroupFont();
aFont.SetName( aUserInterfaceFont );
2001-07-06 15:06:48 +00:00
aStyleSettings.SetGroupFont( aFont );
rSettings.SetStyleSettings( aStyleSettings );
}
if( 1 )
{
// #97047: Force all fonts except Mneu and Help to a fixed height
// to avoid UI scaling due to large fonts
StyleSettings aStyleSettings = rSettings.GetStyleSettings();
Font aFont = aStyleSettings.GetAppFont();
aFont.SetHeight( 8 );
aStyleSettings.SetAppFont( aFont );
//aFont = aStyleSettings.GetHelpFont();
//aFont.SetHeight( 8 );
//aStyleSettings.SetHelpFont( aFont );
aFont = aStyleSettings.GetTitleFont();
aFont.SetHeight( 8 );
aStyleSettings.SetTitleFont( aFont );
aFont = aStyleSettings.GetFloatTitleFont();
aFont.SetHeight( 8 );
aStyleSettings.SetFloatTitleFont( aFont );
//aFont = aStyleSettings.GetMenuFont();
//aFont.SetHeight( 8 );
//aStyleSettings.SetMenuFont( aFont );
aFont = aStyleSettings.GetToolFont();
aFont.SetHeight( 8 );
aStyleSettings.SetToolFont( aFont );
aFont = aStyleSettings.GetLabelFont();
aFont.SetHeight( 8 );
aStyleSettings.SetLabelFont( aFont );
aFont = aStyleSettings.GetInfoFont();
aFont.SetHeight( 8 );
aStyleSettings.SetInfoFont( aFont );
aFont = aStyleSettings.GetRadioCheckFont();
aFont.SetHeight( 8 );
aStyleSettings.SetRadioCheckFont( aFont );
aFont = aStyleSettings.GetPushButtonFont();
aFont.SetHeight( 8 );
aStyleSettings.SetPushButtonFont( aFont );
aFont = aStyleSettings.GetFieldFont();
aFont.SetHeight( 8 );
aStyleSettings.SetFieldFont( aFont );
aFont = aStyleSettings.GetIconFont();
aFont.SetHeight( 8 );
aStyleSettings.SetIconFont( aFont );
aFont = aStyleSettings.GetGroupFont();
aFont.SetHeight( 8 );
aStyleSettings.SetGroupFont( aFont );
rSettings.SetStyleSettings( aStyleSettings );
}
2001-07-06 15:06:48 +00:00
#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 = rSettings.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 );
rSettings.SetStyleSettings( aStyleSettings );
}
#endif
2001-08-30 12:39:27 +00:00
if ( bCallHdl )
GetpApp()->SystemSettingsChanging( rSettings, this );
2001-07-06 15:06:48 +00:00
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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;
2002-02-14 16:13:26 +00:00
mpAccessibleInfos = NULL;
2000-09-18 16:07:07 +00:00
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
2002-07-11 06:31:51 +00:00
mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning
2000-09-18 16:07:07 +00:00
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
2001-07-06 15:06:48 +00:00
mnLockCount = 0; // LockCount
2000-09-18 16:07:07 +00:00
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
2002-03-21 17:35:44 +00:00
mbToolBox = FALSE; // TRUE: ToolBox is the base class
2002-06-10 14:41:22 +00:00
mbMenuFloatingWindow= FALSE; // TRUE: MenuFloatingWindow is the base class
2002-05-23 08:43:15 +00:00
mbSplitter = FALSE; // TRUE: Splitter is the base class
2000-09-18 16:07:07 +00:00
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;
2002-06-03 15:08:11 +00:00
mbSuppressAccessibilityEvents = FALSE; // TRUE: do not send any accessibility events
2000-09-18 16:07:07 +00:00
#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;
2000-09-18 16:07:07 +00:00
if ( nStyle & WB_CLOSEABLE )
nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE;
if ( nStyle & WB_APP )
nFrameStyle |= SAL_FRAME_STYLE_DEFAULT;
if( ! (nFrameStyle & ~SAL_FRAME_STYLE_CLOSEABLE) && // closeable only is ok, useful for undecorated floaters
( mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) )
)
2001-10-24 07:57:18 +00:00
nFrameStyle = SAL_FRAME_STYLE_FLOAT; // hmmm, was '0' before ????
else if( mbFloatWin )
nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW;
2000-09-18 16:07:07 +00:00
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 );
#else
if ( !(nStyle & WB_MOVEABLE) &&
(mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) ) )
2001-11-23 11:39:27 +00:00
nStyle = WB_SYSTEMFLOATWIN; // window corresponds to a float win on the server
2001-08-30 12:39:27 +00:00
2000-09-18 16:07:07 +00:00
RmFrameWindow* pParentFrame = pParent ? pParent->mpFrame : NULL;;
star::uno::Reference< star::portal::client::XRmFrameWindow >
xClientWindow;
star::uno::Any aToken;
if (!(aSystemWorkWindowToken >>= xClientWindow))
aToken = aSystemWorkWindowToken;
RmFrameWindow* pFrame = new RmFrameWindow(this, xClientWindow);
2000-09-18 16:07:07 +00:00
if ( !pFrame->IsValid() )
{
2001-08-30 12:39:27 +00:00
delete pFrame;
pFrame = NULL;
2000-09-18 16:07:07 +00:00
GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
}
else
{
pFrame->Create( nStyle, pFrame->GetEventHdlInterface(), GetAccessible()->getAccessibleContext(),
aToken,
2000-09-18 16:07:07 +00:00
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->maPaintTimer.SetTimeout( 30 );
mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
mpFrameData->mbInternalDragGestureRecognizer = FALSE;
2000-09-18 16:07:07 +00:00
}
// init data
mpRealParent = pRealParent;
// #99318: make sure fontcache and list is available before call to SetSettings
mpFontList = mpFrameData->mpFontList;
mpFontCache = mpFrameData->mpFontCache;
2000-09-18 16:07:07 +00:00
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 );
}
}
#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 );
}
}
#endif
2001-07-06 15:06:48 +00:00
#ifndef REMOTE_APPSERVER
// Muessen Application-Settings noch upgedatet werden
if ( !pSVData->maAppData.mbSettingsInit )
{
mpFrame->UpdateSettings( *pSVData->maAppData.mpSettings );
ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
pSVData->maAppData.mbSettingsInit = TRUE;
}
#endif
2000-09-18 16:07:07 +00:00
// 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 );
#ifndef REMOTE_APPSERVER
2002-06-14 07:53:51 +00:00
if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
{
// instanciate access bridge service
2002-06-14 07:53:51 +00:00
if( !pSVData->mxAccessBridge.is() )
{
2002-06-14 07:53:51 +00:00
if( !ImplInitAccessBridge() )
{
AllSettings aSettings = Application::GetSettings();
MiscSettings aMisc = aSettings.GetMiscSettings();
aMisc.SetEnableATToolSupport( FALSE );
aSettings.SetMiscSettings( aMisc );
Application::SetSettings( aSettings );
}
}
}
#endif
2000-09-18 16:07:07 +00:00
}
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;
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 );
2002-05-31 06:57:29 +00:00
if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() )
GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDCREATED, this );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void Window::ImplSetFrameParent( const Window* pParent )
{
2002-04-10 15:23:55 +00:00
Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
while( pFrameWindow )
{
2002-04-10 15:23:55 +00:00
if( ImplIsRealParentPath( pFrameWindow ) )
{
2002-04-10 15:23:55 +00:00
DBG_ASSERT( mpFrame != pFrameWindow->mpFrame, "SetFrameParent to own" );
DBG_ASSERT( mpFrame, "no frame" );
2002-04-08 15:58:38 +00:00
#ifndef REMOTE_APPSERVER
2002-04-10 15:23:55 +00:00
SalFrame* pParentFrame = pParent ? pParent->mpFrame : NULL;
pFrameWindow->mpFrame->SetParent( pParentFrame );
2002-04-08 15:58:38 +00:00
#else
2002-04-10 15:23:55 +00:00
RmFrameWindow* pParentFrame = pParent ? pParent->mpFrame : NULL;
pFrameWindow->mpFrame->SetParent( pParentFrame ? pParentFrame->GetFrameInterface() : REF( NMSP_CLIENT::XRmFrameWindow )() );
2002-04-08 15:58:38 +00:00
#endif
}
2002-04-10 15:23:55 +00:00
pFrameWindow = pFrameWindow->mpFrameData->mpNextFrame;
}
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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
}
}
// -----------------------------------------------------------------------
2001-09-04 04:59:33 +00:00
void Window::ImplCallResize()
{
mbCallResize = FALSE;
Resize();
// #88419# Most classes don't call the base class in Resize() and Move(),
// => Call ImpleResize/Move instead of Resize/Move directly...
ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE );
2001-09-04 04:59:33 +00:00
}
// -----------------------------------------------------------------------
void Window::ImplCallMove()
{
mbCallMove = FALSE;
Move();
ImplCallEventListeners( VCLEVENT_WINDOW_MOVE );
2001-09-04 04:59:33 +00:00
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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->mpExtOldText = NULL;
mpWinData->mpExtOldAttrAry = NULL;
2000-11-03 08:04:36 +00:00
mpWinData->mpCursorRect = 0;
mpWinData->mnCursorExtWidth = 0;
2000-09-18 16:07:07 +00:00
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( mpWinData && mbTrackVisible )
/* #98602# need to repaint all children within the
* tracking rectangle, so the following invert
* operation takes places without traces of the previous
* one.
*/
maInvalidateRegion.Union( *mpWinData->mpTrackRect );
2000-09-18 16:07:07 +00:00
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) );
}
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 ( mpWinData && mbTrackVisible && (mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
/* #98602# need to invert the tracking rect AFTER
* the children have painted
*/
InvertTracking( *(mpWinData->mpTrackRect), mpWinData->mnTrackFlags );
2000-09-18 16:07:07 +00:00
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;
2001-09-04 04:59:33 +00:00
2000-09-18 16:07:07 +00:00
if ( pWindow->IsVisible() )
{
2001-09-04 04:59:33 +00:00
pWindow->ImplCallMove();
2000-09-18 16:07:07 +00:00
}
else
2001-09-04 04:59:33 +00:00
{
2000-09-18 16:07:07 +00:00
pWindow->mbCallMove = TRUE;
2001-09-04 04:59:33 +00:00
}
2000-09-18 16:07:07 +00:00
}
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
// -----------------------------------------------------------------------
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 )
{
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 )
{
2002-07-11 06:31:51 +00:00
//if ( nX != mnX )
// --- RTL --- (compare the screen coordinates)
Point aPtDev( ImplLogicToDevicePixel( Point( nX, 0 ) ) );
2002-07-15 14:07:10 +00:00
#ifndef REMOTE_APPSERVER
2002-07-11 06:31:51 +00:00
if( ImplGetGraphics() && mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL )
((SalGraphicsLayout*)mpGraphics)->mirror( aPtDev.X() );
2002-07-15 14:07:10 +00:00
#endif //REMOTE_APPSERVER
2002-07-11 06:31:51 +00:00
if ( mnAbsScreenX != aPtDev.X() || nX != mnX )
2000-09-18 16:07:07 +00:00
{
if ( bCopyBits && !pOverlapRegion )
{
pOverlapRegion = new Region();
ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
Size( mnOutWidth, mnOutHeight ) ),
*pOverlapRegion, FALSE, TRUE, TRUE );
}
mnX = nX;
2002-07-11 06:31:51 +00:00
maPos.X() = nX;
mnAbsScreenX = aPtDev.X(); // --- RTL --- (store real screen pos)
2000-09-18 16:07:07 +00:00
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;
}
}
2001-10-24 07:57:18 +00:00
/* if ( nFlags & (WINDOW_POSSIZE_X|WINDOW_POSSIZE_Y) )
{
POINT aPt;
aPt.x = maPos.X();
aPt.y = maPos.Y();
ClientToScreen( mpFrame->maFrameData.mhWnd , &aPt );
maPos.X() = aPt.x;
maPos.Y() = aPt.y;
}
*/
2000-09-18 16:07:07 +00:00
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() )
{
2001-09-04 04:59:33 +00:00
mpClientWindow->ImplCallMove();
2000-09-18 16:07:07 +00:00
}
else
2001-09-04 04:59:33 +00:00
{
2000-09-18 16:07:07 +00:00
mpClientWindow->mbCallMove = TRUE;
2001-09-04 04:59:33 +00:00
}
2000-09-18 16:07:07 +00:00
}
}
else
{
if ( mpBorderWindow )
maPos = mpBorderWindow->maPos;
}
// Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor
// einem Show() kommt
if ( IsVisible() )
{
if ( bNewPos )
{
2001-09-04 04:59:33 +00:00
ImplCallMove();
2000-09-18 16:07:07 +00:00
}
if ( bNewSize )
{
2001-09-04 04:59:33 +00:00
ImplCallResize();
2000-09-18 16:07:07 +00:00
}
}
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
2001-11-23 11:39:27 +00:00
// do not bring floating windows on the client to top
if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
{
USHORT nSysFlags = 0;
if ( nFlags & TOTOP_RESTOREWHENMIN )
nSysFlags = SAL_FRAME_TOTOP_RESTOREWHENMIN;
if ( nFlags & TOTOP_FOREGROUNDTASK )
nSysFlags = SAL_FRAME_TOTOP_FOREGROUNDTASK;
mpFrame->ToTop( nSysFlags );
}
2000-09-18 16:07:07 +00:00
#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 )
{
if( pOldOverlapWindow->mbActive )
{
pOldOverlapWindow->mbActive = FALSE;
pOldOverlapWindow->Deactivate();
}
2000-09-18 16:07:07 +00:00
if ( pOldRealWindow != pOldOverlapWindow )
{
if( pOldRealWindow->mbActive )
{
pOldRealWindow->mbActive = FALSE;
pOldRealWindow->Deactivate();
}
2000-09-18 16:07:07 +00:00
}
}
if ( bCallActivate && ! pNewOverlapWindow->mbActive )
2000-09-18 16:07:07 +00:00
{
if( ! pNewOverlapWindow->mbActive )
{
pNewOverlapWindow->mbActive = TRUE;
pNewOverlapWindow->Activate();
}
2000-09-18 16:07:07 +00:00
if ( pNewRealWindow != pNewOverlapWindow )
{
if( ! pNewRealWindow->mbActive )
{
pNewRealWindow->mbActive = TRUE;
pNewRealWindow->Activate();
}
2000-09-18 16:07:07 +00:00
}
}
}
// -----------------------------------------------------------------------
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->IsInputEnabled() )
2000-09-18 16:07:07 +00:00
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->IsInputEnabled() )
2000-09-18 16:07:07 +00:00
{
mpLastFocusWindow->GrabFocus();
return;
}
}
// If the Windows is disabled, then we doesn't change the focus
if ( !IsEnabled() || !IsInputEnabled() )
return;
// we only need to set the focus if it is not already set
// note: if some other frame is waiting for an asynchrounous focus event
// we also have to post an asynchronous focus event for this frame
// which is done using ToTop
2000-09-18 16:07:07 +00:00
ImplSVData* pSVData = ImplGetSVData();
BOOL bAsyncFocusWaiting = FALSE;
Window *pFrame = pSVData->maWinData.mpFirstFrame;
while( pFrame )
{
if( pFrame != mpFrameWindow && pFrame->mpFrameData->mnFocusId )
{
bAsyncFocusWaiting = TRUE;
break;
}
pFrame = pFrame->mpFrameData->mpNextFrame;
}
BOOL bHasFocus = TRUE;
#ifndef REMOTE_APPSERVER
if ( !mpSysObj && !mpFrameData->mbHasFocus )
bHasFocus = FALSE;
#else
if ( !mpFrameData->mbHasFocus )
bHasFocus = FALSE;
#endif
BOOL bMustNotGrabFocus = FALSE;
// #100242#, check parent hierarchy if some floater prohibits grab focus
Window *pParent = mpParent;
while( pParent )
{
// #102158#, ignore grabfocus only if the floating parent grabs keyboard focus by itself (GrabsFocus())
// otherwise we cannot set the focus in a floating toolbox
if( ( (pParent->mbFloatWin && ((FloatingWindow*)pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) )
{
bMustNotGrabFocus = TRUE;
break;
}
pParent = pParent->mpParent;
}
if ( pSVData->maWinData.mpFocusWin != this || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
2000-09-18 16:07:07 +00:00
{
// EndExtTextInput if it is not the same window
if ( pSVData->maWinData.mpExtTextInputWin &&
(pSVData->maWinData.mpExtTextInputWin != this) )
pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
2000-09-18 16:07:07 +00:00
// Dieses Fenster als letztes FocusWindow merken
Window* pOverlapWindow = ImplGetFirstOverlapWindow();
pOverlapWindow->mpLastFocusWindow = this;
mpFrameData->mpFocusWin = this;
if( !bHasFocus )
2000-09-18 16:07:07 +00:00
{
2001-10-24 07:57:18 +00:00
// menue windows never get the system focus
// the application will keep the focus
if( bMustNotGrabFocus )
2001-10-24 07:57:18 +00:00
return;
else
{
// Hier setzen wir schon den Focus um, da ToTop() den Focus
// nicht auf ein anderes Fenster setzen darf
2002-04-18 14:11:18 +00:00
//DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
#ifndef REMOTE_APPSERVER
2002-04-15 11:50:03 +00:00
mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS );
#else
2002-04-16 10:31:03 +00:00
mpFrame->ToTop(0);
#endif
2001-10-24 07:57:18 +00:00
return;
}
2000-09-18 16:07:07 +00:00
}
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 );
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;
// if we're changing focus due to closing a popup floating window
// notify the new focus window so it can restore the inner focus
// eg, toolboxes can select their recent active item
if( pOldFocusWindow &&
( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) )
mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL;
2000-09-18 16:07:07 +00:00
NotifyEvent aNEvt( EVENT_GETFOCUS, this );
if ( !ImplCallPreNotify( aNEvt ) )
GetFocus();
ImplCallActivateListeners( pOldFocusWindow );
mnGetFocusFlags = 0;
mbInFocusHdl = FALSE;
}
}
GetpApp()->FocusChanged();
ImplNewInputContext();
}
}
// -----------------------------------------------------------------------
void Window::ImplNewInputContext()
{
2000-11-03 08:04:36 +00:00
ImplSVData* pSVData = ImplGetSVData();
Window* pFocusWin = pSVData->maWinData.mpFocusWin;
if ( !pFocusWin )
return;
// Is InputContext changed?
const InputContext& rInputContext = pFocusWin->GetInputContext();
if ( rInputContext == pFocusWin->mpFrameData->maOldInputContext )
return;
pFocusWin->mpFrameData->maOldInputContext = rInputContext;
2000-09-18 16:07:07 +00:00
#ifndef REMOTE_APPSERVER
SalInputContext aNewContext;
const Font& rFont = rInputContext.GetFont();
const XubString& rFontName = rFont.GetName();
ImplFontEntry* pFontEntry = NULL;
aNewContext.mpFont = NULL;
if ( rFontName.Len() )
{
Size aSize = pFocusWin->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*pFocusWin->mnDPIY)/72;
}
pFontEntry = pFocusWin->mpFontCache->Get( pFocusWin->mpFontList, rFont, aSize );
2000-11-03 08:04:36 +00:00
if ( pFontEntry )
aNewContext.mpFont = &pFontEntry->maFontSelData;
2000-11-03 08:04:36 +00:00
}
aNewContext.meLanguage = rFont.GetLanguage();
aNewContext.mnOptions = rInputContext.GetOptions();
pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
if ( pFontEntry )
pFocusWin->mpFontCache->Release( pFontEntry );
#else
2001-06-22 13:15:50 +00:00
const Font& rFont = rInputContext.GetFont();
pFocusWin->ImplGetFrame()->SetInputContext( rFont, rInputContext.GetOptions() );
2000-09-18 16:07:07 +00:00
#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 );
DBG_ASSERT( !mbInDtor, "~Window - already in DTOR!" );
2000-09-18 16:07:07 +00:00
mbInDtor = TRUE;
ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
// do not send child events for frames that were registered as native frames
2002-06-10 14:41:22 +00:00
if( !ImplIsAccessibleNativeFrame() )
if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED, this );
2001-02-05 08:45:05 +00:00
// shutdown drag and drop
::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xComponent( mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY );
if( xComponent.is() )
xComponent->dispose();
2002-06-10 14:41:22 +00:00
if( mbFrame && mpFrameData )
{
try
{
2002-06-10 14:41:22 +00:00
ImplRevokeAccessibleNativeFrame();
// deregister drop target listener
if( mpFrameData->mxDropTargetListener.is() )
{
OSL_TRACE( "removing drop target listener" );
Reference< XDragGestureRecognizer > xDragGestureRecognizer =
Reference< XDragGestureRecognizer > (mpFrameData->mxDragSource, UNO_QUERY);
if( xDragGestureRecognizer.is() )
{
xDragGestureRecognizer->removeDragGestureListener(
Reference< XDragGestureListener > (mpFrameData->mxDropTargetListener, UNO_QUERY));
}
mpFrameData->mxDropTarget->removeDropTargetListener( mpFrameData->mxDropTargetListener );
mpFrameData->mxDropTargetListener.clear();
}
// shutdown drag and drop for this frame window
Reference< XComponent > xComponent( mpFrameData->mxDropTarget, UNO_QUERY );
// DNDEventDispatcher does not hold a reference of the DropTarget,
// so it's ok if it does not support XComponent
if( xComponent.is() )
xComponent->dispose();
}
catch ( Exception exc )
{
// can be safely ignored here.
}
}
2000-09-18 16:07:07 +00:00
2001-03-15 10:33:48 +00:00
UnoWrapperBase* pWrapper = Application::GetUnoWrapper( FALSE );
2000-09-18 16:07:07 +00:00
if ( pWrapper )
pWrapper->WindowDestroyed( this );
// MT: Must be called after WindowDestroyed!
// Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
// But accessibility implementations from applications need this dispose.
if ( mxAccessible.is() )
{
::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xC( mxAccessible, ::com::sun::star::uno::UNO_QUERY );
if ( xC.is() )
xC->dispose();
}
2000-09-18 16:07:07 +00:00
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() );
}
bError = FALSE;
pTempWin = pSVData->maWinData.mpFirstFrame;
while ( pTempWin )
{
if ( ImplIsRealParentPath( pTempWin ) )
{
bError = TRUE;
if ( aErrorStr.Len() )
aErrorStr += "; ";
aErrorStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
}
pTempWin = pTempWin->mpFrameData->mpNextFrame;
}
if ( bError )
2000-09-18 16:07:07 +00:00
{
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 );
}
// EndExtTextInputMode
if ( pSVData->maWinData.mpExtTextInputWin == this )
{
EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
if ( pSVData->maWinData.mpExtTextInputWin == this )
pSVData->maWinData.mpExtTextInputWin = NULL;
}
2000-09-18 16:07:07 +00:00
// 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...
2001-03-20 09:36:58 +00:00
vos::OGuard aGuard( pSVData->mpWindowObjectMutex );
2000-09-18 16:07:07 +00:00
if ( mpRmEvents )
{
ExtRmEvent* p = mpRmEvents;
while ( p )
{
p->MarkInvalid();
p = p->GetNextWindowEvent();
}
}
}
#endif
if ( mbFrame )
{
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->mpExtOldText )
delete mpWinData->mpExtOldText;
if ( mpWinData->mpExtOldAttrAry )
delete mpWinData->mpExtOldAttrAry;
2000-11-03 08:04:36 +00:00
if ( mpWinData->mpCursorRect )
delete mpWinData->mpCursorRect;
2000-09-18 16:07:07 +00:00
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
2001-09-27 16:28:34 +00:00
REF( NMSP_CLIENT::XRmOutputDevice ) aTmp;
mpGraphics->SetInterface( aTmp );
2000-09-18 16:07:07 +00:00
delete mpFrame;
2001-06-18 07:54:03 +00:00
#endif
2000-09-18 16:07:07 +00:00
delete mpFrameData;
#ifdef REMOTE_APPSERVER
delete mpGraphics;
#endif
}
if ( mpChildClipRegion )
delete mpChildClipRegion;
2002-02-14 16:13:26 +00:00
delete mpAccessibleInfos;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
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 );
}
ImplCallEventListeners( VCLEVENT_WINDOW_PAINT, (void*)&rRect );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void Window::Draw( OutputDevice*, const Point&, const Size&, ULONG )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
// -----------------------------------------------------------------------
void Window::Move()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
// -----------------------------------------------------------------------
void Window::Resize()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
// -----------------------------------------------------------------------
void Window::Activate()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
// -----------------------------------------------------------------------
void Window::Deactivate()
{
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 )
2001-04-20 06:37:03 +00:00
pHelp->Start( nStartHelpId, this );
2000-09-18 16:07:07 +00:00
}
}
}
// -----------------------------------------------------------------------
void Window::Command( const CommandEvent& rCEvt )
{
{ // Klammerung, da in diesem Handler das Window zerstoert werden darf
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE, (void*)&rCEvt );
2000-09-18 16:07:07 +00:00
NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt );
if ( !Notify( aNEvt ) )
mbCommand = TRUE;
}
// -----------------------------------------------------------------------
void Window::Tracking( const TrackingEvent& )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
// -----------------------------------------------------------------------
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 );
}
2000-11-24 17:51:54 +00:00
long bDone = FALSE;
2000-09-18 16:07:07 +00:00
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 ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
2000-09-18 16:07:07 +00:00
}
else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
BOOL bCompoundFocusChanged = FALSE;
if ( mbCompoundControl && mbCompoundControlHasFocus && !HasChildPathFocus() )
{
mbCompoundControlHasFocus = FALSE ;
bCompoundFocusChanged = TRUE;
}
if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
2000-09-18 16:07:07 +00:00
}
else if( rNEvt.GetType() == EVENT_MOUSEMOVE )
{
if ( mbCompoundControl || ( rNEvt.GetWindow() == this ) )
2000-09-18 16:07:07 +00:00
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
2000-09-18 16:07:07 +00:00
else
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
2000-09-18 16:07:07 +00:00
}
}
else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
{
if ( mbCompoundControl || ( rNEvt.GetWindow() == this ) )
2000-09-18 16:07:07 +00:00
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
2000-09-18 16:07:07 +00:00
else
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
2000-09-18 16:07:07 +00:00
}
}
else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
{
if ( mbCompoundControl || ( rNEvt.GetWindow() == this ) )
2000-09-18 16:07:07 +00:00
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
2000-09-18 16:07:07 +00:00
else
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
2000-09-18 16:07:07 +00:00
}
}
else if( rNEvt.GetType() == EVENT_KEYINPUT )
{
if ( mbCompoundControl || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
2000-09-18 16:07:07 +00:00
}
else if( rNEvt.GetType() == EVENT_KEYUP )
{
if ( mbCompoundControl || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
2000-09-18 16:07:07 +00:00
}
}
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;
}
// -----------------------------------------------------------------------
void Window::ImplCallEventListeners( ULONG nEvent, void* pData )
{
VclWindowEvent aEvent( this, nEvent, pData );
ImplSVData* pSVData = ImplGetSVData();
pSVData->mpApp->ImplCallEventListeners( &aEvent );
2002-02-14 16:13:26 +00:00
if ( !maEventListeners.empty() )
maEventListeners.Call( &aEvent );
Window* pWindow = this;
while ( pWindow )
{
2002-02-14 16:13:26 +00:00
if ( !pWindow->maChildEventListeners.empty() )
pWindow->maChildEventListeners.Call( &aEvent );
pWindow = pWindow->GetParent();
}
}
// -----------------------------------------------------------------------
void Window::AddEventListener( const Link& rEventListener )
{
2002-02-14 16:13:26 +00:00
maEventListeners.push_back( rEventListener );
}
// -----------------------------------------------------------------------
void Window::RemoveEventListener( const Link& rEventListener )
{
2002-02-14 16:13:26 +00:00
maEventListeners.remove( rEventListener );
}
// -----------------------------------------------------------------------
void Window::AddChildEventListener( const Link& rEventListener )
{
2002-02-14 16:13:26 +00:00
maChildEventListeners.push_back( rEventListener );
}
// -----------------------------------------------------------------------
void Window::RemoveChildEventListener( const Link& rEventListener )
{
2002-02-14 16:13:26 +00:00
maChildEventListeners.remove( rEventListener );
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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 );
}
// -----------------------------------------------------------------------
2001-07-06 15:06:48 +00:00
2001-08-30 12:39:27 +00:00
BOOL Window::IsLocked( BOOL bChilds ) const
2001-07-06 15:06:48 +00:00
{
2001-08-30 12:39:27 +00:00
if ( mnLockCount != 0 )
return TRUE;
if ( bChilds || mbChildNotify )
{
Window* pChild = mpFirstChild;
while ( pChild )
{
if ( pChild->IsLocked( TRUE ) )
return TRUE;
pChild = pChild->mpNext;
}
}
return FALSE;
2001-07-06 15:06:48 +00:00
}
// -----------------------------------------------------------------------
BOOL Window::IsUICaptured( BOOL bChilds ) const
{
return Application::IsUICaptured();
}
// -----------------------------------------------------------------------
BOOL Window::IsUserActive( USHORT nTest, BOOL bChilds ) const
{
return Application::IsUserActive( nTest );
}
// -----------------------------------------------------------------------
ULONG Window::GetLastInputInterval() const
{
return Application::GetLastInputInterval();
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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::EndExtTextInput( USHORT nFlags )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mbExtTextInput )
ImplGetFrame()->EndExtTextInput( nFlags );
}
// -----------------------------------------------------------------------
2000-11-03 08:04:36 +00:00
void Window::SetCursorRect( const Rectangle* pRect, long nExtTextInputWidth )
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplWinData* pWinData = ImplGetWinData();
2000-11-03 08:04:36 +00:00
if ( pWinData->mpCursorRect )
2000-09-18 16:07:07 +00:00
{
2000-11-03 08:04:36 +00:00
if ( pRect )
*pWinData->mpCursorRect = *pRect;
else
{
delete pWinData->mpCursorRect;
pWinData->mpCursorRect = NULL;
}
2000-09-18 16:07:07 +00:00
}
else
2000-11-03 08:04:36 +00:00
{
if ( pRect )
pWinData->mpCursorRect = new Rectangle( *pRect );
}
pWinData->mnCursorExtWidth = nExtTextInputWidth;
#ifdef REMOTE_APPSERVER
// update remote cursor pos
ImplUpdateCursorRect( this );
#endif
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2000-11-03 08:04:36 +00:00
const Rectangle* Window::GetCursorRect() const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplWinData* pWinData = ImplGetWinData();
2000-11-03 08:04:36 +00:00
return pWinData->mpCursorRect;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2000-11-03 08:04:36 +00:00
long Window::GetCursorExtTextInputWidth() const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplWinData* pWinData = ImplGetWinData();
2000-11-03 08:04:36 +00:00
return pWinData->mnCursorExtWidth;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
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 );
2001-08-30 12:39:27 +00:00
// AppFont-Aufloesung und DPI-Aufloesung neu berechnen
ImplInitResolutionSettings();
2000-09-18 16:07:07 +00:00
if ( nChangeFlags )
{
DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
DataChanged( aDCEvt );
}
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 );
2001-08-30 12:39:27 +00:00
// AppFont-Aufloesung und DPI-Aufloesung neu berechnen
ImplInitResolutionSettings();
2000-09-18 16:07:07 +00:00
if ( nChangeFlags )
{
DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
DataChanged( aDCEvt );
}
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" );
ImplSetFrameParent( pNewParent );
2000-09-18 16:07:07 +00:00
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 );
BOOL bNativeFrameRegistered = FALSE;
2000-09-18 16:07:07 +00:00
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 )
2002-06-03 15:08:11 +00:00
{
mbSuppressAccessibilityEvents = TRUE;
2002-07-18 14:18:11 +00:00
mpFrame->Show( FALSE, FALSE );
2002-06-03 15:08:11 +00:00
}
2000-09-18 16:07:07 +00:00
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 )
{
2001-09-04 04:59:33 +00:00
ImplCallMove();
2000-09-18 16:07:07 +00:00
}
if ( mbCallResize )
{
2001-09-04 04:59:33 +00:00
ImplCallResize();
2000-09-18 16:07:07 +00:00
}
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 )
{
//DBG_ASSERT( !mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated");
2002-06-03 15:08:11 +00:00
mbSuppressAccessibilityEvents = FALSE;
2000-09-18 16:07:07 +00:00
mbPaintFrame = TRUE;
2002-07-16 08:04:37 +00:00
BOOL bNoActivate = nFlags & (SHOW_NOACTIVATE|SHOW_NOFOCUSCHANGE);
mpFrame->Show( TRUE, bNoActivate );
2000-09-18 16:07:07 +00:00
// 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
2001-12-14 12:57:53 +00:00
if ( IsDialog() || (GetType() == WINDOW_TABPAGE) || (GetType() == WINDOW_DOCKINGWINDOW) )
2000-09-18 16:07:07 +00:00
{
DBG_DIALOGTEST( this );
}
#endif
ImplShowAllOverlaps();
#ifndef REMOTE_APPSERVER
// filter system windows that are accessible over the Accessibility API anyway
2002-06-10 14:41:22 +00:00
if( ImplIsAccessibleNativeFrame() )
bNativeFrameRegistered = ImplRegisterAccessibleNativeFrame();
#endif
2000-09-18 16:07:07 +00:00
}
// Hintergrund-Sicherung zuruecksetzen
if ( mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
2002-05-31 06:57:29 +00:00
// the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
// to avoid creation event to be send twice a NULL handle is passed if this (frame)window was already registered
2002-06-10 14:41:22 +00:00
// a NULL handle is also passed if:
// the window is hidden
// the window is not really visible (ie, all parents must be visible)
2002-05-31 06:57:29 +00:00
ImplCallEventListeners( mbVisible ? VCLEVENT_WINDOW_SHOW : VCLEVENT_WINDOW_HIDE,
2002-06-10 14:41:22 +00:00
( bNativeFrameRegistered || !ImplIsAccessibleCandidate() || !bVisible || !mbReallyVisible ) ? NULL : this );
}
// -----------------------------------------------------------------------
Size Window::GetSizePixel() const
{
return Size( mnOutWidth+mnLeftBorder+mnRightBorder,
mnOutHeight+mnTopBorder+mnBottomBorder );
}
void Window::GetBorder( long& rLeftBorder, long& rTopBorder,
long& rRightBorder, long& rBottomBorder ) const
{
rLeftBorder = mnLeftBorder;
rTopBorder = mnTopBorder;
rRightBorder = mnRightBorder;
rBottomBorder = mnBottomBorder;
}
2002-06-10 14:41:22 +00:00
// -----------------------------------------------------------------------
BOOL Window::ImplRegisterAccessibleNativeFrame()
{
BOOL bNativeFrameRegistered = FALSE;
#ifndef REMOTE_APPSERVER
ImplSVData* pSVData = ImplGetSVData();
// register proxy accessible for the new native frame window
if(pSVData->mxAccessBridge.is())
{
const SystemEnvData * pEnvData = GetSystemData();
if(pEnvData)
{
Reference< XTopWindow > xTopWindow( ImplGetWindow()->GetComponentInterface(), UNO_QUERY );
if(xTopWindow.is())
{
#ifdef WNT
pSVData->mxAccessBridge->registerAccessibleNativeFrame( makeAny((sal_uInt32) pEnvData->hWnd), GetAccessible(), xTopWindow);
#else
pSVData->mxAccessBridge->registerAccessibleNativeFrame( makeAny((sal_uInt32) pEnvData->aWindow), GetAccessible(), xTopWindow);
#endif
bNativeFrameRegistered = TRUE;
mbSuppressAccessibilityEvents = FALSE; // allow accessibility events
}
}
}
#endif
return bNativeFrameRegistered;
}
void Window::ImplRevokeAccessibleNativeFrame()
{
#ifndef REMOTE_APPSERVER
const SystemEnvData * pEnvData = GetSystemData();
ImplSVData* pSVData = ImplGetSVData();
// revoke native frame from access bridge
if(pEnvData && pSVData)
{
mbSuppressAccessibilityEvents = TRUE; // avoid further accessibility events
if( pSVData->mxAccessBridge.is() )
{
#ifdef WNT
pSVData->mxAccessBridge->revokeAccessibleNativeFrame(makeAny((sal_uInt32) pEnvData->hWnd));
#else
pSVData->mxAccessBridge->revokeAccessibleNativeFrame(makeAny((sal_uInt32) pEnvData->aWindow));
#endif
}
}
#endif
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
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 );
ImplCallEventListeners( bEnable ? VCLEVENT_WINDOW_ENABLED : VCLEVENT_WINDOW_DISABLED );
2000-09-18 16:07:07 +00:00
}
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;
}
// enable/disable floating system windows as well
Window* pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
while ( pFrameWin )
{
if( pFrameWin->ImplIsFloatingWindow() )
{
// Is Window in the path from this window
if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, TRUE ) )
{
// Is Window not in the exclude window path or not the
// exclude window, than change the status
if ( !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, TRUE ) )
pFrameWin->EnableInput( bEnable, bChild );
}
}
pFrameWin = pFrameWin->mpFrameData->mpNextFrame;
}
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
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 )
{
2001-10-24 07:57:18 +00:00
if ( !(nFlags & WINDOW_POSSIZE_WIDTH) )
nWidth = pWindow->mnOutWidth;
if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) )
nHeight = pWindow->mnOutHeight;
long nOldWidth = pWindow->mnOutWidth;
long nOldHeight = pWindow->mnOutHeight;
2001-10-24 09:24:19 +00:00
#ifndef REMOTE_APPSERVER
2001-10-24 07:57:18 +00:00
USHORT nSysFlags=0;
if( nFlags & WINDOW_POSSIZE_WIDTH )
nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
if( nFlags & WINDOW_POSSIZE_HEIGHT )
nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
if( nFlags & WINDOW_POSSIZE_X )
nSysFlags |= SAL_FRAME_POSSIZE_X;
if( nFlags & WINDOW_POSSIZE_Y )
nSysFlags |= SAL_FRAME_POSSIZE_Y;
pWindow->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
2001-10-24 09:24:19 +00:00
#else
2001-11-23 11:39:27 +00:00
pWindow->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nFlags );
2001-10-24 09:24:19 +00:00
#endif
2001-10-24 07:57:18 +00:00
// 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 large.
ImplHandleResize( pWindow, nWidth, nHeight );
2000-09-18 16:07:07 +00:00
}
else
{
pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
if ( IsReallyVisible() )
ImplGenerateMouseMove();
}
}
// -----------------------------------------------------------------------
2002-01-15 10:44:59 +00:00
Point Window::GetPosPixel() const
{
2002-04-18 17:11:00 +00:00
return maPos;
2002-01-15 10:44:59 +00:00
}
// -----------------------------------------------------------------------
Rectangle Window::GetDesktopRectPixel() const
{
Rectangle rRect;
mpFrameWindow->mpFrame->GetWorkArea( rRect );
return rRect;
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
Point Window::OutputToScreenPixel( const Point& rPos ) const
{
2001-10-24 07:57:18 +00:00
// relative to top level parent
2000-09-18 16:07:07 +00:00
return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
}
// -----------------------------------------------------------------------
Point Window::ScreenToOutputPixel( const Point& rPos ) const
{
2001-10-24 07:57:18 +00:00
// relative to top level parent
2000-09-18 16:07:07 +00:00
return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
}
// -----------------------------------------------------------------------
2001-10-24 07:57:18 +00:00
Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
{
// relative to the screen
Point p = OutputToScreenPixel( rPos );
2001-11-23 11:39:27 +00:00
SalFrameGeometry g = mpFrame->GetGeometry();
2001-10-24 07:57:18 +00:00
p.X() += g.nX;
p.Y() += g.nY;
return p;
}
// -----------------------------------------------------------------------
Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const
{
// relative to the screen
Point p = ScreenToOutputPixel( rPos );
2001-11-23 11:39:27 +00:00
SalFrameGeometry g = mpFrame->GetGeometry();
2001-10-24 07:57:18 +00:00
p.X() -= g.nX;
p.Y() -= g.nY;
return p;
}
// -----------------------------------------------------------------------
Rectangle Window::GetWindowExtentsRelative( Window *pRelativeWindow )
{
2001-11-23 11:39:27 +00:00
SalFrameGeometry g = mpFrame->GetGeometry();
Point aPos( OutputToScreenPixel( Point(0,0) ) );
aPos.X() += g.nX;
aPos.Y() += g.nY;
Size aSize ( GetSizePixel() );
if( mbFrame || (mpBorderWindow && mpBorderWindow->mbFrame) )
{
aPos.X() -= g.nLeftDecoration;
aPos.Y() -= g.nTopDecoration;
aSize.Width() += g.nLeftDecoration + g.nRightDecoration;
aSize.Height() += g.nTopDecoration + g.nBottomDecoration;
}
if( pRelativeWindow )
aPos = pRelativeWindow->AbsoluteScreenToOutputPixel( aPos );
return Rectangle( aPos, aSize );
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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);
}
// -----------------------------------------------------------------------
2002-05-06 12:15:07 +00:00
void Window::GrabFocusToDocument()
{
Window *pWin = this;
while( pWin )
{
if( !pWin->GetParent() )
{
pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
return;
}
pWin = pWin->GetParent();
}
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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() );
}
}
// -----------------------------------------------------------------------
ULONG Window::GetCurrentModButtons()
{
return mpFrame ? mpFrame->GetCurrentModButtons() : 0;
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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 );
2002-06-03 15:08:11 +00:00
String oldTitle( maText );
2000-09-18 16:07:07 +00:00
maText = rStr;
if ( mpBorderWindow )
mpBorderWindow->SetText( rStr );
else if ( mbFrame )
mpFrame->SetTitle( rStr );
ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
2000-09-18 16:07:07 +00:00
StateChanged( STATE_CHANGE_TEXT );
}
// -----------------------------------------------------------------------
String Window::GetText() const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
return maText;
}
// -----------------------------------------------------------------------
String Window::GetDisplayText() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
return GetText();
}
// -----------------------------------------------------------------------
const Wallpaper& Window::GetDisplayBackground() const
{
if( !IsBackground() )
{
if( mpParent )
return mpParent->GetDisplayBackground();
}
const Wallpaper& rBack = GetBackground();
if( ! rBack.IsBitmap() &&
! rBack.IsGradient() &&
rBack.GetColor().GetColor() == COL_TRANSPARENT &&
mpParent )
return mpParent->GetDisplayBackground();
return rBack;
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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 )
2001-04-12 08:49:41 +00:00
((Window*)this)->maHelpText = pHelp->GetHelpText( GetHelpId(), this );
2000-09-18 16:07:07 +00:00
}
}
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
2001-02-05 08:45:05 +00:00
return mpFrame ? mpFrame->GetSystemData() : NULL;
2000-09-18 16:07:07 +00:00
#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 )
{
// no deactivation if the the newly activated window is my child
2000-09-18 16:07:07 +00:00
if ( !pNew || !ImplIsChild( pNew ) )
{
ImplCallEventListeners( VCLEVENT_WINDOW_DEACTIVATE );
// #100759#, avoid walking the wrong frame's hierarchy
// eg, undocked docking windows (ImplDockFloatWin)
if ( ImplGetParent() && mpFrameWindow == ImplGetParent()->mpFrameWindow )
2000-09-18 16:07:07 +00:00
ImplGetParent()->ImplCallDeactivateListeners( pNew );
}
}
// -----------------------------------------------------------------------
void Window::ImplCallActivateListeners( Window *pOld )
{
// no activation if the the old active window is my child
2000-09-18 16:07:07 +00:00
if ( !pOld || !ImplIsChild( pOld ) )
{
ImplCallEventListeners( VCLEVENT_WINDOW_ACTIVATE, pOld );
// #100759#, avoid walking the wrong frame's hierarchy
// eg, undocked docking windows (ImplDockFloatWin)
if ( ImplGetParent() && mpFrameWindow == ImplGetParent()->mpFrameWindow )
2000-09-18 16:07:07 +00:00
ImplGetParent()->ImplCallActivateListeners( pOld );
}
}
2001-02-05 08:45:05 +00:00
// -----------------------------------------------------------------------
2001-02-09 14:59:18 +00:00
Reference< XDropTarget > Window::GetDropTarget()
2001-02-05 08:45:05 +00:00
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( ! mxDNDListenerContainer.is() )
2001-02-09 14:59:18 +00:00
{
2001-02-13 12:12:53 +00:00
sal_Int8 nDefaultActions = 0;
2001-02-09 14:59:18 +00:00
if( mpFrameData )
{
if( ! mpFrameData->mxDropTarget.is() )
{
// initialization is done in GetDragSource
Reference< XDragSource > xDragSource = GetDragSource();
}
2001-02-09 14:59:18 +00:00
if( mpFrameData->mxDropTarget.is() )
{
nDefaultActions = mpFrameData->mxDropTarget->getDefaultActions();
if( ! mpFrameData->mxDropTargetListener.is() )
{
mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpFrameWindow );
try
{
// OSL_TRACE( "adding droptarget listener" );
mpFrameData->mxDropTarget->addDropTargetListener( mpFrameData->mxDropTargetListener );
// register also as drag gesture listener if directly supported by drag source
Reference< XDragGestureRecognizer > xDragGestureRecognizer =
Reference< XDragGestureRecognizer > (mpFrameData->mxDragSource, UNO_QUERY);
if( xDragGestureRecognizer.is() )
{
xDragGestureRecognizer->addDragGestureListener(
Reference< XDragGestureListener > (mpFrameData->mxDropTargetListener, UNO_QUERY));
}
else
mpFrameData->mbInternalDragGestureRecognizer = TRUE;
}
catch( RuntimeException exc )
{
// release all instances
mpFrameData->mxDropTarget.clear();
mpFrameData->mxDragSource.clear();
}
}
}
}
2001-02-09 14:59:18 +00:00
mxDNDListenerContainer = static_cast < XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
}
2001-02-05 08:45:05 +00:00
// this object is located in the same process, so there will be no runtime exception
2001-02-09 14:59:18 +00:00
return Reference< XDropTarget > ( mxDNDListenerContainer, UNO_QUERY );
2001-02-05 08:45:05 +00:00
}
// -----------------------------------------------------------------------
2001-02-09 14:59:18 +00:00
Reference< XDragSource > Window::GetDragSource()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( mpFrameData )
{
if( ! mpFrameData->mxDragSource.is() )
{
try
{
#ifdef REMOTE_APPSERVER
if ( mpFrame->IsValid() )
mpFrame->GetDragSourceDropTarget( mpFrameData->mxDragSource, mpFrameData->mxDropTarget );
#else
Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
if ( xFactory.is() )
{
const SystemEnvData * pEnvData = GetSystemData();
if( pEnvData )
{
Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
OUString aDragSourceSN, aDropTargetSN;
#if defined WNT
aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" );
aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" );
aDragSourceAL[ 1 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
aDropTargetAL[ 0 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
#elif defined UNX
aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DragSource" );
aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DropTarget" );
aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
aDropTargetAL[ 1 ] = makeAny( pEnvData->aShellWindow );
#endif
if( aDragSourceSN.getLength() )
mpFrameData->mxDragSource = Reference< XDragSource > ( xFactory->createInstanceWithArguments( aDragSourceSN, aDragSourceAL ), UNO_QUERY );
if( aDropTargetSN.getLength() )
mpFrameData->mxDropTarget = Reference< XDropTarget > ( xFactory->createInstanceWithArguments( aDropTargetSN, aDropTargetAL ), UNO_QUERY );
}
}
#endif
}
// createInstance can throw any exception
catch( Exception exc )
{
// release all instances
mpFrameData->mxDropTarget.clear();
mpFrameData->mxDragSource.clear();
}
}
return mpFrameData->mxDragSource;
}
return Reference< XDragSource > ();
2001-02-09 14:59:18 +00:00
}
// -----------------------------------------------------------------------
void Window::GetDragSourceDropTarget(Reference< XDragSource >& xDragSource, Reference< XDropTarget > &xDropTarget )
// only for RVP transmission
2001-02-05 08:45:05 +00:00
{
if( mpFrameData )
2001-02-09 14:59:18 +00:00
{
// initialization is done in GetDragSource
xDragSource = GetDragSource();
xDropTarget = mpFrameData->mxDropTarget;
2001-02-09 14:59:18 +00:00
}
else
{
xDragSource.clear();
xDropTarget.clear();
}
}
2001-02-05 08:45:05 +00:00
// -----------------------------------------------------------------------
Reference< XDragGestureRecognizer > Window::GetDragGestureRecognizer()
{
return Reference< XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
2001-02-05 08:45:05 +00:00
}
2001-02-19 08:18:59 +00:00
// -----------------------------------------------------------------------
Reference< XClipboard > Window::GetClipboard()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( mpFrameData )
{
if( ! mpFrameData->mxClipboard.is() )
{
try
{
#ifdef REMOTE_APPSERVER
if ( mpFrame->IsValid() )
mpFrame->GetFrameInterface()->GetClipboardAndSelection( mpFrameData->mxClipboard, mpFrameData->mxSelection );
#else
Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
if( xFactory.is() )
{
mpFrameData->mxClipboard = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY );
#ifdef UNX // unix clipboard needs to be initialized
if( mpFrameData->mxClipboard.is() )
{
Reference< XInitialization > xInit = Reference< XInitialization >( mpFrameData->mxClipboard, UNO_QUERY );
if( xInit.is() )
{
Sequence< Any > aArgumentList( 2 );
aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "CLIPBOARD" ) );
xInit->initialize( aArgumentList );
}
}
#endif
}
#endif
}
// createInstance can throw any exception
catch( Exception exc )
{
// release all instances
mpFrameData->mxClipboard.clear();
}
}
2001-02-19 08:18:59 +00:00
return mpFrameData->mxClipboard;
}
2001-02-19 08:18:59 +00:00
return static_cast < XClipboard * > (0);
}
// -----------------------------------------------------------------------
Reference< XClipboard > Window::GetSelection()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( mpFrameData )
{
if( ! mpFrameData->mxSelection.is() )
{
try
{
#ifdef REMOTE_APPSERVER
if ( mpFrame->IsValid() )
mpFrame->GetFrameInterface()->GetClipboardAndSelection( mpFrameData->mxClipboard, mpFrameData->mxSelection );
#else
Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
if( xFactory.is() )
{
# ifdef UNX
Sequence< Any > aArgumentList( 2 );
aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "PRIMARY" ) );
mpFrameData->mxSelection = Reference< XClipboard >( xFactory->createInstanceWithArguments(
OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ), aArgumentList ), UNO_QUERY );
# else
static Reference< XClipboard > s_xSelection;
if ( !s_xSelection.is() )
s_xSelection = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ) ), UNO_QUERY );
mpFrameData->mxSelection = s_xSelection;
# endif
}
#endif
}
// createInstance can throw any exception
catch( Exception exc )
{
// release all instances
mpFrameData->mxSelection.clear();
}
}
2001-02-19 08:18:59 +00:00
return mpFrameData->mxSelection;
}
2001-02-19 08:18:59 +00:00
return static_cast < XClipboard * > (0);
}
2002-07-12 14:50:22 +00:00
// -----------------------------------------------------------------------
// Accessibility
// -----------------------------------------------------------------------
::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > Window::GetAccessible( BOOL bCreate )
{
// do not optimize hierarchy for the top level border win (ie, when there is no parent)
/* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy
if ( GetParent() && ( GetType() == WINDOW_BORDERWINDOW ) && ( GetChildCount() == 1 ) )
2002-05-31 06:57:29 +00:00
//if( !ImplIsAccessibleCandidate() )
2002-02-08 07:55:12 +00:00
{
Window* pChild = GetAccessibleChildWindow( 0 );
if ( pChild )
return pChild->GetAccessible();
}
*/
if ( !mxAccessible.is() && bCreate )
mxAccessible = CreateAccessible();
return mxAccessible;
}
::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
{
::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( TRUE ), ::com::sun::star::uno::UNO_QUERY );
return xAcc;
}
void Window::SetAccessible( ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > x )
{
mxAccessible = x;
}
2002-02-05 07:13:10 +00:00
// skip all border windows that are no top level frames
BOOL Window::ImplIsAccessibleCandidate() const
2002-02-05 07:13:10 +00:00
{
if( !mbBorderWin )
return TRUE;
else
if( mbFrame && mnStyle & (WB_MOVEABLE | WB_CLOSEABLE | WB_SIZEABLE) )
return TRUE;
else
return FALSE;
}
2002-06-10 14:41:22 +00:00
BOOL Window::ImplIsAccessibleNativeFrame() const
{
if( mbFrame )
if( (mnStyle & (WB_MOVEABLE | WB_CLOSEABLE | WB_SIZEABLE)) )
return TRUE;
else
return FALSE;
else
return FALSE;
}
USHORT Window::ImplGetAccessibleCandidateChildWindowCount( USHORT nFirstWindowType ) const
{
USHORT nChildren = 0;
Window* pChild = GetWindow( nFirstWindowType );
while ( pChild )
2002-02-05 07:13:10 +00:00
{
if( pChild->ImplIsAccessibleCandidate() )
nChildren++;
else
nChildren += pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD );
pChild = pChild->mpNext;
2002-02-05 07:13:10 +00:00
}
return nChildren;
}
Window* Window::ImplGetAccessibleCandidateChild( USHORT nChild, USHORT& rChildCount, USHORT nFirstWindowType, BOOL bTopLevel ) const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( bTopLevel )
rChildCount = 0;
Window* pChild = GetWindow( nFirstWindowType );
while ( pChild )
{
Window *pTmpChild = pChild;
if( !pChild->ImplIsAccessibleCandidate() )
pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, WINDOW_FIRSTCHILD, FALSE );
if ( nChild == rChildCount )
return pTmpChild;
pChild = pChild->mpNext;
rChildCount++;
}
return NULL;
}
2002-05-31 06:57:29 +00:00
/*
Window* Window::GetAccessibleParentWindow() const
{
Window* pParent = GetParent();
while ( pParent )
if( pParent->ImplIsAccessibleCandidate() )
break;
else
pParent = pParent->GetParent();
2002-02-05 07:13:10 +00:00
return pParent;
}
2002-05-31 06:57:29 +00:00
*/
2002-02-05 07:13:10 +00:00
2002-05-31 06:57:29 +00:00
Window* Window::GetAccessibleParentWindow() const
{
Window* pParent = mpParent;
2002-07-12 14:50:22 +00:00
if( GetType() == WINDOW_MENUBARWINDOW )
{
// report the menubar as a child of THE workwindow
Window *pWorkWin = GetParent()->mpFirstChild;
while( pWorkWin && (pWorkWin == this) )
pWorkWin = pWorkWin->mpNext;
pParent = pWorkWin;
}
else if( pParent && !pParent->ImplIsAccessibleCandidate() )
2002-05-31 06:57:29 +00:00
{
pParent = pParent->mpParent;
2002-05-31 06:57:29 +00:00
}
return pParent;
}
2002-06-03 15:08:11 +00:00
2002-05-31 06:57:29 +00:00
/*
2002-02-08 07:55:12 +00:00
USHORT Window::GetAccessibleChildWindowCount()
{
USHORT nChildren = ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD );
// Search also for SystemWindows.
Window* pOverlap = GetWindow( WINDOW_OVERLAP );
nChildren += pOverlap->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTOVERLAP );
return nChildren;
2002-02-08 07:55:12 +00:00
}
2002-05-31 06:57:29 +00:00
*/
USHORT Window::GetAccessibleChildWindowCount()
{
USHORT nChildren = 0;
Window* pChild = mpFirstChild;
while( pChild )
{
if( pChild->IsVisible() )
nChildren++;
pChild = pChild->mpNext;
}
2002-05-31 06:57:29 +00:00
// Search also for SystemWindows.
Window* pOverlap = GetWindow( WINDOW_OVERLAP );
pOverlap = pOverlap->GetWindow( WINDOW_FIRSTOVERLAP );
while ( pOverlap )
{
if( pOverlap->IsVisible() )
nChildren++;
2002-05-31 06:57:29 +00:00
pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
}
2002-02-08 07:55:12 +00:00
2002-07-12 14:50:22 +00:00
// report the menubarwindow as a child of THE workwindow
if( GetType() == WINDOW_BORDERWINDOW )
{
if( ((ImplBorderWindow *) this)->mpMenuBarWindow &&
((ImplBorderWindow *) this)->mpMenuBarWindow->IsVisible()
)
2002-07-12 14:50:22 +00:00
--nChildren;
}
else if( GetType() == WINDOW_WORKWINDOW )
{
if( ((WorkWindow *) this)->GetMenuBar() &&
((WorkWindow *) this)->GetMenuBar()->GetWindow() &&
((WorkWindow *) this)->GetMenuBar()->GetWindow()->IsVisible()
)
2002-07-12 14:50:22 +00:00
++nChildren;
}
2002-05-31 06:57:29 +00:00
return nChildren;
}
/*
2002-02-05 07:13:10 +00:00
Window* Window::GetAccessibleChildWindow( USHORT n )
{
USHORT nChildCount; // will be set in ImplGetAccessibleCandidateChild(...)
Window* pChild = ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTCHILD, TRUE );
if ( !pChild && ( n >= nChildCount ) )
{
Window* pOverlap = GetWindow( WINDOW_OVERLAP );
pChild = pOverlap->ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTOVERLAP, FALSE );
2002-02-05 07:13:10 +00:00
}
2002-02-05 07:13:10 +00:00
return pChild;
}
2002-05-31 06:57:29 +00:00
*/
Window* Window::GetAccessibleChildWindow( USHORT n )
{
2002-07-12 14:50:22 +00:00
// report the menubarwindow as a the first child of THE workwindow
if( GetType() == WINDOW_WORKWINDOW && ((WorkWindow *) this)->GetMenuBar() )
{
if( n == 0 )
2002-07-12 14:50:22 +00:00
{
MenuBar *pMenuBar = ((WorkWindow *) this)->GetMenuBar();
if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
return pMenuBar->GetWindow();
2002-07-12 14:50:22 +00:00
}
else
--n;
}
// transform n to child number including invisible children
USHORT nChildren = n;
Window* pChild = mpFirstChild;
while( pChild )
2002-07-12 14:50:22 +00:00
{
if( pChild->IsVisible() )
{
if( ! nChildren )
break;
nChildren--;
}
2002-07-12 14:50:22 +00:00
pChild = pChild->mpNext;
}
if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
{
do pChild = pChild->mpNext; while( pChild && ! pChild->IsVisible() );
2002-07-12 14:50:22 +00:00
DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
}
if ( !pChild )
2002-05-31 06:57:29 +00:00
{
Window* pOverlap = GetWindow( WINDOW_OVERLAP );
pOverlap = pOverlap->GetWindow( WINDOW_FIRSTOVERLAP );
while ( !pChild && pOverlap )
{
if ( !nChildren && pOverlap->IsVisible() )
{
2002-05-31 06:57:29 +00:00
pChild = pOverlap;
break;
}
pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
if( pOverlap && pOverlap->IsVisible() )
nChildren--;
2002-05-31 06:57:29 +00:00
}
}
if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
{
pChild = pChild->GetChild( 0 );
}
return pChild;
}
2002-02-05 07:13:10 +00:00
void Window::SetAccessibleRole( USHORT nRole )
{
2002-02-14 16:13:26 +00:00
if ( !mpAccessibleInfos )
mpAccessibleInfos = new ImplAccessibleInfos;
2002-02-08 07:55:12 +00:00
2002-02-14 16:13:26 +00:00
DBG_ASSERT( mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
mpAccessibleInfos->nAccessibleRole = nRole;
2002-02-05 07:13:10 +00:00
}
USHORT Window::GetAccessibleRole() const
{
using namespace ::drafts::com::sun::star;
2002-02-14 16:13:26 +00:00
USHORT nRole = mpAccessibleInfos ? mpAccessibleInfos->nAccessibleRole : 0xFFFF;
2002-02-05 07:13:10 +00:00
if ( nRole == 0xFFFF )
{
switch ( GetType() )
{
case WINDOW_MESSBOX: // MT: Would be nice to have special roles!
case WINDOW_INFOBOX:
case WINDOW_WARNINGBOX:
case WINDOW_ERRORBOX:
case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::OPTIONPANE; break;
case WINDOW_MODELESSDIALOG:
case WINDOW_MODALDIALOG:
case WINDOW_SYSTEMDIALOG:
case WINDOW_PRINTERSETUPDIALOG:
case WINDOW_PRINTDIALOG:
case WINDOW_TABDIALOG:
case WINDOW_BUTTONDIALOG:
case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break;
case WINDOW_PUSHBUTTON:
case WINDOW_OKBUTTON:
case WINDOW_CANCELBUTTON:
case WINDOW_HELPBUTTON:
case WINDOW_IMAGEBUTTON:
case WINDOW_MENUBUTTON:
case WINDOW_MOREBUTTON:
case WINDOW_SPINBUTTON:
case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSHBUTTON; break;
case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORYPANE; break;
case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILECHOOSER; break;
case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLORCHOOSER; break;
case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONTCHOOSER; break;
case WINDOW_IMAGERADIOBUTTON:
case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIOBUTTON; break;
case WINDOW_TRISTATEBOX:
case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECKBOX; break;
case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLLPANE; break;
2002-02-05 07:13:10 +00:00
case WINDOW_PATTERNFIELD:
case WINDOW_NUMERICFIELD:
case WINDOW_METRICFIELD:
case WINDOW_CURRENCYFIELD:
case WINDOW_LONGCURRENCYFIELD:
case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORDTEXT) : (accessibility::AccessibleRole::TEXT); break;
case WINDOW_PATTERNBOX:
case WINDOW_NUMERICBOX:
case WINDOW_METRICBOX:
case WINDOW_CURRENCYBOX:
case WINDOW_LONGCURRENCYBOX:
case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBOBOX; break;
case WINDOW_LISTBOX:
case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
case WINDOW_FIXEDBORDER:
case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break;
case WINDOW_FIXEDBITMAP:
case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUPBOX; break;
case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLLBAR; break;
case WINDOW_SLIDER:
case WINDOW_SPLITTER:
case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLITPANE; break;
case WINDOW_DATEBOX:
case WINDOW_TIMEBOX:
case WINDOW_DATEFIELD:
case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATEEDITOR; break;
case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPINBOX; break;
case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOLBAR; break;
case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUSBAR; break;
case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PAGETAB; break;
case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGETABLIST; break;
case WINDOW_DOCKINGWINDOW:
case WINDOW_SYSWINDOW:
case WINDOW_FLOATINGWINDOW: nRole = accessibility::AccessibleRole::LAYEREDPANE; break;
2002-07-12 14:50:22 +00:00
case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOTPANE; break;
2002-02-05 07:13:10 +00:00
case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
case WINDOW_WINDOW:
case WINDOW_CONTROL:
case WINDOW_BORDERWINDOW:
case WINDOW_SYSTEMCHILDWINDOW:
2002-07-12 14:50:22 +00:00
default:
if (ImplIsAccessibleNativeFrame() )
nRole = accessibility::AccessibleRole::FRAME;
else if( IsScrollable() )
nRole = accessibility::AccessibleRole::SCROLLPANE;
else
nRole = accessibility::AccessibleRole::WINDOW;
2002-02-05 07:13:10 +00:00
}
}
return nRole;
}
2002-02-08 07:55:12 +00:00
void Window::SetAccessibleName( const String& rName )
{
2002-02-14 16:13:26 +00:00
if ( !mpAccessibleInfos )
mpAccessibleInfos = new ImplAccessibleInfos;
2002-02-08 07:55:12 +00:00
2002-02-14 16:13:26 +00:00
DBG_ASSERT( !mpAccessibleInfos->pAccessibleName, "AccessibleName already set!" );
delete mpAccessibleInfos->pAccessibleName;
mpAccessibleInfos->pAccessibleName = new String( rName );
2002-02-08 07:55:12 +00:00
}
String Window::GetAccessibleName() const
{
String aAccessibleName;
2002-02-14 16:13:26 +00:00
if ( mpAccessibleInfos && mpAccessibleInfos->pAccessibleName )
2002-02-08 07:55:12 +00:00
{
2002-02-14 16:13:26 +00:00
aAccessibleName = *mpAccessibleInfos->pAccessibleName;
2002-02-08 07:55:12 +00:00
}
else
{
switch ( GetType() )
{
// case WINDOW_IMAGERADIOBUTTON:
// case WINDOW_RADIOBUTTON:
// case WINDOW_TRISTATEBOX:
// case WINDOW_CHECKBOX:
case WINDOW_MULTILINEEDIT:
case WINDOW_PATTERNFIELD:
case WINDOW_NUMERICFIELD:
case WINDOW_METRICFIELD:
case WINDOW_CURRENCYFIELD:
case WINDOW_LONGCURRENCYFIELD:
case WINDOW_EDIT:
case WINDOW_DATEBOX:
case WINDOW_TIMEBOX:
case WINDOW_CURRENCYBOX:
case WINDOW_LONGCURRENCYBOX:
case WINDOW_DATEFIELD:
case WINDOW_TIMEFIELD:
case WINDOW_SPINFIELD:
case WINDOW_COMBOBOX:
case WINDOW_LISTBOX:
case WINDOW_MULTILISTBOX:
{
Window *pLabel = GetLabeledBy();
if( pLabel )
aAccessibleName = pLabel->GetText();
else if ( ( GetType() == WINDOW_LISTBOX ) || ( GetType() == WINDOW_MULTILISTBOX ) )
aAccessibleName = GetText();
}
break;
default:
aAccessibleName = GetText();
break;
}
aAccessibleName = GetNonMnemonicString( aAccessibleName );
2002-02-08 07:55:12 +00:00
}
return aAccessibleName;
}
void Window::SetAccessibleDescription( const String& rDescription )
{
2002-02-14 16:13:26 +00:00
if ( ! mpAccessibleInfos )
mpAccessibleInfos = new ImplAccessibleInfos;
2002-02-08 07:55:12 +00:00
2002-02-14 16:13:26 +00:00
DBG_ASSERT( !mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
delete mpAccessibleInfos->pAccessibleDescription;
mpAccessibleInfos->pAccessibleDescription = new String( rDescription );
2002-02-08 07:55:12 +00:00
}
String Window::GetAccessibleDescription() const
{
String aAccessibleDescription;
2002-02-14 16:13:26 +00:00
if ( mpAccessibleInfos && mpAccessibleInfos->pAccessibleDescription )
2002-02-08 07:55:12 +00:00
{
2002-02-14 16:13:26 +00:00
aAccessibleDescription = *mpAccessibleInfos->pAccessibleDescription;
2002-02-08 07:55:12 +00:00
}
else
{
}
return aAccessibleDescription;
}
2002-04-18 07:04:36 +00:00
2002-06-03 15:08:11 +00:00
BOOL Window::IsAccessibilityEventsSuppressed( BOOL bTraverseParentPath )
{
if( !bTraverseParentPath )
return mbSuppressAccessibilityEvents;
else
{
Window *pParent = this;
while ( pParent )
{
if( pParent->mbSuppressAccessibilityEvents )
return TRUE;
else
pParent = pParent->mpParent; // do not use GetParent() to find borderwindows that are frames
2002-06-03 15:08:11 +00:00
}
return FALSE;
}
}
2002-04-18 07:04:36 +00:00
2002-07-12 14:50:22 +00:00
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
2002-04-18 07:04:36 +00:00
// returns background color used in this control
// false: could not determine color
BOOL Window::ImplGetCurrentBackgroundColor( Color& rCol )
{
BOOL bRet = TRUE;
switch ( GetType() )
{
// peform special handling here
case WINDOW_PUSHBUTTON:
case WINDOW_OKBUTTON:
case WINDOW_CANCELBUTTON:
// etc.
default:
if( IsControlBackground() )
rCol = GetControlBackground();
else if( IsBackground() )
{
Wallpaper aWall = GetBackground();
if( !aWall.IsGradient() && !aWall.IsBitmap() )
rCol = aWall.GetColor();
else
bRet = FALSE;
}
else
rCol = GetSettings().GetStyleSettings().GetFaceColor();
break;
}
return bRet;
}
2002-05-06 12:15:07 +00:00
void Window::DrawSelectionBackground( const Rectangle& rRect, USHORT highlight, BOOL bChecked, BOOL bDrawBorder, BOOL bDrawExtBorderOnly )
{
// colors used for item highlighting
Color aSelectionBorderCol( GetSettings().GetStyleSettings().GetActiveColor() );
Color aSelectionFillCol( aSelectionBorderCol );
Color aSelectionMaskCol( aSelectionBorderCol );
USHORT lum = GetSettings().GetStyleSettings().GetFaceColor().GetLuminance();
BOOL bDark = (lum <= 25);
BOOL bBright = (lum >= 225);
Rectangle aRect( rRect );
if( bDrawExtBorderOnly )
{
aRect.nLeft -= 1;
aRect.nTop -= 1;
aRect.nRight += 1;
aRect.nBottom += 1;
}
Color oldFillCol = GetFillColor();
Color oldLineCol = GetLineColor();
if( bDrawBorder )
SetLineColor( bDark ? Color(COL_WHITE) : ( bBright ? Color(COL_BLACK) : aSelectionBorderCol ) );
else
SetLineColor();
USHORT nPercent;
if( !highlight )
{
if( bDark )
aSelectionFillCol = COL_BLACK;
else
nPercent = 95; // just checked (light)
}
else
{
if( bChecked || highlight == 1 )
{
if( bDark )
aSelectionFillCol = COL_GRAY;
else
nPercent = 55; // selected, pressed or checked ( very dark )
}
else
{
if( bDark )
aSelectionFillCol = COL_LIGHTGRAY;
else
nPercent = 85; // selected ( dark )
}
}
if( bDark && bDrawExtBorderOnly )
SetFillColor();
else
SetFillColor( aSelectionFillCol );
if( bDark )
{
DrawRect( aRect );
}
else
{
Polygon aPoly( aRect );
PolyPolygon aPolyPoly( aPoly );
DrawTransparent( aPolyPoly, nPercent );
}
SetFillColor( oldFillCol );
SetLineColor( oldLineCol );
}
/*
void Window::DbgAssertNoEventListeners()
{
VclWindowEvent aEvent( this, 0, NULL );
DBG_ASSERT( maEventListeners.empty(), "Eventlistener: Who is still listening???" )
if ( !maEventListeners.empty() )
maEventListeners.Call( &aEvent );
DBG_ASSERT( maChildEventListeners.empty(), "ChildEventlistener: Who is still listening???" )
if ( !maChildEventListeners.empty() )
maChildEventListeners.Call( &aEvent );
}
*/
// controls should return the window that gets the
// focus by default, so keyevents can be sent to that window directly
Window* Window::GetPreferredKeyInputWindow()
{
return this;
}
2002-07-12 14:50:22 +00:00
BOOL Window::IsScrollable() const
{
// check for scrollbars
Window *pChild = mpFirstChild;
while( pChild )
{
if( pChild->GetType() == WINDOW_SCROLLBAR )
return true;
else
pChild = pChild->mpNext;
}
return false;
}
BOOL Window::IsTopWindow() const
{
// topwindows must be frames or they must have a borderwindow which is a frame
if( !mbFrame && (!mpBorderWindow || (mpBorderWindow && !mpBorderWindow->mbFrame) ) )
return FALSE;
Reference< XTopWindow > xTopWindow( ((Window*)this)->GetComponentInterface(), UNO_QUERY );
return xTopWindow.is() ? TRUE : FALSE;
}