Files
libreoffice/vcl/source/window/window.cxx
Frank Schoenheit [fs] 3633ecf16d slidecopy: removed the old TaskPane implementation, now completely superseded by the new one
carrying both implementations was only temporary, to be able to easily compare both.
The new implementation still has not A11Y API implementation, that's on the TODO list.
2010-03-17 10:48:49 +01:00

9961 lines
350 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: window.cxx,v $
* $Revision: 1.285.38.2 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org 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 version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#ifndef _SV_SVSYS_HXX
#include "svsys.h"
#endif
#include "vcl/salframe.hxx"
#include "vcl/salobj.hxx"
#include "vcl/salinst.hxx"
#include "vcl/salgtype.hxx"
#include "vcl/salgdi.hxx"
#include "vcl/salctrlhandle.hxx"
#include "vcl/unohelp.hxx"
#include "tools/time.hxx"
#include "tools/debug.hxx"
#ifndef _SV_RC_H
#include "tools/rc.h"
#endif
#include "vcl/svdata.hxx"
#include "vcl/windata.hxx"
#include "vcl/dbggui.hxx"
#include "vcl/outfont.hxx"
#include "vcl/outdev.h"
#include "vcl/region.h"
#include "vcl/event.hxx"
#include "vcl/help.hxx"
#include "vcl/cursor.hxx"
#include "vcl/svapp.hxx"
#include "vcl/window.h"
#include "vcl/window.hxx"
#include "vcl/syswin.hxx"
#include "vcl/syschild.hxx"
#include "vcl/brdwin.hxx"
#include "vcl/helpwin.hxx"
#include "vcl/dockwin.hxx"
#include "vcl/menu.hxx"
#include "vcl/wrkwin.hxx"
#include "vcl/wall.hxx"
#include "vcl/gradient.hxx"
#include "vcl/toolbox.h"
#include "unotools/fontcfg.hxx"
#include "vcl/sysdata.hxx"
#include "vcl/sallayout.hxx"
#include "vcl/button.hxx" // Button::GetStandardText
#include "vcl/taskpanelist.hxx"
#include "com/sun/star/awt/XWindowPeer.hpp"
#include "com/sun/star/rendering/XCanvas.hpp"
#include "com/sun/star/rendering/XSpriteCanvas.hpp"
#include "com/sun/star/awt/XWindow.hpp"
#include "comphelper/processfactory.hxx"
#include "com/sun/star/datatransfer/dnd/XDragSource.hpp"
#include "com/sun/star/datatransfer/dnd/XDropTarget.hpp"
#include "com/sun/star/datatransfer/clipboard/XClipboard.hpp"
#include "com/sun/star/awt/XTopWindow.hpp"
#include "com/sun/star/awt/XDisplayConnection.hpp"
#include "com/sun/star/lang/XInitialization.hpp"
#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/lang/XServiceName.hpp"
#include "com/sun/star/accessibility/XAccessible.hpp"
#include "com/sun/star/accessibility/AccessibleRole.hpp"
#include "vcl/dialog.hxx"
#include "vcl/unowrap.hxx"
#include "dndlcon.hxx"
#include "dndevdis.hxx"
#include "vcl/impbmpconv.hxx"
#include "unotools/confignode.hxx"
#include "vcl/gdimtf.hxx"
#include "vcl/pdfextoutdevdata.hxx"
#include "vcl/lazydelete.hxx"
#include <set>
using namespace rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::datatransfer::clipboard;
using namespace ::com::sun::star::datatransfer::dnd;
using namespace ::com::sun::star;
using namespace com::sun;
using ::com::sun::star::awt::XTopWindow;
// =======================================================================
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)
#define IMPL_PAINT_CHECKRTL ((USHORT)0x0020)
// -----------------------------------------------------------------------
typedef Window* PWINDOW;
// -----------------------------------------------------------------------
struct ImplCalcToTopData
{
ImplCalcToTopData* mpNext;
Window* mpWindow;
Region* mpInvalidateRegion;
};
struct ImplAccessibleInfos
{
USHORT nAccessibleRole;
String* pAccessibleName;
String* pAccessibleDescription;
ImplAccessibleInfos()
{
nAccessibleRole = 0xFFFF;
pAccessibleName = NULL;
pAccessibleDescription = NULL;
}
~ImplAccessibleInfos()
{
delete pAccessibleName;
delete pAccessibleDescription;
}
};
// -----------------------------------------------------------------------
WindowImpl::WindowImpl()
{
}
WindowImpl::~WindowImpl()
{
}
// -----------------------------------------------------------------------
// helper method to allow inline constructor even for pWindow!=NULL case
void ImplDelData::AttachToWindow( const Window* pWindow )
{
if( pWindow )
const_cast<Window*>(pWindow)->ImplAddDel( this );
}
// -----------------------------------------------------------------------
// define dtor for ImplDelData
ImplDelData::~ImplDelData()
{
// #112873# auto remove of ImplDelData
// due to this code actively calling ImplRemoveDel() is not mandatory anymore
if( !mbDel && mpWindow )
{
// the window still exists but we were not removed
const_cast<Window*>(mpWindow)->ImplRemoveDel( this );
mpWindow = NULL;
}
}
// -----------------------------------------------------------------------
#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->mpWindowImpl->mpFirstChild;
while ( pChild )
{
if ( pChild->mpWindowImpl->mpParent != pWindow )
return "Child-Window-Parent wrong";
pChild = pChild->mpWindowImpl->mpNext;
}
return NULL;
}
#endif
// =======================================================================
void Window::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;
// FIXME: this is currently only on aqua, check with other
// platforms
if( pSVData->maNWFData.mbNoFocusRects )
{
// try to find out wether there is a large correction
// of control sizes, if yes, make app font scalings larger
// so dialog positioning is not completely off
ImplControlValue aControlValue;
Region aCtrlRegion( (const Rectangle&)Rectangle( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) ) );
Region aBoundingRgn( aCtrlRegion );
Region aContentRgn( aCtrlRegion );
if( pWindow->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
aBoundingRgn, aContentRgn ) )
{
Rectangle aContentRect( aContentRgn.GetBoundRect() );
// comment: the magical +6 is for the extra border in bordered
// (which is the standard) edit fields
if( aContentRect.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
pSVData->maGDIData.mnAppFontY = (aContentRect.GetHeight()-4) * 10;
}
}
pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX;
if ( pSVData->maAppData.mnDialogScaleX )
pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100;
}
// -----------------------------------------------------------------------
bool Window::ImplCheckUIFont( const Font& rFont )
{
if( ImplGetSVData()->maGDIData.mbNativeFontConfig )
return true;
String aTestText;
aTestText.Append( Button::GetStandardText( BUTTON_OK ) );
aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) );
aTestText.Append( Button::GetStandardText( BUTTON_YES ) );
aTestText.Append( Button::GetStandardText( BUTTON_NO ) );
aTestText.Append( Button::GetStandardText( BUTTON_RETRY ) );
aTestText.Append( Button::GetStandardText( BUTTON_HELP ) );
aTestText.Append( Button::GetStandardText( BUTTON_CLOSE ) );
aTestText.Append( Button::GetStandardText( BUTTON_MORE ) );
aTestText.Append( Button::GetStandardText( BUTTON_LESS ) );
aTestText.Append( Button::GetStandardText( BUTTON_ABORT ) );
return HasGlyphs( rFont, aTestText ) >= aTestText.Len();
}
// -----------------------------------------------------------------------
void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, BOOL bCallHdl )
{
// reset high contrast to false, so the system can either update it
// or AutoDetectSystemHC can kick in (see below)
StyleSettings aTmpSt( rSettings.GetStyleSettings() );
aTmpSt.SetHighContrastMode( FALSE );
rSettings.SetStyleSettings( aTmpSt );
ImplGetFrame()->UpdateSettings( rSettings );
// Verify availability of the configured UI font, otherwise choose "Andale Sans UI"
String aUserInterfaceFont;
bool bUseSystemFont = rSettings.GetStyleSettings().GetUseSystemUIFonts();
// check whether system UI font can display a typical UI text
if( bUseSystemFont )
bUseSystemFont = ImplCheckUIFont( rSettings.GetStyleSettings().GetAppFont() );
if ( !bUseSystemFont )
{
ImplInitFontList();
String aConfigFont = utl::DefaultFontConfiguration::get()->getUserInterfaceFont( rSettings.GetUILocale() );
xub_StrLen nIndex = 0;
while( nIndex != STRING_NOTFOUND )
{
String aName( aConfigFont.GetToken( 0, ';', nIndex ) );
if ( aName.Len() && mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aName ) )
{
aUserInterfaceFont = aConfigFont;
break;
}
}
if ( ! aUserInterfaceFont.Len() )
{
String aFallbackFont (RTL_CONSTASCII_USTRINGPARAM( "Andale Sans UI" ));
if ( mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aFallbackFont ) )
aUserInterfaceFont = aFallbackFont;
}
}
if ( !bUseSystemFont && aUserInterfaceFont.Len() )
{
StyleSettings aStyleSettings = rSettings.GetStyleSettings();
Font aFont = aStyleSettings.GetAppFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetAppFont( aFont );
aFont = aStyleSettings.GetHelpFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetHelpFont( aFont );
aFont = aStyleSettings.GetTitleFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetTitleFont( aFont );
aFont = aStyleSettings.GetFloatTitleFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetFloatTitleFont( aFont );
aFont = aStyleSettings.GetMenuFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetMenuFont( aFont );
aFont = aStyleSettings.GetToolFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetToolFont( aFont );
aFont = aStyleSettings.GetLabelFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetLabelFont( aFont );
aFont = aStyleSettings.GetInfoFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetInfoFont( aFont );
aFont = aStyleSettings.GetRadioCheckFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetRadioCheckFont( aFont );
aFont = aStyleSettings.GetPushButtonFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetPushButtonFont( aFont );
aFont = aStyleSettings.GetFieldFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetFieldFont( aFont );
aFont = aStyleSettings.GetIconFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetIconFont( aFont );
aFont = aStyleSettings.GetGroupFont();
aFont.SetName( aUserInterfaceFont );
aStyleSettings.SetGroupFont( aFont );
rSettings.SetStyleSettings( aStyleSettings );
}
StyleSettings aStyleSettings = rSettings.GetStyleSettings();
// #97047: Force all fonts except Menu and Help to a fixed height
// to avoid UI scaling due to large fonts
// - but allow bigger fonts on bigger screens (i16682, i21238)
// dialogs were designed to fit 800x600 with an 8pt font, so scale accordingly
int maxFontheight = 9; // #107886#: 9 is default for some asian systems, so always allow if requested
if( GetDesktopRectPixel().getHeight() > 600 )
maxFontheight = (int) ((( 8.0 * (double) GetDesktopRectPixel().getHeight()) / 600.0) + 1.5);
Font aFont = aStyleSettings.GetMenuFont();
int defFontheight = aFont.GetHeight();
if( defFontheight > maxFontheight )
defFontheight = maxFontheight;
// if the UI is korean, chinese or another locale
// where the system font size is kown to be often too small to
// generate readable fonts enforce a minimum font size of 9 points
bool bBrokenLangFontHeight = false;
static const LanguageType eBrokenSystemFontSizeLanguages[] =
{ LANGUAGE_KOREAN, LANGUAGE_KOREAN_JOHAB,
LANGUAGE_CHINESE_HONGKONG, LANGUAGE_CHINESE_MACAU, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_SINGAPORE, LANGUAGE_CHINESE_TRADITIONAL
};
static std::set< LanguageType > aBrokenSystemFontSizeLanguagesSet(
eBrokenSystemFontSizeLanguages,
eBrokenSystemFontSizeLanguages +
(sizeof(eBrokenSystemFontSizeLanguages)/sizeof(eBrokenSystemFontSizeLanguages[0]))
);
LanguageType aLang = Application::GetSettings().GetUILanguage();
if( aBrokenSystemFontSizeLanguagesSet.find( aLang ) != aBrokenSystemFontSizeLanguagesSet.end() )
{
defFontheight = Max(9, defFontheight);
bBrokenLangFontHeight = true;
}
// i22098, toolfont will be scaled differently to avoid bloated rulers and status bars for big fonts
int toolfontheight = defFontheight;
if( toolfontheight > 9 )
toolfontheight = (defFontheight+8) / 2;
aFont = aStyleSettings.GetAppFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetAppFont( aFont );
aFont = aStyleSettings.GetTitleFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetTitleFont( aFont );
aFont = aStyleSettings.GetFloatTitleFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetFloatTitleFont( aFont );
// keep menu and help font size from system unless in broken locale size
if( bBrokenLangFontHeight )
{
aFont = aStyleSettings.GetMenuFont();
if( aFont.GetHeight() < defFontheight )
{
aFont.SetHeight( defFontheight );
aStyleSettings.SetMenuFont( aFont );
}
aFont = aStyleSettings.GetHelpFont();
if( aFont.GetHeight() < defFontheight )
{
aFont.SetHeight( defFontheight );
aStyleSettings.SetHelpFont( aFont );
}
}
// use different height for toolfont
aFont = aStyleSettings.GetToolFont();
aFont.SetHeight( toolfontheight );
aStyleSettings.SetToolFont( aFont );
aFont = aStyleSettings.GetLabelFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetLabelFont( aFont );
aFont = aStyleSettings.GetInfoFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetInfoFont( aFont );
aFont = aStyleSettings.GetRadioCheckFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetRadioCheckFont( aFont );
aFont = aStyleSettings.GetPushButtonFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetPushButtonFont( aFont );
aFont = aStyleSettings.GetFieldFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetFieldFont( aFont );
aFont = aStyleSettings.GetIconFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetIconFont( aFont );
aFont = aStyleSettings.GetGroupFont();
aFont.SetHeight( defFontheight );
aStyleSettings.SetGroupFont( aFont );
// set workspace gradient to black in dark themes
if( aStyleSettings.GetWindowColor().IsDark() )
aStyleSettings.SetWorkspaceGradient( Wallpaper( Color( COL_BLACK ) ) );
else
{
Gradient aGrad( GRADIENT_LINEAR, DEFAULT_WORKSPACE_GRADIENT_START_COLOR, DEFAULT_WORKSPACE_GRADIENT_END_COLOR );
aStyleSettings.SetWorkspaceGradient( Wallpaper( aGrad ) );
}
rSettings.SetStyleSettings( aStyleSettings );
// auto detect HC mode; if the system already set it to "yes"
// (see above) then accept that
if( !rSettings.GetStyleSettings().GetHighContrastMode() )
{
sal_Bool bTmp = sal_False, bAutoHCMode = sal_True;
utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
vcl::unohelper::GetMultiServiceFactory(),
OUString::createFromAscii( "org.openoffice.Office.Common/Accessibility" ) ); // note: case sensisitive !
if ( aNode.isValid() )
{
::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "AutoDetectSystemHC" ) );
if( aValue >>= bTmp )
bAutoHCMode = bTmp;
}
if( bAutoHCMode )
{
if( rSettings.GetStyleSettings().GetFaceColor().IsDark()
|| rSettings.GetStyleSettings().GetWindowColor().IsDark() )
{
aStyleSettings = rSettings.GetStyleSettings();
aStyleSettings.SetHighContrastMode( TRUE );
rSettings.SetStyleSettings( aStyleSettings );
}
}
}
#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() )
{
aStyleSettings = rSettings.GetStyleSettings();
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
if ( bCallHdl )
GetpApp()->SystemSettingsChanging( rSettings, this );
}
// -----------------------------------------------------------------------
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() );
}
// -----------------------------------------------------------------------
CommandEvent ImplTranslateCommandEvent( const CommandEvent& rCEvt, Window* pSource, Window* pDest )
{
if ( !rCEvt.IsMouseEvent() )
return rCEvt;
Point aPos = pSource->OutputToScreenPixel( rCEvt.GetMousePosPixel() );
aPos = pDest->ScreenToOutputPixel( aPos );
return CommandEvent( aPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
}
// =======================================================================
void Window::ImplInitWindowData( WindowType nType )
{
mpWindowImpl = new WindowImpl;
meOutDevType = OUTDEV_WINDOW;
mpWindowImpl->maZoom = Fraction( 1, 1 );
mpWindowImpl->maWinRegion = Region( REGION_NULL );
mpWindowImpl->maWinClipRegion = Region( REGION_NULL );
mpWindowImpl->mpWinData = NULL; // Extra Window Data, that we dont need for all windows
mpWindowImpl->mpOverlapData = NULL; // Overlap Data
mpWindowImpl->mpFrameData = NULL; // Frame Data
mpWindowImpl->mpFrame = NULL; // Pointer to frame window
mpWindowImpl->mpSysObj = NULL;
mpWindowImpl->mpFrameWindow = NULL; // window to top level parent (same as frame window)
mpWindowImpl->mpOverlapWindow = NULL; // first overlap parent
mpWindowImpl->mpBorderWindow = NULL; // Border-Window
mpWindowImpl->mpClientWindow = NULL; // Client-Window of a FrameWindow
mpWindowImpl->mpParent = NULL; // parent (inkl. BorderWindow)
mpWindowImpl->mpRealParent = NULL; // real parent (exkl. BorderWindow)
mpWindowImpl->mpFirstChild = NULL; // first child window
mpWindowImpl->mpLastChild = NULL; // last child window
mpWindowImpl->mpFirstOverlap = NULL; // first overlap window (only set in overlap windows)
mpWindowImpl->mpLastOverlap = NULL; // last overlap window (only set in overlap windows)
mpWindowImpl->mpPrev = NULL; // prev window
mpWindowImpl->mpNext = NULL; // next window
mpWindowImpl->mpNextOverlap = NULL; // next overlap window of frame
mpWindowImpl->mpLastFocusWindow = NULL; // window for focus restore
mpWindowImpl->mpDlgCtrlDownWindow = NULL; // window for dialog control
mpWindowImpl->mpFirstDel = NULL; // Dtor notification list
mpWindowImpl->mpUserData = NULL; // user data
mpWindowImpl->mpCursor = NULL; // cursor
mpWindowImpl->mpControlFont = NULL; // font propertie
mpWindowImpl->mpVCLXWindow = NULL;
mpWindowImpl->mpAccessibleInfos = NULL;
mpWindowImpl->maControlForeground = Color( COL_TRANSPARENT ); // kein Foreground gesetzt
mpWindowImpl->maControlBackground = Color( COL_TRANSPARENT ); // kein Background gesetzt
mpWindowImpl->mnLeftBorder = 0; // left border
mpWindowImpl->mnTopBorder = 0; // top border
mpWindowImpl->mnRightBorder = 0; // right border
mpWindowImpl->mnBottomBorder = 0; // bottom border
mpWindowImpl->mnX = 0; // X-Position to Parent
mpWindowImpl->mnY = 0; // Y-Position to Parent
mpWindowImpl->mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning
mpWindowImpl->mnHelpId = 0; // help id
mpWindowImpl->mnUniqId = 0; // unique id
mpWindowImpl->mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren
mpWindowImpl->mpPaintRegion = NULL; // Paint-ClipRegion
mpWindowImpl->mnStyle = 0; // style (init in ImplInitWindow)
mpWindowImpl->mnPrevStyle = 0; // prevstyle (set in SetStyle)
mpWindowImpl->mnExtendedStyle = 0; // extended style (init in ImplInitWindow)
mpWindowImpl->mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle)
mpWindowImpl->mnType = nType; // type
mpWindowImpl->mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf
mpWindowImpl->mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer)
mpWindowImpl->mnPaintFlags = 0; // Flags for ImplCallPaint
mpWindowImpl->mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode
mpWindowImpl->mnActivateMode = 0; // Wird bei System/Overlap-Windows umgesetzt
mpWindowImpl->mnDlgCtrlFlags = 0; // DialogControl-Flags
mpWindowImpl->mnLockCount = 0; // LockCount
mpWindowImpl->meAlwaysInputMode = AlwaysInputNone; // neither AlwaysEnableInput nor AlwaysDisableInput called
mpWindowImpl->mbFrame = FALSE; // TRUE: Window is a frame window
mpWindowImpl->mbBorderWin = FALSE; // TRUE: Window is a border window
mpWindowImpl->mbOverlapWin = FALSE; // TRUE: Window is a overlap window
mpWindowImpl->mbSysWin = FALSE; // TRUE: SystemWindow is the base class
mpWindowImpl->mbDialog = FALSE; // TRUE: Dialog is the base class
mpWindowImpl->mbDockWin = FALSE; // TRUE: DockingWindow is the base class
mpWindowImpl->mbFloatWin = FALSE; // TRUE: FloatingWindow is the base class
mpWindowImpl->mbPushButton = FALSE; // TRUE: PushButton is the base class
mpWindowImpl->mbToolBox = FALSE; // TRUE: ToolBox is the base class
mpWindowImpl->mbMenuFloatingWindow= FALSE; // TRUE: MenuFloatingWindow is the base class
mpWindowImpl->mbToolbarFloatingWindow= FALSE; // TRUE: ImplPopupFloatWin is the base class, used for subtoolbars
mpWindowImpl->mbSplitter = FALSE; // TRUE: Splitter is the base class
mpWindowImpl->mbVisible = FALSE; // TRUE: Show( TRUE ) called
mpWindowImpl->mbOverlapVisible = FALSE; // TRUE: Hide called for visible window from ImplHideAllOverlapWindow()
mpWindowImpl->mbDisabled = FALSE; // TRUE: Enable( FALSE ) called
mpWindowImpl->mbInputDisabled = FALSE; // TRUE: EnableInput( FALSE ) called
mpWindowImpl->mbDropDisabled = FALSE; // TRUE: Drop is enabled
mpWindowImpl->mbNoUpdate = FALSE; // TRUE: SetUpdateMode( FALSE ) called
mpWindowImpl->mbNoParentUpdate = FALSE; // TRUE: SetParentUpdateMode( FALSE ) called
mpWindowImpl->mbActive = FALSE; // TRUE: Window Active
mpWindowImpl->mbParentActive = FALSE; // TRUE: OverlapActive from Parent
mpWindowImpl->mbReallyVisible = FALSE; // TRUE: this and all parents to an overlaped window are visible
mpWindowImpl->mbReallyShown = FALSE; // TRUE: this and all parents to an overlaped window are shown
mpWindowImpl->mbInInitShow = FALSE; // TRUE: we are in InitShow
mpWindowImpl->mbChildNotify = FALSE; // TRUE: ChildNotify
mpWindowImpl->mbChildPtrOverwrite = FALSE; // TRUE: PointerStyle overwrites Child-Pointer
mpWindowImpl->mbNoPtrVisible = FALSE; // TRUE: ShowPointer( FALSE ) called
mpWindowImpl->mbMouseMove = FALSE; // TRUE: BaseMouseMove called
mpWindowImpl->mbPaintFrame = FALSE; // TRUE: Paint is visible, but not painted
mpWindowImpl->mbInPaint = FALSE; // TRUE: Inside PaintHdl
mpWindowImpl->mbMouseButtonDown = FALSE; // TRUE: BaseMouseButtonDown called
mpWindowImpl->mbMouseButtonUp = FALSE; // TRUE: BaseMouseButtonUp called
mpWindowImpl->mbKeyInput = FALSE; // TRUE: BaseKeyInput called
mpWindowImpl->mbKeyUp = FALSE; // TRUE: BaseKeyUp called
mpWindowImpl->mbCommand = FALSE; // TRUE: BaseCommand called
mpWindowImpl->mbDefPos = TRUE; // TRUE: Position is not Set
mpWindowImpl->mbDefSize = TRUE; // TRUE: Size is not Set
mpWindowImpl->mbCallMove = TRUE; // TRUE: Move must be called by Show
mpWindowImpl->mbCallResize = TRUE; // TRUE: Resize must be called by Show
mpWindowImpl->mbWaitSystemResize = TRUE; // TRUE: Wait for System-Resize
mpWindowImpl->mbInitWinClipRegion = TRUE; // TRUE: Calc Window Clip Region
mpWindowImpl->mbInitChildRegion = FALSE; // TRUE: InitChildClipRegion
mpWindowImpl->mbWinRegion = FALSE; // TRUE: Window Region
mpWindowImpl->mbClipChildren = FALSE; // TRUE: Child-Fenster muessen evt. geclippt werden
mpWindowImpl->mbClipSiblings = FALSE; // TRUE: Nebeneinanderliegende Child-Fenster muessen evt. geclippt werden
mpWindowImpl->mbChildTransparent = FALSE; // TRUE: Child-Fenster duerfen transparent einschalten (inkl. Parent-CLIPCHILDREN)
mpWindowImpl->mbPaintTransparent = FALSE; // TRUE: Paints muessen auf Parent ausgeloest werden
mpWindowImpl->mbMouseTransparent = FALSE; // TRUE: Window is transparent for Mouse
mpWindowImpl->mbDlgCtrlStart = FALSE; // TRUE: Ab hier eigenes Dialog-Control
mpWindowImpl->mbFocusVisible = FALSE; // TRUE: Focus Visible
mpWindowImpl->mbUseNativeFocus = FALSE;
mpWindowImpl->mbNativeFocusVisible= FALSE; // TRUE: native Focus Visible
mpWindowImpl->mbInShowFocus = FALSE; // prevent recursion
mpWindowImpl->mbInHideFocus = FALSE; // prevent recursion
mpWindowImpl->mbTrackVisible = FALSE; // TRUE: Tracking Visible
mpWindowImpl->mbControlForeground = FALSE; // TRUE: Foreground-Property set
mpWindowImpl->mbControlBackground = FALSE; // TRUE: Background-Property set
mpWindowImpl->mbAlwaysOnTop = FALSE; // TRUE: immer vor allen anderen normalen Fenstern sichtbar
mpWindowImpl->mbCompoundControl = FALSE; // TRUE: Zusammengesetztes Control => Listener...
mpWindowImpl->mbCompoundControlHasFocus = FALSE; // TRUE: Zusammengesetztes Control hat irgendwo den Focus
mpWindowImpl->mbPaintDisabled = FALSE; // TRUE: Paint soll nicht ausgefuehrt werden
mpWindowImpl->mbAllResize = FALSE; // TRUE: Auch ResizeEvents mit 0,0 schicken
mpWindowImpl->mbInDtor = FALSE; // TRUE: Wir befinden uns im Window-Dtor
mpWindowImpl->mbExtTextInput = FALSE; // TRUE: ExtTextInput-Mode is active
mpWindowImpl->mbInFocusHdl = FALSE; // TRUE: Innerhalb vom GetFocus-Handler
mpWindowImpl->mbCreatedWithToolkit = FALSE;
mpWindowImpl->mbSuppressAccessibilityEvents = FALSE; // TRUE: do not send any accessibility events
mpWindowImpl->mbDrawSelectionBackground = FALSE; // TRUE: draws transparent window background to indicate (toolbox) selection
mpWindowImpl->mbIsInTaskPaneList = FALSE; // TRUE: window was added to the taskpanelist in the topmost system window
mpWindowImpl->mnNativeBackground = 0; // initialize later, depends on type
mpWindowImpl->mbCallHandlersDuringInputDisabled = FALSE; // TRUE: call event handlers even if input is disabled
mpWindowImpl->mbDisableAccessibleLabelForRelation = FALSE; // TRUE: do not set LabelFor relation on accessible objects
mpWindowImpl->mbDisableAccessibleLabeledByRelation = FALSE; // TRUE: do not set LabeledBy relation on accessible objects
mpWindowImpl->mbHelpTextDynamic = FALSE; // TRUE: append help id in HELP_DEBUG case
mpWindowImpl->mbFakeFocusSet = FALSE; // TRUE: pretend as if the window has focus.
mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // TRUE: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
}
// -----------------------------------------------------------------------
void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& /*aSystemWorkWindowToken*/ )
{
ImplInit( pParent, nStyle, NULL );
}
// -----------------------------------------------------------------------
void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
{
DBG_ASSERT( mpWindowImpl->mbFrame || pParent, "Window::Window(): pParent == NULL" );
ImplSVData* pSVData = ImplGetSVData();
Window* pRealParent = pParent;
// 3D-Look vererben
if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
nStyle |= WB_3DLOOK;
// create border window if necessary
if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
&& (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
{
USHORT nBorderTypeStyle = 0;
if( (nStyle & WB_SYSTEMCHILDWINDOW) )
{
// handle WB_SYSTEMCHILDWINDOW
// these should be analogous to a top level frame; meaning they
// should have a border window with style BORDERWINDOW_STYLE_FRAME
// which controls their size
nBorderTypeStyle |= BORDERWINDOW_STYLE_FRAME;
nStyle |= WB_BORDER;
}
ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle );
((Window*)pBorderWin)->mpWindowImpl->mpClientWindow = this;
pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
mpWindowImpl->mpBorderWindow = pBorderWin;
pParent = mpWindowImpl->mpBorderWindow;
}
else if( !mpWindowImpl->mbFrame && ! pParent )
{
mpWindowImpl->mbOverlapWin = TRUE;
mpWindowImpl->mbFrame = TRUE;
}
// insert window in list
ImplInsertWindow( pParent );
mpWindowImpl->mnStyle = nStyle;
// Overlap-Window-Daten
if ( mpWindowImpl->mbOverlapWin )
{
mpWindowImpl->mpOverlapData = new ImplOverlapData;
mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL;
mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL;
mpWindowImpl->mpOverlapData->mpNextBackWin = NULL;
mpWindowImpl->mpOverlapData->mnSaveBackSize = 0;
mpWindowImpl->mpOverlapData->mbSaveBack = FALSE;
mpWindowImpl->mpOverlapData->mnTopLevel = 1;
}
if( pParent && ! mpWindowImpl->mbFrame )
mbEnableRTL = pParent->mbEnableRTL;
// test for frame creation
if ( mpWindowImpl->mbFrame )
{
// create frame
ULONG nFrameStyle = 0;
if ( nStyle & WB_MOVEABLE )
nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE;
if ( nStyle & WB_SIZEABLE )
nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE;
if ( nStyle & WB_CLOSEABLE )
nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE;
if ( nStyle & WB_APP )
nFrameStyle |= SAL_FRAME_STYLE_DEFAULT;
// check for undecorated floating window
if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
( !(nFrameStyle & ~SAL_FRAME_STYLE_CLOSEABLE) &&
( mpWindowImpl->mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
// 2. borderwindows of floaters with ownerdraw decoration
( ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) ) )
{
nFrameStyle = SAL_FRAME_STYLE_FLOAT;
if( nStyle & WB_OWNERDRAWDECORATION )
nFrameStyle |= (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_NOSHADOW);
if( nStyle & WB_NEEDSFOCUS )
nFrameStyle |= SAL_FRAME_STYLE_FLOAT_FOCUSABLE;
}
else if( mpWindowImpl->mbFloatWin )
nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW;
if( nStyle & WB_INTROWIN )
nFrameStyle |= SAL_FRAME_STYLE_INTRO;
if( nStyle & WB_TOOLTIPWIN )
nFrameStyle |= SAL_FRAME_STYLE_TOOLTIP;
if( nStyle & WB_NOSHADOW )
nFrameStyle |= SAL_FRAME_STYLE_NOSHADOW;
if( nStyle & WB_SYSTEMCHILDWINDOW )
nFrameStyle |= SAL_FRAME_STYLE_SYSTEMCHILD;
switch (mpWindowImpl->mnType)
{
case WINDOW_DIALOG:
case WINDOW_TABDIALOG:
case WINDOW_MODALDIALOG:
case WINDOW_MODELESSDIALOG:
case WINDOW_MESSBOX:
case WINDOW_INFOBOX:
case WINDOW_WARNINGBOX:
case WINDOW_ERRORBOX:
case WINDOW_QUERYBOX:
nFrameStyle |= SAL_FRAME_STYLE_DIALOG;
default:
break;
}
SalFrame* pParentFrame = NULL;
if ( pParent )
pParentFrame = pParent->mpWindowImpl->mpFrame;
SalFrame* pFrame;
if ( pSystemParentData )
pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_PLUG );
else
pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
if ( !pFrame )
{
// do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
throw ::com::sun::star::uno::RuntimeException(
OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system window!" ) ),
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
//GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
}
pFrame->SetCallback( this, ImplWindowFrameProc );
// set window frame data
mpWindowImpl->mpFrameData = new ImplFrameData;
mpWindowImpl->mpFrame = pFrame;
mpWindowImpl->mpFrameWindow = this;
mpWindowImpl->mpOverlapWindow = this;
// set frame data
mpWindowImpl->mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame;
pSVData->maWinData.mpFirstFrame = this;
mpWindowImpl->mpFrameData->mpFirstOverlap = NULL;
mpWindowImpl->mpFrameData->mpFocusWin = NULL;
mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
mpWindowImpl->mpFrameData->mpFirstBackWin = NULL;
mpWindowImpl->mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList;
mpWindowImpl->mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache;
mpWindowImpl->mpFrameData->mnAllSaveBackSize = 0;
mpWindowImpl->mpFrameData->mnFocusId = 0;
mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
mpWindowImpl->mpFrameData->mnLastMouseX = -1;
mpWindowImpl->mpFrameData->mnLastMouseY = -1;
mpWindowImpl->mpFrameData->mnBeforeLastMouseX = -1;
mpWindowImpl->mpFrameData->mnBeforeLastMouseY = -1;
mpWindowImpl->mpFrameData->mnFirstMouseX = -1;
mpWindowImpl->mpFrameData->mnFirstMouseY = -1;
mpWindowImpl->mpFrameData->mnLastMouseWinX = -1;
mpWindowImpl->mpFrameData->mnLastMouseWinY = -1;
mpWindowImpl->mpFrameData->mnModalMode = 0;
mpWindowImpl->mpFrameData->mnMouseDownTime = 0;
mpWindowImpl->mpFrameData->mnClickCount = 0;
mpWindowImpl->mpFrameData->mnFirstMouseCode = 0;
mpWindowImpl->mpFrameData->mnMouseCode = 0;
mpWindowImpl->mpFrameData->mnMouseMode = 0;
mpWindowImpl->mpFrameData->meMapUnit = MAP_PIXEL;
mpWindowImpl->mpFrameData->mbHasFocus = FALSE;
mpWindowImpl->mpFrameData->mbInMouseMove = FALSE;
mpWindowImpl->mpFrameData->mbMouseIn = FALSE;
mpWindowImpl->mpFrameData->mbStartDragCalled = FALSE;
mpWindowImpl->mpFrameData->mbNeedSysWindow = FALSE;
mpWindowImpl->mpFrameData->mbMinimized = FALSE;
mpWindowImpl->mpFrameData->mbStartFocusState = FALSE;
mpWindowImpl->mpFrameData->mbInSysObjFocusHdl = FALSE;
mpWindowImpl->mpFrameData->mbInSysObjToTopHdl = FALSE;
mpWindowImpl->mpFrameData->mbSysObjFocus = FALSE;
mpWindowImpl->mpFrameData->maPaintTimer.SetTimeout( 30 );
mpWindowImpl->mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
mpWindowImpl->mpFrameData->maResizeTimer.SetTimeout( 50 );
mpWindowImpl->mpFrameData->maResizeTimer.SetTimeoutHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = FALSE;
if ( pRealParent && IsTopWindow() )
{
ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
pParentWinData->maTopWindowChildren.push_back( this );
}
}
// init data
mpWindowImpl->mpRealParent = pRealParent;
// #99318: make sure fontcache and list is available before call to SetSettings
mpFontList = mpWindowImpl->mpFrameData->mpFontList;
mpFontCache = mpWindowImpl->mpFrameData->mpFontCache;
if ( mpWindowImpl->mbFrame )
{
if ( pParent )
{
mpWindowImpl->mpFrameData->mnDPIX = pParent->mpWindowImpl->mpFrameData->mnDPIX;
mpWindowImpl->mpFrameData->mnDPIY = pParent->mpWindowImpl->mpFrameData->mnDPIY;
}
else
{
if ( ImplGetGraphics() )
{
mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY );
}
}
// add ownerdraw decorated frame windows to list in the top-most frame window
// so they can be hidden on lose focus
if( nStyle & WB_OWNERDRAWDECORATION )
ImplGetOwnerDrawList().push_back( this );
// delay settings initialization until first "real" frame
// this relies on the IntroWindow not needing any system settings
if ( !pSVData->maAppData.mbSettingsInit &&
! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
)
{
// side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
pSVData->maAppData.mbSettingsInit = TRUE;
}
// 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) )
mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
}
else
{
if ( pParent )
{
if ( !ImplIsOverlapWindow() )
{
mpWindowImpl->mbDisabled = pParent->mpWindowImpl->mbDisabled;
mpWindowImpl->mbInputDisabled = pParent->mpWindowImpl->mbInputDisabled;
mpWindowImpl->meAlwaysInputMode = pParent->mpWindowImpl->meAlwaysInputMode;
}
OutputDevice::SetSettings( pParent->GetSettings() );
}
}
const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
USHORT nScreenZoom = rStyleSettings.GetScreenZoom();
mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
mnDPIY = (mpWindowImpl->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();
// calculate app font res (except for the Intro Window or the default window)
if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
ImplInitAppFontData( this );
if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() )
GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDCREATED, this );
}
// -----------------------------------------------------------------------
void Window::ImplSetFrameParent( const Window* pParent )
{
Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
while( pFrameWindow )
{
// search all frames that are children of this window
// and reparent them
if( ImplIsRealParentPath( pFrameWindow ) )
{
DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" );
DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" );
SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL;
pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
}
pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
}
}
// -----------------------------------------------------------------------
void Window::ImplInsertWindow( Window* pParent )
{
mpWindowImpl->mpParent = pParent;
mpWindowImpl->mpRealParent = pParent;
if ( pParent && !mpWindowImpl->mbFrame )
{
// search frame window and set window frame data
Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
mpWindowImpl->mpFrameWindow = pFrameParent;
mpWindowImpl->mbFrame = FALSE;
// search overlap window and insert window in list
if ( ImplIsOverlapWindow() )
{
Window* pFirstOverlapParent = pParent;
while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
mpWindowImpl->mpOverlapWindow = pFirstOverlapParent;
mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap;
mpWindowImpl->mpFrameData->mpFirstOverlap = this;
// Overlap-Windows sind per default die obersten
mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap;
pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this;
if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap )
pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this;
else
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
}
else
{
if ( pParent->ImplIsOverlapWindow() )
mpWindowImpl->mpOverlapWindow = pParent;
else
mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
pParent->mpWindowImpl->mpLastChild = this;
if ( !pParent->mpWindowImpl->mpFirstChild )
pParent->mpWindowImpl->mpFirstChild = this;
else
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
}
}
}
// -----------------------------------------------------------------------
void Window::ImplRemoveWindow( BOOL bRemoveFrameData )
{
// Fenster aus den Listen austragen
if ( !mpWindowImpl->mbFrame )
{
if ( ImplIsOverlapWindow() )
{
if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this )
mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap;
else
{
Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
while ( pTempWin->mpWindowImpl->mpNextOverlap != this )
pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap;
}
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
}
else
{
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
}
mpWindowImpl->mpPrev = NULL;
mpWindowImpl->mpNext = NULL;
}
if ( bRemoveFrameData )
{
// Graphic freigeben
ImplReleaseGraphics();
}
}
// -----------------------------------------------------------------------
void Window::ImplCallResize()
{
mpWindowImpl->mbCallResize = FALSE;
if( GetBackground().IsGradient() )
Invalidate();
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 );
}
// -----------------------------------------------------------------------
void Window::ImplCallMove()
{
mpWindowImpl->mbCallMove = FALSE;
if( mpWindowImpl->mbFrame )
{
// update frame position
SalFrame *pParentFrame = NULL;
Window *pParent = ImplGetParent();
while( pParent )
{
if( pParent->mpWindowImpl->mpFrame != mpWindowImpl->mpFrame )
{
pParentFrame = pParent->mpWindowImpl->mpFrame;
break;
}
pParent = pParent->GetParent();
}
SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
mpWindowImpl->maPos = Point( g.nX, g.nY );
if( pParentFrame )
{
g = pParentFrame->GetGeometry();
mpWindowImpl->maPos -= Point( g.nX, g.nY );
}
// the client window and and all its subclients have the same position as the borderframe
// this is important for floating toolbars where the borderwindow is a floating window
// which has another borderwindow (ie the system floating window)
Window *pClientWin = mpWindowImpl->mpClientWindow;
while( pClientWin )
{
pClientWin->mpWindowImpl->maPos = mpWindowImpl->maPos;
pClientWin = pClientWin->mpWindowImpl->mpClientWindow;
}
}
Move();
ImplCallEventListeners( VCLEVENT_WINDOW_MOVE );
}
// -----------------------------------------------------------------------
static ULONG ImplAutoHelpID( ResMgr* pResMgr )
{
if ( !Application::IsAutoHelpIdEnabled() )
return 0;
ULONG nHID = 0;
DBG_ASSERT( pResMgr, "No res mgr for auto help id" );
if( ! pResMgr )
return 0;
nHID = pResMgr->GetAutoHelpId();
return nHID;
}
// -----------------------------------------------------------------------
WinBits Window::ImplInitRes( const ResId& rResId )
{
GetRes( rResId );
char* pRes = (char*)GetClassRes();
pRes += 8;
sal_uInt32 nStyle = (sal_uInt32)GetLongRes( (void*)pRes );
rResId.SetWinBits( nStyle );
return nStyle;
}
// -----------------------------------------------------------------------
void Window::ImplLoadRes( const ResId& rResId )
{
// newer move this line after IncrementRes
char* pRes = (char*)GetClassRes();
pRes += 12;
sal_uInt32 nHelpId = (sal_uInt32)GetLongRes( (void*)pRes );
if ( !nHelpId )
nHelpId = ImplAutoHelpID( rResId.GetResMgr() );
SetHelpId( nHelpId );
ULONG nObjMask = ReadLongRes();
// ResourceStyle
ULONG nRSStyle = ReadLongRes();
// 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)ReadLongRes();
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)ReadLongRes();
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() );
mpWindowImpl->mbHelpTextDynamic = TRUE;
}
if ( nObjMask & WINDOW_QUICKTEXT )
SetQuickHelpText( ReadStringRes() );
if ( nObjMask & WINDOW_EXTRALONG )
SetData( (void*)ReadLongRes() );
if ( nObjMask & WINDOW_UNIQUEID )
SetUniqueId( (ULONG)ReadLongRes() );
if ( nObjMask & WINDOW_BORDER_STYLE )
{
USHORT nBorderStyle = (USHORT)ReadLongRes();
SetBorderStyle( nBorderStyle );
}
}
// -----------------------------------------------------------------------
ImplWinData* Window::ImplGetWinData() const
{
if ( !mpWindowImpl->mpWinData )
{
static const char* pNoNWF = getenv( "SAL_NO_NWF" );
((Window*)this)->mpWindowImpl->mpWinData = new ImplWinData;
mpWindowImpl->mpWinData->mpExtOldText = NULL;
mpWindowImpl->mpWinData->mpExtOldAttrAry = NULL;
mpWindowImpl->mpWinData->mpCursorRect = 0;
mpWindowImpl->mpWinData->mnCursorExtWidth = 0;
mpWindowImpl->mpWinData->mpFocusRect = NULL;
mpWindowImpl->mpWinData->mpTrackRect = NULL;
mpWindowImpl->mpWinData->mnTrackFlags = 0;
mpWindowImpl->mpWinData->mnIsTopWindow = (USHORT) ~0; // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
mpWindowImpl->mpWinData->mbMouseOver = FALSE;
mpWindowImpl->mpWinData->mbEnableNativeWidget = (pNoNWF && *pNoNWF) ? FALSE : TRUE; // TRUE: try to draw this control with native theme API
mpWindowImpl->mpWinData->mpSmartHelpId = NULL;
mpWindowImpl->mpWinData->mpSmartUniqueId = NULL;
}
return mpWindowImpl->mpWinData;
}
// -----------------------------------------------------------------------
SalGraphics* Window::ImplGetFrameGraphics() const
{
if ( mpWindowImpl->mpFrameWindow->mpGraphics )
mpWindowImpl->mpFrameWindow->mbInitClipRegion = TRUE;
else
mpWindowImpl->mpFrameWindow->ImplGetGraphics();
mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion();
return mpWindowImpl->mpFrameWindow->mpGraphics;
}
// -----------------------------------------------------------------------
Window* Window::ImplFindWindow( const Point& rFramePos )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
Window* pTempWindow;
Window* pFindWindow;
// Zuerst alle ueberlappenden Fenster ueberpruefen
pTempWindow = mpWindowImpl->mpFirstOverlap;
while ( pTempWindow )
{
pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
if ( pFindWindow )
return pFindWindow;
pTempWindow = pTempWindow->mpWindowImpl->mpNext;
}
// dann testen wir unser Fenster
if ( !mpWindowImpl->mbVisible )
return NULL;
USHORT nHitTest = ImplHitTest( rFramePos );
if ( nHitTest & WINDOW_HITTEST_INSIDE )
{
// und danach gehen wir noch alle Child-Fenster durch
pTempWindow = mpWindowImpl->mpFirstChild;
while ( pTempWindow )
{
pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
if ( pFindWindow )
return pFindWindow;
pTempWindow = pTempWindow->mpWindowImpl->mpNext;
}
if ( nHitTest & WINDOW_HITTEST_TRANSPARENT )
return NULL;
else
return this;
}
return NULL;
}
// -----------------------------------------------------------------------
USHORT Window::ImplHitTest( const Point& rFramePos )
{
Point aFramePos( rFramePos );
if( ImplIsAntiparallel() )
{
// - RTL - re-mirror frame pos at this window
ImplReMirror( aFramePos );
}
Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
if ( !aRect.IsInside( aFramePos ) )
return 0;
if ( mpWindowImpl->mbWinRegion )
{
Point aTempPos = aFramePos;
aTempPos.X() -= mnOutOffX;
aTempPos.Y() -= mnOutOffY;
if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
return 0;
}
USHORT nHitTest = WINDOW_HITTEST_INSIDE;
if ( mpWindowImpl->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 ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->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() && ! IsInModalMode() )
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->mpWindowImpl->mbNoPtrVisible )
return POINTER_NULL;
if ( !bWait )
{
if ( pWindow->mpWindowImpl->mnWaitCount )
{
ePointerStyle = POINTER_WAIT;
bWait = TRUE;
}
else
{
if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
ePointerStyle = pWindow->GetPointer().GetStyle();
}
}
if ( pWindow->ImplIsOverlapWindow() )
break;
pWindow = pWindow->ImplGetParent();
}
while ( pWindow );
return ePointerStyle;
}
// -----------------------------------------------------------------------
void Window::ImplResetReallyVisible()
{
BOOL bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
mbDevOutput = FALSE;
mpWindowImpl->mbReallyVisible = FALSE;
mpWindowImpl->mbReallyShown = FALSE;
// the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
// For this, the data member of the event must not be NULL.
// Previously, we did this in Window::Show, but there some events got lost in certain situations.
// #104887# - 2004-08-10 - fs@openoffice.org
if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
ImplCallEventListeners( VCLEVENT_WINDOW_HIDE, this );
// TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_HIDE. Normally, we should
// introduce another event which explicitly triggers the Accessibility implementations.
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbReallyVisible )
pWindow->ImplResetReallyVisible();
pWindow = pWindow->mpWindowImpl->mpNext;
}
pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbReallyVisible )
pWindow->ImplResetReallyVisible();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplSetReallyVisible()
{
// #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
// ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
// mbReallyShown is a useful indicator
if( !mpWindowImpl->mbReallyShown )
ImplCallInitShow();
BOOL bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;
mbDevOutput = TRUE;
mpWindowImpl->mbReallyVisible = TRUE;
mpWindowImpl->mbReallyShown = TRUE;
// the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
// For this, the data member of the event must not be NULL.
// Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
// we're doing it when the visibility really changes
// #104887# - 2004-08-10 - fs@openoffice.org
if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
ImplCallEventListeners( VCLEVENT_WINDOW_SHOW, this );
// TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_SHOW. Normally, we should
// introduce another event which explicitly triggers the Accessibility implementations.
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbVisible )
pWindow->ImplSetReallyVisible();
pWindow = pWindow->mpWindowImpl->mpNext;
}
pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbVisible )
pWindow->ImplSetReallyVisible();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplCallInitShow()
{
mpWindowImpl->mbReallyShown = TRUE;
mpWindowImpl->mbInInitShow = TRUE;
StateChanged( STATE_CHANGE_INITSHOW );
mpWindowImpl->mbInInitShow = FALSE;
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbVisible )
pWindow->ImplCallInitShow();
pWindow = pWindow->mpWindowImpl->mpNext;
}
pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbVisible )
pWindow->ImplCallInitShow();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok
{
DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" );
if( !pDel->mpWindow )
{
pDel->mpWindow = this; // #112873# store ref to this window, so pDel can remove itself
pDel->mpNext = mpWindowImpl->mpFirstDel;
mpWindowImpl->mpFirstDel = pDel;
}
}
// -----------------------------------------------------------------------
void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok
{
pDel->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
if ( mpWindowImpl->mpFirstDel == pDel )
mpWindowImpl->mpFirstDel = pDel->mpNext;
else
{
ImplDelData* pData = mpWindowImpl->mpFirstDel;
while ( pData->mpNext != pDel )
pData = pData->mpNext;
pData->mpNext = pDel->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplInitResolutionSettings()
{
// AppFont-Aufloesung und DPI-Aufloesung neu berechnen
if ( mpWindowImpl->mbFrame )
{
const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
USHORT nScreenZoom = rStyleSettings.GetScreenZoom();
mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
SetPointFont( rStyleSettings.GetAppFont() );
}
else if ( mpWindowImpl->mpParent )
{
mnDPIX = mpWindowImpl->mpParent->mnDPIX;
mnDPIY = mpWindowImpl->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() *= mpWindowImpl->mpFrameData->mnDPIX;
aSize.Width() += 72/2;
aSize.Width() /= 72;
aSize.Width() *= nScreenFontZoom;
aSize.Width() /= 100;
}
aSize.Height() *= mpWindowImpl->mpFrameData->mnDPIY;
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() += mpWindowImpl->mpFrameData->mnDPIX/2;
aSize.Width() /= mpWindowImpl->mpFrameData->mnDPIX;
}
aSize.Height() *= 100;
aSize.Height() /= nScreenFontZoom;
aSize.Height() *= 72;
aSize.Height() += mpWindowImpl->mpFrameData->mnDPIY/2;
aSize.Height() /= mpWindowImpl->mpFrameData->mnDPIY;
rFont.SetSize( aSize );
}
// -----------------------------------------------------------------------
BOOL Window::ImplSysObjClip( const Region* pOldRegion )
{
BOOL bUpdate = TRUE;
if ( mpWindowImpl->mpSysObj )
{
BOOL bVisibleState = mpWindowImpl->mbReallyVisible;
if ( bVisibleState )
{
Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
if ( !pWinChildClipRegion->IsEmpty() )
{
if ( pOldRegion )
{
Region aNewRegion = *pWinChildClipRegion;
pWinChildClipRegion->Intersect( *pOldRegion );
bUpdate = aNewRegion == *pWinChildClipRegion;
}
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
Region aRegion = *pWinChildClipRegion;
Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
Region aWinRectRegion( aWinRect );
USHORT nClipFlags = mpWindowImpl->mpSysObj->GetClipRegionType();
if ( aRegion == aWinRectRegion )
mpWindowImpl->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();
mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount );
bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
while ( bRegionRect )
{
mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
}
mpWindowImpl->mpSysObj->EndSetClipRegion();
}
}
else
bVisibleState = FALSE;
}
// Visible-Status updaten
mpWindowImpl->mpSysObj->Show( bVisibleState );
}
return bUpdate;
}
// -----------------------------------------------------------------------
void Window::ImplUpdateSysObjChildsClip()
{
if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion )
ImplSysObjClip( NULL );
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
pWindow->ImplUpdateSysObjChildsClip();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplUpdateSysObjOverlapsClip()
{
ImplUpdateSysObjChildsClip();
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
pWindow->ImplUpdateSysObjOverlapsClip();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplUpdateSysObjClip()
{
if ( !ImplIsOverlapWindow() )
{
ImplUpdateSysObjChildsClip();
// Schwestern muessen ihre ClipRegion auch neu berechnen
if ( mpWindowImpl->mbClipSiblings )
{
Window* pWindow = mpWindowImpl->mpNext;
while ( pWindow )
{
pWindow->ImplUpdateSysObjChildsClip();
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
}
else
mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip();
}
// -----------------------------------------------------------------------
BOOL Window::ImplSetClipFlagChilds( BOOL bSysObjOnlySmaller )
{
BOOL bUpdate = TRUE;
if ( mpWindowImpl->mpSysObj )
{
Region* pOldRegion = NULL;
if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion )
pOldRegion = new Region( mpWindowImpl->maWinClipRegion );
mbInitClipRegion = TRUE;
mpWindowImpl->mbInitWinClipRegion = TRUE;
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
bUpdate = FALSE;
pWindow = pWindow->mpWindowImpl->mpNext;
}
if ( !ImplSysObjClip( pOldRegion ) )
{
mbInitClipRegion = TRUE;
mpWindowImpl->mbInitWinClipRegion = TRUE;
bUpdate = FALSE;
}
if ( pOldRegion )
delete pOldRegion;
}
else
{
mbInitClipRegion = TRUE;
mpWindowImpl->mbInitWinClipRegion = TRUE;
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
bUpdate = FALSE;
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
return bUpdate;
}
// -----------------------------------------------------------------------
BOOL Window::ImplSetClipFlagOverlapWindows( BOOL bSysObjOnlySmaller )
{
BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
bUpdate = FALSE;
pWindow = pWindow->mpWindowImpl->mpNext;
}
return bUpdate;
}
// -----------------------------------------------------------------------
BOOL Window::ImplSetClipFlag( BOOL bSysObjOnlySmaller )
{
if ( !ImplIsOverlapWindow() )
{
BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
Window* pParent = ImplGetParent();
if ( pParent &&
((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP)) )
{
pParent->mbInitClipRegion = TRUE;
pParent->mpWindowImpl->mbInitChildRegion = TRUE;
}
// Schwestern muessen ihre ClipRegion auch neu berechnen
if ( mpWindowImpl->mbClipSiblings )
{
Window* pWindow = mpWindowImpl->mpNext;
while ( pWindow )
{
if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
bUpdate = FALSE;
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
return bUpdate;
}
else
return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
}
// -----------------------------------------------------------------------
void Window::ImplIntersectWindowClipRegion( Region& rRegion )
{
if ( mpWindowImpl->mbInitWinClipRegion )
ImplInitWinClipRegion();
rRegion.Intersect( mpWindowImpl->maWinClipRegion );
}
// -----------------------------------------------------------------------
void Window::ImplIntersectWindowRegion( Region& rRegion )
{
rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ),
Size( mnOutWidth, mnOutHeight ) ) );
if ( mpWindowImpl->mbWinRegion )
rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
}
// -----------------------------------------------------------------------
void Window::ImplExcludeWindowRegion( Region& rRegion )
{
if ( mpWindowImpl->mbWinRegion )
{
Point aPoint( mnOutOffX, mnOutOffY );
Region aRegion( Rectangle( aPoint,
Size( mnOutWidth, mnOutHeight ) ) );
aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
rRegion.Exclude( aRegion );
}
else
{
Point aPoint( mnOutOffX, mnOutOffY );
rRegion.Exclude( Rectangle( aPoint,
Size( mnOutWidth, mnOutHeight ) ) );
}
}
// -----------------------------------------------------------------------
void Window::ImplExcludeOverlapWindows( Region& rRegion )
{
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbReallyVisible )
{
pWindow->ImplExcludeWindowRegion( rRegion );
pWindow->ImplExcludeOverlapWindows( rRegion );
}
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplExcludeOverlapWindows2( Region& rRegion )
{
if ( mpWindowImpl->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 ( !mpWindowImpl->mbFrame )
rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
if ( bOverlaps && !rRegion.IsEmpty() )
{
// Clip Overlap Siblings
Window* pStartOverlapWindow = this;
while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
{
Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
{
pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
}
pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
}
// Clip Child Overlap Windows
ImplExcludeOverlapWindows( rRegion );
}
}
else
ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
}
// -----------------------------------------------------------------------
BOOL Window::ImplClipChilds( Region& rRegion )
{
BOOL bOtherClip = FALSE;
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->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->mpWindowImpl->mpNext;
}
return bOtherClip;
}
// -----------------------------------------------------------------------
void Window::ImplClipAllChilds( Region& rRegion )
{
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbReallyVisible )
pWindow->ImplExcludeWindowRegion( rRegion );
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplClipSiblings( Region& rRegion )
{
Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow == this )
break;
if ( pWindow->mpWindowImpl->mbReallyVisible )
pWindow->ImplExcludeWindowRegion( rRegion );
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplInitWinClipRegion()
{
// Build Window Region
mpWindowImpl->maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ),
Size( mnOutWidth, mnOutHeight ) );
if ( mpWindowImpl->mbWinRegion )
mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
// ClipSiblings
if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() )
ImplClipSiblings( mpWindowImpl->maWinClipRegion );
// Clip Parent Boundaries
ImplClipBoundaries( mpWindowImpl->maWinClipRegion, FALSE, TRUE );
// Clip Children
if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren )
mpWindowImpl->mbInitChildRegion = TRUE;
mpWindowImpl->mbInitWinClipRegion = FALSE;
}
// -----------------------------------------------------------------------
void Window::ImplInitWinChildClipRegion()
{
if ( !mpWindowImpl->mpFirstChild )
{
if ( mpWindowImpl->mpChildClipRegion )
{
delete mpWindowImpl->mpChildClipRegion;
mpWindowImpl->mpChildClipRegion = NULL;
}
}
else
{
if ( !mpWindowImpl->mpChildClipRegion )
mpWindowImpl->mpChildClipRegion = new Region( mpWindowImpl->maWinClipRegion );
else
*mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion;
ImplClipChilds( *mpWindowImpl->mpChildClipRegion );
}
mpWindowImpl->mbInitChildRegion = FALSE;
}
// -----------------------------------------------------------------------
Region* Window::ImplGetWinChildClipRegion()
{
if ( mpWindowImpl->mbInitWinClipRegion )
ImplInitWinClipRegion();
if ( mpWindowImpl->mbInitChildRegion )
ImplInitWinChildClipRegion();
if ( mpWindowImpl->mpChildClipRegion )
return mpWindowImpl->mpChildClipRegion;
else
return &mpWindowImpl->maWinClipRegion;
}
// -----------------------------------------------------------------------
void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion )
{
Window* pWindow = mpWindowImpl->mpFirstOverlap;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbReallyVisible )
{
Region aTempRegion( rInterRegion );
pWindow->ImplIntersectWindowRegion( aTempRegion );
rRegion.Union( aTempRegion );
pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
}
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion )
{
if ( mpWindowImpl->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 = mpWindowImpl->mpOverlapWindow;
else
pStartOverlapWindow = this;
while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
{
Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
{
pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
}
pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
}
// Clip Child Overlap Windows
if ( !ImplIsOverlapWindow() )
mpWindowImpl->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 ( mpWindowImpl->mbWinRegion )
rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->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->mpWindowImpl->mbFrame )
{
aTempRegion = aRegion;
aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
rRegion.Union( aTempRegion );
}
}
// Siblings
if ( bSiblings && !ImplIsOverlapWindow() )
{
pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
do
{
if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) )
{
aTempRegion = aRegion;
pWindow->ImplIntersectWindowRegion( aTempRegion );
rRegion.Union( aTempRegion );
}
pWindow = pWindow->mpWindowImpl->mpNext;
}
while ( pWindow );
}
// Childs
if ( bChilds )
{
pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
if ( pWindow->mpWindowImpl->mbReallyVisible )
{
aTempRegion = aRegion;
pWindow->ImplIntersectWindowRegion( aTempRegion );
rRegion.Union( aTempRegion );
}
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
}
// -----------------------------------------------------------------------
void Window::ImplCallPaint( const Region* pRegion, USHORT nPaintFlags )
{
// call PrePaint. PrePaint may add to the invalidate region as well as
// other parameters used below.
PrePaint();
mpWindowImpl->mbPaintFrame = FALSE;
if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDS | (nPaintFlags & IMPL_PAINT_PAINTALL);
if ( nPaintFlags & IMPL_PAINT_PAINTCHILDS )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS;
if ( nPaintFlags & IMPL_PAINT_ERASE )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
if ( nPaintFlags & IMPL_PAINT_CHECKRTL )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
if ( !mpWindowImpl->mpFirstChild )
mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDS;
if ( mpWindowImpl->mbPaintDisabled )
{
if ( mpWindowImpl->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 = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT);
Region* pChildRegion = NULL;
Rectangle aSelectionRect;
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
{
Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
mpWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
else
{
if ( pRegion )
mpWindowImpl->maInvalidateRegion.Union( *pRegion );
if( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible )
/* #98602# need to repaint all children within the
* tracking rectangle, so the following invert
* operation takes places without traces of the previous
* one.
*/
mpWindowImpl->maInvalidateRegion.Union( *mpWindowImpl->mpWinData->mpTrackRect );
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
pChildRegion = new Region( mpWindowImpl->maInvalidateRegion );
mpWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion );
}
mpWindowImpl->mnPaintFlags = 0;
if ( !mpWindowImpl->maInvalidateRegion.IsEmpty() )
{
if ( mpWindowImpl->mpCursor )
mpWindowImpl->mpCursor->ImplHide();
mbInitClipRegion = TRUE;
mpWindowImpl->mbInPaint = TRUE;
// Paint-Region zuruecksetzen
Region aPaintRegion( mpWindowImpl->maInvalidateRegion );
Rectangle aPaintRect = aPaintRegion.GetBoundRect();
// - RTL - re-mirror paint rect and region at this window
if( ImplIsAntiparallel() )
{
ImplReMirror( aPaintRect );
ImplReMirror( aPaintRegion );
}
aPaintRect = ImplDevicePixelToLogic( aPaintRect);
mpWindowImpl->mpPaintRegion = &aPaintRegion;
mpWindowImpl->maInvalidateRegion.SetEmpty();
if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() )
{
if ( IsClipRegion() )
{
Region aOldRegion = GetClipRegion();
SetClipRegion();
Erase();
SetClipRegion( aOldRegion );
}
else
Erase();
}
// #98943# trigger drawing of toolbox selection after all childern are painted
if( mpWindowImpl->mbDrawSelectionBackground )
aSelectionRect = aPaintRect;
Paint( aPaintRect );
if ( mpWindowImpl->mpWinData )
{
if ( mpWindowImpl->mbFocusVisible )
ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
}
mpWindowImpl->mbInPaint = FALSE;
mbInitClipRegion = TRUE;
mpWindowImpl->mpPaintRegion = NULL;
if ( mpWindowImpl->mpCursor )
mpWindowImpl->mpCursor->ImplShow( FALSE );
}
}
else
mpWindowImpl->mnPaintFlags = 0;
if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDS | IMPL_PAINT_PAINTCHILDS) )
{
// die Childfenster ausgeben
Window* pTempWindow = mpWindowImpl->mpFirstChild;
while ( pTempWindow )
{
if ( pTempWindow->mpWindowImpl->mbVisible )
pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags );
pTempWindow = pTempWindow->mpWindowImpl->mpNext;
}
}
if ( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
/* #98602# need to invert the tracking rect AFTER
* the children have painted
*/
InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
// #98943# draw toolbox selection
if( !aSelectionRect.IsEmpty() )
DrawSelectionBackground( aSelectionRect, 3, FALSE, TRUE, FALSE );
if ( pChildRegion )
delete pChildRegion;
}
// -----------------------------------------------------------------------
void Window::ImplCallOverlapPaint()
{
// Zuerst geben wir die ueberlappenden Fenster aus
Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
while ( pTempWindow )
{
if ( pTempWindow->mpWindowImpl->mbReallyVisible )
pTempWindow->ImplCallOverlapPaint();
pTempWindow = pTempWindow->mpWindowImpl->mpNext;
}
// und dann erst uns selber
if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
{
// - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
// because we were called from the Sal layer
ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
}
}
// -----------------------------------------------------------------------
void Window::ImplPostPaint()
{
if ( !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
mpWindowImpl->mpFrameData->maPaintTimer.Start();
}
// -----------------------------------------------------------------------
IMPL_LINK( Window, ImplHandlePaintHdl, void*, EMPTYARG )
{
// save paint events until resizing is done
if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
mpWindowImpl->mpFrameData->maPaintTimer.Start();
else if ( mpWindowImpl->mbReallyVisible )
ImplCallOverlapPaint();
return 0;
}
// -----------------------------------------------------------------------
IMPL_LINK( Window, ImplHandleResizeTimerHdl, void*, EMPTYARG )
{
if( mpWindowImpl->mbReallyVisible )
{
ImplCallResize();
if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
{
mpWindowImpl->mpFrameData->maPaintTimer.Stop();
mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL );
}
}
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;
USHORT nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0;
do
{
pTempWindow = pTempWindow->ImplGetParent();
if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS )
break;
pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS | nTranspPaint;
if( ! pTempWindow->IsPaintTransparent() )
nTranspPaint = 0;
}
while ( !pTempWindow->ImplIsOverlapWindow() );
}
// Paint-Flags setzen
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT;
if ( nFlags & INVALIDATE_CHILDREN )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDS;
if ( !(nFlags & INVALIDATE_NOERASE) )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
if ( !pRegion )
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL;
// Wenn nicht alles neu ausgegeben werden muss, dann die Region
// dazupacken
if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) )
mpWindowImpl->maInvalidateRegion.Union( *pRegion );
// Handle transparent windows correctly: invalidate must be done on the first opaque parent
if( ((IsPaintTransparent() && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
&& ImplGetParent() )
{
Window *pParent = ImplGetParent();
while( pParent && pParent->IsPaintTransparent() )
pParent = pParent->ImplGetParent();
if( pParent )
{
Region *pChildRegion;
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
// invalidate the whole child window region in the parent
pChildRegion = ImplGetWinChildClipRegion();
else
// invalidate the same region in the parent that has to be repainted in the child
pChildRegion = &mpWindowImpl->maInvalidateRegion;
nFlags |= INVALIDATE_CHILDREN; // paint should also be done on all children
nFlags &= ~INVALIDATE_NOERASE; // parent should paint and erase to create proper background
pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
}
}
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 = mpWindowImpl->mpFirstOverlap;
while ( pTempWindow )
{
if ( pTempWindow->IsVisible() )
pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
pTempWindow = pTempWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplInvalidateParentFrameRegion( Region& rRegion )
{
if ( mpWindowImpl->mbOverlapWin )
mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
else
{
if( ImplGetParent() )
ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN );
}
}
// -----------------------------------------------------------------------
void Window::ImplInvalidate( const Region* pRegion, USHORT nFlags )
{
// Hintergrund-Sicherung zuruecksetzen
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
// Feststellen, was neu ausgegeben werden muss
BOOL bInvalidateAll = !pRegion;
// Transparent-Invalidate beruecksichtigen
Window* pOpaqueWindow = this;
if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
{
Window* pTempWindow = pOpaqueWindow->ImplGetParent();
while ( pTempWindow )
{
if ( !pTempWindow->IsPaintTransparent() )
{
pOpaqueWindow = 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 ( GetStyle() & WB_CLIPCHILDREN )
nFlags |= INVALIDATE_NOCHILDREN;
else
nFlags |= INVALIDATE_CHILDREN;
}
if ( (nFlags & INVALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
bInvalidateAll = FALSE;
if ( bInvalidateAll )
ImplInvalidateFrameRegion( NULL, nFlags );
else
{
Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
Region aRegion( aRect );
if ( pRegion )
{
// --- RTL --- remirror region before intersecting it
if ( ImplIsAntiparallel() )
{
Region aRgn( *pRegion );
ImplReMirror( aRgn );
aRegion.Intersect( aRgn );
}
else
aRegion.Intersect( *pRegion );
}
ImplClipBoundaries( aRegion, TRUE, TRUE );
if ( nFlags & INVALIDATE_NOCHILDREN )
{
nFlags &= ~INVALIDATE_CHILDREN;
if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) )
{
if ( nOrgFlags & INVALIDATE_NOCHILDREN )
ImplClipAllChilds( aRegion );
else
{
if ( ImplClipChilds( aRegion ) )
nFlags |= INVALIDATE_CHILDREN;
}
}
}
if ( !aRegion.IsEmpty() )
ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
}
if ( nFlags & INVALIDATE_UPDATE )
pOpaqueWindow->Update(); // start painting at the opaque parent
}
// -----------------------------------------------------------------------
void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
long nHorzScroll, long nVertScroll,
BOOL bChilds )
{
if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
{
Region aTempRegion = mpWindowImpl->maInvalidateRegion;
aTempRegion.Intersect( rRect );
aTempRegion.Move( nHorzScroll, nVertScroll );
mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
}
if ( bChilds && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS) )
{
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, TRUE );
pWindow = pWindow->mpWindowImpl->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->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
{
if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
{
aPaintAllRegion.SetEmpty();
break;
}
else
aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
}
}
while ( !pPaintAllWindow->ImplIsOverlapWindow() );
if ( !aPaintAllRegion.IsEmpty() )
{
aPaintAllRegion.Move( nHorzScroll, nVertScroll );
USHORT nPaintFlags = 0;
if ( bChilds )
mpWindowImpl->mnPaintFlags |= INVALIDATE_CHILDREN;
ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
}
}
}
// -----------------------------------------------------------------------
void Window::ImplValidateFrameRegion( const Region* pRegion, USHORT nFlags )
{
if ( !pRegion )
mpWindowImpl->maInvalidateRegion.SetEmpty();
else
{
// Wenn alle Childfenster neu ausgegeben werden muessen,
// dann invalidieren wir diese vorher
if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS) && mpWindowImpl->mpFirstChild )
{
Region aChildRegion = mpWindowImpl->maInvalidateRegion;
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
{
Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
aChildRegion = aRect;
}
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
pChild = pChild->mpWindowImpl->mpNext;
}
}
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
{
Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
mpWindowImpl->maInvalidateRegion = aRect;
}
mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
}
mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
if ( nFlags & VALIDATE_CHILDREN )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->ImplValidateFrameRegion( pRegion, nFlags );
pChild = pChild->mpWindowImpl->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) && mpWindowImpl->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 ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
if ( mpWindowImpl->mpCursor )
mpWindowImpl->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 ( !mpWindowImpl->mpFirstChild )
bScrollChilds = FALSE;
// --- RTL --- check if this window requires special action
BOOL bReMirror = ( ImplIsAntiparallel() );
Rectangle aRectMirror( rRect );
if( bReMirror )
{
// --- RTL --- make sure the invalidate region of this window is
// computed in the same coordinate space as the one from the overlap windows
ImplReMirror( aRectMirror );
}
// Paint-Bereiche anpassen
ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChilds );
if ( !(nFlags & SCROLL_NOINVALIDATE) )
{
ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChilds, TRUE, FALSE );
// --- RTL ---
// if the scrolling on the device is performed in the opposite direction
// then move the overlaps in that direction to compute the invalidate region
// on the correct side, i.e., revert nHorzScroll
if ( !aInvalidateRegion.IsEmpty() )
{
aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
bErase = TRUE;
}
if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) )
{
Rectangle aDestRect( aRectMirror );
aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
Region aWinInvalidateRegion( aRectMirror );
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 ( mpWindowImpl->mbWinRegion )
aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->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 ( mpWindowImpl->mpWinData )
{
if ( mpWindowImpl->mbFocusVisible )
ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
}
SalGraphics* pGraphics = ImplGetFrameGraphics();
if ( pGraphics )
{
if( bReMirror )
{
// --- RTL --- frame coordinates require re-mirroring
ImplReMirror( aRegion );
}
ImplSelectClipRegion( aRegion, pGraphics );
pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
rRect.Left(), rRect.Top(),
rRect.GetWidth(), rRect.GetHeight(),
SAL_COPYAREA_WINDOWINVALIDATE, this );
}
if ( mpWindowImpl->mpWinData )
{
if ( mpWindowImpl->mbFocusVisible )
ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
}
}
if ( !aInvalidateRegion.IsEmpty() )
{
// --- RTL --- the invalidate region for this windows is already computed in frame coordinates
// so it has to be re-mirrored before calling the Paint-handler
mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
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 )
{
Window* pWindow = mpWindowImpl->mpFirstChild;
while ( pWindow )
{
Point aPos = pWindow->GetPosPixel();
aPos += Point( nHorzScroll, nVertScroll );
pWindow->SetPosPixel( aPos );
pWindow = pWindow->mpWindowImpl->mpNext;
}
}
if ( nFlags & SCROLL_UPDATE )
Update();
if ( mpWindowImpl->mpCursor )
mpWindowImpl->mpCursor->ImplShow( FALSE );
}
// -----------------------------------------------------------------------
void Window::ImplUpdateAll( BOOL bOverlapWindows )
{
if ( !mpWindowImpl->mbReallyVisible )
return;
BOOL bFlush = FALSE;
if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
{
Point aPoint( 0, 0 );
Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
ImplInvalidateOverlapFrameRegion( aRegion );
if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->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->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
pWindow->ImplCallPaint( NULL, pWindow->mpWindowImpl->mnPaintFlags );
}
if ( bFlush )
Flush();
}
// -----------------------------------------------------------------------
void Window::ImplUpdateWindowPtr( Window* pWindow )
{
if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
{
// Graphic freigeben
ImplReleaseGraphics();
}
mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData;
mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow;
if ( pWindow->ImplIsOverlapWindow() )
mpWindowImpl->mpOverlapWindow = pWindow;
else
mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->ImplUpdateWindowPtr( pWindow );
pChild = pChild->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplUpdateWindowPtr()
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->ImplUpdateWindowPtr( this );
pChild = pChild->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplUpdateOverlapWindowPtr( BOOL bNewFrame )
{
BOOL bVisible = IsVisible();
Show( FALSE );
ImplRemoveWindow( bNewFrame );
Window* pRealParent = mpWindowImpl->mpRealParent;
ImplInsertWindow( ImplGetParent() );
mpWindowImpl->mpRealParent = pRealParent;
ImplUpdateWindowPtr();
if ( ImplUpdatePos() )
ImplUpdateSysObjPos();
if ( bNewFrame )
{
Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow )
{
Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
pOverlapWindow = pNextOverlapWindow;
}
}
if ( bVisible )
Show( TRUE );
}
// -----------------------------------------------------------------------
BOOL Window::ImplUpdatePos()
{
BOOL bSysChild = FALSE;
if ( ImplIsOverlapWindow() )
{
mnOutOffX = mpWindowImpl->mnX;
mnOutOffY = mpWindowImpl->mnY;
}
else
{
Window* pParent = ImplGetParent();
mnOutOffX = mpWindowImpl->mnX + pParent->mnOutOffX;
mnOutOffY = mpWindowImpl->mnY + pParent->mnOutOffY;
}
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
if ( pChild->ImplUpdatePos() )
bSysChild = TRUE;
pChild = pChild->mpWindowImpl->mpNext;
}
if ( mpWindowImpl->mpSysObj )
bSysChild = TRUE;
return bSysChild;
}
// -----------------------------------------------------------------------
void Window::ImplUpdateSysObjPos()
{
if ( mpWindowImpl->mpSysObj )
mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->ImplUpdateSysObjPos();
pChild = pChild->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplPosSizeWindow( long nX, long nY,
long nWidth, long nHeight, USHORT nFlags )
{
BOOL bNewPos = FALSE;
BOOL bNewSize = FALSE;
BOOL bNewWidth = FALSE;
BOOL bCopyBits = FALSE;
long nOldOutOffX = mnOutOffX;
long nOldOutOffY = mnOutOffY;
long nOldOutWidth = mnOutWidth;
long nOldOutHeight = mnOutHeight;
Region* pOverlapRegion = NULL;
Region* pOldRegion = NULL;
if ( IsReallyVisible() )
{
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
Size( nOldOutWidth, nOldOutHeight ) );
pOldRegion = new Region( aOldWinRect );
if ( mpWindowImpl->mbWinRegion )
pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
!mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
!HasPaintEvent() )
bCopyBits = TRUE;
}
BOOL bnXRecycled = FALSE; // avoid duplicate mirroring in RTL case
if ( nFlags & WINDOW_POSSIZE_WIDTH )
{
if(!( nFlags & WINDOW_POSSIZE_X ))
{
nX = mpWindowImpl->mnX;
nFlags |= WINDOW_POSSIZE_X;
bnXRecycled = TRUE; // we're using a mnX which was already mirrored in RTL case
}
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 )
{
long nOrgX = nX;
// --- RTL --- (compare the screen coordinates)
Point aPtDev( Point( nX+mnOutOffX, 0 ) );
if( ImplHasMirroredGraphics() )
{
mpGraphics->mirror( aPtDev.X(), this );
// #106948# always mirror our pos if our parent is not mirroring, even
// if we are also not mirroring
// --- RTL --- check if parent is in different coordinates
if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
{
// --- RTL --- (re-mirror at parent window)
nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
}
/* #i99166# An LTR window in RTL UI that gets sized only would be
expected to not moved its upper left point
*/
if( bnXRecycled )
{
if( ImplIsAntiparallel() )
{
aPtDev.X() = mpWindowImpl->mnAbsScreenX;
nOrgX = mpWindowImpl->maPos.X();
}
}
}
else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
{
// mirrored window in LTR UI
{
// --- RTL --- (re-mirror at parent window)
nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
}
}
// check maPos as well, as it could have been changed for client windows (ImplCallMove())
if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
{
if ( bCopyBits && !pOverlapRegion )
{
pOverlapRegion = new Region();
ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
Size( mnOutWidth, mnOutHeight ) ),
*pOverlapRegion, FALSE, TRUE, TRUE );
}
mpWindowImpl->mnX = nX;
mpWindowImpl->maPos.X() = nOrgX;
mpWindowImpl->mnAbsScreenX = aPtDev.X(); // --- RTL --- (store real screen pos)
bNewPos = TRUE;
}
}
if ( nFlags & WINDOW_POSSIZE_Y )
{
// check maPos as well, as it could have been changed for client windows (ImplCallMove())
if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
{
if ( bCopyBits && !pOverlapRegion )
{
pOverlapRegion = new Region();
ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
Size( mnOutWidth, mnOutHeight ) ),
*pOverlapRegion, FALSE, TRUE, TRUE );
}
mpWindowImpl->mnY = nY;
mpWindowImpl->maPos.Y() = nY;
bNewPos = TRUE;
}
}
/* if ( nFlags & (WINDOW_POSSIZE_X|WINDOW_POSSIZE_Y) )
{
POINT aPt;
aPt.x = mpWindowImpl->maPos.X();
aPt.y = mpWindowImpl->maPos.Y();
ClientToScreen( mpWindowImpl->mpFrame->maFrameData.mhWnd , &aPt );
mpWindowImpl->maPos.X() = aPt.x;
mpWindowImpl->maPos.Y() = aPt.y;
}
*/
if ( bNewPos || bNewSize )
{
BOOL bUpdateSysObjPos = FALSE;
if ( bNewPos )
bUpdateSysObjPos = ImplUpdatePos();
// the borderwindow always specifies the position for its client window
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
if ( mpWindowImpl->mpClientWindow )
{
mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->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
mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
if ( bNewPos )
{
if ( mpWindowImpl->mpClientWindow->IsVisible() )
{
mpWindowImpl->mpClientWindow->ImplCallMove();
}
else
{
mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = TRUE;
}
}
}
// else
// {
// if ( mpWindowImpl->mpBorderWindow )
// mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
// }
// Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor
// einem Show() kommt
if ( IsVisible() )
{
if ( bNewPos )
{
ImplCallMove();
}
if ( bNewSize )
{
ImplCallResize();
}
}
else
{
if ( bNewPos )
mpWindowImpl->mbCallMove = TRUE;
if ( bNewSize )
mpWindowImpl->mbCallResize = TRUE;
}
BOOL bUpdateSysObjClip = FALSE;
if ( IsReallyVisible() )
{
if ( bNewPos || bNewSize )
{
// Hintergrund-Sicherung zuruecksetzen
if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
ImplDeleteOverlapBackground();
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
// Clip-Flag neu setzen
bUpdateSysObjClip = !ImplSetClipFlag( TRUE );
}
// Fensterinhalt invalidieren ?
if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
{
if ( bNewPos )
{
BOOL bInvalidate = FALSE;
BOOL bParentPaint = TRUE;
if ( !ImplIsOverlapWindow() )
bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
if ( bCopyBits && bParentPaint && !HasPaintEvent() )
{
Point aPoint( mnOutOffX, mnOutOffY );
Region aRegion( Rectangle( aPoint,
Size( mnOutWidth, mnOutHeight ) ) );
if ( mpWindowImpl->mbWinRegion )
aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->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 );
SalGraphics* pGraphics = ImplGetFrameGraphics();
if ( pGraphics )
{
const bool bSelectClipRegion = ImplSelectClipRegion( aRegion, pGraphics );
if ( bSelectClipRegion )
{
pGraphics->CopyArea( mnOutOffX, mnOutOffY,
nOldOutOffX, nOldOutOffY,
nOldOutWidth, nOldOutHeight,
SAL_COPYAREA_WINDOWINVALIDATE, this );
}
else
bInvalidate = TRUE;
}
else
bInvalidate = TRUE;
if ( !bInvalidate )
{
if ( !pOverlapRegion->IsEmpty() )
ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN );
}
}
else
bInvalidate = TRUE;
}
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 ( mpWindowImpl->mbWinRegion )
aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->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 ( !mpWindowImpl->mbPaintTransparent )
ImplExcludeWindowRegion( aRegion );
ImplClipBoundaries( aRegion, FALSE, TRUE );
if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
ImplInvalidateParentFrameRegion( aRegion );
}
}
// System-Objekte anpassen
if ( bUpdateSysObjClip )
ImplUpdateSysObjClip();
if ( bUpdateSysObjPos )
ImplUpdateSysObjPos();
if ( bNewSize && mpWindowImpl->mpSysObj )
mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
}
if ( pOverlapRegion )
delete pOverlapRegion;
if ( pOldRegion )
delete pOldRegion;
}
// -----------------------------------------------------------------------
void Window::ImplToBottomChild()
{
if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) )
{
// Fenster an das Ende der Liste setzen
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
mpWindowImpl->mpNext = NULL;
}
}
// -----------------------------------------------------------------------
void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
{
DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
if ( !mpWindowImpl->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 = mpWindowImpl->mpFirstOverlap;
while ( pOverlap )
{
pOverlap->ImplCalcToTop( pPrevData );
if ( pPrevData->mpNext )
pPrevData = pPrevData->mpNext;
pOverlap = pOverlap->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplToTop( USHORT nFlags )
{
DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
if ( mpWindowImpl->mbFrame )
{
// Wenn in das externe Fenster geklickt wird, ist dieses
// dafuer zustaendig dafuer zu sorgen, das unser Frame
// nach vorne kommt
if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
!mpWindowImpl->mpFrameData->mbSysObjFocus &&
!mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
!mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
{
// 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;
if ( nFlags & TOTOP_GRABFOCUSONLY )
nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY;
mpWindowImpl->mpFrame->ToTop( nSysFlags );
}
}
}
else
{
if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this )
{
// Fenster aus der Liste entfernen
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
// AlwaysOnTop beruecksichtigen
BOOL bOnTop = IsAlwaysOnTopEnabled();
Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
if ( !bOnTop )
{
while ( pNextWin )
{
if ( !pNextWin->IsAlwaysOnTopEnabled() )
break;
pNextWin = pNextWin->mpWindowImpl->mpNext;
}
}
// TopLevel abpruefen
BYTE nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel;
while ( pNextWin )
{
if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) ||
(nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) )
break;
pNextWin = pNextWin->mpWindowImpl->mpNext;
}
// Fenster in die Liste wieder eintragen
mpWindowImpl->mpNext = pNextWin;
if ( pNextWin )
{
mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
pNextWin->mpWindowImpl->mpPrev = this;
}
else
{
mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
}
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
// ClipRegion muss von diesem Fenster und allen weiteren
// ueberlappenden Fenstern neu berechnet werden.
if ( IsReallyVisible() )
{
// Hintergrund-Sicherung zuruecksetzen
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
}
}
}
}
// -----------------------------------------------------------------------
void Window::ImplStartToTop( USHORT nFlags )
{
ImplCalcToTopData aStartData;
ImplCalcToTopData* pCurData;
ImplCalcToTopData* pNextData;
Window* pOverlapWindow;
if ( ImplIsOverlapWindow() )
pOverlapWindow = this;
else
pOverlapWindow = mpWindowImpl->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->mpWindowImpl->mpOverlapWindow;
}
while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
// Dann die Paint-Bereiche der ChildOverlap-Windows berechnen
pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
while ( pTempOverlapWindow )
{
pTempOverlapWindow->ImplCalcToTop( pCurData );
if ( pCurData->mpNext )
pCurData = pCurData->mpNext;
pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
}
// Dann die Fenster-Verkettung aendern
pTempOverlapWindow = pOverlapWindow;
do
{
pTempOverlapWindow->ImplToTop( nFlags );
pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
}
while ( !pTempOverlapWindow->mpWindowImpl->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->mpWindowImpl->mpBorderWindow )
{
if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS )
break;
}
pFocusWindow = pFocusWindow->ImplGetParent();
}
if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) &&
!pFocusWindow->HasChildPathFocus( TRUE ) )
pFocusWindow->GrabFocus();
}
if ( bReallyVisible )
ImplGenerateMouseMove();
}
// -----------------------------------------------------------------------
void Window::ImplShowAllOverlaps()
{
Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow )
{
if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
{
pOverlapWindow->Show( TRUE, SHOW_NOACTIVATE );
pOverlapWindow->mpWindowImpl->mbOverlapVisible = FALSE;
}
pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplHideAllOverlaps()
{
Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow )
{
if ( pOverlapWindow->IsVisible() )
{
pOverlapWindow->mpWindowImpl->mbOverlapVisible = TRUE;
pOverlapWindow->Show( FALSE );
}
pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
void Window::ImplCallMouseMove( USHORT nMouseCode, BOOL bModChanged )
{
if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible )
{
ULONG nTime = Time::GetSystemTicks();
long nX = mpWindowImpl->mpFrameData->mnLastMouseX;
long nY = mpWindowImpl->mpFrameData->mnLastMouseY;
USHORT nCode = nMouseCode;
USHORT nMode = mpWindowImpl->mpFrameData->mnMouseMode;
BOOL bLeave;
// Auf MouseLeave testen
if ( ((nX < 0) || (nY < 0) ||
(nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) ||
(nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) &&
!ImplGetSVData()->maWinData.mpCaptureWin )
bLeave = TRUE;
else
bLeave = FALSE;
nMode |= MOUSE_SYNTHETIC;
if ( bModChanged )
nMode |= MOUSE_MODIFIERCHANGED;
ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
}
}
// -----------------------------------------------------------------------
void Window::ImplGenerateMouseMove()
{
if ( !mpWindowImpl->mpFrameData->mnMouseMoveId )
Application::PostUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId, LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) );
}
// -----------------------------------------------------------------------
IMPL_LINK( Window, ImplGenerateMouseMoveHdl, void*, EMPTYARG )
{
mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
Window* pCaptureWin = ImplGetSVData()->maWinData.mpCaptureWin;
if( ! pCaptureWin ||
(pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame)
)
{
ImplCallMouseMove( mpWindowImpl->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->mpWindowImpl->mbActive = FALSE;
pSVData->maWinData.mpLastDeacWin->Deactivate();
if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin )
{
pLastRealWindow->mpWindowImpl->mbActive = TRUE;
pLastRealWindow->Activate();
}
}
pSVData->maWinData.mpLastDeacWin = NULL;
}
}
if ( bCallDeactivate )
{
if( pOldOverlapWindow->mpWindowImpl->mbActive )
{
pOldOverlapWindow->mpWindowImpl->mbActive = FALSE;
pOldOverlapWindow->Deactivate();
}
if ( pOldRealWindow != pOldOverlapWindow )
{
if( pOldRealWindow->mpWindowImpl->mbActive )
{
pOldRealWindow->mpWindowImpl->mbActive = FALSE;
pOldRealWindow->Deactivate();
}
}
}
if ( bCallActivate && ! pNewOverlapWindow->mpWindowImpl->mbActive )
{
if( ! pNewOverlapWindow->mpWindowImpl->mbActive )
{
pNewOverlapWindow->mpWindowImpl->mbActive = TRUE;
pNewOverlapWindow->Activate();
}
if ( pNewRealWindow != pNewOverlapWindow )
{
if( ! pNewRealWindow->mpWindowImpl->mbActive )
{
pNewRealWindow->mpWindowImpl->mbActive = TRUE;
pNewRealWindow->Activate();
}
}
}
}
static bool IsWindowFocused(const WindowImpl& rWinImpl)
{
if (rWinImpl.mpSysObj)
return true;
if (rWinImpl.mpFrameData->mbHasFocus)
return true;
if (rWinImpl.mbFakeFocusSet)
return true;
return false;
}
// -----------------------------------------------------------------------
void Window::ImplGrabFocus( USHORT nFlags )
{
// #143570# no focus for destructing windows
if( mpWindowImpl->mbInDtor )
return;
// some event listeners do really bad stuff
// => prepare for the worst
ImplDelData aDogTag( this );
// Currently the client window should always get the focus
// Should the border window at some point be focusable
// we need to change all GrabFocus() instances in VCL,
// e.g. in ToTop()
if ( mpWindowImpl->mpClientWindow )
{
// For a lack of design we need a little hack here to
// ensure that dialogs on close pass the focus back to
// the correct window
if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
!(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
)
mpWindowImpl->mpLastFocusWindow->GrabFocus();
else
mpWindowImpl->mpClientWindow->GrabFocus();
return;
}
else if ( mpWindowImpl->mbFrame )
{
// For a lack of design we need a little hack here to
// ensure that dialogs on close pass the focus back to
// the correct window
if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
!(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
)
{
mpWindowImpl->mpLastFocusWindow->GrabFocus();
return;
}
}
// If the Window is disabled, then we don't change the focus
if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
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
ImplSVData* pSVData = ImplGetSVData();
BOOL bAsyncFocusWaiting = FALSE;
Window *pFrame = pSVData->maWinData.mpFirstFrame;
while( pFrame )
{
if( pFrame != mpWindowImpl->mpFrameWindow && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
{
bAsyncFocusWaiting = TRUE;
break;
}
pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
}
bool bHasFocus = IsWindowFocused(*mpWindowImpl);
BOOL bMustNotGrabFocus = FALSE;
// #100242#, check parent hierarchy if some floater prohibits grab focus
Window *pParent = this;
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->mpWindowImpl->mbFloatWin && ((FloatingWindow*)pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) )
{
bMustNotGrabFocus = TRUE;
break;
}
pParent = pParent->mpWindowImpl->mpParent;
}
if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
{
// EndExtTextInput if it is not the same window
if ( pSVData->maWinData.mpExtTextInputWin &&
(pSVData->maWinData.mpExtTextInputWin != this) )
pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
// Dieses Fenster als letztes FocusWindow merken
Window* pOverlapWindow = ImplGetFirstOverlapWindow();
pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
mpWindowImpl->mpFrameData->mpFocusWin = this;
if( !bHasFocus )
{
// menue windows never get the system focus
// the application will keep the focus
if( bMustNotGrabFocus )
return;
else
{
// Hier setzen wir schon den Focus um, da ToTop() den Focus
// nicht auf ein anderes Fenster setzen darf
//DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
mpWindowImpl->mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS | SAL_FRAME_TOTOP_GRABFOCUS_ONLY );
return;
}
}
Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin;
ImplDelData aOldFocusDel( pOldFocusWindow );
pSVData->maWinData.mpFocusWin = this;
if ( pOldFocusWindow )
{
// Cursor hiden
if ( pOldFocusWindow->mpWindowImpl->mpCursor )
pOldFocusWindow->mpWindowImpl->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->mpWindowImpl->mbActive = TRUE;
pNewOverlapWindow->Activate();
if ( pNewRealWindow != pNewOverlapWindow )
{
pNewRealWindow->mpWindowImpl->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->mpWindowImpl->mbParentActive )
break;
}
pDeactivateParent = pDeactivateParent->ImplGetParent();
}
if ( pOldFocusWindow )
{
pActivateParent = this;
while ( pActivateParent )
{
pParent = pActivateParent;
if ( pParent->ImplIsChild( pOldFocusWindow ) )
break;
if ( pActivateParent->ImplIsOverlapWindow() )
{
if ( !pActivateParent->mpWindowImpl->mbParentActive )
break;
}
pActivateParent = pActivateParent->ImplGetParent();
}
}
else
{
if ( ImplIsOverlapWindow() )
pActivateParent = this;
else
pActivateParent = mpWindowImpl->mpOverlapWindow;
while ( pActivateParent )
{
if ( pActivateParent->ImplIsOverlapWindow() )
{
if ( !pActivateParent->mpWindowImpl->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->mpWindowImpl->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->mpWindowImpl->mbActive = TRUE;
pParent->Activate();
pActivateParent = pLastParent;
}
while ( pActivateParent != this );
*/
// call Get- and LoseFocus
if ( pOldFocusWindow && ! aOldFocusDel.IsDelete() )
{
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 )
{
if ( mpWindowImpl->mpSysObj )
{
mpWindowImpl->mpFrameData->mpFocusWin = this;
if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
mpWindowImpl->mpSysObj->GrabFocus();
}
if ( pSVData->maWinData.mpFocusWin == this )
{
if ( mpWindowImpl->mpCursor )
mpWindowImpl->mpCursor->ImplShow();
mpWindowImpl->mbInFocusHdl = TRUE;
mpWindowImpl->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 &&
! aOldFocusDel.IsDelete() &&
( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) )
mpWindowImpl->mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL;
NotifyEvent aNEvt( EVENT_GETFOCUS, this );
if ( !ImplCallPreNotify( aNEvt ) && !aDogTag.IsDelete() )
GetFocus();
if( !aDogTag.IsDelete() )
ImplCallActivateListeners( (pOldFocusWindow && ! aOldFocusDel.IsDelete()) ? pOldFocusWindow : NULL );
if( !aDogTag.IsDelete() )
{
mpWindowImpl->mnGetFocusFlags = 0;
mpWindowImpl->mbInFocusHdl = FALSE;
}
}
}
GetpApp()->FocusChanged();
ImplNewInputContext();
}
}
// -----------------------------------------------------------------------
void Window::ImplNewInputContext()
{
ImplSVData* pSVData = ImplGetSVData();
Window* pFocusWin = pSVData->maWinData.mpFocusWin;
if ( !pFocusWin )
return;
// Is InputContext changed?
const InputContext& rInputContext = pFocusWin->GetInputContext();
if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
return;
pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;
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;
}
// TODO: No display device uses ImplDirectFontSubstitution thingy, right? => remove it
ImplDirectFontSubstitution* pFontSubst = NULL;
//if( pFocusWin->mpOutDevData )
// pFontSubst = &pFocusWin->mpOutDevData->maDevFontSubst;
pFontEntry = pFocusWin->mpFontCache->GetFontEntry( pFocusWin->mpFontList,
rFont, aSize, static_cast<float>(aSize.Height()), pFontSubst );
if ( pFontEntry )
aNewContext.mpFont = &pFontEntry->maFontSelData;
}
aNewContext.meLanguage = rFont.GetLanguage();
aNewContext.mnOptions = rInputContext.GetOptions();
pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
if ( pFontEntry )
pFocusWin->mpFontCache->Release( pFontEntry );
}
// -----------------------------------------------------------------------
Window::Window( WindowType nType )
{
DBG_CTOR( Window, ImplDbgCheckWindow );
ImplInitWindowData( nType );
}
// -----------------------------------------------------------------------
Window::Window( Window* pParent, WinBits nStyle )
{
DBG_CTOR( Window, ImplDbgCheckWindow );
ImplInitWindowData( WINDOW_WINDOW );
ImplInit( pParent, nStyle, NULL );
}
// -----------------------------------------------------------------------
Window::Window( Window* pParent, const ResId& rResId )
{
DBG_CTOR( Window, ImplDbgCheckWindow );
ImplInitWindowData( WINDOW_WINDOW );
rResId.SetRT( RSC_WINDOW );
WinBits nStyle = ImplInitRes( rResId );
ImplInit( pParent, nStyle, NULL );
ImplLoadRes( rResId );
if ( !(nStyle & WB_HIDE) )
Show();
}
// -----------------------------------------------------------------------
#if OSL_DEBUG_LEVEL > 0
namespace
{
const sal_Char* lcl_getWindowClassName( const Window& i_rWindow )
{
return typeid( i_rWindow ).name();
}
}
#endif
// -----------------------------------------------------------------------
Window::~Window()
{
vcl::LazyDeletor<Window>::Undelete( this );
DBG_DTOR( Window, ImplDbgCheckWindow );
DBG_ASSERT( !mpWindowImpl->mbInDtor, "~Window - already in DTOR!" );
// remove Key and Mouse events issued by Application::PostKey/MouseEvent
Application::RemoveMouseAndKeyEvents( this );
// Dispose of the canvas implementation (which, currently, has an
// own wrapper window as a child to this one.
Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
if( xCanvas.is() )
{
uno::Reference < lang::XComponent > xCanvasComponent( xCanvas,
uno::UNO_QUERY );
if( xCanvasComponent.is() )
xCanvasComponent->dispose();
}
mpWindowImpl->mbInDtor = TRUE;
ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
// do not send child events for frames that were registered as native frames
if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible )
if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED, this );
// remove associated data structures from dockingmanager
ImplGetDockingManager()->RemoveWindow( this );
// remove ownerdraw decorated windows from list in the top-most frame window
if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
{
::std::vector< Window* >& rList = ImplGetOwnerDrawList();
::std::vector< Window* >::iterator p;
p = ::std::find( rList.begin(), rList.end(), this );
if( p != rList.end() )
rList.erase( p );
}
// shutdown drag and drop
::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY );
if( xDnDComponent.is() )
xDnDComponent->dispose();
if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
{
try
{
// deregister drop target listener
if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
{
Reference< XDragGestureRecognizer > xDragGestureRecognizer =
Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
if( xDragGestureRecognizer.is() )
{
xDragGestureRecognizer->removeDragGestureListener(
Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
}
mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
}
// shutdown drag and drop for this frame window
Reference< XComponent > xComponent( mpWindowImpl->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.
}
}
UnoWrapperBase* pWrapper = Application::GetUnoWrapper( FALSE );
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 ( mpWindowImpl->mxAccessible.is() )
{
::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xC( mpWindowImpl->mxAccessible, ::com::sun::star::uno::UNO_QUERY );
if ( xC.is() )
xC->dispose();
}
ImplSVData* pSVData = ImplGetSVData();
if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) )
ImplDestroyHelpWindow( true );
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" );
// #103442# DefModalDialogParent is now determined on-the-fly, so this pointer is unimportant now
//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 ( TRUE ) // always perform these tests in non-pro versions
{
ByteString aErrorStr;
BOOL bError = FALSE;
Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
while ( pTempWin )
{
if ( ImplIsRealParentPath( pTempWin ) )
{
bError = TRUE;
if ( aErrorStr.Len() )
aErrorStr += "; ";
aErrorStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
}
pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
}
if ( bError )
{
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") with living SystemWindow(s) destroyed: ";
aTempStr += aErrorStr;
DBG_ERROR( aTempStr.GetBuffer() );
GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
}
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->mpWindowImpl->mpFrameData->mpNextFrame;
}
if ( bError )
{
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") with living SystemWindow(s) destroyed: ";
aTempStr += aErrorStr;
DBG_ERROR( aTempStr.GetBuffer() );
GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
}
if ( mpWindowImpl->mpFirstChild )
{
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") with living Child(s) destroyed: ";
pTempWin = mpWindowImpl->mpFirstChild;
while ( pTempWin )
{
aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
pTempWin = pTempWin->mpWindowImpl->mpNext;
if ( pTempWin )
aTempStr += "; ";
}
DBG_ERROR( aTempStr.GetBuffer() );
GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
}
if ( mpWindowImpl->mpFirstOverlap )
{
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") with living SystemWindow(s) destroyed: ";
pTempWin = mpWindowImpl->mpFirstOverlap;
while ( pTempWin )
{
aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
pTempWin = pTempWin->mpWindowImpl->mpNext;
if ( pTempWin )
aTempStr += "; ";
}
DBG_ERROR( aTempStr.GetBuffer() );
GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
}
Window* pMyParent = this;
SystemWindow* pMySysWin = NULL;
while ( pMyParent )
{
if ( pMyParent->IsSystemWindow() )
pMySysWin = (SystemWindow*)pMyParent;
pMyParent = pMyParent->GetParent();
}
if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
{
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") still in TaskPanelList!";
DBG_ERROR( aTempStr.GetBuffer() );
GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
}
}
#endif
if( mpWindowImpl->mbIsInTaskPaneList )
{
Window* pMyParent = this;
SystemWindow* pMySysWin = NULL;
while ( pMyParent )
{
if ( pMyParent->IsSystemWindow() )
pMySysWin = (SystemWindow*)pMyParent;
pMyParent = pMyParent->GetParent();
}
if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
{
pMySysWin->GetTaskPaneList()->RemoveWindow( this );
}
else
{
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") not found in TaskPanelList!";
DBG_ERROR( aTempStr.GetBuffer() );
}
}
// 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;
}
// check if the focus window is our child
BOOL bHasFocussedChild = FALSE;
if( pSVData->maWinData.mpFocusWin && ImplIsRealParentPath( pSVData->maWinData.mpFocusWin ) )
{
// #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
bHasFocussedChild = TRUE;
#ifdef DBG_UTIL
ByteString aTempStr( "Window (" );
aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
aTempStr += ") with focussed child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
DBG_ERROR( aTempStr.GetBuffer() );
GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
#endif
}
// Wenn wir den Focus haben, dann den Focus auf ein anderes Fenster setzen
Window* pOverlapWindow = ImplGetFirstOverlapWindow();
if ( pSVData->maWinData.mpFocusWin == this
|| bHasFocussedChild ) // #122232#, see above, try some cleanup
{
if ( mpWindowImpl->mbFrame )
{
pSVData->maWinData.mpFocusWin = NULL;
pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
GetpApp()->FocusChanged();
}
else
{
Window* pParent = GetParent();
Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
// Bei ueberlappenden Fenstern wird der Focus auf den
// Parent vom naechsten FrameWindow gesetzt
if ( pBorderWindow )
{
if ( pBorderWindow->ImplIsOverlapWindow() )
pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
}
else if ( ImplIsOverlapWindow() )
pParent = mpWindowImpl->mpOverlapWindow;
if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
pParent->GrabFocus();
else
mpWindowImpl->mpFrameWindow->GrabFocus();
// If the focus was set back to 'this' set it to nothing
if ( pSVData->maWinData.mpFocusWin == this )
{
pSVData->maWinData.mpFocusWin = NULL;
pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
GetpApp()->FocusChanged();
}
}
}
if ( pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
// reset hint for DefModalDialogParent
if( pSVData->maWinData.mpActiveApplicationFrame == this )
pSVData->maWinData.mpActiveApplicationFrame = NULL;
// gemerkte Fenster zuruecksetzen
if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
mpWindowImpl->mpFrameData->mpFocusWin = NULL;
if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
// Deactivate-Window zuruecksetzen
if ( pSVData->maWinData.mpLastDeacWin == this )
pSVData->maWinData.mpLastDeacWin = NULL;
if ( mpWindowImpl->mbFrame )
{
if ( mpWindowImpl->mpFrameData->mnFocusId )
Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
}
// Graphic freigeben
ImplReleaseGraphics();
// Evt. anderen Funktion mitteilen, das das Fenster geloescht
// wurde
ImplDelData* pDelData = mpWindowImpl->mpFirstDel;
while ( pDelData )
{
pDelData->mbDel = TRUE;
pDelData->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
pDelData = pDelData->mpNext;
}
// Fenster aus den Listen austragen
ImplRemoveWindow( TRUE );
// de-register as "top window child" at our parent, if necessary
if ( mpWindowImpl->mbFrame )
{
BOOL bIsTopWindow = mpWindowImpl->mpWinData && ( mpWindowImpl->mpWinData->mnIsTopWindow == 1 );
if ( mpWindowImpl->mpRealParent && bIsTopWindow )
{
ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();
::std::list< Window* >::iterator myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
pParentWinData->maTopWindowChildren.end(), this );
DBG_ASSERT( myPos != pParentWinData->maTopWindowChildren.end(), "Window::~Window: inconsistency in top window chain!" );
if ( myPos != pParentWinData->maTopWindowChildren.end() )
pParentWinData->maTopWindowChildren.erase( myPos );
}
}
// Extra Window Daten loeschen
if ( mpWindowImpl->mpWinData )
{
if ( mpWindowImpl->mpWinData->mpExtOldText )
delete mpWindowImpl->mpWinData->mpExtOldText;
if ( mpWindowImpl->mpWinData->mpExtOldAttrAry )
delete mpWindowImpl->mpWinData->mpExtOldAttrAry;
if ( mpWindowImpl->mpWinData->mpCursorRect )
delete mpWindowImpl->mpWinData->mpCursorRect;
if ( mpWindowImpl->mpWinData->mpFocusRect )
delete mpWindowImpl->mpWinData->mpFocusRect;
if ( mpWindowImpl->mpWinData->mpTrackRect )
delete mpWindowImpl->mpWinData->mpTrackRect;
if ( mpWindowImpl->mpWinData->mpSmartHelpId )
delete mpWindowImpl->mpWinData->mpSmartHelpId;
if ( mpWindowImpl->mpWinData->mpSmartUniqueId )
delete mpWindowImpl->mpWinData->mpSmartUniqueId;
delete mpWindowImpl->mpWinData;
}
// Overlap-Window-Daten loeschen
if ( mpWindowImpl->mpOverlapData )
{
delete mpWindowImpl->mpOverlapData;
}
// Evt. noch BorderWindow oder Frame zerstoeren
if ( mpWindowImpl->mpBorderWindow )
delete mpWindowImpl->mpBorderWindow;
else if ( mpWindowImpl->mbFrame )
{
if ( pSVData->maWinData.mpFirstFrame == this )
pSVData->maWinData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
else
{
Window* pSysWin = pSVData->maWinData.mpFirstFrame;
while ( pSysWin->mpWindowImpl->mpFrameData->mpNextFrame != this )
pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
}
mpWindowImpl->mpFrame->SetCallback( NULL, NULL );
pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
delete mpWindowImpl->mpFrameData;
}
if ( mpWindowImpl->mpChildClipRegion )
delete mpWindowImpl->mpChildClipRegion;
delete mpWindowImpl->mpAccessibleInfos;
delete mpWindowImpl->mpControlFont;
// should be the last statements
delete mpWindowImpl; mpWindowImpl = NULL;
}
// -----------------------------------------------------------------------
void Window::doLazyDelete()
{
SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
{
Show( FALSE );
SetParent( ImplGetDefaultWindow() );
}
vcl::LazyDeletor<Window>::Delete( this );
}
// -----------------------------------------------------------------------
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 ) )
mpWindowImpl->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 ) )
mpWindowImpl->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 ) )
mpWindowImpl->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 ) )
mpWindowImpl->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 ) )
mpWindowImpl->mbKeyUp = TRUE;
}
// -----------------------------------------------------------------------
void Window::PrePaint()
{
}
// -----------------------------------------------------------------------
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 );
}
// -----------------------------------------------------------------------
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() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
{
ImplDelData aDogtag( this );
mpWindowImpl->mpLastFocusWindow->GrabFocus();
if( aDogtag.IsDelete() )
return;
}
NotifyEvent aNEvt( EVENT_GETFOCUS, this );
Notify( aNEvt );
}
// -----------------------------------------------------------------------
void Window::LoseFocus()
{
{ // Klammerung, da in diesem Handler das Window zerstoert werden darf
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
NotifyEvent aNEvt( EVENT_LOSEFOCUS, this );
Notify( aNEvt );
}
// -----------------------------------------------------------------------
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
{
SmartId aSmartId = GetSmartHelpId();
ULONG nNumHelpId = 0;
String aStrHelpId;
if( aSmartId.HasString() )
aStrHelpId = aSmartId.GetStr();
if( aSmartId.HasNumeric() )
nNumHelpId = aSmartId.GetNum();
if ( !nNumHelpId && aStrHelpId.Len() == 0 && ImplGetParent() )
ImplGetParent()->RequestHelp( rHEvt );
else
{
if ( !nNumHelpId && aStrHelpId.Len() == 0 )
nNumHelpId = OOO_HELP_INDEX;
Help* pHelp = Application::GetHelp();
if ( pHelp )
{
if( aStrHelpId.Len() > 0 )
pHelp->Start( aStrHelpId, this );
else
pHelp->Start( nNumHelpId, this );
}
}
}
}
// -----------------------------------------------------------------------
void Window::Command( const CommandEvent& rCEvt )
{
{ // Klammerung, da in diesem Handler das Window zerstoert werden darf
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, (void*)&rCEvt );
NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt );
if ( !Notify( aNEvt ) )
mpWindowImpl->mbCommand = TRUE;
}
// -----------------------------------------------------------------------
void Window::Tracking( const TrackingEvent& rTEvt )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
if( pWrapper )
pWrapper->Tracking( rTEvt );
}
// -----------------------------------------------------------------------
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 );
}
// -----------------------------------------------------------------------
void Window::ImplNotifyKeyMouseCommandEventListeners( NotifyEvent& rNEvt )
{
if( rNEvt.GetType() == EVENT_COMMAND )
{
const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
if ( pCEvt->GetCommand() != COMMAND_CONTEXTMENU )
// non context menu events are not to be notified up the chain
// so we return immediately
return;
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
// not interested in: The event listeners are already called in ::Command,
// and calling them here a second time doesn't make sense
;
else
{
CommandEvent aCommandEvent = ImplTranslateCommandEvent( *pCEvt, rNEvt.GetWindow(), this );
ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, &aCommandEvent );
}
}
}
// #82968# notify event listeners for mouse and key events seperately and
// not in PreNotify ( as for focus listeners )
// this allows for procesing those events internally first and pass it to
// the toolkit later
ImplDelData aDelData;
ImplAddDel( &aDelData );
if( rNEvt.GetType() == EVENT_MOUSEMOVE )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
else
{
MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &aMouseEvent );
}
}
}
else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
else
{
MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &aMouseEvent );
}
}
}
else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
else
{
MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &aMouseEvent );
}
}
}
else if( rNEvt.GetType() == EVENT_KEYINPUT )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
}
else if( rNEvt.GetType() == EVENT_KEYUP )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
}
if ( aDelData.IsDelete() )
return;
ImplRemoveDel( &aDelData );
// #106721# check if we're part of a compound control and notify
Window *pParent = ImplGetParent();
while( pParent )
{
if( pParent->IsCompoundControl() )
{
pParent->ImplNotifyKeyMouseCommandEventListeners( rNEvt );
break;
}
pParent = pParent->ImplGetParent();
}
}
// -----------------------------------------------------------------------
long Window::PreNotify( NotifyEvent& rNEvt )
{
{ // Klammerung, da in diesem Handler das Window zerstoert werden darf
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
long bDone = FALSE;
if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
bDone = mpWindowImpl->mpParent->PreNotify( rNEvt );
if ( !bDone )
{
if( rNEvt.GetType() == EVENT_GETFOCUS )
{
BOOL bCompoundFocusChanged = FALSE;
if ( mpWindowImpl->mbCompoundControl && !mpWindowImpl->mbCompoundControlHasFocus && HasChildPathFocus() )
{
mpWindowImpl->mbCompoundControlHasFocus = TRUE;
bCompoundFocusChanged = TRUE;
}
if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
}
else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
{
BOOL bCompoundFocusChanged = FALSE;
if ( mpWindowImpl->mbCompoundControl && mpWindowImpl->mbCompoundControlHasFocus && !HasChildPathFocus() )
{
mpWindowImpl->mbCompoundControlHasFocus = FALSE ;
bCompoundFocusChanged = TRUE;
}
if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
}
// #82968# mouse and key events will be notified after processing ( in ImplNotifyKeyMouseCommandEventListeners() )!
// see also ImplHandleMouseEvent(), ImplHandleKey()
/*
else if( rNEvt.GetType() == EVENT_MOUSEMOVE )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
else
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
}
}
else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
else
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
}
}
else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
{
if ( rNEvt.GetWindow() == this )
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
else
ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
}
}
else if( rNEvt.GetType() == EVENT_KEYINPUT )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
}
else if( rNEvt.GetType() == EVENT_KEYUP )
{
if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
}
*/
}
return bDone;
}
// -----------------------------------------------------------------------
long Window::Notify( NotifyEvent& rNEvt )
{
{ // Klammerung, da in diesem Handler das Window zerstoert werden darf
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
}
long nRet = FALSE;
// check for docking window
// but do nothing if window is docked and locked
ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
if( pWrapper && !( !pWrapper->IsFloatingMode() && pWrapper->IsLocked() ) )
{
if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
{
const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
BOOL bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
if ( pMEvt->IsLeft() )
{
if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
{
// ctrl double click toggles floating mode
pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
return TRUE;
}
else if ( pMEvt->GetClicks() == 1 && bHit)
{
// allow start docking during mouse move
pWrapper->ImplEnableStartDocking();
return TRUE;
}
}
}
else if ( rNEvt.GetType() == EVENT_MOUSEMOVE )
{
const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
BOOL bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
if ( pMEvt->IsLeft() )
{
// check if a single click initiated this sequence ( ImplStartDockingEnabled() )
// check if window is docked and
if( pWrapper->ImplStartDockingEnabled() && !pWrapper->IsFloatingMode() &&
!pWrapper->IsDocking() && bHit )
{
Point aPos = pMEvt->GetPosPixel();
Window* pWindow = rNEvt.GetWindow();
if ( pWindow != this )
{
aPos = pWindow->OutputToScreenPixel( aPos );
aPos = ScreenToOutputPixel( aPos );
}
pWrapper->ImplStartDocking( aPos );
}
return TRUE;
}
}
else if( rNEvt.GetType() == EVENT_KEYINPUT )
{
const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
rKey.IsShift() && rKey.IsMod1() )
{
pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
/* At this point the floating toolbar frame does not have the
* input focus since these frames don't get the focus per default
* To enable keyboard handling of this toolbar set the input focus
* to the frame. This needs to be done with ToTop since GrabFocus
* would not notice any change since "this" already has the focus.
*/
if( pWrapper->IsFloatingMode() )
ToTop( TOTOP_GRABFOCUSONLY );
return TRUE;
}
}
}
// 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) && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
{
USHORT n = 0;
Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
if ( pFirstChild )
pFirstChild->ImplControlFocus();
}
}
}
if ( !nRet )
{
if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
nRet = mpWindowImpl->mpParent->Notify( rNEvt );
}
return nRet;
}
// -----------------------------------------------------------------------
void Window::ImplCallEventListeners( ULONG nEvent, void* pData )
{
// The implementation was moved to CallEventListeners(),
// because derived classes in svtools must be able to
// call the event listeners and ImplCallEventListeners()
// is not exported.
// TODO: replace ImplCallEventListeners() by CallEventListeners() in vcl
CallEventListeners( nEvent, pData );
}
// -----------------------------------------------------------------------
void Window::CallEventListeners( ULONG nEvent, void* pData )
{
VclWindowEvent aEvent( this, nEvent, pData );
ImplDelData aDelData;
ImplAddDel( &aDelData );
ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent );
if ( aDelData.IsDelete() )
return;
if ( !mpWindowImpl->maEventListeners.empty() )
mpWindowImpl->maEventListeners.Call( &aEvent );
if ( aDelData.IsDelete() )
return;
ImplRemoveDel( &aDelData );
Window* pWindow = this;
while ( pWindow )
{
pWindow->ImplAddDel( &aDelData );
if ( !pWindow->mpWindowImpl->maChildEventListeners.empty() )
pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent );
if ( aDelData.IsDelete() )
return;
pWindow->ImplRemoveDel( &aDelData );
pWindow = pWindow->GetParent();
}
}
void Window::FireVclEvent( VclSimpleEvent* pEvent )
{
ImplGetSVData()->mpApp->ImplCallEventListeners(pEvent);
}
// -----------------------------------------------------------------------
void Window::AddEventListener( const Link& rEventListener )
{
mpWindowImpl->maEventListeners.push_back( rEventListener );
}
// -----------------------------------------------------------------------
void Window::RemoveEventListener( const Link& rEventListener )
{
mpWindowImpl->maEventListeners.remove( rEventListener );
}
// -----------------------------------------------------------------------
void Window::AddChildEventListener( const Link& rEventListener )
{
mpWindowImpl->maChildEventListeners.push_back( rEventListener );
}
// -----------------------------------------------------------------------
void Window::RemoveChildEventListener( const Link& rEventListener )
{
mpWindowImpl->maChildEventListeners.remove( rEventListener );
}
// -----------------------------------------------------------------------
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;
if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
return TRUE;
else
{
rEventId = 0;
ImplRemoveDel( &(pSVEvent->maDelData) );
delete pSVEvent;
return FALSE;
}
}
// -----------------------------------------------------------------------
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;
if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
return TRUE;
else
{
rEventId = 0;
ImplRemoveDel( &(pSVEvent->maDelData) );
delete pSVEvent;
return FALSE;
}
}
// -----------------------------------------------------------------------
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 );
}
// -----------------------------------------------------------------------
BOOL Window::IsLocked( BOOL bChilds ) const
{
if ( mpWindowImpl->mnLockCount != 0 )
return TRUE;
if ( bChilds || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
if ( pChild->IsLocked( TRUE ) )
return TRUE;
pChild = pChild->mpWindowImpl->mpNext;
}
}
return FALSE;
}
// -----------------------------------------------------------------------
void Window::SetStyle( WinBits nStyle )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mnStyle != nStyle )
{
mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
mpWindowImpl->mnStyle = nStyle;
StateChanged( STATE_CHANGE_STYLE );
}
}
// -----------------------------------------------------------------------
void Window::SetExtendedStyle( WinBits nExtendedStyle )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mnExtendedStyle != nExtendedStyle )
{
Window* pWindow = ImplGetBorderWindow();
if( ! pWindow )
pWindow = this;
if( pWindow->mpWindowImpl->mbFrame )
{
SalExtStyle nExt = 0;
if( (nExtendedStyle & WB_EXT_DOCUMENT) )
nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
if( (nExtendedStyle & WB_EXT_DOCMODIFIED) )
nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;
pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
}
mpWindowImpl->mnPrevExtendedStyle = mpWindowImpl->mnExtendedStyle;
mpWindowImpl->mnExtendedStyle = nExtendedStyle;
StateChanged( STATE_CHANGE_EXTENDEDSTYLE );
}
}
// -----------------------------------------------------------------------
SystemWindow* Window::GetSystemWindow() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
const Window* pWin = this;
while ( pWin && !pWin->IsSystemWindow() )
pWin = pWin->GetParent();
return (SystemWindow*)pWin;
}
// -----------------------------------------------------------------------
void Window::SetBorderStyle( USHORT nBorderStyle )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
{
if( nBorderStyle == WINDOW_BORDER_REMOVEBORDER &&
! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
)
{
// this is a little awkward: some controls (e.g. svtools ProgressBar)
// cannot avoid getting constructed with WB_BORDER but want to disable
// borders in case of NWF drawing. So they need a method to remove their border window
Window* pBorderWin = mpWindowImpl->mpBorderWindow;
// remove us as border window's client
pBorderWin->mpWindowImpl->mpClientWindow = NULL;
mpWindowImpl->mpBorderWindow = NULL;
mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
// reparent us above the border window
SetParent( pBorderWin->mpWindowImpl->mpParent );
// set us to the position and size of our previous border
Point aBorderPos( pBorderWin->GetPosPixel() );
Size aBorderSize( pBorderWin->GetSizePixel() );
SetPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
// release border window
delete pBorderWin;
// set new style bits
SetStyle( GetStyle() & (~WB_BORDER) );
}
else
{
if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetBorderStyle( nBorderStyle );
else
mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
}
}
}
// -----------------------------------------------------------------------
USHORT Window::GetBorderStyle() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
{
if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorderStyle();
else
return mpWindowImpl->mpBorderWindow->GetBorderStyle();
}
return 0;
}
// -----------------------------------------------------------------------
long Window::CalcTitleWidth() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
{
if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->CalcTitleWidth();
else
return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
}
else if ( mpWindowImpl->mbFrame && (mpWindowImpl->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 ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings );
mpWindowImpl->mbClipSiblings = bClipSiblings;
}
// -----------------------------------------------------------------------
void Window::SetMouseTransparent( BOOL bTransparent )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
if( mpWindowImpl->mpSysObj )
mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
mpWindowImpl->mbMouseTransparent = bTransparent;
}
// -----------------------------------------------------------------------
void Window::SetPaintTransparent( BOOL bTransparent )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
// transparency is not useful for frames as the background would have to be provided by a different frame
if( bTransparent && mpWindowImpl->mbFrame )
return;
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
mpWindowImpl->mbPaintTransparent = bTransparent;
}
// -----------------------------------------------------------------------
void Window::SetInputContext( const InputContext& rInputContext )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
mpWindowImpl->maInputContext = rInputContext;
if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
ImplNewInputContext();
}
// -----------------------------------------------------------------------
void Window::EndExtTextInput( USHORT nFlags )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mbExtTextInput )
ImplGetFrame()->EndExtTextInput( nFlags );
}
// -----------------------------------------------------------------------
void Window::SetCursorRect( const Rectangle* pRect, long nExtTextInputWidth )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplWinData* pWinData = ImplGetWinData();
if ( pWinData->mpCursorRect )
{
if ( pRect )
*pWinData->mpCursorRect = *pRect;
else
{
delete pWinData->mpCursorRect;
pWinData->mpCursorRect = NULL;
}
}
else
{
if ( pRect )
pWinData->mpCursorRect = new Rectangle( *pRect );
}
pWinData->mnCursorExtWidth = nExtTextInputWidth;
}
// -----------------------------------------------------------------------
const Rectangle* Window::GetCursorRect() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplWinData* pWinData = ImplGetWinData();
return pWinData->mpCursorRect;
}
// -----------------------------------------------------------------------
long Window::GetCursorExtTextInputWidth() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplWinData* pWinData = ImplGetWinData();
return pWinData->mnCursorExtWidth;
}
// -----------------------------------------------------------------------
void Window::SetSettings( const AllSettings& rSettings )
{
SetSettings( rSettings, FALSE );
}
void Window::SetSettings( const AllSettings& rSettings, BOOL bChild )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpBorderWindow->SetSettings( rSettings, FALSE );
if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, TRUE );
}
AllSettings aOldSettings = maSettings;
OutputDevice::SetSettings( rSettings );
ULONG nChangeFlags = aOldSettings.GetChangeFlags( rSettings );
// AppFont-Aufloesung und DPI-Aufloesung neu berechnen
ImplInitResolutionSettings();
if ( nChangeFlags )
{
DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
DataChanged( aDCEvt );
}
if ( bChild || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->SetSettings( rSettings, bChild );
pChild = pChild->mpWindowImpl->mpNext;
}
}
}
// -----------------------------------------------------------------------
void Window::UpdateSettings( const AllSettings& rSettings, BOOL bChild )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpBorderWindow->UpdateSettings( rSettings, FALSE );
if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, TRUE );
}
AllSettings aOldSettings = maSettings;
ULONG nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings );
nChangeFlags |= SETTINGS_IN_UPDATE_SETTINGS; // Set this flag so the receiver of the data changed
// event can distinguish between the changing of global
// setting and a local change ( with SetSettings )
// AppFont-Aufloesung und DPI-Aufloesung neu berechnen
ImplInitResolutionSettings();
/* #i73785#
* do not overwrite a WheelBehavior with false
* this looks kind of a hack, but WheelBehavior
* is always a local change, not a system property,
* so we can spare all our users the hassle of reacting on
* this in their respective DataChanged.
*/
MouseSettings aSet( maSettings.GetMouseSettings() );
aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() );
maSettings.SetMouseSettings( aSet );
if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() )
{
Wallpaper aWallpaper = GetBackground();
if( !aWallpaper.IsBitmap() && !aWallpaper.IsGradient() )
{
if ( mpWindowImpl->mnStyle & WB_3DLOOK )
SetBackground( Wallpaper( rSettings.GetStyleSettings().GetFaceColor() ) );
else
SetBackground( Wallpaper( rSettings.GetStyleSettings().GetWindowColor() ) );
}
}
if ( nChangeFlags )
{
DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
DataChanged( aDCEvt );
// notify data change handler
ImplCallEventListeners( VCLEVENT_WINDOW_DATACHANGED, &aDCEvt);
}
if ( bChild || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->UpdateSettings( rSettings, bChild );
pChild = pChild->mpWindowImpl->mpNext;
}
}
}
// -----------------------------------------------------------------------
void Window::NotifyAllChilds( DataChangedEvent& rDCEvt )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
DataChanged( rDCEvt );
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->NotifyAllChilds( rDCEvt );
pChild = pChild->mpWindowImpl->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;
}
// -----------------------------------------------------------------------
// TODO: remove in next incompatible build
void Window::GetFontResolution( sal_Int32& nDPIX, sal_Int32& nDPIY ) const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
nDPIX = mpWindowImpl->mpFrameData->mnDPIX;
nDPIY = mpWindowImpl->mpFrameData->mnDPIY;
}
// -----------------------------------------------------------------------
void Window::SetParentClipMode( USHORT nMode )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode );
else
{
if ( !ImplIsOverlapWindow() )
{
mpWindowImpl->mnParentClipMode = nMode;
if ( nMode & PARENTCLIPMODE_CLIP )
mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = TRUE;
}
}
}
// -----------------------------------------------------------------------
USHORT Window::GetParentClipMode() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
return mpWindowImpl->mpBorderWindow->GetParentClipMode();
else
return mpWindowImpl->mnParentClipMode;
}
// -----------------------------------------------------------------------
void Window::SetWindowRegionPixel()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
else if( mpWindowImpl->mbFrame )
{
mpWindowImpl->maWinRegion = Region( REGION_NULL);
mpWindowImpl->mbWinRegion = FALSE;
mpWindowImpl->mpFrame->ResetClipRegion();
}
else
{
if ( mpWindowImpl->mbWinRegion )
{
mpWindowImpl->maWinRegion = Region( REGION_NULL );
mpWindowImpl->mbWinRegion = FALSE;
ImplSetClipFlag();
if ( IsReallyVisible() )
{
// Hintergrund-Sicherung zuruecksetzen
if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
ImplDeleteOverlapBackground();
if ( mpWindowImpl->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 ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
else if( mpWindowImpl->mbFrame )
{
if( rRegion.GetType() != REGION_NULL )
{
mpWindowImpl->maWinRegion = rRegion;
mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
if( mpWindowImpl->mbWinRegion )
{
// ClipRegion setzen/updaten
long nX;
long nY;
long nWidth;
long nHeight;
ULONG nRectCount;
ImplRegionInfo aInfo;
BOOL bRegionRect;
nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
while ( bRegionRect )
{
mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
}
mpWindowImpl->mpFrame->EndSetClipRegion();
}
else
SetWindowRegionPixel();
}
else
SetWindowRegionPixel();
}
else
{
BOOL bInvalidate = FALSE;
if ( rRegion.GetType() == REGION_NULL )
{
if ( mpWindowImpl->mbWinRegion )
{
mpWindowImpl->maWinRegion = Region( REGION_NULL );
mpWindowImpl->mbWinRegion = FALSE;
ImplSetClipFlag();
bInvalidate = TRUE;
}
}
else
{
mpWindowImpl->maWinRegion = rRegion;
mpWindowImpl->mbWinRegion = TRUE;
ImplSetClipFlag();
bInvalidate = TRUE;
}
if ( IsReallyVisible() )
{
// Hintergrund-Sicherung zuruecksetzen
if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
ImplDeleteOverlapBackground();
if ( mpWindowImpl->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 ( mpWindowImpl->mpBorderWindow )
return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel();
else
return mpWindowImpl->maWinRegion;
}
// -----------------------------------------------------------------------
BOOL Window::IsWindowRegionPixel() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel();
else
return mpWindowImpl->mbWinRegion;
}
// -----------------------------------------------------------------------
Region Window::GetWindowClipRegionPixel( USHORT nFlags ) const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
Region aWinClipRegion;
if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN )
{
if ( mpWindowImpl->mbInitWinClipRegion )
((Window*)this)->ImplInitWinClipRegion();
aWinClipRegion = mpWindowImpl->maWinClipRegion;
}
else
{
Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion();
aWinClipRegion = *pWinChildClipRegion;
// --- RTL --- remirror clip region before passing it to somebody
if( ImplIsAntiparallel() )
ImplReMirror( aWinClipRegion );
}
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 ( mpWindowImpl->mpPaintRegion )
{
Region aRegion = *mpWindowImpl->mpPaintRegion;
aRegion.Move( -mnOutOffX, -mnOutOffY );
return PixelToLogic( aRegion );
}
else
{
Region aPaintRegion( REGION_NULL );
return aPaintRegion;
}
}
// -----------------------------------------------------------------------
void Window::ExpandPaintClipRegion( const Region& rRegion )
{
if( mpWindowImpl->mpPaintRegion )
{
Region aPixRegion = LogicToPixel( rRegion );
Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion );
Region aWinChildRegion = *ImplGetWinChildClipRegion();
// --- RTL -- only this region is in frame coordinates, so re-mirror it
if( ImplIsAntiparallel() )
ImplReMirror( aWinChildRegion );
aDevPixRegion.Intersect( aWinChildRegion );
if( ! aDevPixRegion.IsEmpty() )
{
mpWindowImpl->mpPaintRegion->Union( aDevPixRegion );
mbInitClipRegion = TRUE;
}
}
}
// -----------------------------------------------------------------------
static SystemWindow *ImplGetLastSystemWindow( Window *pWin )
{
// get the most top-level system window, the one that contains the taskpanelist
SystemWindow *pSysWin = NULL;
if( !pWin )
return pSysWin;
Window *pMyParent = pWin;
while ( pMyParent )
{
if ( pMyParent->IsSystemWindow() )
pSysWin = (SystemWindow*)pMyParent;
pMyParent = pMyParent->GetParent();
}
return pSysWin;
}
void Window::SetParent( Window* pNewParent )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" );
DBG_ASSERT( pNewParent != this, "someone tried to reparent a window to itself" );
if( pNewParent == this )
return;
// check if the taskpanelist would change and move the window pointer accordingly
SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
SystemWindow *pNewSysWin = NULL;
BOOL bChangeTaskPaneList = FALSE;
if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
{
pNewSysWin = ImplGetLastSystemWindow( pNewParent );
if( pNewSysWin && pNewSysWin != pSysWin )
{
bChangeTaskPaneList = TRUE;
pSysWin->GetTaskPaneList()->RemoveWindow( this );
}
}
// remove ownerdraw decorated windows from list in the top-most frame window
if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
{
::std::vector< Window* >& rList = ImplGetOwnerDrawList();
::std::vector< Window* >::iterator p;
p = ::std::find( rList.begin(), rList.end(), this );
if( p != rList.end() )
rList.erase( p );
}
ImplSetFrameParent( pNewParent );
if ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpRealParent = pNewParent;
mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
return;
}
if ( mpWindowImpl->mpParent == pNewParent )
return;
if ( mpWindowImpl->mbFrame )
mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
BOOL bVisible = IsVisible();
Show( FALSE, SHOW_NOFOCUSCHANGE );
// Testen, ob sich das Overlap-Window aendert
Window* pOldOverlapWindow;
Window* pNewOverlapWindow = NULL;
if ( ImplIsOverlapWindow() )
pOldOverlapWindow = NULL;
else
{
pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
if ( mpWindowImpl->mpOverlapWindow != pNewOverlapWindow )
pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
else
pOldOverlapWindow = NULL;
}
// Fenster in der Hirachie umsetzen
BOOL bFocusOverlapWin = HasChildPathFocus( TRUE );
BOOL bFocusWin = HasChildPathFocus();
BOOL bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
if ( bNewFrame )
{
if ( mpWindowImpl->mpFrameData->mpFocusWin )
{
if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
mpWindowImpl->mpFrameData->mpFocusWin = NULL;
}
if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
{
if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
}
if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
{
if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
}
}
ImplRemoveWindow( bNewFrame );
ImplInsertWindow( pNewParent );
if ( mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP )
pNewParent->mpWindowImpl->mbClipChildren = TRUE;
ImplUpdateWindowPtr();
if ( ImplUpdatePos() )
ImplUpdateSysObjPos();
// 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 = mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow )
{
Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
pOverlapWindow = pNextOverlapWindow;
}
}
}
else if ( pOldOverlapWindow )
{
// Focus-Save zuruecksetzen
if ( bFocusWin ||
(pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
while ( pOverlapWindow )
{
Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->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( mpWindowImpl->mpFrameData->mbHasFocus );
}
// Focus evtl. auf den neuen Frame umsetzen, wenn FocusWindow mit
// SetParent() umgesetzt wird
if ( bFocusOverlapWin )
{
mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
if ( !mpWindowImpl->mpFrameData->mbHasFocus )
{
mpWindowImpl->mpFrame->ToTop( 0 );
}
}
// Assure DragSource and DropTarget members are created
if ( bNewFrame )
{
GetDropTarget();
}
if( bChangeTaskPaneList )
pNewSysWin->GetTaskPaneList()->AddWindow( this );
if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
ImplGetOwnerDrawList().push_back( this );
if ( bVisible )
Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
}
// -----------------------------------------------------------------------
void Window::Show( BOOL bVisible, USHORT nFlags )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mbVisible == bVisible )
return;
ImplDelData aDogTag( this );
BOOL bRealVisibilityChanged = FALSE;
mpWindowImpl->mbVisible = (bVisible != 0);
if ( !bVisible )
{
ImplHideAllOverlaps();
if( aDogTag.IsDelete() )
return;
if ( mpWindowImpl->mpBorderWindow )
{
BOOL bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
if ( mpWindowImpl->mbNoParentUpdate )
mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = TRUE;
mpWindowImpl->mpBorderWindow->Show( FALSE, nFlags );
mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
}
else if ( mpWindowImpl->mbFrame )
{
mpWindowImpl->mbSuppressAccessibilityEvents = TRUE;
mpWindowImpl->mpFrame->Show( FALSE, FALSE );
}
StateChanged( STATE_CHANGE_VISIBLE );
if ( mpWindowImpl->mbReallyVisible )
{
Region aInvRegion( REGION_EMPTY );
BOOL bSaveBack = FALSE;
if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
{
if ( ImplRestoreOverlapBackground( aInvRegion ) )
bSaveBack = TRUE;
}
if ( !bSaveBack )
{
if ( mpWindowImpl->mbInitWinClipRegion )
ImplInitWinClipRegion();
aInvRegion = mpWindowImpl->maWinClipRegion;
}
if( aDogTag.IsDelete() )
return;
bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
ImplResetReallyVisible();
ImplSetClipFlag();
if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
{
// Focus umsetzen
if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() )
{
if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
! mpWindowImpl->mpOverlapWindow->IsInModalMode()
)
mpWindowImpl->mpOverlapWindow->GrabFocus();
}
}
if ( !mpWindowImpl->mbFrame )
{
if( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget )
{
/*
* #i48371# native theming: some themes draw outside the control
* area we tell them to (bad thing, but we cannot do much about it ).
* On hiding these controls they get invalidated with their window rectangle
* which leads to the parts outside the control area being left and not
* invalidated. Workaround: invalidate an area on the parent, too
*/
const int workaround_border = 5;
Rectangle aBounds( aInvRegion.GetBoundRect() );
aBounds.Left() -= workaround_border;
aBounds.Top() -= workaround_border;
aBounds.Right() += workaround_border;
aBounds.Bottom() += workaround_border;
aInvRegion = aBounds;
}
if ( !mpWindowImpl->mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) )
{
if ( !aInvRegion.IsEmpty() )
ImplInvalidateParentFrameRegion( aInvRegion );
}
ImplGenerateMouseMove();
}
}
}
else
{
// inherit native widget flag for form controls
// required here, because frames never show up in the child hierarchy - which should be fixed....
// eg, the drop down of a combobox which is a system floating window
if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() &&
GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() )
EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
if ( mpWindowImpl->mbCallMove )
{
ImplCallMove();
}
if ( mpWindowImpl->mbCallResize )
{
ImplCallResize();
}
StateChanged( STATE_CHANGE_VISIBLE );
Window* pTestParent;
if ( ImplIsOverlapWindow() )
pTestParent = mpWindowImpl->mpOverlapWindow;
else
pTestParent = ImplGetParent();
if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->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(( nFlags & SHOW_FOREGROUNDTASK ) ? TOTOP_FOREGROUNDTASK : 0 );
ImplFocusToTop( 0, FALSE );
}
// Hintergrund sichern
if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mbSaveBack )
ImplSaveOverlapBackground();
// adjust mpWindowImpl->mbReallyVisible
bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
ImplSetReallyVisible();
// Dafuer sorgen, das Clip-Rechtecke neu berechnet werden
ImplSetClipFlag();
if ( !mpWindowImpl->mbFrame )
{
USHORT nInvalidateFlags = INVALIDATE_CHILDREN;
if( ! IsPaintTransparent() )
nInvalidateFlags |= INVALIDATE_NOTRANSPARENT;
ImplInvalidate( NULL, nInvalidateFlags );
ImplGenerateMouseMove();
}
}
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->Show( TRUE, nFlags );
else if ( mpWindowImpl->mbFrame )
{
ImplSVData* pSVData = ImplGetSVData();
// #106431#, hide SplashScreen
if( pSVData->mpIntroWindow && !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
pSVData->mpIntroWindow->Hide();
//DBG_ASSERT( !mpWindowImpl->mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated");
mpWindowImpl->mbSuppressAccessibilityEvents = FALSE;
mpWindowImpl->mbPaintFrame = TRUE;
BOOL bNoActivate = (nFlags & (SHOW_NOACTIVATE|SHOW_NOFOCUSCHANGE)) ? TRUE : FALSE;
mpWindowImpl->mpFrame->Show( TRUE, bNoActivate );
if( aDogTag.IsDelete() )
return;
// Query the correct size of the window, if we are waiting for
// a system resize
if ( mpWindowImpl->mbWaitSystemResize )
{
long nOutWidth;
long nOutHeight;
mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
ImplHandleResize( this, nOutWidth, nOutHeight );
}
}
if( aDogTag.IsDelete() )
return;
#ifdef DBG_UTIL
if ( IsDialog() || (GetType() == WINDOW_TABPAGE) || (GetType() == WINDOW_DOCKINGWINDOW) )
{
DBG_DIALOGTEST( this );
}
#endif
ImplShowAllOverlaps();
}
if( aDogTag.IsDelete() )
return;
// invalidate all saved backgrounds
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
// the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
// However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
// we re-use the SHOW/HIDE events this way, with this particular semantics).
// Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
// now only notify with a NULL data pointer, for all other clients except the access bridge.
if ( !bRealVisibilityChanged )
ImplCallEventListeners( mpWindowImpl->mbVisible ? VCLEVENT_WINDOW_SHOW : VCLEVENT_WINDOW_HIDE, NULL );
if( aDogTag.IsDelete() )
return;
// #107575#, if a floating windows is shown that grabs the focus, we have to notify the toolkit about it
// ImplGrabFocus() is not called in this case
// Because this might lead to problems the task will be shifted to 6.y
// Note: top-level context menues are registered at the access bridge after being shown,
// so this will probably not help here....
/*
if( mpWindowImpl->mbFloatWin && ((FloatingWindow*) this )->GrabsFocus() )
{
ImplSVData* pSVData = ImplGetSVData();
if( !mpWindowImpl->mbVisible )
{
ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
if( pSVData->maWinData.mpFocusWin )
pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
}
else
{
if( pSVData->maWinData.mpFocusWin )
pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
}
}
*/
}
// -----------------------------------------------------------------------
Size Window::GetSizePixel() const
{
// #i43257# trigger pending resize handler to assure correct window sizes
if( mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
{
ImplDelData aDogtag( this );
mpWindowImpl->mpFrameData->maResizeTimer.Stop();
mpWindowImpl->mpFrameData->maResizeTimer.GetTimeoutHdl().Call( NULL );
if( aDogtag.IsDelete() )
return Size(0,0);
}
return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
}
void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
{
rLeftBorder = mpWindowImpl->mnLeftBorder;
rTopBorder = mpWindowImpl->mnTopBorder;
rRightBorder = mpWindowImpl->mnRightBorder;
rBottomBorder = mpWindowImpl->mnBottomBorder;
}
// -----------------------------------------------------------------------
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
// mpWindowImpl->mbDisabled darf erst nach Aufruf von ImplDlgCtrlNextWindow() gesetzt
// werden. Ansonsten muss ImplDlgCtrlNextWindow() umgestellt werden
if ( HasFocus() )
ImplDlgCtrlNextWindow();
}
if ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpBorderWindow->Enable( bEnable, FALSE );
if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, TRUE );
}
// #i56102# restore app focus win in case the
// window was disabled when the frame focus changed
ImplSVData* pSVData = ImplGetSVData();
if( bEnable &&
pSVData->maWinData.mpFocusWin == NULL &&
mpWindowImpl->mpFrameData->mbHasFocus &&
mpWindowImpl->mpFrameData->mpFocusWin == this )
pSVData->maWinData.mpFocusWin = this;
if ( mpWindowImpl->mbDisabled != !bEnable )
{
mpWindowImpl->mbDisabled = !bEnable;
if ( mpWindowImpl->mpSysObj )
mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
// if ( mpWindowImpl->mbFrame )
// mpWindowImpl->mpFrame->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
StateChanged( STATE_CHANGE_ENABLE );
ImplCallEventListeners( bEnable ? VCLEVENT_WINDOW_ENABLED : VCLEVENT_WINDOW_DISABLED );
}
if ( bChild || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->Enable( bEnable, bChild );
pChild = pChild->mpWindowImpl->mpNext;
}
}
if ( IsReallyVisible() )
ImplGenerateMouseMove();
}
// -----------------------------------------------------------------------
void Window::SetCallHandlersOnInputDisabled( bool bCall )
{
mpWindowImpl->mbCallHandlersDuringInputDisabled = bCall ? TRUE : FALSE;
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->SetCallHandlersOnInputDisabled( bCall );
pChild = pChild->mpWindowImpl->mpNext;
}
}
// -----------------------------------------------------------------------
bool Window::IsCallHandlersOnInputDisabled() const
{
return mpWindowImpl->mbCallHandlersDuringInputDisabled ? true : false;
}
// -----------------------------------------------------------------------
void Window::EnableInput( BOOL bEnable, BOOL bChild )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
BOOL bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
if ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpBorderWindow->EnableInput( bEnable, FALSE );
if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, TRUE );
}
if ( (! bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) ||
( bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled) )
{
// 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 ( mpWindowImpl->mbInputDisabled != !bEnable )
{
mpWindowImpl->mbInputDisabled = !bEnable;
if ( mpWindowImpl->mpSysObj )
mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
// if ( mpWindowImpl->mbFrame )
// mpWindowImpl->mpFrame->Enable( !mpWindowImpl->mbDisabled && bEnable );
}
}
// #i56102# restore app focus win in case the
// window was disabled when the frame focus changed
ImplSVData* pSVData = ImplGetSVData();
if( bEnable &&
pSVData->maWinData.mpFocusWin == NULL &&
mpWindowImpl->mpFrameData->mbHasFocus &&
mpWindowImpl->mpFrameData->mpFocusWin == this )
pSVData->maWinData.mpFocusWin = this;
if ( bChild || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->EnableInput( bEnable, bChild );
pChild = pChild->mpWindowImpl->mpNext;
}
}
if ( IsReallyVisible() )
ImplGenerateMouseMove();
// #104827# notify parent
if ( bNotify )
{
NotifyEvent aNEvt( bEnable ? EVENT_INPUTENABLE : EVENT_INPUTDISABLE, this );
Notify( aNEvt );
}
}
// -----------------------------------------------------------------------
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
if( pExcludeWindow )
pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->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 || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, TRUE ) )
pSysWin->EnableInput( bEnable, bChild );
}
pSysWin = pSysWin->mpWindowImpl->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 || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, TRUE ) )
pFrameWin->EnableInput( bEnable, bChild );
}
}
pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
}
// the same for ownerdraw floating windows
if( mpWindowImpl->mbFrame )
{
::std::vector< Window* >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
::std::vector< Window* >::iterator p = rList.begin();
while( p != rList.end() )
{
// Is Window in the path from this window
if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( (*p), TRUE ) )
{
// Is Window not in the exclude window path or not the
// exclude window, than change the status
if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( (*p), TRUE ) )
(*p)->EnableInput( bEnable, bChild );
}
p++;
}
}
}
}
// -----------------------------------------------------------------------
void Window::AlwaysEnableInput( BOOL bAlways, BOOL bChild )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, FALSE );
if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
{
mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
if ( bAlways )
EnableInput( TRUE, FALSE );
}
else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
{
mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
}
if ( bChild || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->AlwaysEnableInput( bAlways, bChild );
pChild = pChild->mpWindowImpl->mpNext;
}
}
}
// -----------------------------------------------------------------------
void Window::AlwaysDisableInput( BOOL bAlways, BOOL bChild )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->AlwaysDisableInput( bAlways, FALSE );
if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled )
{
mpWindowImpl->meAlwaysInputMode = AlwaysInputDisabled;
if ( bAlways )
EnableInput( FALSE, FALSE );
}
else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled )
{
mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
}
if ( bChild || mpWindowImpl->mbChildNotify )
{
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
pChild->AlwaysDisableInput( bAlways, bChild );
pChild = pChild->mpWindowImpl->mpNext;
}
}
}
// -----------------------------------------------------------------------
void Window::SetActivateMode( USHORT nMode )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
if ( mpWindowImpl->mnActivateMode != nMode )
{
mpWindowImpl->mnActivateMode = nMode;
// Evtl. ein Decativate/Activate ausloesen
if ( mpWindowImpl->mnActivateMode )
{
if ( (mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW)) &&
!HasChildPathFocus( TRUE ) )
{
mpWindowImpl->mbActive = FALSE;
Deactivate();
}
}
else
{
if ( !mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW) )
{
mpWindowImpl->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 ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
return;
}
if ( nFlags & WINDOW_ZORDER_FIRST )
{
if ( ImplIsOverlapWindow() )
pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
else
pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
nFlags |= WINDOW_ZORDER_BEFOR;
}
else if ( nFlags & WINDOW_ZORDER_LAST )
{
if ( ImplIsOverlapWindow() )
pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
else
pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
nFlags |= WINDOW_ZORDER_BEHIND;
}
while ( pRefWindow->mpWindowImpl->mpBorderWindow )
pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
if ( (pRefWindow == this) || mpWindowImpl->mbFrame )
return;
DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" );
if ( nFlags & WINDOW_ZORDER_BEFOR )
{
if ( pRefWindow->mpWindowImpl->mpPrev == this )
return;
if ( ImplIsOverlapWindow() )
{
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
if ( !pRefWindow->mpWindowImpl->mpPrev )
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
}
else
{
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
if ( !pRefWindow->mpWindowImpl->mpPrev )
mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
}
mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev;
mpWindowImpl->mpNext = pRefWindow;
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
}
else if ( nFlags & WINDOW_ZORDER_BEHIND )
{
if ( pRefWindow->mpWindowImpl->mpNext == this )
return;
if ( ImplIsOverlapWindow() )
{
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
if ( !pRefWindow->mpWindowImpl->mpNext )
mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
}
else
{
if ( mpWindowImpl->mpPrev )
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
else
mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
else
mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
if ( !pRefWindow->mpWindowImpl->mpNext )
mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
}
mpWindowImpl->mpPrev = pRefWindow;
mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
if ( mpWindowImpl->mpNext )
mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
}
if ( IsReallyVisible() )
{
// Hintergrund-Sicherung zuruecksetzen
if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
ImplInvalidateAllOverlapBackgrounds();
if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
{
BOOL bInitWinClipRegion = mpWindowImpl->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 ( mpWindowImpl->mpOverlapWindow )
pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
}
else
pWindow = ImplGetParent()->mpWindowImpl->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->mpWindowImpl->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->mpWindowImpl->mpNext;
}
}
}
}
}
// -----------------------------------------------------------------------
void Window::EnableAlwaysOnTop( BOOL bEnable )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
mpWindowImpl->mbAlwaysOnTop = bEnable;
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable );
else if ( bEnable && IsReallyVisible() )
ToTop();
if ( mpWindowImpl->mbFrame )
mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable );
}
// -----------------------------------------------------------------------
void Window::SetPosSizePixel( long nX, long nY,
long nWidth, long nHeight, USHORT nFlags )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
BOOL bHasValidSize = !mpWindowImpl->mbDefSize;
if ( nFlags & WINDOW_POSSIZE_POS )
mpWindowImpl->mbDefPos = FALSE;
if ( nFlags & WINDOW_POSSIZE_SIZE )
mpWindowImpl->mbDefSize = FALSE;
// Oberstes BorderWindow ist das Window, welches positioniert werden soll
Window* pWindow = this;
while ( pWindow->mpWindowImpl->mpBorderWindow )
pWindow = pWindow->mpWindowImpl->mpBorderWindow;
if ( pWindow->mpWindowImpl->mbFrame )
{
// Note: if we're positioning a frame, the coordinates are interpreted
// as being the top-left corner of the window's client area and NOT
// as the position of the border ! (due to limitations of several UNIX window managers)
long nOldWidth = pWindow->mnOutWidth;
if ( !(nFlags & WINDOW_POSSIZE_WIDTH) )
nWidth = pWindow->mnOutWidth;
if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) )
nHeight = pWindow->mnOutHeight;
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( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
{
Window* pParent = pWindow->GetParent();
nX += pParent->mnOutOffX;
}
if( GetParent() && GetParent()->ImplIsAntiparallel() )
{
// --- RTL --- (re-mirror at parent window)
Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
GetParent()->ImplReMirror( aRect );
nX = aRect.nLeft;
}
}
if( !(nFlags & WINDOW_POSSIZE_X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth )
{
// --- RTL --- make sure the old right aligned position is not changed
// system windows will always grow to the right
if( pWindow->GetParent() && pWindow->GetParent()->ImplHasMirroredGraphics() )
{
long myWidth = nOldWidth;
if( !myWidth )
myWidth = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth;
if( !myWidth )
myWidth = nWidth;
nFlags |= WINDOW_POSSIZE_X;
nSysFlags |= SAL_FRAME_POSSIZE_X;
nX = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX -
mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration;
nX = pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration +
pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth - myWidth - 1 - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX;
if(!(nFlags & WINDOW_POSSIZE_Y))
{
nFlags |= WINDOW_POSSIZE_Y;
nSysFlags |= SAL_FRAME_POSSIZE_Y;
nY = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY -
mpWindowImpl->mpFrame->GetUnmirroredGeometry().nTopDecoration;
}
}
}
if( nFlags & WINDOW_POSSIZE_Y )
{
nSysFlags |= SAL_FRAME_POSSIZE_Y;
if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
{
Window* pParent = pWindow->GetParent();
nY += pParent->mnOutOffY;
}
}
if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
{
// check for min/max client size and adjust size accordingly
// otherwise it may happen that the resize event is ignored, i.e. the old size remains
// unchanged but ImplHandleResize() is called with the wrong size
SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow );
if( pSystemWindow )
{
Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
if( nWidth < aMinSize.Width() )
nWidth = aMinSize.Width();
if( nHeight < aMinSize.Height() )
nHeight = aMinSize.Height();
if( nWidth > aMaxSize.Width() )
nWidth = aMaxSize.Width();
if( nHeight > aMaxSize.Height() )
nHeight = aMaxSize.Height();
}
}
pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
// 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 );
}
else
{
pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
if ( IsReallyVisible() )
ImplGenerateMouseMove();
}
}
// -----------------------------------------------------------------------
Point Window::GetPosPixel() const
{
return mpWindowImpl->maPos;
}
// -----------------------------------------------------------------------
Rectangle Window::GetDesktopRectPixel() const
{
Rectangle rRect;
mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
return rRect;
}
// -----------------------------------------------------------------------
Point Window::OutputToScreenPixel( const Point& rPos ) const
{
// relative to top level parent
return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
}
// -----------------------------------------------------------------------
Point Window::ScreenToOutputPixel( const Point& rPos ) const
{
// relative to top level parent
return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
}
// -----------------------------------------------------------------------
long Window::ImplGetUnmirroredOutOffX()
{
// revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
long offx = mnOutOffX;
if( ImplHasMirroredGraphics() )
{
if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
{
if ( !ImplIsOverlapWindow() )
offx -= mpWindowImpl->mpParent->mnOutOffX;
offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx;
if ( !ImplIsOverlapWindow() )
offx += mpWindowImpl->mpParent->mnOutOffX;
}
}
return offx;
}
// normalized screen pixel are independent of mirroring
Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
{
// relative to top level parent
long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
return Point( rPos.X()+offx, rPos.Y()+mnOutOffY );
}
Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
{
// relative to top level parent
long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
return Point( rPos.X()-offx, rPos.Y()-mnOutOffY );
}
// -----------------------------------------------------------------------
Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
{
// relative to the screen
Point p = OutputToScreenPixel( rPos );
SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
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 );
SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
p.X() -= g.nX;
p.Y() -= g.nY;
return p;
}
// -----------------------------------------------------------------------
Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle &rRect ) const
{
// this method creates unmirrored screen coordinates to be compared with the desktop
// and is used for positioning of RTL popup windows correctly on the screen
SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
Point p1 = OutputToScreenPixel( rRect.TopRight() );
p1.X() = g.nX+g.nWidth-p1.X();
p1.Y() += g.nY;
Point p2 = OutputToScreenPixel( rRect.BottomLeft() );
p2.X() = g.nX+g.nWidth-p2.X();
p2.Y() += g.nY;
return Rectangle( p1, p2 );
}
// -----------------------------------------------------------------------
Rectangle Window::GetWindowExtentsRelative( Window *pRelativeWindow )
{
// with decoration
return ImplGetWindowExtentsRelative( pRelativeWindow, FALSE );
}
Rectangle Window::GetClientWindowExtentsRelative( Window *pRelativeWindow )
{
// without decoration
return ImplGetWindowExtentsRelative( pRelativeWindow, TRUE );
}
// -----------------------------------------------------------------------
Rectangle Window::ImplGetWindowExtentsRelative( Window *pRelativeWindow, BOOL bClientOnly )
{
SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
// make sure we use the extent of our border window,
// otherwise we miss a few pixels
Window *pWin = (!bClientOnly && mpWindowImpl->mpBorderWindow) ? mpWindowImpl->mpBorderWindow : this;
Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) );
aPos.X() += g.nX;
aPos.Y() += g.nY;
Size aSize ( pWin->GetSizePixel() );
// #104088# do not add decoration to the workwindow to be compatible to java accessibility api
if( !bClientOnly && (mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WINDOW_WORKWINDOW)) )
{
aPos.X() -= g.nLeftDecoration;
aPos.Y() -= g.nTopDecoration;
aSize.Width() += g.nLeftDecoration + g.nRightDecoration;
aSize.Height() += g.nTopDecoration + g.nBottomDecoration;
}
if( pRelativeWindow )
{
// #106399# express coordinates relative to borderwindow
Window *pRelWin = (!bClientOnly && pRelativeWindow->mpWindowImpl->mpBorderWindow) ? pRelativeWindow->mpWindowImpl->mpBorderWindow : pRelativeWindow;
aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos );
}
return Rectangle( aPos, aSize );
}
// -----------------------------------------------------------------------
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 ( !mpWindowImpl->mbReallyVisible )
return FALSE;
if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
return TRUE;
if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
return TRUE;
if ( !ImplIsOverlapWindow() )
{
const Window* pTempWindow = this;
do
{
pTempWindow = pTempWindow->ImplGetParent();
if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDS | IMPL_PAINT_PAINTALLCHILDS) )
return TRUE;
}
while ( !pTempWindow->ImplIsOverlapWindow() );
}
return FALSE;
}
// -----------------------------------------------------------------------
void Window::Update()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpBorderWindow )
{
mpWindowImpl->mpBorderWindow->Update();
return;
}
if ( !mpWindowImpl->mbReallyVisible )
return;
BOOL bFlush = FALSE;
if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
{
Point aPoint( 0, 0 );
Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
ImplInvalidateOverlapFrameRegion( aRegion );
if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
bFlush = TRUE;
}
// Zuerst muessen wir alle Fenster ueberspringen, die Paint-Transparent
// sind
Window* pUpdateWindow = this;
Window* pWindow = pUpdateWindow;
while ( !pWindow->ImplIsOverlapWindow() )
{
if ( !pWindow->mpWindowImpl->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->mpWindowImpl->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->mpWindowImpl->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()->mpWindowImpl->mpFirstOverlap;
while ( pUpdateOverlapWindow )
{
pUpdateOverlapWindow->Update();
pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
}
pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags );
}
if ( bFlush )
Flush();
}
// -----------------------------------------------------------------------
void Window::Flush()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
const Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
mpWindowImpl->mpFrame->Flush( aWinRect );
}
// -----------------------------------------------------------------------
void Window::Sync()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
mpWindowImpl->mpFrame->Sync();
}
// -----------------------------------------------------------------------
void Window::SetUpdateMode( BOOL bUpdate )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
mpWindowImpl->mbNoUpdate = !bUpdate;
StateChanged( STATE_CHANGE_UPDATEMODE );
}
// -----------------------------------------------------------------------
void Window::GrabFocus()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
ImplGrabFocus( 0 );
}
// -----------------------------------------------------------------------
BOOL Window::HasFocus() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
// #107575# the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
// task was shifted to 6.y, so its commented out
/*
Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
else
pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
return (this == pFocusWin);
*/
return (this == ImplGetSVData()->maWinData.mpFocusWin);
}
// -----------------------------------------------------------------------
void Window::GrabFocusToDocument()
{
Window *pWin = this;
while( pWin )
{
if( !pWin->GetParent() )
{
pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
return;
}
pWin = pWin->GetParent();
}
}
void Window::SetFakeFocus( bool bFocus )
{
ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
}
// -----------------------------------------------------------------------
BOOL Window::HasChildPathFocus( BOOL bSystemWindow ) const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
// #107575#, the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
// task was shifted to 6.y, so its commented out
/*
Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
else
pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
*/
Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
if ( pFocusWin )
return ImplIsWindowOrChild( pFocusWin, 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;
mpWindowImpl->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;
mpWindowImpl->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 ( mpWindowImpl->maPointer == rPointer )
return;
mpWindowImpl->maPointer = rPointer;
// Pointer evt. direkt umsetzen
if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
}
// -----------------------------------------------------------------------
void Window::EnableChildPointerOverwrite( BOOL bOverwrite )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
return;
mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
// Pointer evt. direkt umsetzen
if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
}
// -----------------------------------------------------------------------
void Window::SetPointerPosPixel( const Point& rPos )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
Point aPos = ImplOutputToFrame( rPos );
if( ImplHasMirroredGraphics() )
{
if( !IsRTLEnabled() )
{
// --- RTL --- (re-mirror mouse pos at this window)
ImplReMirror( aPos );
}
// mirroring is required here, SetPointerPos bypasses SalGraphics
mpGraphics->mirror( aPos.X(), this );
}
else if( ImplIsAntiparallel() )
{
ImplReMirror( aPos );
}
mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
}
// -----------------------------------------------------------------------
Point Window::GetPointerPosPixel()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
if( ImplIsAntiparallel() )
{
// --- RTL --- (re-mirror mouse pos at this window)
ImplReMirror( aPos );
}
return ImplFrameToOutput( aPos );
}
// -----------------------------------------------------------------------
Point Window::GetLastPointerPosPixel()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
if( ImplIsAntiparallel() )
{
// --- RTL --- (re-mirror mouse pos at this window)
ImplReMirror( aPos );
}
return ImplFrameToOutput( aPos );
}
// -----------------------------------------------------------------------
void Window::ShowPointer( BOOL bVisible )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
{
mpWindowImpl->mbNoPtrVisible = !bVisible;
// Pointer evt. direkt umsetzen
if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
}
}
// -----------------------------------------------------------------------
Window::PointerState Window::GetPointerState()
{
PointerState aState;
aState.mnState = 0;
if (mpWindowImpl->mpFrame)
{
SalFrame::SalPointerState aSalPointerState;
aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
if( ImplIsAntiparallel() )
{
// --- RTL --- (re-mirror mouse pos at this window)
ImplReMirror( aSalPointerState.maPos );
}
aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
aState.mnState = aSalPointerState.mnState;
}
return aState;
}
// -----------------------------------------------------------------------
BOOL Window::IsMouseOver()
{
return ImplGetWinData()->mbMouseOver;
}
// -----------------------------------------------------------------------
void Window::EnterWait()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
mpWindowImpl->mnWaitCount++;
if ( mpWindowImpl->mnWaitCount == 1 )
{
// Pointer evt. direkt umsetzen
if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
}
}
// -----------------------------------------------------------------------
void Window::LeaveWait()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mnWaitCount )
{
mpWindowImpl->mnWaitCount--;
if ( !mpWindowImpl->mnWaitCount )
{
// Pointer evt. direkt umsetzen
if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
}
}
}
// -----------------------------------------------------------------------
void Window::SetCursor( Cursor* pCursor )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if ( mpWindowImpl->mpCursor != pCursor )
{
if ( mpWindowImpl->mpCursor )
mpWindowImpl->mpCursor->ImplHide();
mpWindowImpl->mpCursor = pCursor;
if ( pCursor )
pCursor->ImplShow();
}
}
// -----------------------------------------------------------------------
void Window::SetText( const XubString& rStr )
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
String oldTitle( mpWindowImpl->maText );
mpWindowImpl->maText = rStr;
if ( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->SetText( rStr );
else if ( mpWindowImpl->mbFrame )
mpWindowImpl->mpFrame->SetTitle( rStr );
ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
// #107247# needed for accessibility
// The VCLEVENT_WINDOW_FRAMETITLECHANGED is (mis)used to notify accessible name changes.
// Therefore a window, which is labeled by this window, must also notify an accessible
// name change.
if ( IsReallyVisible() )
{
Window* pWindow = GetLabelFor();
if ( pWindow && pWindow != this )
pWindow->ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
}
StateChanged( STATE_CHANGE_TEXT );
}
// -----------------------------------------------------------------------
String Window::GetText() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
return mpWindowImpl->maText;
}
// -----------------------------------------------------------------------
String Window::GetDisplayText() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
return GetText();
}
// -----------------------------------------------------------------------
const Wallpaper& Window::GetDisplayBackground() const
{
// FIXME: fix issue 52349, need to fix this really in
// all NWF enabled controls
const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
if( pTB )
{
if( IsNativeWidgetEnabled() )
return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
}
if( !IsBackground() )
{
if( mpWindowImpl->mpParent )
return mpWindowImpl->mpParent->GetDisplayBackground();
}
const Wallpaper& rBack = GetBackground();
if( ! rBack.IsBitmap() &&
! rBack.IsGradient() &&
rBack.GetColor().GetColor() == COL_TRANSPARENT &&
mpWindowImpl->mpParent )
return mpWindowImpl->mpParent->GetDisplayBackground();
return rBack;
}
// -----------------------------------------------------------------------
const XubString& Window::GetHelpText() const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
SmartId aSmartId = GetSmartHelpId();
ULONG nNumHelpId = 0;
String aStrHelpId;
if( aSmartId.HasString() )
aStrHelpId = aSmartId.GetStr();
if( aSmartId.HasNumeric() )
nNumHelpId = aSmartId.GetNum();
bool bStrHelpId = (aStrHelpId.Len() > 0);
if ( !mpWindowImpl->maHelpText.Len() && (nNumHelpId || bStrHelpId) )
{
if ( !IsDialog() && (mpWindowImpl->mnType != WINDOW_TABPAGE) && (mpWindowImpl->mnType != WINDOW_FLOATINGWINDOW) )
{
Help* pHelp = Application::GetHelp();
if ( pHelp )
{
if( bStrHelpId )
((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this );
else
((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( nNumHelpId, this );
mpWindowImpl->mbHelpTextDynamic = FALSE;
}
}
}
else if( mpWindowImpl->mbHelpTextDynamic && (nNumHelpId || bStrHelpId) )
{
static const char* pEnv = getenv( "HELP_DEBUG" );
if( pEnv && *pEnv )
{
rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() );
aTxt.append( mpWindowImpl->maHelpText );
aTxt.appendAscii( "\n+++++++++++++++\n" );
if( bStrHelpId )
aTxt.append( rtl::OUString( aStrHelpId ) );
else
aTxt.append( sal_Int32( nNumHelpId ) );
mpWindowImpl->maHelpText = aTxt.makeStringAndClear();
}
mpWindowImpl->mbHelpTextDynamic = FALSE;
}
return mpWindowImpl->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 = mpWindowImpl->mpFirstChild;
while ( pChild )
{
nChildCount++;
pChild = pChild->mpWindowImpl->mpNext;
}
return nChildCount;
}
// -----------------------------------------------------------------------
Window* Window::GetChild( USHORT nChild ) const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
USHORT nChildCount = 0;
Window* pChild = mpWindowImpl->mpFirstChild;
while ( pChild )
{
if ( nChild == nChildCount )
return pChild;
pChild = pChild->mpWindowImpl->mpNext;
nChildCount++;
}
return NULL;
}
// -----------------------------------------------------------------------
Window* Window::GetWindow( USHORT nType ) const
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
switch ( nType )
{
case WINDOW_PARENT:
return mpWindowImpl->mpRealParent;
case WINDOW_FIRSTCHILD:
return mpWindowImpl->mpFirstChild;
case WINDOW_LASTCHILD:
return mpWindowImpl->mpLastChild;
case WINDOW_PREV:
return mpWindowImpl->mpPrev;
case WINDOW_NEXT:
return mpWindowImpl->mpNext;
case WINDOW_FIRSTOVERLAP:
return mpWindowImpl->mpFirstOverlap;
case WINDOW_LASTOVERLAP:
return mpWindowImpl->mpLastOverlap;
case WINDOW_OVERLAP:
if ( ImplIsOverlapWindow() )
return (Window*)this;
else
return mpWindowImpl->mpOverlapWindow;
case WINDOW_PARENTOVERLAP:
if ( ImplIsOverlapWindow() )
return mpWindowImpl->mpOverlapWindow;
else
return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
case WINDOW_CLIENT:
return ((Window*)this)->ImplGetWindow();
case WINDOW_REALPARENT:
return ImplGetParent();
case WINDOW_FRAME:
return mpWindowImpl->mpFrameWindow;
case WINDOW_BORDER:
if ( mpWindowImpl->mpBorderWindow )
return mpWindowImpl->mpBorderWindow->GetWindow( WINDOW_BORDER );
return (Window*)this;
case WINDOW_FIRSTTOPWINDOWCHILD:
return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.begin();
case WINDOW_LASTTOPWINDOWCHILD:
return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.rbegin();
case WINDOW_PREVTOPWINDOWSIBLING:
{
if ( !mpWindowImpl->mpRealParent )
return NULL;
const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
::std::list< Window* >::const_iterator myPos =
::std::find( rTopWindows.begin(), rTopWindows.end(), this );
if ( myPos == rTopWindows.end() )
return NULL;
if ( myPos == rTopWindows.begin() )
return NULL;
return *--myPos;
}
case WINDOW_NEXTTOPWINDOWSIBLING:
{
if ( !mpWindowImpl->mpRealParent )
return NULL;
const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
::std::list< Window* >::const_iterator myPos =
::std::find( rTopWindows.begin(), rTopWindows.end(), this );
if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
return NULL;
return *myPos;
}
}
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 );
return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : NULL;
}
::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 )
{
// be safe against re-entrance: first clear the old ref, then assign the new one
// #133706# / 2006-03-30 / frank.schoenheit@sun.com
mpWindowImpl->mxWindowPeer.clear();
mpWindowImpl->mxWindowPeer = xPeer;
mpWindowImpl->mpVCLXWindow = pVCLXWindow;
}
// -----------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( BOOL bCreate )
{
if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
{
UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
if ( pWrapper )
mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True );
}
return mpWindowImpl->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
if ( !pNew || !ImplIsChild( pNew ) )
{
ImplDelData aDogtag( this );
ImplCallEventListeners( VCLEVENT_WINDOW_DEACTIVATE );
if( aDogtag.IsDelete() )
return;
// #100759#, avoid walking the wrong frame's hierarchy
// eg, undocked docking windows (ImplDockFloatWin)
if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
ImplGetParent()->ImplCallDeactivateListeners( pNew );
}
}
// -----------------------------------------------------------------------
void Window::ImplCallActivateListeners( Window *pOld )
{
// no activation if the the old active window is my child
if ( !pOld || !ImplIsChild( pOld ) )
{
ImplDelData aDogtag( this );
ImplCallEventListeners( VCLEVENT_WINDOW_ACTIVATE, pOld );
if( aDogtag.IsDelete() )
return;
// #106298# revoke the change for 105369, because this change
// disabled the activate event for the parent,
// if the parent is a compound control
//if( !GetParent() || !GetParent()->IsCompoundControl() )
//{
// #100759#, avoid walking the wrong frame's hierarchy
// eg, undocked docking windows (ImplDockFloatWin)
// #104714#, revert the changes for 100759 because it has a side effect when pOld is a dialog
// additionally the gallery is not dockable anymore, so 100759 canot occur
if ( ImplGetParent() ) /* && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow ) */
ImplGetParent()->ImplCallActivateListeners( pOld );
else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
{
// top level frame reached: store hint for DefModalDialogParent
ImplGetSVData()->maWinData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
}
//}
}
}
// -----------------------------------------------------------------------
bool Window::ImplStopDnd()
{
bool bRet = false;
if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
{
bRet = true;
mpWindowImpl->mpFrameData->mxDropTarget.clear();
mpWindowImpl->mpFrameData->mxDragSource.clear();
mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
}
return bRet;
}
// -----------------------------------------------------------------------
void Window::ImplStartDnd()
{
GetDropTarget();
}
// -----------------------------------------------------------------------
Reference< XDropTarget > Window::GetDropTarget()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( ! mpWindowImpl->mxDNDListenerContainer.is() )
{
sal_Int8 nDefaultActions = 0;
if( mpWindowImpl->mpFrameData )
{
if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
{
// initialization is done in GetDragSource
Reference< XDragSource > xDragSource = GetDragSource();
}
if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
{
nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
{
mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
try
{
mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
// register also as drag gesture listener if directly supported by drag source
Reference< XDragGestureRecognizer > xDragGestureRecognizer =
Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
if( xDragGestureRecognizer.is() )
{
xDragGestureRecognizer->addDragGestureListener(
Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
}
else
mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = TRUE;
}
catch( RuntimeException exc )
{
// release all instances
mpWindowImpl->mpFrameData->mxDropTarget.clear();
mpWindowImpl->mpFrameData->mxDragSource.clear();
}
}
}
}
mpWindowImpl->mxDNDListenerContainer = static_cast < XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
}
// this object is located in the same process, so there will be no runtime exception
return Reference< XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
}
// -----------------------------------------------------------------------
Reference< XDragSource > Window::GetDragSource()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( mpWindowImpl->mpFrameData )
{
if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
{
try
{
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 QUARTZ
/* FIXME: Mac OS X specific dnd interface does not exist! *
* Using Windows based dnd as a temporary solution */
aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" );
aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" );
aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) );
aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) );
#elif defined UNX
aDropTargetAL.realloc( 3 );
aDragSourceAL.realloc( 3 );
aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DragSource" );
aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DropTarget" );
aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
aDragSourceAL[ 2 ] = makeAny( vcl::createBmpConverter() );
aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
aDropTargetAL[ 1 ] = makeAny( (sal_Size)(pEnvData->aShellWindow) );
aDropTargetAL[ 2 ] = makeAny( vcl::createBmpConverter() );
#endif
if( aDragSourceSN.getLength() )
mpWindowImpl->mpFrameData->mxDragSource = Reference< XDragSource > ( xFactory->createInstanceWithArguments( aDragSourceSN, aDragSourceAL ), UNO_QUERY );
if( aDropTargetSN.getLength() )
mpWindowImpl->mpFrameData->mxDropTarget = Reference< XDropTarget > ( xFactory->createInstanceWithArguments( aDropTargetSN, aDropTargetAL ), UNO_QUERY );
}
}
}
// createInstance can throw any exception
catch( Exception exc )
{
// release all instances
mpWindowImpl->mpFrameData->mxDropTarget.clear();
mpWindowImpl->mpFrameData->mxDragSource.clear();
}
}
return mpWindowImpl->mpFrameData->mxDragSource;
}
return Reference< XDragSource > ();
}
// -----------------------------------------------------------------------
void Window::GetDragSourceDropTarget(Reference< XDragSource >& xDragSource, Reference< XDropTarget > &xDropTarget )
// only for RVP transmission
{
if( mpWindowImpl->mpFrameData )
{
// initialization is done in GetDragSource
xDragSource = GetDragSource();
xDropTarget = mpWindowImpl->mpFrameData->mxDropTarget;
}
else
{
xDragSource.clear();
xDropTarget.clear();
}
}
// -----------------------------------------------------------------------
Reference< XDragGestureRecognizer > Window::GetDragGestureRecognizer()
{
return Reference< XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
}
// -----------------------------------------------------------------------
Reference< XClipboard > Window::GetClipboard()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( mpWindowImpl->mpFrameData )
{
if( ! mpWindowImpl->mpFrameData->mxClipboard.is() )
{
try
{
Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
if( xFactory.is() )
{
mpWindowImpl->mpFrameData->mxClipboard = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY );
#if defined(UNX) && !defined(QUARTZ) // unix clipboard needs to be initialized
if( mpWindowImpl->mpFrameData->mxClipboard.is() )
{
Reference< XInitialization > xInit = Reference< XInitialization >( mpWindowImpl->mpFrameData->mxClipboard, UNO_QUERY );
if( xInit.is() )
{
Sequence< Any > aArgumentList( 3 );
aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "CLIPBOARD" ) );
aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
xInit->initialize( aArgumentList );
}
}
#endif
}
}
// createInstance can throw any exception
catch( Exception exc )
{
// release all instances
mpWindowImpl->mpFrameData->mxClipboard.clear();
}
}
return mpWindowImpl->mpFrameData->mxClipboard;
}
return static_cast < XClipboard * > (0);
}
// -----------------------------------------------------------------------
Reference< XClipboard > Window::GetPrimarySelection()
{
DBG_CHKTHIS( Window, ImplDbgCheckWindow );
if( mpWindowImpl->mpFrameData )
{
if( ! mpWindowImpl->mpFrameData->mxSelection.is() )
{
try
{
Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
if( xFactory.is() )
{
#if defined(UNX) && !defined(QUARTZ)
Sequence< Any > aArgumentList( 3 );
aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "PRIMARY" ) );
aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
mpWindowImpl->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 );
mpWindowImpl->mpFrameData->mxSelection = s_xSelection;
# endif
}
}
// createInstance can throw any exception
catch( Exception exc )
{
// release all instances
mpWindowImpl->mpFrameData->mxSelection.clear();
}
}
return mpWindowImpl->mpFrameData->mxSelection;
}
return static_cast < XClipboard * > (0);
}
// -----------------------------------------------------------------------
// Accessibility
// -----------------------------------------------------------------------
::com::sun::star::uno::Reference< ::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 ) )
//if( !ImplIsAccessibleCandidate() )
{
Window* pChild = GetAccessibleChildWindow( 0 );
if ( pChild )
return pChild->GetAccessible();
}
*/
if ( !mpWindowImpl->mxAccessible.is() && bCreate )
mpWindowImpl->mxAccessible = CreateAccessible();
return mpWindowImpl->mxAccessible;
}
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
{
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( TRUE ), ::com::sun::star::uno::UNO_QUERY );
return xAcc;
}
void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x )
{
mpWindowImpl->mxAccessible = x;
}
// skip all border windows that are no top level frames
BOOL Window::ImplIsAccessibleCandidate() const
{
if( !mpWindowImpl->mbBorderWin )
return TRUE;
else
// #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menues!) are closeable
if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) )
return TRUE;
else
return FALSE;
}
BOOL Window::ImplIsAccessibleNativeFrame() const
{
if( mpWindowImpl->mbFrame )
// #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menues!) are closeable
if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | 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 )
{
if( pChild->ImplIsAccessibleCandidate() )
nChildren++;
else
nChildren = sal::static_int_cast<USHORT>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD ));
pChild = pChild->mpWindowImpl->mpNext;
}
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->mpWindowImpl->mpNext;
rChildCount++;
}
return NULL;
}
/*
Window* Window::GetAccessibleParentWindow() const
{
Window* pParent = GetParent();
while ( pParent )
if( pParent->ImplIsAccessibleCandidate() )
break;
else
pParent = pParent->GetParent();
return pParent;
}
*/
Window* Window::GetAccessibleParentWindow() const
{
if ( ImplIsAccessibleNativeFrame() )
return NULL;
Window* pParent = mpWindowImpl->mpParent;
if( GetType() == WINDOW_MENUBARWINDOW )
{
// report the menubar as a child of THE workwindow
Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild;
while( pWorkWin && (pWorkWin == this) )
pWorkWin = pWorkWin->mpWindowImpl->mpNext;
pParent = pWorkWin;
}
// If this a floating window which has a native boarder window, this one should be reported as
// accessible parent
else if( GetType() == WINDOW_FLOATINGWINDOW &&
mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame)
{
pParent = mpWindowImpl->mpBorderWindow;
}
else if( pParent && !pParent->ImplIsAccessibleCandidate() )
{
pParent = pParent->mpWindowImpl->mpParent;
}
return pParent;
}
/*
USHORT Window::GetAccessibleChildWindowCount()
{
USHORT nChildren = ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD );
// Search also for SystemWindows.
Window* pOverlap = GetWindow( WINDOW_OVERLAP );
nChildren += pOverlap->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTOVERLAP );
return nChildren;
}
*/
USHORT Window::GetAccessibleChildWindowCount()
{
USHORT nChildren = 0;
Window* pChild = mpWindowImpl->mpFirstChild;
while( pChild )
{
if( pChild->IsVisible() )
nChildren++;
pChild = pChild->mpWindowImpl->mpNext;
}
// #107176# ignore overlapwindows
// this only affects non-system floating windows
// which are either not accessible (like the HelpAgent) or should be changed to system windows anyway
/*
if( ImplIsOverlapWindow() )
{
Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
while ( pOverlap )
{
if( pOverlap->IsVisible() )
nChildren++;
pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
}
}
*/
// report the menubarwindow as a child of THE workwindow
if( GetType() == WINDOW_BORDERWINDOW )
{
if( ((ImplBorderWindow *) this)->mpMenuBarWindow &&
((ImplBorderWindow *) this)->mpMenuBarWindow->IsVisible()
)
--nChildren;
}
else if( GetType() == WINDOW_WORKWINDOW )
{
if( ((WorkWindow *) this)->GetMenuBar() &&
((WorkWindow *) this)->GetMenuBar()->GetWindow() &&
((WorkWindow *) this)->GetMenuBar()->GetWindow()->IsVisible()
)
++nChildren;
}
return nChildren;
}
/*
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 );
}
return pChild;
}
*/
Window* Window::GetAccessibleChildWindow( USHORT n )
{
// report the menubarwindow as a the first child of THE workwindow
if( GetType() == WINDOW_WORKWINDOW && ((WorkWindow *) this)->GetMenuBar() )
{
if( n == 0 )
{
MenuBar *pMenuBar = ((WorkWindow *) this)->GetMenuBar();
if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
return pMenuBar->GetWindow();
}
else
--n;
}
// transform n to child number including invisible children
USHORT nChildren = n;
Window* pChild = mpWindowImpl->mpFirstChild;
while( pChild )
{
if( pChild->IsVisible() )
{
if( ! nChildren )
break;
nChildren--;
}
pChild = pChild->mpWindowImpl->mpNext;
}
if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
{
do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() );
DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
}
if ( !pChild )
{
// #107176# ignore overlapwindows
/*
if( ImplIsOverlapWindow() )
{
Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
while ( !pChild && pOverlap )
{
if ( !nChildren && pOverlap->IsVisible() )
{
pChild = pOverlap;
break;
}
pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
if( pOverlap && pOverlap->IsVisible() )
nChildren--;
}
}
*/
}
if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
{
pChild = pChild->GetChild( 0 );
}
return pChild;
}
void Window::SetAccessibleRole( USHORT nRole )
{
if ( !mpWindowImpl->mpAccessibleInfos )
mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole;
}
USHORT Window::GetAccessibleRole() const
{
using namespace ::com::sun::star;
USHORT nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF;
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::ALERT; 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::PUSH_BUTTON; break;
case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break;
case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break;
case WINDOW_IMAGERADIOBUTTON:
case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break;
case WINDOW_TRISTATEBOX:
case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break;
case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
case WINDOW_PATTERNFIELD:
case WINDOW_NUMERICFIELD:
case WINDOW_METRICFIELD:
case WINDOW_CURRENCYFIELD:
case WINDOW_LONGCURRENCYFIELD:
case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (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::COMBO_BOX; break;
case WINDOW_LISTBOX:
case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; 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::GROUP_BOX; break;
case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
case WINDOW_SLIDER:
case WINDOW_SPLITTER:
case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
case WINDOW_DATEBOX:
case WINDOW_TIMEBOX:
case WINDOW_DATEFIELD:
case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break;
case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break;
case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
case WINDOW_DOCKINGWINDOW:
case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME :
accessibility::AccessibleRole::PANEL; break;
case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame ||
(mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ||
(GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME :
accessibility::AccessibleRole::WINDOW; break;
case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break;
case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break;
case WINDOW_WINDOW:
case WINDOW_CONTROL:
case WINDOW_BORDERWINDOW:
case WINDOW_SYSTEMCHILDWINDOW:
default:
if (ImplIsAccessibleNativeFrame() )
nRole = accessibility::AccessibleRole::FRAME;
else if( IsScrollable() )
nRole = accessibility::AccessibleRole::SCROLL_PANE;
else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() )
nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenues are windows (i.e. toplevel)
else
// #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead
// a WINDOW is interpreted as a top-level window, which is typically not the case
//nRole = accessibility::AccessibleRole::WINDOW;
nRole = accessibility::AccessibleRole::PANEL;
}
}
return nRole;
}
void Window::SetAccessibleName( const String& rName )
{
if ( !mpWindowImpl->mpAccessibleInfos )
mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleName, "AccessibleName already set!" );
delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
mpWindowImpl->mpAccessibleInfos->pAccessibleName = new String( rName );
}
String Window::GetAccessibleName() const
{
String aAccessibleName;
if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName )
{
aAccessibleName = *mpWindowImpl->mpAccessibleInfos->pAccessibleName;
}
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:
case WINDOW_TREELISTBOX:
{
Window *pLabel = GetLabeledBy();
if ( pLabel && pLabel != this )
aAccessibleName = pLabel->GetText();
}
break;
case WINDOW_IMAGEBUTTON:
case WINDOW_PUSHBUTTON:
aAccessibleName = GetText();
if ( !aAccessibleName.Len() )
{
aAccessibleName = GetQuickHelpText();
if ( !aAccessibleName.Len() )
aAccessibleName = GetHelpText();
}
break;
default:
aAccessibleName = GetText();
break;
}
aAccessibleName = GetNonMnemonicString( aAccessibleName );
}
return aAccessibleName;
}
void Window::SetAccessibleDescription( const String& rDescription )
{
if ( ! mpWindowImpl->mpAccessibleInfos )
mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new String( rDescription );
}
String Window::GetAccessibleDescription() const
{
String aAccessibleDescription;
if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
{
aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
}
else
{
// Special code for help text windows. ZT asks the border window for the
// description so we have to forward this request to our inner window.
const Window* pWin = ((Window *)this)->ImplGetWindow();
if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW )
aAccessibleDescription = pWin->GetHelpText();
else
aAccessibleDescription = GetHelpText();
}
return aAccessibleDescription;
}
BOOL Window::IsAccessibilityEventsSuppressed( BOOL bTraverseParentPath )
{
if( !bTraverseParentPath )
return mpWindowImpl->mbSuppressAccessibilityEvents;
else
{
Window *pParent = this;
while ( pParent && pParent->mpWindowImpl)
{
if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents )
return TRUE;
else
pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
}
return FALSE;
}
}
void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const Rectangle& rRect )
{
if( ! mpOutDevData )
ImplInitOutDevData();
mpOutDevData->mpRecordLayout = pLayout;
mpOutDevData->maRecordRect = rRect;
Paint( rRect );
mpOutDevData->mpRecordLayout = NULL;
}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// 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;
}
void Window::DrawSelectionBackground( const Rectangle& rRect, USHORT highlight, BOOL bChecked, BOOL bDrawBorder, BOOL bDrawExtBorderOnly )
{
DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, NULL, NULL );
}
void Window::DrawSelectionBackground( const Rectangle& rRect, USHORT highlight, BOOL bChecked, BOOL bDrawBorder, BOOL bDrawExtBorderOnly, Color* pSelectionTextColor )
{
DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, pSelectionTextColor, NULL );
}
void Window::DrawSelectionBackground( const Rectangle& rRect,
USHORT highlight,
BOOL bChecked,
BOOL bDrawBorder,
BOOL bDrawExtBorderOnly,
long nCornerRadius,
Color* pSelectionTextColor,
Color* pPaintColor
)
{
if( rRect.IsEmpty() )
return;
bool bRoundEdges = nCornerRadius > 0;
const StyleSettings& rStyles = GetSettings().GetStyleSettings();
// colors used for item highlighting
Color aSelectionBorderCol( pPaintColor ? *pPaintColor : rStyles.GetHighlightColor() );
Color aSelectionFillCol( aSelectionBorderCol );
BOOL bDark = rStyles.GetFaceColor().IsDark();
BOOL bBright = ( rStyles.GetFaceColor() == Color( COL_WHITE ) );
int c1 = aSelectionBorderCol.GetLuminance();
int c2 = GetDisplayBackground().GetColor().GetLuminance();
if( !bDark && !bBright && abs( c2-c1 ) < (pPaintColor ? 40 : 75) )
{
// constrast too low
USHORT h,s,b;
aSelectionFillCol.RGBtoHSB( h, s, b );
if( b > 50 ) b -= 40;
else b += 40;
aSelectionFillCol.SetColor( Color::HSBtoRGB( h, s, b ) );
aSelectionBorderCol = aSelectionFillCol;
}
if( bRoundEdges )
{
if( aSelectionBorderCol.IsDark() )
aSelectionBorderCol.IncreaseLuminance( 128 );
else
aSelectionBorderCol.DecreaseLuminance( 128 );
}
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 = 0;
if( !highlight )
{
if( bDark )
aSelectionFillCol = COL_BLACK;
else
nPercent = bRoundEdges ? 90 : 80; // just checked (light)
}
else
{
if( bChecked && highlight == 2 )
{
if( bDark )
aSelectionFillCol = COL_LIGHTGRAY;
else if ( bBright )
{
aSelectionFillCol = COL_BLACK;
SetLineColor( COL_BLACK );
nPercent = 0;
}
else
nPercent = bRoundEdges ? 50 : 20; // selected, pressed or checked ( very dark )
}
else if( bChecked || highlight == 1 )
{
if( bDark )
aSelectionFillCol = COL_GRAY;
else if ( bBright )
{
aSelectionFillCol = COL_BLACK;
SetLineColor( COL_BLACK );
nPercent = 0;
}
else
nPercent = bRoundEdges ? 70 : 35; // selected, pressed or checked ( very dark )
}
else
{
if( bDark )
aSelectionFillCol = COL_LIGHTGRAY;
else if ( bBright )
{
aSelectionFillCol = COL_BLACK;
SetLineColor( COL_BLACK );
if( highlight == 3 )
nPercent = 80;
else
nPercent = 0;
}
else
nPercent = bRoundEdges ? 80 : 70; // selected ( dark )
}
}
if( bDark && bDrawExtBorderOnly )
{
SetFillColor();
if( pSelectionTextColor )
*pSelectionTextColor = rStyles.GetHighlightTextColor();
}
else
{
SetFillColor( aSelectionFillCol );
if( pSelectionTextColor )
{
Color aTextColor = IsControlBackground() ? GetControlForeground() : rStyles.GetButtonTextColor();
Color aHLTextColor = rStyles.GetHighlightTextColor();
int nTextDiff = abs(aSelectionFillCol.GetLuminance() - aTextColor.GetLuminance());
int nHLDiff = abs(aSelectionFillCol.GetLuminance() - aHLTextColor.GetLuminance());
*pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor;
}
}
if( bDark )
{
DrawRect( aRect );
}
else
{
if( bRoundEdges )
{
Polygon aPoly( aRect, nCornerRadius, nCornerRadius );
PolyPolygon aPolyPoly( aPoly );
DrawTransparent( aPolyPoly, nPercent );
}
else
{
Polygon aPoly( aRect );
PolyPolygon aPolyPoly( aPoly );
DrawTransparent( aPolyPoly, nPercent );
}
}
SetFillColor( oldFillCol );
SetLineColor( oldLineCol );
}
/*
void Window::DbgAssertNoEventListeners()
{
VclWindowEvent aEvent( this, 0, NULL );
DBG_ASSERT( mpWindowImpl->maEventListeners.empty(), "Eventlistener: Who is still listening???" )
if ( !mpWindowImpl->maEventListeners.empty() )
mpWindowImpl->maEventListeners.Call( &aEvent );
DBG_ASSERT( mpWindowImpl->maChildEventListeners.empty(), "ChildEventlistener: Who is still listening???" )
if ( !mpWindowImpl->maChildEventListeners.empty() )
mpWindowImpl->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;
}
BOOL Window::IsScrollable() const
{
// check for scrollbars
Window *pChild = mpWindowImpl->mpFirstChild;
while( pChild )
{
if( pChild->GetType() == WINDOW_SCROLLBAR )
return true;
else
pChild = pChild->mpWindowImpl->mpNext;
}
return false;
}
BOOL Window::IsTopWindow() const
{
if ( mpWindowImpl->mbInDtor )
return FALSE;
// topwindows must be frames or they must have a borderwindow which is a frame
if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) )
return FALSE;
ImplGetWinData();
if( mpWindowImpl->mpWinData->mnIsTopWindow == (USHORT)~0) // still uninitialized
{
// #113722#, cache result of expensive queryInterface call
Window *pThisWin = (Window*)this;
Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
}
return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? TRUE : FALSE;
}
void Window::ImplMirrorFramePos( Point &pt ) const
{
pt.X() = mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X();
}
// frame based modal counter (dialogs are not modal to the whole application anymore)
BOOL Window::IsInModalMode() const
{
return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
}
void Window::ImplIncModalCount()
{
Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
Window* pParent = pFrameWindow;
while( pFrameWindow )
{
pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
{
pParent = pParent->GetParent();
}
pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
}
}
void Window::ImplDecModalCount()
{
Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
Window* pParent = pFrameWindow;
while( pFrameWindow )
{
pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
{
pParent = pParent->GetParent();
}
pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
}
}
BOOL Window::ImplIsInTaskPaneList()
{
return mpWindowImpl->mbIsInTaskPaneList;
}
void Window::ImplIsInTaskPaneList( BOOL mbIsInTaskList )
{
mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
}
void Window::ImplNotifyIconifiedState( BOOL bIconified )
{
mpWindowImpl->mpFrameWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
// #109206# notify client window as well to have toolkit topwindow listeners notified
if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
}
BOOL Window::HasActiveChildFrame()
{
BOOL bRet = FALSE;
Window *pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
while( pFrameWin )
{
if( pFrameWin != mpWindowImpl->mpFrameWindow )
{
BOOL bDecorated = FALSE;
Window *pChildFrame = pFrameWin->ImplGetWindow();
// #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
// be removed for ToolBoxes to influence the keyboard accessibility
// thus WB_MOVEABLE is no indicator for decoration anymore
// but FloatingWindows carry this information in their TitleType...
// TODO: avoid duplicate WinBits !!!
if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
bDecorated = ((FloatingWindow*) pChildFrame)->GetTitleType() != FLOATWIN_TITLE_NONE;
if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
{
if( ImplIsChild( pChildFrame, TRUE ) )
{
bRet = TRUE;
break;
}
}
}
pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
}
return bRet;
}
LanguageType Window::GetInputLanguage() const
{
return mpWindowImpl->mpFrame->GetInputLanguage();
}
void Window::EnableNativeWidget( BOOL bEnable )
{
static const char* pNoNWF = getenv( "SAL_NO_NWF" );
if( pNoNWF && *pNoNWF )
bEnable = FALSE;
if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
{
ImplGetWinData()->mbEnableNativeWidget = bEnable;
// send datachanged event to allow for internal changes required for NWF
// like clipmode, transparency, etc.
DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &maSettings, SETTINGS_STYLE );
DataChanged( aDCEvt );
// sometimes the borderwindow is queried, so keep it in sync
if( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
}
// push down, useful for compound controls
Window *pChild = mpWindowImpl->mpFirstChild;
while( pChild )
{
pChild->EnableNativeWidget( bEnable );
pChild = pChild->mpWindowImpl->mpNext;
}
}
BOOL Window::IsNativeWidgetEnabled() const
{
return ImplGetWinData()->mbEnableNativeWidget;
}
#ifdef WNT // see #140456#
#include <salframe.h>
#endif
Reference< rendering::XCanvas > Window::ImplGetCanvas( const Size& rFullscreenSize,
bool bFullscreen,
bool bSpriteCanvas ) const
{
// try to retrieve hard reference from weak member
Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
// canvas still valid? Then we're done.
if( xCanvas.is() )
return xCanvas;
Sequence< Any > aArg(6);
// Feed any with operating system's window handle
// ==============================================
// common: first any is VCL pointer to window (for VCL canvas)
aArg[ 0 ] = makeAny( reinterpret_cast<sal_Int64>(this) );
// TODO(Q1): Make GetSystemData method virtual
// check whether we're a SysChild: have to fetch system data
// directly from SystemChildWindow, because the GetSystemData
// method is unfortunately not virtual
const SystemChildWindow* pSysChild = dynamic_cast< const SystemChildWindow* >( this );
if( pSysChild )
{
aArg[ 1 ] = pSysChild->GetSystemDataAny();
aArg[ 5 ] = pSysChild->GetSystemGfxDataAny();
}
else
{
aArg[ 1 ] = GetSystemDataAny();
aArg[ 5 ] = GetSystemGfxDataAny();
}
if( bFullscreen )
aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( 0, 0,
rFullscreenSize.Width(),
rFullscreenSize.Height() ) );
else
aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
aArg[ 3 ] = makeAny( mpWindowImpl->mbAlwaysOnTop ? sal_True : sal_False );
aArg[ 4 ] = makeAny( Reference< awt::XWindow >(
const_cast<Window*>(this)->GetComponentInterface(),
uno::UNO_QUERY ));
Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
// Create canvas instance with window handle
// =========================================
if ( xFactory.is() )
{
static Reference<lang::XMultiServiceFactory> xCanvasFactory(
xFactory->createInstance(
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star."
"rendering.CanvasFactory") ) ), UNO_QUERY );
if(xCanvasFactory.is())
{
#ifdef WNT
// see #140456# - if we're running on a multiscreen setup,
// request special, multi-screen safe sprite canvas
// implementation (not DX5 canvas, as it cannot cope with
// surfaces spanning multiple displays). Note: canvas
// (without sprite) stays the same)
const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay;
if( (nDisplay >= Application::GetScreenCount()) )
{
xCanvas.set( xCanvasFactory->createInstanceWithArguments(
bSpriteCanvas ?
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.rendering.SpriteCanvas.MultiScreen" )) :
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.rendering.Canvas" )),
aArg ),
UNO_QUERY );
}
else
{
#endif
xCanvas.set( xCanvasFactory->createInstanceWithArguments(
bSpriteCanvas ?
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.rendering.SpriteCanvas" )) :
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.rendering.Canvas" )),
aArg ),
UNO_QUERY );
#ifdef WNT
}
#endif
mpWindowImpl->mxCanvas = xCanvas;
}
}
// no factory??? Empty reference, then.
return xCanvas;
}
Reference< rendering::XCanvas > Window::GetCanvas() const
{
return ImplGetCanvas( Size(), false, false );
}
Reference< rendering::XSpriteCanvas > Window::GetSpriteCanvas() const
{
Reference< rendering::XSpriteCanvas > xSpriteCanvas(
ImplGetCanvas( Size(), false, true ), uno::UNO_QUERY );
return xSpriteCanvas;
}
Reference< ::com::sun::star::rendering::XSpriteCanvas > Window::GetFullscreenSpriteCanvas( const Size& rFullscreenSize ) const
{
Reference< rendering::XSpriteCanvas > xSpriteCanvas(
ImplGetCanvas( rFullscreenSize, true, true ), uno::UNO_QUERY );
return xSpriteCanvas;
}
void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
{
BOOL bRVisible = mpWindowImpl->mbReallyVisible;
mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
BOOL bDevOutput = mbDevOutput;
mbDevOutput = TRUE;
long nOldDPIX = ImplGetDPIX();
long nOldDPIY = ImplGetDPIY();
mnDPIX = i_pTargetOutDev->ImplGetDPIX();
mnDPIY = i_pTargetOutDev->ImplGetDPIY();
BOOL bOutput = IsOutputEnabled();
EnableOutput();
DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
if ( GetMapMode().GetMapUnit() != MAP_PIXEL )
return;
// preserve graphicsstate
Push();
Region aClipRegion( GetClipRegion() );
SetClipRegion();
GDIMetaFile* pOldMtf = GetConnectMetaFile();
GDIMetaFile aMtf;
SetConnectMetaFile( &aMtf );
// put a push action to metafile
Push();
// copy graphics state to metafile
Font aCopyFont = GetFont();
if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY )
{
aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY );
aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX );
}
SetFont( aCopyFont );
SetTextColor( GetTextColor() );
if( IsLineColor() )
SetLineColor( GetLineColor() );
else
SetLineColor();
if( IsFillColor() )
SetFillColor( GetFillColor() );
else
SetFillColor();
if( IsTextLineColor() )
SetTextLineColor( GetTextLineColor() );
else
SetTextLineColor();
if( IsOverlineColor() )
SetOverlineColor( GetOverlineColor() );
else
SetOverlineColor();
if( IsTextFillColor() )
SetTextFillColor( GetTextFillColor() );
else
SetTextFillColor();
SetTextAlign( GetTextAlign() );
SetRasterOp( GetRasterOp() );
if( IsRefPoint() )
SetRefPoint( GetRefPoint() );
else
SetRefPoint();
SetLayoutMode( GetLayoutMode() );
SetDigitLanguage( GetDigitLanguage() );
Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() );
aClipRegion.Intersect( aPaintRect );
SetClipRegion( aClipRegion );
// do the actual paint
// background
if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & PARENTCLIPMODE_NOCLIP ) )
Erase();
// foreground
Paint( aPaintRect );
// put a pop action to metafile
Pop();
SetConnectMetaFile( pOldMtf );
EnableOutput( bOutput );
mpWindowImpl->mbReallyVisible = bRVisible;
// paint metafile to VDev
VirtualDevice* pMaskedDevice = new VirtualDevice( *i_pTargetOutDev, 0, 0 );
pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
pMaskedDevice->EnableRTL( IsRTLEnabled() );
aMtf.WindStart();
aMtf.Play( pMaskedDevice );
BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) );
i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
// get rid of virtual device now so they don't pile up during recursive calls
delete pMaskedDevice, pMaskedDevice = NULL;
for( Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
{
if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
{
long nDeltaX = pChild->mnOutOffX - mnOutOffX;
if( ImplHasMirroredGraphics() )
nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth;
long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
Point aPos( i_rPos );
Point aDelta( nDeltaX, nDeltaY );
aPos += aDelta;
pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
}
}
// restore graphics state
Pop();
EnableOutput( bOutput );
mpWindowImpl->mbReallyVisible = bRVisible;
mbDevOutput = bDevOutput;
mnDPIX = nOldDPIX;
mnDPIY = nOldDPIY;
}
void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ )
{
// FIXME: scaling: currently this is for pixel copying only
DBG_ASSERT( ! pDev->ImplHasMirroredGraphics(), "PaintToDevice to mirroring graphics" );
DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" );
Point aPos = pDev->LogicToPixel( rPos );
Window* pRealParent = NULL;
if( ! mpWindowImpl->mbVisible )
{
Window* pTempParent = ImplGetDefaultWindow();
if( pTempParent )
pTempParent->EnableChildTransparentMode();
pRealParent = GetParent();
SetParent( pTempParent );
// trigger correct visibility flags for children
Show();
Hide();
}
BOOL bVisible = mpWindowImpl->mbVisible;
mpWindowImpl->mbVisible = TRUE;
if( mpWindowImpl->mpBorderWindow )
mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
else
ImplPaintToDevice( pDev, rPos );
mpWindowImpl->mbVisible = bVisible;
if( pRealParent )
SetParent( pRealParent );
}
XubString Window::GetSurroundingText() const
{
return XubString::EmptyString();
}
Selection Window::GetSurroundingTextSelection() const
{
return Selection( 0, 0 );
}