bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / window / window.cxx
blobda28672f58931773a4c99ecb34d448b968e731db
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include <i18nlangtag/mslangid.hxx>
24 #include "tools/time.hxx"
25 #include "tools/debug.hxx"
26 #include "tools/rc.h"
28 #include "unotools/fontcfg.hxx"
29 #include "unotools/confignode.hxx"
31 #include "vcl/layout.hxx"
32 #include "vcl/salgtype.hxx"
33 #include "vcl/event.hxx"
34 #include "vcl/fixed.hxx"
35 #include "vcl/help.hxx"
36 #include "vcl/cursor.hxx"
37 #include "vcl/svapp.hxx"
38 #include "vcl/window.hxx"
39 #include "vcl/syswin.hxx"
40 #include "vcl/syschild.hxx"
41 #include "vcl/dockwin.hxx"
42 #include "vcl/menu.hxx"
43 #include "vcl/wrkwin.hxx"
44 #include "vcl/wall.hxx"
45 #include "vcl/gradient.hxx"
46 #include "vcl/salctype.hxx"
47 #include "vcl/button.hxx"
48 #include "vcl/taskpanelist.hxx"
49 #include "vcl/dialog.hxx"
50 #include "vcl/unowrap.hxx"
51 #include "vcl/gdimtf.hxx"
52 #include "vcl/pdfextoutdevdata.hxx"
53 #include "vcl/popupmenuwindow.hxx"
54 #include "vcl/lazydelete.hxx"
55 #include "vcl/virdev.hxx"
57 // declare system types in sysdata.hxx
58 #include "svsys.h"
59 #include "vcl/sysdata.hxx"
61 #include "salframe.hxx"
62 #include "salobj.hxx"
63 #include "salinst.hxx"
64 #include "salgdi.hxx"
65 #include "svdata.hxx"
66 #include "dbggui.hxx"
67 #include "outfont.hxx"
68 #include "window.h"
69 #include "toolbox.h"
70 #include "outdev.h"
71 #include "region.h"
72 #include "brdwin.hxx"
73 #include "helpwin.hxx"
74 #include "sallayout.hxx"
75 #include "dndlcon.hxx"
76 #include "dndevdis.hxx"
78 #include "com/sun/star/accessibility/XAccessible.hpp"
79 #include "com/sun/star/accessibility/AccessibleRole.hpp"
80 #include "com/sun/star/awt/XWindowPeer.hpp"
81 #include "com/sun/star/awt/XTopWindow.hpp"
82 #include "com/sun/star/awt/XWindow.hpp"
83 #include "com/sun/star/awt/XDisplayConnection.hpp"
84 #include "com/sun/star/datatransfer/dnd/XDragSource.hpp"
85 #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp"
86 #include "com/sun/star/datatransfer/clipboard/XClipboard.hpp"
87 #include "com/sun/star/lang/XInitialization.hpp"
88 #include "com/sun/star/lang/XComponent.hpp"
89 #include "com/sun/star/lang/XServiceName.hpp"
90 #include "com/sun/star/rendering/CanvasFactory.hpp"
91 #include "com/sun/star/rendering/XCanvas.hpp"
92 #include "com/sun/star/rendering/XSpriteCanvas.hpp"
93 #include "comphelper/processfactory.hxx"
95 #include <sal/macros.h>
96 #include <rtl/strbuf.hxx>
98 #include <set>
99 #include <typeinfo>
101 using namespace ::com::sun::star::uno;
102 using namespace ::com::sun::star::lang;
103 using namespace ::com::sun::star::datatransfer::clipboard;
104 using namespace ::com::sun::star::datatransfer::dnd;
105 using namespace ::com::sun::star;
106 using namespace com::sun;
109 using ::com::sun::star::awt::XTopWindow;
111 // =======================================================================
113 DBG_NAME( Window )
115 // =======================================================================
117 #define IMPL_PAINT_PAINT ((sal_uInt16)0x0001)
118 #define IMPL_PAINT_PAINTALL ((sal_uInt16)0x0002)
119 #define IMPL_PAINT_PAINTALLCHILDREN ((sal_uInt16)0x0004)
120 #define IMPL_PAINT_PAINTCHILDREN ((sal_uInt16)0x0008)
121 #define IMPL_PAINT_ERASE ((sal_uInt16)0x0010)
122 #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020)
124 // -----------------------------------------------------------------------
126 struct ImplCalcToTopData
128 ImplCalcToTopData* mpNext;
129 Window* mpWindow;
130 Region* mpInvalidateRegion;
133 ImplAccessibleInfos::ImplAccessibleInfos()
135 nAccessibleRole = 0xFFFF;
136 pAccessibleName = NULL;
137 pAccessibleDescription = NULL;
138 pLabeledByWindow = NULL;
139 pLabelForWindow = NULL;
140 pMemberOfWindow = NULL;
143 ImplAccessibleInfos::~ImplAccessibleInfos()
145 delete pAccessibleName;
146 delete pAccessibleDescription;
149 // -----------------------------------------------------------------------
151 WindowImpl::WindowImpl( WindowType nType )
153 maZoom = Fraction( 1, 1 );
154 maWinRegion = Region( REGION_NULL );
155 maWinClipRegion = Region( REGION_NULL );
156 mpWinData = NULL; // Extra Window Data, that we dont need for all windows
157 mpOverlapData = NULL; // Overlap Data
158 mpFrameData = NULL; // Frame Data
159 mpFrame = NULL; // Pointer to frame window
160 mpSysObj = NULL;
161 mpFrameWindow = NULL; // window to top level parent (same as frame window)
162 mpOverlapWindow = NULL; // first overlap parent
163 mpBorderWindow = NULL; // Border-Window
164 mpClientWindow = NULL; // Client-Window of a FrameWindow
165 mpParent = NULL; // parent (inkl. BorderWindow)
166 mpRealParent = NULL; // real parent (exkl. BorderWindow)
167 mpFirstChild = NULL; // first child window
168 mpLastChild = NULL; // last child window
169 mpFirstOverlap = NULL; // first overlap window (only set in overlap windows)
170 mpLastOverlap = NULL; // last overlap window (only set in overlap windows)
171 mpPrev = NULL; // prev window
172 mpNext = NULL; // next window
173 mpNextOverlap = NULL; // next overlap window of frame
174 mpLastFocusWindow = NULL; // window for focus restore
175 mpDlgCtrlDownWindow = NULL; // window for dialog control
176 mpFirstDel = NULL; // Dtor notification list
177 mpUserData = NULL; // user data
178 mpCursor = NULL; // cursor
179 mpControlFont = NULL; // font propertie
180 mpVCLXWindow = NULL;
181 mpAccessibleInfos = NULL;
182 maControlForeground = Color( COL_TRANSPARENT ); // no foreground set
183 maControlBackground = Color( COL_TRANSPARENT ); // no background set
184 mnLeftBorder = 0; // left border
185 mnTopBorder = 0; // top border
186 mnRightBorder = 0; // right border
187 mnBottomBorder = 0; // bottom border
188 mnWidthRequest = -1; // width request
189 mnHeightRequest = -1; // height request
190 mnX = 0; // X-Position to Parent
191 mnY = 0; // Y-Position to Parent
192 mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning
193 mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren
194 mpPaintRegion = NULL; // Paint-ClipRegion
195 mnStyle = 0; // style (init in ImplInitWindow)
196 mnPrevStyle = 0; // prevstyle (set in SetStyle)
197 mnExtendedStyle = 0; // extended style (init in ImplInitWindow)
198 mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle)
199 mnType = nType; // type
200 mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf
201 mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer)
202 mnPaintFlags = 0; // Flags for ImplCallPaint
203 mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode
204 mnActivateMode = 0; // Will be converted in System/Overlap-Windows
205 mnDlgCtrlFlags = 0; // DialogControl-Flags
206 mnLockCount = 0; // LockCount
207 meAlwaysInputMode = AlwaysInputNone; // neither AlwaysEnableInput nor AlwaysDisableInput called
208 meHalign = VCL_ALIGN_FILL;
209 meValign = VCL_ALIGN_FILL;
210 mePackType = VCL_PACK_START;
211 mnPadding = 0;
212 mnGridHeight = 1;
213 mnGridLeftAttach = -1;
214 mnGridTopAttach = -1;
215 mnGridWidth = 1;
216 mnBorderWidth = 0;
217 mnMarginLeft = 0;
218 mnMarginRight = 0;
219 mnMarginTop = 0;
220 mnMarginBottom = 0;
221 mbFrame = sal_False; // sal_True: Window is a frame window
222 mbBorderWin = sal_False; // sal_True: Window is a border window
223 mbOverlapWin = sal_False; // sal_True: Window is a overlap window
224 mbSysWin = sal_False; // sal_True: SystemWindow is the base class
225 mbDialog = sal_False; // sal_True: Dialog is the base class
226 mbDockWin = sal_False; // sal_True: DockingWindow is the base class
227 mbFloatWin = sal_False; // sal_True: FloatingWindow is the base class
228 mbPushButton = sal_False; // sal_True: PushButton is the base class
229 mbToolBox = sal_False; // sal_True: ToolBox is the base class
230 mbMenuFloatingWindow= sal_False; // sal_True: MenuFloatingWindow is the base class
231 mbToolbarFloatingWindow= sal_False; // sal_True: ImplPopupFloatWin is the base class, used for subtoolbars
232 mbSplitter = sal_False; // sal_True: Splitter is the base class
233 mbVisible = sal_False; // sal_True: Show( sal_True ) called
234 mbOverlapVisible = sal_False; // sal_True: Hide called for visible window from ImplHideAllOverlapWindow()
235 mbDisabled = sal_False; // sal_True: Enable( sal_False ) called
236 mbInputDisabled = sal_False; // sal_True: EnableInput( sal_False ) called
237 mbDropDisabled = sal_False; // sal_True: Drop is enabled
238 mbNoUpdate = sal_False; // sal_True: SetUpdateMode( sal_False ) called
239 mbNoParentUpdate = sal_False; // sal_True: SetParentUpdateMode( sal_False ) called
240 mbActive = sal_False; // sal_True: Window Active
241 mbParentActive = sal_False; // sal_True: OverlapActive from Parent
242 mbReallyVisible = sal_False; // sal_True: this and all parents to an overlaped window are visible
243 mbReallyShown = sal_False; // sal_True: this and all parents to an overlaped window are shown
244 mbInInitShow = sal_False; // sal_True: we are in InitShow
245 mbChildNotify = sal_False; // sal_True: ChildNotify
246 mbChildPtrOverwrite = sal_False; // sal_True: PointerStyle overwrites Child-Pointer
247 mbNoPtrVisible = sal_False; // sal_True: ShowPointer( sal_False ) called
248 mbMouseMove = sal_False; // sal_True: BaseMouseMove called
249 mbPaintFrame = sal_False; // sal_True: Paint is visible, but not painted
250 mbInPaint = sal_False; // sal_True: Inside PaintHdl
251 mbMouseButtonDown = sal_False; // sal_True: BaseMouseButtonDown called
252 mbMouseButtonUp = sal_False; // sal_True: BaseMouseButtonUp called
253 mbKeyInput = sal_False; // sal_True: BaseKeyInput called
254 mbKeyUp = sal_False; // sal_True: BaseKeyUp called
255 mbCommand = sal_False; // sal_True: BaseCommand called
256 mbDefPos = sal_True; // sal_True: Position is not Set
257 mbDefSize = sal_True; // sal_True: Size is not Set
258 mbCallMove = sal_True; // sal_True: Move must be called by Show
259 mbCallResize = sal_True; // sal_True: Resize must be called by Show
260 mbWaitSystemResize = sal_True; // sal_True: Wait for System-Resize
261 mbInitWinClipRegion = sal_True; // sal_True: Calc Window Clip Region
262 mbInitChildRegion = sal_False; // sal_True: InitChildClipRegion
263 mbWinRegion = sal_False; // sal_True: Window Region
264 mbClipChildren = sal_False; // sal_True: Child-window should be clipped
265 mbClipSiblings = sal_False; // sal_True: Adjacent Child-window should be clipped
266 mbChildTransparent = sal_False; // sal_True: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
267 mbPaintTransparent = sal_False; // sal_True: Paints should be executed on the Parent
268 mbMouseTransparent = sal_False; // sal_True: Window is transparent for Mouse
269 mbDlgCtrlStart = sal_False; // sal_True: From here on own Dialog-Control
270 mbFocusVisible = sal_False; // sal_True: Focus Visible
271 mbUseNativeFocus = sal_False;
272 mbNativeFocusVisible= sal_False; // sal_True: native Focus Visible
273 mbInShowFocus = sal_False; // prevent recursion
274 mbInHideFocus = sal_False; // prevent recursion
275 mbTrackVisible = sal_False; // sal_True: Tracking Visible
276 mbControlForeground = sal_False; // sal_True: Foreground-Property set
277 mbControlBackground = sal_False; // sal_True: Background-Property set
278 mbAlwaysOnTop = sal_False; // sal_True: always visible for all others windows
279 mbCompoundControl = sal_False; // sal_True: Composite Control => Listener...
280 mbCompoundControlHasFocus = sal_False; // sal_True: Composite Control has focus somewhere
281 mbPaintDisabled = sal_False; // sal_True: Paint should not be executed
282 mbAllResize = sal_False; // sal_True: Also sent ResizeEvents with 0,0
283 mbInDtor = sal_False; // sal_True: We're still in Window-Dtor
284 mbExtTextInput = sal_False; // sal_True: ExtTextInput-Mode is active
285 mbInFocusHdl = sal_False; // sal_True: Within GetFocus-Handler
286 mbCreatedWithToolkit = sal_False;
287 mbSuppressAccessibilityEvents = sal_False; // sal_True: do not send any accessibility events
288 mbDrawSelectionBackground = sal_False; // sal_True: draws transparent window background to indicate (toolbox) selection
289 mbIsInTaskPaneList = sal_False; // sal_True: window was added to the taskpanelist in the topmost system window
290 mnNativeBackground = 0; // initialize later, depends on type
291 mbCallHandlersDuringInputDisabled = sal_False; // sal_True: call event handlers even if input is disabled
292 mbHelpTextDynamic = sal_False; // sal_True: append help id in HELP_DEBUG case
293 mbFakeFocusSet = sal_False; // sal_True: pretend as if the window has focus.
294 mbHexpand = false;
295 mbVexpand = false;
296 mbExpand = false;
297 mbFill = true;
298 mbSecondary = false;
299 mbIsThemingEnabled = true;
302 WindowImpl::~WindowImpl()
304 delete mpChildClipRegion;
305 delete mpAccessibleInfos;
306 delete mpControlFont;
310 // -----------------------------------------------------------------------
312 // helper method to allow inline constructor even for pWindow!=NULL case
313 void ImplDelData::AttachToWindow( const Window* pWindow )
315 if( pWindow )
316 const_cast<Window*>(pWindow)->ImplAddDel( this );
319 // -----------------------------------------------------------------------
321 // define dtor for ImplDelData
322 ImplDelData::~ImplDelData()
324 // #112873# auto remove of ImplDelData
325 // due to this code actively calling ImplRemoveDel() is not mandatory anymore
326 if( !mbDel && mpWindow )
328 // the window still exists but we were not removed
329 const_cast<Window*>(mpWindow)->ImplRemoveDel( this );
330 mpWindow = NULL;
334 // -----------------------------------------------------------------------
336 #ifdef DBG_UTIL
337 const char* ImplDbgCheckWindow( const void* pObj )
339 DBG_TESTSOLARMUTEX();
341 const Window* pWindow = (Window*)pObj;
343 if ( (pWindow->GetType() < WINDOW_FIRST) || (pWindow->GetType() > WINDOW_LAST) )
344 return "Window data overwrite";
346 // check window-chain
347 Window* pChild = pWindow->mpWindowImpl->mpFirstChild;
348 while ( pChild )
350 if ( pChild->mpWindowImpl->mpParent != pWindow )
351 return "Child-Window-Parent wrong";
352 pChild = pChild->mpWindowImpl->mpNext;
355 return NULL;
357 #endif
359 // =======================================================================
361 void Window::ImplInitAppFontData( Window* pWindow )
363 ImplSVData* pSVData = ImplGetSVData();
364 long nTextHeight = pWindow->GetTextHeight();
365 long nTextWidth = pWindow->approximate_char_width() * 8;
366 long nSymHeight = nTextHeight*4;
367 // Make the basis wider if the font is too narrow
368 // such that the dialog looks symmetrical and does not become too narrow.
369 // Add some extra space when the dialog has the same width,
370 // as a little more space is better.
371 if ( nSymHeight > nTextWidth )
372 nTextWidth = nSymHeight;
373 else if ( nSymHeight+5 > nTextWidth )
374 nTextWidth = nSymHeight+5;
375 pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
376 pSVData->maGDIData.mnAppFontY = nTextHeight * 10;
378 // FIXME: this is currently only on aqua, check with other
379 // platforms
380 if( pSVData->maNWFData.mbNoFocusRects )
382 // try to find out whether there is a large correction
383 // of control sizes, if yes, make app font scalings larger
384 // so dialog positioning is not completely off
385 ImplControlValue aControlValue;
386 Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) );
387 Rectangle aBoundingRgn( aCtrlRegion );
388 Rectangle aContentRgn( aCtrlRegion );
389 if( pWindow->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
390 CTRL_STATE_ENABLED, aControlValue, OUString(),
391 aBoundingRgn, aContentRgn ) )
393 // comment: the magical +6 is for the extra border in bordered
394 // (which is the standard) edit fields
395 if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
396 pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10;
401 pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX;
402 if ( pSVData->maAppData.mnDialogScaleX )
403 pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100;
406 // -----------------------------------------------------------------------
408 bool Window::ImplCheckUIFont( const Font& rFont )
410 if( ImplGetSVData()->maGDIData.mbNativeFontConfig )
411 return true;
413 // create a text string using the localized text of important buttons
414 String aTestText;
415 static const StandardButtonType aTestButtons[] =
417 BUTTON_OK, BUTTON_CANCEL, BUTTON_CLOSE, BUTTON_ABORT,
418 BUTTON_YES, BUTTON_NO, BUTTON_MORE, BUTTON_IGNORE,
419 BUTTON_RETRY, BUTTON_HELP
422 const int nTestButtonCount = SAL_N_ELEMENTS(aTestButtons);
423 for( int n = 0; n < nTestButtonCount; ++n )
425 String aButtonStr = Button::GetStandardText( aTestButtons[n] );
426 // #i115432# ignore mnemonic+accelerator part of each string
427 // TODO: use a string filtering method when it becomes available
428 const int nLen = aButtonStr.Len();
429 bool bInside = false;
430 for( int i = 0; i < nLen; ++i ) {
431 const sal_Unicode c = aButtonStr.GetChar( i );
432 if( (c == '('))
433 bInside = true;
434 if( (c == ')'))
435 bInside = false;
436 if( (c == '~')
437 || (c == '(') || (c == ')')
438 || ((c >= 'A') && (c <= 'Z') && bInside) )
439 aButtonStr.SetChar( i, ' ' );
441 // append sanitized button text to test string
442 aTestText.Append( aButtonStr );
445 const int nFirstChar = HasGlyphs( rFont, aTestText );
446 const bool bUIFontOk = (nFirstChar >= aTestText.Len());
447 return bUIFontOk;
450 // -----------------------------------------------------------------------
452 void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, sal_Bool bCallHdl )
454 StyleSettings aTmpSt( rSettings.GetStyleSettings() );
455 aTmpSt.SetHighContrastMode( sal_False );
456 rSettings.SetStyleSettings( aTmpSt );
457 ImplGetFrame()->UpdateSettings( rSettings );
458 // reset default border width for layouters
459 ImplGetSVData()->maAppData.mnDefaultLayoutBorder = -1;
461 // Verify availability of the configured UI font, otherwise choose "Andale Sans UI"
463 // WTF, what makes Andale Sans UI a suitable cross-platform fallback font?
465 String aUserInterfaceFont;
466 bool bUseSystemFont = rSettings.GetStyleSettings().GetUseSystemUIFonts();
468 // check whether system UI font can display a typical UI text
469 if( bUseSystemFont )
470 bUseSystemFont = ImplCheckUIFont( rSettings.GetStyleSettings().GetAppFont() );
472 if ( !bUseSystemFont )
474 ImplInitFontList();
475 String aConfigFont = utl::DefaultFontConfiguration::get().getUserInterfaceFont( rSettings.GetUILanguageTag().getLocale() );
476 sal_Int32 nIndex = 0;
477 while( nIndex != -1 )
479 String aName( aConfigFont.GetToken( 0, ';', nIndex ) );
480 if ( aName.Len() && mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aName ) )
482 aUserInterfaceFont = aConfigFont;
483 break;
487 if ( ! aUserInterfaceFont.Len() )
489 String aFallbackFont ("Andale Sans UI" );
490 if ( mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aFallbackFont ) )
491 aUserInterfaceFont = aFallbackFont;
495 if ( !bUseSystemFont && aUserInterfaceFont.Len() )
497 StyleSettings aStyleSettings = rSettings.GetStyleSettings();
498 Font aFont = aStyleSettings.GetAppFont();
499 aFont.SetName( aUserInterfaceFont );
500 aStyleSettings.SetAppFont( aFont );
501 aFont = aStyleSettings.GetHelpFont();
502 aFont.SetName( aUserInterfaceFont );
503 aStyleSettings.SetHelpFont( aFont );
504 aFont = aStyleSettings.GetTitleFont();
505 aFont.SetName( aUserInterfaceFont );
506 aStyleSettings.SetTitleFont( aFont );
507 aFont = aStyleSettings.GetFloatTitleFont();
508 aFont.SetName( aUserInterfaceFont );
509 aStyleSettings.SetFloatTitleFont( aFont );
510 aFont = aStyleSettings.GetMenuFont();
511 aFont.SetName( aUserInterfaceFont );
512 aStyleSettings.SetMenuFont( aFont );
513 aFont = aStyleSettings.GetToolFont();
514 aFont.SetName( aUserInterfaceFont );
515 aStyleSettings.SetToolFont( aFont );
516 aFont = aStyleSettings.GetLabelFont();
517 aFont.SetName( aUserInterfaceFont );
518 aStyleSettings.SetLabelFont( aFont );
519 aFont = aStyleSettings.GetInfoFont();
520 aFont.SetName( aUserInterfaceFont );
521 aStyleSettings.SetInfoFont( aFont );
522 aFont = aStyleSettings.GetRadioCheckFont();
523 aFont.SetName( aUserInterfaceFont );
524 aStyleSettings.SetRadioCheckFont( aFont );
525 aFont = aStyleSettings.GetPushButtonFont();
526 aFont.SetName( aUserInterfaceFont );
527 aStyleSettings.SetPushButtonFont( aFont );
528 aFont = aStyleSettings.GetFieldFont();
529 aFont.SetName( aUserInterfaceFont );
530 aStyleSettings.SetFieldFont( aFont );
531 aFont = aStyleSettings.GetIconFont();
532 aFont.SetName( aUserInterfaceFont );
533 aStyleSettings.SetIconFont( aFont );
534 aFont = aStyleSettings.GetGroupFont();
535 aFont.SetName( aUserInterfaceFont );
536 aStyleSettings.SetGroupFont( aFont );
537 rSettings.SetStyleSettings( aStyleSettings );
540 StyleSettings aStyleSettings = rSettings.GetStyleSettings();
541 // #97047: Force all fonts except Menu and Help to a fixed height
542 // to avoid UI scaling due to large fonts
543 // - but allow bigger fonts on bigger screens (i16682, i21238)
544 // dialogs were designed to fit 800x600 with an 8pt font, so scale accordingly
545 int maxFontheight = 9; // #107886#: 9 is default for some asian systems, so always allow if requested
546 if( GetDesktopRectPixel().getHeight() > 600 )
547 maxFontheight = (int) ((( 8.0 * (double) GetDesktopRectPixel().getHeight()) / 600.0) + 1.5);
549 Font aFont = aStyleSettings.GetMenuFont();
550 int defFontheight = aFont.GetHeight();
551 if( defFontheight > maxFontheight )
552 defFontheight = maxFontheight;
554 // if the UI is korean, chinese or another locale
555 // where the system font size is kown to be often too small to
556 // generate readable fonts enforce a minimum font size of 9 points
557 bool bBrokenLangFontHeight = MsLangId::isCJK(Application::GetSettings().GetUILanguageTag().getLanguageType());
558 if (bBrokenLangFontHeight)
559 defFontheight = std::max(9, defFontheight);
561 // i22098, toolfont will be scaled differently to avoid bloated rulers and status bars for big fonts
562 int toolfontheight = defFontheight;
563 if( toolfontheight > 9 )
564 toolfontheight = (defFontheight+8) / 2;
566 aFont = aStyleSettings.GetAppFont();
567 aFont.SetHeight( defFontheight );
568 aStyleSettings.SetAppFont( aFont );
569 aFont = aStyleSettings.GetTitleFont();
570 aFont.SetHeight( defFontheight );
571 aStyleSettings.SetTitleFont( aFont );
572 aFont = aStyleSettings.GetFloatTitleFont();
573 aFont.SetHeight( defFontheight );
574 aStyleSettings.SetFloatTitleFont( aFont );
575 // keep menu and help font size from system unless in broken locale size
576 if( bBrokenLangFontHeight )
578 aFont = aStyleSettings.GetMenuFont();
579 if( aFont.GetHeight() < defFontheight )
581 aFont.SetHeight( defFontheight );
582 aStyleSettings.SetMenuFont( aFont );
584 aFont = aStyleSettings.GetHelpFont();
585 if( aFont.GetHeight() < defFontheight )
587 aFont.SetHeight( defFontheight );
588 aStyleSettings.SetHelpFont( aFont );
592 // use different height for toolfont
593 aFont = aStyleSettings.GetToolFont();
594 aFont.SetHeight( toolfontheight );
595 aStyleSettings.SetToolFont( aFont );
597 aFont = aStyleSettings.GetLabelFont();
598 aFont.SetHeight( defFontheight );
599 aStyleSettings.SetLabelFont( aFont );
600 aFont = aStyleSettings.GetInfoFont();
601 aFont.SetHeight( defFontheight );
602 aStyleSettings.SetInfoFont( aFont );
603 aFont = aStyleSettings.GetRadioCheckFont();
604 aFont.SetHeight( defFontheight );
605 aStyleSettings.SetRadioCheckFont( aFont );
606 aFont = aStyleSettings.GetPushButtonFont();
607 aFont.SetHeight( defFontheight );
608 aStyleSettings.SetPushButtonFont( aFont );
609 aFont = aStyleSettings.GetFieldFont();
610 aFont.SetHeight( defFontheight );
611 aStyleSettings.SetFieldFont( aFont );
612 aFont = aStyleSettings.GetIconFont();
613 aFont.SetHeight( defFontheight );
614 aStyleSettings.SetIconFont( aFont );
615 aFont = aStyleSettings.GetGroupFont();
616 aFont.SetHeight( defFontheight );
617 aStyleSettings.SetGroupFont( aFont );
619 // set workspace gradient to black in dark themes
620 if( aStyleSettings.GetWindowColor().IsDark() )
621 aStyleSettings.SetWorkspaceGradient( Wallpaper( Color( COL_BLACK ) ) );
622 else
624 Gradient aGrad( GradientStyle_LINEAR, DEFAULT_WORKSPACE_GRADIENT_START_COLOR, DEFAULT_WORKSPACE_GRADIENT_END_COLOR );
625 aStyleSettings.SetWorkspaceGradient( Wallpaper( aGrad ) );
628 rSettings.SetStyleSettings( aStyleSettings );
630 // auto detect HC mode; if the system already set it to "yes"
631 // (see above) then accept that
632 if( !rSettings.GetStyleSettings().GetHighContrastMode() )
634 sal_Bool bTmp = sal_False, bAutoHCMode = sal_True;
635 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithComponentContext(
636 comphelper::getProcessComponentContext(),
637 OUString("org.openoffice.Office.Common/Accessibility") ); // note: case sensitive !
638 if ( aNode.isValid() )
640 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString("AutoDetectSystemHC") );
641 if( aValue >>= bTmp )
642 bAutoHCMode = bTmp;
644 if( bAutoHCMode )
646 if( rSettings.GetStyleSettings().GetFaceColor().IsDark()
647 || rSettings.GetStyleSettings().GetWindowColor().IsDark() )
649 aStyleSettings = rSettings.GetStyleSettings();
650 aStyleSettings.SetHighContrastMode( sal_True );
651 aStyleSettings.SetSymbolsStyle( STYLE_SYMBOLS_HICONTRAST );
652 rSettings.SetStyleSettings( aStyleSettings );
657 static const char* pEnvHC = getenv( "SAL_FORCE_HC" );
658 if( pEnvHC && *pEnvHC )
660 aStyleSettings.SetHighContrastMode( sal_True );
661 aStyleSettings.SetSymbolsStyle( STYLE_SYMBOLS_HICONTRAST );
662 rSettings.SetStyleSettings( aStyleSettings );
665 #if defined(DBG_UTIL)
666 // If needed, set AppFont to bold, in order to check
667 // if there is enough space available for texts on other systems
668 if ( DbgIsBoldAppFont() )
670 aStyleSettings = rSettings.GetStyleSettings();
671 aFont = aStyleSettings.GetAppFont();
672 aFont.SetWeight( WEIGHT_BOLD );
673 aStyleSettings.SetAppFont( aFont );
674 aFont = aStyleSettings.GetGroupFont();
675 aFont.SetWeight( WEIGHT_BOLD );
676 aStyleSettings.SetGroupFont( aFont );
677 aFont = aStyleSettings.GetLabelFont();
678 aFont.SetWeight( WEIGHT_BOLD );
679 aStyleSettings.SetLabelFont( aFont );
680 aFont = aStyleSettings.GetRadioCheckFont();
681 aFont.SetWeight( WEIGHT_BOLD );
682 aStyleSettings.SetRadioCheckFont( aFont );
683 aFont = aStyleSettings.GetPushButtonFont();
684 aFont.SetWeight( WEIGHT_BOLD );
685 aStyleSettings.SetPushButtonFont( aFont );
686 aFont = aStyleSettings.GetFieldFont();
687 aFont.SetWeight( WEIGHT_BOLD );
688 aStyleSettings.SetFieldFont( aFont );
689 aFont = aStyleSettings.GetIconFont();
690 aFont.SetWeight( WEIGHT_BOLD );
691 aStyleSettings.SetIconFont( aFont );
692 rSettings.SetStyleSettings( aStyleSettings );
694 #endif
696 if ( bCallHdl )
697 GetpApp()->SystemSettingsChanging( rSettings, this );
700 // -----------------------------------------------------------------------
702 MouseEvent ImplTranslateMouseEvent( const MouseEvent& rE, Window* pSource, Window* pDest )
704 Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() );
705 aPos = pDest->ScreenToOutputPixel( aPos );
706 return MouseEvent( aPos, rE.GetClicks(), rE.GetMode(), rE.GetButtons(), rE.GetModifier() );
709 // -----------------------------------------------------------------------
711 CommandEvent ImplTranslateCommandEvent( const CommandEvent& rCEvt, Window* pSource, Window* pDest )
713 if ( !rCEvt.IsMouseEvent() )
714 return rCEvt;
716 Point aPos = pSource->OutputToScreenPixel( rCEvt.GetMousePosPixel() );
717 aPos = pDest->ScreenToOutputPixel( aPos );
718 return CommandEvent( aPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
721 // =======================================================================
723 void Window::ImplInitWindowData( WindowType nType )
725 mpWindowImpl = new WindowImpl( nType );
727 meOutDevType = OUTDEV_WINDOW;
730 mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // sal_True: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
733 // -----------------------------------------------------------------------
735 void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
737 DBG_ASSERT( mpWindowImpl->mbFrame || pParent, "Window::Window(): pParent == NULL" );
739 ImplSVData* pSVData = ImplGetSVData();
740 Window* pRealParent = pParent;
742 // 3D-Look vererben
743 if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
744 nStyle |= WB_3DLOOK;
746 // create border window if necessary
747 if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
748 && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
750 sal_uInt16 nBorderTypeStyle = 0;
751 if( (nStyle & WB_SYSTEMCHILDWINDOW) )
753 // handle WB_SYSTEMCHILDWINDOW
754 // these should be analogous to a top level frame; meaning they
755 // should have a border window with style BORDERWINDOW_STYLE_FRAME
756 // which controls their size
757 nBorderTypeStyle |= BORDERWINDOW_STYLE_FRAME;
758 nStyle |= WB_BORDER;
760 ImplBorderWindow* pBorderWin =
761 mpWindowImpl->mbIsThemingEnabled
762 ? CreateBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle )
763 : new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle );
764 ((Window*)pBorderWin)->mpWindowImpl->mpClientWindow = this;
765 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
766 mpWindowImpl->mpBorderWindow = pBorderWin;
767 pParent = mpWindowImpl->mpBorderWindow;
769 else if( !mpWindowImpl->mbFrame && ! pParent )
771 mpWindowImpl->mbOverlapWin = sal_True;
772 mpWindowImpl->mbFrame = sal_True;
775 // insert window in list
776 ImplInsertWindow( pParent );
777 mpWindowImpl->mnStyle = nStyle;
779 // Overlap-Window-Data
780 if ( mpWindowImpl->mbOverlapWin )
782 mpWindowImpl->mpOverlapData = new ImplOverlapData;
783 mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL;
784 mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL;
785 mpWindowImpl->mpOverlapData->mpNextBackWin = NULL;
786 mpWindowImpl->mpOverlapData->mnSaveBackSize = 0;
787 mpWindowImpl->mpOverlapData->mbSaveBack = sal_False;
788 mpWindowImpl->mpOverlapData->mnTopLevel = 1;
791 if( pParent && ! mpWindowImpl->mbFrame )
792 mbEnableRTL = Application::GetSettings().GetLayoutRTL();
794 // test for frame creation
795 if ( mpWindowImpl->mbFrame )
797 // create frame
798 sal_uLong nFrameStyle = 0;
800 if ( nStyle & WB_MOVEABLE )
801 nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE;
802 if ( nStyle & WB_SIZEABLE )
803 nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE;
804 if ( nStyle & WB_CLOSEABLE )
805 nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE;
806 if ( nStyle & WB_APP )
807 nFrameStyle |= SAL_FRAME_STYLE_DEFAULT;
808 // check for undecorated floating window
809 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
810 ( !(nFrameStyle & ~SAL_FRAME_STYLE_CLOSEABLE) &&
811 ( mpWindowImpl->mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
812 // 2. borderwindows of floaters with ownerdraw decoration
813 ( ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) ) )
815 nFrameStyle = SAL_FRAME_STYLE_FLOAT;
816 if( nStyle & WB_OWNERDRAWDECORATION )
817 nFrameStyle |= (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_NOSHADOW);
818 if( nStyle & WB_NEEDSFOCUS )
819 nFrameStyle |= SAL_FRAME_STYLE_FLOAT_FOCUSABLE;
821 else if( mpWindowImpl->mbFloatWin )
822 nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW;
824 if( nStyle & WB_INTROWIN )
825 nFrameStyle |= SAL_FRAME_STYLE_INTRO;
826 if( nStyle & WB_TOOLTIPWIN )
827 nFrameStyle |= SAL_FRAME_STYLE_TOOLTIP;
829 if( nStyle & WB_NOSHADOW )
830 nFrameStyle |= SAL_FRAME_STYLE_NOSHADOW;
832 if( nStyle & WB_SYSTEMCHILDWINDOW )
833 nFrameStyle |= SAL_FRAME_STYLE_SYSTEMCHILD;
835 switch (mpWindowImpl->mnType)
837 case WINDOW_DIALOG:
838 case WINDOW_TABDIALOG:
839 case WINDOW_MODALDIALOG:
840 case WINDOW_MODELESSDIALOG:
841 case WINDOW_MESSBOX:
842 case WINDOW_INFOBOX:
843 case WINDOW_WARNINGBOX:
844 case WINDOW_ERRORBOX:
845 case WINDOW_QUERYBOX:
846 nFrameStyle |= SAL_FRAME_STYLE_DIALOG;
847 default:
848 break;
851 SalFrame* pParentFrame = NULL;
852 if ( pParent )
853 pParentFrame = pParent->mpWindowImpl->mpFrame;
854 SalFrame* pFrame;
855 if ( pSystemParentData )
856 pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_PLUG );
857 else
858 pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
859 if ( !pFrame )
861 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
862 throw ::com::sun::star::uno::RuntimeException(
863 OUString( "Could not create system window!" ),
864 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
865 //GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
868 pFrame->SetCallback( this, ImplWindowFrameProc );
870 // set window frame data
871 mpWindowImpl->mpFrameData = new ImplFrameData;
872 mpWindowImpl->mpFrame = pFrame;
873 mpWindowImpl->mpFrameWindow = this;
874 mpWindowImpl->mpOverlapWindow = this;
876 // set frame data
877 mpWindowImpl->mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame;
878 pSVData->maWinData.mpFirstFrame = this;
879 mpWindowImpl->mpFrameData->mpFirstOverlap = NULL;
880 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
881 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
882 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
883 mpWindowImpl->mpFrameData->mpFirstBackWin = NULL;
884 mpWindowImpl->mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList;
885 mpWindowImpl->mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache;
886 mpWindowImpl->mpFrameData->mnAllSaveBackSize = 0;
887 mpWindowImpl->mpFrameData->mnFocusId = 0;
888 mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
889 mpWindowImpl->mpFrameData->mnLastMouseX = -1;
890 mpWindowImpl->mpFrameData->mnLastMouseY = -1;
891 mpWindowImpl->mpFrameData->mnBeforeLastMouseX = -1;
892 mpWindowImpl->mpFrameData->mnBeforeLastMouseY = -1;
893 mpWindowImpl->mpFrameData->mnFirstMouseX = -1;
894 mpWindowImpl->mpFrameData->mnFirstMouseY = -1;
895 mpWindowImpl->mpFrameData->mnLastMouseWinX = -1;
896 mpWindowImpl->mpFrameData->mnLastMouseWinY = -1;
897 mpWindowImpl->mpFrameData->mnModalMode = 0;
898 mpWindowImpl->mpFrameData->mnMouseDownTime = 0;
899 mpWindowImpl->mpFrameData->mnClickCount = 0;
900 mpWindowImpl->mpFrameData->mnFirstMouseCode = 0;
901 mpWindowImpl->mpFrameData->mnMouseCode = 0;
902 mpWindowImpl->mpFrameData->mnMouseMode = 0;
903 mpWindowImpl->mpFrameData->meMapUnit = MAP_PIXEL;
904 mpWindowImpl->mpFrameData->mbHasFocus = sal_False;
905 mpWindowImpl->mpFrameData->mbInMouseMove = sal_False;
906 mpWindowImpl->mpFrameData->mbMouseIn = sal_False;
907 mpWindowImpl->mpFrameData->mbStartDragCalled = sal_False;
908 mpWindowImpl->mpFrameData->mbNeedSysWindow = sal_False;
909 mpWindowImpl->mpFrameData->mbMinimized = sal_False;
910 mpWindowImpl->mpFrameData->mbStartFocusState = sal_False;
911 mpWindowImpl->mpFrameData->mbInSysObjFocusHdl = sal_False;
912 mpWindowImpl->mpFrameData->mbInSysObjToTopHdl = sal_False;
913 mpWindowImpl->mpFrameData->mbSysObjFocus = sal_False;
914 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeout( 30 );
915 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
916 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeout( 50 );
917 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeoutHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
918 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = sal_False;
920 if ( pRealParent && IsTopWindow() )
922 ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
923 pParentWinData->maTopWindowChildren.push_back( this );
927 // init data
928 mpWindowImpl->mpRealParent = pRealParent;
930 // #99318: make sure fontcache and list is available before call to SetSettings
931 mpFontList = mpWindowImpl->mpFrameData->mpFontList;
932 mpFontCache = mpWindowImpl->mpFrameData->mpFontCache;
934 if ( mpWindowImpl->mbFrame )
936 if ( pParent )
938 mpWindowImpl->mpFrameData->mnDPIX = pParent->mpWindowImpl->mpFrameData->mnDPIX;
939 mpWindowImpl->mpFrameData->mnDPIY = pParent->mpWindowImpl->mpFrameData->mnDPIY;
941 else
943 if ( ImplGetGraphics() )
945 mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY );
949 // add ownerdraw decorated frame windows to list in the top-most frame window
950 // so they can be hidden on lose focus
951 if( nStyle & WB_OWNERDRAWDECORATION )
952 ImplGetOwnerDrawList().push_back( this );
954 // delay settings initialization until first "real" frame
955 // this relies on the IntroWindow not needing any system settings
956 if ( !pSVData->maAppData.mbSettingsInit &&
957 ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
960 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
961 ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
962 OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
963 pSVData->maAppData.mbSettingsInit = sal_True;
966 // If we create a Window with default size, query this
967 // size directly, because we want resize all Controls to
968 // the correct size before we display the window
969 if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
970 mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
972 else
974 if ( pParent )
976 if ( !ImplIsOverlapWindow() )
978 mpWindowImpl->mbDisabled = pParent->mpWindowImpl->mbDisabled;
979 mpWindowImpl->mbInputDisabled = pParent->mpWindowImpl->mbInputDisabled;
980 mpWindowImpl->meAlwaysInputMode = pParent->mpWindowImpl->meAlwaysInputMode;
983 OutputDevice::SetSettings( pParent->GetSettings() );
988 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
989 sal_uInt16 nScreenZoom = rStyleSettings.GetScreenZoom();
990 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
991 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
992 maFont = rStyleSettings.GetAppFont();
993 ImplPointToLogic( maFont );
995 if ( nStyle & WB_3DLOOK )
997 SetTextColor( rStyleSettings.GetButtonTextColor() );
998 SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
1000 else
1002 SetTextColor( rStyleSettings.GetWindowTextColor() );
1003 SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
1006 ImplUpdatePos();
1008 // calculate app font res (except for the Intro Window or the default window)
1009 if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
1010 ImplInitAppFontData( this );
1012 if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() )
1013 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDCREATED, this );
1016 // -----------------------------------------------------------------------
1018 void Window::ImplSetFrameParent( const Window* pParent )
1020 Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
1021 while( pFrameWindow )
1023 // search all frames that are children of this window
1024 // and reparent them
1025 if( ImplIsRealParentPath( pFrameWindow ) )
1027 DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" );
1028 DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" );
1029 SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL;
1030 pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
1032 pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
1036 // -----------------------------------------------------------------------
1038 void Window::ImplInsertWindow( Window* pParent )
1040 mpWindowImpl->mpParent = pParent;
1041 mpWindowImpl->mpRealParent = pParent;
1043 if ( pParent && !mpWindowImpl->mbFrame )
1045 // search frame window and set window frame data
1046 Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
1047 mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
1048 mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
1049 mpWindowImpl->mpFrameWindow = pFrameParent;
1050 mpWindowImpl->mbFrame = sal_False;
1052 // search overlap window and insert window in list
1053 if ( ImplIsOverlapWindow() )
1055 Window* pFirstOverlapParent = pParent;
1056 while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
1057 pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
1058 mpWindowImpl->mpOverlapWindow = pFirstOverlapParent;
1060 mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap;
1061 mpWindowImpl->mpFrameData->mpFirstOverlap = this;
1063 // Overlap-Windows are by default the uppermost
1064 mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap;
1065 pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this;
1066 if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap )
1067 pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this;
1068 else
1069 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
1071 else
1073 if ( pParent->ImplIsOverlapWindow() )
1074 mpWindowImpl->mpOverlapWindow = pParent;
1075 else
1076 mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
1077 mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
1078 pParent->mpWindowImpl->mpLastChild = this;
1079 if ( !pParent->mpWindowImpl->mpFirstChild )
1080 pParent->mpWindowImpl->mpFirstChild = this;
1081 else
1082 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
1087 // -----------------------------------------------------------------------
1089 void Window::ImplRemoveWindow( sal_Bool bRemoveFrameData )
1091 // remove window from the lists
1092 if ( !mpWindowImpl->mbFrame )
1094 if ( ImplIsOverlapWindow() )
1096 if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this )
1097 mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap;
1098 else
1100 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
1101 while ( pTempWin->mpWindowImpl->mpNextOverlap != this )
1102 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
1103 pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap;
1106 if ( mpWindowImpl->mpPrev )
1107 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
1108 else
1109 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
1110 if ( mpWindowImpl->mpNext )
1111 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
1112 else
1113 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
1115 else
1117 if ( mpWindowImpl->mpPrev )
1118 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
1119 else if ( mpWindowImpl->mpParent )
1120 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
1121 if ( mpWindowImpl->mpNext )
1122 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
1123 else if ( mpWindowImpl->mpParent )
1124 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
1127 mpWindowImpl->mpPrev = NULL;
1128 mpWindowImpl->mpNext = NULL;
1131 if ( bRemoveFrameData )
1133 // release the graphic
1134 ImplReleaseGraphics();
1138 void Window::reorderWithinParent(sal_uInt16 nNewPosition)
1140 sal_uInt16 nChildCount = 0;
1141 Window *pSource = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
1142 while (pSource)
1144 if (nChildCount == nNewPosition)
1145 break;
1146 pSource = pSource->mpWindowImpl->mpNext;
1147 nChildCount++;
1150 if (pSource == this) //already at the right place
1151 return;
1153 ImplRemoveWindow(false);
1155 if (pSource)
1157 mpWindowImpl->mpNext = pSource;
1158 mpWindowImpl->mpPrev = pSource->mpWindowImpl->mpPrev;
1159 pSource->mpWindowImpl->mpPrev = this;
1161 else
1162 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
1164 if (mpWindowImpl->mpPrev)
1165 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
1166 else
1167 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
1170 // -----------------------------------------------------------------------
1172 void Window::ImplCallResize()
1174 mpWindowImpl->mbCallResize = sal_False;
1176 if( GetBackground().IsGradient() )
1177 Invalidate();
1179 Resize();
1181 // #88419# Most classes don't call the base class in Resize() and Move(),
1182 // => Call ImpleResize/Move instead of Resize/Move directly...
1183 ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE );
1186 // -----------------------------------------------------------------------
1188 void Window::ImplCallMove()
1190 mpWindowImpl->mbCallMove = sal_False;
1192 if( mpWindowImpl->mbFrame )
1194 // update frame position
1195 SalFrame *pParentFrame = NULL;
1196 Window *pParent = ImplGetParent();
1197 while( pParent )
1199 if( pParent->mpWindowImpl->mpFrame != mpWindowImpl->mpFrame )
1201 pParentFrame = pParent->mpWindowImpl->mpFrame;
1202 break;
1204 pParent = pParent->GetParent();
1207 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
1208 mpWindowImpl->maPos = Point( g.nX, g.nY );
1209 if( pParentFrame )
1211 g = pParentFrame->GetGeometry();
1212 mpWindowImpl->maPos -= Point( g.nX, g.nY );
1214 // the client window and and all its subclients have the same position as the borderframe
1215 // this is important for floating toolbars where the borderwindow is a floating window
1216 // which has another borderwindow (ie the system floating window)
1217 Window *pClientWin = mpWindowImpl->mpClientWindow;
1218 while( pClientWin )
1220 pClientWin->mpWindowImpl->maPos = mpWindowImpl->maPos;
1221 pClientWin = pClientWin->mpWindowImpl->mpClientWindow;
1225 Move();
1227 ImplCallEventListeners( VCLEVENT_WINDOW_MOVE );
1230 // -----------------------------------------------------------------------
1232 static OString ImplAutoHelpID( ResMgr* pResMgr )
1234 OString aRet;
1236 if( pResMgr && Application::IsAutoHelpIdEnabled() )
1237 aRet = pResMgr->GetAutoHelpId();
1239 return aRet;
1242 // -----------------------------------------------------------------------
1244 WinBits Window::ImplInitRes( const ResId& rResId )
1246 GetRes( rResId );
1248 char* pRes = (char*)GetClassRes();
1249 pRes += 8;
1250 sal_uInt32 nStyle = (sal_uInt32)GetLongRes( (void*)pRes );
1251 rResId.SetWinBits( nStyle );
1252 return nStyle;
1255 // -----------------------------------------------------------------------
1257 WindowResHeader Window::ImplLoadResHeader( const ResId& rResId )
1259 WindowResHeader aHeader;
1261 aHeader.nObjMask = ReadLongRes();
1263 // we need to calculate auto helpids before the resource gets closed
1264 // if the resource only contains flags, it will be closed before we try to read a help id
1265 // so we always create an auto help id that might be overwritten later
1266 // HelpId
1267 aHeader.aHelpId = ImplAutoHelpID( rResId.GetResMgr() );
1269 // ResourceStyle
1270 aHeader.nRSStyle = ReadLongRes();
1271 // WinBits
1272 ReadLongRes();
1274 if( aHeader.nObjMask & WINDOW_HELPID )
1275 aHeader.aHelpId = ReadByteStringRes();
1277 return aHeader;
1280 void Window::ImplLoadRes( const ResId& rResId )
1282 WindowResHeader aHeader = ImplLoadResHeader( rResId );
1284 SetHelpId( aHeader.aHelpId );
1286 sal_uLong nObjMask = aHeader.nObjMask;
1288 sal_Bool bPos = sal_False;
1289 sal_Bool bSize = sal_False;
1290 Point aPos;
1291 Size aSize;
1293 if ( nObjMask & (WINDOW_XYMAPMODE | WINDOW_X | WINDOW_Y) )
1295 // use size as per resource
1296 MapUnit ePosMap = MAP_PIXEL;
1298 bPos = sal_True;
1300 if ( nObjMask & WINDOW_XYMAPMODE )
1301 ePosMap = (MapUnit)ReadLongRes();
1302 if ( nObjMask & WINDOW_X )
1303 aPos.X() = ImplLogicUnitToPixelX( ReadLongRes(), ePosMap );
1304 if ( nObjMask & WINDOW_Y )
1305 aPos.Y() = ImplLogicUnitToPixelY( ReadLongRes(), ePosMap );
1308 if ( nObjMask & (WINDOW_WHMAPMODE | WINDOW_WIDTH | WINDOW_HEIGHT) )
1310 // use size as per resource
1311 MapUnit eSizeMap = MAP_PIXEL;
1313 bSize = sal_True;
1315 if ( nObjMask & WINDOW_WHMAPMODE )
1316 eSizeMap = (MapUnit)ReadLongRes();
1317 if ( nObjMask & WINDOW_WIDTH )
1318 aSize.Width() = ImplLogicUnitToPixelX( ReadLongRes(), eSizeMap );
1319 if ( nObjMask & WINDOW_HEIGHT )
1320 aSize.Height() = ImplLogicUnitToPixelY( ReadLongRes(), eSizeMap );
1323 sal_uLong nRSStyle = aHeader.nRSStyle;
1325 // looks bad due to optimisation
1326 if ( nRSStyle & RSWND_CLIENTSIZE )
1328 if ( bPos )
1329 SetPosPixel( aPos );
1330 if ( bSize )
1331 SetOutputSizePixel( aSize );
1333 else if ( bPos && bSize )
1334 SetPosSizePixel( aPos, aSize );
1335 else if ( bPos )
1336 SetPosPixel( aPos );
1337 else if ( bSize )
1338 SetSizePixel( aSize );
1340 if ( nRSStyle & RSWND_DISABLED )
1341 Enable( sal_False );
1343 if ( nObjMask & WINDOW_TEXT )
1344 SetText( ReadStringRes() );
1345 if ( nObjMask & WINDOW_HELPTEXT )
1347 SetHelpText( ReadStringRes() );
1348 mpWindowImpl->mbHelpTextDynamic = sal_True;
1350 if ( nObjMask & WINDOW_QUICKTEXT )
1351 SetQuickHelpText( ReadStringRes() );
1352 if ( nObjMask & WINDOW_EXTRALONG )
1354 sal_uIntPtr nRes = ReadLongRes();
1355 SetData( (void*)nRes );
1357 if ( nObjMask & WINDOW_UNIQUEID )
1358 SetUniqueId( ReadByteStringRes() );
1360 if ( nObjMask & WINDOW_BORDER_STYLE )
1362 sal_uInt16 nBorderStyle = (sal_uInt16)ReadLongRes();
1363 SetBorderStyle( nBorderStyle );
1367 // -----------------------------------------------------------------------
1369 ImplWinData* Window::ImplGetWinData() const
1371 if ( !mpWindowImpl->mpWinData )
1373 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
1375 ((Window*)this)->mpWindowImpl->mpWinData = new ImplWinData;
1376 mpWindowImpl->mpWinData->mpExtOldText = NULL;
1377 mpWindowImpl->mpWinData->mpExtOldAttrAry = NULL;
1378 mpWindowImpl->mpWinData->mpCursorRect = NULL;
1379 mpWindowImpl->mpWinData->mnCursorExtWidth = 0;
1380 mpWindowImpl->mpWinData->mpCompositionCharRects = NULL;
1381 mpWindowImpl->mpWinData->mnCompositionCharRects = 0;
1382 mpWindowImpl->mpWinData->mpFocusRect = NULL;
1383 mpWindowImpl->mpWinData->mpTrackRect = NULL;
1384 mpWindowImpl->mpWinData->mnTrackFlags = 0;
1385 mpWindowImpl->mpWinData->mnIsTopWindow = (sal_uInt16) ~0; // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
1386 mpWindowImpl->mpWinData->mbMouseOver = sal_False;
1387 mpWindowImpl->mpWinData->mbEnableNativeWidget = (pNoNWF && *pNoNWF) ? sal_False : sal_True; // sal_True: try to draw this control with native theme API
1390 return mpWindowImpl->mpWinData;
1393 // -----------------------------------------------------------------------
1395 SalGraphics* Window::ImplGetFrameGraphics() const
1397 if ( mpWindowImpl->mpFrameWindow->mpGraphics )
1398 mpWindowImpl->mpFrameWindow->mbInitClipRegion = sal_True;
1399 else
1400 mpWindowImpl->mpFrameWindow->ImplGetGraphics();
1401 mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion();
1402 return mpWindowImpl->mpFrameWindow->mpGraphics;
1405 // -----------------------------------------------------------------------
1407 Window* Window::ImplFindWindow( const Point& rFramePos )
1409 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1411 Window* pTempWindow;
1412 Window* pFindWindow;
1414 // first check all overlapping windows
1415 pTempWindow = mpWindowImpl->mpFirstOverlap;
1416 while ( pTempWindow )
1418 pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
1419 if ( pFindWindow )
1420 return pFindWindow;
1421 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
1424 // then we check our window
1425 if ( !mpWindowImpl->mbVisible )
1426 return NULL;
1428 sal_uInt16 nHitTest = ImplHitTest( rFramePos );
1429 if ( nHitTest & WINDOW_HITTEST_INSIDE )
1431 // and then we check all child windows
1432 pTempWindow = mpWindowImpl->mpFirstChild;
1433 while ( pTempWindow )
1435 pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
1436 if ( pFindWindow )
1437 return pFindWindow;
1438 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
1441 if ( nHitTest & WINDOW_HITTEST_TRANSPARENT )
1442 return NULL;
1443 else
1444 return this;
1447 return NULL;
1450 // -----------------------------------------------------------------------
1452 sal_uInt16 Window::ImplHitTest( const Point& rFramePos )
1454 Point aFramePos( rFramePos );
1455 if( ImplIsAntiparallel() )
1457 // - RTL - re-mirror frame pos at this window
1458 ImplReMirror( aFramePos );
1460 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
1461 if ( !aRect.IsInside( aFramePos ) )
1462 return 0;
1463 if ( mpWindowImpl->mbWinRegion )
1465 Point aTempPos = aFramePos;
1466 aTempPos.X() -= mnOutOffX;
1467 aTempPos.Y() -= mnOutOffY;
1468 if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
1469 return 0;
1472 sal_uInt16 nHitTest = WINDOW_HITTEST_INSIDE;
1473 if ( mpWindowImpl->mbMouseTransparent )
1474 nHitTest |= WINDOW_HITTEST_TRANSPARENT;
1475 return nHitTest;
1478 // -----------------------------------------------------------------------
1480 sal_Bool Window::ImplIsRealParentPath( const Window* pWindow ) const
1482 pWindow = pWindow->GetParent();
1483 while ( pWindow )
1485 if ( pWindow == this )
1486 return sal_True;
1487 pWindow = pWindow->GetParent();
1490 return sal_False;
1493 // -----------------------------------------------------------------------
1495 sal_Bool Window::ImplIsChild( const Window* pWindow, sal_Bool bSystemWindow ) const
1499 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
1500 break;
1502 pWindow = pWindow->ImplGetParent();
1504 if ( pWindow == this )
1505 return sal_True;
1507 while ( pWindow );
1509 return sal_False;
1512 // -----------------------------------------------------------------------
1514 sal_Bool Window::ImplIsWindowOrChild( const Window* pWindow, sal_Bool bSystemWindow ) const
1516 if ( this == pWindow )
1517 return sal_True;
1518 return ImplIsChild( pWindow, bSystemWindow );
1521 // -----------------------------------------------------------------------
1523 int Window::ImplTestMousePointerSet()
1525 // as soon as mouse is captured, switch mouse-pointer
1526 if ( IsMouseCaptured() )
1527 return sal_True;
1529 // if the mouse is over the window, switch it
1530 Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
1531 if ( aClientRect.IsInside( GetPointerPosPixel() ) )
1532 return sal_True;
1534 return sal_False;
1537 // -----------------------------------------------------------------------
1539 PointerStyle Window::ImplGetMousePointer() const
1541 PointerStyle ePointerStyle;
1542 sal_Bool bWait = sal_False;
1544 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
1545 ePointerStyle = GetPointer().GetStyle();
1546 else
1547 ePointerStyle = POINTER_ARROW;
1549 const Window* pWindow = this;
1552 // when the pointer is not visible stop the search, as
1553 // this status should not be overwritten
1554 if ( pWindow->mpWindowImpl->mbNoPtrVisible )
1555 return POINTER_NULL;
1557 if ( !bWait )
1559 if ( pWindow->mpWindowImpl->mnWaitCount )
1561 ePointerStyle = POINTER_WAIT;
1562 bWait = sal_True;
1564 else
1566 if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
1567 ePointerStyle = pWindow->GetPointer().GetStyle();
1571 if ( pWindow->ImplIsOverlapWindow() )
1572 break;
1574 pWindow = pWindow->ImplGetParent();
1576 while ( pWindow );
1578 return ePointerStyle;
1581 // -----------------------------------------------------------------------
1583 void Window::ImplResetReallyVisible()
1585 sal_Bool bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
1587 mbDevOutput = sal_False;
1588 mpWindowImpl->mbReallyVisible = sal_False;
1589 mpWindowImpl->mbReallyShown = sal_False;
1591 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1592 // For this, the data member of the event must not be NULL.
1593 // Previously, we did this in Window::Show, but there some events got lost in certain situations.
1594 if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
1595 ImplCallEventListeners( VCLEVENT_WINDOW_HIDE, this );
1596 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_HIDE. Normally, we should
1597 // introduce another event which explicitly triggers the Accessibility implementations.
1599 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1600 while ( pWindow )
1602 if ( pWindow->mpWindowImpl->mbReallyVisible )
1603 pWindow->ImplResetReallyVisible();
1604 pWindow = pWindow->mpWindowImpl->mpNext;
1607 pWindow = mpWindowImpl->mpFirstChild;
1608 while ( pWindow )
1610 if ( pWindow->mpWindowImpl->mbReallyVisible )
1611 pWindow->ImplResetReallyVisible();
1612 pWindow = pWindow->mpWindowImpl->mpNext;
1616 // -----------------------------------------------------------------------
1618 void Window::ImplSetReallyVisible()
1620 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1621 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1622 // mbReallyShown is a useful indicator
1623 if( !mpWindowImpl->mbReallyShown )
1624 ImplCallInitShow();
1626 sal_Bool bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;
1628 mbDevOutput = sal_True;
1629 mpWindowImpl->mbReallyVisible = sal_True;
1630 mpWindowImpl->mbReallyShown = sal_True;
1632 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1633 // For this, the data member of the event must not be NULL.
1634 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1635 // we're doing it when the visibility really changes
1636 if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
1637 ImplCallEventListeners( VCLEVENT_WINDOW_SHOW, this );
1638 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_SHOW. Normally, we should
1639 // introduce another event which explicitly triggers the Accessibility implementations.
1641 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1642 while ( pWindow )
1644 if ( pWindow->mpWindowImpl->mbVisible )
1645 pWindow->ImplSetReallyVisible();
1646 pWindow = pWindow->mpWindowImpl->mpNext;
1649 pWindow = mpWindowImpl->mpFirstChild;
1650 while ( pWindow )
1652 if ( pWindow->mpWindowImpl->mbVisible )
1653 pWindow->ImplSetReallyVisible();
1654 pWindow = pWindow->mpWindowImpl->mpNext;
1658 // -----------------------------------------------------------------------
1660 void Window::ImplCallInitShow()
1662 mpWindowImpl->mbReallyShown = sal_True;
1663 mpWindowImpl->mbInInitShow = sal_True;
1664 StateChanged( STATE_CHANGE_INITSHOW );
1665 mpWindowImpl->mbInInitShow = sal_False;
1667 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1668 while ( pWindow )
1670 if ( pWindow->mpWindowImpl->mbVisible )
1671 pWindow->ImplCallInitShow();
1672 pWindow = pWindow->mpWindowImpl->mpNext;
1675 pWindow = mpWindowImpl->mpFirstChild;
1676 while ( pWindow )
1678 if ( pWindow->mpWindowImpl->mbVisible )
1679 pWindow->ImplCallInitShow();
1680 pWindow = pWindow->mpWindowImpl->mpNext;
1684 // -----------------------------------------------------------------------
1686 void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok
1688 DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" );
1689 if( !pDel->mpWindow )
1691 pDel->mpWindow = this; // #112873# store ref to this window, so pDel can remove itself
1692 pDel->mpNext = mpWindowImpl->mpFirstDel;
1693 mpWindowImpl->mpFirstDel = pDel;
1697 // -----------------------------------------------------------------------
1699 void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok
1701 pDel->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
1702 if ( mpWindowImpl->mpFirstDel == pDel )
1703 mpWindowImpl->mpFirstDel = pDel->mpNext;
1704 else
1706 ImplDelData* pData = mpWindowImpl->mpFirstDel;
1707 while ( pData->mpNext != pDel )
1708 pData = pData->mpNext;
1709 pData->mpNext = pDel->mpNext;
1713 // -----------------------------------------------------------------------
1715 void Window::ImplInitResolutionSettings()
1717 // recalculate AppFont-resolution and DPI-resolution
1718 if ( mpWindowImpl->mbFrame )
1720 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
1721 sal_uInt16 nScreenZoom = rStyleSettings.GetScreenZoom();
1722 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
1723 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
1724 SetPointFont( rStyleSettings.GetAppFont() );
1726 else if ( mpWindowImpl->mpParent )
1728 mnDPIX = mpWindowImpl->mpParent->mnDPIX;
1729 mnDPIY = mpWindowImpl->mpParent->mnDPIY;
1732 // update the recalculated values for logical units
1733 // and also tools belonging to the values
1734 if ( IsMapMode() )
1736 MapMode aMapMode = GetMapMode();
1737 SetMapMode();
1738 SetMapMode( aMapMode );
1742 // -----------------------------------------------------------------------
1744 void Window::ImplPointToLogic( Font& rFont ) const
1746 Size aSize = rFont.GetSize();
1747 sal_uInt16 nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
1749 if ( aSize.Width() )
1751 aSize.Width() *= mpWindowImpl->mpFrameData->mnDPIX;
1752 aSize.Width() += 72/2;
1753 aSize.Width() /= 72;
1754 aSize.Width() *= nScreenFontZoom;
1755 aSize.Width() /= 100;
1757 aSize.Height() *= mpWindowImpl->mpFrameData->mnDPIY;
1758 aSize.Height() += 72/2;
1759 aSize.Height() /= 72;
1760 aSize.Height() *= nScreenFontZoom;
1761 aSize.Height() /= 100;
1763 if ( IsMapModeEnabled() )
1764 aSize = PixelToLogic( aSize );
1766 rFont.SetSize( aSize );
1769 // -----------------------------------------------------------------------
1771 void Window::ImplLogicToPoint( Font& rFont ) const
1773 Size aSize = rFont.GetSize();
1774 sal_uInt16 nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
1776 if ( IsMapModeEnabled() )
1777 aSize = LogicToPixel( aSize );
1779 if ( aSize.Width() )
1781 aSize.Width() *= 100;
1782 aSize.Width() /= nScreenFontZoom;
1783 aSize.Width() *= 72;
1784 aSize.Width() += mpWindowImpl->mpFrameData->mnDPIX/2;
1785 aSize.Width() /= mpWindowImpl->mpFrameData->mnDPIX;
1787 aSize.Height() *= 100;
1788 aSize.Height() /= nScreenFontZoom;
1789 aSize.Height() *= 72;
1790 aSize.Height() += mpWindowImpl->mpFrameData->mnDPIY/2;
1791 aSize.Height() /= mpWindowImpl->mpFrameData->mnDPIY;
1793 rFont.SetSize( aSize );
1796 // -----------------------------------------------------------------------
1798 sal_Bool Window::ImplSysObjClip( const Region* pOldRegion )
1800 sal_Bool bUpdate = sal_True;
1802 if ( mpWindowImpl->mpSysObj )
1804 bool bVisibleState = mpWindowImpl->mbReallyVisible;
1806 if ( bVisibleState )
1808 Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
1810 if ( !pWinChildClipRegion->IsEmpty() )
1812 if ( pOldRegion )
1814 Region aNewRegion = *pWinChildClipRegion;
1815 pWinChildClipRegion->Intersect( *pOldRegion );
1816 bUpdate = aNewRegion == *pWinChildClipRegion;
1819 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
1820 ImplInvalidateAllOverlapBackgrounds();
1822 Region aRegion = *pWinChildClipRegion;
1823 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
1824 Region aWinRectRegion( aWinRect );
1825 sal_uInt16 nClipFlags = mpWindowImpl->mpSysObj->GetClipRegionType();
1827 if ( aRegion == aWinRectRegion )
1828 mpWindowImpl->mpSysObj->ResetClipRegion();
1829 else
1831 if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS )
1833 aWinRectRegion.Exclude( aRegion );
1834 aRegion = aWinRectRegion;
1836 if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) )
1837 aRegion.Move( -mnOutOffX, -mnOutOffY );
1839 // ClipRegion setzen/updaten
1840 long nX;
1841 long nY;
1842 long nWidth;
1843 long nHeight;
1844 sal_uLong nRectCount;
1845 ImplRegionInfo aInfo;
1846 sal_Bool bRegionRect;
1848 nRectCount = aRegion.GetRectCount();
1849 mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount );
1850 bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1851 while ( bRegionRect )
1853 mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
1854 bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1856 mpWindowImpl->mpSysObj->EndSetClipRegion();
1859 else
1860 bVisibleState = sal_False;
1863 // Visible-Status updaten
1864 mpWindowImpl->mpSysObj->Show( bVisibleState );
1867 return bUpdate;
1870 // -----------------------------------------------------------------------
1872 void Window::ImplUpdateSysObjChildrenClip()
1874 if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion )
1875 ImplSysObjClip( NULL );
1877 Window* pWindow = mpWindowImpl->mpFirstChild;
1878 while ( pWindow )
1880 pWindow->ImplUpdateSysObjChildrenClip();
1881 pWindow = pWindow->mpWindowImpl->mpNext;
1885 // -----------------------------------------------------------------------
1887 void Window::ImplUpdateSysObjOverlapsClip()
1889 ImplUpdateSysObjChildrenClip();
1891 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1892 while ( pWindow )
1894 pWindow->ImplUpdateSysObjOverlapsClip();
1895 pWindow = pWindow->mpWindowImpl->mpNext;
1899 // -----------------------------------------------------------------------
1901 void Window::ImplUpdateSysObjClip()
1903 if ( !ImplIsOverlapWindow() )
1905 ImplUpdateSysObjChildrenClip();
1907 // siblings should recalculate their clip region
1908 if ( mpWindowImpl->mbClipSiblings )
1910 Window* pWindow = mpWindowImpl->mpNext;
1911 while ( pWindow )
1913 pWindow->ImplUpdateSysObjChildrenClip();
1914 pWindow = pWindow->mpWindowImpl->mpNext;
1918 else
1919 mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip();
1922 // -----------------------------------------------------------------------
1924 sal_Bool Window::ImplSetClipFlagChildren( sal_Bool bSysObjOnlySmaller )
1926 sal_Bool bUpdate = sal_True;
1927 if ( mpWindowImpl->mpSysObj )
1929 Region* pOldRegion = NULL;
1930 if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion )
1931 pOldRegion = new Region( mpWindowImpl->maWinClipRegion );
1933 mbInitClipRegion = sal_True;
1934 mpWindowImpl->mbInitWinClipRegion = sal_True;
1936 Window* pWindow = mpWindowImpl->mpFirstChild;
1937 while ( pWindow )
1939 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
1940 bUpdate = sal_False;
1941 pWindow = pWindow->mpWindowImpl->mpNext;
1944 if ( !ImplSysObjClip( pOldRegion ) )
1946 mbInitClipRegion = sal_True;
1947 mpWindowImpl->mbInitWinClipRegion = sal_True;
1948 bUpdate = sal_False;
1951 delete pOldRegion;
1953 else
1955 mbInitClipRegion = sal_True;
1956 mpWindowImpl->mbInitWinClipRegion = sal_True;
1958 Window* pWindow = mpWindowImpl->mpFirstChild;
1959 while ( pWindow )
1961 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
1962 bUpdate = sal_False;
1963 pWindow = pWindow->mpWindowImpl->mpNext;
1966 return bUpdate;
1969 // -----------------------------------------------------------------------
1971 sal_Bool Window::ImplSetClipFlagOverlapWindows( sal_Bool bSysObjOnlySmaller )
1973 sal_Bool bUpdate = ImplSetClipFlagChildren( bSysObjOnlySmaller );
1975 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1976 while ( pWindow )
1978 if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
1979 bUpdate = sal_False;
1980 pWindow = pWindow->mpWindowImpl->mpNext;
1983 return bUpdate;
1986 // -----------------------------------------------------------------------
1988 sal_Bool Window::ImplSetClipFlag( sal_Bool bSysObjOnlySmaller )
1990 if ( !ImplIsOverlapWindow() )
1992 sal_Bool bUpdate = ImplSetClipFlagChildren( bSysObjOnlySmaller );
1994 Window* pParent = ImplGetParent();
1995 if ( pParent &&
1996 ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP)) )
1998 pParent->mbInitClipRegion = sal_True;
1999 pParent->mpWindowImpl->mbInitChildRegion = sal_True;
2002 // siblings should recalculate their clip region
2003 if ( mpWindowImpl->mbClipSiblings )
2005 Window* pWindow = mpWindowImpl->mpNext;
2006 while ( pWindow )
2008 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
2009 bUpdate = sal_False;
2010 pWindow = pWindow->mpWindowImpl->mpNext;
2014 return bUpdate;
2016 else
2017 return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
2020 // -----------------------------------------------------------------------
2022 void Window::ImplIntersectWindowClipRegion( Region& rRegion )
2024 if ( mpWindowImpl->mbInitWinClipRegion )
2025 ImplInitWinClipRegion();
2027 rRegion.Intersect( mpWindowImpl->maWinClipRegion );
2030 // -----------------------------------------------------------------------
2032 void Window::ImplIntersectWindowRegion( Region& rRegion )
2034 rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ),
2035 Size( mnOutWidth, mnOutHeight ) ) );
2036 if ( mpWindowImpl->mbWinRegion )
2037 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2040 // -----------------------------------------------------------------------
2042 void Window::ImplExcludeWindowRegion( Region& rRegion )
2044 if ( mpWindowImpl->mbWinRegion )
2046 Point aPoint( mnOutOffX, mnOutOffY );
2047 Region aRegion( Rectangle( aPoint,
2048 Size( mnOutWidth, mnOutHeight ) ) );
2049 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2050 rRegion.Exclude( aRegion );
2052 else
2054 Point aPoint( mnOutOffX, mnOutOffY );
2055 rRegion.Exclude( Rectangle( aPoint,
2056 Size( mnOutWidth, mnOutHeight ) ) );
2060 // -----------------------------------------------------------------------
2062 void Window::ImplExcludeOverlapWindows( Region& rRegion )
2064 Window* pWindow = mpWindowImpl->mpFirstOverlap;
2065 while ( pWindow )
2067 if ( pWindow->mpWindowImpl->mbReallyVisible )
2069 pWindow->ImplExcludeWindowRegion( rRegion );
2070 pWindow->ImplExcludeOverlapWindows( rRegion );
2073 pWindow = pWindow->mpWindowImpl->mpNext;
2077 // -----------------------------------------------------------------------
2079 void Window::ImplExcludeOverlapWindows2( Region& rRegion )
2081 if ( mpWindowImpl->mbReallyVisible )
2082 ImplExcludeWindowRegion( rRegion );
2084 ImplExcludeOverlapWindows( rRegion );
2087 // -----------------------------------------------------------------------
2089 void Window::ImplClipBoundaries( Region& rRegion, sal_Bool bThis, sal_Bool bOverlaps )
2091 if ( bThis )
2092 ImplIntersectWindowClipRegion( rRegion );
2093 else if ( ImplIsOverlapWindow() )
2095 // clip to frame if required
2096 if ( !mpWindowImpl->mbFrame )
2097 rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
2099 if ( bOverlaps && !rRegion.IsEmpty() )
2101 // Clip Overlap Siblings
2102 Window* pStartOverlapWindow = this;
2103 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
2105 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
2106 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
2108 pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
2109 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
2111 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
2114 // Clip Child Overlap Windows
2115 ImplExcludeOverlapWindows( rRegion );
2118 else
2119 ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
2122 // -----------------------------------------------------------------------
2124 sal_Bool Window::ImplClipChildren( Region& rRegion )
2126 sal_Bool bOtherClip = sal_False;
2127 Window* pWindow = mpWindowImpl->mpFirstChild;
2128 while ( pWindow )
2130 if ( pWindow->mpWindowImpl->mbReallyVisible )
2132 // read-out ParentClipMode-Flags
2133 sal_uInt16 nClipMode = pWindow->GetParentClipMode();
2134 if ( !(nClipMode & PARENTCLIPMODE_NOCLIP) &&
2135 ((nClipMode & PARENTCLIPMODE_CLIP) || (GetStyle() & WB_CLIPCHILDREN)) )
2136 pWindow->ImplExcludeWindowRegion( rRegion );
2137 else
2138 bOtherClip = sal_True;
2141 pWindow = pWindow->mpWindowImpl->mpNext;
2144 return bOtherClip;
2147 // -----------------------------------------------------------------------
2149 void Window::ImplClipAllChildren( Region& rRegion )
2151 Window* pWindow = mpWindowImpl->mpFirstChild;
2152 while ( pWindow )
2154 if ( pWindow->mpWindowImpl->mbReallyVisible )
2155 pWindow->ImplExcludeWindowRegion( rRegion );
2156 pWindow = pWindow->mpWindowImpl->mpNext;
2160 // -----------------------------------------------------------------------
2162 void Window::ImplClipSiblings( Region& rRegion )
2164 Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
2165 while ( pWindow )
2167 if ( pWindow == this )
2168 break;
2170 if ( pWindow->mpWindowImpl->mbReallyVisible )
2171 pWindow->ImplExcludeWindowRegion( rRegion );
2173 pWindow = pWindow->mpWindowImpl->mpNext;
2177 // -----------------------------------------------------------------------
2179 void Window::ImplInitWinClipRegion()
2181 // Build Window Region
2182 mpWindowImpl->maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ),
2183 Size( mnOutWidth, mnOutHeight ) );
2184 if ( mpWindowImpl->mbWinRegion )
2185 mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2187 // ClipSiblings
2188 if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() )
2189 ImplClipSiblings( mpWindowImpl->maWinClipRegion );
2191 // Clip Parent Boundaries
2192 ImplClipBoundaries( mpWindowImpl->maWinClipRegion, sal_False, sal_True );
2194 // Clip Children
2195 if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren )
2196 mpWindowImpl->mbInitChildRegion = sal_True;
2198 mpWindowImpl->mbInitWinClipRegion = sal_False;
2201 // -----------------------------------------------------------------------
2203 void Window::ImplInitWinChildClipRegion()
2205 if ( !mpWindowImpl->mpFirstChild )
2207 if ( mpWindowImpl->mpChildClipRegion )
2209 delete mpWindowImpl->mpChildClipRegion;
2210 mpWindowImpl->mpChildClipRegion = NULL;
2213 else
2215 if ( !mpWindowImpl->mpChildClipRegion )
2216 mpWindowImpl->mpChildClipRegion = new Region( mpWindowImpl->maWinClipRegion );
2217 else
2218 *mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion;
2220 ImplClipChildren( *mpWindowImpl->mpChildClipRegion );
2223 mpWindowImpl->mbInitChildRegion = sal_False;
2226 // -----------------------------------------------------------------------
2228 Region* Window::ImplGetWinChildClipRegion()
2230 if ( mpWindowImpl->mbInitWinClipRegion )
2231 ImplInitWinClipRegion();
2232 if ( mpWindowImpl->mbInitChildRegion )
2233 ImplInitWinChildClipRegion();
2234 if ( mpWindowImpl->mpChildClipRegion )
2235 return mpWindowImpl->mpChildClipRegion;
2236 else
2237 return &mpWindowImpl->maWinClipRegion;
2240 // -----------------------------------------------------------------------
2242 void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion )
2244 Window* pWindow = mpWindowImpl->mpFirstOverlap;
2245 while ( pWindow )
2247 if ( pWindow->mpWindowImpl->mbReallyVisible )
2249 Region aTempRegion( rInterRegion );
2250 pWindow->ImplIntersectWindowRegion( aTempRegion );
2251 rRegion.Union( aTempRegion );
2252 pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2255 pWindow = pWindow->mpWindowImpl->mpNext;
2259 // -----------------------------------------------------------------------
2261 void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion )
2263 if ( mpWindowImpl->mbReallyVisible )
2265 Region aTempRegion( rInterRegion );
2266 ImplIntersectWindowRegion( aTempRegion );
2267 rRegion.Union( aTempRegion );
2270 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2273 // -----------------------------------------------------------------------
2275 void Window::ImplCalcOverlapRegionOverlaps( const Region& rInterRegion, Region& rRegion )
2277 // Clip Overlap Siblings
2278 Window* pStartOverlapWindow;
2279 if ( !ImplIsOverlapWindow() )
2280 pStartOverlapWindow = mpWindowImpl->mpOverlapWindow;
2281 else
2282 pStartOverlapWindow = this;
2283 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
2285 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
2286 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
2288 pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
2289 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
2291 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
2294 // Clip Child Overlap Windows
2295 if ( !ImplIsOverlapWindow() )
2296 mpWindowImpl->mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2297 else
2298 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2301 // -----------------------------------------------------------------------
2303 void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, Region& rRegion,
2304 sal_Bool bChildren, sal_Bool bParent, sal_Bool bSiblings )
2306 Region aRegion( rSourceRect );
2307 if ( mpWindowImpl->mbWinRegion )
2308 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2309 Region aTempRegion;
2310 Window* pWindow;
2312 ImplCalcOverlapRegionOverlaps( aRegion, rRegion );
2314 // Parent-Boundaries
2315 if ( bParent )
2317 pWindow = this;
2318 if ( !ImplIsOverlapWindow() )
2320 pWindow = ImplGetParent();
2323 aTempRegion = aRegion;
2324 pWindow->ImplExcludeWindowRegion( aTempRegion );
2325 rRegion.Union( aTempRegion );
2326 if ( pWindow->ImplIsOverlapWindow() )
2327 break;
2328 pWindow = pWindow->ImplGetParent();
2330 while ( pWindow );
2332 if ( pWindow && !pWindow->mpWindowImpl->mbFrame )
2334 aTempRegion = aRegion;
2335 aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
2336 rRegion.Union( aTempRegion );
2340 // Siblings
2341 if ( bSiblings && !ImplIsOverlapWindow() )
2343 pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
2346 if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) )
2348 aTempRegion = aRegion;
2349 pWindow->ImplIntersectWindowRegion( aTempRegion );
2350 rRegion.Union( aTempRegion );
2352 pWindow = pWindow->mpWindowImpl->mpNext;
2354 while ( pWindow );
2357 if ( bChildren )
2359 pWindow = mpWindowImpl->mpFirstChild;
2360 while ( pWindow )
2362 if ( pWindow->mpWindowImpl->mbReallyVisible )
2364 aTempRegion = aRegion;
2365 pWindow->ImplIntersectWindowRegion( aTempRegion );
2366 rRegion.Union( aTempRegion );
2368 pWindow = pWindow->mpWindowImpl->mpNext;
2373 // -----------------------------------------------------------------------
2375 void Window::ImplCallPaint( const Region* pRegion, sal_uInt16 nPaintFlags )
2377 // call PrePaint. PrePaint may add to the invalidate region as well as
2378 // other parameters used below.
2379 PrePaint();
2381 mpWindowImpl->mbPaintFrame = sal_False;
2383 if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
2384 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDREN | (nPaintFlags & IMPL_PAINT_PAINTALL);
2385 if ( nPaintFlags & IMPL_PAINT_PAINTCHILDREN )
2386 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDREN;
2387 if ( nPaintFlags & IMPL_PAINT_ERASE )
2388 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
2389 if ( nPaintFlags & IMPL_PAINT_CHECKRTL )
2390 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
2391 if ( !mpWindowImpl->mpFirstChild )
2392 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDREN;
2394 if ( mpWindowImpl->mbPaintDisabled )
2396 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2397 Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
2398 else if ( pRegion )
2399 Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
2400 return;
2403 nPaintFlags = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT);
2405 Region* pChildRegion = NULL;
2406 Rectangle aSelectionRect;
2407 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
2409 Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
2410 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2411 mpWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
2412 else
2414 if ( pRegion )
2415 mpWindowImpl->maInvalidateRegion.Union( *pRegion );
2417 if( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible )
2418 /* #98602# need to repaint all children within the
2419 * tracking rectangle, so the following invert
2420 * operation takes places without traces of the previous
2421 * one.
2423 mpWindowImpl->maInvalidateRegion.Union( *mpWindowImpl->mpWinData->mpTrackRect );
2425 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
2426 pChildRegion = new Region( mpWindowImpl->maInvalidateRegion );
2427 mpWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion );
2429 mpWindowImpl->mnPaintFlags = 0;
2430 if ( !mpWindowImpl->maInvalidateRegion.IsEmpty() )
2432 bool bRestoreCursor = false;
2433 if ( mpWindowImpl->mpCursor )
2434 bRestoreCursor = mpWindowImpl->mpCursor->ImplSuspend();
2436 mbInitClipRegion = sal_True;
2437 mpWindowImpl->mbInPaint = sal_True;
2439 // restore Paint-Region
2440 Region aPaintRegion( mpWindowImpl->maInvalidateRegion );
2441 Rectangle aPaintRect = aPaintRegion.GetBoundRect();
2443 // - RTL - re-mirror paint rect and region at this window
2444 if( ImplIsAntiparallel() )
2446 ImplReMirror( aPaintRect );
2447 ImplReMirror( aPaintRegion );
2449 aPaintRect = ImplDevicePixelToLogic( aPaintRect);
2450 mpWindowImpl->mpPaintRegion = &aPaintRegion;
2451 mpWindowImpl->maInvalidateRegion.SetEmpty();
2453 if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() )
2455 if ( IsClipRegion() )
2457 Region aOldRegion = GetClipRegion();
2458 SetClipRegion();
2459 Erase();
2460 SetClipRegion( aOldRegion );
2462 else
2463 Erase();
2466 // #98943# trigger drawing of toolbox selection after all childern are painted
2467 if( mpWindowImpl->mbDrawSelectionBackground )
2468 aSelectionRect = aPaintRect;
2470 Paint( aPaintRect );
2472 if ( mpWindowImpl->mpWinData )
2474 if ( mpWindowImpl->mbFocusVisible )
2475 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
2477 mpWindowImpl->mbInPaint = sal_False;
2478 mbInitClipRegion = sal_True;
2479 mpWindowImpl->mpPaintRegion = NULL;
2480 if ( mpWindowImpl->mpCursor )
2481 mpWindowImpl->mpCursor->ImplResume( bRestoreCursor );
2484 else
2485 mpWindowImpl->mnPaintFlags = 0;
2487 if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDREN | IMPL_PAINT_PAINTCHILDREN) )
2489 // Paint from the bottom child window and frontward.
2490 Window* pTempWindow = mpWindowImpl->mpLastChild;
2491 while ( pTempWindow )
2493 if ( pTempWindow->mpWindowImpl->mbVisible )
2494 pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags );
2495 pTempWindow = pTempWindow->mpWindowImpl->mpPrev;
2499 if ( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
2500 /* #98602# need to invert the tracking rect AFTER
2501 * the children have painted
2503 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
2505 // #98943# draw toolbox selection
2506 if( !aSelectionRect.IsEmpty() )
2507 DrawSelectionBackground( aSelectionRect, 3, sal_False, sal_True, sal_False );
2509 delete pChildRegion;
2512 // -----------------------------------------------------------------------
2514 void Window::ImplCallOverlapPaint()
2516 // emit overlapping windows first
2517 Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
2518 while ( pTempWindow )
2520 if ( pTempWindow->mpWindowImpl->mbReallyVisible )
2521 pTempWindow->ImplCallOverlapPaint();
2522 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2525 // only then ourself
2526 if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
2528 // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
2529 // because we were called from the Sal layer
2530 ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
2534 // -----------------------------------------------------------------------
2536 void Window::ImplPostPaint()
2538 if ( !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
2539 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2542 // -----------------------------------------------------------------------
2544 IMPL_LINK_NOARG(Window, ImplHandlePaintHdl)
2546 // save paint events until layout is done
2547 if (IsDialog() && static_cast<const Dialog*>(this)->hasPendingLayout())
2549 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2550 return 0;
2553 // save paint events until resizing is done
2554 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
2555 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2556 else if ( mpWindowImpl->mbReallyVisible )
2557 ImplCallOverlapPaint();
2558 return 0;
2561 // -----------------------------------------------------------------------
2563 IMPL_LINK_NOARG(Window, ImplHandleResizeTimerHdl)
2565 if( mpWindowImpl->mbReallyVisible )
2567 ImplCallResize();
2568 if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
2570 mpWindowImpl->mpFrameData->maPaintTimer.Stop();
2571 mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL );
2575 return 0;
2578 // -----------------------------------------------------------------------
2580 void Window::ImplInvalidateFrameRegion( const Region* pRegion, sal_uInt16 nFlags )
2582 // set PAINTCHILDREN for all parent windows till the first OverlapWindow
2583 if ( !ImplIsOverlapWindow() )
2585 Window* pTempWindow = this;
2586 sal_uInt16 nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0;
2589 pTempWindow = pTempWindow->ImplGetParent();
2590 if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDREN )
2591 break;
2592 pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDREN | nTranspPaint;
2593 if( ! pTempWindow->IsPaintTransparent() )
2594 nTranspPaint = 0;
2596 while ( !pTempWindow->ImplIsOverlapWindow() );
2599 // set Paint-Flags
2600 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT;
2601 if ( nFlags & INVALIDATE_CHILDREN )
2602 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDREN;
2603 if ( !(nFlags & INVALIDATE_NOERASE) )
2604 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
2605 if ( !pRegion )
2606 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL;
2608 // if not everything has to be redrawn, add the region to it
2609 if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) )
2610 mpWindowImpl->maInvalidateRegion.Union( *pRegion );
2612 // Handle transparent windows correctly: invalidate must be done on the first opaque parent
2613 if( ((IsPaintTransparent() && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
2614 && ImplGetParent() )
2616 Window *pParent = ImplGetParent();
2617 while( pParent && pParent->IsPaintTransparent() )
2618 pParent = pParent->ImplGetParent();
2619 if( pParent )
2621 Region *pChildRegion;
2622 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2623 // invalidate the whole child window region in the parent
2624 pChildRegion = ImplGetWinChildClipRegion();
2625 else
2626 // invalidate the same region in the parent that has to be repainted in the child
2627 pChildRegion = &mpWindowImpl->maInvalidateRegion;
2629 nFlags |= INVALIDATE_CHILDREN; // paint should also be done on all children
2630 nFlags &= ~INVALIDATE_NOERASE; // parent should paint and erase to create proper background
2631 pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
2634 ImplPostPaint();
2637 // -----------------------------------------------------------------------
2639 void Window::ImplInvalidateOverlapFrameRegion( const Region& rRegion )
2641 Region aRegion = rRegion;
2643 ImplClipBoundaries( aRegion, sal_True, sal_True );
2644 if ( !aRegion.IsEmpty() )
2645 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
2647 // now we invalidate the overlapping windows
2648 Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
2649 while ( pTempWindow )
2651 if ( pTempWindow->IsVisible() )
2652 pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
2654 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2658 // -----------------------------------------------------------------------
2660 void Window::ImplInvalidateParentFrameRegion( Region& rRegion )
2662 if ( mpWindowImpl->mbOverlapWin )
2663 mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
2664 else
2666 if( ImplGetParent() )
2667 ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN );
2671 // -----------------------------------------------------------------------
2673 void Window::ImplInvalidate( const Region* pRegion, sal_uInt16 nFlags )
2676 // reset background storage
2677 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
2678 ImplInvalidateAllOverlapBackgrounds();
2680 // check what has to be redrawn
2681 sal_Bool bInvalidateAll = !pRegion;
2683 // take Transparent-Invalidate into account
2684 Window* pOpaqueWindow = this;
2685 if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
2687 Window* pTempWindow = pOpaqueWindow->ImplGetParent();
2688 while ( pTempWindow )
2690 if ( !pTempWindow->IsPaintTransparent() )
2692 pOpaqueWindow = pTempWindow;
2693 nFlags |= INVALIDATE_CHILDREN;
2694 bInvalidateAll = sal_False;
2695 break;
2698 if ( pTempWindow->ImplIsOverlapWindow() )
2699 break;
2701 pTempWindow = pTempWindow->ImplGetParent();
2705 // assemble region
2706 sal_uInt16 nOrgFlags = nFlags;
2707 if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) )
2709 if ( GetStyle() & WB_CLIPCHILDREN )
2710 nFlags |= INVALIDATE_NOCHILDREN;
2711 else
2712 nFlags |= INVALIDATE_CHILDREN;
2714 if ( (nFlags & INVALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
2715 bInvalidateAll = sal_False;
2716 if ( bInvalidateAll )
2717 ImplInvalidateFrameRegion( NULL, nFlags );
2718 else
2720 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2721 Region aRegion( aRect );
2722 if ( pRegion )
2724 // --- RTL --- remirror region before intersecting it
2725 if ( ImplIsAntiparallel() )
2727 Region aRgn( *pRegion );
2728 ImplReMirror( aRgn );
2729 aRegion.Intersect( aRgn );
2731 else
2732 aRegion.Intersect( *pRegion );
2734 ImplClipBoundaries( aRegion, sal_True, sal_True );
2735 if ( nFlags & INVALIDATE_NOCHILDREN )
2737 nFlags &= ~INVALIDATE_CHILDREN;
2738 if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) )
2740 if ( nOrgFlags & INVALIDATE_NOCHILDREN )
2741 ImplClipAllChildren( aRegion );
2742 else
2744 if ( ImplClipChildren( aRegion ) )
2745 nFlags |= INVALIDATE_CHILDREN;
2749 if ( !aRegion.IsEmpty() )
2750 ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
2753 if ( nFlags & INVALIDATE_UPDATE )
2754 pOpaqueWindow->Update(); // start painting at the opaque parent
2757 // -----------------------------------------------------------------------
2759 void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
2760 long nHorzScroll, long nVertScroll,
2761 sal_Bool bChildren )
2763 if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
2765 Region aTempRegion = mpWindowImpl->maInvalidateRegion;
2766 aTempRegion.Intersect( rRect );
2767 aTempRegion.Move( nHorzScroll, nVertScroll );
2768 mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
2771 if ( bChildren && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDREN) )
2773 Window* pWindow = mpWindowImpl->mpFirstChild;
2774 while ( pWindow )
2776 pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, sal_True );
2777 pWindow = pWindow->mpWindowImpl->mpNext;
2782 // -----------------------------------------------------------------------
2784 void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect,
2785 long nHorzScroll, long nVertScroll,
2786 sal_Bool bChildren )
2788 // also shift Paint-Region when paints need processing
2789 ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChildren );
2790 // Paint-Region should be shifted, as drawn by the parents
2791 if ( !ImplIsOverlapWindow() )
2793 Region aPaintAllRegion;
2794 Window* pPaintAllWindow = this;
2797 pPaintAllWindow = pPaintAllWindow->ImplGetParent();
2798 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
2800 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2802 aPaintAllRegion.SetEmpty();
2803 break;
2805 else
2806 aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
2809 while ( !pPaintAllWindow->ImplIsOverlapWindow() );
2810 if ( !aPaintAllRegion.IsEmpty() )
2812 aPaintAllRegion.Move( nHorzScroll, nVertScroll );
2813 sal_uInt16 nPaintFlags = 0;
2814 if ( bChildren )
2815 mpWindowImpl->mnPaintFlags |= INVALIDATE_CHILDREN;
2816 ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
2821 // -----------------------------------------------------------------------
2823 void Window::ImplValidateFrameRegion( const Region* pRegion, sal_uInt16 nFlags )
2825 if ( !pRegion )
2826 mpWindowImpl->maInvalidateRegion.SetEmpty();
2827 else
2829 // when all child windows have to be drawn we need to invalidate them before doing so
2830 if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN) && mpWindowImpl->mpFirstChild )
2832 Region aChildRegion = mpWindowImpl->maInvalidateRegion;
2833 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2835 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2836 aChildRegion = aRect;
2838 Window* pChild = mpWindowImpl->mpFirstChild;
2839 while ( pChild )
2841 pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
2842 pChild = pChild->mpWindowImpl->mpNext;
2845 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2847 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2848 mpWindowImpl->maInvalidateRegion = aRect;
2850 mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
2852 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
2854 if ( nFlags & VALIDATE_CHILDREN )
2856 Window* pChild = mpWindowImpl->mpFirstChild;
2857 while ( pChild )
2859 pChild->ImplValidateFrameRegion( pRegion, nFlags );
2860 pChild = pChild->mpWindowImpl->mpNext;
2865 // -----------------------------------------------------------------------
2867 void Window::ImplValidate( const Region* pRegion, sal_uInt16 nFlags )
2869 // assemble region
2870 sal_Bool bValidateAll = !pRegion;
2871 sal_uInt16 nOrgFlags = nFlags;
2872 if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) )
2874 if ( GetStyle() & WB_CLIPCHILDREN )
2875 nFlags |= VALIDATE_NOCHILDREN;
2876 else
2877 nFlags |= VALIDATE_CHILDREN;
2879 if ( (nFlags & VALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
2880 bValidateAll = sal_False;
2881 if ( bValidateAll )
2882 ImplValidateFrameRegion( NULL, nFlags );
2883 else
2885 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2886 Region aRegion( aRect );
2887 if ( pRegion )
2888 aRegion.Intersect( *pRegion );
2889 ImplClipBoundaries( aRegion, sal_True, sal_True );
2890 if ( nFlags & VALIDATE_NOCHILDREN )
2892 nFlags &= ~VALIDATE_CHILDREN;
2893 if ( nOrgFlags & VALIDATE_NOCHILDREN )
2894 ImplClipAllChildren( aRegion );
2895 else
2897 if ( ImplClipChildren( aRegion ) )
2898 nFlags |= VALIDATE_CHILDREN;
2901 if ( !aRegion.IsEmpty() )
2902 ImplValidateFrameRegion( &aRegion, nFlags );
2906 // -----------------------------------------------------------------------
2908 void Window::ImplScroll( const Rectangle& rRect,
2909 long nHorzScroll, long nVertScroll, sal_uInt16 nFlags )
2911 if ( !IsDeviceOutputNecessary() )
2912 return;
2914 nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll );
2915 nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll );
2917 if ( !nHorzScroll && !nVertScroll )
2918 return;
2920 // restore background storage
2921 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
2922 ImplInvalidateAllOverlapBackgrounds();
2924 if ( mpWindowImpl->mpCursor )
2925 mpWindowImpl->mpCursor->ImplSuspend();
2927 sal_uInt16 nOrgFlags = nFlags;
2928 if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) )
2930 if ( GetStyle() & WB_CLIPCHILDREN )
2931 nFlags |= SCROLL_NOCHILDREN;
2932 else
2933 nFlags |= SCROLL_CHILDREN;
2936 Region aInvalidateRegion;
2937 sal_Bool bScrollChildren = (nFlags & SCROLL_CHILDREN) != 0;
2938 sal_Bool bErase = (nFlags & SCROLL_NOERASE) == 0;
2940 if ( !mpWindowImpl->mpFirstChild )
2941 bScrollChildren = sal_False;
2943 // --- RTL --- check if this window requires special action
2944 sal_Bool bReMirror = ( ImplIsAntiparallel() );
2946 Rectangle aRectMirror( rRect );
2947 if( bReMirror )
2949 // --- RTL --- make sure the invalidate region of this window is
2950 // computed in the same coordinate space as the one from the overlap windows
2951 ImplReMirror( aRectMirror );
2954 // adapt paint areas
2955 ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChildren );
2957 if ( !(nFlags & SCROLL_NOINVALIDATE) )
2959 ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChildren, sal_True, sal_False );
2961 // --- RTL ---
2962 // if the scrolling on the device is performed in the opposite direction
2963 // then move the overlaps in that direction to compute the invalidate region
2964 // on the correct side, i.e., revert nHorzScroll
2966 if ( !aInvalidateRegion.IsEmpty() )
2968 aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
2969 bErase = sal_True;
2971 if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) )
2973 Rectangle aDestRect( aRectMirror );
2974 aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
2975 Region aWinInvalidateRegion( aRectMirror );
2976 aWinInvalidateRegion.Exclude( aDestRect );
2978 aInvalidateRegion.Union( aWinInvalidateRegion );
2982 Point aPoint( mnOutOffX, mnOutOffY );
2983 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
2984 if ( nFlags & SCROLL_CLIP )
2985 aRegion.Intersect( rRect );
2986 if ( mpWindowImpl->mbWinRegion )
2987 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2989 aRegion.Exclude( aInvalidateRegion );
2991 ImplClipBoundaries( aRegion, sal_False, sal_True );
2992 if ( !bScrollChildren )
2994 if ( nOrgFlags & SCROLL_NOCHILDREN )
2995 ImplClipAllChildren( aRegion );
2996 else
2997 ImplClipChildren( aRegion );
2999 if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) )
3000 aRegion.Intersect( maRegion );
3001 if ( !aRegion.IsEmpty() )
3003 if ( mpWindowImpl->mpWinData )
3005 if ( mpWindowImpl->mbFocusVisible )
3006 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
3007 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
3008 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
3011 SalGraphics* pGraphics = ImplGetFrameGraphics();
3012 if ( pGraphics )
3014 if( bReMirror )
3016 // --- RTL --- frame coordinates require re-mirroring
3017 ImplReMirror( aRegion );
3020 ImplSelectClipRegion( aRegion, pGraphics );
3021 pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
3022 rRect.Left(), rRect.Top(),
3023 rRect.GetWidth(), rRect.GetHeight(),
3024 SAL_COPYAREA_WINDOWINVALIDATE, this );
3027 if ( mpWindowImpl->mpWinData )
3029 if ( mpWindowImpl->mbFocusVisible )
3030 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
3031 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
3032 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
3036 if ( !aInvalidateRegion.IsEmpty() )
3038 // --- RTL --- the invalidate region for this windows is already computed in frame coordinates
3039 // so it has to be re-mirrored before calling the Paint-handler
3040 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
3042 sal_uInt16 nPaintFlags = INVALIDATE_CHILDREN;
3043 if ( !bErase )
3044 nPaintFlags |= INVALIDATE_NOERASE;
3045 if ( !bScrollChildren )
3047 if ( nOrgFlags & SCROLL_NOCHILDREN )
3048 ImplClipAllChildren( aInvalidateRegion );
3049 else
3050 ImplClipChildren( aInvalidateRegion );
3052 ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags );
3055 if ( bScrollChildren )
3057 Window* pWindow = mpWindowImpl->mpFirstChild;
3058 while ( pWindow )
3060 Point aPos = pWindow->GetPosPixel();
3061 aPos += Point( nHorzScroll, nVertScroll );
3062 pWindow->SetPosPixel( aPos );
3064 pWindow = pWindow->mpWindowImpl->mpNext;
3068 if ( nFlags & SCROLL_UPDATE )
3069 Update();
3071 if ( mpWindowImpl->mpCursor )
3072 mpWindowImpl->mpCursor->ImplResume();
3075 // -----------------------------------------------------------------------
3077 void Window::ImplUpdateAll( sal_Bool bOverlapWindows )
3079 if ( !mpWindowImpl->mbReallyVisible )
3080 return;
3082 sal_Bool bFlush = sal_False;
3083 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
3085 Point aPoint( 0, 0 );
3086 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
3087 ImplInvalidateOverlapFrameRegion( aRegion );
3088 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
3089 bFlush = sal_True;
3092 // an update changes the OverlapWindow, such that for later paints
3093 // not too much has to be drawn, if ALLCHILDREN etc. is set
3094 Window* pWindow = ImplGetFirstOverlapWindow();
3095 if ( bOverlapWindows )
3096 pWindow->ImplCallOverlapPaint();
3097 else
3099 if ( pWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
3100 pWindow->ImplCallPaint( NULL, pWindow->mpWindowImpl->mnPaintFlags );
3103 if ( bFlush )
3104 Flush();
3107 // -----------------------------------------------------------------------
3109 void Window::ImplUpdateWindowPtr( Window* pWindow )
3111 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
3113 // release graphic
3114 ImplReleaseGraphics();
3117 mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData;
3118 mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
3119 mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow;
3120 if ( pWindow->ImplIsOverlapWindow() )
3121 mpWindowImpl->mpOverlapWindow = pWindow;
3122 else
3123 mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
3125 Window* pChild = mpWindowImpl->mpFirstChild;
3126 while ( pChild )
3128 pChild->ImplUpdateWindowPtr( pWindow );
3129 pChild = pChild->mpWindowImpl->mpNext;
3133 // -----------------------------------------------------------------------
3135 void Window::ImplUpdateWindowPtr()
3137 Window* pChild = mpWindowImpl->mpFirstChild;
3138 while ( pChild )
3140 pChild->ImplUpdateWindowPtr( this );
3141 pChild = pChild->mpWindowImpl->mpNext;
3145 // -----------------------------------------------------------------------
3147 void Window::ImplUpdateOverlapWindowPtr( sal_Bool bNewFrame )
3149 sal_Bool bVisible = IsVisible();
3150 Show( false );
3151 ImplRemoveWindow( bNewFrame );
3152 Window* pRealParent = mpWindowImpl->mpRealParent;
3153 ImplInsertWindow( ImplGetParent() );
3154 mpWindowImpl->mpRealParent = pRealParent;
3155 ImplUpdateWindowPtr();
3156 if ( ImplUpdatePos() )
3157 ImplUpdateSysObjPos();
3159 if ( bNewFrame )
3161 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3162 while ( pOverlapWindow )
3164 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3165 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
3166 pOverlapWindow = pNextOverlapWindow;
3170 if ( bVisible )
3171 Show( true );
3174 // -----------------------------------------------------------------------
3176 sal_Bool Window::ImplUpdatePos()
3178 sal_Bool bSysChild = sal_False;
3180 if ( ImplIsOverlapWindow() )
3182 mnOutOffX = mpWindowImpl->mnX;
3183 mnOutOffY = mpWindowImpl->mnY;
3185 else
3187 Window* pParent = ImplGetParent();
3189 mnOutOffX = mpWindowImpl->mnX + pParent->mnOutOffX;
3190 mnOutOffY = mpWindowImpl->mnY + pParent->mnOutOffY;
3193 Window* pChild = mpWindowImpl->mpFirstChild;
3194 while ( pChild )
3196 if ( pChild->ImplUpdatePos() )
3197 bSysChild = sal_True;
3198 pChild = pChild->mpWindowImpl->mpNext;
3201 if ( mpWindowImpl->mpSysObj )
3202 bSysChild = sal_True;
3204 return bSysChild;
3207 // -----------------------------------------------------------------------
3209 void Window::ImplUpdateSysObjPos()
3211 if ( mpWindowImpl->mpSysObj )
3212 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3214 Window* pChild = mpWindowImpl->mpFirstChild;
3215 while ( pChild )
3217 pChild->ImplUpdateSysObjPos();
3218 pChild = pChild->mpWindowImpl->mpNext;
3221 // -----------------------------------------------------------------------
3223 void Window::ImplPosSizeWindow( long nX, long nY,
3224 long nWidth, long nHeight, sal_uInt16 nFlags )
3226 sal_Bool bNewPos = sal_False;
3227 sal_Bool bNewSize = sal_False;
3228 sal_Bool bCopyBits = sal_False;
3229 long nOldOutOffX = mnOutOffX;
3230 long nOldOutOffY = mnOutOffY;
3231 long nOldOutWidth = mnOutWidth;
3232 long nOldOutHeight = mnOutHeight;
3233 Region* pOverlapRegion = NULL;
3234 Region* pOldRegion = NULL;
3236 if ( IsReallyVisible() )
3238 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3239 ImplInvalidateAllOverlapBackgrounds();
3241 Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
3242 Size( nOldOutWidth, nOldOutHeight ) );
3243 pOldRegion = new Region( aOldWinRect );
3244 if ( mpWindowImpl->mbWinRegion )
3245 pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3247 if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
3248 !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
3249 !HasPaintEvent() )
3250 bCopyBits = sal_True;
3253 sal_Bool bnXRecycled = sal_False; // avoid duplicate mirroring in RTL case
3254 if ( nFlags & WINDOW_POSSIZE_WIDTH )
3256 if(!( nFlags & WINDOW_POSSIZE_X ))
3258 nX = mpWindowImpl->mnX;
3259 nFlags |= WINDOW_POSSIZE_X;
3260 bnXRecycled = sal_True; // we're using a mnX which was already mirrored in RTL case
3263 if ( nWidth < 0 )
3264 nWidth = 0;
3265 if ( nWidth != mnOutWidth )
3267 mnOutWidth = nWidth;
3268 bNewSize = sal_True;
3269 bCopyBits = sal_False;
3272 if ( nFlags & WINDOW_POSSIZE_HEIGHT )
3274 if ( nHeight < 0 )
3275 nHeight = 0;
3276 if ( nHeight != mnOutHeight )
3278 mnOutHeight = nHeight;
3279 bNewSize = sal_True;
3280 bCopyBits = sal_False;
3284 if ( nFlags & WINDOW_POSSIZE_X )
3286 long nOrgX = nX;
3287 // --- RTL --- (compare the screen coordinates)
3288 Point aPtDev( Point( nX+mnOutOffX, 0 ) );
3289 if( ImplHasMirroredGraphics() )
3291 mpGraphics->mirror( aPtDev.X(), this );
3293 // #106948# always mirror our pos if our parent is not mirroring, even
3294 // if we are also not mirroring
3295 // --- RTL --- check if parent is in different coordinates
3296 if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
3298 // --- RTL --- (re-mirror at parent window)
3299 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
3301 /* #i99166# An LTR window in RTL UI that gets sized only would be
3302 expected to not moved its upper left point
3304 if( bnXRecycled )
3306 if( ImplIsAntiparallel() )
3308 aPtDev.X() = mpWindowImpl->mnAbsScreenX;
3309 nOrgX = mpWindowImpl->maPos.X();
3313 else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
3315 // mirrored window in LTR UI
3317 // --- RTL --- (re-mirror at parent window)
3318 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
3322 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
3323 if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
3325 if ( bCopyBits && !pOverlapRegion )
3327 pOverlapRegion = new Region();
3328 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
3329 Size( mnOutWidth, mnOutHeight ) ),
3330 *pOverlapRegion, sal_False, sal_True, sal_True );
3332 mpWindowImpl->mnX = nX;
3333 mpWindowImpl->maPos.X() = nOrgX;
3334 mpWindowImpl->mnAbsScreenX = aPtDev.X(); // --- RTL --- (store real screen pos)
3335 bNewPos = sal_True;
3338 if ( nFlags & WINDOW_POSSIZE_Y )
3340 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
3341 if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
3343 if ( bCopyBits && !pOverlapRegion )
3345 pOverlapRegion = new Region();
3346 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
3347 Size( mnOutWidth, mnOutHeight ) ),
3348 *pOverlapRegion, sal_False, sal_True, sal_True );
3350 mpWindowImpl->mnY = nY;
3351 mpWindowImpl->maPos.Y() = nY;
3352 bNewPos = sal_True;
3356 if ( bNewPos || bNewSize )
3358 sal_Bool bUpdateSysObjPos = sal_False;
3359 if ( bNewPos )
3360 bUpdateSysObjPos = ImplUpdatePos();
3362 // the borderwindow always specifies the position for its client window
3363 if ( mpWindowImpl->mpBorderWindow )
3364 mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
3366 if ( mpWindowImpl->mpClientWindow )
3368 mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
3369 mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
3370 mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
3371 mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder,
3372 WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y |
3373 WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
3374 // Wenn wir ein ClientWindow haben, dann hat dieses fuer die
3375 // Applikation auch die Position des FloatingWindows
3376 mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
3377 if ( bNewPos )
3379 if ( mpWindowImpl->mpClientWindow->IsVisible() )
3381 mpWindowImpl->mpClientWindow->ImplCallMove();
3383 else
3385 mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = sal_True;
3390 // Move()/Resize() will be called only for Show(), such that
3391 // at least one is called before Show()
3392 if ( IsVisible() )
3394 if ( bNewPos )
3396 ImplCallMove();
3398 if ( bNewSize )
3400 ImplCallResize();
3403 else
3405 if ( bNewPos )
3406 mpWindowImpl->mbCallMove = sal_True;
3407 if ( bNewSize )
3408 mpWindowImpl->mbCallResize = sal_True;
3411 sal_Bool bUpdateSysObjClip = sal_False;
3412 if ( IsReallyVisible() )
3414 if ( bNewPos || bNewSize )
3416 // reset background storage
3417 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
3418 ImplDeleteOverlapBackground();
3419 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3420 ImplInvalidateAllOverlapBackgrounds();
3421 // set Clip-Flag
3422 bUpdateSysObjClip = !ImplSetClipFlag( sal_True );
3425 // invalidate window content ?
3426 if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
3428 if ( bNewPos )
3430 sal_Bool bInvalidate = sal_False;
3431 sal_Bool bParentPaint = sal_True;
3432 if ( !ImplIsOverlapWindow() )
3433 bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
3434 if ( bCopyBits && bParentPaint && !HasPaintEvent() )
3436 Point aPoint( mnOutOffX, mnOutOffY );
3437 Region aRegion( Rectangle( aPoint,
3438 Size( mnOutWidth, mnOutHeight ) ) );
3439 if ( mpWindowImpl->mbWinRegion )
3440 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3441 ImplClipBoundaries( aRegion, sal_False, sal_True );
3442 if ( !pOverlapRegion->IsEmpty() )
3444 pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY );
3445 aRegion.Exclude( *pOverlapRegion );
3447 if ( !aRegion.IsEmpty() )
3449 // adapt Paint areas
3450 ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX, nOldOutOffY ),
3451 Size( nOldOutWidth, nOldOutHeight ) ),
3452 mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY,
3453 sal_True );
3454 SalGraphics* pGraphics = ImplGetFrameGraphics();
3455 if ( pGraphics )
3457 const bool bSelectClipRegion = ImplSelectClipRegion( aRegion, pGraphics );
3458 if ( bSelectClipRegion )
3460 pGraphics->CopyArea( mnOutOffX, mnOutOffY,
3461 nOldOutOffX, nOldOutOffY,
3462 nOldOutWidth, nOldOutHeight,
3463 SAL_COPYAREA_WINDOWINVALIDATE, this );
3465 else
3466 bInvalidate = sal_True;
3468 else
3469 bInvalidate = sal_True;
3470 if ( !bInvalidate )
3472 if ( !pOverlapRegion->IsEmpty() )
3473 ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN );
3476 else
3477 bInvalidate = sal_True;
3479 else
3480 bInvalidate = sal_True;
3481 if ( bInvalidate )
3482 ImplInvalidateFrameRegion( NULL, INVALIDATE_CHILDREN );
3484 else
3486 Point aPoint( mnOutOffX, mnOutOffY );
3487 Region aRegion( Rectangle( aPoint,
3488 Size( mnOutWidth, mnOutHeight ) ) );
3489 aRegion.Exclude( *pOldRegion );
3490 if ( mpWindowImpl->mbWinRegion )
3491 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3492 ImplClipBoundaries( aRegion, sal_False, sal_True );
3493 if ( !aRegion.IsEmpty() )
3494 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
3498 // invalidate Parent or Overlaps
3499 if ( bNewPos ||
3500 (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) )
3502 Region aRegion( *pOldRegion );
3503 if ( !mpWindowImpl->mbPaintTransparent )
3504 ImplExcludeWindowRegion( aRegion );
3505 ImplClipBoundaries( aRegion, sal_False, sal_True );
3506 if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
3507 ImplInvalidateParentFrameRegion( aRegion );
3511 // adapt system objects
3512 if ( bUpdateSysObjClip )
3513 ImplUpdateSysObjClip();
3514 if ( bUpdateSysObjPos )
3515 ImplUpdateSysObjPos();
3516 if ( bNewSize && mpWindowImpl->mpSysObj )
3517 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3520 delete pOverlapRegion;
3521 delete pOldRegion;
3524 // -----------------------------------------------------------------------
3526 void Window::ImplToBottomChild()
3528 if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) )
3530 // put the window to the end of the list
3531 if ( mpWindowImpl->mpPrev )
3532 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
3533 else
3534 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
3535 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
3536 mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
3537 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
3538 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
3539 mpWindowImpl->mpNext = NULL;
3543 // -----------------------------------------------------------------------
3545 void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
3547 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
3549 if ( !mpWindowImpl->mbFrame )
3551 if ( IsReallyVisible() )
3553 // calculate region, where the window overlaps with other windows
3554 Point aPoint( mnOutOffX, mnOutOffY );
3555 Region aRegion( Rectangle( aPoint,
3556 Size( mnOutWidth, mnOutHeight ) ) );
3557 Region aInvalidateRegion;
3558 ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
3560 if ( !aInvalidateRegion.IsEmpty() )
3562 ImplCalcToTopData* pData = new ImplCalcToTopData;
3563 pPrevData->mpNext = pData;
3564 pData->mpNext = NULL;
3565 pData->mpWindow = this;
3566 pData->mpInvalidateRegion = new Region( aInvalidateRegion );
3572 // -----------------------------------------------------------------------
3574 void Window::ImplToTop( sal_uInt16 nFlags )
3576 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
3578 if ( mpWindowImpl->mbFrame )
3580 // on a mouse click in the external window, it is the latter's
3581 // responsibility to assure our frame is put in front
3582 if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
3583 !mpWindowImpl->mpFrameData->mbSysObjFocus &&
3584 !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
3585 !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
3587 // do not bring floating windows on the client to top
3588 if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
3590 sal_uInt16 nSysFlags = 0;
3591 if ( nFlags & TOTOP_RESTOREWHENMIN )
3592 nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN;
3593 if ( nFlags & TOTOP_FOREGROUNDTASK )
3594 nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK;
3595 if ( nFlags & TOTOP_GRABFOCUSONLY )
3596 nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY;
3597 mpWindowImpl->mpFrame->ToTop( nSysFlags );
3601 else
3603 if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this )
3605 // remove window from the list
3606 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
3607 if ( mpWindowImpl->mpNext )
3608 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
3609 else
3610 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
3612 // take AlwaysOnTop into account
3613 sal_Bool bOnTop = IsAlwaysOnTopEnabled();
3614 Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
3615 if ( !bOnTop )
3617 while ( pNextWin )
3619 if ( !pNextWin->IsAlwaysOnTopEnabled() )
3620 break;
3621 pNextWin = pNextWin->mpWindowImpl->mpNext;
3625 // check TopLevel
3626 sal_uInt8 nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel;
3627 while ( pNextWin )
3629 if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) ||
3630 (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) )
3631 break;
3632 pNextWin = pNextWin->mpWindowImpl->mpNext;
3635 // add the window to the list again
3636 mpWindowImpl->mpNext = pNextWin;
3637 if ( pNextWin )
3639 mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
3640 pNextWin->mpWindowImpl->mpPrev = this;
3642 else
3644 mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
3645 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
3647 if ( mpWindowImpl->mpPrev )
3648 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
3649 else
3650 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
3652 // recalculate ClipRegion of this and all overlapping windows
3653 if ( IsReallyVisible() )
3655 // reset background storage
3656 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3657 ImplInvalidateAllOverlapBackgrounds();
3658 mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
3664 // -----------------------------------------------------------------------
3666 void Window::ImplStartToTop( sal_uInt16 nFlags )
3668 ImplCalcToTopData aStartData;
3669 ImplCalcToTopData* pCurData;
3670 ImplCalcToTopData* pNextData;
3671 Window* pOverlapWindow;
3672 if ( ImplIsOverlapWindow() )
3673 pOverlapWindow = this;
3674 else
3675 pOverlapWindow = mpWindowImpl->mpOverlapWindow;
3677 // first calculate paint areas
3678 Window* pTempOverlapWindow = pOverlapWindow;
3679 aStartData.mpNext = NULL;
3680 pCurData = &aStartData;
3683 pTempOverlapWindow->ImplCalcToTop( pCurData );
3684 if ( pCurData->mpNext )
3685 pCurData = pCurData->mpNext;
3686 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
3688 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
3689 // next calculate the paint areas of the ChildOverlap windows
3690 pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
3691 while ( pTempOverlapWindow )
3693 pTempOverlapWindow->ImplCalcToTop( pCurData );
3694 if ( pCurData->mpNext )
3695 pCurData = pCurData->mpNext;
3696 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
3699 // and next change the windows list
3700 pTempOverlapWindow = pOverlapWindow;
3703 pTempOverlapWindow->ImplToTop( nFlags );
3704 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
3706 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
3707 // as last step invalidate the invalid areas
3708 pCurData = aStartData.mpNext;
3709 while ( pCurData )
3711 pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN );
3712 pNextData = pCurData->mpNext;
3713 delete pCurData->mpInvalidateRegion;
3714 delete pCurData;
3715 pCurData = pNextData;
3719 // -----------------------------------------------------------------------
3721 void Window::ImplFocusToTop( sal_uInt16 nFlags, sal_Bool bReallyVisible )
3723 // do we need to fetch the focus?
3724 if ( !(nFlags & TOTOP_NOGRABFOCUS) )
3726 // first window with GrabFocus-Activate gets the focus
3727 Window* pFocusWindow = this;
3728 while ( !pFocusWindow->ImplIsOverlapWindow() )
3730 // if the window has no BorderWindow, we
3731 // should always find the belonging BorderWindow
3732 if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
3734 if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS )
3735 break;
3737 pFocusWindow = pFocusWindow->ImplGetParent();
3739 if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) &&
3740 !pFocusWindow->HasChildPathFocus( sal_True ) )
3741 pFocusWindow->GrabFocus();
3744 if ( bReallyVisible )
3745 ImplGenerateMouseMove();
3748 // -----------------------------------------------------------------------
3750 void Window::ImplShowAllOverlaps()
3752 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3753 while ( pOverlapWindow )
3755 if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
3757 pOverlapWindow->Show( true, SHOW_NOACTIVATE );
3758 pOverlapWindow->mpWindowImpl->mbOverlapVisible = sal_False;
3761 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3765 // -----------------------------------------------------------------------
3767 void Window::ImplHideAllOverlaps()
3769 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3770 while ( pOverlapWindow )
3772 if ( pOverlapWindow->IsVisible() )
3774 pOverlapWindow->mpWindowImpl->mbOverlapVisible = sal_True;
3775 pOverlapWindow->Show( false );
3778 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3782 // -----------------------------------------------------------------------
3784 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, sal_Bool bModChanged )
3786 if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible )
3788 sal_uLong nTime = Time::GetSystemTicks();
3789 long nX = mpWindowImpl->mpFrameData->mnLastMouseX;
3790 long nY = mpWindowImpl->mpFrameData->mnLastMouseY;
3791 sal_uInt16 nCode = nMouseCode;
3792 sal_uInt16 nMode = mpWindowImpl->mpFrameData->mnMouseMode;
3793 sal_Bool bLeave;
3794 // check for MouseLeave
3795 if ( ((nX < 0) || (nY < 0) ||
3796 (nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) ||
3797 (nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) &&
3798 !ImplGetSVData()->maWinData.mpCaptureWin )
3799 bLeave = sal_True;
3800 else
3801 bLeave = sal_False;
3802 nMode |= MOUSE_SYNTHETIC;
3803 if ( bModChanged )
3804 nMode |= MOUSE_MODIFIERCHANGED;
3805 ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
3809 // -----------------------------------------------------------------------
3811 void Window::ImplGenerateMouseMove()
3813 if ( !mpWindowImpl->mpFrameData->mnMouseMoveId )
3814 Application::PostUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId, LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) );
3817 // -----------------------------------------------------------------------
3819 IMPL_LINK_NOARG(Window, ImplGenerateMouseMoveHdl)
3821 mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
3822 Window* pCaptureWin = ImplGetSVData()->maWinData.mpCaptureWin;
3823 if( ! pCaptureWin ||
3824 (pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame)
3827 ImplCallMouseMove( mpWindowImpl->mpFrameData->mnMouseCode );
3829 return 0;
3832 // -----------------------------------------------------------------------
3834 void Window::ImplInvertFocus( const Rectangle& rRect )
3836 InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
3839 // -----------------------------------------------------------------------
3841 void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow,
3842 Window* pOldOverlapWindow )
3844 ImplSVData* pSVData = ImplGetSVData();
3845 Window* pNewRealWindow;
3846 Window* pOldRealWindow;
3847 Window* pLastRealWindow;
3848 sal_Bool bCallActivate = sal_True;
3849 sal_Bool bCallDeactivate = sal_True;
3851 pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
3852 pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
3853 if ( (pOldRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
3854 pOldRealWindow->GetActivateMode() )
3856 if ( (pNewRealWindow->GetType() == WINDOW_FLOATINGWINDOW) &&
3857 !pNewRealWindow->GetActivateMode() )
3859 pSVData->maWinData.mpLastDeacWin = pOldOverlapWindow;
3860 bCallDeactivate = sal_False;
3863 else if ( (pNewRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
3864 pNewRealWindow->GetActivateMode() )
3866 if ( pSVData->maWinData.mpLastDeacWin )
3868 if ( pSVData->maWinData.mpLastDeacWin == pNewOverlapWindow )
3869 bCallActivate = sal_False;
3870 else
3872 pLastRealWindow = pSVData->maWinData.mpLastDeacWin->ImplGetWindow();
3873 pSVData->maWinData.mpLastDeacWin->mpWindowImpl->mbActive = sal_False;
3874 pSVData->maWinData.mpLastDeacWin->Deactivate();
3875 if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin )
3877 pLastRealWindow->mpWindowImpl->mbActive = sal_True;
3878 pLastRealWindow->Activate();
3881 pSVData->maWinData.mpLastDeacWin = NULL;
3885 if ( bCallDeactivate )
3887 if( pOldOverlapWindow->mpWindowImpl->mbActive )
3889 pOldOverlapWindow->mpWindowImpl->mbActive = sal_False;
3890 pOldOverlapWindow->Deactivate();
3892 if ( pOldRealWindow != pOldOverlapWindow )
3894 if( pOldRealWindow->mpWindowImpl->mbActive )
3896 pOldRealWindow->mpWindowImpl->mbActive = sal_False;
3897 pOldRealWindow->Deactivate();
3901 if ( bCallActivate && ! pNewOverlapWindow->mpWindowImpl->mbActive )
3903 if( ! pNewOverlapWindow->mpWindowImpl->mbActive )
3905 pNewOverlapWindow->mpWindowImpl->mbActive = sal_True;
3906 pNewOverlapWindow->Activate();
3908 if ( pNewRealWindow != pNewOverlapWindow )
3910 if( ! pNewRealWindow->mpWindowImpl->mbActive )
3912 pNewRealWindow->mpWindowImpl->mbActive = sal_True;
3913 pNewRealWindow->Activate();
3919 static bool IsWindowFocused(const WindowImpl& rWinImpl)
3921 if (rWinImpl.mpSysObj)
3922 return true;
3924 if (rWinImpl.mpFrameData->mbHasFocus)
3925 return true;
3927 if (rWinImpl.mbFakeFocusSet)
3928 return true;
3930 return false;
3933 // -----------------------------------------------------------------------
3934 void Window::ImplGrabFocus( sal_uInt16 nFlags )
3936 // #143570# no focus for destructing windows
3937 if( mpWindowImpl->mbInDtor )
3938 return;
3940 // some event listeners do really bad stuff
3941 // => prepare for the worst
3942 ImplDelData aDogTag( this );
3944 // Currently the client window should always get the focus
3945 // Should the border window at some point be focusable
3946 // we need to change all GrabFocus() instances in VCL,
3947 // e.g. in ToTop()
3949 if ( mpWindowImpl->mpClientWindow )
3951 // For a lack of design we need a little hack here to
3952 // ensure that dialogs on close pass the focus back to
3953 // the correct window
3954 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
3955 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
3956 mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
3957 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
3958 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
3960 mpWindowImpl->mpLastFocusWindow->GrabFocus();
3961 else
3962 mpWindowImpl->mpClientWindow->GrabFocus();
3963 return;
3965 else if ( mpWindowImpl->mbFrame )
3967 // For a lack of design we need a little hack here to
3968 // ensure that dialogs on close pass the focus back to
3969 // the correct window
3970 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
3971 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
3972 mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
3973 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
3974 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
3977 mpWindowImpl->mpLastFocusWindow->GrabFocus();
3978 return;
3982 // If the Window is disabled, then we don't change the focus
3983 if ( !IsEnabled() || !IsInputEnabled() || IsInModalNonRefMode() )
3984 return;
3986 // we only need to set the focus if it is not already set
3987 // note: if some other frame is waiting for an asynchrounous focus event
3988 // we also have to post an asynchronous focus event for this frame
3989 // which is done using ToTop
3990 ImplSVData* pSVData = ImplGetSVData();
3992 sal_Bool bAsyncFocusWaiting = sal_False;
3993 Window *pFrame = pSVData->maWinData.mpFirstFrame;
3994 while( pFrame )
3996 if( pFrame != mpWindowImpl->mpFrameWindow && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
3998 bAsyncFocusWaiting = sal_True;
3999 break;
4001 pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
4004 bool bHasFocus = IsWindowFocused(*mpWindowImpl);
4006 sal_Bool bMustNotGrabFocus = sal_False;
4007 // #100242#, check parent hierarchy if some floater prohibits grab focus
4009 Window *pParent = this;
4010 while( pParent )
4012 // #102158#, ignore grabfocus only if the floating parent grabs keyboard focus by itself (GrabsFocus())
4013 // otherwise we cannot set the focus in a floating toolbox
4014 if( ( (pParent->mpWindowImpl->mbFloatWin && ((FloatingWindow*)pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) )
4016 bMustNotGrabFocus = sal_True;
4017 break;
4019 pParent = pParent->mpWindowImpl->mpParent;
4023 if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
4025 // EndExtTextInput if it is not the same window
4026 if ( pSVData->maWinData.mpExtTextInputWin &&
4027 (pSVData->maWinData.mpExtTextInputWin != this) )
4028 pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
4030 // mark this windows as the last FocusWindow
4031 Window* pOverlapWindow = ImplGetFirstOverlapWindow();
4032 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
4033 mpWindowImpl->mpFrameData->mpFocusWin = this;
4035 if( !bHasFocus )
4037 // menu windows never get the system focus
4038 // the application will keep the focus
4039 if( bMustNotGrabFocus )
4040 return;
4041 else
4043 // here we already switch focus as ToTop()
4044 // should not give focus to another window
4045 //DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
4046 mpWindowImpl->mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS | SAL_FRAME_TOTOP_GRABFOCUS_ONLY );
4047 return;
4051 Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin;
4052 ImplDelData aOldFocusDel( pOldFocusWindow );
4054 pSVData->maWinData.mpFocusWin = this;
4056 if ( pOldFocusWindow )
4058 // Cursor hidden
4059 if ( pOldFocusWindow->mpWindowImpl->mpCursor )
4060 pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide( true );
4063 // !!!!! due to old SV-Office Activate/Deactivate handling
4064 // !!!!! first as before
4065 if ( pOldFocusWindow )
4067 // remember Focus
4068 Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
4069 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
4070 if ( pOldOverlapWindow != pNewOverlapWindow )
4071 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
4073 else
4075 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
4076 Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
4077 pNewOverlapWindow->mpWindowImpl->mbActive = sal_True;
4078 pNewOverlapWindow->Activate();
4079 if ( pNewRealWindow != pNewOverlapWindow )
4081 pNewRealWindow->mpWindowImpl->mbActive = sal_True;
4082 pNewRealWindow->Activate();
4086 // call Get- and LoseFocus
4087 if ( pOldFocusWindow && ! aOldFocusDel.IsDead() )
4089 if ( pOldFocusWindow->IsTracking() &&
4090 (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) )
4091 pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS );
4092 NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow );
4093 if ( !ImplCallPreNotify( aNEvt ) )
4094 pOldFocusWindow->LoseFocus();
4095 pOldFocusWindow->ImplCallDeactivateListeners( this );
4098 if ( pSVData->maWinData.mpFocusWin == this )
4100 if ( mpWindowImpl->mpSysObj )
4102 mpWindowImpl->mpFrameData->mpFocusWin = this;
4103 if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
4104 mpWindowImpl->mpSysObj->GrabFocus();
4107 if ( pSVData->maWinData.mpFocusWin == this )
4109 if ( mpWindowImpl->mpCursor )
4110 mpWindowImpl->mpCursor->ImplShow();
4111 mpWindowImpl->mbInFocusHdl = sal_True;
4112 mpWindowImpl->mnGetFocusFlags = nFlags;
4113 // if we're changing focus due to closing a popup floating window
4114 // notify the new focus window so it can restore the inner focus
4115 // eg, toolboxes can select their recent active item
4116 if( pOldFocusWindow &&
4117 ! aOldFocusDel.IsDead() &&
4118 ( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) )
4119 mpWindowImpl->mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL;
4120 NotifyEvent aNEvt( EVENT_GETFOCUS, this );
4121 if ( !ImplCallPreNotify( aNEvt ) && !aDogTag.IsDead() )
4122 GetFocus();
4123 if( !aDogTag.IsDead() )
4124 ImplCallActivateListeners( (pOldFocusWindow && ! aOldFocusDel.IsDead()) ? pOldFocusWindow : NULL );
4125 if( !aDogTag.IsDead() )
4127 mpWindowImpl->mnGetFocusFlags = 0;
4128 mpWindowImpl->mbInFocusHdl = sal_False;
4133 GetpApp()->FocusChanged();
4134 ImplNewInputContext();
4138 // -----------------------------------------------------------------------
4140 void Window::ImplNewInputContext()
4142 ImplSVData* pSVData = ImplGetSVData();
4143 Window* pFocusWin = pSVData->maWinData.mpFocusWin;
4144 if ( !pFocusWin )
4145 return;
4147 // Is InputContext changed?
4148 const InputContext& rInputContext = pFocusWin->GetInputContext();
4149 if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
4150 return;
4152 pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;
4154 SalInputContext aNewContext;
4155 const Font& rFont = rInputContext.GetFont();
4156 const XubString& rFontName = rFont.GetName();
4157 ImplFontEntry* pFontEntry = NULL;
4158 aNewContext.mpFont = NULL;
4159 if ( rFontName.Len() )
4161 Size aSize = pFocusWin->ImplLogicToDevicePixel( rFont.GetSize() );
4162 if ( !aSize.Height() )
4164 // only set default sizes if the font height in logical
4165 // coordinates equals 0
4166 if ( rFont.GetSize().Height() )
4167 aSize.Height() = 1;
4168 else
4169 aSize.Height() = (12*pFocusWin->mnDPIY)/72;
4171 // TODO: No display device uses ImplDirectFontSubstitution thingy, right? => remove it
4172 ImplDirectFontSubstitution* pFontSubst = NULL;
4173 //if( pFocusWin->mpOutDevData )
4174 // pFontSubst = &pFocusWin->mpOutDevData->maDevFontSubst;
4175 pFontEntry = pFocusWin->mpFontCache->GetFontEntry( pFocusWin->mpFontList,
4176 rFont, aSize, static_cast<float>(aSize.Height()), pFontSubst );
4177 if ( pFontEntry )
4178 aNewContext.mpFont = &pFontEntry->maFontSelData;
4180 aNewContext.meLanguage = rFont.GetLanguage();
4181 aNewContext.mnOptions = rInputContext.GetOptions();
4182 pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
4184 if ( pFontEntry )
4185 pFocusWin->mpFontCache->Release( pFontEntry );
4188 // -----------------------------------------------------------------------
4190 Window::Window( WindowType nType )
4192 DBG_CTOR( Window, ImplDbgCheckWindow );
4194 ImplInitWindowData( nType );
4197 // -----------------------------------------------------------------------
4199 Window::Window( Window* pParent, WinBits nStyle )
4201 DBG_CTOR( Window, ImplDbgCheckWindow );
4203 ImplInitWindowData( WINDOW_WINDOW );
4204 ImplInit( pParent, nStyle, NULL );
4207 // -----------------------------------------------------------------------
4209 Window::Window( Window* pParent, const ResId& rResId )
4210 : mpWindowImpl(NULL)
4212 DBG_CTOR( Window, ImplDbgCheckWindow );
4214 rResId.SetRT( RSC_WINDOW );
4215 WinBits nStyle = ImplInitRes( rResId );
4216 ImplInitWindowData( WINDOW_WINDOW );
4217 ImplInit( pParent, nStyle, NULL );
4218 ImplLoadRes( rResId );
4220 if ( !(nStyle & WB_HIDE) )
4221 Show();
4224 // -----------------------------------------------------------------------
4225 #if OSL_DEBUG_LEVEL > 0
4226 namespace
4228 OString lcl_createWindowInfo(const Window& i_rWindow)
4230 // skip border windows, they don't carry information which helps diagnosing the problem
4231 const Window* pWindow( &i_rWindow );
4232 while ( pWindow && ( pWindow->GetType() == WINDOW_BORDERWINDOW ) )
4233 pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD );
4234 if ( !pWindow )
4235 pWindow = &i_rWindow;
4237 OStringBuffer aErrorString;
4238 aErrorString.append(' ');
4239 aErrorString.append(typeid( *pWindow ).name());
4240 aErrorString.append(" (");
4241 aErrorString.append(OUStringToOString(pWindow->GetText(), RTL_TEXTENCODING_UTF8));
4242 aErrorString.append(")");
4243 return aErrorString.makeStringAndClear();
4246 #endif
4247 // -----------------------------------------------------------------------
4249 Window::~Window()
4251 vcl::LazyDeletor<Window>::Undelete( this );
4253 DBG_DTOR( Window, ImplDbgCheckWindow );
4254 DBG_ASSERT( !mpWindowImpl->mbInDtor, "~Window - already in DTOR!" );
4257 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
4258 Application::RemoveMouseAndKeyEvents( this );
4260 // Dispose of the canvas implementation (which, currently, has an
4261 // own wrapper window as a child to this one.
4262 uno::Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
4263 if( xCanvas.is() )
4265 uno::Reference < lang::XComponent > xCanvasComponent( xCanvas,
4266 uno::UNO_QUERY );
4267 if( xCanvasComponent.is() )
4268 xCanvasComponent->dispose();
4271 mpWindowImpl->mbInDtor = sal_True;
4273 ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
4275 // do not send child events for frames that were registered as native frames
4276 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible )
4277 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
4278 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED, this );
4280 // remove associated data structures from dockingmanager
4281 ImplGetDockingManager()->RemoveWindow( this );
4284 // remove ownerdraw decorated windows from list in the top-most frame window
4285 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
4287 ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
4288 ::std::vector< Window* >::iterator p;
4289 p = ::std::find( rList.begin(), rList.end(), this );
4290 if( p != rList.end() )
4291 rList.erase( p );
4294 // shutdown drag and drop
4295 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY );
4297 if( xDnDComponent.is() )
4298 xDnDComponent->dispose();
4300 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
4304 // deregister drop target listener
4305 if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
4307 uno::Reference< XDragGestureRecognizer > xDragGestureRecognizer =
4308 uno::Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
4309 if( xDragGestureRecognizer.is() )
4311 xDragGestureRecognizer->removeDragGestureListener(
4312 uno::Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
4315 mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
4316 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
4319 // shutdown drag and drop for this frame window
4320 uno::Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );
4322 // DNDEventDispatcher does not hold a reference of the DropTarget,
4323 // so it's ok if it does not support XComponent
4324 if( xComponent.is() )
4325 xComponent->dispose();
4327 catch (const Exception&)
4329 // can be safely ignored here.
4333 UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False );
4334 if ( pWrapper )
4335 pWrapper->WindowDestroyed( this );
4337 // MT: Must be called after WindowDestroyed!
4338 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
4339 // But accessibility implementations from applications need this dispose.
4340 if ( mpWindowImpl->mxAccessible.is() )
4342 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xC( mpWindowImpl->mxAccessible, ::com::sun::star::uno::UNO_QUERY );
4343 if ( xC.is() )
4344 xC->dispose();
4347 ImplSVData* pSVData = ImplGetSVData();
4349 if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) )
4350 ImplDestroyHelpWindow( true );
4352 DBG_ASSERT( pSVData->maWinData.mpTrackWin != this,
4353 "Window::~Window(): Window is in TrackingMode" );
4354 DBG_ASSERT( pSVData->maWinData.mpCaptureWin != this,
4355 "Window::~Window(): Window has the mouse captured" );
4356 // #103442# DefModalDialogParent is now determined on-the-fly, so this pointer is unimportant now
4357 //DBG_ASSERT( pSVData->maWinData.mpDefDialogParent != this,
4358 // "Window::~Window(): Window is DefModalDialogParent" );
4360 // due to old compatibility
4361 if ( pSVData->maWinData.mpTrackWin == this )
4362 EndTracking();
4363 if ( pSVData->maWinData.mpCaptureWin == this )
4364 ReleaseMouse();
4365 if ( pSVData->maWinData.mpDefDialogParent == this )
4366 pSVData->maWinData.mpDefDialogParent = NULL;
4368 #if OSL_DEBUG_LEVEL > 0
4369 if ( sal_True ) // always perform these tests in non-pro versions
4371 OStringBuffer aErrorStr;
4372 sal_Bool bError = sal_False;
4373 Window* pTempWin;
4374 if (mpWindowImpl->mpFrameData != 0)
4376 pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
4377 while ( pTempWin )
4379 if ( ImplIsRealParentPath( pTempWin ) )
4381 bError = sal_True;
4382 aErrorStr.append(lcl_createWindowInfo(*pTempWin));
4384 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
4386 if ( bError )
4388 OStringBuffer aTempStr;
4389 aTempStr.append("Window (");
4390 aTempStr.append(OUStringToOString(GetText(),
4391 RTL_TEXTENCODING_UTF8));
4392 aTempStr.append(") with live SystemWindows destroyed: ");
4393 aTempStr.append(aErrorStr.toString());
4394 OSL_FAIL(aTempStr.getStr());
4395 // abort in non-pro version, this must be fixed!
4396 GetpApp()->Abort(OStringToOUString(
4397 aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8));
4401 bError = sal_False;
4402 pTempWin = pSVData->maWinData.mpFirstFrame;
4403 while ( pTempWin )
4405 if ( ImplIsRealParentPath( pTempWin ) )
4407 bError = sal_True;
4408 aErrorStr.append(lcl_createWindowInfo(*pTempWin));
4410 pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame;
4412 if ( bError )
4414 OStringBuffer aTempStr( "Window (" );
4415 aTempStr.append(OUStringToOString(GetText(), RTL_TEXTENCODING_UTF8));
4416 aTempStr.append(") with live SystemWindows destroyed: ");
4417 aTempStr.append(aErrorStr.toString());
4418 OSL_FAIL( aTempStr.getStr() );
4419 GetpApp()->Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8)); // abort in non-pro version, this must be fixed!
4422 if ( mpWindowImpl->mpFirstChild )
4424 OStringBuffer aTempStr("Window (");
4425 aTempStr.append(OUStringToOString(GetText(), RTL_TEXTENCODING_UTF8));
4426 aTempStr.append(") with live children destroyed: ");
4427 pTempWin = mpWindowImpl->mpFirstChild;
4428 while ( pTempWin )
4430 aTempStr.append(lcl_createWindowInfo(*pTempWin));
4431 pTempWin = pTempWin->mpWindowImpl->mpNext;
4433 OSL_FAIL( aTempStr.getStr() );
4434 GetpApp()->Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8)); // abort in non-pro version, this must be fixed!
4437 if ( mpWindowImpl->mpFirstOverlap )
4439 OStringBuffer aTempStr("Window (");
4440 aTempStr.append(OUStringToOString(GetText(), RTL_TEXTENCODING_UTF8));
4441 aTempStr.append(") with live SystemWindows destroyed: ");
4442 pTempWin = mpWindowImpl->mpFirstOverlap;
4443 while ( pTempWin )
4445 aTempStr.append(lcl_createWindowInfo(*pTempWin));
4446 pTempWin = pTempWin->mpWindowImpl->mpNext;
4448 OSL_FAIL( aTempStr.getStr() );
4449 GetpApp()->Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8)); // abort in non-pro version, this must be fixed!
4452 Window* pMyParent = this;
4453 SystemWindow* pMySysWin = NULL;
4455 while ( pMyParent )
4457 if ( pMyParent->IsSystemWindow() )
4458 pMySysWin = (SystemWindow*)pMyParent;
4459 pMyParent = pMyParent->GetParent();
4461 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
4463 OStringBuffer aTempStr("Window (");
4464 aTempStr.append(OUStringToOString(GetText(), RTL_TEXTENCODING_UTF8));
4465 aTempStr.append(") still in TaskPanelList!");
4466 OSL_FAIL( aTempStr.getStr() );
4467 GetpApp()->Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8)); // abort in non-pro version, this must be fixed!
4470 #endif
4472 if( mpWindowImpl->mbIsInTaskPaneList )
4474 Window* pMyParent = this;
4475 SystemWindow* pMySysWin = NULL;
4477 while ( pMyParent )
4479 if ( pMyParent->IsSystemWindow() )
4480 pMySysWin = (SystemWindow*)pMyParent;
4481 pMyParent = pMyParent->GetParent();
4483 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
4485 pMySysWin->GetTaskPaneList()->RemoveWindow( this );
4487 else
4489 OStringBuffer aTempStr("Window (");
4490 aTempStr.append(OUStringToOString(GetText(), RTL_TEXTENCODING_UTF8));
4491 aTempStr.append(") not found in TaskPanelList!");
4492 OSL_FAIL( aTempStr.getStr() );
4496 // remove from size-group if necessary
4497 remove_from_all_size_groups();
4499 // clear mnemonic labels
4500 std::vector<FixedText*> aMnemonicLabels(list_mnemonic_labels());
4501 for (std::vector<FixedText*>::iterator aI = aMnemonicLabels.begin();
4502 aI != aMnemonicLabels.end(); ++aI)
4504 remove_mnemonic_label(*aI);
4507 // hide window in order to trigger the Paint-Handling
4508 Hide();
4510 // announce the window is to be destroyed
4512 NotifyEvent aNEvt( EVENT_DESTROY, this );
4513 Notify( aNEvt );
4516 // EndExtTextInputMode
4517 if ( pSVData->maWinData.mpExtTextInputWin == this )
4519 EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
4520 if ( pSVData->maWinData.mpExtTextInputWin == this )
4521 pSVData->maWinData.mpExtTextInputWin = NULL;
4524 // check if the focus window is our child
4525 sal_Bool bHasFocussedChild = sal_False;
4526 if( pSVData->maWinData.mpFocusWin && ImplIsRealParentPath( pSVData->maWinData.mpFocusWin ) )
4528 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
4529 bHasFocussedChild = sal_True;
4530 #if OSL_DEBUG_LEVEL > 0
4531 OStringBuffer aTempStr("Window (");
4532 aTempStr.append(OUStringToOString(GetText(),
4533 RTL_TEXTENCODING_UTF8)).
4534 append(") with focussed child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !");
4535 OSL_FAIL( aTempStr.getStr() );
4536 GetpApp()->Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8 )); // abort in non-pro version, this must be fixed!
4537 #endif
4540 // if we get focus pass focus to another window
4541 Window* pOverlapWindow = ImplGetFirstOverlapWindow();
4542 if ( pSVData->maWinData.mpFocusWin == this
4543 || bHasFocussedChild ) // #122232#, see above, try some cleanup
4545 if ( mpWindowImpl->mbFrame )
4547 pSVData->maWinData.mpFocusWin = NULL;
4548 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4549 GetpApp()->FocusChanged();
4551 else
4553 Window* pParent = GetParent();
4554 Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
4555 // when windows overlap, give focus to the parent
4556 // of the next FrameWindow
4557 if ( pBorderWindow )
4559 if ( pBorderWindow->ImplIsOverlapWindow() )
4560 pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
4562 else if ( ImplIsOverlapWindow() )
4563 pParent = mpWindowImpl->mpOverlapWindow;
4565 if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
4566 pParent->GrabFocus();
4567 else
4568 mpWindowImpl->mpFrameWindow->GrabFocus();
4570 // If the focus was set back to 'this' set it to nothing
4571 if ( pSVData->maWinData.mpFocusWin == this )
4573 pSVData->maWinData.mpFocusWin = NULL;
4574 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4575 GetpApp()->FocusChanged();
4581 if ( pOverlapWindow != 0 &&
4582 pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
4583 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4585 // reset hint for DefModalDialogParent
4586 if( pSVData->maWinData.mpActiveApplicationFrame == this )
4587 pSVData->maWinData.mpActiveApplicationFrame = NULL;
4589 // reset marked windows
4590 if ( mpWindowImpl->mpFrameData != 0 )
4592 if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
4593 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
4594 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
4595 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
4596 if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
4597 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
4600 // reset Deactivate-Window
4601 if ( pSVData->maWinData.mpLastDeacWin == this )
4602 pSVData->maWinData.mpLastDeacWin = NULL;
4604 if ( mpWindowImpl->mbFrame )
4606 if ( mpWindowImpl->mpFrameData->mnFocusId )
4607 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
4608 if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
4609 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
4612 // release SalGraphics
4613 ImplReleaseGraphics();
4615 // notify ImplDelData subscribers of this window about the window deletion
4616 ImplDelData* pDelData = mpWindowImpl->mpFirstDel;
4617 while ( pDelData )
4619 pDelData->mbDel = sal_True;
4620 pDelData->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
4621 pDelData = pDelData->mpNext;
4624 // remove window from the lists
4625 ImplRemoveWindow( sal_True );
4627 // de-register as "top window child" at our parent, if necessary
4628 if ( mpWindowImpl->mbFrame )
4630 sal_Bool bIsTopWindow = mpWindowImpl->mpWinData && ( mpWindowImpl->mpWinData->mnIsTopWindow == 1 );
4631 if ( mpWindowImpl->mpRealParent && bIsTopWindow )
4633 ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();
4635 ::std::list< Window* >::iterator myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
4636 pParentWinData->maTopWindowChildren.end(), this );
4637 DBG_ASSERT( myPos != pParentWinData->maTopWindowChildren.end(), "Window::~Window: inconsistency in top window chain!" );
4638 if ( myPos != pParentWinData->maTopWindowChildren.end() )
4639 pParentWinData->maTopWindowChildren.erase( myPos );
4643 // cleanup Extra Window Data, TODO: add and use ImplWinData destructor
4644 if ( mpWindowImpl->mpWinData )
4646 if ( mpWindowImpl->mpWinData->mpExtOldText )
4647 delete mpWindowImpl->mpWinData->mpExtOldText;
4648 if ( mpWindowImpl->mpWinData->mpExtOldAttrAry )
4649 delete mpWindowImpl->mpWinData->mpExtOldAttrAry;
4650 if ( mpWindowImpl->mpWinData->mpCursorRect )
4651 delete mpWindowImpl->mpWinData->mpCursorRect;
4652 if ( mpWindowImpl->mpWinData->mpCompositionCharRects)
4653 delete[] mpWindowImpl->mpWinData->mpCompositionCharRects;
4654 if ( mpWindowImpl->mpWinData->mpFocusRect )
4655 delete mpWindowImpl->mpWinData->mpFocusRect;
4656 if ( mpWindowImpl->mpWinData->mpTrackRect )
4657 delete mpWindowImpl->mpWinData->mpTrackRect;
4659 delete mpWindowImpl->mpWinData;
4662 // cleanup overlap related window data
4663 if ( mpWindowImpl->mpOverlapData )
4664 delete mpWindowImpl->mpOverlapData;
4666 // remove BorderWindow or Frame window data
4667 if ( mpWindowImpl->mpBorderWindow )
4668 delete mpWindowImpl->mpBorderWindow;
4669 else if ( mpWindowImpl->mbFrame )
4671 if ( pSVData->maWinData.mpFirstFrame == this )
4672 pSVData->maWinData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
4673 else
4675 Window* pSysWin = pSVData->maWinData.mpFirstFrame;
4676 while ( pSysWin->mpWindowImpl->mpFrameData->mpNextFrame != this )
4677 pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
4678 pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
4680 mpWindowImpl->mpFrame->SetCallback( NULL, NULL );
4681 pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
4682 delete mpWindowImpl->mpFrameData;
4685 // should be the last statements
4686 delete mpWindowImpl; mpWindowImpl = NULL;
4689 // -----------------------------------------------------------------------
4690 void Window::doLazyDelete()
4692 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
4693 DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
4694 if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
4696 Show( false );
4697 SetParent( ImplGetDefaultWindow() );
4699 vcl::LazyDeletor<Window>::Delete( this );
4702 sal_uInt16 Window::GetIndicatorState() const
4704 return mpWindowImpl->mpFrame->GetIndicatorState().mnState;
4707 void Window::SimulateKeyPress( sal_uInt16 nKeyCode ) const
4709 mpWindowImpl->mpFrame->SimulateKeyPress(nKeyCode);
4712 // -----------------------------------------------------------------------
4714 void Window::MouseMove( const MouseEvent& rMEvt )
4716 { // Parentheses, as in this handler the window can be destroyed
4717 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4720 NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt );
4721 if ( !Notify( aNEvt ) )
4722 mpWindowImpl->mbMouseMove = sal_True;
4725 // -----------------------------------------------------------------------
4727 void Window::MouseButtonDown( const MouseEvent& rMEvt )
4729 { // Parentheses, as in this handler the window can be destroyed
4730 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4733 NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt );
4734 if ( !Notify( aNEvt ) )
4735 mpWindowImpl->mbMouseButtonDown = sal_True;
4738 // -----------------------------------------------------------------------
4740 void Window::MouseButtonUp( const MouseEvent& rMEvt )
4742 { // Parentheses, as in this handler the window can be destroyed
4743 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4746 NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt );
4747 if ( !Notify( aNEvt ) )
4748 mpWindowImpl->mbMouseButtonUp = sal_True;
4751 // -----------------------------------------------------------------------
4753 void Window::KeyInput( const KeyEvent& rKEvt )
4755 { // Parentheses, as in this handler the window can be destroyed
4756 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4759 NotifyEvent aNEvt( EVENT_KEYINPUT, this, &rKEvt );
4760 if ( !Notify( aNEvt ) )
4761 mpWindowImpl->mbKeyInput = sal_True;
4764 // -----------------------------------------------------------------------
4766 void Window::KeyUp( const KeyEvent& rKEvt )
4768 { // Parentheses, as in this handler the window can be destroyed
4769 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4772 NotifyEvent aNEvt( EVENT_KEYUP, this, &rKEvt );
4773 if ( !Notify( aNEvt ) )
4774 mpWindowImpl->mbKeyUp = sal_True;
4777 // -----------------------------------------------------------------------
4779 void Window::PrePaint()
4783 // -----------------------------------------------------------------------
4785 void Window::Paint( const Rectangle& rRect )
4787 { // Parentheses, as in this handler the window can be destroyed
4788 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4791 ImplCallEventListeners( VCLEVENT_WINDOW_PAINT, (void*)&rRect );
4794 // -----------------------------------------------------------------------
4796 void Window::PostPaint()
4800 // -----------------------------------------------------------------------
4802 void Window::Draw( OutputDevice*, const Point&, const Size&, sal_uLong )
4804 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4807 // -----------------------------------------------------------------------
4809 void Window::Move()
4811 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4814 // -----------------------------------------------------------------------
4816 void Window::Resize()
4818 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4821 // -----------------------------------------------------------------------
4823 void Window::Activate()
4825 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4828 // -----------------------------------------------------------------------
4830 void Window::Deactivate()
4832 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4835 // -----------------------------------------------------------------------
4837 void Window::GetFocus()
4839 { // Parentheses, as in this handler the window can be destroyed
4840 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4843 if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
4845 ImplDelData aDogtag( this );
4846 mpWindowImpl->mpLastFocusWindow->GrabFocus();
4847 if( aDogtag.IsDead() )
4848 return;
4851 NotifyEvent aNEvt( EVENT_GETFOCUS, this );
4852 Notify( aNEvt );
4855 // -----------------------------------------------------------------------
4857 void Window::LoseFocus()
4859 { // Parentheses, as in this handler the window can be destroyed
4860 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4863 NotifyEvent aNEvt( EVENT_LOSEFOCUS, this );
4864 Notify( aNEvt );
4867 // -----------------------------------------------------------------------
4869 void Window::RequestHelp( const HelpEvent& rHEvt )
4871 { // Parentheses, as in this handler the window can be destroyed
4872 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4875 // if Balloon-Help is requested, show the balloon
4876 // with help text set
4877 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
4879 const XubString* pStr = &(GetHelpText());
4880 if ( !pStr->Len() )
4881 pStr = &(GetQuickHelpText());
4882 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
4883 ImplGetParent()->RequestHelp( rHEvt );
4884 else
4885 Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), *pStr );
4887 else if ( rHEvt.GetMode() & HELPMODE_QUICK )
4889 const XubString* pStr = &(GetQuickHelpText());
4890 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
4891 ImplGetParent()->RequestHelp( rHEvt );
4892 else
4894 Point aPos = GetPosPixel();
4895 if ( ImplGetParent() && !ImplIsOverlapWindow() )
4896 aPos = ImplGetParent()->OutputToScreenPixel( aPos );
4897 Rectangle aRect( aPos, GetSizePixel() );
4898 String aHelpText;
4899 if ( pStr->Len() )
4900 aHelpText = GetHelpText();
4901 Help::ShowQuickHelp( this, aRect, *pStr, aHelpText, QUICKHELP_CTRLTEXT );
4904 else
4906 String aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
4907 if ( aStrHelpId.Len() == 0 && ImplGetParent() )
4908 ImplGetParent()->RequestHelp( rHEvt );
4909 else
4911 Help* pHelp = Application::GetHelp();
4912 if ( pHelp )
4914 if( aStrHelpId.Len() > 0 )
4915 pHelp->Start( aStrHelpId, this );
4916 else
4917 pHelp->Start( OUString( OOO_HELP_INDEX ), this );
4923 // -----------------------------------------------------------------------
4925 void Window::Command( const CommandEvent& rCEvt )
4927 { // Parentheses, as in this handler the window can be destroyed
4928 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4931 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, (void*)&rCEvt );
4933 NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt );
4934 if ( !Notify( aNEvt ) )
4935 mpWindowImpl->mbCommand = sal_True;
4938 // -----------------------------------------------------------------------
4940 void Window::Tracking( const TrackingEvent& rTEvt )
4942 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4944 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
4945 if( pWrapper )
4946 pWrapper->Tracking( rTEvt );
4949 // -----------------------------------------------------------------------
4951 void Window::UserEvent( sal_uLong, void* )
4953 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4956 // -----------------------------------------------------------------------
4958 void Window::StateChanged( StateChangedType eType )
4960 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4961 switch (eType)
4963 //stuff that doesn't invalidate the layout
4964 case STATE_CHANGE_CONTROLFOREGROUND:
4965 case STATE_CHANGE_CONTROLBACKGROUND:
4966 case STATE_CHANGE_TRANSPARENT:
4967 case STATE_CHANGE_UPDATEMODE:
4968 case STATE_CHANGE_READONLY:
4969 case STATE_CHANGE_ENABLE:
4970 case STATE_CHANGE_STATE:
4971 case STATE_CHANGE_DATA:
4972 case STATE_CHANGE_INITSHOW:
4973 case STATE_CHANGE_CONTROL_FOCUS:
4974 break;
4975 //stuff that does invalidate the layout
4976 default:
4977 queue_resize();
4978 break;
4982 // -----------------------------------------------------------------------
4984 void Window::DataChanged( const DataChangedEvent& )
4986 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4989 // -----------------------------------------------------------------------
4991 void Window::ImplNotifyKeyMouseCommandEventListeners( NotifyEvent& rNEvt )
4993 if( rNEvt.GetType() == EVENT_COMMAND )
4995 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
4996 if ( pCEvt->GetCommand() != COMMAND_CONTEXTMENU )
4997 // non context menu events are not to be notified up the chain
4998 // so we return immediately
4999 return;
5001 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5003 if ( rNEvt.GetWindow() == this )
5004 // not interested in: The event listeners are already called in ::Command,
5005 // and calling them here a second time doesn't make sense
5007 else
5009 CommandEvent aCommandEvent = ImplTranslateCommandEvent( *pCEvt, rNEvt.GetWindow(), this );
5010 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, &aCommandEvent );
5015 // #82968# notify event listeners for mouse and key events separately and
5016 // not in PreNotify ( as for focus listeners )
5017 // this allows for procesing those events internally first and pass it to
5018 // the toolkit later
5020 ImplDelData aDelData;
5021 ImplAddDel( &aDelData );
5023 if( rNEvt.GetType() == EVENT_MOUSEMOVE )
5025 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5027 if ( rNEvt.GetWindow() == this )
5028 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
5029 else
5031 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5032 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &aMouseEvent );
5036 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
5038 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5040 if ( rNEvt.GetWindow() == this )
5041 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
5042 else
5044 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5045 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &aMouseEvent );
5049 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5051 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5053 if ( rNEvt.GetWindow() == this )
5054 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
5055 else
5057 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5058 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &aMouseEvent );
5062 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5064 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5065 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
5067 else if( rNEvt.GetType() == EVENT_KEYUP )
5069 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5070 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
5073 if ( aDelData.IsDead() )
5074 return;
5075 ImplRemoveDel( &aDelData );
5077 // #106721# check if we're part of a compound control and notify
5078 Window *pParent = ImplGetParent();
5079 while( pParent )
5081 if( pParent->IsCompoundControl() )
5083 pParent->ImplNotifyKeyMouseCommandEventListeners( rNEvt );
5084 break;
5086 pParent = pParent->ImplGetParent();
5090 // -----------------------------------------------------------------------
5092 long Window::PreNotify( NotifyEvent& rNEvt )
5094 { // Parentheses, as in this handler the window can be destroyed
5095 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5098 long bDone = sal_False;
5099 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
5100 bDone = mpWindowImpl->mpParent->PreNotify( rNEvt );
5102 if ( !bDone )
5104 if( rNEvt.GetType() == EVENT_GETFOCUS )
5106 sal_Bool bCompoundFocusChanged = sal_False;
5107 if ( mpWindowImpl->mbCompoundControl && !mpWindowImpl->mbCompoundControlHasFocus && HasChildPathFocus() )
5109 mpWindowImpl->mbCompoundControlHasFocus = sal_True;
5110 bCompoundFocusChanged = sal_True;
5113 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
5114 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
5116 else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
5118 sal_Bool bCompoundFocusChanged = sal_False;
5119 if ( mpWindowImpl->mbCompoundControl && mpWindowImpl->mbCompoundControlHasFocus && !HasChildPathFocus() )
5121 mpWindowImpl->mbCompoundControlHasFocus = sal_False ;
5122 bCompoundFocusChanged = sal_True;
5125 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
5126 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
5129 // #82968# mouse and key events will be notified after processing ( in ImplNotifyKeyMouseCommandEventListeners() )!
5130 // see also ImplHandleMouseEvent(), ImplHandleKey()
5134 return bDone;
5137 // -----------------------------------------------------------------------
5139 long Window::Notify( NotifyEvent& rNEvt )
5141 { // Parentheses, as in this handler the window can be destroyed
5142 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5145 long nRet = sal_False;
5147 // check for docking window
5148 // but do nothing if window is docked and locked
5149 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
5150 if( pWrapper && !( !pWrapper->IsFloatingMode() && pWrapper->IsLocked() ) )
5152 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5154 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
5155 sal_Bool bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
5156 if ( pMEvt->IsLeft() )
5158 if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
5160 // ctrl double click toggles floating mode
5161 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
5162 return sal_True;
5164 else if ( pMEvt->GetClicks() == 1 && bHit)
5166 // allow start docking during mouse move
5167 pWrapper->ImplEnableStartDocking();
5168 return sal_True;
5172 else if ( rNEvt.GetType() == EVENT_MOUSEMOVE )
5174 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
5175 sal_Bool bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
5176 if ( pMEvt->IsLeft() )
5178 // check if a single click initiated this sequence ( ImplStartDockingEnabled() )
5179 // check if window is docked and
5180 if( pWrapper->ImplStartDockingEnabled() && !pWrapper->IsFloatingMode() &&
5181 !pWrapper->IsDocking() && bHit )
5183 Point aPos = pMEvt->GetPosPixel();
5184 Window* pWindow = rNEvt.GetWindow();
5185 if ( pWindow != this )
5187 aPos = pWindow->OutputToScreenPixel( aPos );
5188 aPos = ScreenToOutputPixel( aPos );
5190 pWrapper->ImplStartDocking( aPos );
5192 return sal_True;
5195 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5197 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
5198 if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
5199 rKey.IsShift() && rKey.IsMod1() )
5201 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
5202 /* At this point the floating toolbar frame does not have the
5203 * input focus since these frames don't get the focus per default
5204 * To enable keyboard handling of this toolbar set the input focus
5205 * to the frame. This needs to be done with ToTop since GrabFocus
5206 * would not notice any change since "this" already has the focus.
5208 if( pWrapper->IsFloatingMode() )
5209 ToTop( TOTOP_GRABFOCUSONLY );
5210 return sal_True;
5215 // manage the dialogs
5216 if ( (GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
5218 // if the parent also has dialog control activated, the parent takes over control
5219 if ( (rNEvt.GetType() == EVENT_KEYINPUT) || (rNEvt.GetType() == EVENT_KEYUP) )
5221 if ( ImplIsOverlapWindow() ||
5222 ((getNonLayoutRealParent(this)->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
5224 nRet = ImplDlgCtrl( *rNEvt.GetKeyEvent(), rNEvt.GetType() == EVENT_KEYINPUT );
5227 else if ( (rNEvt.GetType() == EVENT_GETFOCUS) || (rNEvt.GetType() == EVENT_LOSEFOCUS) )
5229 ImplDlgCtrlFocusChanged( rNEvt.GetWindow(), rNEvt.GetType() == EVENT_GETFOCUS );
5230 if ( (rNEvt.GetWindow() == this) && (rNEvt.GetType() == EVENT_GETFOCUS) &&
5231 !(GetStyle() & WB_TABSTOP) && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
5233 sal_uInt16 n = 0;
5234 Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
5235 if ( pFirstChild )
5236 pFirstChild->ImplControlFocus();
5241 if ( !nRet )
5243 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
5244 nRet = mpWindowImpl->mpParent->Notify( rNEvt );
5247 return nRet;
5250 // -----------------------------------------------------------------------
5252 void Window::ImplCallEventListeners( sal_uLong nEvent, void* pData )
5254 // The implementation was moved to CallEventListeners(),
5255 // because derived classes in svtools must be able to
5256 // call the event listeners and ImplCallEventListeners()
5257 // is not exported.
5258 // TODO: replace ImplCallEventListeners() by CallEventListeners() in vcl
5260 CallEventListeners( nEvent, pData );
5263 // -----------------------------------------------------------------------
5265 void Window::CallEventListeners( sal_uLong nEvent, void* pData )
5267 VclWindowEvent aEvent( this, nEvent, pData );
5269 ImplDelData aDelData;
5270 ImplAddDel( &aDelData );
5272 ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent );
5274 if ( aDelData.IsDead() )
5275 return;
5277 mpWindowImpl->maEventListeners.Call( &aEvent );
5279 if ( aDelData.IsDead() )
5280 return;
5282 ImplRemoveDel( &aDelData );
5284 Window* pWindow = this;
5285 while ( pWindow )
5287 pWindow->ImplAddDel( &aDelData );
5289 pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent );
5291 if ( aDelData.IsDead() )
5292 return;
5294 pWindow->ImplRemoveDel( &aDelData );
5296 pWindow = pWindow->GetParent();
5300 void Window::FireVclEvent( VclSimpleEvent* pEvent )
5302 ImplGetSVData()->mpApp->ImplCallEventListeners(pEvent);
5305 // -----------------------------------------------------------------------
5307 void Window::AddEventListener( const Link& rEventListener )
5309 mpWindowImpl->maEventListeners.addListener( rEventListener );
5312 // -----------------------------------------------------------------------
5314 void Window::RemoveEventListener( const Link& rEventListener )
5316 mpWindowImpl->maEventListeners.removeListener( rEventListener );
5319 // -----------------------------------------------------------------------
5321 void Window::AddChildEventListener( const Link& rEventListener )
5323 mpWindowImpl->maChildEventListeners.addListener( rEventListener );
5326 // -----------------------------------------------------------------------
5328 void Window::RemoveChildEventListener( const Link& rEventListener )
5330 mpWindowImpl->maChildEventListeners.removeListener( rEventListener );
5333 // -----------------------------------------------------------------------
5335 sal_uLong Window::PostUserEvent( const Link& rLink, void* pCaller )
5337 sal_uLong nEventId;
5338 PostUserEvent( nEventId, rLink, pCaller );
5339 return nEventId;
5342 // -----------------------------------------------------------------------
5344 // -----------------------------------------------------------------------
5346 sal_Bool Window::PostUserEvent( sal_uLong& rEventId, const Link& rLink, void* pCaller )
5348 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5350 ImplSVEvent* pSVEvent = new ImplSVEvent;
5351 pSVEvent->mnEvent = 0;
5352 pSVEvent->mpData = pCaller;
5353 pSVEvent->mpLink = new Link( rLink );
5354 pSVEvent->mpWindow = this;
5355 pSVEvent->mbCall = sal_True;
5356 ImplAddDel( &(pSVEvent->maDelData) );
5357 rEventId = (sal_uLong)pSVEvent;
5358 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
5359 return sal_True;
5360 else
5362 rEventId = 0;
5363 ImplRemoveDel( &(pSVEvent->maDelData) );
5364 delete pSVEvent;
5365 return sal_False;
5369 // -----------------------------------------------------------------------
5371 void Window::RemoveUserEvent( sal_uLong nUserEvent )
5373 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5375 ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent;
5377 DBG_ASSERT( pSVEvent->mpWindow == this,
5378 "Window::RemoveUserEvent(): Event doesn't send to this window or is already removed" );
5379 DBG_ASSERT( pSVEvent->mbCall,
5380 "Window::RemoveUserEvent(): Event is already removed" );
5382 if ( pSVEvent->mpWindow )
5384 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
5385 pSVEvent->mpWindow = NULL;
5388 pSVEvent->mbCall = sal_False;
5391 // -----------------------------------------------------------------------
5393 sal_Bool Window::IsLocked( sal_Bool bChildren ) const
5395 if ( mpWindowImpl->mnLockCount != 0 )
5396 return sal_True;
5398 if ( bChildren || mpWindowImpl->mbChildNotify )
5400 Window* pChild = mpWindowImpl->mpFirstChild;
5401 while ( pChild )
5403 if ( pChild->IsLocked( sal_True ) )
5404 return sal_True;
5405 pChild = pChild->mpWindowImpl->mpNext;
5409 return sal_False;
5412 // -----------------------------------------------------------------------
5414 void Window::SetStyle( WinBits nStyle )
5416 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5418 if ( mpWindowImpl->mnStyle != nStyle )
5420 mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
5421 mpWindowImpl->mnStyle = nStyle;
5422 StateChanged( STATE_CHANGE_STYLE );
5426 // -----------------------------------------------------------------------
5428 void Window::SetExtendedStyle( WinBits nExtendedStyle )
5430 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5432 if ( mpWindowImpl->mnExtendedStyle != nExtendedStyle )
5434 Window* pWindow = ImplGetBorderWindow();
5435 if( ! pWindow )
5436 pWindow = this;
5437 if( pWindow->mpWindowImpl->mbFrame )
5439 SalExtStyle nExt = 0;
5440 if( (nExtendedStyle & WB_EXT_DOCUMENT) )
5441 nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
5442 if( (nExtendedStyle & WB_EXT_DOCMODIFIED) )
5443 nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;
5445 pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
5447 mpWindowImpl->mnPrevExtendedStyle = mpWindowImpl->mnExtendedStyle;
5448 mpWindowImpl->mnExtendedStyle = nExtendedStyle;
5449 StateChanged( STATE_CHANGE_EXTENDEDSTYLE );
5453 // -----------------------------------------------------------------------
5455 SystemWindow* Window::GetSystemWindow() const
5457 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5459 const Window* pWin = this;
5460 while ( pWin && !pWin->IsSystemWindow() )
5461 pWin = pWin->GetParent();
5462 return (SystemWindow*)pWin;
5465 // -----------------------------------------------------------------------
5467 void Window::SetBorderStyle( sal_uInt16 nBorderStyle )
5469 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5471 if ( mpWindowImpl->mpBorderWindow )
5473 if( nBorderStyle == WINDOW_BORDER_REMOVEBORDER &&
5474 ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
5475 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
5478 // this is a little awkward: some controls (e.g. svtools ProgressBar)
5479 // cannot avoid getting constructed with WB_BORDER but want to disable
5480 // borders in case of NWF drawing. So they need a method to remove their border window
5481 Window* pBorderWin = mpWindowImpl->mpBorderWindow;
5482 // remove us as border window's client
5483 pBorderWin->mpWindowImpl->mpClientWindow = NULL;
5484 mpWindowImpl->mpBorderWindow = NULL;
5485 mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
5486 // reparent us above the border window
5487 SetParent( pBorderWin->mpWindowImpl->mpParent );
5488 // set us to the position and size of our previous border
5489 Point aBorderPos( pBorderWin->GetPosPixel() );
5490 Size aBorderSize( pBorderWin->GetSizePixel() );
5491 setPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
5492 // release border window
5493 delete pBorderWin;
5495 // set new style bits
5496 SetStyle( GetStyle() & (~WB_BORDER) );
5498 else
5500 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5501 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetBorderStyle( nBorderStyle );
5502 else
5503 mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
5508 // -----------------------------------------------------------------------
5510 sal_uInt16 Window::GetBorderStyle() const
5512 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5514 if ( mpWindowImpl->mpBorderWindow )
5516 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5517 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorderStyle();
5518 else
5519 return mpWindowImpl->mpBorderWindow->GetBorderStyle();
5522 return 0;
5525 // -----------------------------------------------------------------------
5527 long Window::CalcTitleWidth() const
5529 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5531 if ( mpWindowImpl->mpBorderWindow )
5533 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5534 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->CalcTitleWidth();
5535 else
5536 return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
5538 else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
5540 // we guess the width for frame windows as we do not know the
5541 // border of external dialogs
5542 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
5543 Font aFont = GetFont();
5544 ((Window*)this)->SetPointFont( rStyleSettings.GetTitleFont() );
5545 long nTitleWidth = GetTextWidth( GetText() );
5546 ((Window*)this)->SetFont( aFont );
5547 nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
5548 nTitleWidth += rStyleSettings.GetBorderSize() * 2;
5549 nTitleWidth += 10;
5550 return nTitleWidth;
5553 return 0;
5556 // -----------------------------------------------------------------------
5558 void Window::EnableClipSiblings( sal_Bool bClipSiblings )
5560 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5562 if ( mpWindowImpl->mpBorderWindow )
5563 mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings );
5565 mpWindowImpl->mbClipSiblings = bClipSiblings;
5568 // -----------------------------------------------------------------------
5570 void Window::SetMouseTransparent( sal_Bool bTransparent )
5572 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5574 if ( mpWindowImpl->mpBorderWindow )
5575 mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
5577 if( mpWindowImpl->mpSysObj )
5578 mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
5580 mpWindowImpl->mbMouseTransparent = bTransparent;
5583 // -----------------------------------------------------------------------
5585 void Window::SetPaintTransparent( sal_Bool bTransparent )
5587 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5589 // transparency is not useful for frames as the background would have to be provided by a different frame
5590 if( bTransparent && mpWindowImpl->mbFrame )
5591 return;
5593 if ( mpWindowImpl->mpBorderWindow )
5594 mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
5596 mpWindowImpl->mbPaintTransparent = bTransparent;
5599 // -----------------------------------------------------------------------
5601 void Window::SetInputContext( const InputContext& rInputContext )
5603 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5605 mpWindowImpl->maInputContext = rInputContext;
5606 if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
5607 ImplNewInputContext();
5610 // -----------------------------------------------------------------------
5612 void Window::EndExtTextInput( sal_uInt16 nFlags )
5614 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5616 if ( mpWindowImpl->mbExtTextInput )
5617 ImplGetFrame()->EndExtTextInput( nFlags );
5620 // -----------------------------------------------------------------------
5622 void Window::SetCursorRect( const Rectangle* pRect, long nExtTextInputWidth )
5624 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5626 ImplWinData* pWinData = ImplGetWinData();
5627 if ( pWinData->mpCursorRect )
5629 if ( pRect )
5630 *pWinData->mpCursorRect = *pRect;
5631 else
5633 delete pWinData->mpCursorRect;
5634 pWinData->mpCursorRect = NULL;
5637 else
5639 if ( pRect )
5640 pWinData->mpCursorRect = new Rectangle( *pRect );
5643 pWinData->mnCursorExtWidth = nExtTextInputWidth;
5647 // -----------------------------------------------------------------------
5649 const Rectangle* Window::GetCursorRect() const
5651 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5653 ImplWinData* pWinData = ImplGetWinData();
5654 return pWinData->mpCursorRect;
5657 // -----------------------------------------------------------------------
5659 long Window::GetCursorExtTextInputWidth() const
5661 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5663 ImplWinData* pWinData = ImplGetWinData();
5664 return pWinData->mnCursorExtWidth;
5667 // -----------------------------------------------------------------------
5669 void Window::SetCompositionCharRect( const Rectangle* pRect, long nCompositionLength, sal_Bool bVertical ) {
5670 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5672 ImplWinData* pWinData = ImplGetWinData();
5673 delete[] pWinData->mpCompositionCharRects;
5674 pWinData->mbVertical = bVertical;
5675 pWinData->mpCompositionCharRects = NULL;
5676 pWinData->mnCompositionCharRects = nCompositionLength;
5677 if ( pRect && (nCompositionLength > 0) )
5679 pWinData->mpCompositionCharRects = new Rectangle[nCompositionLength];
5680 for (long i = 0; i < nCompositionLength; ++i)
5681 pWinData->mpCompositionCharRects[i] = pRect[i];
5685 // -----------------------------------------------------------------------
5686 void Window::SetSettings( const AllSettings& rSettings )
5688 SetSettings( rSettings, sal_False );
5691 void Window::SetSettings( const AllSettings& rSettings, sal_Bool bChild )
5693 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5695 if ( mpWindowImpl->mpBorderWindow )
5697 mpWindowImpl->mpBorderWindow->SetSettings( rSettings, sal_False );
5698 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
5699 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
5700 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, sal_True );
5703 AllSettings aOldSettings = maSettings;
5704 OutputDevice::SetSettings( rSettings );
5705 sal_uLong nChangeFlags = aOldSettings.GetChangeFlags( rSettings );
5707 // recalculate AppFont-resolution and DPI-resolution
5708 ImplInitResolutionSettings();
5710 if ( nChangeFlags )
5712 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
5713 DataChanged( aDCEvt );
5716 if ( bChild || mpWindowImpl->mbChildNotify )
5718 Window* pChild = mpWindowImpl->mpFirstChild;
5719 while ( pChild )
5721 pChild->SetSettings( rSettings, bChild );
5722 pChild = pChild->mpWindowImpl->mpNext;
5727 // -----------------------------------------------------------------------
5729 void Window::UpdateSettings( const AllSettings& rSettings, sal_Bool bChild )
5731 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5733 if ( mpWindowImpl->mpBorderWindow )
5735 mpWindowImpl->mpBorderWindow->UpdateSettings( rSettings, sal_False );
5736 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
5737 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
5738 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, sal_True );
5741 AllSettings aOldSettings = maSettings;
5742 sal_uLong nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings );
5743 nChangeFlags |= SETTINGS_IN_UPDATE_SETTINGS; // Set this flag so the receiver of the data changed
5744 // event can distinguish between the changing of global
5745 // setting and a local change ( with SetSettings )
5747 // recalculate AppFont-resolution and DPI-resolution
5748 ImplInitResolutionSettings();
5750 /* #i73785#
5751 * do not overwrite a WheelBehavior with false
5752 * this looks kind of a hack, but WheelBehavior
5753 * is always a local change, not a system property,
5754 * so we can spare all our users the hassle of reacting on
5755 * this in their respective DataChanged.
5757 MouseSettings aSet( maSettings.GetMouseSettings() );
5758 aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() );
5759 maSettings.SetMouseSettings( aSet );
5761 if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() )
5763 Wallpaper aWallpaper = GetBackground();
5764 if( !aWallpaper.IsBitmap() && !aWallpaper.IsGradient() )
5766 if ( mpWindowImpl->mnStyle & WB_3DLOOK )
5767 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetFaceColor() ) );
5768 else
5769 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetWindowColor() ) );
5773 if ( nChangeFlags )
5775 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
5776 DataChanged( aDCEvt );
5777 // notify data change handler
5778 ImplCallEventListeners( VCLEVENT_WINDOW_DATACHANGED, &aDCEvt);
5781 if ( bChild || mpWindowImpl->mbChildNotify )
5783 Window* pChild = mpWindowImpl->mpFirstChild;
5784 while ( pChild )
5786 pChild->UpdateSettings( rSettings, bChild );
5787 pChild = pChild->mpWindowImpl->mpNext;
5792 // -----------------------------------------------------------------------
5794 void Window::NotifyAllChildren( DataChangedEvent& rDCEvt )
5796 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5798 DataChanged( rDCEvt );
5800 Window* pChild = mpWindowImpl->mpFirstChild;
5801 while ( pChild )
5803 pChild->NotifyAllChildren( rDCEvt );
5804 pChild = pChild->mpWindowImpl->mpNext;
5808 // -----------------------------------------------------------------------
5810 void Window::SetPointFont( const Font& rFont )
5812 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5814 Font aFont = rFont;
5815 ImplPointToLogic( aFont );
5816 SetFont( aFont );
5819 // -----------------------------------------------------------------------
5821 Font Window::GetPointFont() const
5823 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5825 Font aFont = GetFont();
5826 ImplLogicToPoint( aFont );
5827 return aFont;
5830 // -----------------------------------------------------------------------
5832 void Window::SetParentClipMode( sal_uInt16 nMode )
5834 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5836 if ( mpWindowImpl->mpBorderWindow )
5837 mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode );
5838 else
5840 if ( !ImplIsOverlapWindow() )
5842 mpWindowImpl->mnParentClipMode = nMode;
5843 if ( nMode & PARENTCLIPMODE_CLIP )
5844 mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = sal_True;
5849 // -----------------------------------------------------------------------
5851 sal_uInt16 Window::GetParentClipMode() const
5853 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5855 if ( mpWindowImpl->mpBorderWindow )
5856 return mpWindowImpl->mpBorderWindow->GetParentClipMode();
5857 else
5858 return mpWindowImpl->mnParentClipMode;
5861 // -----------------------------------------------------------------------
5863 void Window::SetWindowRegionPixel()
5865 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5867 if ( mpWindowImpl->mpBorderWindow )
5868 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
5869 else if( mpWindowImpl->mbFrame )
5871 mpWindowImpl->maWinRegion = Region( REGION_NULL);
5872 mpWindowImpl->mbWinRegion = sal_False;
5873 mpWindowImpl->mpFrame->ResetClipRegion();
5875 else
5877 if ( mpWindowImpl->mbWinRegion )
5879 mpWindowImpl->maWinRegion = Region( REGION_NULL );
5880 mpWindowImpl->mbWinRegion = sal_False;
5881 ImplSetClipFlag();
5883 if ( IsReallyVisible() )
5885 // restore background storage
5886 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
5887 ImplDeleteOverlapBackground();
5888 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
5889 ImplInvalidateAllOverlapBackgrounds();
5890 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
5891 Region aRegion( aRect );
5892 ImplInvalidateParentFrameRegion( aRegion );
5898 // -----------------------------------------------------------------------
5900 void Window::SetWindowRegionPixel( const Region& rRegion )
5902 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5904 if ( mpWindowImpl->mpBorderWindow )
5905 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
5906 else if( mpWindowImpl->mbFrame )
5908 if( rRegion.GetType() != REGION_NULL )
5910 mpWindowImpl->maWinRegion = rRegion;
5911 mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
5912 if( mpWindowImpl->mbWinRegion )
5914 // set/update ClipRegion
5915 long nX;
5916 long nY;
5917 long nWidth;
5918 long nHeight;
5919 sal_uLong nRectCount;
5920 ImplRegionInfo aInfo;
5921 sal_Bool bRegionRect;
5923 nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
5924 mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
5925 bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
5926 while ( bRegionRect )
5928 mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
5929 bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
5931 mpWindowImpl->mpFrame->EndSetClipRegion();
5933 else
5934 SetWindowRegionPixel();
5936 else
5937 SetWindowRegionPixel();
5939 else
5941 if ( rRegion.GetType() == REGION_NULL )
5943 if ( mpWindowImpl->mbWinRegion )
5945 mpWindowImpl->maWinRegion = Region( REGION_NULL );
5946 mpWindowImpl->mbWinRegion = sal_False;
5947 ImplSetClipFlag();
5950 else
5952 mpWindowImpl->maWinRegion = rRegion;
5953 mpWindowImpl->mbWinRegion = sal_True;
5954 ImplSetClipFlag();
5957 if ( IsReallyVisible() )
5959 // restore background storage
5960 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
5961 ImplDeleteOverlapBackground();
5962 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
5963 ImplInvalidateAllOverlapBackgrounds();
5964 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
5965 Region aRegion( aRect );
5966 ImplInvalidateParentFrameRegion( aRegion );
5971 // -----------------------------------------------------------------------
5973 const Region& Window::GetWindowRegionPixel() const
5975 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5977 if ( mpWindowImpl->mpBorderWindow )
5978 return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel();
5979 else
5980 return mpWindowImpl->maWinRegion;
5983 // -----------------------------------------------------------------------
5985 sal_Bool Window::IsWindowRegionPixel() const
5987 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5989 if ( mpWindowImpl->mpBorderWindow )
5990 return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel();
5991 else
5992 return mpWindowImpl->mbWinRegion;
5995 // -----------------------------------------------------------------------
5997 Region Window::GetWindowClipRegionPixel( sal_uInt16 nFlags ) const
5999 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6001 Region aWinClipRegion;
6003 if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN )
6005 if ( mpWindowImpl->mbInitWinClipRegion )
6006 ((Window*)this)->ImplInitWinClipRegion();
6007 aWinClipRegion = mpWindowImpl->maWinClipRegion;
6009 else
6011 Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion();
6012 aWinClipRegion = *pWinChildClipRegion;
6013 // --- RTL --- remirror clip region before passing it to somebody
6014 if( ImplIsAntiparallel() )
6015 ImplReMirror( aWinClipRegion );
6018 if ( nFlags & WINDOW_GETCLIPREGION_NULL )
6020 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6021 Region aWinRegion( aWinRect );
6023 if ( aWinRegion == aWinClipRegion )
6024 aWinClipRegion.SetNull();
6027 aWinClipRegion.Move( -mnOutOffX, -mnOutOffY );
6029 return aWinClipRegion;
6032 // -----------------------------------------------------------------------
6034 Region Window::GetPaintRegion() const
6036 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6038 if ( mpWindowImpl->mpPaintRegion )
6040 Region aRegion = *mpWindowImpl->mpPaintRegion;
6041 aRegion.Move( -mnOutOffX, -mnOutOffY );
6042 return PixelToLogic( aRegion );
6044 else
6046 Region aPaintRegion( REGION_NULL );
6047 return aPaintRegion;
6051 // -----------------------------------------------------------------------
6053 void Window::ExpandPaintClipRegion( const Region& rRegion )
6055 if( mpWindowImpl->mpPaintRegion )
6057 Region aPixRegion = LogicToPixel( rRegion );
6058 Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion );
6060 Region aWinChildRegion = *ImplGetWinChildClipRegion();
6061 // --- RTL -- only this region is in frame coordinates, so re-mirror it
6062 if( ImplIsAntiparallel() )
6063 ImplReMirror( aWinChildRegion );
6064 aDevPixRegion.Intersect( aWinChildRegion );
6065 if( ! aDevPixRegion.IsEmpty() )
6067 mpWindowImpl->mpPaintRegion->Union( aDevPixRegion );
6068 mbInitClipRegion = sal_True;
6073 // -----------------------------------------------------------------------
6075 static SystemWindow *ImplGetLastSystemWindow( Window *pWin )
6077 // get the most top-level system window, the one that contains the taskpanelist
6078 SystemWindow *pSysWin = NULL;
6079 if( !pWin )
6080 return pSysWin;
6081 Window *pMyParent = pWin;
6082 while ( pMyParent )
6084 if ( pMyParent->IsSystemWindow() )
6085 pSysWin = (SystemWindow*)pMyParent;
6086 pMyParent = pMyParent->GetParent();
6088 return pSysWin;
6091 void Window::SetParent( Window* pNewParent )
6093 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6094 DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" );
6095 DBG_ASSERT( pNewParent != this, "someone tried to reparent a window to itself" );
6097 if( pNewParent == this )
6098 return;
6100 // check if the taskpanelist would change and move the window pointer accordingly
6101 SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
6102 SystemWindow *pNewSysWin = NULL;
6103 sal_Bool bChangeTaskPaneList = sal_False;
6104 if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
6106 pNewSysWin = ImplGetLastSystemWindow( pNewParent );
6107 if( pNewSysWin && pNewSysWin != pSysWin )
6109 bChangeTaskPaneList = sal_True;
6110 pSysWin->GetTaskPaneList()->RemoveWindow( this );
6113 // remove ownerdraw decorated windows from list in the top-most frame window
6114 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
6116 ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
6117 ::std::vector< Window* >::iterator p;
6118 p = ::std::find( rList.begin(), rList.end(), this );
6119 if( p != rList.end() )
6120 rList.erase( p );
6123 ImplSetFrameParent( pNewParent );
6125 if ( mpWindowImpl->mpBorderWindow )
6127 mpWindowImpl->mpRealParent = pNewParent;
6128 mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
6129 return;
6132 if ( mpWindowImpl->mpParent == pNewParent )
6133 return;
6135 if ( mpWindowImpl->mbFrame )
6136 mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
6138 sal_Bool bVisible = IsVisible();
6139 Show( false, SHOW_NOFOCUSCHANGE );
6141 // check if the overlap window changes
6142 Window* pOldOverlapWindow;
6143 Window* pNewOverlapWindow = NULL;
6144 if ( ImplIsOverlapWindow() )
6145 pOldOverlapWindow = NULL;
6146 else
6148 pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
6149 if ( mpWindowImpl->mpOverlapWindow != pNewOverlapWindow )
6150 pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
6151 else
6152 pOldOverlapWindow = NULL;
6155 // convert windows in the hierarchy
6156 sal_Bool bFocusOverlapWin = HasChildPathFocus( sal_True );
6157 sal_Bool bFocusWin = HasChildPathFocus();
6158 sal_Bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
6159 if ( bNewFrame )
6161 if ( mpWindowImpl->mpFrameData->mpFocusWin )
6163 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
6164 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
6166 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
6168 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
6169 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
6171 if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
6173 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
6174 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
6177 ImplRemoveWindow( bNewFrame );
6178 ImplInsertWindow( pNewParent );
6179 if ( mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP )
6180 pNewParent->mpWindowImpl->mbClipChildren = sal_True;
6181 ImplUpdateWindowPtr();
6182 if ( ImplUpdatePos() )
6183 ImplUpdateSysObjPos();
6185 // If the Overlap-Window has changed, we need to test whether
6186 // OverlapWindows that had the Child window as their parent
6187 // need to be put into the window hierarchy.
6188 if ( ImplIsOverlapWindow() )
6190 if ( bNewFrame )
6192 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
6193 while ( pOverlapWindow )
6195 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
6196 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
6197 pOverlapWindow = pNextOverlapWindow;
6201 else if ( pOldOverlapWindow )
6203 // reset Focus-Save
6204 if ( bFocusWin ||
6205 (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
6206 IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
6207 pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
6209 Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
6210 while ( pOverlapWindow )
6212 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
6213 if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
6214 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
6215 pOverlapWindow = pNextOverlapWindow;
6218 // update activate-status at next overlap window
6219 if ( HasChildPathFocus( sal_True ) )
6220 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
6223 // also convert Activate-Status
6224 if ( bNewFrame )
6226 if ( (GetType() == WINDOW_BORDERWINDOW) &&
6227 (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
6228 ((ImplBorderWindow*)this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
6231 // when required give focus to new frame if
6232 // FocusWindow is changed with SetParent()
6233 if ( bFocusOverlapWin )
6235 mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
6236 if ( !mpWindowImpl->mpFrameData->mbHasFocus )
6238 mpWindowImpl->mpFrame->ToTop( 0 );
6242 // Assure DragSource and DropTarget members are created
6243 if ( bNewFrame )
6245 GetDropTarget();
6248 if( bChangeTaskPaneList )
6249 pNewSysWin->GetTaskPaneList()->AddWindow( this );
6251 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
6252 ImplGetOwnerDrawList().push_back( this );
6254 if ( bVisible )
6255 Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
6258 // -----------------------------------------------------------------------
6260 void Window::Show( sal_Bool bVisible, sal_uInt16 nFlags )
6262 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6264 if ( mpWindowImpl->mbVisible == bVisible )
6265 return;
6267 ImplDelData aDogTag( this );
6269 sal_Bool bRealVisibilityChanged = sal_False;
6270 mpWindowImpl->mbVisible = (bVisible != 0);
6272 if ( !bVisible )
6274 ImplHideAllOverlaps();
6275 if( aDogTag.IsDead() )
6276 return;
6278 if ( mpWindowImpl->mpBorderWindow )
6280 bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
6281 if ( mpWindowImpl->mbNoParentUpdate )
6282 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = sal_True;
6283 mpWindowImpl->mpBorderWindow->Show( false, nFlags );
6284 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
6286 else if ( mpWindowImpl->mbFrame )
6288 mpWindowImpl->mbSuppressAccessibilityEvents = sal_True;
6289 mpWindowImpl->mpFrame->Show( sal_False, sal_False );
6292 StateChanged( STATE_CHANGE_VISIBLE );
6294 if ( mpWindowImpl->mbReallyVisible )
6296 Region aInvRegion( REGION_EMPTY );
6297 sal_Bool bSaveBack = sal_False;
6299 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
6301 if ( ImplRestoreOverlapBackground( aInvRegion ) )
6302 bSaveBack = sal_True;
6305 if ( !bSaveBack )
6307 if ( mpWindowImpl->mbInitWinClipRegion )
6308 ImplInitWinClipRegion();
6309 aInvRegion = mpWindowImpl->maWinClipRegion;
6312 if( aDogTag.IsDead() )
6313 return;
6315 bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
6316 ImplResetReallyVisible();
6317 ImplSetClipFlag();
6319 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
6321 // convert focus
6322 if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() )
6324 if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
6325 mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
6326 ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
6328 mpWindowImpl->mpOverlapWindow->GrabFocus();
6332 if ( !mpWindowImpl->mbFrame )
6334 if( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget )
6337 * #i48371# native theming: some themes draw outside the control
6338 * area we tell them to (bad thing, but we cannot do much about it ).
6339 * On hiding these controls they get invalidated with their window rectangle
6340 * which leads to the parts outside the control area being left and not
6341 * invalidated. Workaround: invalidate an area on the parent, too
6343 const int workaround_border = 5;
6344 Rectangle aBounds( aInvRegion.GetBoundRect() );
6345 aBounds.Left() -= workaround_border;
6346 aBounds.Top() -= workaround_border;
6347 aBounds.Right() += workaround_border;
6348 aBounds.Bottom() += workaround_border;
6349 aInvRegion = aBounds;
6351 if ( !mpWindowImpl->mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) )
6353 if ( !aInvRegion.IsEmpty() )
6354 ImplInvalidateParentFrameRegion( aInvRegion );
6356 ImplGenerateMouseMove();
6360 else
6362 // inherit native widget flag for form controls
6363 // required here, because frames never show up in the child hierarchy - which should be fixed....
6364 // eg, the drop down of a combobox which is a system floating window
6365 if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() &&
6366 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() )
6367 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
6369 if ( mpWindowImpl->mbCallMove )
6371 ImplCallMove();
6373 if ( mpWindowImpl->mbCallResize )
6375 ImplCallResize();
6378 StateChanged( STATE_CHANGE_VISIBLE );
6380 Window* pTestParent;
6381 if ( ImplIsOverlapWindow() )
6382 pTestParent = mpWindowImpl->mpOverlapWindow;
6383 else
6384 pTestParent = ImplGetParent();
6385 if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
6387 // if a window becomes visible, send all child windows a StateChange,
6388 // such that these can initialise themselves
6389 ImplCallInitShow();
6391 // If it is a SystemWindow it automatically pops up on top of
6392 // all other windows if needed.
6393 if ( ImplIsOverlapWindow() && !(nFlags & SHOW_NOACTIVATE) )
6395 ImplStartToTop(( nFlags & SHOW_FOREGROUNDTASK ) ? TOTOP_FOREGROUNDTASK : 0 );
6396 ImplFocusToTop( 0, sal_False );
6399 // save background
6400 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mbSaveBack )
6401 ImplSaveOverlapBackground();
6402 // adjust mpWindowImpl->mbReallyVisible
6403 bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
6404 ImplSetReallyVisible();
6406 // assure clip rectangles will be recalculated
6407 ImplSetClipFlag();
6409 if ( !mpWindowImpl->mbFrame )
6411 sal_uInt16 nInvalidateFlags = INVALIDATE_CHILDREN;
6412 if( ! IsPaintTransparent() )
6413 nInvalidateFlags |= INVALIDATE_NOTRANSPARENT;
6414 ImplInvalidate( NULL, nInvalidateFlags );
6415 ImplGenerateMouseMove();
6419 if ( mpWindowImpl->mpBorderWindow )
6420 mpWindowImpl->mpBorderWindow->Show( true, nFlags );
6421 else if ( mpWindowImpl->mbFrame )
6423 // #106431#, hide SplashScreen
6424 ImplSVData* pSVData = ImplGetSVData();
6425 if ( !pSVData->mpIntroWindow )
6427 // The right way would be just to call this (not even in the 'if')
6428 GetpApp()->InitFinished();
6430 else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
6432 // ... but the VCL splash is broken, and it needs this
6433 // (for ./soffice slot:5500)
6434 pSVData->mpIntroWindow->Hide();
6437 //DBG_ASSERT( !mpWindowImpl->mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated");
6438 mpWindowImpl->mbSuppressAccessibilityEvents = sal_False;
6440 mpWindowImpl->mbPaintFrame = sal_True;
6441 sal_Bool bNoActivate = (nFlags & (SHOW_NOACTIVATE|SHOW_NOFOCUSCHANGE)) ? sal_True : sal_False;
6442 mpWindowImpl->mpFrame->Show( sal_True, bNoActivate );
6443 if( aDogTag.IsDead() )
6444 return;
6446 // Query the correct size of the window, if we are waiting for
6447 // a system resize
6448 if ( mpWindowImpl->mbWaitSystemResize )
6450 long nOutWidth;
6451 long nOutHeight;
6452 mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
6453 ImplHandleResize( this, nOutWidth, nOutHeight );
6457 if( aDogTag.IsDead() )
6458 return;
6460 #if OSL_DEBUG_LEVEL > 0
6461 if ( IsDialog() || (GetType() == WINDOW_TABPAGE) || (GetType() == WINDOW_DOCKINGWINDOW) )
6463 DBG_DIALOGTEST( this );
6465 #endif
6467 ImplShowAllOverlaps();
6470 if( aDogTag.IsDead() )
6471 return;
6472 // invalidate all saved backgrounds
6473 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6474 ImplInvalidateAllOverlapBackgrounds();
6476 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
6477 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
6478 // we re-use the SHOW/HIDE events this way, with this particular semantics).
6479 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
6480 // now only notify with a NULL data pointer, for all other clients except the access bridge.
6481 if ( !bRealVisibilityChanged )
6482 ImplCallEventListeners( mpWindowImpl->mbVisible ? VCLEVENT_WINDOW_SHOW : VCLEVENT_WINDOW_HIDE, NULL );
6483 if( aDogTag.IsDead() )
6484 return;
6486 // #107575#, if a floating windows is shown that grabs the focus, we have to notify the toolkit about it
6487 // ImplGrabFocus() is not called in this case
6488 // Because this might lead to problems the task will be shifted to 6.y
6489 // Note: top-level context menus are registered at the access bridge after being shown,
6490 // so this will probably not help here....
6492 if( mpWindowImpl->mbFloatWin && ((FloatingWindow*) this )->GrabsFocus() )
6494 ImplSVData* pSVData = ImplGetSVData();
6495 if( !mpWindowImpl->mbVisible )
6497 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
6498 if( pSVData->maWinData.mpFocusWin )
6499 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
6501 else
6503 if( pSVData->maWinData.mpFocusWin )
6504 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
6505 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
6511 // -----------------------------------------------------------------------
6513 Size Window::GetSizePixel() const
6515 if (!mpWindowImpl)
6517 SAL_WARN("vcl.layout", "WTF no windowimpl");
6518 return Size(0,0);
6521 // #i43257# trigger pending resize handler to assure correct window sizes
6522 if( mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
6524 ImplDelData aDogtag( this );
6525 mpWindowImpl->mpFrameData->maResizeTimer.Stop();
6526 mpWindowImpl->mpFrameData->maResizeTimer.GetTimeoutHdl().Call( NULL );
6527 if( aDogtag.IsDead() )
6528 return Size(0,0);
6531 return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
6532 mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
6535 void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
6536 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
6538 rLeftBorder = mpWindowImpl->mnLeftBorder;
6539 rTopBorder = mpWindowImpl->mnTopBorder;
6540 rRightBorder = mpWindowImpl->mnRightBorder;
6541 rBottomBorder = mpWindowImpl->mnBottomBorder;
6545 // -----------------------------------------------------------------------
6547 void Window::Enable( bool bEnable, bool bChild )
6549 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6551 if ( !bEnable )
6553 // the tracking mode will be stopped or the capture will be stolen
6554 // when a window is disabled,
6555 if ( IsTracking() )
6556 EndTracking( ENDTRACK_CANCEL );
6557 if ( IsMouseCaptured() )
6558 ReleaseMouse();
6559 // try to pass focus to the next control
6560 // if the window has focus and is contained in the dialog control
6561 // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
6562 // Otherwise ImplDlgCtrlNextWindow() should be used
6563 if ( HasFocus() )
6564 ImplDlgCtrlNextWindow();
6567 if ( mpWindowImpl->mpBorderWindow )
6569 mpWindowImpl->mpBorderWindow->Enable( bEnable, sal_False );
6570 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
6571 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
6572 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, sal_True );
6575 // #i56102# restore app focus win in case the
6576 // window was disabled when the frame focus changed
6577 ImplSVData* pSVData = ImplGetSVData();
6578 if( bEnable &&
6579 pSVData->maWinData.mpFocusWin == NULL &&
6580 mpWindowImpl->mpFrameData->mbHasFocus &&
6581 mpWindowImpl->mpFrameData->mpFocusWin == this )
6582 pSVData->maWinData.mpFocusWin = this;
6584 if ( mpWindowImpl->mbDisabled != !bEnable )
6586 mpWindowImpl->mbDisabled = !bEnable;
6587 if ( mpWindowImpl->mpSysObj )
6588 mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
6589 StateChanged( STATE_CHANGE_ENABLE );
6591 ImplCallEventListeners( bEnable ? VCLEVENT_WINDOW_ENABLED : VCLEVENT_WINDOW_DISABLED );
6594 if ( bChild || mpWindowImpl->mbChildNotify )
6596 Window* pChild = mpWindowImpl->mpFirstChild;
6597 while ( pChild )
6599 pChild->Enable( bEnable, bChild );
6600 pChild = pChild->mpWindowImpl->mpNext;
6604 if ( IsReallyVisible() )
6605 ImplGenerateMouseMove();
6608 // -----------------------------------------------------------------------
6610 void Window::SetCallHandlersOnInputDisabled( bool bCall )
6612 mpWindowImpl->mbCallHandlersDuringInputDisabled = bCall ? sal_True : sal_False;
6614 Window* pChild = mpWindowImpl->mpFirstChild;
6615 while ( pChild )
6617 pChild->SetCallHandlersOnInputDisabled( bCall );
6618 pChild = pChild->mpWindowImpl->mpNext;
6622 // -----------------------------------------------------------------------
6624 bool Window::IsCallHandlersOnInputDisabled() const
6626 return mpWindowImpl->mbCallHandlersDuringInputDisabled ? true : false;
6629 // -----------------------------------------------------------------------
6631 void Window::EnableInput( sal_Bool bEnable, sal_Bool bChild )
6633 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6635 sal_Bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
6636 if ( mpWindowImpl->mpBorderWindow )
6638 mpWindowImpl->mpBorderWindow->EnableInput( bEnable, sal_False );
6639 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
6640 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
6641 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, sal_True );
6644 if ( (! bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) ||
6645 ( bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled) )
6647 // automatically stop the tracking mode or steal capture
6648 // if the window is disabled
6649 if ( !bEnable )
6651 if ( IsTracking() )
6652 EndTracking( ENDTRACK_CANCEL );
6653 if ( IsMouseCaptured() )
6654 ReleaseMouse();
6657 if ( mpWindowImpl->mbInputDisabled != !bEnable )
6659 mpWindowImpl->mbInputDisabled = !bEnable;
6660 if ( mpWindowImpl->mpSysObj )
6661 mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
6665 // #i56102# restore app focus win in case the
6666 // window was disabled when the frame focus changed
6667 ImplSVData* pSVData = ImplGetSVData();
6668 if( bEnable &&
6669 pSVData->maWinData.mpFocusWin == NULL &&
6670 mpWindowImpl->mpFrameData->mbHasFocus &&
6671 mpWindowImpl->mpFrameData->mpFocusWin == this )
6672 pSVData->maWinData.mpFocusWin = this;
6674 if ( bChild || mpWindowImpl->mbChildNotify )
6676 Window* pChild = mpWindowImpl->mpFirstChild;
6677 while ( pChild )
6679 pChild->EnableInput( bEnable, bChild );
6680 pChild = pChild->mpWindowImpl->mpNext;
6684 if ( IsReallyVisible() )
6685 ImplGenerateMouseMove();
6687 // #104827# notify parent
6688 if ( bNotify )
6690 NotifyEvent aNEvt( bEnable ? EVENT_INPUTENABLE : EVENT_INPUTDISABLE, this );
6691 Notify( aNEvt );
6695 // -----------------------------------------------------------------------
6697 void Window::EnableInput( sal_Bool bEnable, sal_Bool bChild, sal_Bool bSysWin,
6698 const Window* pExcludeWindow )
6700 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6702 EnableInput( bEnable, bChild );
6703 if ( bSysWin )
6705 // pExculeWindow is the first Overlap-Frame --> if this
6706 // shouldn't be the case, than this must be changed in dialog.cxx
6707 if( pExcludeWindow )
6708 pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
6709 Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
6710 while ( pSysWin )
6712 // Is Window in the path from this window
6713 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, sal_True ) )
6715 // Is Window not in the exclude window path or not the
6716 // exclude window, than change the status
6717 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, sal_True ) )
6718 pSysWin->EnableInput( bEnable, bChild );
6720 pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
6723 // enable/disable floating system windows as well
6724 Window* pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
6725 while ( pFrameWin )
6727 if( pFrameWin->ImplIsFloatingWindow() )
6729 // Is Window in the path from this window
6730 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, sal_True ) )
6732 // Is Window not in the exclude window path or not the
6733 // exclude window, than change the status
6734 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, sal_True ) )
6735 pFrameWin->EnableInput( bEnable, bChild );
6738 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
6741 // the same for ownerdraw floating windows
6742 if( mpWindowImpl->mbFrame )
6744 ::std::vector< Window* >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
6745 ::std::vector< Window* >::iterator p = rList.begin();
6746 while( p != rList.end() )
6748 // Is Window in the path from this window
6749 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( (*p), sal_True ) )
6751 // Is Window not in the exclude window path or not the
6752 // exclude window, than change the status
6753 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( (*p), sal_True ) )
6754 (*p)->EnableInput( bEnable, bChild );
6756 ++p;
6762 // -----------------------------------------------------------------------
6764 void Window::AlwaysEnableInput( sal_Bool bAlways, sal_Bool bChild )
6766 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6768 if ( mpWindowImpl->mpBorderWindow )
6769 mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, sal_False );
6771 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
6773 mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
6775 if ( bAlways )
6776 EnableInput( sal_True, sal_False );
6778 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
6780 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
6783 if ( bChild || mpWindowImpl->mbChildNotify )
6785 Window* pChild = mpWindowImpl->mpFirstChild;
6786 while ( pChild )
6788 pChild->AlwaysEnableInput( bAlways, bChild );
6789 pChild = pChild->mpWindowImpl->mpNext;
6794 // -----------------------------------------------------------------------
6796 void Window::AlwaysDisableInput( sal_Bool bAlways, sal_Bool bChild )
6798 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6800 if ( mpWindowImpl->mpBorderWindow )
6801 mpWindowImpl->mpBorderWindow->AlwaysDisableInput( bAlways, sal_False );
6803 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled )
6805 mpWindowImpl->meAlwaysInputMode = AlwaysInputDisabled;
6807 if ( bAlways )
6808 EnableInput( sal_False, sal_False );
6810 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled )
6812 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
6815 if ( bChild || mpWindowImpl->mbChildNotify )
6817 Window* pChild = mpWindowImpl->mpFirstChild;
6818 while ( pChild )
6820 pChild->AlwaysDisableInput( bAlways, bChild );
6821 pChild = pChild->mpWindowImpl->mpNext;
6826 // -----------------------------------------------------------------------
6828 void Window::SetActivateMode( sal_uInt16 nMode )
6830 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6832 if ( mpWindowImpl->mpBorderWindow )
6833 mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
6835 if ( mpWindowImpl->mnActivateMode != nMode )
6837 mpWindowImpl->mnActivateMode = nMode;
6839 // possibly trigger Decativate/Activate
6840 if ( mpWindowImpl->mnActivateMode )
6842 if ( (mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW)) &&
6843 !HasChildPathFocus( sal_True ) )
6845 mpWindowImpl->mbActive = sal_False;
6846 Deactivate();
6849 else
6851 if ( !mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW) )
6853 mpWindowImpl->mbActive = sal_True;
6854 Activate();
6860 // -----------------------------------------------------------------------
6862 void Window::ToTop( sal_uInt16 nFlags )
6864 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6866 ImplStartToTop( nFlags );
6867 ImplFocusToTop( nFlags, IsReallyVisible() );
6870 // -----------------------------------------------------------------------
6872 void Window::SetZOrder( Window* pRefWindow, sal_uInt16 nFlags )
6874 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6876 if ( mpWindowImpl->mpBorderWindow )
6878 mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
6879 return;
6882 if ( nFlags & WINDOW_ZORDER_FIRST )
6884 if ( ImplIsOverlapWindow() )
6885 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
6886 else
6887 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
6888 nFlags |= WINDOW_ZORDER_BEFOR;
6890 else if ( nFlags & WINDOW_ZORDER_LAST )
6892 if ( ImplIsOverlapWindow() )
6893 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
6894 else
6895 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
6896 nFlags |= WINDOW_ZORDER_BEHIND;
6899 while ( pRefWindow->mpWindowImpl->mpBorderWindow )
6900 pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
6901 if ( (pRefWindow == this) || mpWindowImpl->mbFrame )
6902 return;
6904 DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" );
6905 if ( nFlags & WINDOW_ZORDER_BEFOR )
6907 if ( pRefWindow->mpWindowImpl->mpPrev == this )
6908 return;
6910 if ( ImplIsOverlapWindow() )
6912 if ( mpWindowImpl->mpPrev )
6913 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
6914 else
6915 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
6916 if ( mpWindowImpl->mpNext )
6917 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
6918 else
6919 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
6920 if ( !pRefWindow->mpWindowImpl->mpPrev )
6921 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
6923 else
6925 if ( mpWindowImpl->mpPrev )
6926 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
6927 else
6928 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
6929 if ( mpWindowImpl->mpNext )
6930 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
6931 else
6932 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
6933 if ( !pRefWindow->mpWindowImpl->mpPrev )
6934 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
6937 mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev;
6938 mpWindowImpl->mpNext = pRefWindow;
6939 if ( mpWindowImpl->mpPrev )
6940 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
6941 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
6943 else if ( nFlags & WINDOW_ZORDER_BEHIND )
6945 if ( pRefWindow->mpWindowImpl->mpNext == this )
6946 return;
6948 if ( ImplIsOverlapWindow() )
6950 if ( mpWindowImpl->mpPrev )
6951 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
6952 else
6953 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
6954 if ( mpWindowImpl->mpNext )
6955 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
6956 else
6957 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
6958 if ( !pRefWindow->mpWindowImpl->mpNext )
6959 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
6961 else
6963 if ( mpWindowImpl->mpPrev )
6964 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
6965 else
6966 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
6967 if ( mpWindowImpl->mpNext )
6968 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
6969 else
6970 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
6971 if ( !pRefWindow->mpWindowImpl->mpNext )
6972 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
6975 mpWindowImpl->mpPrev = pRefWindow;
6976 mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
6977 if ( mpWindowImpl->mpNext )
6978 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
6979 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
6982 if ( IsReallyVisible() )
6984 // restore background storage
6985 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6986 ImplInvalidateAllOverlapBackgrounds();
6988 if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
6990 sal_Bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion;
6991 ImplSetClipFlag();
6993 // When ClipRegion was not initialised, assume
6994 // the window has not been sent, therefore do not
6995 // trigger any Invalidates. This is an optimisation
6996 // for HTML documents with many controls. If this
6997 // check gives problems, a flag should be introduced
6998 // which tracks whether the window has already been
6999 // emitted after Show
7000 if ( !bInitWinClipRegion )
7002 // Invalidate all windows which are next to each other
7003 // Is INCOMPLETE !!!
7004 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
7005 Window* pWindow = NULL;
7006 if ( ImplIsOverlapWindow() )
7008 if ( mpWindowImpl->mpOverlapWindow )
7009 pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
7011 else
7012 pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
7013 // Invalidate all windows in front of us and which are covered by us
7014 while ( pWindow )
7016 if ( pWindow == this )
7017 break;
7018 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
7019 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
7020 if ( aWinRect.IsOver( aCompRect ) )
7021 pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
7022 pWindow = pWindow->mpWindowImpl->mpNext;
7025 // If we are covered by a window in the background
7026 // we should redraw it
7027 while ( pWindow )
7029 if ( pWindow != this )
7031 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
7032 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
7033 if ( aWinRect.IsOver( aCompRect ) )
7035 Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
7036 break;
7039 pWindow = pWindow->mpWindowImpl->mpNext;
7046 // -----------------------------------------------------------------------
7048 void Window::EnableAlwaysOnTop( sal_Bool bEnable )
7050 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7052 mpWindowImpl->mbAlwaysOnTop = bEnable;
7054 if ( mpWindowImpl->mpBorderWindow )
7055 mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable );
7056 else if ( bEnable && IsReallyVisible() )
7057 ToTop();
7059 if ( mpWindowImpl->mbFrame )
7060 mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable );
7063 // -----------------------------------------------------------------------
7065 void Window::setPosSizePixel( long nX, long nY,
7066 long nWidth, long nHeight, sal_uInt16 nFlags )
7068 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7070 sal_Bool bHasValidSize = !mpWindowImpl->mbDefSize;
7072 if ( nFlags & WINDOW_POSSIZE_POS )
7073 mpWindowImpl->mbDefPos = sal_False;
7074 if ( nFlags & WINDOW_POSSIZE_SIZE )
7075 mpWindowImpl->mbDefSize = sal_False;
7077 // The top BorderWindow is the window which is to be positioned
7078 Window* pWindow = this;
7079 while ( pWindow->mpWindowImpl->mpBorderWindow )
7080 pWindow = pWindow->mpWindowImpl->mpBorderWindow;
7082 if ( pWindow->mpWindowImpl->mbFrame )
7084 // Note: if we're positioning a frame, the coordinates are interpreted
7085 // as being the top-left corner of the window's client area and NOT
7086 // as the position of the border ! (due to limitations of several UNIX window managers)
7087 long nOldWidth = pWindow->mnOutWidth;
7089 if ( !(nFlags & WINDOW_POSSIZE_WIDTH) )
7090 nWidth = pWindow->mnOutWidth;
7091 if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) )
7092 nHeight = pWindow->mnOutHeight;
7095 sal_uInt16 nSysFlags=0;
7096 if( nFlags & WINDOW_POSSIZE_WIDTH )
7097 nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
7098 if( nFlags & WINDOW_POSSIZE_HEIGHT )
7099 nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
7100 if( nFlags & WINDOW_POSSIZE_X )
7102 nSysFlags |= SAL_FRAME_POSSIZE_X;
7103 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
7105 Window* pParent = pWindow->GetParent();
7106 nX += pParent->mnOutOffX;
7108 if( GetParent() && GetParent()->ImplIsAntiparallel() )
7110 // --- RTL --- (re-mirror at parent window)
7111 Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
7112 GetParent()->ImplReMirror( aRect );
7113 nX = aRect.Left();
7116 if( !(nFlags & WINDOW_POSSIZE_X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth )
7118 // --- RTL --- make sure the old right aligned position is not changed
7119 // system windows will always grow to the right
7120 if( pWindow->GetParent() && pWindow->GetParent()->ImplHasMirroredGraphics() )
7122 long myWidth = nOldWidth;
7123 if( !myWidth )
7124 myWidth = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth;
7125 if( !myWidth )
7126 myWidth = nWidth;
7127 nFlags |= WINDOW_POSSIZE_X;
7128 nSysFlags |= SAL_FRAME_POSSIZE_X;
7129 nX = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX -
7130 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration;
7131 nX = pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration +
7132 pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth - myWidth - 1 - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX;
7133 if(!(nFlags & WINDOW_POSSIZE_Y))
7135 nFlags |= WINDOW_POSSIZE_Y;
7136 nSysFlags |= SAL_FRAME_POSSIZE_Y;
7137 nY = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY -
7138 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nTopDecoration;
7142 if( nFlags & WINDOW_POSSIZE_Y )
7144 nSysFlags |= SAL_FRAME_POSSIZE_Y;
7145 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
7147 Window* pParent = pWindow->GetParent();
7148 nY += pParent->mnOutOffY;
7152 if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
7154 // check for min/max client size and adjust size accordingly
7155 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
7156 // unchanged but ImplHandleResize() is called with the wrong size
7157 SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow );
7158 if( pSystemWindow )
7160 Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
7161 Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
7162 if( nWidth < aMinSize.Width() )
7163 nWidth = aMinSize.Width();
7164 if( nHeight < aMinSize.Height() )
7165 nHeight = aMinSize.Height();
7167 if( nWidth > aMaxSize.Width() )
7168 nWidth = aMaxSize.Width();
7169 if( nHeight > aMaxSize.Height() )
7170 nHeight = aMaxSize.Height();
7174 pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
7176 // Resize should be called directly. If we havn't
7177 // set the correct size, we get a second resize from
7178 // the system with the correct size. This can be happened
7179 // if the size is to small or to large.
7180 ImplHandleResize( pWindow, nWidth, nHeight );
7182 else
7184 pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
7185 if ( IsReallyVisible() )
7186 ImplGenerateMouseMove();
7190 // -----------------------------------------------------------------------
7192 Point Window::GetPosPixel() const
7194 return mpWindowImpl->maPos;
7197 // -----------------------------------------------------------------------
7199 Rectangle Window::GetDesktopRectPixel() const
7201 Rectangle rRect;
7202 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
7203 return rRect;
7206 // -----------------------------------------------------------------------
7208 Point Window::OutputToScreenPixel( const Point& rPos ) const
7210 // relative to top level parent
7211 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
7214 // -----------------------------------------------------------------------
7216 Point Window::ScreenToOutputPixel( const Point& rPos ) const
7218 // relative to top level parent
7219 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
7222 // -----------------------------------------------------------------------
7224 long Window::ImplGetUnmirroredOutOffX()
7226 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
7227 long offx = mnOutOffX;
7228 if( ImplHasMirroredGraphics() )
7230 if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
7232 if ( !ImplIsOverlapWindow() )
7233 offx -= mpWindowImpl->mpParent->mnOutOffX;
7235 offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx;
7237 if ( !ImplIsOverlapWindow() )
7238 offx += mpWindowImpl->mpParent->mnOutOffX;
7242 return offx;
7245 // normalized screen pixel are independent of mirroring
7246 Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
7248 // relative to top level parent
7249 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
7250 return Point( rPos.X()+offx, rPos.Y()+mnOutOffY );
7253 Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
7255 // relative to top level parent
7256 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
7257 return Point( rPos.X()-offx, rPos.Y()-mnOutOffY );
7260 // -----------------------------------------------------------------------
7262 Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
7264 // relative to the screen
7265 Point p = OutputToScreenPixel( rPos );
7266 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7267 p.X() += g.nX;
7268 p.Y() += g.nY;
7269 return p;
7272 // -----------------------------------------------------------------------
7274 Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const
7276 // relative to the screen
7277 Point p = ScreenToOutputPixel( rPos );
7278 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7279 p.X() -= g.nX;
7280 p.Y() -= g.nY;
7281 return p;
7284 // -----------------------------------------------------------------------
7286 Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle &rRect ) const
7288 // this method creates unmirrored screen coordinates to be compared with the desktop
7289 // and is used for positioning of RTL popup windows correctly on the screen
7290 SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
7292 Point p1 = OutputToScreenPixel( rRect.TopRight() );
7293 p1.X() = g.nX+g.nWidth-p1.X();
7294 p1.Y() += g.nY;
7296 Point p2 = OutputToScreenPixel( rRect.BottomLeft() );
7297 p2.X() = g.nX+g.nWidth-p2.X();
7298 p2.Y() += g.nY;
7300 return Rectangle( p1, p2 );
7304 // -----------------------------------------------------------------------
7306 Rectangle Window::GetWindowExtentsRelative( Window *pRelativeWindow ) const
7308 // with decoration
7309 return ImplGetWindowExtentsRelative( pRelativeWindow, sal_False );
7312 Rectangle Window::GetClientWindowExtentsRelative( Window *pRelativeWindow ) const
7314 // without decoration
7315 return ImplGetWindowExtentsRelative( pRelativeWindow, sal_True );
7318 // -----------------------------------------------------------------------
7320 Rectangle Window::ImplGetWindowExtentsRelative( Window *pRelativeWindow, sal_Bool bClientOnly ) const
7322 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7323 // make sure we use the extent of our border window,
7324 // otherwise we miss a few pixels
7325 const Window *pWin = (!bClientOnly && mpWindowImpl->mpBorderWindow) ? mpWindowImpl->mpBorderWindow : this;
7327 Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) );
7328 aPos.X() += g.nX;
7329 aPos.Y() += g.nY;
7330 Size aSize ( pWin->GetSizePixel() );
7331 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
7332 if( !bClientOnly && (mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WINDOW_WORKWINDOW)) )
7334 aPos.X() -= g.nLeftDecoration;
7335 aPos.Y() -= g.nTopDecoration;
7336 aSize.Width() += g.nLeftDecoration + g.nRightDecoration;
7337 aSize.Height() += g.nTopDecoration + g.nBottomDecoration;
7339 if( pRelativeWindow )
7341 // #106399# express coordinates relative to borderwindow
7342 Window *pRelWin = (!bClientOnly && pRelativeWindow->mpWindowImpl->mpBorderWindow) ? pRelativeWindow->mpWindowImpl->mpBorderWindow : pRelativeWindow;
7343 aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos );
7345 return Rectangle( aPos, aSize );
7348 // -----------------------------------------------------------------------
7350 void Window::Scroll( long nHorzScroll, long nVertScroll, sal_uInt16 nFlags )
7352 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7354 ImplScroll( Rectangle( Point( mnOutOffX, mnOutOffY ),
7355 Size( mnOutWidth, mnOutHeight ) ),
7356 nHorzScroll, nVertScroll, nFlags & ~SCROLL_CLIP );
7359 // -----------------------------------------------------------------------
7361 void Window::Scroll( long nHorzScroll, long nVertScroll,
7362 const Rectangle& rRect, sal_uInt16 nFlags )
7364 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7366 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7367 aRect.Intersection( Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) );
7368 if ( !aRect.IsEmpty() )
7369 ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
7372 // -----------------------------------------------------------------------
7374 void Window::Invalidate( sal_uInt16 nFlags )
7376 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7378 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7379 return;
7381 ImplInvalidate( NULL, nFlags );
7384 // -----------------------------------------------------------------------
7386 void Window::Invalidate( const Rectangle& rRect, sal_uInt16 nFlags )
7388 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7390 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7391 return;
7393 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7394 if ( !aRect.IsEmpty() )
7396 Region aRegion( aRect );
7397 ImplInvalidate( &aRegion, nFlags );
7401 // -----------------------------------------------------------------------
7403 void Window::Invalidate( const Region& rRegion, sal_uInt16 nFlags )
7405 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7407 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7408 return;
7410 if ( rRegion.IsNull() )
7411 ImplInvalidate( NULL, nFlags );
7412 else
7414 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
7415 if ( !aRegion.IsEmpty() )
7416 ImplInvalidate( &aRegion, nFlags );
7420 // -----------------------------------------------------------------------
7422 void Window::Validate( sal_uInt16 nFlags )
7424 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7426 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7427 return;
7429 ImplValidate( NULL, nFlags );
7432 // -----------------------------------------------------------------------
7434 sal_Bool Window::HasPaintEvent() const
7436 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7438 if ( !mpWindowImpl->mbReallyVisible )
7439 return sal_False;
7441 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
7442 return sal_True;
7444 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
7445 return sal_True;
7447 if ( !ImplIsOverlapWindow() )
7449 const Window* pTempWindow = this;
7452 pTempWindow = pTempWindow->ImplGetParent();
7453 if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDREN | IMPL_PAINT_PAINTALLCHILDREN) )
7454 return sal_True;
7456 while ( !pTempWindow->ImplIsOverlapWindow() );
7459 return sal_False;
7462 // -----------------------------------------------------------------------
7464 void Window::Update()
7466 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7468 if ( mpWindowImpl->mpBorderWindow )
7470 mpWindowImpl->mpBorderWindow->Update();
7471 return;
7474 if ( !mpWindowImpl->mbReallyVisible )
7475 return;
7477 sal_Bool bFlush = sal_False;
7478 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
7480 Point aPoint( 0, 0 );
7481 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
7482 ImplInvalidateOverlapFrameRegion( aRegion );
7483 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
7484 bFlush = sal_True;
7487 // First we should skip all windows which are Paint-Transparent
7488 Window* pUpdateWindow = this;
7489 Window* pWindow = pUpdateWindow;
7490 while ( !pWindow->ImplIsOverlapWindow() )
7492 if ( !pWindow->mpWindowImpl->mbPaintTransparent )
7494 pUpdateWindow = pWindow;
7495 break;
7497 pWindow = pWindow->ImplGetParent();
7499 // In order to limit drawing, an update only draws the window which
7500 // has PAINTALLCHILDREN set
7501 pWindow = pUpdateWindow;
7504 if ( pWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
7505 pUpdateWindow = pWindow;
7506 if ( pWindow->ImplIsOverlapWindow() )
7507 break;
7508 pWindow = pWindow->ImplGetParent();
7510 while ( pWindow );
7512 // if there is something to paint, trigger a Paint
7513 if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
7515 ImplDelData aDogTag(this);
7517 // trigger an update also for system windows on top of us,
7518 // otherwise holes would remain
7519 Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap;
7520 while ( pUpdateOverlapWindow )
7522 pUpdateOverlapWindow->Update();
7523 pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
7526 pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags );
7528 if (aDogTag.IsDead())
7529 return;
7532 if ( bFlush )
7533 Flush();
7536 // -----------------------------------------------------------------------
7538 void Window::Flush()
7540 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7542 const Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
7543 mpWindowImpl->mpFrame->Flush( aWinRect );
7546 // -----------------------------------------------------------------------
7548 void Window::Sync()
7550 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7552 mpWindowImpl->mpFrame->Sync();
7555 // -----------------------------------------------------------------------
7557 void Window::SetUpdateMode( sal_Bool bUpdate )
7559 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7561 mpWindowImpl->mbNoUpdate = !bUpdate;
7562 StateChanged( STATE_CHANGE_UPDATEMODE );
7565 // -----------------------------------------------------------------------
7567 void Window::GrabFocus()
7569 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7571 ImplGrabFocus( 0 );
7574 // -----------------------------------------------------------------------
7576 sal_Bool Window::HasFocus() const
7578 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7580 // #107575# the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
7581 // task was shifted to 6.y, so its commented out
7583 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
7584 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
7585 pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
7586 else
7587 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7589 return (this == pFocusWin);
7592 return (this == ImplGetSVData()->maWinData.mpFocusWin);
7595 // -----------------------------------------------------------------------
7597 void Window::GrabFocusToDocument()
7599 Window *pWin = this;
7600 while( pWin )
7602 if( !pWin->GetParent() )
7604 pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
7605 return;
7607 pWin = pWin->GetParent();
7611 void Window::SetFakeFocus( bool bFocus )
7613 ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
7616 // -----------------------------------------------------------------------
7618 sal_Bool Window::HasChildPathFocus( sal_Bool bSystemWindow ) const
7620 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7622 // #107575#, the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
7623 // task was shifted to 6.y, so its commented out
7625 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
7626 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
7627 pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
7628 else
7629 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7631 Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7632 if ( pFocusWin )
7633 return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
7634 return sal_False;
7637 // -----------------------------------------------------------------------
7639 void Window::CaptureMouse()
7641 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7643 ImplSVData* pSVData = ImplGetSVData();
7645 // possibly stop tracking
7646 if ( pSVData->maWinData.mpTrackWin != this )
7648 if ( pSVData->maWinData.mpTrackWin )
7649 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
7652 if ( pSVData->maWinData.mpCaptureWin != this )
7654 pSVData->maWinData.mpCaptureWin = this;
7655 mpWindowImpl->mpFrame->CaptureMouse( sal_True );
7659 // -----------------------------------------------------------------------
7661 void Window::ReleaseMouse()
7663 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7665 ImplSVData* pSVData = ImplGetSVData();
7667 DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this,
7668 "Window::ReleaseMouse(): window doesn't have the mouse capture" );
7670 if ( pSVData->maWinData.mpCaptureWin == this )
7672 pSVData->maWinData.mpCaptureWin = NULL;
7673 mpWindowImpl->mpFrame->CaptureMouse( sal_False );
7674 ImplGenerateMouseMove();
7678 // -----------------------------------------------------------------------
7680 sal_Bool Window::IsMouseCaptured() const
7682 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7684 return (this == ImplGetSVData()->maWinData.mpCaptureWin);
7687 // -----------------------------------------------------------------------
7689 void Window::SetPointer( const Pointer& rPointer )
7691 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7693 if ( mpWindowImpl->maPointer == rPointer )
7694 return;
7696 mpWindowImpl->maPointer = rPointer;
7698 // possibly immediately move pointer
7699 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7700 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7703 // -----------------------------------------------------------------------
7705 void Window::EnableChildPointerOverwrite( sal_Bool bOverwrite )
7707 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7709 if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
7710 return;
7712 mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
7714 // possibly immediately move pointer
7715 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7716 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7719 // -----------------------------------------------------------------------
7721 void Window::SetPointerPosPixel( const Point& rPos )
7723 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7725 Point aPos = ImplOutputToFrame( rPos );
7726 if( ImplHasMirroredGraphics() )
7728 if( !IsRTLEnabled() )
7730 // --- RTL --- (re-mirror mouse pos at this window)
7731 ImplReMirror( aPos );
7733 // mirroring is required here, SetPointerPos bypasses SalGraphics
7734 mpGraphics->mirror( aPos.X(), this );
7736 else if( ImplIsAntiparallel() )
7738 ImplReMirror( aPos );
7740 mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
7743 // -----------------------------------------------------------------------
7745 Point Window::GetPointerPosPixel()
7747 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7749 Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
7750 if( ImplIsAntiparallel() )
7752 // --- RTL --- (re-mirror mouse pos at this window)
7753 ImplReMirror( aPos );
7755 return ImplFrameToOutput( aPos );
7758 // -----------------------------------------------------------------------
7760 Point Window::GetLastPointerPosPixel()
7762 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7764 Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
7765 if( ImplIsAntiparallel() )
7767 // --- RTL --- (re-mirror mouse pos at this window)
7768 ImplReMirror( aPos );
7770 return ImplFrameToOutput( aPos );
7773 // -----------------------------------------------------------------------
7775 void Window::ShowPointer( sal_Bool bVisible )
7777 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7779 if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
7781 mpWindowImpl->mbNoPtrVisible = !bVisible;
7783 // possibly immediately move pointer
7784 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7785 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7789 // -----------------------------------------------------------------------
7791 Window::PointerState Window::GetPointerState()
7793 PointerState aState;
7794 aState.mnState = 0;
7796 if (mpWindowImpl->mpFrame)
7798 SalFrame::SalPointerState aSalPointerState;
7800 aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
7801 if( ImplIsAntiparallel() )
7803 // --- RTL --- (re-mirror mouse pos at this window)
7804 ImplReMirror( aSalPointerState.maPos );
7806 aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
7807 aState.mnState = aSalPointerState.mnState;
7809 return aState;
7812 // -----------------------------------------------------------------------
7814 sal_Bool Window::IsMouseOver()
7816 return ImplGetWinData()->mbMouseOver;
7819 // -----------------------------------------------------------------------
7821 void Window::EnterWait()
7823 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7825 mpWindowImpl->mnWaitCount++;
7827 if ( mpWindowImpl->mnWaitCount == 1 )
7829 // possibly immediately move pointer
7830 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7831 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7835 // -----------------------------------------------------------------------
7837 void Window::LeaveWait()
7839 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7841 if ( mpWindowImpl->mnWaitCount )
7843 mpWindowImpl->mnWaitCount--;
7845 if ( !mpWindowImpl->mnWaitCount )
7847 // possibly immediately move pointer
7848 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7849 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7854 // -----------------------------------------------------------------------
7856 void Window::SetCursor( Cursor* pCursor )
7858 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7860 if ( mpWindowImpl->mpCursor != pCursor )
7862 if ( mpWindowImpl->mpCursor )
7863 mpWindowImpl->mpCursor->ImplHide( true );
7864 mpWindowImpl->mpCursor = pCursor;
7865 if ( pCursor )
7866 pCursor->ImplShow();
7870 // -----------------------------------------------------------------------
7872 void Window::SetText( const OUString& rStr )
7874 if (rStr == OUString(mpWindowImpl->maText))
7875 return;
7877 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7879 String oldTitle( mpWindowImpl->maText );
7880 mpWindowImpl->maText = rStr;
7882 if ( mpWindowImpl->mpBorderWindow )
7883 mpWindowImpl->mpBorderWindow->SetText( rStr );
7884 else if ( mpWindowImpl->mbFrame )
7885 mpWindowImpl->mpFrame->SetTitle( rStr );
7887 ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
7889 // #107247# needed for accessibility
7890 // The VCLEVENT_WINDOW_FRAMETITLECHANGED is (mis)used to notify accessible name changes.
7891 // Therefore a window, which is labeled by this window, must also notify an accessible
7892 // name change.
7893 if ( IsReallyVisible() )
7895 Window* pWindow = GetAccessibleRelationLabelFor();
7896 if ( pWindow && pWindow != this )
7897 pWindow->ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
7900 StateChanged( STATE_CHANGE_TEXT );
7903 // -----------------------------------------------------------------------
7905 OUString Window::GetText() const
7907 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7909 return mpWindowImpl->maText;
7912 // -----------------------------------------------------------------------
7914 OUString Window::GetDisplayText() const
7916 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7918 return GetText();
7921 // -----------------------------------------------------------------------
7923 const Wallpaper& Window::GetDisplayBackground() const
7925 // FIXME: fix issue 52349, need to fix this really in
7926 // all NWF enabled controls
7927 const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
7928 if( pTB )
7930 if( IsNativeWidgetEnabled() )
7931 return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
7934 if( !IsBackground() )
7936 if( mpWindowImpl->mpParent )
7937 return mpWindowImpl->mpParent->GetDisplayBackground();
7940 const Wallpaper& rBack = GetBackground();
7941 if( ! rBack.IsBitmap() &&
7942 ! rBack.IsGradient() &&
7943 rBack.GetColor().GetColor() == COL_TRANSPARENT &&
7944 mpWindowImpl->mpParent )
7945 return mpWindowImpl->mpParent->GetDisplayBackground();
7946 return rBack;
7949 // -----------------------------------------------------------------------
7951 const XubString& Window::GetHelpText() const
7953 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7955 String aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
7956 bool bStrHelpId = (aStrHelpId.Len() > 0);
7958 if ( !mpWindowImpl->maHelpText.Len() && bStrHelpId )
7960 if ( !IsDialog() && (mpWindowImpl->mnType != WINDOW_TABPAGE) && (mpWindowImpl->mnType != WINDOW_FLOATINGWINDOW) )
7962 Help* pHelp = Application::GetHelp();
7963 if ( pHelp )
7965 ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this );
7966 mpWindowImpl->mbHelpTextDynamic = sal_False;
7970 else if( mpWindowImpl->mbHelpTextDynamic && bStrHelpId )
7972 static const char* pEnv = getenv( "HELP_DEBUG" );
7973 if( pEnv && *pEnv )
7975 OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() );
7976 aTxt.append( mpWindowImpl->maHelpText );
7977 aTxt.appendAscii( "\n------------------\n" );
7978 aTxt.append( OUString( aStrHelpId ) );
7979 mpWindowImpl->maHelpText = aTxt.makeStringAndClear();
7981 mpWindowImpl->mbHelpTextDynamic = sal_False;
7984 return mpWindowImpl->maHelpText;
7987 // -----------------------------------------------------------------------
7989 Window* Window::FindWindow( const Point& rPos ) const
7991 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7993 Point aPos = OutputToScreenPixel( rPos );
7994 return ((Window*)this)->ImplFindWindow( aPos );
7997 // -----------------------------------------------------------------------
7999 sal_uInt16 Window::GetChildCount() const
8001 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8003 sal_uInt16 nChildCount = 0;
8004 Window* pChild = mpWindowImpl->mpFirstChild;
8005 while ( pChild )
8007 nChildCount++;
8008 pChild = pChild->mpWindowImpl->mpNext;
8011 return nChildCount;
8014 // -----------------------------------------------------------------------
8016 Window* Window::GetChild( sal_uInt16 nChild ) const
8018 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8020 sal_uInt16 nChildCount = 0;
8021 Window* pChild = mpWindowImpl->mpFirstChild;
8022 while ( pChild )
8024 if ( nChild == nChildCount )
8025 return pChild;
8026 pChild = pChild->mpWindowImpl->mpNext;
8027 nChildCount++;
8030 return NULL;
8033 // -----------------------------------------------------------------------
8035 Window* Window::GetWindow( sal_uInt16 nType ) const
8037 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8039 switch ( nType )
8041 case WINDOW_PARENT:
8042 return mpWindowImpl->mpRealParent;
8044 case WINDOW_FIRSTCHILD:
8045 return mpWindowImpl->mpFirstChild;
8047 case WINDOW_LASTCHILD:
8048 return mpWindowImpl->mpLastChild;
8050 case WINDOW_PREV:
8051 return mpWindowImpl->mpPrev;
8053 case WINDOW_NEXT:
8054 return mpWindowImpl->mpNext;
8056 case WINDOW_FIRSTOVERLAP:
8057 return mpWindowImpl->mpFirstOverlap;
8059 case WINDOW_LASTOVERLAP:
8060 return mpWindowImpl->mpLastOverlap;
8062 case WINDOW_OVERLAP:
8063 if ( ImplIsOverlapWindow() )
8064 return (Window*)this;
8065 else
8066 return mpWindowImpl->mpOverlapWindow;
8068 case WINDOW_PARENTOVERLAP:
8069 if ( ImplIsOverlapWindow() )
8070 return mpWindowImpl->mpOverlapWindow;
8071 else
8072 return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
8074 case WINDOW_CLIENT:
8075 return ((Window*)this)->ImplGetWindow();
8077 case WINDOW_REALPARENT:
8078 return ImplGetParent();
8080 case WINDOW_FRAME:
8081 return mpWindowImpl->mpFrameWindow;
8083 case WINDOW_BORDER:
8084 if ( mpWindowImpl->mpBorderWindow )
8085 return mpWindowImpl->mpBorderWindow->GetWindow( WINDOW_BORDER );
8086 return (Window*)this;
8088 case WINDOW_FIRSTTOPWINDOWCHILD:
8089 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.begin();
8091 case WINDOW_LASTTOPWINDOWCHILD:
8092 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.rbegin();
8094 case WINDOW_PREVTOPWINDOWSIBLING:
8096 if ( !mpWindowImpl->mpRealParent )
8097 return NULL;
8098 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
8099 ::std::list< Window* >::const_iterator myPos =
8100 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
8101 if ( myPos == rTopWindows.end() )
8102 return NULL;
8103 if ( myPos == rTopWindows.begin() )
8104 return NULL;
8105 return *--myPos;
8108 case WINDOW_NEXTTOPWINDOWSIBLING:
8110 if ( !mpWindowImpl->mpRealParent )
8111 return NULL;
8112 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
8113 ::std::list< Window* >::const_iterator myPos =
8114 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
8115 if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
8116 return NULL;
8117 return *myPos;
8122 return NULL;
8125 // -----------------------------------------------------------------------
8127 sal_Bool Window::IsChild( const Window* pWindow, sal_Bool bSystemWindow ) const
8129 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8130 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
8134 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
8135 break;
8137 pWindow = pWindow->ImplGetParent();
8139 if ( pWindow == this )
8140 return sal_True;
8142 while ( pWindow );
8144 return sal_False;
8147 // -----------------------------------------------------------------------
8149 sal_Bool Window::IsWindowOrChild( const Window* pWindow, sal_Bool bSystemWindow ) const
8151 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8152 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
8154 if ( this == pWindow )
8155 return sal_True;
8156 return ImplIsChild( pWindow, bSystemWindow );
8159 // -----------------------------------------------------------------------
8161 const SystemEnvData* Window::GetSystemData() const
8163 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8165 return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : NULL;
8168 ::com::sun::star::uno::Any Window::GetSystemDataAny() const
8170 ::com::sun::star::uno::Any aRet;
8171 const SystemEnvData* pSysData = GetSystemData();
8172 if( pSysData )
8174 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)pSysData, pSysData->nSize );
8175 aRet <<= aSeq;
8177 return aRet;
8180 // -----------------------------------------------------------------------
8182 void Window::SetWindowPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer, VCLXWindow* pVCLXWindow )
8184 // be safe against re-entrance: first clear the old ref, then assign the new one
8185 // #133706# / 2006-03-30 / frank.schoenheit@sun.com
8186 mpWindowImpl->mxWindowPeer.clear();
8187 mpWindowImpl->mxWindowPeer = xPeer;
8189 mpWindowImpl->mpVCLXWindow = pVCLXWindow;
8192 // -----------------------------------------------------------------------
8194 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( sal_Bool bCreate )
8196 if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
8198 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
8199 if ( pWrapper )
8200 mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True );
8202 return mpWindowImpl->mxWindowPeer;
8205 // -----------------------------------------------------------------------
8207 void Window::SetComponentInterface( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xIFace )
8209 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
8210 DBG_ASSERT( pWrapper, "SetComponentInterface: No Wrapper!" );
8211 if ( pWrapper )
8212 pWrapper->SetWindowInterface( this, xIFace );
8215 // -----------------------------------------------------------------------
8217 void Window::ImplCallDeactivateListeners( Window *pNew )
8219 // no deactivation if the newly activated window is my child
8220 if ( !pNew || !ImplIsChild( pNew ) )
8222 ImplDelData aDogtag( this );
8223 ImplCallEventListeners( VCLEVENT_WINDOW_DEACTIVATE );
8224 if( aDogtag.IsDead() )
8225 return;
8227 // #100759#, avoid walking the wrong frame's hierarchy
8228 // eg, undocked docking windows (ImplDockFloatWin)
8229 if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
8230 ImplGetParent()->ImplCallDeactivateListeners( pNew );
8234 // -----------------------------------------------------------------------
8236 void Window::ImplCallActivateListeners( Window *pOld )
8238 // no activation if the old active window is my child
8239 if ( !pOld || !ImplIsChild( pOld ) )
8241 ImplDelData aDogtag( this );
8242 ImplCallEventListeners( VCLEVENT_WINDOW_ACTIVATE, pOld );
8243 if( aDogtag.IsDead() )
8244 return;
8246 // #106298# revoke the change for 105369, because this change
8247 // disabled the activate event for the parent,
8248 // if the parent is a compound control
8249 //if( !GetParent() || !GetParent()->IsCompoundControl() )
8251 // #100759#, avoid walking the wrong frame's hierarchy
8252 // eg, undocked docking windows (ImplDockFloatWin)
8253 // #104714#, revert the changes for 100759 because it has a side effect when pOld is a dialog
8254 // additionally the gallery is not dockable anymore, so 100759 canot occur
8255 if ( ImplGetParent() ) /* && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow ) */
8256 ImplGetParent()->ImplCallActivateListeners( pOld );
8257 else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
8259 // top level frame reached: store hint for DefModalDialogParent
8260 ImplGetSVData()->maWinData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
8266 // -----------------------------------------------------------------------
8268 bool Window::ImplStopDnd()
8270 bool bRet = false;
8271 if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
8273 bRet = true;
8274 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8275 mpWindowImpl->mpFrameData->mxDragSource.clear();
8276 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
8279 return bRet;
8282 // -----------------------------------------------------------------------
8284 void Window::ImplStartDnd()
8286 GetDropTarget();
8289 // -----------------------------------------------------------------------
8291 uno::Reference< XDropTarget > Window::GetDropTarget()
8293 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8295 if( ! mpWindowImpl->mxDNDListenerContainer.is() )
8297 sal_Int8 nDefaultActions = 0;
8299 if( mpWindowImpl->mpFrameData )
8301 if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
8303 // initialization is done in GetDragSource
8304 uno::Reference< XDragSource > xDragSource = GetDragSource();
8307 if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
8309 nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
8311 if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
8313 mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
8317 mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
8319 // register also as drag gesture listener if directly supported by drag source
8320 uno::Reference< XDragGestureRecognizer > xDragGestureRecognizer =
8321 uno::Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
8323 if( xDragGestureRecognizer.is() )
8325 xDragGestureRecognizer->addDragGestureListener(
8326 uno::Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
8328 else
8329 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = sal_True;
8332 catch (const RuntimeException&)
8334 // release all instances
8335 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8336 mpWindowImpl->mpFrameData->mxDragSource.clear();
8343 mpWindowImpl->mxDNDListenerContainer = static_cast < XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
8346 // this object is located in the same process, so there will be no runtime exception
8347 return uno::Reference< XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
8350 // -----------------------------------------------------------------------
8352 uno::Reference< XDragSource > Window::GetDragSource()
8354 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8356 #if HAVE_FEATURE_DESKTOP
8358 if( mpWindowImpl->mpFrameData )
8360 if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
8364 uno::Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
8365 const SystemEnvData * pEnvData = GetSystemData();
8367 if( pEnvData )
8369 Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
8370 OUString aDragSourceSN, aDropTargetSN;
8371 #if defined WNT
8372 aDragSourceSN = OUString("com.sun.star.datatransfer.dnd.OleDragSource");
8373 aDropTargetSN = OUString("com.sun.star.datatransfer.dnd.OleDropTarget");
8374 aDragSourceAL[ 1 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
8375 aDropTargetAL[ 0 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
8376 #elif defined MACOSX
8377 /* FIXME: Mac OS X specific dnd interface does not exist! *
8378 * Using Windows based dnd as a temporary solution */
8379 aDragSourceSN = OUString("com.sun.star.datatransfer.dnd.OleDragSource");
8380 aDropTargetSN = OUString("com.sun.star.datatransfer.dnd.OleDropTarget");
8381 aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) );
8382 aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) );
8383 #elif defined UNX
8384 aDropTargetAL.realloc( 3 );
8385 aDragSourceAL.realloc( 3 );
8386 aDragSourceSN = OUString("com.sun.star.datatransfer.dnd.X11DragSource");
8387 aDropTargetSN = OUString("com.sun.star.datatransfer.dnd.X11DropTarget");
8389 aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
8390 aDragSourceAL[ 2 ] = makeAny( vcl::createBmpConverter() );
8391 aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
8392 aDropTargetAL[ 1 ] = makeAny( (sal_Size)(pEnvData->aShellWindow) );
8393 aDropTargetAL[ 2 ] = makeAny( vcl::createBmpConverter() );
8394 #endif
8395 if( !aDragSourceSN.isEmpty() )
8396 mpWindowImpl->mpFrameData->mxDragSource.set(
8397 xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDragSourceSN, aDragSourceAL, xContext ),
8398 UNO_QUERY );
8400 if( !aDropTargetSN.isEmpty() )
8401 mpWindowImpl->mpFrameData->mxDropTarget.set(
8402 xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDropTargetSN, aDropTargetAL, xContext ),
8403 UNO_QUERY );
8407 // createInstance can throw any exception
8408 catch (const Exception&)
8410 // release all instances
8411 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8412 mpWindowImpl->mpFrameData->mxDragSource.clear();
8416 return mpWindowImpl->mpFrameData->mxDragSource;
8418 #endif
8419 return uno::Reference< XDragSource > ();
8422 // -----------------------------------------------------------------------
8424 uno::Reference< XDragGestureRecognizer > Window::GetDragGestureRecognizer()
8426 return uno::Reference< XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
8429 // -----------------------------------------------------------------------
8431 uno::Reference< XClipboard > Window::GetClipboard()
8433 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8435 if( mpWindowImpl->mpFrameData )
8437 if( ! mpWindowImpl->mpFrameData->mxClipboard.is() )
8441 uno::Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
8443 mpWindowImpl->mpFrameData->mxClipboard = uno::Reference< XClipboard >( xFactory->createInstance( OUString("com.sun.star.datatransfer.clipboard.SystemClipboard") ), UNO_QUERY );
8445 #if defined(UNX) && !defined(MACOSX) // unix clipboard needs to be initialized
8446 if( mpWindowImpl->mpFrameData->mxClipboard.is() )
8448 uno::Reference< XInitialization > xInit = uno::Reference< XInitialization >( mpWindowImpl->mpFrameData->mxClipboard, UNO_QUERY );
8450 if( xInit.is() )
8452 Sequence< Any > aArgumentList( 3 );
8453 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
8454 aArgumentList[ 1 ] = makeAny( OUString("CLIPBOARD") );
8455 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
8457 xInit->initialize( aArgumentList );
8460 #endif
8463 // createInstance can throw any exception
8464 catch (const Exception&)
8466 // release all instances
8467 mpWindowImpl->mpFrameData->mxClipboard.clear();
8471 return mpWindowImpl->mpFrameData->mxClipboard;
8474 return static_cast < XClipboard * > (0);
8477 // -----------------------------------------------------------------------
8479 uno::Reference< XClipboard > Window::GetPrimarySelection()
8481 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8483 if( mpWindowImpl->mpFrameData )
8485 if( ! mpWindowImpl->mpFrameData->mxSelection.is() )
8489 #if defined(UNX) && !defined(MACOSX)
8490 uno::Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
8492 Sequence< Any > aArgumentList( 3 );
8493 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
8494 aArgumentList[ 1 ] = makeAny( OUString("PRIMARY") );
8495 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
8497 mpWindowImpl->mpFrameData->mxSelection = uno::Reference< XClipboard >( xFactory->createInstanceWithArguments(
8498 OUString("com.sun.star.datatransfer.clipboard.SystemClipboard"), aArgumentList ), UNO_QUERY );
8499 # else
8500 uno::Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
8502 static uno::Reference< XClipboard > s_xSelection(
8503 xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.datatransfer.clipboard.GenericClipboard", xContext ), UNO_QUERY );
8505 mpWindowImpl->mpFrameData->mxSelection = s_xSelection;
8506 # endif
8509 // createInstance can throw any exception
8510 catch (const Exception&)
8512 // release all instances
8513 mpWindowImpl->mpFrameData->mxSelection.clear();
8517 return mpWindowImpl->mpFrameData->mxSelection;
8520 return static_cast < XClipboard * > (0);
8523 // -----------------------------------------------------------------------
8524 // Accessibility
8525 // -----------------------------------------------------------------------
8527 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::GetAccessible( sal_Bool bCreate )
8529 // do not optimize hierarchy for the top level border win (ie, when there is no parent)
8530 /* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy
8531 if ( GetParent() && ( GetType() == WINDOW_BORDERWINDOW ) && ( GetChildCount() == 1 ) )
8532 //if( !ImplIsAccessibleCandidate() )
8534 Window* pChild = GetAccessibleChildWindow( 0 );
8535 if ( pChild )
8536 return pChild->GetAccessible();
8539 if ( !mpWindowImpl->mxAccessible.is() && bCreate )
8540 mpWindowImpl->mxAccessible = CreateAccessible();
8542 return mpWindowImpl->mxAccessible;
8545 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
8547 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( sal_True ), ::com::sun::star::uno::UNO_QUERY );
8548 return xAcc;
8551 void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x )
8553 mpWindowImpl->mxAccessible = x;
8556 // skip all border windows that are no top level frames
8557 sal_Bool Window::ImplIsAccessibleCandidate() const
8559 if( !mpWindowImpl->mbBorderWin )
8560 return sal_True;
8561 else
8562 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
8563 if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) )
8564 return sal_True;
8565 else
8566 return sal_False;
8569 sal_Bool Window::ImplIsAccessibleNativeFrame() const
8571 if( mpWindowImpl->mbFrame )
8572 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
8573 if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
8574 return sal_True;
8575 else
8576 return sal_False;
8577 else
8578 return sal_False;
8581 sal_uInt16 Window::ImplGetAccessibleCandidateChildWindowCount( sal_uInt16 nFirstWindowType ) const
8583 sal_uInt16 nChildren = 0;
8584 Window* pChild = GetWindow( nFirstWindowType );
8585 while ( pChild )
8587 if( pChild->ImplIsAccessibleCandidate() )
8588 nChildren++;
8589 else
8590 nChildren = sal::static_int_cast<sal_uInt16>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD ));
8591 pChild = pChild->mpWindowImpl->mpNext;
8593 return nChildren;
8596 Window* Window::ImplGetAccessibleCandidateChild( sal_uInt16 nChild, sal_uInt16& rChildCount, sal_uInt16 nFirstWindowType, sal_Bool bTopLevel ) const
8598 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8600 if( bTopLevel )
8601 rChildCount = 0;
8603 Window* pChild = GetWindow( nFirstWindowType );
8604 while ( pChild )
8606 Window *pTmpChild = pChild;
8608 if( !pChild->ImplIsAccessibleCandidate() )
8609 pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, WINDOW_FIRSTCHILD, sal_False );
8611 if ( nChild == rChildCount )
8612 return pTmpChild;
8613 pChild = pChild->mpWindowImpl->mpNext;
8614 rChildCount++;
8617 return NULL;
8620 Window* Window::GetAccessibleParentWindow() const
8622 if ( ImplIsAccessibleNativeFrame() )
8623 return NULL;
8625 Window* pParent = mpWindowImpl->mpParent;
8626 if( GetType() == WINDOW_MENUBARWINDOW )
8628 // report the menubar as a child of THE workwindow
8629 Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild;
8630 while( pWorkWin && (pWorkWin == this) )
8631 pWorkWin = pWorkWin->mpWindowImpl->mpNext;
8632 pParent = pWorkWin;
8634 // If this is a floating window which has a native border window, then that border should be reported as
8635 // the accessible parent, unless the floating window is a PopupMenuFloatingWindow
8637 // The logic here has to match that of AccessibleFactory::createAccessibleContext in
8638 // accessibility/source/helper/acc_factory.cxx to avoid PopupMenuFloatingWindow
8639 // becoming a11y parents of themselves
8640 else if( GetType() == WINDOW_FLOATINGWINDOW &&
8641 mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
8642 !PopupMenuFloatingWindow::isPopupMenu(this))
8644 pParent = mpWindowImpl->mpBorderWindow;
8646 else if( pParent && !pParent->ImplIsAccessibleCandidate() )
8648 pParent = pParent->mpWindowImpl->mpParent;
8650 return pParent;
8653 sal_uInt16 Window::GetAccessibleChildWindowCount()
8655 sal_uInt16 nChildren = 0;
8656 Window* pChild = mpWindowImpl->mpFirstChild;
8657 while( pChild )
8659 if( pChild->IsVisible() )
8660 nChildren++;
8661 pChild = pChild->mpWindowImpl->mpNext;
8664 // #107176# ignore overlapwindows
8665 // this only affects non-system floating windows
8666 // which are either not accessible (like the HelpAgent) or should be changed to system windows anyway
8668 if( ImplIsOverlapWindow() )
8670 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
8671 while ( pOverlap )
8673 if( pOverlap->IsVisible() )
8674 nChildren++;
8675 pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
8680 // report the menubarwindow as a child of THE workwindow
8681 if( GetType() == WINDOW_BORDERWINDOW )
8683 if( ((ImplBorderWindow *) this)->mpMenuBarWindow &&
8684 ((ImplBorderWindow *) this)->mpMenuBarWindow->IsVisible()
8686 --nChildren;
8688 else if( GetType() == WINDOW_WORKWINDOW )
8690 if( ((WorkWindow *) this)->GetMenuBar() &&
8691 ((WorkWindow *) this)->GetMenuBar()->GetWindow() &&
8692 ((WorkWindow *) this)->GetMenuBar()->GetWindow()->IsVisible()
8694 ++nChildren;
8697 return nChildren;
8700 Window* Window::GetAccessibleChildWindow( sal_uInt16 n )
8702 // report the menubarwindow as a the first child of THE workwindow
8703 if( GetType() == WINDOW_WORKWINDOW && ((WorkWindow *) this)->GetMenuBar() )
8705 if( n == 0 )
8707 MenuBar *pMenuBar = ((WorkWindow *) this)->GetMenuBar();
8708 if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
8709 return pMenuBar->GetWindow();
8711 else
8712 --n;
8715 // transform n to child number including invisible children
8716 sal_uInt16 nChildren = n;
8717 Window* pChild = mpWindowImpl->mpFirstChild;
8718 while( pChild )
8720 if( pChild->IsVisible() )
8722 if( ! nChildren )
8723 break;
8724 nChildren--;
8726 pChild = pChild->mpWindowImpl->mpNext;
8729 if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
8731 do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() );
8732 DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
8734 if ( !pChild )
8736 // #107176# ignore overlapwindows
8738 if( ImplIsOverlapWindow() )
8740 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
8741 while ( !pChild && pOverlap )
8743 if ( !nChildren && pOverlap->IsVisible() )
8745 pChild = pOverlap;
8746 break;
8748 pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
8749 if( pOverlap && pOverlap->IsVisible() )
8750 nChildren--;
8756 if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
8758 pChild = pChild->GetChild( 0 );
8760 return pChild;
8764 void Window::SetAccessibleRole( sal_uInt16 nRole )
8766 if ( !mpWindowImpl->mpAccessibleInfos )
8767 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
8769 DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
8770 mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole;
8773 sal_uInt16 Window::getDefaultAccessibleRole() const
8775 sal_uInt16 nRole = 0xFFFF;
8776 switch ( GetType() )
8778 case WINDOW_MESSBOX: // MT: Would be nice to have special roles!
8779 case WINDOW_INFOBOX:
8780 case WINDOW_WARNINGBOX:
8781 case WINDOW_ERRORBOX:
8782 case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break;
8784 case WINDOW_MODELESSDIALOG:
8785 case WINDOW_MODALDIALOG:
8786 case WINDOW_SYSTEMDIALOG:
8787 case WINDOW_PRINTERSETUPDIALOG:
8788 case WINDOW_PRINTDIALOG:
8789 case WINDOW_TABDIALOG:
8790 case WINDOW_BUTTONDIALOG:
8791 case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break;
8793 case WINDOW_PUSHBUTTON:
8794 case WINDOW_OKBUTTON:
8795 case WINDOW_CANCELBUTTON:
8796 case WINDOW_HELPBUTTON:
8797 case WINDOW_IMAGEBUTTON:
8798 case WINDOW_MENUBUTTON:
8799 case WINDOW_MOREBUTTON:
8800 case WINDOW_SPINBUTTON:
8801 case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break;
8803 case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
8804 case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
8805 case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break;
8806 case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break;
8808 case WINDOW_IMAGERADIOBUTTON:
8809 case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break;
8810 case WINDOW_TRISTATEBOX:
8811 case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break;
8813 case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
8815 case WINDOW_PATTERNFIELD:
8816 case WINDOW_NUMERICFIELD:
8817 case WINDOW_METRICFIELD:
8818 case WINDOW_CURRENCYFIELD:
8819 case WINDOW_LONGCURRENCYFIELD:
8820 case WINDOW_CALCINPUTLINE:
8821 case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break;
8823 case WINDOW_PATTERNBOX:
8824 case WINDOW_NUMERICBOX:
8825 case WINDOW_METRICBOX:
8826 case WINDOW_CURRENCYBOX:
8827 case WINDOW_LONGCURRENCYBOX:
8828 case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break;
8830 case WINDOW_LISTBOX:
8831 case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
8833 case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break;
8835 case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
8836 case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break;
8837 case WINDOW_FIXEDBITMAP:
8838 case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
8839 case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break;
8840 case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
8842 case WINDOW_SLIDER:
8843 case WINDOW_SPLITTER:
8844 case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
8846 case WINDOW_DATEBOX:
8847 case WINDOW_TIMEBOX:
8848 case WINDOW_DATEFIELD:
8849 case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
8851 case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
8853 case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
8854 case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break;
8856 case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break;
8857 case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
8859 case WINDOW_DOCKINGWINDOW:
8860 case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME :
8861 accessibility::AccessibleRole::PANEL; break;
8863 case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame ||
8864 (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ||
8865 (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME :
8866 accessibility::AccessibleRole::WINDOW; break;
8868 case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break;
8871 case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
8873 case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break;
8875 case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break;
8877 case WINDOW_SCROLLWINDOW: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
8879 case WINDOW_WINDOW:
8880 case WINDOW_CONTROL:
8881 case WINDOW_BORDERWINDOW:
8882 case WINDOW_SYSTEMCHILDWINDOW:
8883 default:
8884 if (ImplIsAccessibleNativeFrame() )
8885 nRole = accessibility::AccessibleRole::FRAME;
8886 else if( IsScrollable() )
8887 nRole = accessibility::AccessibleRole::SCROLL_PANE;
8888 else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() )
8889 nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenus are windows (i.e. toplevel)
8890 else
8891 // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead
8892 // a WINDOW is interpreted as a top-level window, which is typically not the case
8893 //nRole = accessibility::AccessibleRole::WINDOW;
8894 nRole = accessibility::AccessibleRole::PANEL;
8896 return nRole;
8899 sal_uInt16 Window::GetAccessibleRole() const
8901 using namespace ::com::sun::star;
8903 sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF;
8904 if ( nRole == 0xFFFF )
8905 nRole = getDefaultAccessibleRole();
8906 return nRole;
8909 void Window::SetAccessibleName( const String& rName )
8911 if ( !mpWindowImpl->mpAccessibleInfos )
8912 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
8914 delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
8915 mpWindowImpl->mpAccessibleInfos->pAccessibleName = new String( rName );
8918 String Window::GetAccessibleName() const
8920 if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName)
8921 return *mpWindowImpl->mpAccessibleInfos->pAccessibleName;
8922 return getDefaultAccessibleName();
8925 OUString Window::getDefaultAccessibleName() const
8927 OUString aAccessibleName;
8928 switch ( GetType() )
8930 case WINDOW_MULTILINEEDIT:
8931 case WINDOW_PATTERNFIELD:
8932 case WINDOW_NUMERICFIELD:
8933 case WINDOW_METRICFIELD:
8934 case WINDOW_CURRENCYFIELD:
8935 case WINDOW_LONGCURRENCYFIELD:
8936 case WINDOW_CALCINPUTLINE:
8937 case WINDOW_EDIT:
8939 case WINDOW_DATEBOX:
8940 case WINDOW_TIMEBOX:
8941 case WINDOW_CURRENCYBOX:
8942 case WINDOW_LONGCURRENCYBOX:
8943 case WINDOW_DATEFIELD:
8944 case WINDOW_TIMEFIELD:
8945 case WINDOW_SPINFIELD:
8947 case WINDOW_COMBOBOX:
8948 case WINDOW_LISTBOX:
8949 case WINDOW_MULTILISTBOX:
8950 case WINDOW_TREELISTBOX:
8951 case WINDOW_METRICBOX:
8953 Window *pLabel = GetAccessibleRelationLabeledBy();
8954 if ( pLabel && pLabel != this )
8955 aAccessibleName = pLabel->GetText();
8957 break;
8959 case WINDOW_IMAGEBUTTON:
8960 case WINDOW_PUSHBUTTON:
8961 aAccessibleName = GetText();
8962 if (aAccessibleName.isEmpty())
8964 aAccessibleName = GetQuickHelpText();
8965 if (aAccessibleName.isEmpty())
8966 aAccessibleName = GetHelpText();
8968 break;
8970 default:
8971 aAccessibleName = GetText();
8972 break;
8975 return GetNonMnemonicString( aAccessibleName );
8978 void Window::SetAccessibleDescription( const String& rDescription )
8980 if ( ! mpWindowImpl->mpAccessibleInfos )
8981 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
8983 DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
8984 delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
8985 mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new String( rDescription );
8988 String Window::GetAccessibleDescription() const
8990 String aAccessibleDescription;
8991 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
8993 aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
8995 else
8997 // Special code for help text windows. ZT asks the border window for the
8998 // description so we have to forward this request to our inner window.
8999 const Window* pWin = ((Window *)this)->ImplGetWindow();
9000 if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW )
9001 aAccessibleDescription = pWin->GetHelpText();
9002 else
9003 aAccessibleDescription = GetHelpText();
9006 return aAccessibleDescription;
9009 void Window::SetAccessibleRelationLabeledBy( Window* pLabeledBy )
9011 if ( !mpWindowImpl->mpAccessibleInfos )
9012 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9013 mpWindowImpl->mpAccessibleInfos->pLabeledByWindow = pLabeledBy;
9016 void Window::SetAccessibleRelationLabelFor( Window* pLabelFor )
9018 if ( !mpWindowImpl->mpAccessibleInfos )
9019 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9020 mpWindowImpl->mpAccessibleInfos->pLabelForWindow = pLabelFor;
9023 void Window::SetAccessibleRelationMemberOf( Window* pMemberOfWin )
9025 if ( !mpWindowImpl->mpAccessibleInfos )
9026 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9027 mpWindowImpl->mpAccessibleInfos->pMemberOfWindow = pMemberOfWin;
9030 Window* Window::GetAccessibleRelationMemberOf() const
9032 if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pMemberOfWindow)
9033 return mpWindowImpl->mpAccessibleInfos->pMemberOfWindow;
9035 if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
9036 return getLegacyNonLayoutAccessibleRelationMemberOf();
9038 return NULL;
9041 Window* Window::getAccessibleRelationLabelFor() const
9043 if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow)
9044 return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
9046 return NULL;
9049 Window* Window::GetAccessibleRelationLabelFor() const
9051 Window* pWindow = getAccessibleRelationLabelFor();
9053 if (pWindow)
9054 return pWindow;
9056 if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
9057 return getLegacyNonLayoutAccessibleRelationLabelFor();
9059 return NULL;
9062 Window* Window::GetAccessibleRelationLabeledBy() const
9064 if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow)
9065 return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
9067 std::vector<FixedText*> m_aMnemonicLabels(list_mnemonic_labels());
9068 if (!m_aMnemonicLabels.empty())
9070 SAL_WARN_IF(m_aMnemonicLabels.size() != 1, "vcl.a11y", "TODO: multiple LabeledBy not handled yet");
9071 return m_aMnemonicLabels[0];
9074 if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
9075 return getLegacyNonLayoutAccessibleRelationLabeledBy();
9077 return NULL;
9080 sal_Bool Window::IsAccessibilityEventsSuppressed( sal_Bool bTraverseParentPath )
9082 if( !bTraverseParentPath )
9083 return mpWindowImpl->mbSuppressAccessibilityEvents;
9084 else
9086 Window *pParent = this;
9087 while ( pParent && pParent->mpWindowImpl)
9089 if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents )
9090 return sal_True;
9091 else
9092 pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
9094 return sal_False;
9098 void Window::SetAccessibilityEventsSuppressed(sal_Bool bSuppressed)
9100 mpWindowImpl->mbSuppressAccessibilityEvents = bSuppressed;
9103 void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const Rectangle& rRect )
9105 if( ! mpOutDevData )
9106 ImplInitOutDevData();
9107 mpOutDevData->mpRecordLayout = pLayout;
9108 mpOutDevData->maRecordRect = rRect;
9109 Paint( rRect );
9110 mpOutDevData->mpRecordLayout = NULL;
9113 // -----------------------------------------------------------------------
9115 void Window::DrawSelectionBackground( const Rectangle& rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bDrawBorder, sal_Bool bDrawExtBorderOnly )
9117 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, NULL, NULL );
9120 void Window::DrawSelectionBackground( const Rectangle& rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bDrawBorder, sal_Bool bDrawExtBorderOnly, Color* pSelectionTextColor )
9122 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, pSelectionTextColor, NULL );
9125 void Window::DrawSelectionBackground( const Rectangle& rRect,
9126 sal_uInt16 highlight,
9127 sal_Bool bChecked,
9128 sal_Bool bDrawBorder,
9129 sal_Bool bDrawExtBorderOnly,
9130 long nCornerRadius,
9131 Color* pSelectionTextColor,
9132 Color* pPaintColor
9135 if( rRect.IsEmpty() )
9136 return;
9138 bool bRoundEdges = nCornerRadius > 0;
9140 const StyleSettings& rStyles = GetSettings().GetStyleSettings();
9143 // colors used for item highlighting
9144 Color aSelectionBorderCol( pPaintColor ? *pPaintColor : rStyles.GetHighlightColor() );
9145 Color aSelectionFillCol( aSelectionBorderCol );
9147 sal_Bool bDark = rStyles.GetFaceColor().IsDark();
9148 sal_Bool bBright = ( rStyles.GetFaceColor() == Color( COL_WHITE ) );
9150 int c1 = aSelectionBorderCol.GetLuminance();
9151 int c2 = GetDisplayBackground().GetColor().GetLuminance();
9153 if( !bDark && !bBright && abs( c2-c1 ) < (pPaintColor ? 40 : 75) )
9155 // constrast too low
9156 sal_uInt16 h,s,b;
9157 aSelectionFillCol.RGBtoHSB( h, s, b );
9158 if( b > 50 ) b -= 40;
9159 else b += 40;
9160 aSelectionFillCol.SetColor( Color::HSBtoRGB( h, s, b ) );
9161 aSelectionBorderCol = aSelectionFillCol;
9164 if( bRoundEdges )
9166 if( aSelectionBorderCol.IsDark() )
9167 aSelectionBorderCol.IncreaseLuminance( 128 );
9168 else
9169 aSelectionBorderCol.DecreaseLuminance( 128 );
9172 Rectangle aRect( rRect );
9173 if( bDrawExtBorderOnly )
9175 --aRect.Left();
9176 --aRect.Top();
9177 ++aRect.Right();
9178 ++aRect.Bottom();
9180 Color oldFillCol = GetFillColor();
9181 Color oldLineCol = GetLineColor();
9183 if( bDrawBorder )
9184 SetLineColor( bDark ? Color(COL_WHITE) : ( bBright ? Color(COL_BLACK) : aSelectionBorderCol ) );
9185 else
9186 SetLineColor();
9188 sal_uInt16 nPercent = 0;
9189 if( !highlight )
9191 if( bDark )
9192 aSelectionFillCol = COL_BLACK;
9193 else
9194 nPercent = 80; // just checked (light)
9196 else
9198 if( bChecked && highlight == 2 )
9200 if( bDark )
9201 aSelectionFillCol = COL_LIGHTGRAY;
9202 else if ( bBright )
9204 aSelectionFillCol = COL_BLACK;
9205 SetLineColor( COL_BLACK );
9206 nPercent = 0;
9208 else
9209 nPercent = bRoundEdges ? 40 : 20; // selected, pressed or checked ( very dark )
9211 else if( bChecked || highlight == 1 )
9213 if( bDark )
9214 aSelectionFillCol = COL_GRAY;
9215 else if ( bBright )
9217 aSelectionFillCol = COL_BLACK;
9218 SetLineColor( COL_BLACK );
9219 nPercent = 0;
9221 else
9222 nPercent = bRoundEdges ? 60 : 35; // selected, pressed or checked ( very dark )
9224 else
9226 if( bDark )
9227 aSelectionFillCol = COL_LIGHTGRAY;
9228 else if ( bBright )
9230 aSelectionFillCol = COL_BLACK;
9231 SetLineColor( COL_BLACK );
9232 if( highlight == 3 )
9233 nPercent = 80;
9234 else
9235 nPercent = 0;
9237 else
9238 nPercent = 70; // selected ( dark )
9242 if( bDark && bDrawExtBorderOnly )
9244 SetFillColor();
9245 if( pSelectionTextColor )
9246 *pSelectionTextColor = rStyles.GetHighlightTextColor();
9248 else
9250 SetFillColor( aSelectionFillCol );
9251 if( pSelectionTextColor )
9253 Color aTextColor = IsControlBackground() ? GetControlForeground() : rStyles.GetButtonTextColor();
9254 Color aHLTextColor = rStyles.GetHighlightTextColor();
9255 int nTextDiff = abs(aSelectionFillCol.GetLuminance() - aTextColor.GetLuminance());
9256 int nHLDiff = abs(aSelectionFillCol.GetLuminance() - aHLTextColor.GetLuminance());
9257 *pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor;
9262 if( bDark )
9264 DrawRect( aRect );
9266 else
9268 if( bRoundEdges )
9270 Polygon aPoly( aRect, nCornerRadius, nCornerRadius );
9271 PolyPolygon aPolyPoly( aPoly );
9272 DrawTransparent( aPolyPoly, nPercent );
9274 else
9276 Polygon aPoly( aRect );
9277 PolyPolygon aPolyPoly( aPoly );
9278 DrawTransparent( aPolyPoly, nPercent );
9282 SetFillColor( oldFillCol );
9283 SetLineColor( oldLineCol );
9286 // controls should return the window that gets the
9287 // focus by default, so keyevents can be sent to that window directly
9288 Window* Window::GetPreferredKeyInputWindow()
9290 return this;
9294 sal_Bool Window::IsScrollable() const
9296 // check for scrollbars
9297 Window *pChild = mpWindowImpl->mpFirstChild;
9298 while( pChild )
9300 if( pChild->GetType() == WINDOW_SCROLLBAR )
9301 return true;
9302 else
9303 pChild = pChild->mpWindowImpl->mpNext;
9305 return false;
9308 sal_Bool Window::IsTopWindow() const
9310 if ( mpWindowImpl->mbInDtor )
9311 return sal_False;
9313 // topwindows must be frames or they must have a borderwindow which is a frame
9314 if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) )
9315 return sal_False;
9317 ImplGetWinData();
9318 if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized
9320 // #113722#, cache result of expensive queryInterface call
9321 Window *pThisWin = (Window*)this;
9322 uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
9323 pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
9325 return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? sal_True : sal_False;
9328 void Window::ImplMirrorFramePos( Point &pt ) const
9330 pt.X() = mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X();
9333 // frame based modal counter (dialogs are not modal to the whole application anymore)
9334 sal_Bool Window::IsInModalMode() const
9336 return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
9339 bool Window::IsInModalNonRefMode() const
9341 if(mpWindowImpl->mnStyle & WB_REFMODE)
9342 return false;
9344 return IsInModalMode();
9347 void Window::ImplIncModalCount()
9349 Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
9350 Window* pParent = pFrameWindow;
9351 while( pFrameWindow )
9353 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
9354 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
9356 pParent = pParent->GetParent();
9358 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
9361 void Window::ImplDecModalCount()
9363 Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
9364 Window* pParent = pFrameWindow;
9365 while( pFrameWindow )
9367 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
9368 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
9370 pParent = pParent->GetParent();
9372 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
9376 void Window::ImplIsInTaskPaneList( sal_Bool mbIsInTaskList )
9378 mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
9381 void Window::ImplNotifyIconifiedState( sal_Bool bIconified )
9383 mpWindowImpl->mpFrameWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
9384 // #109206# notify client window as well to have toolkit topwindow listeners notified
9385 if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
9386 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
9389 sal_Bool Window::HasActiveChildFrame()
9391 sal_Bool bRet = sal_False;
9392 Window *pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
9393 while( pFrameWin )
9395 if( pFrameWin != mpWindowImpl->mpFrameWindow )
9397 sal_Bool bDecorated = sal_False;
9398 Window *pChildFrame = pFrameWin->ImplGetWindow();
9399 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
9400 // be removed for ToolBoxes to influence the keyboard accessibility
9401 // thus WB_MOVEABLE is no indicator for decoration anymore
9402 // but FloatingWindows carry this information in their TitleType...
9403 // TODO: avoid duplicate WinBits !!!
9404 if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
9405 bDecorated = ((FloatingWindow*) pChildFrame)->GetTitleType() != FLOATWIN_TITLE_NONE;
9406 if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
9407 if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
9409 if( ImplIsChild( pChildFrame, sal_True ) )
9411 bRet = sal_True;
9412 break;
9416 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
9418 return bRet;
9421 LanguageType Window::GetInputLanguage() const
9423 return mpWindowImpl->mpFrame->GetInputLanguage();
9426 void Window::EnableNativeWidget( sal_Bool bEnable )
9428 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
9429 if( pNoNWF && *pNoNWF )
9430 bEnable = sal_False;
9432 if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
9434 ImplGetWinData()->mbEnableNativeWidget = bEnable;
9436 // send datachanged event to allow for internal changes required for NWF
9437 // like clipmode, transparency, etc.
9438 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &maSettings, SETTINGS_STYLE );
9439 DataChanged( aDCEvt );
9441 // sometimes the borderwindow is queried, so keep it in sync
9442 if( mpWindowImpl->mpBorderWindow )
9443 mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
9446 // push down, useful for compound controls
9447 Window *pChild = mpWindowImpl->mpFirstChild;
9448 while( pChild )
9450 pChild->EnableNativeWidget( bEnable );
9451 pChild = pChild->mpWindowImpl->mpNext;
9455 sal_Bool Window::IsNativeWidgetEnabled() const
9457 return ImplGetWinData()->mbEnableNativeWidget;
9460 #ifdef WNT // see #140456#
9461 #include <win/salframe.h>
9462 #endif
9464 uno::Reference< rendering::XCanvas > Window::ImplGetCanvas( const Size& rFullscreenSize,
9465 bool bFullscreen,
9466 bool bSpriteCanvas ) const
9468 // try to retrieve hard reference from weak member
9469 uno::Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
9471 // canvas still valid? Then we're done.
9472 if( xCanvas.is() )
9473 return xCanvas;
9475 Sequence< Any > aArg(6);
9477 // Feed any with operating system's window handle
9478 // ==============================================
9480 // common: first any is VCL pointer to window (for VCL canvas)
9481 aArg[ 0 ] = makeAny( reinterpret_cast<sal_Int64>(this) );
9483 // TODO(Q1): Make GetSystemData method virtual
9485 // check whether we're a SysChild: have to fetch system data
9486 // directly from SystemChildWindow, because the GetSystemData
9487 // method is unfortunately not virtual
9488 const SystemChildWindow* pSysChild = dynamic_cast< const SystemChildWindow* >( this );
9489 if( pSysChild )
9491 aArg[ 1 ] = pSysChild->GetSystemDataAny();
9492 aArg[ 5 ] = pSysChild->GetSystemGfxDataAny();
9494 else
9496 aArg[ 1 ] = GetSystemDataAny();
9497 aArg[ 5 ] = GetSystemGfxDataAny();
9500 if( bFullscreen )
9501 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( 0, 0,
9502 rFullscreenSize.Width(),
9503 rFullscreenSize.Height() ) );
9504 else
9505 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
9507 aArg[ 3 ] = makeAny( mpWindowImpl->mbAlwaysOnTop ? sal_True : sal_False );
9508 aArg[ 4 ] = makeAny( uno::Reference< awt::XWindow >(
9509 const_cast<Window*>(this)->GetComponentInterface(),
9510 uno::UNO_QUERY ));
9512 uno::Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
9514 // Create canvas instance with window handle
9515 // =========================================
9516 static ::vcl::DeleteUnoReferenceOnDeinit<lang::XMultiComponentFactory> xStaticCanvasFactory(
9517 rendering::CanvasFactory::create( xContext ) );
9518 uno::Reference<lang::XMultiComponentFactory> xCanvasFactory(xStaticCanvasFactory.get());
9520 if(xCanvasFactory.is())
9522 #ifdef WNT
9523 // see #140456# - if we're running on a multiscreen setup,
9524 // request special, multi-screen safe sprite canvas
9525 // implementation (not DX5 canvas, as it cannot cope with
9526 // surfaces spanning multiple displays). Note: canvas
9527 // (without sprite) stays the same)
9528 const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay;
9529 if( (nDisplay >= Application::GetScreenCount()) )
9531 xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
9532 bSpriteCanvas ?
9533 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
9534 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
9535 aArg,
9536 xContext ),
9537 UNO_QUERY );
9540 else
9542 #endif
9543 xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
9544 bSpriteCanvas ?
9545 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
9546 OUString( "com.sun.star.rendering.Canvas" ),
9547 aArg,
9548 xContext ),
9549 UNO_QUERY );
9551 #ifdef WNT
9553 #endif
9554 mpWindowImpl->mxCanvas = xCanvas;
9557 // no factory??? Empty reference, then.
9558 return xCanvas;
9561 uno::Reference< rendering::XCanvas > Window::GetCanvas() const
9563 return ImplGetCanvas( Size(), false, false );
9566 uno::Reference< rendering::XSpriteCanvas > Window::GetSpriteCanvas() const
9568 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas(
9569 ImplGetCanvas( Size(), false, true ), uno::UNO_QUERY );
9570 return xSpriteCanvas;
9573 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
9575 sal_Bool bRVisible = mpWindowImpl->mbReallyVisible;
9576 mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
9577 sal_Bool bDevOutput = mbDevOutput;
9578 mbDevOutput = sal_True;
9580 long nOldDPIX = ImplGetDPIX();
9581 long nOldDPIY = ImplGetDPIY();
9582 mnDPIX = i_pTargetOutDev->ImplGetDPIX();
9583 mnDPIY = i_pTargetOutDev->ImplGetDPIY();
9584 sal_Bool bOutput = IsOutputEnabled();
9585 EnableOutput();
9587 DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
9588 if ( GetMapMode().GetMapUnit() != MAP_PIXEL )
9589 return;
9591 // preserve graphicsstate
9592 Push();
9593 Region aClipRegion( GetClipRegion() );
9594 SetClipRegion();
9596 GDIMetaFile* pOldMtf = GetConnectMetaFile();
9597 GDIMetaFile aMtf;
9598 SetConnectMetaFile( &aMtf );
9600 // put a push action to metafile
9601 Push();
9602 // copy graphics state to metafile
9603 Font aCopyFont = GetFont();
9604 if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY )
9606 aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY );
9607 aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX );
9609 SetFont( aCopyFont );
9610 SetTextColor( GetTextColor() );
9611 if( IsLineColor() )
9612 SetLineColor( GetLineColor() );
9613 else
9614 SetLineColor();
9615 if( IsFillColor() )
9616 SetFillColor( GetFillColor() );
9617 else
9618 SetFillColor();
9619 if( IsTextLineColor() )
9620 SetTextLineColor( GetTextLineColor() );
9621 else
9622 SetTextLineColor();
9623 if( IsOverlineColor() )
9624 SetOverlineColor( GetOverlineColor() );
9625 else
9626 SetOverlineColor();
9627 if( IsTextFillColor() )
9628 SetTextFillColor( GetTextFillColor() );
9629 else
9630 SetTextFillColor();
9631 SetTextAlign( GetTextAlign() );
9632 SetRasterOp( GetRasterOp() );
9633 if( IsRefPoint() )
9634 SetRefPoint( GetRefPoint() );
9635 else
9636 SetRefPoint();
9637 SetLayoutMode( GetLayoutMode() );
9638 SetDigitLanguage( GetDigitLanguage() );
9639 Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() );
9640 aClipRegion.Intersect( aPaintRect );
9641 SetClipRegion( aClipRegion );
9643 // do the actual paint
9645 // background
9646 if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & PARENTCLIPMODE_NOCLIP ) )
9647 Erase();
9648 // foreground
9649 Paint( aPaintRect );
9650 // put a pop action to metafile
9651 Pop();
9653 SetConnectMetaFile( pOldMtf );
9654 EnableOutput( bOutput );
9655 mpWindowImpl->mbReallyVisible = bRVisible;
9657 // paint metafile to VDev
9658 VirtualDevice* pMaskedDevice = new VirtualDevice( *i_pTargetOutDev, 0, 0 );
9659 pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
9660 pMaskedDevice->EnableRTL( IsRTLEnabled() );
9661 aMtf.WindStart();
9662 aMtf.Play( pMaskedDevice );
9663 BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) );
9664 i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
9665 // get rid of virtual device now so they don't pile up during recursive calls
9666 delete pMaskedDevice, pMaskedDevice = NULL;
9669 for( Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
9671 if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
9673 long nDeltaX = pChild->mnOutOffX - mnOutOffX;
9674 if( ImplHasMirroredGraphics() )
9675 nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth;
9676 long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
9677 Point aPos( i_rPos );
9678 Point aDelta( nDeltaX, nDeltaY );
9679 aPos += aDelta;
9680 pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
9684 // restore graphics state
9685 Pop();
9687 EnableOutput( bOutput );
9688 mpWindowImpl->mbReallyVisible = bRVisible;
9689 mbDevOutput = bDevOutput;
9690 mnDPIX = nOldDPIX;
9691 mnDPIY = nOldDPIY;
9694 void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ )
9696 // FIXME: scaling: currently this is for pixel copying only
9698 DBG_ASSERT( ! pDev->ImplHasMirroredGraphics(), "PaintToDevice to mirroring graphics" );
9699 DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" );
9701 Window* pRealParent = NULL;
9702 if( ! mpWindowImpl->mbVisible )
9704 Window* pTempParent = ImplGetDefaultWindow();
9705 if( pTempParent )
9706 pTempParent->EnableChildTransparentMode();
9707 pRealParent = GetParent();
9708 SetParent( pTempParent );
9709 // trigger correct visibility flags for children
9710 Show();
9711 Hide();
9714 sal_Bool bVisible = mpWindowImpl->mbVisible;
9715 mpWindowImpl->mbVisible = sal_True;
9717 if( mpWindowImpl->mpBorderWindow )
9718 mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
9719 else
9720 ImplPaintToDevice( pDev, rPos );
9722 mpWindowImpl->mbVisible = bVisible;
9724 if( pRealParent )
9725 SetParent( pRealParent );
9728 OUString Window::GetSurroundingText() const
9730 return OUString();
9733 Selection Window::GetSurroundingTextSelection() const
9735 return Selection( 0, 0 );
9738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */