1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #include "tools/time.hxx"
28 #include "tools/debug.hxx"
29 #include "tools/rc.h"
30
31 #include "unotools/fontcfg.hxx"
32 #include "unotools/confignode.hxx"
33
34 #include "vcl/unohelp.hxx"
35 #include "vcl/salgtype.hxx"
36 #include "vcl/event.hxx"
37 #include "vcl/help.hxx"
38 #include "vcl/cursor.hxx"
39 #include "vcl/svapp.hxx"
40 #include "vcl/window.hxx"
41 #include "vcl/syswin.hxx"
42 #include "vcl/syschild.hxx"
43 #include "vcl/dockwin.hxx"
44 #include "vcl/menu.hxx"
45 #include "vcl/wrkwin.hxx"
46 #include "vcl/wall.hxx"
47 #include "vcl/gradient.hxx"
48 #include "vcl/salctype.hxx"
49 #include "vcl/button.hxx"
50 #include "vcl/taskpanelist.hxx"
51 #include "vcl/dialog.hxx"
52 #include "vcl/unowrap.hxx"
53 #include "vcl/gdimtf.hxx"
54 #include "vcl/pdfextoutdevdata.hxx"
55 #include "vcl/lazydelete.hxx"
56
57 // declare system types in sysdata.hxx
58 #include "svsys.h"
59 #include "vcl/sysdata.hxx"
60
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 "brdwin.hxx"
72 #include "helpwin.hxx"
73 #include "sallayout.hxx"
74 #include "dndlcon.hxx"
75 #include "dndevdis.hxx"
76
77 #include "com/sun/star/awt/XWindowPeer.hpp"
78 #include "com/sun/star/rendering/XCanvas.hpp"
79 #include "com/sun/star/rendering/XSpriteCanvas.hpp"
80 #include "com/sun/star/awt/XWindow.hpp"
81 #include "comphelper/processfactory.hxx"
82 #include "com/sun/star/datatransfer/dnd/XDragSource.hpp"
83 #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp"
84 #include "com/sun/star/datatransfer/clipboard/XClipboard.hpp"
85 #include "com/sun/star/awt/XTopWindow.hpp"
86 #include "com/sun/star/awt/XDisplayConnection.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/accessibility/XAccessible.hpp"
91 #include "com/sun/star/accessibility/AccessibleRole.hpp"
92
93 #include <set>
94 #include <typeinfo>
95
96 using namespace rtl;
97 using namespace ::com::sun::star::uno;
98 using namespace ::com::sun::star::lang;
99 using namespace ::com::sun::star::datatransfer::clipboard;
100 using namespace ::com::sun::star::datatransfer::dnd;
101 using namespace ::com::sun::star;
102 using namespace com::sun;
103
104 using ::com::sun::star::awt::XTopWindow;
105
106 // =======================================================================
107
108 DBG_NAME( Window )
109
110 // =======================================================================
111
112 #define IMPL_PAINT_PAINT ((sal_uInt16)0x0001)
113 #define IMPL_PAINT_PAINTALL ((sal_uInt16)0x0002)
114 #define IMPL_PAINT_PAINTALLCHILDS ((sal_uInt16)0x0004)
115 #define IMPL_PAINT_PAINTCHILDS ((sal_uInt16)0x0008)
116 #define IMPL_PAINT_ERASE ((sal_uInt16)0x0010)
117 #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020)
118
119 // -----------------------------------------------------------------------
120
121 typedef Window* PWINDOW;
122
123 // -----------------------------------------------------------------------
124
125 struct ImplCalcToTopData
126 {
127 ImplCalcToTopData* mpNext;
128 Window* mpWindow;
129 Region* mpInvalidateRegion;
130 };
131
ImplAccessibleInfos()132 ImplAccessibleInfos::ImplAccessibleInfos()
133 {
134 nAccessibleRole = 0xFFFF;
135 pAccessibleName = NULL;
136 pAccessibleDescription = NULL;
137 pLabeledByWindow = NULL;
138 pLabelForWindow = NULL;
139 pMemberOfWindow = NULL;
140 }
141
~ImplAccessibleInfos()142 ImplAccessibleInfos::~ImplAccessibleInfos()
143 {
144 delete pAccessibleName;
145 delete pAccessibleDescription;
146 }
147
148 // -----------------------------------------------------------------------
149
WindowImpl(WindowType nType)150 WindowImpl::WindowImpl( WindowType nType )
151 {
152 maZoom = Fraction( 1, 1 );
153 maWinRegion = Region(true);
154 maWinClipRegion = Region(true);
155 mpWinData = NULL; // Extra Window Data, that we don't need for all windows
156 mpOverlapData = NULL; // Overlap Data
157 mpFrameData = NULL; // Frame Data
158 mpFrame = NULL; // Pointer to frame window
159 mpSysObj = NULL;
160 mpFrameWindow = NULL; // window to top level parent (same as frame window)
161 mpOverlapWindow = NULL; // first overlap parent
162 mpBorderWindow = NULL; // Border-Window
163 mpClientWindow = NULL; // Client-Window of a FrameWindow
164 mpParent = NULL; // parent (incl. BorderWindow)
165 mpRealParent = NULL; // real parent (excl. BorderWindow)
166 mpFirstChild = NULL; // first child window
167 mpLastChild = NULL; // last child window
168 mpFirstOverlap = NULL; // first overlap window (only set in overlap windows)
169 mpLastOverlap = NULL; // last overlap window (only set in overlap windows)
170 mpPrev = NULL; // prev window
171 mpNext = NULL; // next window
172 mpNextOverlap = NULL; // next overlap window of frame
173 mpLastFocusWindow = NULL; // window for focus restore
174 mpDlgCtrlDownWindow = NULL; // window for dialog control
175 mpFirstDel = NULL; // Dtor notification list
176 mpUserData = NULL; // user data
177 mpExtImpl = NULL; // extended implementation data
178 mpCursor = NULL; // cursor
179 mpControlFont = NULL; // font property
180 mpVCLXWindow = NULL;
181 mpAccessibleInfos = NULL;
182 maControlForeground = Color( COL_TRANSPARENT ); // foreground color not set
183 maControlBackground = Color( COL_TRANSPARENT ); // background color not set
184 mnLeftBorder = 0; // left border
185 mnTopBorder = 0; // top border
186 mnRightBorder = 0; // right border
187 mnBottomBorder = 0; // bottom border
188 mnX = 0; // X-Position to Parent
189 mnY = 0; // Y-Position to Parent
190 mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning
191 mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren
192 mpPaintRegion = NULL; // Paint-ClipRegion
193 mnStyle = 0; // style (init in ImplInitWindow)
194 mnPrevStyle = 0; // prevstyle (set in SetStyle)
195 mnExtendedStyle = 0; // extended style (init in ImplInitWindow)
196 mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle)
197 mnType = nType; // window type
198 mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf
199 mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer)
200 mnPaintFlags = 0; // Flags for ImplCallPaint
201 mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode
202 mnActivateMode = 0; // Wird bei System/Overlap-Windows umgesetzt
203 mnDlgCtrlFlags = 0; // DialogControl-Flags
204 mnLockCount = 0; // LockCount
205 meAlwaysInputMode = AlwaysInputNone; // neither AlwaysEnableInput nor AlwaysDisableInput called
206 mbFrame = sal_False; // sal_True: Window is a frame window
207 mbBorderWin = sal_False; // sal_True: Window is a border window
208 mbOverlapWin = sal_False; // sal_True: Window is a overlap window
209 mbSysWin = sal_False; // sal_True: SystemWindow is the base class
210 mbDialog = sal_False; // sal_True: Dialog is the base class
211 mbDockWin = sal_False; // sal_True: DockingWindow is the base class
212 mbFloatWin = sal_False; // sal_True: FloatingWindow is the base class
213 mbPushButton = sal_False; // sal_True: PushButton is the base class
214 mbToolBox = sal_False; // sal_True: ToolBox is the base class
215 mbMenuFloatingWindow= sal_False; // sal_True: MenuFloatingWindow is the base class
216 mbToolbarFloatingWindow= sal_False; // sal_True: ImplPopupFloatWin is the base class, used for subtoolbars
217 mbSplitter = sal_False; // sal_True: Splitter is the base class
218 mbVisible = sal_False; // sal_True: Show( sal_True ) called
219 mbOverlapVisible = sal_False; // sal_True: Hide called for visible window from ImplHideAllOverlapWindow()
220 mbDisabled = sal_False; // sal_True: Enable( sal_False ) called
221 mbInputDisabled = sal_False; // sal_True: EnableInput( sal_False ) called
222 mbDropDisabled = sal_False; // sal_True: Drop is enabled
223 mbNoUpdate = sal_False; // sal_True: SetUpdateMode( sal_False ) called
224 mbNoParentUpdate = sal_False; // sal_True: SetParentUpdateMode( sal_False ) called
225 mbActive = sal_False; // sal_True: Window Active
226 mbParentActive = sal_False; // sal_True: OverlapActive from Parent
227 mbReallyVisible = sal_False; // sal_True: this and all parents to an overlapped window are visible
228 mbReallyShown = sal_False; // sal_True: this and all parents to an overlapped window are shown
229 mbInInitShow = sal_False; // sal_True: we are in InitShow
230 mbChildNotify = sal_False; // sal_True: ChildNotify
231 mbChildPtrOverwrite = sal_False; // sal_True: PointerStyle overwrites Child-Pointer
232 mbNoPtrVisible = sal_False; // sal_True: ShowPointer( sal_False ) called
233 mbMouseMove = sal_False; // sal_True: BaseMouseMove called
234 mbPaintFrame = sal_False; // sal_True: Paint is visible, but not painted
235 mbInPaint = sal_False; // sal_True: Inside PaintHdl
236 mbMouseButtonDown = sal_False; // sal_True: BaseMouseButtonDown called
237 mbMouseButtonUp = sal_False; // sal_True: BaseMouseButtonUp called
238 mbKeyInput = sal_False; // sal_True: BaseKeyInput called
239 mbKeyUp = sal_False; // sal_True: BaseKeyUp called
240 mbCommand = sal_False; // sal_True: BaseCommand called
241 mbDefPos = sal_True; // sal_True: Position is not Set
242 mbDefSize = sal_True; // sal_True: Size is not Set
243 mbCallMove = sal_True; // sal_True: Move must be called by Show
244 mbCallResize = sal_True; // sal_True: Resize must be called by Show
245 mbWaitSystemResize = sal_True; // sal_True: Wait for System-Resize
246 mbInitWinClipRegion = sal_True; // sal_True: Calc Window Clip Region
247 mbInitChildRegion = sal_False; // sal_True: InitChildClipRegion
248 mbWinRegion = sal_False; // sal_True: Window Region
249 mbClipChildren = sal_False; // sal_True: request that child-windows get clipped
250 mbClipSiblings = sal_False; // sal_True: request that sibling child-windows get clipped
251 mbChildTransparent = sal_False; // sal_True: allow child-windows to enable transparency (incl. Parent-CLIPCHILDREN)
252 mbPaintTransparent = sal_False; // sal_True: Paints muessen auf Parent ausgeloest werden
253 mbMouseTransparent = sal_False; // sal_True: Window is transparent for Mouse
254 mbDlgCtrlStart = sal_False; // sal_True: Ab hier eigenes Dialog-Control
255 mbFocusVisible = sal_False; // sal_True: Focus Visible
256 mbUseNativeFocus = sal_False;
257 mbNativeFocusVisible= sal_False; // sal_True: native Focus Visible
258 mbInShowFocus = sal_False; // prevent recursion
259 mbInHideFocus = sal_False; // prevent recursion
260 mbTrackVisible = sal_False; // sal_True: Tracking Visible
261 mbControlForeground = sal_False; // sal_True: Foreground-Property set
262 mbControlBackground = sal_False; // sal_True: Background-Property set
263 mbAlwaysOnTop = sal_False; // sal_True: window is always on top
264 mbCompoundControl = sal_False; // sal_True: Zusammengesetztes Control => Listener...
265 mbCompoundControlHasFocus = sal_False; // sal_True: Zusammengesetztes Control hat irgendwo den Focus
266 mbPaintDisabled = sal_False; // sal_True: to disable paint events
267 mbAllResize = sal_False; // sal_True: to enable sending of ResizeEvents with both height=0 and width=0
268 mbInDtor = sal_False; // sal_True: is set when the window is being destructed
269 mbExtTextInput = sal_False; // sal_True: ExtTextInput-Mode is active
270 mbInFocusHdl = sal_False; // sal_True: is set when inside a GetFocus-Handler context
271 mbCreatedWithToolkit = sal_False;
272 mbSuppressAccessibilityEvents = sal_False; // sal_True: do not send any accessibility events
273 mbDrawSelectionBackground = sal_False; // sal_True: draws transparent window background to indicate (toolbox) selection
274 mbIsInTaskPaneList = sal_False; // sal_True: window was added to the taskpanelist in the topmost system window
275 mnNativeBackground = 0; // initialize later, depends on type
276 mbCallHandlersDuringInputDisabled = sal_False; // sal_True: call event handlers even if input is disabled
277 mbDisableAccessibleLabelForRelation = sal_False; // sal_True: do not set LabelFor relation on accessible objects
278 mbDisableAccessibleLabeledByRelation = sal_False; // sal_True: do not set LabeledBy relation on accessible objects
279 mbHelpTextDynamic = sal_False; // sal_True: append help id in HELP_DEBUG case
280 mbFakeFocusSet = sal_False; // sal_True: pretend as if the window
281 // has focus.
282 mbIsThemingEnabled = sal_True;
283 }
284
~WindowImpl()285 WindowImpl::~WindowImpl()
286 {
287 delete mpChildClipRegion;
288 delete mpAccessibleInfos;
289 delete mpControlFont;
290 }
291
292
293 // -----------------------------------------------------------------------
294
295 // helper method to allow inline constructor even for pWindow!=NULL case
AttachToWindow(const Window * pWindow)296 void ImplDelData::AttachToWindow( const Window* pWindow )
297 {
298 if( pWindow )
299 const_cast<Window*>(pWindow)->ImplAddDel( this );
300 }
301
302 // -----------------------------------------------------------------------
303
304 // define dtor for ImplDelData
~ImplDelData()305 ImplDelData::~ImplDelData()
306 {
307 // #112873# auto remove of ImplDelData
308 // due to this code actively calling ImplRemoveDel() is not mandatory anymore
309 if( !mbDel && mpWindow )
310 {
311 // the window still exists but we were not removed
312 const_cast<Window*>(mpWindow)->ImplRemoveDel( this );
313 mpWindow = NULL;
314 }
315 }
316
317 // -----------------------------------------------------------------------
318
319 #ifdef DBG_UTIL
ImplDbgCheckWindow(const void * pObj)320 const char* ImplDbgCheckWindow( const void* pObj )
321 {
322 DBG_TESTSOLARMUTEX();
323
324 const Window* pWindow = (Window*)pObj;
325
326 if ( (pWindow->GetType() < WINDOW_FIRST) || (pWindow->GetType() > WINDOW_LAST) )
327 return "Window data overwrite";
328
329 // Fenster-Verkettung ueberpruefen
330 Window* pChild = pWindow->mpWindowImpl->mpFirstChild;
331 while ( pChild )
332 {
333 if ( pChild->mpWindowImpl->mpParent != pWindow )
334 return "Child-Window-Parent wrong";
335 pChild = pChild->mpWindowImpl->mpNext;
336 }
337
338 return NULL;
339 }
340 #endif
341
342 // =======================================================================
343
ImplInitAppFontData(Window * pWindow)344 void Window::ImplInitAppFontData( Window* pWindow )
345 {
346 ImplSVData* pSVData = ImplGetSVData();
347 long nTextHeight = pWindow->GetTextHeight();
348 long nTextWidth = pWindow->GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "aemnnxEM" ) ) );
349 long nSymHeight = nTextHeight*4;
350 // Falls Font zu schmal ist, machen wir die Basis breiter,
351 // damit die Dialoge symetrisch aussehen und nicht zu schmal
352 // werden. Wenn der Dialog die gleiche breite hat, geben wir
353 // noch etwas Spielraum dazu, da etwas mehr Platz besser ist.
354 if ( nSymHeight > nTextWidth )
355 nTextWidth = nSymHeight;
356 else if ( nSymHeight+5 > nTextWidth )
357 nTextWidth = nSymHeight+5;
358 pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
359 pSVData->maGDIData.mnAppFontY = nTextHeight * 10;
360
361 // FIXME: this is currently only on aqua, check with other
362 // platforms
363 if( pSVData->maNWFData.mbNoFocusRects )
364 {
365 // try to find out whether there is a large correction
366 // of control sizes, if yes, make app font scalings larger
367 // so dialog positioning is not completely off
368 ImplControlValue aControlValue;
369 Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) );
370 Rectangle aBoundingRgn( aCtrlRegion );
371 Rectangle aContentRgn( aCtrlRegion );
372 if( pWindow->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
373 CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
374 aBoundingRgn, aContentRgn ) )
375 {
376 // comment: the magical +6 is for the extra border in bordered
377 // (which is the standard) edit fields
378 if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
379 pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10;
380 }
381 }
382
383
384 pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX;
385 if ( pSVData->maAppData.mnDialogScaleX )
386 pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100;
387 }
388
389 // -----------------------------------------------------------------------
390
ImplCheckUIFont(const Font & rFont)391 bool Window::ImplCheckUIFont( const Font& rFont )
392 {
393 if( ImplGetSVData()->maGDIData.mbNativeFontConfig )
394 return true;
395
396 // create a text string using the localized text of important buttons
397 String aTestText;
398 static const StandardButtonType aTestButtons[] =
399 {
400 BUTTON_OK, BUTTON_CANCEL, BUTTON_CLOSE, BUTTON_ABORT,
401 BUTTON_YES, BUTTON_NO, BUTTON_MORE, BUTTON_IGNORE,
402 BUTTON_RETRY, BUTTON_HELP
403 };
404
405 const int nTestButtonCount = sizeof(aTestButtons)/sizeof(*aTestButtons);
406 for( int n = 0; n < nTestButtonCount; ++n )
407 {
408 String aButtonStr = Button::GetStandardText( aTestButtons[n] );
409 // #i115432# ignore mnemonic+accelerator part of each string
410 // TODO: use a string filtering method when it becomes available
411 const int nLen = aButtonStr.Len();
412 bool bInside = false;
413 for( int i = 0; i < nLen; ++i ) {
414 const sal_Unicode c = aButtonStr.GetChar( i );
415 if( (c == '('))
416 bInside = true;
417 if( (c == ')'))
418 bInside = false;
419 if( (c == '~')
420 || (c == '(') || (c == ')')
421 || ((c >= 'A') && (c <= 'Z') && bInside) )
422 aButtonStr.SetChar( i, ' ' );
423 }
424 // append sanitized button text to test string
425 aTestText.Append( aButtonStr );
426 }
427
428 const int nFirstChar = HasGlyphs( rFont, aTestText );
429 const bool bUIFontOk = (nFirstChar >= aTestText.Len());
430 return bUIFontOk;
431 }
432
433 // -----------------------------------------------------------------------
434
ImplUpdateGlobalSettings(AllSettings & rSettings,sal_Bool bCallHdl)435 void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, sal_Bool bCallHdl )
436 {
437 // reset high contrast to false, so the system can either update it
438 // or AutoDetectSystemHC can kick in (see below)
439 StyleSettings aTmpSt( rSettings.GetStyleSettings() );
440 aTmpSt.SetHighContrastMode( sal_False );
441 rSettings.SetStyleSettings( aTmpSt );
442 ImplGetFrame()->UpdateSettings( rSettings );
443 // reset default border width for layouters
444 ImplGetSVData()->maAppData.mnDefaultLayoutBorder = -1;
445
446 // Verify availability of the configured UI font, otherwise choose "Andale Sans UI"
447 String aUserInterfaceFont;
448 bool bUseSystemFont = rSettings.GetStyleSettings().GetUseSystemUIFonts();
449
450 // check whether system UI font can display a typical UI text
451 if( bUseSystemFont )
452 bUseSystemFont = ImplCheckUIFont( rSettings.GetStyleSettings().GetAppFont() );
453
454 if ( !bUseSystemFont )
455 {
456 ImplInitFontList();
457 String aConfigFont = utl::DefaultFontConfiguration::get()->getUserInterfaceFont( rSettings.GetUILocale() );
458 xub_StrLen nIndex = 0;
459 while( nIndex != STRING_NOTFOUND )
460 {
461 String aName( aConfigFont.GetToken( 0, ';', nIndex ) );
462 if ( aName.Len() && mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aName ) )
463 {
464 aUserInterfaceFont = aConfigFont;
465 break;
466 }
467 }
468
469 if ( ! aUserInterfaceFont.Len() )
470 {
471 String aFallbackFont (RTL_CONSTASCII_USTRINGPARAM( "Andale Sans UI" ));
472 if ( mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aFallbackFont ) )
473 aUserInterfaceFont = aFallbackFont;
474 }
475 }
476
477 if ( !bUseSystemFont && aUserInterfaceFont.Len() )
478 {
479 StyleSettings aStyleSettings = rSettings.GetStyleSettings();
480 Font aFont = aStyleSettings.GetAppFont();
481 aFont.SetName( aUserInterfaceFont );
482 aStyleSettings.SetAppFont( aFont );
483 aFont = aStyleSettings.GetHelpFont();
484 aFont.SetName( aUserInterfaceFont );
485 aStyleSettings.SetHelpFont( aFont );
486 aFont = aStyleSettings.GetTitleFont();
487 aFont.SetName( aUserInterfaceFont );
488 aStyleSettings.SetTitleFont( aFont );
489 aFont = aStyleSettings.GetFloatTitleFont();
490 aFont.SetName( aUserInterfaceFont );
491 aStyleSettings.SetFloatTitleFont( aFont );
492 aFont = aStyleSettings.GetMenuFont();
493 aFont.SetName( aUserInterfaceFont );
494 aStyleSettings.SetMenuFont( aFont );
495 aFont = aStyleSettings.GetToolFont();
496 aFont.SetName( aUserInterfaceFont );
497 aStyleSettings.SetToolFont( aFont );
498 aFont = aStyleSettings.GetLabelFont();
499 aFont.SetName( aUserInterfaceFont );
500 aStyleSettings.SetLabelFont( aFont );
501 aFont = aStyleSettings.GetInfoFont();
502 aFont.SetName( aUserInterfaceFont );
503 aStyleSettings.SetInfoFont( aFont );
504 aFont = aStyleSettings.GetRadioCheckFont();
505 aFont.SetName( aUserInterfaceFont );
506 aStyleSettings.SetRadioCheckFont( aFont );
507 aFont = aStyleSettings.GetPushButtonFont();
508 aFont.SetName( aUserInterfaceFont );
509 aStyleSettings.SetPushButtonFont( aFont );
510 aFont = aStyleSettings.GetFieldFont();
511 aFont.SetName( aUserInterfaceFont );
512 aStyleSettings.SetFieldFont( aFont );
513 aFont = aStyleSettings.GetIconFont();
514 aFont.SetName( aUserInterfaceFont );
515 aStyleSettings.SetIconFont( aFont );
516 aFont = aStyleSettings.GetGroupFont();
517 aFont.SetName( aUserInterfaceFont );
518 aStyleSettings.SetGroupFont( aFont );
519 rSettings.SetStyleSettings( aStyleSettings );
520 }
521
522 StyleSettings aStyleSettings = rSettings.GetStyleSettings();
523 // #97047: Force all fonts except Menu and Help to a fixed height
524 // to avoid UI scaling due to large fonts
525 // - but allow bigger fonts on bigger screens (i16682, i21238)
526 // dialogs were designed to fit 800x600 with an 8pt font, so scale accordingly
527 int maxFontheight = 9; // #107886#: 9 is default for some Asian systems, so always allow if requested
528 if( GetDesktopRectPixel().getHeight() > 600 )
529 maxFontheight = (int) ((( 8.0 * (double) GetDesktopRectPixel().getHeight()) / 600.0) + 1.5);
530
531 Font aFont = aStyleSettings.GetMenuFont();
532 int defFontheight = aFont.GetHeight();
533 if( defFontheight > maxFontheight )
534 defFontheight = maxFontheight;
535
536 // if the UI is Korean, Chinese or another locale
537 // where the system font size is known to be often too small to
538 // generate readable fonts enforce a minimum font size of 9 points
539 bool bBrokenLangFontHeight = false;
540 static const LanguageType eBrokenSystemFontSizeLanguages[] =
541 { LANGUAGE_KOREAN, LANGUAGE_KOREAN_JOHAB,
542 LANGUAGE_CHINESE_HONGKONG, LANGUAGE_CHINESE_MACAU, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_SINGAPORE, LANGUAGE_CHINESE_TRADITIONAL
543 };
544 static std::set< LanguageType > aBrokenSystemFontSizeLanguagesSet(
545 eBrokenSystemFontSizeLanguages,
546 eBrokenSystemFontSizeLanguages +
547 (sizeof(eBrokenSystemFontSizeLanguages)/sizeof(eBrokenSystemFontSizeLanguages[0]))
548 );
549 LanguageType aLang = Application::GetSettings().GetUILanguage();
550 if( aBrokenSystemFontSizeLanguagesSet.find( aLang ) != aBrokenSystemFontSizeLanguagesSet.end() )
551 {
552 defFontheight = Max(9, defFontheight);
553 bBrokenLangFontHeight = true;
554 }
555
556 // i22098, toolfont will be scaled differently to avoid bloated rulers and status bars for big fonts
557 int toolfontheight = defFontheight;
558 if( toolfontheight > 9 )
559 toolfontheight = (defFontheight+8) / 2;
560
561 aFont = aStyleSettings.GetAppFont();
562 aFont.SetHeight( defFontheight );
563 aStyleSettings.SetAppFont( aFont );
564 aFont = aStyleSettings.GetTitleFont();
565 aFont.SetHeight( defFontheight );
566 aStyleSettings.SetTitleFont( aFont );
567 aFont = aStyleSettings.GetFloatTitleFont();
568 aFont.SetHeight( defFontheight );
569 aStyleSettings.SetFloatTitleFont( aFont );
570 // keep menu and help font size from system unless in broken locale size
571 if( bBrokenLangFontHeight )
572 {
573 aFont = aStyleSettings.GetMenuFont();
574 if( aFont.GetHeight() < defFontheight )
575 {
576 aFont.SetHeight( defFontheight );
577 aStyleSettings.SetMenuFont( aFont );
578 }
579 aFont = aStyleSettings.GetHelpFont();
580 if( aFont.GetHeight() < defFontheight )
581 {
582 aFont.SetHeight( defFontheight );
583 aStyleSettings.SetHelpFont( aFont );
584 }
585 }
586
587 // use different height for toolfont
588 aFont = aStyleSettings.GetToolFont();
589 aFont.SetHeight( toolfontheight );
590 aStyleSettings.SetToolFont( aFont );
591
592 aFont = aStyleSettings.GetLabelFont();
593 aFont.SetHeight( defFontheight );
594 aStyleSettings.SetLabelFont( aFont );
595 aFont = aStyleSettings.GetInfoFont();
596 aFont.SetHeight( defFontheight );
597 aStyleSettings.SetInfoFont( aFont );
598 aFont = aStyleSettings.GetRadioCheckFont();
599 aFont.SetHeight( defFontheight );
600 aStyleSettings.SetRadioCheckFont( aFont );
601 aFont = aStyleSettings.GetPushButtonFont();
602 aFont.SetHeight( defFontheight );
603 aStyleSettings.SetPushButtonFont( aFont );
604 aFont = aStyleSettings.GetFieldFont();
605 aFont.SetHeight( defFontheight );
606 aStyleSettings.SetFieldFont( aFont );
607 aFont = aStyleSettings.GetIconFont();
608 aFont.SetHeight( defFontheight );
609 aStyleSettings.SetIconFont( aFont );
610 aFont = aStyleSettings.GetGroupFont();
611 aFont.SetHeight( defFontheight );
612 aStyleSettings.SetGroupFont( aFont );
613
614 // set workspace gradient to black in dark themes
615 if( aStyleSettings.GetWindowColor().IsDark() )
616 aStyleSettings.SetWorkspaceGradient( Wallpaper( Color( COL_BLACK ) ) );
617 else
618 {
619 Gradient aGrad( GRADIENT_LINEAR, DEFAULT_WORKSPACE_GRADIENT_START_COLOR, DEFAULT_WORKSPACE_GRADIENT_END_COLOR );
620 aStyleSettings.SetWorkspaceGradient( Wallpaper( aGrad ) );
621 }
622
623 rSettings.SetStyleSettings( aStyleSettings );
624
625
626 // auto detect HC mode; if the system already set it to "yes"
627 // (see above) then accept that
628 if( !rSettings.GetStyleSettings().GetHighContrastMode() )
629 {
630 sal_Bool bTmp = sal_False, bAutoHCMode = sal_True;
631 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
632 vcl::unohelper::GetMultiServiceFactory(),
633 OUString::createFromAscii( "org.openoffice.Office.Common/Accessibility" ) ); // note: case sensitive !
634 if ( aNode.isValid() )
635 {
636 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "AutoDetectSystemHC" ) );
637 if( aValue >>= bTmp )
638 bAutoHCMode = bTmp;
639 }
640 if( bAutoHCMode )
641 {
642 if( rSettings.GetStyleSettings().GetFaceColor().IsDark()
643 || rSettings.GetStyleSettings().GetWindowColor().IsDark() )
644 {
645 aStyleSettings = rSettings.GetStyleSettings();
646 aStyleSettings.SetHighContrastMode( sal_True );
647 rSettings.SetStyleSettings( aStyleSettings );
648 }
649 }
650 }
651
652 static const char* pEnvHC = getenv( "SAL_FORCE_HC" );
653 if( pEnvHC && *pEnvHC )
654 {
655 aStyleSettings.SetHighContrastMode( sal_True );
656 rSettings.SetStyleSettings( aStyleSettings );
657 }
658
659 #ifdef DBG_UTIL
660 // Evt. AppFont auf Fett schalten, damit man feststellen kann,
661 // ob fuer die Texte auf anderen Systemen genuegend Platz
662 // vorhanden ist
663 if ( DbgIsBoldAppFont() )
664 {
665 aStyleSettings = rSettings.GetStyleSettings();
666 aFont = aStyleSettings.GetAppFont();
667 aFont.SetWeight( WEIGHT_BOLD );
668 aStyleSettings.SetAppFont( aFont );
669 aFont = aStyleSettings.GetGroupFont();
670 aFont.SetWeight( WEIGHT_BOLD );
671 aStyleSettings.SetGroupFont( aFont );
672 aFont = aStyleSettings.GetLabelFont();
673 aFont.SetWeight( WEIGHT_BOLD );
674 aStyleSettings.SetLabelFont( aFont );
675 aFont = aStyleSettings.GetRadioCheckFont();
676 aFont.SetWeight( WEIGHT_BOLD );
677 aStyleSettings.SetRadioCheckFont( aFont );
678 aFont = aStyleSettings.GetPushButtonFont();
679 aFont.SetWeight( WEIGHT_BOLD );
680 aStyleSettings.SetPushButtonFont( aFont );
681 aFont = aStyleSettings.GetFieldFont();
682 aFont.SetWeight( WEIGHT_BOLD );
683 aStyleSettings.SetFieldFont( aFont );
684 aFont = aStyleSettings.GetIconFont();
685 aFont.SetWeight( WEIGHT_BOLD );
686 aStyleSettings.SetIconFont( aFont );
687 rSettings.SetStyleSettings( aStyleSettings );
688 }
689 #endif
690
691 if ( bCallHdl )
692 GetpApp()->SystemSettingsChanging( rSettings, this );
693 }
694
695 // -----------------------------------------------------------------------
696
ImplTranslateMouseEvent(const MouseEvent & rE,Window * pSource,Window * pDest)697 MouseEvent ImplTranslateMouseEvent( const MouseEvent& rE, Window* pSource, Window* pDest )
698 {
699 Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() );
700 aPos = pDest->ScreenToOutputPixel( aPos );
701 return MouseEvent( aPos, rE.GetClicks(), rE.GetMode(), rE.GetButtons(), rE.GetModifier() );
702 }
703
704 // -----------------------------------------------------------------------
705
ImplTranslateCommandEvent(const CommandEvent & rCEvt,Window * pSource,Window * pDest)706 CommandEvent ImplTranslateCommandEvent( const CommandEvent& rCEvt, Window* pSource, Window* pDest )
707 {
708 if ( !rCEvt.IsMouseEvent() )
709 return rCEvt;
710
711 Point aPos = pSource->OutputToScreenPixel( rCEvt.GetMousePosPixel() );
712 aPos = pDest->ScreenToOutputPixel( aPos );
713 return CommandEvent( aPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
714 }
715
716 // =======================================================================
717
ImplInitWindowData(WindowType nType)718 void Window::ImplInitWindowData( WindowType nType )
719 {
720 mpWindowImpl = new WindowImpl( nType );
721
722 meOutDevType = OUTDEV_WINDOW;
723
724 mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // sal_True: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
725 }
726
727 // -----------------------------------------------------------------------
728
ImplInit(Window * pParent,WinBits nStyle,const::com::sun::star::uno::Any &)729 void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& /*aSystemWorkWindowToken*/ )
730 {
731 ImplInit( pParent, nStyle, NULL );
732 }
733
734 // -----------------------------------------------------------------------
735
ImplInit(Window * pParent,WinBits nStyle,SystemParentData * pSystemParentData)736 void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
737 {
738 DBG_ASSERT( mpWindowImpl->mbFrame || pParent, "Window::Window(): pParent == NULL" );
739
740 ImplSVData* pSVData = ImplGetSVData();
741 Window* pRealParent = pParent;
742
743 // 3D-Look vererben
744 if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
745 nStyle |= WB_3DLOOK;
746
747 // create border window if necessary
748 if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
749 && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
750 {
751 sal_uInt16 nBorderTypeStyle = 0;
752 if( (nStyle & WB_SYSTEMCHILDWINDOW) )
753 {
754 // handle WB_SYSTEMCHILDWINDOW
755 // these should be analogous to a top level frame; meaning they
756 // should have a border window with style BORDERWINDOW_STYLE_FRAME
757 // which controls their size
758 nBorderTypeStyle |= BORDERWINDOW_STYLE_FRAME;
759 nStyle |= WB_BORDER;
760 }
761 ImplBorderWindow* pBorderWin =
762 mpWindowImpl->mbIsThemingEnabled
763 ? CreateBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle )
764 : new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle );
765 ((Window*)pBorderWin)->mpWindowImpl->mpClientWindow = this;
766 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
767 mpWindowImpl->mpBorderWindow = pBorderWin;
768 pParent = mpWindowImpl->mpBorderWindow;
769 }
770 else if( !mpWindowImpl->mbFrame && ! pParent )
771 {
772 mpWindowImpl->mbOverlapWin = sal_True;
773 mpWindowImpl->mbFrame = sal_True;
774 }
775
776 // insert window in list
777 ImplInsertWindow( pParent );
778 mpWindowImpl->mnStyle = nStyle;
779
780 // Overlap-Window-Daten
781 if ( mpWindowImpl->mbOverlapWin )
782 {
783 mpWindowImpl->mpOverlapData = new ImplOverlapData;
784 mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL;
785 mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL;
786 mpWindowImpl->mpOverlapData->mpNextBackWin = NULL;
787 mpWindowImpl->mpOverlapData->mnSaveBackSize = 0;
788 mpWindowImpl->mpOverlapData->mbSaveBack = sal_False;
789 mpWindowImpl->mpOverlapData->mnTopLevel = 1;
790 }
791
792 if( pParent && ! mpWindowImpl->mbFrame )
793 mbEnableRTL = pParent->mbEnableRTL;
794
795 // test for frame creation
796 if ( mpWindowImpl->mbFrame )
797 {
798 // create frame
799 sal_uLong nFrameStyle = 0;
800
801 if ( nStyle & WB_MOVEABLE )
802 nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE;
803 if ( nStyle & WB_SIZEABLE )
804 nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE;
805 if ( nStyle & WB_CLOSEABLE )
806 nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE;
807 if ( nStyle & WB_APP )
808 nFrameStyle |= SAL_FRAME_STYLE_DEFAULT;
809 // check for undecorated floating window
810 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
811 ( !(nFrameStyle & ~SAL_FRAME_STYLE_CLOSEABLE) &&
812 ( mpWindowImpl->mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
813 // 2. borderwindows of floaters with ownerdraw decoration
814 ( ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) ) )
815 {
816 nFrameStyle = SAL_FRAME_STYLE_FLOAT;
817 if( nStyle & WB_OWNERDRAWDECORATION )
818 nFrameStyle |= (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_NOSHADOW);
819 if( nStyle & WB_NEEDSFOCUS )
820 nFrameStyle |= SAL_FRAME_STYLE_FLOAT_FOCUSABLE;
821 }
822 else if( mpWindowImpl->mbFloatWin )
823 nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW;
824
825 if( nStyle & WB_INTROWIN )
826 nFrameStyle |= SAL_FRAME_STYLE_INTRO;
827 if( nStyle & WB_TOOLTIPWIN )
828 nFrameStyle |= SAL_FRAME_STYLE_TOOLTIP;
829
830 if( nStyle & WB_NOSHADOW )
831 nFrameStyle |= SAL_FRAME_STYLE_NOSHADOW;
832
833 if( nStyle & WB_SYSTEMCHILDWINDOW )
834 nFrameStyle |= SAL_FRAME_STYLE_SYSTEMCHILD;
835
836 switch (mpWindowImpl->mnType)
837 {
838 case WINDOW_DIALOG:
839 case WINDOW_TABDIALOG:
840 case WINDOW_MODALDIALOG:
841 case WINDOW_MODELESSDIALOG:
842 case WINDOW_MESSBOX:
843 case WINDOW_INFOBOX:
844 case WINDOW_WARNINGBOX:
845 case WINDOW_ERRORBOX:
846 case WINDOW_QUERYBOX:
847 nFrameStyle |= SAL_FRAME_STYLE_DIALOG;
848 default:
849 break;
850 }
851
852 SalFrame* pParentFrame = NULL;
853 if ( pParent )
854 pParentFrame = pParent->mpWindowImpl->mpFrame;
855 SalFrame* pFrame;
856 if ( pSystemParentData )
857 pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_PLUG );
858 else
859 pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
860 if ( !pFrame )
861 {
862 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
863 throw ::com::sun::star::uno::RuntimeException(
864 OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system window!" ) ),
865 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
866 //GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
867 }
868
869 pFrame->SetCallback( this, ImplWindowFrameProc );
870
871 // set window frame data
872 mpWindowImpl->mpFrameData = new ImplFrameData;
873 mpWindowImpl->mpFrame = pFrame;
874 mpWindowImpl->mpFrameWindow = this;
875 mpWindowImpl->mpOverlapWindow = this;
876
877 // set frame data
878 mpWindowImpl->mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame;
879 pSVData->maWinData.mpFirstFrame = this;
880 mpWindowImpl->mpFrameData->mpFirstOverlap = NULL;
881 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
882 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
883 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
884 mpWindowImpl->mpFrameData->mpFirstBackWin = NULL;
885 mpWindowImpl->mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList;
886 mpWindowImpl->mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache;
887 mpWindowImpl->mpFrameData->mnAllSaveBackSize = 0;
888 mpWindowImpl->mpFrameData->mnFocusId = 0;
889 mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
890 mpWindowImpl->mpFrameData->mnLastMouseX = -1;
891 mpWindowImpl->mpFrameData->mnLastMouseY = -1;
892 mpWindowImpl->mpFrameData->mnBeforeLastMouseX = -1;
893 mpWindowImpl->mpFrameData->mnBeforeLastMouseY = -1;
894 mpWindowImpl->mpFrameData->mnFirstMouseX = -1;
895 mpWindowImpl->mpFrameData->mnFirstMouseY = -1;
896 mpWindowImpl->mpFrameData->mnLastMouseWinX = -1;
897 mpWindowImpl->mpFrameData->mnLastMouseWinY = -1;
898 mpWindowImpl->mpFrameData->mnModalMode = 0;
899 mpWindowImpl->mpFrameData->mnMouseDownTime = 0;
900 mpWindowImpl->mpFrameData->mnClickCount = 0;
901 mpWindowImpl->mpFrameData->mnFirstMouseCode = 0;
902 mpWindowImpl->mpFrameData->mnMouseCode = 0;
903 mpWindowImpl->mpFrameData->mnMouseMode = 0;
904 mpWindowImpl->mpFrameData->meMapUnit = MAP_PIXEL;
905 mpWindowImpl->mpFrameData->mbHasFocus = sal_False;
906 mpWindowImpl->mpFrameData->mbInMouseMove = sal_False;
907 mpWindowImpl->mpFrameData->mbMouseIn = sal_False;
908 mpWindowImpl->mpFrameData->mbStartDragCalled = sal_False;
909 mpWindowImpl->mpFrameData->mbNeedSysWindow = sal_False;
910 mpWindowImpl->mpFrameData->mbMinimized = sal_False;
911 mpWindowImpl->mpFrameData->mbStartFocusState = sal_False;
912 mpWindowImpl->mpFrameData->mbInSysObjFocusHdl = sal_False;
913 mpWindowImpl->mpFrameData->mbInSysObjToTopHdl = sal_False;
914 mpWindowImpl->mpFrameData->mbSysObjFocus = sal_False;
915 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeout( 30 );
916 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
917 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeout( 50 );
918 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeoutHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
919 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = sal_False;
920
921 if ( pRealParent && IsTopWindow() )
922 {
923 ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
924 pParentWinData->maTopWindowChildren.push_back( this );
925 }
926 }
927
928 // init data
929 mpWindowImpl->mpRealParent = pRealParent;
930
931 // #99318: make sure fontcache and list is available before call to SetSettings
932 mpFontList = mpWindowImpl->mpFrameData->mpFontList;
933 mpFontCache = mpWindowImpl->mpFrameData->mpFontCache;
934
935 if ( mpWindowImpl->mbFrame )
936 {
937 if ( pParent )
938 {
939 mpWindowImpl->mpFrameData->mnDPIX = pParent->mpWindowImpl->mpFrameData->mnDPIX;
940 mpWindowImpl->mpFrameData->mnDPIY = pParent->mpWindowImpl->mpFrameData->mnDPIY;
941 }
942 else
943 {
944 if ( ImplGetGraphics() )
945 {
946 mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY );
947 }
948 }
949
950 // add ownerdraw decorated frame windows to list in the top-most frame window
951 // so they can be hidden on lose focus
952 if( nStyle & WB_OWNERDRAWDECORATION )
953 ImplGetOwnerDrawList().push_back( this );
954
955 // delay settings initialization until first "real" frame
956 // this relies on the IntroWindow not needing any system settings
957 if ( !pSVData->maAppData.mbSettingsInit &&
958 ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
959 )
960 {
961 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
962 ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
963 OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
964 pSVData->maAppData.mbSettingsInit = sal_True;
965 }
966
967 // If we create a Window with default size, query this
968 // size directly, because we want resize all Controls to
969 // the correct size before we display the window
970 if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
971 mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
972 }
973 else
974 {
975 if ( pParent )
976 {
977 if ( !ImplIsOverlapWindow() )
978 {
979 mpWindowImpl->mbDisabled = pParent->mpWindowImpl->mbDisabled;
980 mpWindowImpl->mbInputDisabled = pParent->mpWindowImpl->mbInputDisabled;
981 mpWindowImpl->meAlwaysInputMode = pParent->mpWindowImpl->meAlwaysInputMode;
982 }
983
984 OutputDevice::SetSettings( pParent->GetSettings() );
985 }
986
987 }
988
989 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
990 sal_uInt16 nScreenZoom = rStyleSettings.GetScreenZoom();
991 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
992 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
993 maFont = rStyleSettings.GetAppFont();
994 ImplPointToLogic( maFont );
995
996 if ( nStyle & WB_3DLOOK )
997 {
998 SetTextColor( rStyleSettings.GetButtonTextColor() );
999 SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
1000 }
1001 else
1002 {
1003 SetTextColor( rStyleSettings.GetWindowTextColor() );
1004 SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
1005 }
1006
1007 ImplUpdatePos();
1008
1009 // calculate app font res (except for the Intro Window or the default window)
1010 if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
1011 ImplInitAppFontData( this );
1012
1013 if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() )
1014 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDCREATED, this );
1015 }
1016
1017 // -----------------------------------------------------------------------
1018
ImplSetFrameParent(const Window * pParent)1019 void Window::ImplSetFrameParent( const Window* pParent )
1020 {
1021 Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
1022 while( pFrameWindow )
1023 {
1024 // search all frames that are children of this window
1025 // and reparent them
1026 if( ImplIsRealParentPath( pFrameWindow ) )
1027 {
1028 DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" );
1029 DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" );
1030 SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL;
1031 pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
1032 }
1033 pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
1034 }
1035 }
1036
1037 // -----------------------------------------------------------------------
1038
ImplInsertWindow(Window * pParent)1039 void Window::ImplInsertWindow( Window* pParent )
1040 {
1041 mpWindowImpl->mpParent = pParent;
1042 mpWindowImpl->mpRealParent = pParent;
1043
1044 if ( pParent && !mpWindowImpl->mbFrame )
1045 {
1046 // search frame window and set window frame data
1047 Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
1048 mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
1049 mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
1050 mpWindowImpl->mpFrameWindow = pFrameParent;
1051 mpWindowImpl->mbFrame = sal_False;
1052
1053 // search overlap window and insert window in list
1054 if ( ImplIsOverlapWindow() )
1055 {
1056 Window* pFirstOverlapParent = pParent;
1057 while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
1058 pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
1059 mpWindowImpl->mpOverlapWindow = pFirstOverlapParent;
1060
1061 mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap;
1062 mpWindowImpl->mpFrameData->mpFirstOverlap = this;
1063
1064 // Overlap-Windows sind per default die obersten
1065 mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap;
1066 pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this;
1067 if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap )
1068 pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this;
1069 else
1070 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
1071 }
1072 else
1073 {
1074 if ( pParent->ImplIsOverlapWindow() )
1075 mpWindowImpl->mpOverlapWindow = pParent;
1076 else
1077 mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
1078 mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
1079 pParent->mpWindowImpl->mpLastChild = this;
1080 if ( !pParent->mpWindowImpl->mpFirstChild )
1081 pParent->mpWindowImpl->mpFirstChild = this;
1082 else
1083 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
1084 }
1085 }
1086 }
1087
1088 // -----------------------------------------------------------------------
1089
ImplRemoveWindow(sal_Bool bRemoveFrameData)1090 void Window::ImplRemoveWindow( sal_Bool bRemoveFrameData )
1091 {
1092 // Fenster aus den Listen austragen
1093 if ( !mpWindowImpl->mbFrame )
1094 {
1095 if ( ImplIsOverlapWindow() )
1096 {
1097 if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this )
1098 mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap;
1099 else
1100 {
1101 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
1102 while ( pTempWin->mpWindowImpl->mpNextOverlap != this )
1103 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
1104 pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap;
1105 }
1106
1107 if ( mpWindowImpl->mpPrev )
1108 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
1109 else
1110 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
1111 if ( mpWindowImpl->mpNext )
1112 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
1113 else
1114 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
1115 }
1116 else
1117 {
1118 if ( mpWindowImpl->mpPrev )
1119 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
1120 else
1121 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
1122 if ( mpWindowImpl->mpNext )
1123 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
1124 else
1125 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
1126 }
1127
1128 mpWindowImpl->mpPrev = NULL;
1129 mpWindowImpl->mpNext = NULL;
1130 }
1131
1132 if ( bRemoveFrameData )
1133 {
1134 // Graphic freigeben
1135 ImplReleaseGraphics();
1136 }
1137 }
1138
1139 // -----------------------------------------------------------------------
1140
ImplCallResize()1141 void Window::ImplCallResize()
1142 {
1143 mpWindowImpl->mbCallResize = sal_False;
1144
1145 if( GetBackground().IsGradient() )
1146 Invalidate();
1147
1148 Resize();
1149
1150 // #88419# Most classes don't call the base class in Resize() and Move(),
1151 // => Call ImpleResize/Move instead of Resize/Move directly...
1152 ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE );
1153
1154 ImplExtResize();
1155 }
1156
1157 // -----------------------------------------------------------------------
1158
ImplCallMove()1159 void Window::ImplCallMove()
1160 {
1161 mpWindowImpl->mbCallMove = sal_False;
1162
1163 if( mpWindowImpl->mbFrame )
1164 {
1165 // update frame position
1166 SalFrame *pParentFrame = NULL;
1167 Window *pParent = ImplGetParent();
1168 while( pParent )
1169 {
1170 if( pParent->mpWindowImpl->mpFrame != mpWindowImpl->mpFrame )
1171 {
1172 pParentFrame = pParent->mpWindowImpl->mpFrame;
1173 break;
1174 }
1175 pParent = pParent->GetParent();
1176 }
1177
1178 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
1179 mpWindowImpl->maPos = Point( g.nX, g.nY );
1180 if( pParentFrame )
1181 {
1182 g = pParentFrame->GetGeometry();
1183 mpWindowImpl->maPos -= Point( g.nX, g.nY );
1184 }
1185 // the client window and and all its subclients have the same position as the borderframe
1186 // this is important for floating toolbars where the borderwindow is a floating window
1187 // which has another borderwindow (i.e. the system floating window)
1188 Window *pClientWin = mpWindowImpl->mpClientWindow;
1189 while( pClientWin )
1190 {
1191 pClientWin->mpWindowImpl->maPos = mpWindowImpl->maPos;
1192 pClientWin = pClientWin->mpWindowImpl->mpClientWindow;
1193 }
1194 }
1195
1196 Move();
1197
1198 ImplCallEventListeners( VCLEVENT_WINDOW_MOVE );
1199 }
1200
1201 // -----------------------------------------------------------------------
1202
ImplAutoHelpID(ResMgr * pResMgr)1203 static rtl::OString ImplAutoHelpID( ResMgr* pResMgr )
1204 {
1205 rtl::OString aRet;
1206
1207 if( pResMgr && Application::IsAutoHelpIdEnabled() )
1208 aRet = pResMgr->GetAutoHelpId();
1209
1210 return aRet;
1211 }
1212
1213 // -----------------------------------------------------------------------
1214
ImplInitRes(const ResId & rResId)1215 WinBits Window::ImplInitRes( const ResId& rResId )
1216 {
1217 GetRes( rResId );
1218
1219 char* pRes = (char*)GetClassRes();
1220 pRes += 8;
1221 sal_uInt32 nStyle = (sal_uInt32)GetLongRes( (void*)pRes );
1222 rResId.SetWinBits( nStyle );
1223 return nStyle;
1224 }
1225
1226 // -----------------------------------------------------------------------
1227
ImplLoadRes(const ResId & rResId)1228 void Window::ImplLoadRes( const ResId& rResId )
1229 {
1230 sal_uLong nObjMask = ReadLongRes();
1231
1232 // we need to calculate auto helpids before the resource gets closed
1233 // if the resource only contains flags, it will be closed before we try to read a help id
1234 // so we always create an auto help id that might be overwritten later
1235 // HelpId
1236 rtl::OString aHelpId = ImplAutoHelpID( rResId.GetResMgr() );
1237
1238 // ResourceStyle
1239 sal_uLong nRSStyle = ReadLongRes();
1240 // WinBits
1241 ReadLongRes();
1242
1243 if( nObjMask & WINDOW_HELPID )
1244 aHelpId = ReadByteStringRes();
1245
1246 SetHelpId( aHelpId );
1247
1248 sal_Bool bPos = sal_False;
1249 sal_Bool bSize = sal_False;
1250 Point aPos;
1251 Size aSize;
1252
1253 if ( nObjMask & (WINDOW_XYMAPMODE | WINDOW_X | WINDOW_Y) )
1254 {
1255 // Groessenangabe aus der Resource verwenden
1256 MapUnit ePosMap = MAP_PIXEL;
1257
1258 bPos = sal_True;
1259
1260 if ( nObjMask & WINDOW_XYMAPMODE )
1261 ePosMap = (MapUnit)ReadLongRes();
1262 if ( nObjMask & WINDOW_X )
1263 aPos.X() = ImplLogicUnitToPixelX( ReadLongRes(), ePosMap );
1264 if ( nObjMask & WINDOW_Y )
1265 aPos.Y() = ImplLogicUnitToPixelY( ReadLongRes(), ePosMap );
1266 }
1267
1268 if ( nObjMask & (WINDOW_WHMAPMODE | WINDOW_WIDTH | WINDOW_HEIGHT) )
1269 {
1270 // Groessenangabe aus der Resource verwenden
1271 MapUnit eSizeMap = MAP_PIXEL;
1272
1273 bSize = sal_True;
1274
1275 if ( nObjMask & WINDOW_WHMAPMODE )
1276 eSizeMap = (MapUnit)ReadLongRes();
1277 if ( nObjMask & WINDOW_WIDTH )
1278 aSize.Width() = ImplLogicUnitToPixelX( ReadLongRes(), eSizeMap );
1279 if ( nObjMask & WINDOW_HEIGHT )
1280 aSize.Height() = ImplLogicUnitToPixelY( ReadLongRes(), eSizeMap );
1281 }
1282
1283 // Wegen Optimierung so schlimm aussehend
1284 if ( nRSStyle & RSWND_CLIENTSIZE )
1285 {
1286 if ( bPos )
1287 SetPosPixel( aPos );
1288 if ( bSize )
1289 SetOutputSizePixel( aSize );
1290 }
1291 else if ( bPos && bSize )
1292 SetPosSizePixel( aPos, aSize );
1293 else if ( bPos )
1294 SetPosPixel( aPos );
1295 else if ( bSize )
1296 SetSizePixel( aSize );
1297
1298 if ( nRSStyle & RSWND_DISABLED )
1299 Enable( sal_False );
1300
1301 if ( nObjMask & WINDOW_TEXT )
1302 SetText( ReadStringRes() );
1303 if ( nObjMask & WINDOW_HELPTEXT )
1304 {
1305 SetHelpText( ReadStringRes() );
1306 mpWindowImpl->mbHelpTextDynamic = sal_True;
1307 }
1308 if ( nObjMask & WINDOW_QUICKTEXT )
1309 SetQuickHelpText( ReadStringRes() );
1310 if ( nObjMask & WINDOW_EXTRALONG )
1311 SetData( (void*)ReadLongRes() );
1312 if ( nObjMask & WINDOW_UNIQUEID )
1313 SetUniqueId( ReadByteStringRes() );
1314
1315 if ( nObjMask & WINDOW_BORDER_STYLE )
1316 {
1317 sal_uInt16 nBorderStyle = (sal_uInt16)ReadLongRes();
1318 SetBorderStyle( nBorderStyle );
1319 }
1320 }
1321
1322 // -----------------------------------------------------------------------
1323
ImplGetWinData() const1324 ImplWinData* Window::ImplGetWinData() const
1325 {
1326 if ( !mpWindowImpl->mpWinData )
1327 {
1328 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
1329
1330 ((Window*)this)->mpWindowImpl->mpWinData = new ImplWinData;
1331 mpWindowImpl->mpWinData->mpExtOldText = NULL;
1332 mpWindowImpl->mpWinData->mpExtOldAttrAry = NULL;
1333 mpWindowImpl->mpWinData->mpCursorRect = 0;
1334 mpWindowImpl->mpWinData->mnCursorExtWidth = 0;
1335 mpWindowImpl->mpWinData->mpFocusRect = NULL;
1336 mpWindowImpl->mpWinData->mpTrackRect = NULL;
1337 mpWindowImpl->mpWinData->mnTrackFlags = 0;
1338 mpWindowImpl->mpWinData->mnIsTopWindow = (sal_uInt16) ~0; // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
1339 mpWindowImpl->mpWinData->mbMouseOver = sal_False;
1340 mpWindowImpl->mpWinData->mbEnableNativeWidget = (pNoNWF && *pNoNWF) ? sal_False : sal_True; // sal_True: try to draw this control with native theme API
1341 }
1342
1343 return mpWindowImpl->mpWinData;
1344 }
1345
1346 // -----------------------------------------------------------------------
1347
ImplGetFrameGraphics() const1348 SalGraphics* Window::ImplGetFrameGraphics() const
1349 {
1350 if ( mpWindowImpl->mpFrameWindow->mpGraphics )
1351 mpWindowImpl->mpFrameWindow->mbInitClipRegion = sal_True;
1352 else
1353 mpWindowImpl->mpFrameWindow->ImplGetGraphics();
1354 mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion();
1355 return mpWindowImpl->mpFrameWindow->mpGraphics;
1356 }
1357
1358 // -----------------------------------------------------------------------
1359
ImplFindWindow(const Point & rFramePos)1360 Window* Window::ImplFindWindow( const Point& rFramePos )
1361 {
1362 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1363
1364 Window* pTempWindow;
1365 Window* pFindWindow;
1366
1367 // Zuerst alle ueberlappenden Fenster ueberpruefen
1368 pTempWindow = mpWindowImpl->mpFirstOverlap;
1369 while ( pTempWindow )
1370 {
1371 pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
1372 if ( pFindWindow )
1373 return pFindWindow;
1374 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
1375 }
1376
1377 // dann testen wir unser Fenster
1378 if ( !mpWindowImpl->mbVisible )
1379 return NULL;
1380
1381 sal_uInt16 nHitTest = ImplHitTest( rFramePos );
1382 if ( nHitTest & WINDOW_HITTEST_INSIDE )
1383 {
1384 // und danach gehen wir noch alle Child-Fenster durch
1385 pTempWindow = mpWindowImpl->mpFirstChild;
1386 while ( pTempWindow )
1387 {
1388 pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
1389 if ( pFindWindow )
1390 return pFindWindow;
1391 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
1392 }
1393
1394 if ( nHitTest & WINDOW_HITTEST_TRANSPARENT )
1395 return NULL;
1396 else
1397 return this;
1398 }
1399
1400 return NULL;
1401 }
1402
1403 // -----------------------------------------------------------------------
1404
ImplHitTest(const Point & rFramePos)1405 sal_uInt16 Window::ImplHitTest( const Point& rFramePos )
1406 {
1407 Point aFramePos( rFramePos );
1408 if( ImplIsAntiparallel() )
1409 {
1410 // - RTL - re-mirror frame pos at this window
1411 ImplReMirror( aFramePos );
1412 }
1413 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
1414 if ( !aRect.IsInside( aFramePos ) )
1415 return 0;
1416 if ( mpWindowImpl->mbWinRegion )
1417 {
1418 Point aTempPos = aFramePos;
1419 aTempPos.X() -= mnOutOffX;
1420 aTempPos.Y() -= mnOutOffY;
1421 if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
1422 return 0;
1423 }
1424
1425 sal_uInt16 nHitTest = WINDOW_HITTEST_INSIDE;
1426 if ( mpWindowImpl->mbMouseTransparent )
1427 nHitTest |= WINDOW_HITTEST_TRANSPARENT;
1428 return nHitTest;
1429 }
1430
1431 // -----------------------------------------------------------------------
1432
ImplIsRealParentPath(const Window * pWindow) const1433 sal_Bool Window::ImplIsRealParentPath( const Window* pWindow ) const
1434 {
1435 pWindow = pWindow->GetParent();
1436 while ( pWindow )
1437 {
1438 if ( pWindow == this )
1439 return sal_True;
1440 pWindow = pWindow->GetParent();
1441 }
1442
1443 return sal_False;
1444 }
1445
1446 // -----------------------------------------------------------------------
1447
ImplIsChild(const Window * pWindow,sal_Bool bSystemWindow) const1448 sal_Bool Window::ImplIsChild( const Window* pWindow, sal_Bool bSystemWindow ) const
1449 {
1450 do
1451 {
1452 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
1453 break;
1454
1455 pWindow = pWindow->ImplGetParent();
1456
1457 if ( pWindow == this )
1458 return sal_True;
1459 }
1460 while ( pWindow );
1461
1462 return sal_False;
1463 }
1464
1465 // -----------------------------------------------------------------------
1466
ImplIsWindowOrChild(const Window * pWindow,sal_Bool bSystemWindow) const1467 sal_Bool Window::ImplIsWindowOrChild( const Window* pWindow, sal_Bool bSystemWindow ) const
1468 {
1469 if ( this == pWindow )
1470 return sal_True;
1471 return ImplIsChild( pWindow, bSystemWindow );
1472 }
1473
1474 // -----------------------------------------------------------------------
1475
ImplGetSameParent(const Window * pWindow) const1476 Window* Window::ImplGetSameParent( const Window* pWindow ) const
1477 {
1478 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
1479 return NULL;
1480 else
1481 {
1482 if ( pWindow->ImplIsChild( this ) )
1483 return (Window*)pWindow;
1484 else
1485 {
1486 Window* pTestWindow = (Window*)this;
1487 while ( (pTestWindow == pWindow) || pTestWindow->ImplIsChild( pWindow ) )
1488 pTestWindow = pTestWindow->ImplGetParent();
1489 return pTestWindow;
1490 }
1491 }
1492 }
1493
1494 // -----------------------------------------------------------------------
1495
ImplTestMousePointerSet()1496 int Window::ImplTestMousePointerSet()
1497 {
1498 // Wenn Mouse gecaptured ist, dann soll MousePointer umgeschaltet werden
1499 if ( IsMouseCaptured() )
1500 return sal_True;
1501
1502 // Wenn sich Mouse ueber dem Fenster befindet, dann soll MousePointer
1503 // umgeschaltet werden
1504 Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
1505 if ( aClientRect.IsInside( GetPointerPosPixel() ) )
1506 return sal_True;
1507
1508 return sal_False;
1509 }
1510
1511 // -----------------------------------------------------------------------
1512
ImplGetMousePointer() const1513 PointerStyle Window::ImplGetMousePointer() const
1514 {
1515 PointerStyle ePointerStyle;
1516 sal_Bool bWait = sal_False;
1517
1518 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
1519 ePointerStyle = GetPointer().GetStyle();
1520 else
1521 ePointerStyle = POINTER_ARROW;
1522
1523 const Window* pWindow = this;
1524 do
1525 {
1526 // Wenn Pointer nicht sichtbar, dann wird Suche abgebrochen, da
1527 // dieser Status nicht ueberschrieben werden darf
1528 if ( pWindow->mpWindowImpl->mbNoPtrVisible )
1529 return POINTER_NULL;
1530
1531 if ( !bWait )
1532 {
1533 if ( pWindow->mpWindowImpl->mnWaitCount )
1534 {
1535 ePointerStyle = POINTER_WAIT;
1536 bWait = sal_True;
1537 }
1538 else
1539 {
1540 if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
1541 ePointerStyle = pWindow->GetPointer().GetStyle();
1542 }
1543 }
1544
1545 if ( pWindow->ImplIsOverlapWindow() )
1546 break;
1547
1548 pWindow = pWindow->ImplGetParent();
1549 }
1550 while ( pWindow );
1551
1552 return ePointerStyle;
1553 }
1554
1555 // -----------------------------------------------------------------------
1556
ImplResetReallyVisible()1557 void Window::ImplResetReallyVisible()
1558 {
1559 sal_Bool bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
1560
1561 mbDevOutput = sal_False;
1562 mpWindowImpl->mbReallyVisible = sal_False;
1563 mpWindowImpl->mbReallyShown = sal_False;
1564
1565 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1566 // For this, the data member of the event must not be NULL.
1567 // Previously, we did this in Window::Show, but there some events got lost in certain situations.
1568 // #104887# - 2004-08-10 - fs@openoffice.org
1569 if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
1570 ImplCallEventListeners( VCLEVENT_WINDOW_HIDE, this );
1571 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_HIDE. Normally, we should
1572 // introduce another event which explicitly triggers the Accessibility implementations.
1573
1574 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1575 while ( pWindow )
1576 {
1577 if ( pWindow->mpWindowImpl->mbReallyVisible )
1578 pWindow->ImplResetReallyVisible();
1579 pWindow = pWindow->mpWindowImpl->mpNext;
1580 }
1581
1582 pWindow = mpWindowImpl->mpFirstChild;
1583 while ( pWindow )
1584 {
1585 if ( pWindow->mpWindowImpl->mbReallyVisible )
1586 pWindow->ImplResetReallyVisible();
1587 pWindow = pWindow->mpWindowImpl->mpNext;
1588 }
1589 }
1590
1591 // -----------------------------------------------------------------------
1592
ImplSetReallyVisible()1593 void Window::ImplSetReallyVisible()
1594 {
1595 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1596 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1597 // mbReallyShown is a useful indicator
1598 if( !mpWindowImpl->mbReallyShown )
1599 ImplCallInitShow();
1600
1601 sal_Bool bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;
1602
1603 mbDevOutput = sal_True;
1604 mpWindowImpl->mbReallyVisible = sal_True;
1605 mpWindowImpl->mbReallyShown = sal_True;
1606
1607 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1608 // For this, the data member of the event must not be NULL.
1609 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1610 // we're doing it when the visibility really changes
1611 // #104887# - 2004-08-10 - fs@openoffice.org
1612 if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
1613 ImplCallEventListeners( VCLEVENT_WINDOW_SHOW, this );
1614 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_SHOW. Normally, we should
1615 // introduce another event which explicitly triggers the Accessibility implementations.
1616
1617 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1618 while ( pWindow )
1619 {
1620 if ( pWindow->mpWindowImpl->mbVisible )
1621 pWindow->ImplSetReallyVisible();
1622 pWindow = pWindow->mpWindowImpl->mpNext;
1623 }
1624
1625 pWindow = mpWindowImpl->mpFirstChild;
1626 while ( pWindow )
1627 {
1628 if ( pWindow->mpWindowImpl->mbVisible )
1629 pWindow->ImplSetReallyVisible();
1630 pWindow = pWindow->mpWindowImpl->mpNext;
1631 }
1632 }
1633
1634 // -----------------------------------------------------------------------
1635
ImplCallInitShow()1636 void Window::ImplCallInitShow()
1637 {
1638 mpWindowImpl->mbReallyShown = sal_True;
1639 mpWindowImpl->mbInInitShow = sal_True;
1640 StateChanged( STATE_CHANGE_INITSHOW );
1641 mpWindowImpl->mbInInitShow = sal_False;
1642
1643 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1644 while ( pWindow )
1645 {
1646 if ( pWindow->mpWindowImpl->mbVisible )
1647 pWindow->ImplCallInitShow();
1648 pWindow = pWindow->mpWindowImpl->mpNext;
1649 }
1650
1651 pWindow = mpWindowImpl->mpFirstChild;
1652 while ( pWindow )
1653 {
1654 if ( pWindow->mpWindowImpl->mbVisible )
1655 pWindow->ImplCallInitShow();
1656 pWindow = pWindow->mpWindowImpl->mpNext;
1657 }
1658 }
1659
1660 // -----------------------------------------------------------------------
1661
ImplAddDel(ImplDelData * pDel)1662 void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatibility ok
1663 {
1664 DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" );
1665 if( !pDel->mpWindow )
1666 {
1667 pDel->mpWindow = this; // #112873# store ref to this window, so pDel can remove itself
1668 pDel->mpNext = mpWindowImpl->mpFirstDel;
1669 mpWindowImpl->mpFirstDel = pDel;
1670 }
1671 }
1672
1673 // -----------------------------------------------------------------------
1674
ImplRemoveDel(ImplDelData * pDel)1675 void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatibility ok
1676 {
1677 pDel->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
1678 if ( mpWindowImpl->mpFirstDel == pDel )
1679 mpWindowImpl->mpFirstDel = pDel->mpNext;
1680 else
1681 {
1682 ImplDelData* pData = mpWindowImpl->mpFirstDel;
1683 while ( pData->mpNext != pDel )
1684 pData = pData->mpNext;
1685 pData->mpNext = pDel->mpNext;
1686 }
1687 }
1688
1689 // -----------------------------------------------------------------------
1690
ImplInitResolutionSettings()1691 void Window::ImplInitResolutionSettings()
1692 {
1693 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
1694 if ( mpWindowImpl->mbFrame )
1695 {
1696 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
1697 sal_uInt16 nScreenZoom = rStyleSettings.GetScreenZoom();
1698 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
1699 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
1700 SetPointFont( rStyleSettings.GetAppFont() );
1701 }
1702 else if ( mpWindowImpl->mpParent )
1703 {
1704 mnDPIX = mpWindowImpl->mpParent->mnDPIX;
1705 mnDPIY = mpWindowImpl->mpParent->mnDPIY;
1706 }
1707
1708 // Vorberechnete Werte fuer logische Einheiten updaten und auch
1709 // die entsprechenden Tools dazu
1710 if ( IsMapMode() )
1711 {
1712 MapMode aMapMode = GetMapMode();
1713 SetMapMode();
1714 SetMapMode( aMapMode );
1715 }
1716 }
1717
1718 // -----------------------------------------------------------------------
1719
ImplPointToLogic(Font & rFont) const1720 void Window::ImplPointToLogic( Font& rFont ) const
1721 {
1722 Size aSize = rFont.GetSize();
1723 sal_uInt16 nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
1724
1725 if ( aSize.Width() )
1726 {
1727 aSize.Width() *= mpWindowImpl->mpFrameData->mnDPIX;
1728 aSize.Width() += 72/2;
1729 aSize.Width() /= 72;
1730 aSize.Width() *= nScreenFontZoom;
1731 aSize.Width() /= 100;
1732 }
1733 aSize.Height() *= mpWindowImpl->mpFrameData->mnDPIY;
1734 aSize.Height() += 72/2;
1735 aSize.Height() /= 72;
1736 aSize.Height() *= nScreenFontZoom;
1737 aSize.Height() /= 100;
1738
1739 if ( IsMapModeEnabled() )
1740 aSize = PixelToLogic( aSize );
1741
1742 rFont.SetSize( aSize );
1743 }
1744
1745 // -----------------------------------------------------------------------
1746
ImplLogicToPoint(Font & rFont) const1747 void Window::ImplLogicToPoint( Font& rFont ) const
1748 {
1749 Size aSize = rFont.GetSize();
1750 sal_uInt16 nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
1751
1752 if ( IsMapModeEnabled() )
1753 aSize = LogicToPixel( aSize );
1754
1755 if ( aSize.Width() )
1756 {
1757 aSize.Width() *= 100;
1758 aSize.Width() /= nScreenFontZoom;
1759 aSize.Width() *= 72;
1760 aSize.Width() += mpWindowImpl->mpFrameData->mnDPIX/2;
1761 aSize.Width() /= mpWindowImpl->mpFrameData->mnDPIX;
1762 }
1763 aSize.Height() *= 100;
1764 aSize.Height() /= nScreenFontZoom;
1765 aSize.Height() *= 72;
1766 aSize.Height() += mpWindowImpl->mpFrameData->mnDPIY/2;
1767 aSize.Height() /= mpWindowImpl->mpFrameData->mnDPIY;
1768
1769 rFont.SetSize( aSize );
1770 }
1771
1772 // -----------------------------------------------------------------------
1773
ImplSysObjClip(const Region * pOldRegion)1774 sal_Bool Window::ImplSysObjClip( const Region* pOldRegion )
1775 {
1776 sal_Bool bUpdate = sal_True;
1777
1778 if ( mpWindowImpl->mpSysObj )
1779 {
1780 sal_Bool bVisibleState = mpWindowImpl->mbReallyVisible;
1781
1782 if ( bVisibleState )
1783 {
1784 Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
1785
1786 if ( !pWinChildClipRegion->IsEmpty() )
1787 {
1788 if ( pOldRegion )
1789 {
1790 Region aNewRegion = *pWinChildClipRegion;
1791 pWinChildClipRegion->Intersect( *pOldRegion );
1792 bUpdate = aNewRegion == *pWinChildClipRegion;
1793 }
1794
1795 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
1796 ImplInvalidateAllOverlapBackgrounds();
1797
1798 Region aRegion = *pWinChildClipRegion;
1799 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
1800 Region aWinRectRegion( aWinRect );
1801 sal_uInt16 nClipFlags = mpWindowImpl->mpSysObj->GetClipRegionType();
1802
1803 if ( aRegion == aWinRectRegion )
1804 mpWindowImpl->mpSysObj->ResetClipRegion();
1805 else
1806 {
1807 if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS )
1808 {
1809 aWinRectRegion.Exclude( aRegion );
1810 aRegion = aWinRectRegion;
1811 }
1812 if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) )
1813 aRegion.Move( -mnOutOffX, -mnOutOffY );
1814
1815 // ClipRegion setzen/updaten
1816 RectangleVector aRectangles;
1817 aRegion.GetRegionRectangles(aRectangles);
1818 mpWindowImpl->mpSysObj->BeginSetClipRegion(aRectangles.size());
1819
1820 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
1821 {
1822 mpWindowImpl->mpSysObj->UnionClipRegion(
1823 aRectIter->Left(),
1824 aRectIter->Top(),
1825 aRectIter->GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does
1826 aRectIter->GetHeight()); // same for height
1827 }
1828
1829 mpWindowImpl->mpSysObj->EndSetClipRegion();
1830
1831 //long nX;
1832 //long nY;
1833 //long nWidth;
1834 //long nHeight;
1835 //sal_uLong nRectCount;
1836 //ImplRegionInfo aInfo;
1837 //sal_Bool bRegionRect;
1838 //
1839 //nRectCount = aRegion.GetRectCount();
1840 //mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount );
1841 //bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1842 //while ( bRegionRect )
1843 //{
1844 // mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
1845 // bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1846 //}
1847 //mpWindowImpl->mpSysObj->EndSetClipRegion();
1848 }
1849 }
1850 else
1851 bVisibleState = sal_False;
1852 }
1853
1854 // Visible-Status updaten
1855 mpWindowImpl->mpSysObj->Show( bVisibleState );
1856 }
1857
1858 return bUpdate;
1859 }
1860
1861 // -----------------------------------------------------------------------
1862
ImplUpdateSysObjChildsClip()1863 void Window::ImplUpdateSysObjChildsClip()
1864 {
1865 if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion )
1866 ImplSysObjClip( NULL );
1867
1868 Window* pWindow = mpWindowImpl->mpFirstChild;
1869 while ( pWindow )
1870 {
1871 pWindow->ImplUpdateSysObjChildsClip();
1872 pWindow = pWindow->mpWindowImpl->mpNext;
1873 }
1874 }
1875
1876 // -----------------------------------------------------------------------
1877
ImplUpdateSysObjOverlapsClip()1878 void Window::ImplUpdateSysObjOverlapsClip()
1879 {
1880 ImplUpdateSysObjChildsClip();
1881
1882 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1883 while ( pWindow )
1884 {
1885 pWindow->ImplUpdateSysObjOverlapsClip();
1886 pWindow = pWindow->mpWindowImpl->mpNext;
1887 }
1888 }
1889
1890 // -----------------------------------------------------------------------
1891
ImplUpdateSysObjClip()1892 void Window::ImplUpdateSysObjClip()
1893 {
1894 if ( !ImplIsOverlapWindow() )
1895 {
1896 ImplUpdateSysObjChildsClip();
1897
1898 // Schwestern muessen ihre ClipRegion auch neu berechnen
1899 if ( mpWindowImpl->mbClipSiblings )
1900 {
1901 Window* pWindow = mpWindowImpl->mpNext;
1902 while ( pWindow )
1903 {
1904 pWindow->ImplUpdateSysObjChildsClip();
1905 pWindow = pWindow->mpWindowImpl->mpNext;
1906 }
1907 }
1908 }
1909 else
1910 mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip();
1911 }
1912
1913 // -----------------------------------------------------------------------
1914
ImplSetClipFlagChilds(sal_Bool bSysObjOnlySmaller)1915 sal_Bool Window::ImplSetClipFlagChilds( sal_Bool bSysObjOnlySmaller )
1916 {
1917 sal_Bool bUpdate = sal_True;
1918 if ( mpWindowImpl->mpSysObj )
1919 {
1920 Region* pOldRegion = NULL;
1921 if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion )
1922 pOldRegion = new Region( mpWindowImpl->maWinClipRegion );
1923
1924 mbInitClipRegion = sal_True;
1925 mpWindowImpl->mbInitWinClipRegion = sal_True;
1926
1927 Window* pWindow = mpWindowImpl->mpFirstChild;
1928 while ( pWindow )
1929 {
1930 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
1931 bUpdate = sal_False;
1932 pWindow = pWindow->mpWindowImpl->mpNext;
1933 }
1934
1935 if ( !ImplSysObjClip( pOldRegion ) )
1936 {
1937 mbInitClipRegion = sal_True;
1938 mpWindowImpl->mbInitWinClipRegion = sal_True;
1939 bUpdate = sal_False;
1940 }
1941
1942 if ( pOldRegion )
1943 delete pOldRegion;
1944 }
1945 else
1946 {
1947 mbInitClipRegion = sal_True;
1948 mpWindowImpl->mbInitWinClipRegion = sal_True;
1949
1950 Window* pWindow = mpWindowImpl->mpFirstChild;
1951 while ( pWindow )
1952 {
1953 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
1954 bUpdate = sal_False;
1955 pWindow = pWindow->mpWindowImpl->mpNext;
1956 }
1957 }
1958 return bUpdate;
1959 }
1960
1961 // -----------------------------------------------------------------------
1962
ImplSetClipFlagOverlapWindows(sal_Bool bSysObjOnlySmaller)1963 sal_Bool Window::ImplSetClipFlagOverlapWindows( sal_Bool bSysObjOnlySmaller )
1964 {
1965 sal_Bool bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
1966
1967 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1968 while ( pWindow )
1969 {
1970 if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
1971 bUpdate = sal_False;
1972 pWindow = pWindow->mpWindowImpl->mpNext;
1973 }
1974
1975 return bUpdate;
1976 }
1977
1978 // -----------------------------------------------------------------------
1979
ImplSetClipFlag(sal_Bool bSysObjOnlySmaller)1980 sal_Bool Window::ImplSetClipFlag( sal_Bool bSysObjOnlySmaller )
1981 {
1982 if ( !ImplIsOverlapWindow() )
1983 {
1984 sal_Bool bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
1985
1986 Window* pParent = ImplGetParent();
1987 if ( pParent &&
1988 ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP)) )
1989 {
1990 pParent->mbInitClipRegion = sal_True;
1991 pParent->mpWindowImpl->mbInitChildRegion = sal_True;
1992 }
1993
1994 // Schwestern muessen ihre ClipRegion auch neu berechnen
1995 if ( mpWindowImpl->mbClipSiblings )
1996 {
1997 Window* pWindow = mpWindowImpl->mpNext;
1998 while ( pWindow )
1999 {
2000 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
2001 bUpdate = sal_False;
2002 pWindow = pWindow->mpWindowImpl->mpNext;
2003 }
2004 }
2005
2006 return bUpdate;
2007 }
2008 else
2009 return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
2010 }
2011
2012 // -----------------------------------------------------------------------
2013
ImplIntersectWindowClipRegion(Region & rRegion)2014 void Window::ImplIntersectWindowClipRegion( Region& rRegion )
2015 {
2016 if ( mpWindowImpl->mbInitWinClipRegion )
2017 ImplInitWinClipRegion();
2018
2019 rRegion.Intersect( mpWindowImpl->maWinClipRegion );
2020 }
2021
2022 // -----------------------------------------------------------------------
2023
ImplIntersectWindowRegion(Region & rRegion)2024 void Window::ImplIntersectWindowRegion( Region& rRegion )
2025 {
2026 rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ),
2027 Size( mnOutWidth, mnOutHeight ) ) );
2028 if ( mpWindowImpl->mbWinRegion )
2029 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2030 }
2031
2032 // -----------------------------------------------------------------------
2033
ImplExcludeWindowRegion(Region & rRegion)2034 void Window::ImplExcludeWindowRegion( Region& rRegion )
2035 {
2036 if ( mpWindowImpl->mbWinRegion )
2037 {
2038 Point aPoint( mnOutOffX, mnOutOffY );
2039 Region aRegion( Rectangle( aPoint,
2040 Size( mnOutWidth, mnOutHeight ) ) );
2041 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2042 rRegion.Exclude( aRegion );
2043 }
2044 else
2045 {
2046 Point aPoint( mnOutOffX, mnOutOffY );
2047 rRegion.Exclude( Rectangle( aPoint,
2048 Size( mnOutWidth, mnOutHeight ) ) );
2049 }
2050 }
2051
2052 // -----------------------------------------------------------------------
2053
ImplExcludeOverlapWindows(Region & rRegion)2054 void Window::ImplExcludeOverlapWindows( Region& rRegion )
2055 {
2056 Window* pWindow = mpWindowImpl->mpFirstOverlap;
2057 while ( pWindow )
2058 {
2059 if ( pWindow->mpWindowImpl->mbReallyVisible )
2060 {
2061 pWindow->ImplExcludeWindowRegion( rRegion );
2062 pWindow->ImplExcludeOverlapWindows( rRegion );
2063 }
2064
2065 pWindow = pWindow->mpWindowImpl->mpNext;
2066 }
2067 }
2068
2069 // -----------------------------------------------------------------------
2070
ImplExcludeOverlapWindows2(Region & rRegion)2071 void Window::ImplExcludeOverlapWindows2( Region& rRegion )
2072 {
2073 if ( mpWindowImpl->mbReallyVisible )
2074 ImplExcludeWindowRegion( rRegion );
2075
2076 ImplExcludeOverlapWindows( rRegion );
2077 }
2078
2079 // -----------------------------------------------------------------------
2080
ImplClipBoundaries(Region & rRegion,sal_Bool bThis,sal_Bool bOverlaps)2081 void Window::ImplClipBoundaries( Region& rRegion, sal_Bool bThis, sal_Bool bOverlaps )
2082 {
2083 if ( bThis )
2084 ImplIntersectWindowClipRegion( rRegion );
2085 else if ( ImplIsOverlapWindow() )
2086 {
2087 // Evt. noch am Frame clippen
2088 if ( !mpWindowImpl->mbFrame )
2089 rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
2090
2091 if ( bOverlaps && !rRegion.IsEmpty() )
2092 {
2093 // Clip Overlap Siblings
2094 Window* pStartOverlapWindow = this;
2095 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
2096 {
2097 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
2098 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
2099 {
2100 pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
2101 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
2102 }
2103 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
2104 }
2105
2106 // Clip Child Overlap Windows
2107 ImplExcludeOverlapWindows( rRegion );
2108 }
2109 }
2110 else
2111 ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
2112 }
2113
2114 // -----------------------------------------------------------------------
2115
ImplClipChilds(Region & rRegion)2116 sal_Bool Window::ImplClipChilds( Region& rRegion )
2117 {
2118 sal_Bool bOtherClip = sal_False;
2119 Window* pWindow = mpWindowImpl->mpFirstChild;
2120 while ( pWindow )
2121 {
2122 if ( pWindow->mpWindowImpl->mbReallyVisible )
2123 {
2124 // ParentClipMode-Flags auswerten
2125 sal_uInt16 nClipMode = pWindow->GetParentClipMode();
2126 if ( !(nClipMode & PARENTCLIPMODE_NOCLIP) &&
2127 ((nClipMode & PARENTCLIPMODE_CLIP) || (GetStyle() & WB_CLIPCHILDREN)) )
2128 pWindow->ImplExcludeWindowRegion( rRegion );
2129 else
2130 bOtherClip = sal_True;
2131 }
2132
2133 pWindow = pWindow->mpWindowImpl->mpNext;
2134 }
2135
2136 return bOtherClip;
2137 }
2138
2139 // -----------------------------------------------------------------------
2140
ImplClipAllChilds(Region & rRegion)2141 void Window::ImplClipAllChilds( Region& rRegion )
2142 {
2143 Window* pWindow = mpWindowImpl->mpFirstChild;
2144 while ( pWindow )
2145 {
2146 if ( pWindow->mpWindowImpl->mbReallyVisible )
2147 pWindow->ImplExcludeWindowRegion( rRegion );
2148 pWindow = pWindow->mpWindowImpl->mpNext;
2149 }
2150 }
2151
2152 // -----------------------------------------------------------------------
2153
ImplClipSiblings(Region & rRegion)2154 void Window::ImplClipSiblings( Region& rRegion )
2155 {
2156 Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
2157 while ( pWindow )
2158 {
2159 if ( pWindow == this )
2160 break;
2161
2162 if ( pWindow->mpWindowImpl->mbReallyVisible )
2163 pWindow->ImplExcludeWindowRegion( rRegion );
2164
2165 pWindow = pWindow->mpWindowImpl->mpNext;
2166 }
2167 }
2168
2169 // -----------------------------------------------------------------------
2170
ImplInitWinClipRegion()2171 void Window::ImplInitWinClipRegion()
2172 {
2173 // Build Window Region
2174 mpWindowImpl->maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ),
2175 Size( mnOutWidth, mnOutHeight ) );
2176 if ( mpWindowImpl->mbWinRegion )
2177 mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2178
2179 // ClipSiblings
2180 if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() )
2181 ImplClipSiblings( mpWindowImpl->maWinClipRegion );
2182
2183 // Clip Parent Boundaries
2184 ImplClipBoundaries( mpWindowImpl->maWinClipRegion, sal_False, sal_True );
2185
2186 // Clip Children
2187 if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren )
2188 mpWindowImpl->mbInitChildRegion = sal_True;
2189
2190 mpWindowImpl->mbInitWinClipRegion = sal_False;
2191 }
2192
2193 // -----------------------------------------------------------------------
2194
ImplInitWinChildClipRegion()2195 void Window::ImplInitWinChildClipRegion()
2196 {
2197 if ( !mpWindowImpl->mpFirstChild )
2198 {
2199 if ( mpWindowImpl->mpChildClipRegion )
2200 {
2201 delete mpWindowImpl->mpChildClipRegion;
2202 mpWindowImpl->mpChildClipRegion = NULL;
2203 }
2204 }
2205 else
2206 {
2207 if ( !mpWindowImpl->mpChildClipRegion )
2208 mpWindowImpl->mpChildClipRegion = new Region( mpWindowImpl->maWinClipRegion );
2209 else
2210 *mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion;
2211
2212 ImplClipChilds( *mpWindowImpl->mpChildClipRegion );
2213 }
2214
2215 mpWindowImpl->mbInitChildRegion = sal_False;
2216 }
2217
2218 // -----------------------------------------------------------------------
2219
ImplGetWinChildClipRegion()2220 Region* Window::ImplGetWinChildClipRegion()
2221 {
2222 if ( mpWindowImpl->mbInitWinClipRegion )
2223 ImplInitWinClipRegion();
2224 if ( mpWindowImpl->mbInitChildRegion )
2225 ImplInitWinChildClipRegion();
2226 if ( mpWindowImpl->mpChildClipRegion )
2227 return mpWindowImpl->mpChildClipRegion;
2228 else
2229 return &mpWindowImpl->maWinClipRegion;
2230 }
2231
2232 // -----------------------------------------------------------------------
2233
ImplIntersectAndUnionOverlapWindows(const Region & rInterRegion,Region & rRegion)2234 void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion )
2235 {
2236 Window* pWindow = mpWindowImpl->mpFirstOverlap;
2237 while ( pWindow )
2238 {
2239 if ( pWindow->mpWindowImpl->mbReallyVisible )
2240 {
2241 Region aTempRegion( rInterRegion );
2242 pWindow->ImplIntersectWindowRegion( aTempRegion );
2243 rRegion.Union( aTempRegion );
2244 pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2245 }
2246
2247 pWindow = pWindow->mpWindowImpl->mpNext;
2248 }
2249 }
2250
2251 // -----------------------------------------------------------------------
2252
ImplIntersectAndUnionOverlapWindows2(const Region & rInterRegion,Region & rRegion)2253 void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion )
2254 {
2255 if ( mpWindowImpl->mbReallyVisible )
2256 {
2257 Region aTempRegion( rInterRegion );
2258 ImplIntersectWindowRegion( aTempRegion );
2259 rRegion.Union( aTempRegion );
2260 }
2261
2262 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2263 }
2264
2265 // -----------------------------------------------------------------------
2266
ImplCalcOverlapRegionOverlaps(const Region & rInterRegion,Region & rRegion)2267 void Window::ImplCalcOverlapRegionOverlaps( const Region& rInterRegion, Region& rRegion )
2268 {
2269 // Clip Overlap Siblings
2270 Window* pStartOverlapWindow;
2271 if ( !ImplIsOverlapWindow() )
2272 pStartOverlapWindow = mpWindowImpl->mpOverlapWindow;
2273 else
2274 pStartOverlapWindow = this;
2275 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
2276 {
2277 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
2278 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
2279 {
2280 pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
2281 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
2282 }
2283 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
2284 }
2285
2286 // Clip Child Overlap Windows
2287 if ( !ImplIsOverlapWindow() )
2288 mpWindowImpl->mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2289 else
2290 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2291 }
2292
2293 // -----------------------------------------------------------------------
2294
ImplCalcOverlapRegion(const Rectangle & rSourceRect,Region & rRegion,sal_Bool bChilds,sal_Bool bParent,sal_Bool bSiblings)2295 void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, Region& rRegion,
2296 sal_Bool bChilds, sal_Bool bParent, sal_Bool bSiblings )
2297 {
2298 Region aRegion( rSourceRect );
2299 if ( mpWindowImpl->mbWinRegion )
2300 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2301 Region aTempRegion;
2302 Window* pWindow;
2303
2304 ImplCalcOverlapRegionOverlaps( aRegion, rRegion );
2305
2306 // Parent-Boundaries
2307 if ( bParent )
2308 {
2309 pWindow = this;
2310 if ( !ImplIsOverlapWindow() )
2311 {
2312 pWindow = ImplGetParent();
2313 do
2314 {
2315 aTempRegion = aRegion;
2316 pWindow->ImplExcludeWindowRegion( aTempRegion );
2317 rRegion.Union( aTempRegion );
2318 if ( pWindow->ImplIsOverlapWindow() )
2319 break;
2320 pWindow = pWindow->ImplGetParent();
2321 }
2322 while ( pWindow );
2323 }
2324 if ( !pWindow->mpWindowImpl->mbFrame )
2325 {
2326 aTempRegion = aRegion;
2327 aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
2328 rRegion.Union( aTempRegion );
2329 }
2330 }
2331
2332 // Siblings
2333 if ( bSiblings && !ImplIsOverlapWindow() )
2334 {
2335 pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
2336 do
2337 {
2338 if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) )
2339 {
2340 aTempRegion = aRegion;
2341 pWindow->ImplIntersectWindowRegion( aTempRegion );
2342 rRegion.Union( aTempRegion );
2343 }
2344 pWindow = pWindow->mpWindowImpl->mpNext;
2345 }
2346 while ( pWindow );
2347 }
2348
2349 // Childs
2350 if ( bChilds )
2351 {
2352 pWindow = mpWindowImpl->mpFirstChild;
2353 while ( pWindow )
2354 {
2355 if ( pWindow->mpWindowImpl->mbReallyVisible )
2356 {
2357 aTempRegion = aRegion;
2358 pWindow->ImplIntersectWindowRegion( aTempRegion );
2359 rRegion.Union( aTempRegion );
2360 }
2361 pWindow = pWindow->mpWindowImpl->mpNext;
2362 }
2363 }
2364 }
2365
2366 // -----------------------------------------------------------------------
2367
ImplCallPaint(const Region * pRegion,sal_uInt16 nPaintFlags)2368 void Window::ImplCallPaint( const Region* pRegion, sal_uInt16 nPaintFlags )
2369 {
2370 Exception aException;
2371 bool bExceptionCaught(false);
2372
2373 // call PrePaint. PrePaint may add to the invalidate region as well as
2374 // other parameters used below.
2375 PrePaint();
2376
2377 mpWindowImpl->mbPaintFrame = sal_False;
2378
2379 if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
2380 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDS | (nPaintFlags & IMPL_PAINT_PAINTALL);
2381 if ( nPaintFlags & IMPL_PAINT_PAINTCHILDS )
2382 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS;
2383 if ( nPaintFlags & IMPL_PAINT_ERASE )
2384 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
2385 if ( nPaintFlags & IMPL_PAINT_CHECKRTL )
2386 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
2387 if ( !mpWindowImpl->mpFirstChild )
2388 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDS;
2389
2390 if ( mpWindowImpl->mbPaintDisabled )
2391 {
2392 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2393 Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
2394 else if ( pRegion )
2395 Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
2396 return;
2397 }
2398
2399 nPaintFlags = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT);
2400
2401 Region* pChildRegion = NULL;
2402 Rectangle aSelectionRect;
2403 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
2404 {
2405 Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
2406 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2407 mpWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
2408 else
2409 {
2410 if ( pRegion )
2411 mpWindowImpl->maInvalidateRegion.Union( *pRegion );
2412
2413 if( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible )
2414 /* #98602# need to repaint all children within the
2415 * tracking rectangle, so the following invert
2416 * operation takes places without traces of the previous
2417 * one.
2418 */
2419 mpWindowImpl->maInvalidateRegion.Union( *mpWindowImpl->mpWinData->mpTrackRect );
2420
2421 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
2422 pChildRegion = new Region( mpWindowImpl->maInvalidateRegion );
2423 mpWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion );
2424 }
2425 mpWindowImpl->mnPaintFlags = 0;
2426 if ( !mpWindowImpl->maInvalidateRegion.IsEmpty() )
2427 {
2428 bool bRestoreCursor = false;
2429 if ( mpWindowImpl->mpCursor )
2430 bRestoreCursor = mpWindowImpl->mpCursor->ImplHide( false );
2431
2432 mbInitClipRegion = sal_True;
2433 mpWindowImpl->mbInPaint = sal_True;
2434
2435 // Paint-Region zuruecksetzen
2436 Region aPaintRegion( mpWindowImpl->maInvalidateRegion );
2437 Rectangle aPaintRect = aPaintRegion.GetBoundRect();
2438
2439 // - RTL - re-mirror paint rect and region at this window
2440 if( ImplIsAntiparallel() )
2441 {
2442 ImplReMirror( aPaintRect );
2443 ImplReMirror( aPaintRegion );
2444 }
2445 aPaintRect = ImplDevicePixelToLogic( aPaintRect);
2446 mpWindowImpl->mpPaintRegion = &aPaintRegion;
2447 mpWindowImpl->maInvalidateRegion.SetEmpty();
2448
2449 if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() )
2450 {
2451 if ( IsClipRegion() )
2452 {
2453 Region aOldRegion = GetClipRegion();
2454 SetClipRegion();
2455 Erase();
2456 SetClipRegion( aOldRegion );
2457 }
2458 else
2459 Erase();
2460 }
2461
2462 // #98943# trigger drawing of toolbox selection after all children are painted
2463 if( mpWindowImpl->mbDrawSelectionBackground )
2464 aSelectionRect = aPaintRect;
2465
2466 // Paint can throw exceptions; to not have a situation where
2467 // mpWindowImpl->mbInPaint keeps to be on true (and other
2468 // settings, too) better catch here to avoid to go completely out of
2469 // this method without executing the after-paint stuff
2470 try
2471 {
2472 Paint( aPaintRect );
2473 }
2474 catch(Exception& rException)
2475 {
2476 aException = rException;
2477 bExceptionCaught = true;
2478 }
2479
2480 if ( mpWindowImpl->mpWinData )
2481 {
2482 if ( mpWindowImpl->mbFocusVisible )
2483 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
2484 }
2485 mpWindowImpl->mbInPaint = sal_False;
2486 mbInitClipRegion = sal_True;
2487 mpWindowImpl->mpPaintRegion = NULL;
2488 if ( mpWindowImpl->mpCursor )
2489 mpWindowImpl->mpCursor->ImplShow( false, bRestoreCursor );
2490 }
2491 }
2492 else
2493 mpWindowImpl->mnPaintFlags = 0;
2494
2495 if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDS | IMPL_PAINT_PAINTCHILDS) )
2496 {
2497 // die Childfenster ausgeben
2498 Window* pTempWindow = mpWindowImpl->mpFirstChild;
2499 while ( pTempWindow )
2500 {
2501 if ( pTempWindow->mpWindowImpl->mbVisible )
2502 pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags );
2503 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2504 }
2505 }
2506
2507 if ( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
2508 /* #98602# need to invert the tracking rect AFTER
2509 * the children have painted
2510 */
2511 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
2512
2513 // #98943# draw toolbox selection
2514 if( !aSelectionRect.IsEmpty() )
2515 DrawSelectionBackground( aSelectionRect, 3, sal_False, sal_True, sal_False );
2516
2517 if ( pChildRegion )
2518 delete pChildRegion;
2519
2520 if(bExceptionCaught)
2521 {
2522 throw(aException);
2523 }
2524 }
2525
2526 // -----------------------------------------------------------------------
2527
ImplCallOverlapPaint()2528 void Window::ImplCallOverlapPaint()
2529 {
2530 // Zuerst geben wir die ueberlappenden Fenster aus
2531 Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
2532 while ( pTempWindow )
2533 {
2534 if ( pTempWindow->mpWindowImpl->mbReallyVisible )
2535 pTempWindow->ImplCallOverlapPaint();
2536 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2537 }
2538
2539 // und dann erst uns selber
2540 if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
2541 {
2542 // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
2543 // because we were called from the Sal layer
2544 ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
2545 }
2546 }
2547
2548 // -----------------------------------------------------------------------
2549
ImplPostPaint()2550 void Window::ImplPostPaint()
2551 {
2552 if ( !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
2553 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2554 }
2555
2556 // -----------------------------------------------------------------------
2557
IMPL_LINK(Window,ImplHandlePaintHdl,void *,EMPTYARG)2558 IMPL_LINK( Window, ImplHandlePaintHdl, void*, EMPTYARG )
2559 {
2560 // save paint events until resizing is done
2561 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
2562 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2563 else if ( mpWindowImpl->mbReallyVisible )
2564 ImplCallOverlapPaint();
2565 return 0;
2566 }
2567
2568 // -----------------------------------------------------------------------
2569
IMPL_LINK(Window,ImplHandleResizeTimerHdl,void *,EMPTYARG)2570 IMPL_LINK( Window, ImplHandleResizeTimerHdl, void*, EMPTYARG )
2571 {
2572 if( mpWindowImpl->mbReallyVisible )
2573 {
2574 ImplCallResize();
2575 if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
2576 {
2577 mpWindowImpl->mpFrameData->maPaintTimer.Stop();
2578 mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL );
2579 }
2580 }
2581
2582 return 0;
2583 }
2584
2585 // -----------------------------------------------------------------------
2586
ImplInvalidateFrameRegion(const Region * pRegion,sal_uInt16 nFlags)2587 void Window::ImplInvalidateFrameRegion( const Region* pRegion, sal_uInt16 nFlags )
2588 {
2589 // PAINTCHILDS bei allen Parent-Fenster bis zum ersten OverlapWindow
2590 // setzen
2591 if ( !ImplIsOverlapWindow() )
2592 {
2593 Window* pTempWindow = this;
2594 sal_uInt16 nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0;
2595 do
2596 {
2597 pTempWindow = pTempWindow->ImplGetParent();
2598 if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS )
2599 break;
2600 pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS | nTranspPaint;
2601 if( ! pTempWindow->IsPaintTransparent() )
2602 nTranspPaint = 0;
2603 }
2604 while ( !pTempWindow->ImplIsOverlapWindow() );
2605 }
2606
2607 // Paint-Flags setzen
2608 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT;
2609 if ( nFlags & INVALIDATE_CHILDREN )
2610 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDS;
2611 if ( !(nFlags & INVALIDATE_NOERASE) )
2612 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
2613 if ( !pRegion )
2614 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL;
2615
2616 // Wenn nicht alles neu ausgegeben werden muss, dann die Region
2617 // dazupacken
2618 if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) )
2619 mpWindowImpl->maInvalidateRegion.Union( *pRegion );
2620
2621 // Handle transparent windows correctly: invalidate must be done on the first opaque parent
2622 if( ((IsPaintTransparent() && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
2623 && ImplGetParent() )
2624 {
2625 Window *pParent = ImplGetParent();
2626 while( pParent && pParent->IsPaintTransparent() )
2627 pParent = pParent->ImplGetParent();
2628 if( pParent )
2629 {
2630 Region *pChildRegion;
2631 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2632 // invalidate the whole child window region in the parent
2633 pChildRegion = ImplGetWinChildClipRegion();
2634 else
2635 // invalidate the same region in the parent that has to be repainted in the child
2636 pChildRegion = &mpWindowImpl->maInvalidateRegion;
2637
2638 nFlags |= INVALIDATE_CHILDREN; // paint should also be done on all children
2639 nFlags &= ~INVALIDATE_NOERASE; // parent should paint and erase to create proper background
2640 pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
2641 }
2642 }
2643 ImplPostPaint();
2644 }
2645
2646 // -----------------------------------------------------------------------
2647
ImplInvalidateOverlapFrameRegion(const Region & rRegion)2648 void Window::ImplInvalidateOverlapFrameRegion( const Region& rRegion )
2649 {
2650 Region aRegion = rRegion;
2651
2652 ImplClipBoundaries( aRegion, sal_True, sal_True );
2653 if ( !aRegion.IsEmpty() )
2654 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
2655
2656 // Dann invalidieren wir die ueberlappenden Fenster
2657 Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
2658 while ( pTempWindow )
2659 {
2660 if ( pTempWindow->IsVisible() )
2661 pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
2662
2663 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2664 }
2665 }
2666
2667 // -----------------------------------------------------------------------
2668
ImplInvalidateParentFrameRegion(Region & rRegion)2669 void Window::ImplInvalidateParentFrameRegion( Region& rRegion )
2670 {
2671 if ( mpWindowImpl->mbOverlapWin )
2672 mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
2673 else
2674 {
2675 if( ImplGetParent() )
2676 ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN );
2677 }
2678 }
2679
2680 // -----------------------------------------------------------------------
2681
ImplInvalidate(const Region * pRegion,sal_uInt16 nFlags)2682 void Window::ImplInvalidate( const Region* pRegion, sal_uInt16 nFlags )
2683 {
2684
2685 // Hintergrund-Sicherung zuruecksetzen
2686 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
2687 ImplInvalidateAllOverlapBackgrounds();
2688
2689 // Feststellen, was neu ausgegeben werden muss
2690 sal_Bool bInvalidateAll = !pRegion;
2691
2692 // Transparent-Invalidate beruecksichtigen
2693 Window* pOpaqueWindow = this;
2694 if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
2695 {
2696 Window* pTempWindow = pOpaqueWindow->ImplGetParent();
2697 while ( pTempWindow )
2698 {
2699 if ( !pTempWindow->IsPaintTransparent() )
2700 {
2701 pOpaqueWindow = pTempWindow;
2702 nFlags |= INVALIDATE_CHILDREN;
2703 bInvalidateAll = sal_False;
2704 break;
2705 }
2706
2707 if ( pTempWindow->ImplIsOverlapWindow() )
2708 break;
2709
2710 pTempWindow = pTempWindow->ImplGetParent();
2711 }
2712 }
2713
2714 // Region zusammenbauen
2715 sal_uInt16 nOrgFlags = nFlags;
2716 if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) )
2717 {
2718 if ( GetStyle() & WB_CLIPCHILDREN )
2719 nFlags |= INVALIDATE_NOCHILDREN;
2720 else
2721 nFlags |= INVALIDATE_CHILDREN;
2722 }
2723 if ( (nFlags & INVALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
2724 bInvalidateAll = sal_False;
2725 if ( bInvalidateAll )
2726 ImplInvalidateFrameRegion( NULL, nFlags );
2727 else
2728 {
2729 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2730 Region aRegion( aRect );
2731 if ( pRegion )
2732 {
2733 // --- RTL --- remirror region before intersecting it
2734 if ( ImplIsAntiparallel() )
2735 {
2736 Region aRgn( *pRegion );
2737 ImplReMirror( aRgn );
2738 aRegion.Intersect( aRgn );
2739 }
2740 else
2741 aRegion.Intersect( *pRegion );
2742 }
2743 ImplClipBoundaries( aRegion, sal_True, sal_True );
2744 if ( nFlags & INVALIDATE_NOCHILDREN )
2745 {
2746 nFlags &= ~INVALIDATE_CHILDREN;
2747 if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) )
2748 {
2749 if ( nOrgFlags & INVALIDATE_NOCHILDREN )
2750 ImplClipAllChilds( aRegion );
2751 else
2752 {
2753 if ( ImplClipChilds( aRegion ) )
2754 nFlags |= INVALIDATE_CHILDREN;
2755 }
2756 }
2757 }
2758 if ( !aRegion.IsEmpty() )
2759 ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
2760 }
2761
2762 if ( nFlags & INVALIDATE_UPDATE )
2763 pOpaqueWindow->Update(); // start painting at the opaque parent
2764 }
2765
2766 // -----------------------------------------------------------------------
2767
ImplMoveInvalidateRegion(const Rectangle & rRect,long nHorzScroll,long nVertScroll,sal_Bool bChilds)2768 void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
2769 long nHorzScroll, long nVertScroll,
2770 sal_Bool bChilds )
2771 {
2772 if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
2773 {
2774 Region aTempRegion = mpWindowImpl->maInvalidateRegion;
2775 aTempRegion.Intersect( rRect );
2776 aTempRegion.Move( nHorzScroll, nVertScroll );
2777 mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
2778 }
2779
2780 if ( bChilds && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS) )
2781 {
2782 Window* pWindow = mpWindowImpl->mpFirstChild;
2783 while ( pWindow )
2784 {
2785 pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, sal_True );
2786 pWindow = pWindow->mpWindowImpl->mpNext;
2787 }
2788 }
2789 }
2790
2791 // -----------------------------------------------------------------------
2792
ImplMoveAllInvalidateRegions(const Rectangle & rRect,long nHorzScroll,long nVertScroll,sal_Bool bChilds)2793 void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect,
2794 long nHorzScroll, long nVertScroll,
2795 sal_Bool bChilds )
2796 {
2797 // Paint-Region auch verschieben, wenn noch Paints anstehen
2798 ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChilds );
2799 // Paint-Region muss bei uns verschoben gesetzt werden, die durch
2800 // die Parents gezeichnet werden
2801 if ( !ImplIsOverlapWindow() )
2802 {
2803 Region aPaintAllRegion;
2804 Window* pPaintAllWindow = this;
2805 do
2806 {
2807 pPaintAllWindow = pPaintAllWindow->ImplGetParent();
2808 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
2809 {
2810 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2811 {
2812 aPaintAllRegion.SetEmpty();
2813 break;
2814 }
2815 else
2816 aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
2817 }
2818 }
2819 while ( !pPaintAllWindow->ImplIsOverlapWindow() );
2820 if ( !aPaintAllRegion.IsEmpty() )
2821 {
2822 aPaintAllRegion.Move( nHorzScroll, nVertScroll );
2823 sal_uInt16 nPaintFlags = 0;
2824 if ( bChilds )
2825 mpWindowImpl->mnPaintFlags |= INVALIDATE_CHILDREN;
2826 ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
2827 }
2828 }
2829 }
2830
2831 // -----------------------------------------------------------------------
2832
ImplValidateFrameRegion(const Region * pRegion,sal_uInt16 nFlags)2833 void Window::ImplValidateFrameRegion( const Region* pRegion, sal_uInt16 nFlags )
2834 {
2835 if ( !pRegion )
2836 mpWindowImpl->maInvalidateRegion.SetEmpty();
2837 else
2838 {
2839 // Wenn alle Childfenster neu ausgegeben werden muessen,
2840 // dann invalidieren wir diese vorher
2841 if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS) && mpWindowImpl->mpFirstChild )
2842 {
2843 Region aChildRegion = mpWindowImpl->maInvalidateRegion;
2844 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2845 {
2846 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2847 aChildRegion = aRect;
2848 }
2849 Window* pChild = mpWindowImpl->mpFirstChild;
2850 while ( pChild )
2851 {
2852 pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
2853 pChild = pChild->mpWindowImpl->mpNext;
2854 }
2855 }
2856 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2857 {
2858 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2859 mpWindowImpl->maInvalidateRegion = aRect;
2860 }
2861 mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
2862 }
2863 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
2864
2865 if ( nFlags & VALIDATE_CHILDREN )
2866 {
2867 Window* pChild = mpWindowImpl->mpFirstChild;
2868 while ( pChild )
2869 {
2870 pChild->ImplValidateFrameRegion( pRegion, nFlags );
2871 pChild = pChild->mpWindowImpl->mpNext;
2872 }
2873 }
2874 }
2875
2876 // -----------------------------------------------------------------------
2877
ImplValidate(const Region * pRegion,sal_uInt16 nFlags)2878 void Window::ImplValidate( const Region* pRegion, sal_uInt16 nFlags )
2879 {
2880 // Region zusammenbauen
2881 sal_Bool bValidateAll = !pRegion;
2882 sal_uInt16 nOrgFlags = nFlags;
2883 if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) )
2884 {
2885 if ( GetStyle() & WB_CLIPCHILDREN )
2886 nFlags |= VALIDATE_NOCHILDREN;
2887 else
2888 nFlags |= VALIDATE_CHILDREN;
2889 }
2890 if ( (nFlags & VALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
2891 bValidateAll = sal_False;
2892 if ( bValidateAll )
2893 ImplValidateFrameRegion( NULL, nFlags );
2894 else
2895 {
2896 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2897 Region aRegion( aRect );
2898 if ( pRegion )
2899 aRegion.Intersect( *pRegion );
2900 ImplClipBoundaries( aRegion, sal_True, sal_True );
2901 if ( nFlags & VALIDATE_NOCHILDREN )
2902 {
2903 nFlags &= ~VALIDATE_CHILDREN;
2904 if ( nOrgFlags & VALIDATE_NOCHILDREN )
2905 ImplClipAllChilds( aRegion );
2906 else
2907 {
2908 if ( ImplClipChilds( aRegion ) )
2909 nFlags |= VALIDATE_CHILDREN;
2910 }
2911 }
2912 if ( !aRegion.IsEmpty() )
2913 ImplValidateFrameRegion( &aRegion, nFlags );
2914 }
2915 }
2916
2917 // -----------------------------------------------------------------------
2918
ImplScroll(const Rectangle & rRect,long nHorzScroll,long nVertScroll,sal_uInt16 nFlags)2919 void Window::ImplScroll( const Rectangle& rRect,
2920 long nHorzScroll, long nVertScroll, sal_uInt16 nFlags )
2921 {
2922 if ( !IsDeviceOutputNecessary() )
2923 return;
2924
2925 nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll );
2926 nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll );
2927
2928 if ( !nHorzScroll && !nVertScroll )
2929 return;
2930
2931 // Hintergrund-Sicherung zuruecksetzen
2932 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
2933 ImplInvalidateAllOverlapBackgrounds();
2934
2935 if ( mpWindowImpl->mpCursor )
2936 mpWindowImpl->mpCursor->ImplHide( false );
2937
2938 sal_uInt16 nOrgFlags = nFlags;
2939 if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) )
2940 {
2941 if ( GetStyle() & WB_CLIPCHILDREN )
2942 nFlags |= SCROLL_NOCHILDREN;
2943 else
2944 nFlags |= SCROLL_CHILDREN;
2945 }
2946
2947 Region aInvalidateRegion;
2948 sal_Bool bScrollChilds = (nFlags & SCROLL_CHILDREN) != 0;
2949 sal_Bool bErase = (nFlags & SCROLL_NOERASE) == 0;
2950
2951 if ( !mpWindowImpl->mpFirstChild )
2952 bScrollChilds = sal_False;
2953
2954 // --- RTL --- check if this window requires special action
2955 sal_Bool bReMirror = ( ImplIsAntiparallel() );
2956
2957 Rectangle aRectMirror( rRect );
2958 if( bReMirror )
2959 {
2960 // --- RTL --- make sure the invalidate region of this window is
2961 // computed in the same coordinate space as the one from the overlap windows
2962 ImplReMirror( aRectMirror );
2963 }
2964
2965 // Paint-Bereiche anpassen
2966 ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChilds );
2967
2968 if ( !(nFlags & SCROLL_NOINVALIDATE) )
2969 {
2970 ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChilds, sal_True, sal_False );
2971
2972 // --- RTL ---
2973 // if the scrolling on the device is performed in the opposite direction
2974 // then move the overlaps in that direction to compute the invalidate region
2975 // on the correct side, i.e., revert nHorzScroll
2976
2977 if ( !aInvalidateRegion.IsEmpty() )
2978 {
2979 aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
2980 bErase = sal_True;
2981 }
2982 if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) )
2983 {
2984 Rectangle aDestRect( aRectMirror );
2985 aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
2986 Region aWinInvalidateRegion( aRectMirror );
2987 aWinInvalidateRegion.Exclude( aDestRect );
2988
2989 aInvalidateRegion.Union( aWinInvalidateRegion );
2990 }
2991 }
2992
2993 Point aPoint( mnOutOffX, mnOutOffY );
2994 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
2995 if ( nFlags & SCROLL_CLIP )
2996 aRegion.Intersect( rRect );
2997 if ( mpWindowImpl->mbWinRegion )
2998 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2999
3000 aRegion.Exclude( aInvalidateRegion );
3001
3002 ImplClipBoundaries( aRegion, sal_False, sal_True );
3003 if ( !bScrollChilds )
3004 {
3005 if ( nOrgFlags & SCROLL_NOCHILDREN )
3006 ImplClipAllChilds( aRegion );
3007 else
3008 ImplClipChilds( aRegion );
3009 }
3010 if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) )
3011 aRegion.Intersect( maRegion );
3012 if ( !aRegion.IsEmpty() )
3013 {
3014 if ( mpWindowImpl->mpWinData )
3015 {
3016 if ( mpWindowImpl->mbFocusVisible )
3017 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
3018 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
3019 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
3020 }
3021
3022 SalGraphics* pGraphics = ImplGetFrameGraphics();
3023 if ( pGraphics )
3024 {
3025 if( bReMirror )
3026 {
3027 // --- RTL --- frame coordinates require re-mirroring
3028 ImplReMirror( aRegion );
3029 }
3030
3031 ImplSelectClipRegion( aRegion, pGraphics );
3032 pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
3033 rRect.Left(), rRect.Top(),
3034 rRect.GetWidth(), rRect.GetHeight(),
3035 SAL_COPYAREA_WINDOWINVALIDATE, this );
3036 }
3037
3038 if ( mpWindowImpl->mpWinData )
3039 {
3040 if ( mpWindowImpl->mbFocusVisible )
3041 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
3042 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
3043 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
3044 }
3045 }
3046
3047 if ( !aInvalidateRegion.IsEmpty() )
3048 {
3049 // --- RTL --- the invalidate region for this windows is already computed in frame coordinates
3050 // so it has to be re-mirrored before calling the Paint-handler
3051 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
3052
3053 sal_uInt16 nPaintFlags = INVALIDATE_CHILDREN;
3054 if ( !bErase )
3055 nPaintFlags |= INVALIDATE_NOERASE;
3056 if ( !bScrollChilds )
3057 {
3058 if ( nOrgFlags & SCROLL_NOCHILDREN )
3059 ImplClipAllChilds( aInvalidateRegion );
3060 else
3061 ImplClipChilds( aInvalidateRegion );
3062 }
3063 ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags );
3064 }
3065
3066 if ( bScrollChilds )
3067 {
3068 Window* pWindow = mpWindowImpl->mpFirstChild;
3069 while ( pWindow )
3070 {
3071 Point aPos = pWindow->GetPosPixel();
3072 aPos += Point( nHorzScroll, nVertScroll );
3073 pWindow->SetPosPixel( aPos );
3074
3075 pWindow = pWindow->mpWindowImpl->mpNext;
3076 }
3077 }
3078
3079 if ( nFlags & SCROLL_UPDATE )
3080 Update();
3081
3082 if ( mpWindowImpl->mpCursor )
3083 mpWindowImpl->mpCursor->ImplShow( false );
3084 }
3085
3086 // -----------------------------------------------------------------------
3087
ImplUpdateAll(sal_Bool bOverlapWindows)3088 void Window::ImplUpdateAll( sal_Bool bOverlapWindows )
3089 {
3090 if ( !mpWindowImpl->mbReallyVisible )
3091 return;
3092
3093 sal_Bool bFlush = sal_False;
3094 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
3095 {
3096 Point aPoint( 0, 0 );
3097 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
3098 ImplInvalidateOverlapFrameRegion( aRegion );
3099 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
3100 bFlush = sal_True;
3101 }
3102
3103 // Ein Update wirkt immer auf das OverlapWindow, damit bei spaeteren
3104 // Paints nicht zuviel gemalt wird, wenn dort ALLCHILDREN usw. gesetzt
3105 // ist
3106 Window* pWindow = ImplGetFirstOverlapWindow();
3107 if ( bOverlapWindows )
3108 pWindow->ImplCallOverlapPaint();
3109 else
3110 {
3111 if ( pWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
3112 pWindow->ImplCallPaint( NULL, pWindow->mpWindowImpl->mnPaintFlags );
3113 }
3114
3115 if ( bFlush )
3116 Flush();
3117 }
3118
3119 // -----------------------------------------------------------------------
3120
ImplUpdateWindowPtr(Window * pWindow)3121 void Window::ImplUpdateWindowPtr( Window* pWindow )
3122 {
3123 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
3124 {
3125 // Graphic freigeben
3126 ImplReleaseGraphics();
3127 }
3128
3129 mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData;
3130 mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
3131 mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow;
3132 if ( pWindow->ImplIsOverlapWindow() )
3133 mpWindowImpl->mpOverlapWindow = pWindow;
3134 else
3135 mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
3136
3137 Window* pChild = mpWindowImpl->mpFirstChild;
3138 while ( pChild )
3139 {
3140 pChild->ImplUpdateWindowPtr( pWindow );
3141 pChild = pChild->mpWindowImpl->mpNext;
3142 }
3143 }
3144
3145 // -----------------------------------------------------------------------
3146
ImplUpdateWindowPtr()3147 void Window::ImplUpdateWindowPtr()
3148 {
3149 Window* pChild = mpWindowImpl->mpFirstChild;
3150 while ( pChild )
3151 {
3152 pChild->ImplUpdateWindowPtr( this );
3153 pChild = pChild->mpWindowImpl->mpNext;
3154 }
3155 }
3156
3157 // -----------------------------------------------------------------------
3158
ImplUpdateOverlapWindowPtr(sal_Bool bNewFrame)3159 void Window::ImplUpdateOverlapWindowPtr( sal_Bool bNewFrame )
3160 {
3161 sal_Bool bVisible = IsVisible();
3162 Show( sal_False );
3163 ImplRemoveWindow( bNewFrame );
3164 Window* pRealParent = mpWindowImpl->mpRealParent;
3165 ImplInsertWindow( ImplGetParent() );
3166 mpWindowImpl->mpRealParent = pRealParent;
3167 ImplUpdateWindowPtr();
3168 if ( ImplUpdatePos() )
3169 ImplUpdateSysObjPos();
3170
3171 if ( bNewFrame )
3172 {
3173 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3174 while ( pOverlapWindow )
3175 {
3176 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3177 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
3178 pOverlapWindow = pNextOverlapWindow;
3179 }
3180 }
3181
3182 if ( bVisible )
3183 Show( sal_True );
3184 }
3185
3186 // -----------------------------------------------------------------------
3187
ImplUpdatePos()3188 sal_Bool Window::ImplUpdatePos()
3189 {
3190 sal_Bool bSysChild = sal_False;
3191
3192 if ( ImplIsOverlapWindow() )
3193 {
3194 mnOutOffX = mpWindowImpl->mnX;
3195 mnOutOffY = mpWindowImpl->mnY;
3196 }
3197 else
3198 {
3199 Window* pParent = ImplGetParent();
3200
3201 mnOutOffX = mpWindowImpl->mnX + pParent->mnOutOffX;
3202 mnOutOffY = mpWindowImpl->mnY + pParent->mnOutOffY;
3203 }
3204
3205 Window* pChild = mpWindowImpl->mpFirstChild;
3206 while ( pChild )
3207 {
3208 if ( pChild->ImplUpdatePos() )
3209 bSysChild = sal_True;
3210 pChild = pChild->mpWindowImpl->mpNext;
3211 }
3212
3213 if ( mpWindowImpl->mpSysObj )
3214 bSysChild = sal_True;
3215
3216 return bSysChild;
3217 }
3218
3219 // -----------------------------------------------------------------------
3220
ImplUpdateSysObjPos()3221 void Window::ImplUpdateSysObjPos()
3222 {
3223 if ( mpWindowImpl->mpSysObj )
3224 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3225
3226 Window* pChild = mpWindowImpl->mpFirstChild;
3227 while ( pChild )
3228 {
3229 pChild->ImplUpdateSysObjPos();
3230 pChild = pChild->mpWindowImpl->mpNext;
3231 }
3232 }
3233 // -----------------------------------------------------------------------
3234
ImplPosSizeWindow(long nX,long nY,long nWidth,long nHeight,sal_uInt16 nFlags)3235 void Window::ImplPosSizeWindow( long nX, long nY,
3236 long nWidth, long nHeight, sal_uInt16 nFlags )
3237 {
3238 sal_Bool bNewPos = sal_False;
3239 sal_Bool bNewSize = sal_False;
3240 sal_Bool bNewWidth = sal_False;
3241 sal_Bool bCopyBits = sal_False;
3242 long nOldOutOffX = mnOutOffX;
3243 long nOldOutOffY = mnOutOffY;
3244 long nOldOutWidth = mnOutWidth;
3245 long nOldOutHeight = mnOutHeight;
3246 Region* pOverlapRegion = NULL;
3247 Region* pOldRegion = NULL;
3248
3249 if ( IsReallyVisible() )
3250 {
3251 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3252 ImplInvalidateAllOverlapBackgrounds();
3253
3254 Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
3255 Size( nOldOutWidth, nOldOutHeight ) );
3256 pOldRegion = new Region( aOldWinRect );
3257 if ( mpWindowImpl->mbWinRegion )
3258 pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3259
3260 if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
3261 !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
3262 !HasPaintEvent() )
3263 bCopyBits = sal_True;
3264 }
3265
3266 sal_Bool bnXRecycled = sal_False; // avoid duplicate mirroring in RTL case
3267 if ( nFlags & WINDOW_POSSIZE_WIDTH )
3268 {
3269 if(!( nFlags & WINDOW_POSSIZE_X ))
3270 {
3271 nX = mpWindowImpl->mnX;
3272 nFlags |= WINDOW_POSSIZE_X;
3273 bnXRecycled = sal_True; // we're using a mnX which was already mirrored in RTL case
3274 }
3275
3276 if ( nWidth < 0 )
3277 nWidth = 0;
3278 if ( nWidth != mnOutWidth )
3279 {
3280 mnOutWidth = nWidth;
3281 bNewSize = sal_True;
3282 bCopyBits = sal_False;
3283 bNewWidth = sal_True;
3284 }
3285 }
3286 if ( nFlags & WINDOW_POSSIZE_HEIGHT )
3287 {
3288 if ( nHeight < 0 )
3289 nHeight = 0;
3290 if ( nHeight != mnOutHeight )
3291 {
3292 mnOutHeight = nHeight;
3293 bNewSize = sal_True;
3294 bCopyBits = sal_False;
3295 }
3296 }
3297
3298 if ( nFlags & WINDOW_POSSIZE_X )
3299 {
3300 long nOrgX = nX;
3301 // --- RTL --- (compare the screen coordinates)
3302 Point aPtDev( Point( nX+mnOutOffX, 0 ) );
3303 if( ImplHasMirroredGraphics() )
3304 {
3305 mpGraphics->mirror( aPtDev.X(), this );
3306
3307 // #106948# always mirror our pos if our parent is not mirroring, even
3308 // if we are also not mirroring
3309 // --- RTL --- check if parent is in different coordinates
3310 if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
3311 {
3312 // --- RTL --- (re-mirror at parent window)
3313 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
3314 }
3315 /* #i99166# An LTR window in RTL UI that gets sized only would be
3316 expected to not moved its upper left point
3317 */
3318 if( bnXRecycled )
3319 {
3320 if( ImplIsAntiparallel() )
3321 {
3322 aPtDev.X() = mpWindowImpl->mnAbsScreenX;
3323 nOrgX = mpWindowImpl->maPos.X();
3324 }
3325 }
3326 }
3327 else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
3328 {
3329 // mirrored window in LTR UI
3330 {
3331 // --- RTL --- (re-mirror at parent window)
3332 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
3333 }
3334 }
3335
3336 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
3337 if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
3338 {
3339 if ( bCopyBits && !pOverlapRegion )
3340 {
3341 pOverlapRegion = new Region();
3342 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
3343 Size( mnOutWidth, mnOutHeight ) ),
3344 *pOverlapRegion, sal_False, sal_True, sal_True );
3345 }
3346 mpWindowImpl->mnX = nX;
3347 mpWindowImpl->maPos.X() = nOrgX;
3348 mpWindowImpl->mnAbsScreenX = aPtDev.X(); // --- RTL --- (store real screen pos)
3349 bNewPos = sal_True;
3350 }
3351 }
3352 if ( nFlags & WINDOW_POSSIZE_Y )
3353 {
3354 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
3355 if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
3356 {
3357 if ( bCopyBits && !pOverlapRegion )
3358 {
3359 pOverlapRegion = new Region();
3360 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
3361 Size( mnOutWidth, mnOutHeight ) ),
3362 *pOverlapRegion, sal_False, sal_True, sal_True );
3363 }
3364 mpWindowImpl->mnY = nY;
3365 mpWindowImpl->maPos.Y() = nY;
3366 bNewPos = sal_True;
3367 }
3368 }
3369
3370 /* if ( nFlags & (WINDOW_POSSIZE_X|WINDOW_POSSIZE_Y) )
3371 {
3372 POINT aPt;
3373 aPt.x = mpWindowImpl->maPos.X();
3374 aPt.y = mpWindowImpl->maPos.Y();
3375 ClientToScreen( mpWindowImpl->mpFrame->maFrameData.mhWnd , &aPt );
3376 mpWindowImpl->maPos.X() = aPt.x;
3377 mpWindowImpl->maPos.Y() = aPt.y;
3378 }
3379 */
3380 if ( bNewPos || bNewSize )
3381 {
3382 sal_Bool bUpdateSysObjPos = sal_False;
3383 if ( bNewPos )
3384 bUpdateSysObjPos = ImplUpdatePos();
3385
3386 // the borderwindow always specifies the position for its client window
3387 if ( mpWindowImpl->mpBorderWindow )
3388 mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
3389
3390 if ( mpWindowImpl->mpClientWindow )
3391 {
3392 mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
3393 mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
3394 mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
3395 mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder,
3396 WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y |
3397 WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
3398 // Wenn wir ein ClientWindow haben, dann hat dieses fuer die
3399 // Applikation auch die Position des FloatingWindows
3400 mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
3401 if ( bNewPos )
3402 {
3403 if ( mpWindowImpl->mpClientWindow->IsVisible() )
3404 {
3405 mpWindowImpl->mpClientWindow->ImplCallMove();
3406 }
3407 else
3408 {
3409 mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = sal_True;
3410 }
3411 }
3412 }
3413 // else
3414 // {
3415 // if ( mpWindowImpl->mpBorderWindow )
3416 // mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
3417 // }
3418
3419 // Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor
3420 // einem Show() kommt
3421 if ( IsVisible() )
3422 {
3423 if ( bNewPos )
3424 {
3425 ImplCallMove();
3426 }
3427 if ( bNewSize )
3428 {
3429 ImplCallResize();
3430 }
3431 }
3432 else
3433 {
3434 if ( bNewPos )
3435 mpWindowImpl->mbCallMove = sal_True;
3436 if ( bNewSize )
3437 mpWindowImpl->mbCallResize = sal_True;
3438 }
3439
3440 sal_Bool bUpdateSysObjClip = sal_False;
3441 if ( IsReallyVisible() )
3442 {
3443 if ( bNewPos || bNewSize )
3444 {
3445 // Hintergrund-Sicherung zuruecksetzen
3446 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
3447 ImplDeleteOverlapBackground();
3448 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3449 ImplInvalidateAllOverlapBackgrounds();
3450 // Clip-Flag neu setzen
3451 bUpdateSysObjClip = !ImplSetClipFlag( sal_True );
3452 }
3453
3454 // Fensterinhalt invalidieren ?
3455 if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
3456 {
3457 if ( bNewPos )
3458 {
3459 sal_Bool bInvalidate = sal_False;
3460 sal_Bool bParentPaint = sal_True;
3461 if ( !ImplIsOverlapWindow() )
3462 bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
3463 if ( bCopyBits && bParentPaint && !HasPaintEvent() )
3464 {
3465 Point aPoint( mnOutOffX, mnOutOffY );
3466 Region aRegion( Rectangle( aPoint,
3467 Size( mnOutWidth, mnOutHeight ) ) );
3468 if ( mpWindowImpl->mbWinRegion )
3469 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3470 ImplClipBoundaries( aRegion, sal_False, sal_True );
3471 if ( !pOverlapRegion->IsEmpty() )
3472 {
3473 pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY );
3474 aRegion.Exclude( *pOverlapRegion );
3475 }
3476 if ( !aRegion.IsEmpty() )
3477 {
3478 // Paint-Bereiche anpassen
3479 ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX, nOldOutOffY ),
3480 Size( nOldOutWidth, nOldOutHeight ) ),
3481 mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY,
3482 sal_True );
3483 SalGraphics* pGraphics = ImplGetFrameGraphics();
3484 if ( pGraphics )
3485 {
3486 const bool bSelectClipRegion = ImplSelectClipRegion( aRegion, pGraphics );
3487 if ( bSelectClipRegion )
3488 {
3489 pGraphics->CopyArea( mnOutOffX, mnOutOffY,
3490 nOldOutOffX, nOldOutOffY,
3491 nOldOutWidth, nOldOutHeight,
3492 SAL_COPYAREA_WINDOWINVALIDATE, this );
3493 }
3494 else
3495 bInvalidate = sal_True;
3496 }
3497 else
3498 bInvalidate = sal_True;
3499 if ( !bInvalidate )
3500 {
3501 if ( !pOverlapRegion->IsEmpty() )
3502 ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN );
3503 }
3504 }
3505 else
3506 bInvalidate = sal_True;
3507 }
3508 else
3509 bInvalidate = sal_True;
3510 if ( bInvalidate )
3511 ImplInvalidateFrameRegion( NULL, INVALIDATE_CHILDREN );
3512 }
3513 else
3514 {
3515 Point aPoint( mnOutOffX, mnOutOffY );
3516 Region aRegion( Rectangle( aPoint,
3517 Size( mnOutWidth, mnOutHeight ) ) );
3518 aRegion.Exclude( *pOldRegion );
3519 if ( mpWindowImpl->mbWinRegion )
3520 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3521 ImplClipBoundaries( aRegion, sal_False, sal_True );
3522 if ( !aRegion.IsEmpty() )
3523 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
3524 }
3525 }
3526
3527 // Parent oder Overlaps invalidieren
3528 if ( bNewPos ||
3529 (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) )
3530 {
3531 Region aRegion( *pOldRegion );
3532 if ( !mpWindowImpl->mbPaintTransparent )
3533 ImplExcludeWindowRegion( aRegion );
3534 ImplClipBoundaries( aRegion, sal_False, sal_True );
3535 if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
3536 ImplInvalidateParentFrameRegion( aRegion );
3537 }
3538 }
3539
3540 // System-Objekte anpassen
3541 if ( bUpdateSysObjClip )
3542 ImplUpdateSysObjClip();
3543 if ( bUpdateSysObjPos )
3544 ImplUpdateSysObjPos();
3545 if ( bNewSize && mpWindowImpl->mpSysObj )
3546 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3547 }
3548
3549 if ( pOverlapRegion )
3550 delete pOverlapRegion;
3551 if ( pOldRegion )
3552 delete pOldRegion;
3553 }
3554
3555 // -----------------------------------------------------------------------
3556
ImplToBottomChild()3557 void Window::ImplToBottomChild()
3558 {
3559 if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) )
3560 {
3561 // Fenster an das Ende der Liste setzen
3562 if ( mpWindowImpl->mpPrev )
3563 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
3564 else
3565 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
3566 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
3567 mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
3568 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
3569 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
3570 mpWindowImpl->mpNext = NULL;
3571 }
3572 }
3573
3574 // -----------------------------------------------------------------------
3575
ImplCalcToTop(ImplCalcToTopData * pPrevData)3576 void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
3577 {
3578 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
3579
3580 if ( !mpWindowImpl->mbFrame )
3581 {
3582 if ( IsReallyVisible() )
3583 {
3584 // Region berechnen, wo das Fenster mit anderen Fenstern ueberlappt
3585 Point aPoint( mnOutOffX, mnOutOffY );
3586 Region aRegion( Rectangle( aPoint,
3587 Size( mnOutWidth, mnOutHeight ) ) );
3588 Region aInvalidateRegion;
3589 ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
3590
3591 if ( !aInvalidateRegion.IsEmpty() )
3592 {
3593 ImplCalcToTopData* pData = new ImplCalcToTopData;
3594 pPrevData->mpNext = pData;
3595 pData->mpNext = NULL;
3596 pData->mpWindow = this;
3597 pData->mpInvalidateRegion = new Region( aInvalidateRegion );
3598 }
3599 }
3600 }
3601 }
3602
3603 // -----------------------------------------------------------------------
3604
ImplCalcChildOverlapToTop(ImplCalcToTopData * pPrevData)3605 void Window::ImplCalcChildOverlapToTop( ImplCalcToTopData* pPrevData )
3606 {
3607 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcChildOverlapToTop(): Is not a OverlapWindow" );
3608
3609 ImplCalcToTop( pPrevData );
3610 if ( pPrevData->mpNext )
3611 pPrevData = pPrevData->mpNext;
3612
3613 Window* pOverlap = mpWindowImpl->mpFirstOverlap;
3614 while ( pOverlap )
3615 {
3616 pOverlap->ImplCalcToTop( pPrevData );
3617 if ( pPrevData->mpNext )
3618 pPrevData = pPrevData->mpNext;
3619 pOverlap = pOverlap->mpWindowImpl->mpNext;
3620 }
3621 }
3622
3623 // -----------------------------------------------------------------------
3624
ImplToTop(sal_uInt16 nFlags)3625 void Window::ImplToTop( sal_uInt16 nFlags )
3626 {
3627 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
3628
3629 if ( mpWindowImpl->mbFrame )
3630 {
3631 // Wenn in das externe Fenster geklickt wird, ist dieses
3632 // dafuer zustaendig dafuer zu sorgen, das unser Frame
3633 // nach vorne kommt
3634 if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
3635 !mpWindowImpl->mpFrameData->mbSysObjFocus &&
3636 !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
3637 !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
3638 {
3639 // do not bring floating windows on the client to top
3640 if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
3641 {
3642 sal_uInt16 nSysFlags = 0;
3643 if ( nFlags & TOTOP_RESTOREWHENMIN )
3644 nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN;
3645 if ( nFlags & TOTOP_FOREGROUNDTASK )
3646 nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK;
3647 if ( nFlags & TOTOP_GRABFOCUSONLY )
3648 nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY;
3649 mpWindowImpl->mpFrame->ToTop( nSysFlags );
3650 }
3651 }
3652 }
3653 else
3654 {
3655 if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this )
3656 {
3657 // Fenster aus der Liste entfernen
3658 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
3659 if ( mpWindowImpl->mpNext )
3660 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
3661 else
3662 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
3663
3664 // AlwaysOnTop beruecksichtigen
3665 sal_Bool bOnTop = IsAlwaysOnTopEnabled();
3666 Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
3667 if ( !bOnTop )
3668 {
3669 while ( pNextWin )
3670 {
3671 if ( !pNextWin->IsAlwaysOnTopEnabled() )
3672 break;
3673 pNextWin = pNextWin->mpWindowImpl->mpNext;
3674 }
3675 }
3676
3677 // TopLevel abpruefen
3678 sal_uInt8 nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel;
3679 while ( pNextWin )
3680 {
3681 if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) ||
3682 (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) )
3683 break;
3684 pNextWin = pNextWin->mpWindowImpl->mpNext;
3685 }
3686
3687 // Fenster in die Liste wieder eintragen
3688 mpWindowImpl->mpNext = pNextWin;
3689 if ( pNextWin )
3690 {
3691 mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
3692 pNextWin->mpWindowImpl->mpPrev = this;
3693 }
3694 else
3695 {
3696 mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
3697 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
3698 }
3699 if ( mpWindowImpl->mpPrev )
3700 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
3701 else
3702 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
3703
3704 // ClipRegion muss von diesem Fenster und allen weiteren
3705 // ueberlappenden Fenstern neu berechnet werden.
3706 if ( IsReallyVisible() )
3707 {
3708 // Hintergrund-Sicherung zuruecksetzen
3709 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3710 ImplInvalidateAllOverlapBackgrounds();
3711 mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
3712 }
3713 }
3714 }
3715 }
3716
3717 // -----------------------------------------------------------------------
3718
ImplStartToTop(sal_uInt16 nFlags)3719 void Window::ImplStartToTop( sal_uInt16 nFlags )
3720 {
3721 ImplCalcToTopData aStartData;
3722 ImplCalcToTopData* pCurData;
3723 ImplCalcToTopData* pNextData;
3724 Window* pOverlapWindow;
3725 if ( ImplIsOverlapWindow() )
3726 pOverlapWindow = this;
3727 else
3728 pOverlapWindow = mpWindowImpl->mpOverlapWindow;
3729
3730 // Zuerst die Paint-Bereiche berechnen
3731 Window* pTempOverlapWindow = pOverlapWindow;
3732 aStartData.mpNext = NULL;
3733 pCurData = &aStartData;
3734 do
3735 {
3736 pTempOverlapWindow->ImplCalcToTop( pCurData );
3737 if ( pCurData->mpNext )
3738 pCurData = pCurData->mpNext;
3739 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
3740 }
3741 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
3742 // Dann die Paint-Bereiche der ChildOverlap-Windows berechnen
3743 pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
3744 while ( pTempOverlapWindow )
3745 {
3746 pTempOverlapWindow->ImplCalcToTop( pCurData );
3747 if ( pCurData->mpNext )
3748 pCurData = pCurData->mpNext;
3749 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
3750 }
3751
3752 // Dann die Fenster-Verkettung aendern
3753 pTempOverlapWindow = pOverlapWindow;
3754 do
3755 {
3756 pTempOverlapWindow->ImplToTop( nFlags );
3757 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
3758 }
3759 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
3760 // Und zum Schluss invalidieren wir die ungueltigen Bereiche
3761 pCurData = aStartData.mpNext;
3762 while ( pCurData )
3763 {
3764 pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN );
3765 pNextData = pCurData->mpNext;
3766 delete pCurData->mpInvalidateRegion;
3767 delete pCurData;
3768 pCurData = pNextData;
3769 }
3770 }
3771
3772 // -----------------------------------------------------------------------
3773
ImplFocusToTop(sal_uInt16 nFlags,sal_Bool bReallyVisible)3774 void Window::ImplFocusToTop( sal_uInt16 nFlags, sal_Bool bReallyVisible )
3775 {
3776 // Soll Focus auch geholt werden?
3777 if ( !(nFlags & TOTOP_NOGRABFOCUS) )
3778 {
3779 // Erstes Fenster mit GrabFocus-Activate bekommt den Focus
3780 Window* pFocusWindow = this;
3781 while ( !pFocusWindow->ImplIsOverlapWindow() )
3782 {
3783 // Nur wenn Fenster kein Border-Fenster hat, da wir
3784 // immer das dazugehoerende BorderFenster finden wollen
3785 if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
3786 {
3787 if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS )
3788 break;
3789 }
3790 pFocusWindow = pFocusWindow->ImplGetParent();
3791 }
3792 if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) &&
3793 !pFocusWindow->HasChildPathFocus( sal_True ) )
3794 pFocusWindow->GrabFocus();
3795 }
3796
3797 if ( bReallyVisible )
3798 ImplGenerateMouseMove();
3799 }
3800
3801 // -----------------------------------------------------------------------
3802
ImplShowAllOverlaps()3803 void Window::ImplShowAllOverlaps()
3804 {
3805 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3806 while ( pOverlapWindow )
3807 {
3808 if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
3809 {
3810 pOverlapWindow->Show( sal_True, SHOW_NOACTIVATE );
3811 pOverlapWindow->mpWindowImpl->mbOverlapVisible = sal_False;
3812 }
3813
3814 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3815 }
3816 }
3817
3818 // -----------------------------------------------------------------------
3819
ImplHideAllOverlaps()3820 void Window::ImplHideAllOverlaps()
3821 {
3822 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3823 while ( pOverlapWindow )
3824 {
3825 if ( pOverlapWindow->IsVisible() )
3826 {
3827 pOverlapWindow->mpWindowImpl->mbOverlapVisible = sal_True;
3828 pOverlapWindow->Show( sal_False );
3829 }
3830
3831 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3832 }
3833 }
3834
3835 // -----------------------------------------------------------------------
3836
ImplCallMouseMove(sal_uInt16 nMouseCode,sal_Bool bModChanged)3837 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, sal_Bool bModChanged )
3838 {
3839 if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible )
3840 {
3841 sal_uLong nTime = Time::GetSystemTicks();
3842 long nX = mpWindowImpl->mpFrameData->mnLastMouseX;
3843 long nY = mpWindowImpl->mpFrameData->mnLastMouseY;
3844 sal_uInt16 nCode = nMouseCode;
3845 sal_uInt16 nMode = mpWindowImpl->mpFrameData->mnMouseMode;
3846 sal_Bool bLeave;
3847 // Auf MouseLeave testen
3848 if ( ((nX < 0) || (nY < 0) ||
3849 (nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) ||
3850 (nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) &&
3851 !ImplGetSVData()->maWinData.mpCaptureWin )
3852 bLeave = sal_True;
3853 else
3854 bLeave = sal_False;
3855 nMode |= MOUSE_SYNTHETIC;
3856 if ( bModChanged )
3857 nMode |= MOUSE_MODIFIERCHANGED;
3858 ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
3859 }
3860 }
3861
3862 // -----------------------------------------------------------------------
3863
ImplGenerateMouseMove()3864 void Window::ImplGenerateMouseMove()
3865 {
3866 if ( !mpWindowImpl->mpFrameData->mnMouseMoveId )
3867 Application::PostUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId, LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) );
3868 }
3869
3870 // -----------------------------------------------------------------------
3871
IMPL_LINK(Window,ImplGenerateMouseMoveHdl,void *,EMPTYARG)3872 IMPL_LINK( Window, ImplGenerateMouseMoveHdl, void*, EMPTYARG )
3873 {
3874 mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
3875 Window* pCaptureWin = ImplGetSVData()->maWinData.mpCaptureWin;
3876 if( ! pCaptureWin ||
3877 (pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame)
3878 )
3879 {
3880 ImplCallMouseMove( mpWindowImpl->mpFrameData->mnMouseCode );
3881 }
3882 return 0;
3883 }
3884
3885 // -----------------------------------------------------------------------
3886
ImplInvertFocus(const Rectangle & rRect)3887 void Window::ImplInvertFocus( const Rectangle& rRect )
3888 {
3889 InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
3890 }
3891
3892 // -----------------------------------------------------------------------
3893
ImplCallFocusChangeActivate(Window * pNewOverlapWindow,Window * pOldOverlapWindow)3894 void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow,
3895 Window* pOldOverlapWindow )
3896 {
3897 ImplSVData* pSVData = ImplGetSVData();
3898 Window* pNewRealWindow;
3899 Window* pOldRealWindow;
3900 Window* pLastRealWindow;
3901 sal_Bool bCallActivate = sal_True;
3902 sal_Bool bCallDeactivate = sal_True;
3903
3904 pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
3905 pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
3906 if ( (pOldRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
3907 pOldRealWindow->GetActivateMode() )
3908 {
3909 if ( (pNewRealWindow->GetType() == WINDOW_FLOATINGWINDOW) &&
3910 !pNewRealWindow->GetActivateMode() )
3911 {
3912 pSVData->maWinData.mpLastDeacWin = pOldOverlapWindow;
3913 bCallDeactivate = sal_False;
3914 }
3915 }
3916 else if ( (pNewRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
3917 pNewRealWindow->GetActivateMode() )
3918 {
3919 if ( pSVData->maWinData.mpLastDeacWin )
3920 {
3921 if ( pSVData->maWinData.mpLastDeacWin == pNewOverlapWindow )
3922 bCallActivate = sal_False;
3923 else
3924 {
3925 pLastRealWindow = pSVData->maWinData.mpLastDeacWin->ImplGetWindow();
3926 pSVData->maWinData.mpLastDeacWin->mpWindowImpl->mbActive = sal_False;
3927 pSVData->maWinData.mpLastDeacWin->Deactivate();
3928 if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin )
3929 {
3930 pLastRealWindow->mpWindowImpl->mbActive = sal_True;
3931 pLastRealWindow->Activate();
3932 }
3933 }
3934 pSVData->maWinData.mpLastDeacWin = NULL;
3935 }
3936 }
3937
3938 if ( bCallDeactivate )
3939 {
3940 if( pOldOverlapWindow->mpWindowImpl->mbActive )
3941 {
3942 pOldOverlapWindow->mpWindowImpl->mbActive = sal_False;
3943 pOldOverlapWindow->Deactivate();
3944 }
3945 if ( pOldRealWindow != pOldOverlapWindow )
3946 {
3947 if( pOldRealWindow->mpWindowImpl->mbActive )
3948 {
3949 pOldRealWindow->mpWindowImpl->mbActive = sal_False;
3950 pOldRealWindow->Deactivate();
3951 }
3952 }
3953 }
3954 if ( bCallActivate && ! pNewOverlapWindow->mpWindowImpl->mbActive )
3955 {
3956 if( ! pNewOverlapWindow->mpWindowImpl->mbActive )
3957 {
3958 pNewOverlapWindow->mpWindowImpl->mbActive = sal_True;
3959 pNewOverlapWindow->Activate();
3960 }
3961 if ( pNewRealWindow != pNewOverlapWindow )
3962 {
3963 if( ! pNewRealWindow->mpWindowImpl->mbActive )
3964 {
3965 pNewRealWindow->mpWindowImpl->mbActive = sal_True;
3966 pNewRealWindow->Activate();
3967 }
3968 }
3969 }
3970 }
3971
IsWindowFocused(const WindowImpl & rWinImpl)3972 static bool IsWindowFocused(const WindowImpl& rWinImpl)
3973 {
3974 if (rWinImpl.mpSysObj)
3975 return true;
3976
3977 if (rWinImpl.mpFrameData->mbHasFocus)
3978 return true;
3979
3980 if (rWinImpl.mbFakeFocusSet)
3981 return true;
3982
3983 return false;
3984 }
3985
3986 // -----------------------------------------------------------------------
ImplGrabFocus(sal_uInt16 nFlags)3987 void Window::ImplGrabFocus( sal_uInt16 nFlags )
3988 {
3989 // #143570# no focus for destructing windows
3990 if( mpWindowImpl->mbInDtor )
3991 return;
3992
3993 // some event listeners do really bad stuff
3994 // => prepare for the worst
3995 ImplDelData aDogTag( this );
3996
3997 // Currently the client window should always get the focus
3998 // Should the border window at some point be focusable
3999 // we need to change all GrabFocus() instances in VCL,
4000 // e.g. in ToTop()
4001
4002 if ( mpWindowImpl->mpClientWindow )
4003 {
4004 // For a lack of design we need a little hack here to
4005 // ensure that dialogs on close pass the focus back to
4006 // the correct window
4007 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
4008 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
4009 mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
4010 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
4011 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
4012 )
4013 mpWindowImpl->mpLastFocusWindow->GrabFocus();
4014 else
4015 mpWindowImpl->mpClientWindow->GrabFocus();
4016 return;
4017 }
4018 else if ( mpWindowImpl->mbFrame )
4019 {
4020 // For a lack of design we need a little hack here to
4021 // ensure that dialogs on close pass the focus back to
4022 // the correct window
4023 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
4024 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
4025 mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
4026 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
4027 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
4028 )
4029 {
4030 mpWindowImpl->mpLastFocusWindow->GrabFocus();
4031 return;
4032 }
4033 }
4034
4035 // If the Window is disabled, then we don't change the focus
4036 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
4037 return;
4038
4039 // we only need to set the focus if it is not already set
4040 // note: if some other frame is waiting for an asynchronous focus event
4041 // we also have to post an asynchronous focus event for this frame
4042 // which is done using ToTop
4043 ImplSVData* pSVData = ImplGetSVData();
4044
4045 sal_Bool bAsyncFocusWaiting = sal_False;
4046 Window *pFrame = pSVData->maWinData.mpFirstFrame;
4047 while( pFrame )
4048 {
4049 if( pFrame != mpWindowImpl->mpFrameWindow && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
4050 {
4051 bAsyncFocusWaiting = sal_True;
4052 break;
4053 }
4054 pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
4055 }
4056
4057 bool bHasFocus = IsWindowFocused(*mpWindowImpl);
4058
4059 sal_Bool bMustNotGrabFocus = sal_False;
4060 // #100242#, check parent hierarchy if some floater prohibits grab focus
4061
4062 Window *pParent = this;
4063 while( pParent )
4064 {
4065 // #102158#, ignore grabfocus only if the floating parent grabs keyboard focus by itself (GrabsFocus())
4066 // otherwise we cannot set the focus in a floating toolbox
4067 if( ( (pParent->mpWindowImpl->mbFloatWin && ((FloatingWindow*)pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) )
4068 {
4069 bMustNotGrabFocus = sal_True;
4070 break;
4071 }
4072 pParent = pParent->mpWindowImpl->mpParent;
4073 }
4074
4075
4076 if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
4077 {
4078 // EndExtTextInput if it is not the same window
4079 if ( pSVData->maWinData.mpExtTextInputWin &&
4080 (pSVData->maWinData.mpExtTextInputWin != this) )
4081 pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
4082
4083 // Dieses Fenster als letztes FocusWindow merken
4084 Window* pOverlapWindow = ImplGetFirstOverlapWindow();
4085 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
4086 mpWindowImpl->mpFrameData->mpFocusWin = this;
4087
4088 if( !bHasFocus )
4089 {
4090 // menu windows never get the system focus
4091 // the application will keep the focus
4092 if( bMustNotGrabFocus )
4093 return;
4094 else
4095 {
4096 // Hier setzen wir schon den Focus um, da ToTop() den Focus
4097 // nicht auf ein anderes Fenster setzen darf
4098 //DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
4099 mpWindowImpl->mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS | SAL_FRAME_TOTOP_GRABFOCUS_ONLY );
4100 return;
4101 }
4102 }
4103
4104 Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin;
4105 ImplDelData aOldFocusDel( pOldFocusWindow );
4106
4107 pSVData->maWinData.mpFocusWin = this;
4108
4109 if ( pOldFocusWindow )
4110 {
4111 // hide Cursor
4112 if ( pOldFocusWindow->mpWindowImpl->mpCursor )
4113 pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide( true );
4114 }
4115
4116 // !!!!! Wegen altem SV-Office Activate/Deavtivate Handling
4117 // !!!!! erstmal so wie frueher
4118 if ( pOldFocusWindow )
4119 {
4120 // Focus merken
4121 Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
4122 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
4123 if ( pOldOverlapWindow != pNewOverlapWindow )
4124 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
4125 }
4126 else
4127 {
4128 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
4129 Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
4130 pNewOverlapWindow->mpWindowImpl->mbActive = sal_True;
4131 pNewOverlapWindow->Activate();
4132 if ( pNewRealWindow != pNewOverlapWindow )
4133 {
4134 pNewRealWindow->mpWindowImpl->mbActive = sal_True;
4135 pNewRealWindow->Activate();
4136 }
4137 }
4138 /*
4139 // call Deactivate and Activate
4140 Window* pDeactivateParent;
4141 Window* pActivateParent;
4142 Window* pParent;
4143 Window* pLastParent;
4144 pDeactivateParent = pOldFocusWindow;
4145 while ( pDeactivateParent )
4146 {
4147 pParent = pDeactivateParent;
4148 if ( pParent->ImplIsChild( this ) )
4149 break;
4150
4151 if ( pDeactivateParent->ImplIsOverlapWindow() )
4152 {
4153 if ( !pDeactivateParent->mpWindowImpl->mbParentActive )
4154 break;
4155 }
4156
4157 pDeactivateParent = pDeactivateParent->ImplGetParent();
4158 }
4159 if ( pOldFocusWindow )
4160 {
4161 pActivateParent = this;
4162 while ( pActivateParent )
4163 {
4164 pParent = pActivateParent;
4165 if ( pParent->ImplIsChild( pOldFocusWindow ) )
4166 break;
4167
4168 if ( pActivateParent->ImplIsOverlapWindow() )
4169 {
4170 if ( !pActivateParent->mpWindowImpl->mbParentActive )
4171 break;
4172 }
4173
4174 pActivateParent = pActivateParent->ImplGetParent();
4175 }
4176 }
4177 else
4178 {
4179 if ( ImplIsOverlapWindow() )
4180 pActivateParent = this;
4181 else
4182 pActivateParent = mpWindowImpl->mpOverlapWindow;
4183 while ( pActivateParent )
4184 {
4185 if ( pActivateParent->ImplIsOverlapWindow() )
4186 {
4187 if ( !pActivateParent->mpWindowImpl->mbParentActive )
4188 break;
4189 }
4190
4191 pActivateParent = pActivateParent->ImplGetParent();
4192 }
4193 }
4194 if ( pDeactivateParent )
4195 {
4196 do
4197 {
4198 pLastParent = pOldFocusWindow;
4199 if ( pLastParent != pDeactivateParent )
4200 {
4201 pParent = pLastParent->ImplGetParent();
4202 while ( pParent )
4203 {
4204 if ( pParent == pDeactivateParent )
4205 break;
4206 pLastParent = pParent;
4207 pParent = pParent->ImplGetParent();
4208 }
4209 }
4210 else
4211 pParent = pLastParent;
4212
4213 pParent->mpWindowImpl->mbActive = sal_False;
4214 pParent->Deactivate();
4215 pDeactivateParent = pLastParent;
4216 }
4217 while ( pDeactivateParent != pOldFocusWindow );
4218 }
4219 do
4220 {
4221 pLastParent = this;
4222 if ( pLastParent != pActivateParent )
4223 {
4224 pParent = pLastParent->ImplGetParent();
4225 while ( pParent )
4226 {
4227 if ( pParent == pActivateParent )
4228 break;
4229 pLastParent = pParent;
4230 pParent = pParent->ImplGetParent();
4231 }
4232 }
4233 else
4234 pParent = pLastParent;
4235
4236 pParent->mpWindowImpl->mbActive = sal_True;
4237 pParent->Activate();
4238 pActivateParent = pLastParent;
4239 }
4240 while ( pActivateParent != this );
4241 */
4242 // call Get- and LoseFocus
4243 if ( pOldFocusWindow && ! aOldFocusDel.IsDelete() )
4244 {
4245 if ( pOldFocusWindow->IsTracking() &&
4246 (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) )
4247 pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS );
4248 NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow );
4249 if ( !ImplCallPreNotify( aNEvt ) )
4250 pOldFocusWindow->LoseFocus();
4251 pOldFocusWindow->ImplCallDeactivateListeners( this );
4252 }
4253
4254 if ( pSVData->maWinData.mpFocusWin == this )
4255 {
4256 if ( mpWindowImpl->mpSysObj )
4257 {
4258 mpWindowImpl->mpFrameData->mpFocusWin = this;
4259 if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
4260 mpWindowImpl->mpSysObj->GrabFocus();
4261 }
4262
4263 if ( pSVData->maWinData.mpFocusWin == this )
4264 {
4265 if ( mpWindowImpl->mpCursor )
4266 mpWindowImpl->mpCursor->ImplShow();
4267 mpWindowImpl->mbInFocusHdl = sal_True;
4268 mpWindowImpl->mnGetFocusFlags = nFlags;
4269 // if we're changing focus due to closing a popup floating window
4270 // notify the new focus window so it can restore the inner focus
4271 // e.g. toolboxes can select their recent active item
4272 if( pOldFocusWindow &&
4273 ! aOldFocusDel.IsDelete() &&
4274 ( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) )
4275 mpWindowImpl->mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL;
4276 NotifyEvent aNEvt( EVENT_GETFOCUS, this );
4277 if ( !ImplCallPreNotify( aNEvt ) && !aDogTag.IsDelete() )
4278 GetFocus();
4279 if( !aDogTag.IsDelete() )
4280 ImplCallActivateListeners( (pOldFocusWindow && ! aOldFocusDel.IsDelete()) ? pOldFocusWindow : NULL );
4281 if( !aDogTag.IsDelete() )
4282 {
4283 mpWindowImpl->mnGetFocusFlags = 0;
4284 mpWindowImpl->mbInFocusHdl = sal_False;
4285 }
4286 }
4287 }
4288
4289 GetpApp()->FocusChanged();
4290 ImplNewInputContext();
4291 }
4292 }
4293
4294 // -----------------------------------------------------------------------
4295
ImplNewInputContext()4296 void Window::ImplNewInputContext()
4297 {
4298 ImplSVData* pSVData = ImplGetSVData();
4299 Window* pFocusWin = pSVData->maWinData.mpFocusWin;
4300 if ( !pFocusWin )
4301 return;
4302
4303 // Is InputContext changed?
4304 const InputContext& rInputContext = pFocusWin->GetInputContext();
4305 if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
4306 return;
4307
4308 pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;
4309
4310 SalInputContext aNewContext;
4311 const Font& rFont = rInputContext.GetFont();
4312 const XubString& rFontName = rFont.GetName();
4313 ImplFontEntry* pFontEntry = NULL;
4314 aNewContext.mpFont = NULL;
4315 if ( rFontName.Len() )
4316 {
4317 Size aSize = pFocusWin->ImplLogicToDevicePixel( rFont.GetSize() );
4318 if ( !aSize.Height() )
4319 {
4320 // Nur dann Defaultgroesse setzen, wenn Fonthoehe auch in logischen
4321 // Koordinaten 0 ist
4322 if ( rFont.GetSize().Height() )
4323 aSize.Height() = 1;
4324 else
4325 aSize.Height() = (12*pFocusWin->mnDPIY)/72;
4326 }
4327 // TODO: No display device uses ImplDirectFontSubstitution thingy, right? => remove it
4328 ImplDirectFontSubstitution* pFontSubst = NULL;
4329 //if( pFocusWin->mpOutDevData )
4330 // pFontSubst = &pFocusWin->mpOutDevData->maDevFontSubst;
4331 pFontEntry = pFocusWin->mpFontCache->GetFontEntry( pFocusWin->mpFontList,
4332 rFont, aSize, static_cast<float>(aSize.Height()), pFontSubst );
4333 if ( pFontEntry )
4334 aNewContext.mpFont = &pFontEntry->maFontSelData;
4335 }
4336 aNewContext.meLanguage = rFont.GetLanguage();
4337 aNewContext.mnOptions = rInputContext.GetOptions();
4338 pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
4339
4340 if ( pFontEntry )
4341 pFocusWin->mpFontCache->Release( pFontEntry );
4342 }
4343
4344 // -----------------------------------------------------------------------
4345
Window(WindowType nType)4346 Window::Window( WindowType nType )
4347 {
4348 DBG_CTOR( Window, ImplDbgCheckWindow );
4349
4350 ImplInitWindowData( nType );
4351 }
4352
4353 // -----------------------------------------------------------------------
4354
Window(Window * pParent,WinBits nStyle)4355 Window::Window( Window* pParent, WinBits nStyle )
4356 {
4357 DBG_CTOR( Window, ImplDbgCheckWindow );
4358
4359 ImplInitWindowData( WINDOW_WINDOW );
4360 ImplInit( pParent, nStyle, NULL );
4361 }
4362
4363 // -----------------------------------------------------------------------
4364
Window(Window * pParent,const ResId & rResId)4365 Window::Window( Window* pParent, const ResId& rResId )
4366 {
4367 DBG_CTOR( Window, ImplDbgCheckWindow );
4368
4369 ImplInitWindowData( WINDOW_WINDOW );
4370 rResId.SetRT( RSC_WINDOW );
4371 WinBits nStyle = ImplInitRes( rResId );
4372 ImplInit( pParent, nStyle, NULL );
4373 ImplLoadRes( rResId );
4374
4375 if ( !(nStyle & WB_HIDE) )
4376 Show();
4377 }
4378
4379 // -----------------------------------------------------------------------
4380 #if OSL_DEBUG_LEVEL > 0
4381 namespace
4382 {
lcl_appendWindowInfo(ByteString & io_rErrorString,const Window & i_rWindow)4383 void lcl_appendWindowInfo( ByteString& io_rErrorString, const Window& i_rWindow )
4384 {
4385 // skip border windows, they don't carry information which helps diagnosing the problem
4386 const Window* pWindow( &i_rWindow );
4387 while ( pWindow && ( pWindow->GetType() == WINDOW_BORDERWINDOW ) )
4388 pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD );
4389 if ( !pWindow )
4390 pWindow = &i_rWindow;
4391
4392 io_rErrorString += char(13);
4393 io_rErrorString += typeid( *pWindow ).name();
4394 io_rErrorString += " (window text: '";
4395 io_rErrorString += ByteString( pWindow->GetText(), RTL_TEXTENCODING_UTF8 );
4396 io_rErrorString += "')";
4397 }
4398 }
4399 #endif
4400 // -----------------------------------------------------------------------
4401
~Window()4402 Window::~Window()
4403 {
4404 ImplFreeExtWindowImpl();
4405
4406 vcl::LazyDeletor<Window>::Undelete( this );
4407
4408 DBG_DTOR( Window, ImplDbgCheckWindow );
4409 DBG_ASSERT( !mpWindowImpl->mbInDtor, "~Window - already in DTOR!" );
4410
4411
4412 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
4413 Application::RemoveMouseAndKeyEvents( this );
4414
4415 // Dispose of the canvas implementation (which, currently, has an
4416 // own wrapper window as a child to this one)
4417 uno::Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
4418 if( xCanvas.is() )
4419 {
4420 uno::Reference < lang::XComponent > xCanvasComponent( xCanvas,
4421 uno::UNO_QUERY );
4422 if( xCanvasComponent.is() )
4423 xCanvasComponent->dispose();
4424 }
4425
4426 mpWindowImpl->mbInDtor = sal_True;
4427
4428 ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
4429
4430 // do not send child events for frames that were registered as native frames
4431 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible )
4432 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
4433 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED, this );
4434
4435 // remove associated data structures from dockingmanager
4436 ImplGetDockingManager()->RemoveWindow( this );
4437
4438
4439 // remove ownerdraw decorated windows from list in the top-most frame window
4440 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
4441 {
4442 ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
4443 ::std::vector< Window* >::iterator p;
4444 p = ::std::find( rList.begin(), rList.end(), this );
4445 if( p != rList.end() )
4446 rList.erase( p );
4447 }
4448
4449 // shutdown drag and drop
4450 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY );
4451
4452 if( xDnDComponent.is() )
4453 xDnDComponent->dispose();
4454
4455 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
4456 {
4457 try
4458 {
4459 // deregister drop target listener
4460 if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
4461 {
4462 uno::Reference< XDragGestureRecognizer > xDragGestureRecognizer =
4463 uno::Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
4464 if( xDragGestureRecognizer.is() )
4465 {
4466 xDragGestureRecognizer->removeDragGestureListener(
4467 uno::Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
4468 }
4469
4470 mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
4471 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
4472 }
4473
4474 // shutdown drag and drop for this frame window
4475 uno::Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );
4476
4477 // DNDEventDispatcher does not hold a reference of the DropTarget,
4478 // so it's ok if it does not support XComponent
4479 if( xComponent.is() )
4480 xComponent->dispose();
4481 }
4482
4483 catch ( Exception&)
4484 {
4485 // can be safely ignored here.
4486 }
4487 }
4488
4489 UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False );
4490 if ( pWrapper )
4491 pWrapper->WindowDestroyed( this );
4492
4493 // MT: Must be called after WindowDestroyed!
4494 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
4495 // But accessibility implementations from applications need this dispose.
4496 if ( mpWindowImpl->mxAccessible.is() )
4497 {
4498 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xC( mpWindowImpl->mxAccessible, ::com::sun::star::uno::UNO_QUERY );
4499 if ( xC.is() )
4500 xC->dispose();
4501 }
4502
4503 ImplSVData* pSVData = ImplGetSVData();
4504
4505 if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) )
4506 ImplDestroyHelpWindow( true );
4507
4508 DBG_ASSERT( pSVData->maWinData.mpTrackWin != this,
4509 "Window::~Window(): Window is in TrackingMode" );
4510 DBG_ASSERT( pSVData->maWinData.mpCaptureWin != this,
4511 "Window::~Window(): Window has the mouse captured" );
4512 // #103442# DefModalDialogParent is now determined on-the-fly, so this pointer is unimportant now
4513 //DBG_ASSERT( pSVData->maWinData.mpDefDialogParent != this,
4514 // "Window::~Window(): Window is DefModalDialogParent" );
4515
4516 // Wegen alter kompatibilitaet
4517 if ( pSVData->maWinData.mpTrackWin == this )
4518 EndTracking();
4519 if ( pSVData->maWinData.mpCaptureWin == this )
4520 ReleaseMouse();
4521 if ( pSVData->maWinData.mpDefDialogParent == this )
4522 pSVData->maWinData.mpDefDialogParent = NULL;
4523
4524 #ifdef DBG_UTIL
4525 if ( sal_True ) // always perform these tests in non-pro versions
4526 {
4527 ByteString aErrorStr;
4528 sal_Bool bError = sal_False;
4529 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
4530 while ( pTempWin )
4531 {
4532 if ( ImplIsRealParentPath( pTempWin ) )
4533 {
4534 bError = sal_True;
4535 lcl_appendWindowInfo( aErrorStr, *pTempWin );
4536 }
4537 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
4538 }
4539 if ( bError )
4540 {
4541 ByteString aTempStr( "Window (" );
4542 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4543 aTempStr += ") with living SystemWindow(s) destroyed: ";
4544 aTempStr += aErrorStr;
4545 DBG_ERROR( aTempStr.GetBuffer() );
4546 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4547 }
4548
4549 bError = sal_False;
4550 pTempWin = pSVData->maWinData.mpFirstFrame;
4551 while ( pTempWin )
4552 {
4553 if ( ImplIsRealParentPath( pTempWin ) )
4554 {
4555 bError = sal_True;
4556 lcl_appendWindowInfo( aErrorStr, *pTempWin );
4557 }
4558 pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame;
4559 }
4560 if ( bError )
4561 {
4562 ByteString aTempStr( "Window (" );
4563 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4564 aTempStr += ") with living SystemWindow(s) destroyed: ";
4565 aTempStr += aErrorStr;
4566 DBG_ERROR( aTempStr.GetBuffer() );
4567 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4568 }
4569
4570 if ( mpWindowImpl->mpFirstChild )
4571 {
4572 ByteString aTempStr( "Window (" );
4573 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4574 aTempStr += ") with living Child(s) destroyed: ";
4575 pTempWin = mpWindowImpl->mpFirstChild;
4576 while ( pTempWin )
4577 {
4578 lcl_appendWindowInfo( aTempStr, *pTempWin );
4579 pTempWin = pTempWin->mpWindowImpl->mpNext;
4580 }
4581 DBG_ERROR( aTempStr.GetBuffer() );
4582 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4583 }
4584
4585 if ( mpWindowImpl->mpFirstOverlap )
4586 {
4587 ByteString aTempStr( "Window (" );
4588 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4589 aTempStr += ") with living SystemWindow(s) destroyed: ";
4590 pTempWin = mpWindowImpl->mpFirstOverlap;
4591 while ( pTempWin )
4592 {
4593 lcl_appendWindowInfo( aTempStr, *pTempWin );
4594 pTempWin = pTempWin->mpWindowImpl->mpNext;
4595 }
4596 DBG_ERROR( aTempStr.GetBuffer() );
4597 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4598 }
4599
4600 Window* pMyParent = this;
4601 SystemWindow* pMySysWin = NULL;
4602
4603 while ( pMyParent )
4604 {
4605 if ( pMyParent->IsSystemWindow() )
4606 pMySysWin = (SystemWindow*)pMyParent;
4607 pMyParent = pMyParent->GetParent();
4608 }
4609 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
4610 {
4611 ByteString aTempStr( "Window (" );
4612 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4613 aTempStr += ") still in TaskPanelList!";
4614 DBG_ERROR( aTempStr.GetBuffer() );
4615 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4616 }
4617 }
4618 #endif
4619
4620 if( mpWindowImpl->mbIsInTaskPaneList )
4621 {
4622 Window* pMyParent = this;
4623 SystemWindow* pMySysWin = NULL;
4624
4625 while ( pMyParent )
4626 {
4627 if ( pMyParent->IsSystemWindow() )
4628 pMySysWin = (SystemWindow*)pMyParent;
4629 pMyParent = pMyParent->GetParent();
4630 }
4631 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
4632 {
4633 pMySysWin->GetTaskPaneList()->RemoveWindow( this );
4634 }
4635 else
4636 {
4637 ByteString aTempStr( "Window (" );
4638 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4639 aTempStr += ") not found in TaskPanelList!";
4640 DBG_ERROR( aTempStr.GetBuffer() );
4641 }
4642 }
4643
4644 // Fenster hiden, um das entsprechende Paint-Handling auszuloesen
4645 Hide();
4646
4647 // Mitteilen, das Fenster zerstoert wird
4648 {
4649 NotifyEvent aNEvt( EVENT_DESTROY, this );
4650 Notify( aNEvt );
4651 }
4652
4653 // EndExtTextInputMode
4654 if ( pSVData->maWinData.mpExtTextInputWin == this )
4655 {
4656 EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
4657 if ( pSVData->maWinData.mpExtTextInputWin == this )
4658 pSVData->maWinData.mpExtTextInputWin = NULL;
4659 }
4660
4661 // check if the focus window is our child
4662 sal_Bool bHasFocussedChild = sal_False;
4663 if( pSVData->maWinData.mpFocusWin && ImplIsRealParentPath( pSVData->maWinData.mpFocusWin ) )
4664 {
4665 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
4666 bHasFocussedChild = sal_True;
4667 #ifdef DBG_UTIL
4668 ByteString aTempStr( "Window (" );
4669 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4670 aTempStr += ") with focussed child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
4671 DBG_ERROR( aTempStr.GetBuffer() );
4672 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4673 #endif
4674 }
4675
4676 // Wenn wir den Focus haben, dann den Focus auf ein anderes Fenster setzen
4677 Window* pOverlapWindow = ImplGetFirstOverlapWindow();
4678 if ( pSVData->maWinData.mpFocusWin == this
4679 || bHasFocussedChild ) // #122232#, see above, try some cleanup
4680 {
4681 if ( mpWindowImpl->mbFrame )
4682 {
4683 pSVData->maWinData.mpFocusWin = NULL;
4684 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4685 GetpApp()->FocusChanged();
4686 }
4687 else
4688 {
4689 Window* pParent = GetParent();
4690 Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
4691 // Bei ueberlappenden Fenstern wird der Focus auf den
4692 // Parent vom naechsten FrameWindow gesetzt
4693 if ( pBorderWindow )
4694 {
4695 if ( pBorderWindow->ImplIsOverlapWindow() )
4696 pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
4697 }
4698 else if ( ImplIsOverlapWindow() )
4699 pParent = mpWindowImpl->mpOverlapWindow;
4700
4701 if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
4702 pParent->GrabFocus();
4703 else
4704 mpWindowImpl->mpFrameWindow->GrabFocus();
4705
4706 // If the focus was set back to 'this' set it to nothing
4707 if ( pSVData->maWinData.mpFocusWin == this )
4708 {
4709 pSVData->maWinData.mpFocusWin = NULL;
4710 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4711 GetpApp()->FocusChanged();
4712 }
4713 }
4714 }
4715
4716
4717 if ( pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
4718 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4719
4720 // reset hint for DefModalDialogParent
4721 if( pSVData->maWinData.mpActiveApplicationFrame == this )
4722 pSVData->maWinData.mpActiveApplicationFrame = NULL;
4723
4724 // gemerkte Fenster zuruecksetzen
4725 if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
4726 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
4727 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
4728 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
4729 if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
4730 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
4731
4732 // Deactivate-Window zuruecksetzen
4733 if ( pSVData->maWinData.mpLastDeacWin == this )
4734 pSVData->maWinData.mpLastDeacWin = NULL;
4735
4736 if ( mpWindowImpl->mbFrame )
4737 {
4738 if ( mpWindowImpl->mpFrameData->mnFocusId )
4739 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
4740 if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
4741 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
4742 }
4743
4744 // release SalGraphics
4745 ImplReleaseGraphics();
4746
4747 // notify ImplDelData subscribers of this window about the window deletion
4748 ImplDelData* pDelData = mpWindowImpl->mpFirstDel;
4749 while ( pDelData )
4750 {
4751 pDelData->mbDel = sal_True;
4752 pDelData->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
4753 pDelData = pDelData->mpNext;
4754 }
4755
4756 // remove window from the lists
4757 ImplRemoveWindow( sal_True );
4758
4759 // de-register as "top window child" at our parent, if necessary
4760 if ( mpWindowImpl->mbFrame )
4761 {
4762 sal_Bool bIsTopWindow = mpWindowImpl->mpWinData && ( mpWindowImpl->mpWinData->mnIsTopWindow == 1 );
4763 if ( mpWindowImpl->mpRealParent && bIsTopWindow )
4764 {
4765 ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();
4766
4767 ::std::list< Window* >::iterator myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
4768 pParentWinData->maTopWindowChildren.end(), this );
4769 DBG_ASSERT( myPos != pParentWinData->maTopWindowChildren.end(), "Window::~Window: inconsistency in top window chain!" );
4770 if ( myPos != pParentWinData->maTopWindowChildren.end() )
4771 pParentWinData->maTopWindowChildren.erase( myPos );
4772 }
4773 }
4774
4775 // cleanup Extra Window Data, TODO: add and use ImplWinData destructor
4776 if ( mpWindowImpl->mpWinData )
4777 {
4778 if ( mpWindowImpl->mpWinData->mpExtOldText )
4779 delete mpWindowImpl->mpWinData->mpExtOldText;
4780 if ( mpWindowImpl->mpWinData->mpExtOldAttrAry )
4781 delete mpWindowImpl->mpWinData->mpExtOldAttrAry;
4782 if ( mpWindowImpl->mpWinData->mpCursorRect )
4783 delete mpWindowImpl->mpWinData->mpCursorRect;
4784 if ( mpWindowImpl->mpWinData->mpFocusRect )
4785 delete mpWindowImpl->mpWinData->mpFocusRect;
4786 if ( mpWindowImpl->mpWinData->mpTrackRect )
4787 delete mpWindowImpl->mpWinData->mpTrackRect;
4788
4789 delete mpWindowImpl->mpWinData;
4790 }
4791
4792 // cleanup overlap related window data
4793 if ( mpWindowImpl->mpOverlapData )
4794 delete mpWindowImpl->mpOverlapData;
4795
4796 // remove BorderWindow or Frame window data
4797 if ( mpWindowImpl->mpBorderWindow )
4798 delete mpWindowImpl->mpBorderWindow;
4799 else if ( mpWindowImpl->mbFrame )
4800 {
4801 if ( pSVData->maWinData.mpFirstFrame == this )
4802 pSVData->maWinData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
4803 else
4804 {
4805 Window* pSysWin = pSVData->maWinData.mpFirstFrame;
4806 while ( pSysWin->mpWindowImpl->mpFrameData->mpNextFrame != this )
4807 pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
4808 pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
4809 }
4810 mpWindowImpl->mpFrame->SetCallback( NULL, NULL );
4811 pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
4812 delete mpWindowImpl->mpFrameData;
4813 }
4814
4815 // should be the last statements
4816 delete mpWindowImpl; mpWindowImpl = NULL;
4817 }
4818
4819 // -----------------------------------------------------------------------
doLazyDelete()4820 void Window::doLazyDelete()
4821 {
4822 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
4823 DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
4824 if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
4825 {
4826 Show( sal_False );
4827 SetParent( ImplGetDefaultWindow() );
4828 }
4829 vcl::LazyDeletor<Window>::Delete( this );
4830 }
4831
4832 // -----------------------------------------------------------------------
InterceptChildWindowKeyDown(sal_Bool bIntercept)4833 void Window::InterceptChildWindowKeyDown( sal_Bool bIntercept )
4834 {
4835 if( mpWindowImpl->mpSysObj )
4836 mpWindowImpl->mpSysObj->InterceptChildWindowKeyDown( bIntercept );
4837 }
4838
4839 // -----------------------------------------------------------------------
4840
MouseMove(const MouseEvent & rMEvt)4841 void Window::MouseMove( const MouseEvent& rMEvt )
4842 {
4843 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4844 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4845 }
4846
4847 NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt );
4848 if ( !Notify( aNEvt ) )
4849 mpWindowImpl->mbMouseMove = sal_True;
4850 }
4851
4852 // -----------------------------------------------------------------------
4853
MouseButtonDown(const MouseEvent & rMEvt)4854 void Window::MouseButtonDown( const MouseEvent& rMEvt )
4855 {
4856 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4857 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4858 }
4859
4860 NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt );
4861 if ( !Notify( aNEvt ) )
4862 mpWindowImpl->mbMouseButtonDown = sal_True;
4863 }
4864
4865 // -----------------------------------------------------------------------
4866
MouseButtonUp(const MouseEvent & rMEvt)4867 void Window::MouseButtonUp( const MouseEvent& rMEvt )
4868 {
4869 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4870 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4871 }
4872
4873 NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt );
4874 if ( !Notify( aNEvt ) )
4875 mpWindowImpl->mbMouseButtonUp = sal_True;
4876 }
4877
4878 // -----------------------------------------------------------------------
4879
KeyInput(const KeyEvent & rKEvt)4880 void Window::KeyInput( const KeyEvent& rKEvt )
4881 {
4882 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4883 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4884 }
4885
4886 NotifyEvent aNEvt( EVENT_KEYINPUT, this, &rKEvt );
4887 if ( !Notify( aNEvt ) )
4888 mpWindowImpl->mbKeyInput = sal_True;
4889 }
4890
4891 // -----------------------------------------------------------------------
4892
KeyUp(const KeyEvent & rKEvt)4893 void Window::KeyUp( const KeyEvent& rKEvt )
4894 {
4895 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4896 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4897 }
4898
4899 NotifyEvent aNEvt( EVENT_KEYUP, this, &rKEvt );
4900 if ( !Notify( aNEvt ) )
4901 mpWindowImpl->mbKeyUp = sal_True;
4902 }
4903
4904 // -----------------------------------------------------------------------
4905
PrePaint()4906 void Window::PrePaint()
4907 {
4908 }
4909
4910 // -----------------------------------------------------------------------
4911
Paint(const Rectangle & rRect)4912 void Window::Paint( const Rectangle& rRect )
4913 {
4914 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4915 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4916 }
4917
4918 ImplCallEventListeners( VCLEVENT_WINDOW_PAINT, (void*)&rRect );
4919 }
4920
4921 // -----------------------------------------------------------------------
4922
PostPaint()4923 void Window::PostPaint()
4924 {
4925 }
4926
4927 // -----------------------------------------------------------------------
4928
Draw(OutputDevice *,const Point &,const Size &,sal_uLong)4929 void Window::Draw( OutputDevice*, const Point&, const Size&, sal_uLong )
4930 {
4931 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4932 }
4933
4934 // -----------------------------------------------------------------------
4935
Move()4936 void Window::Move()
4937 {
4938 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4939 }
4940
4941 // -----------------------------------------------------------------------
4942
Resize()4943 void Window::Resize()
4944 {
4945 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4946 }
4947
4948 // -----------------------------------------------------------------------
4949
Activate()4950 void Window::Activate()
4951 {
4952 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4953 }
4954
4955 // -----------------------------------------------------------------------
4956
Deactivate()4957 void Window::Deactivate()
4958 {
4959 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4960 }
4961
4962 // -----------------------------------------------------------------------
4963
GetFocus()4964 void Window::GetFocus()
4965 {
4966 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4967 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4968 }
4969
4970 if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
4971 {
4972 ImplDelData aDogtag( this );
4973 mpWindowImpl->mpLastFocusWindow->GrabFocus();
4974 if( aDogtag.IsDelete() )
4975 return;
4976 }
4977
4978 NotifyEvent aNEvt( EVENT_GETFOCUS, this );
4979 Notify( aNEvt );
4980 }
4981
4982 // -----------------------------------------------------------------------
4983
LoseFocus()4984 void Window::LoseFocus()
4985 {
4986 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4987 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4988 }
4989
4990 NotifyEvent aNEvt( EVENT_LOSEFOCUS, this );
4991 Notify( aNEvt );
4992 }
4993
4994 // -----------------------------------------------------------------------
4995
RequestHelp(const HelpEvent & rHEvt)4996 void Window::RequestHelp( const HelpEvent& rHEvt )
4997 {
4998 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4999 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5000 }
5001
5002 // Wenn Balloon-Help angefordert wird, dann den Balloon mit dem
5003 // gesetzten Hilfetext anzeigen
5004 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
5005 {
5006 const XubString* pStr = &(GetHelpText());
5007 if ( !pStr->Len() )
5008 pStr = &(GetQuickHelpText());
5009 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
5010 ImplGetParent()->RequestHelp( rHEvt );
5011 else
5012 Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), *pStr );
5013 }
5014 else if ( rHEvt.GetMode() & HELPMODE_QUICK )
5015 {
5016 const XubString* pStr = &(GetQuickHelpText());
5017 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
5018 ImplGetParent()->RequestHelp( rHEvt );
5019 else
5020 {
5021 Point aPos = GetPosPixel();
5022 if ( ImplGetParent() && !ImplIsOverlapWindow() )
5023 aPos = ImplGetParent()->OutputToScreenPixel( aPos );
5024 Rectangle aRect( aPos, GetSizePixel() );
5025 String aHelpText;
5026 if ( pStr->Len() )
5027 aHelpText = GetHelpText();
5028 Help::ShowQuickHelp( this, aRect, *pStr, aHelpText, QUICKHELP_CTRLTEXT );
5029 }
5030 }
5031 else
5032 {
5033 String aStrHelpId( rtl::OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
5034 if ( aStrHelpId.Len() == 0 && ImplGetParent() )
5035 ImplGetParent()->RequestHelp( rHEvt );
5036 else
5037 {
5038 Help* pHelp = Application::GetHelp();
5039 if ( pHelp )
5040 {
5041 if( aStrHelpId.Len() > 0 )
5042 pHelp->Start( aStrHelpId, this );
5043 else
5044 pHelp->Start( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OOO_HELP_INDEX ) ), this );
5045 }
5046 }
5047 }
5048 }
5049
5050 // -----------------------------------------------------------------------
5051
Command(const CommandEvent & rCEvt)5052 void Window::Command( const CommandEvent& rCEvt )
5053 {
5054 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
5055 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5056 }
5057
5058 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, (void*)&rCEvt );
5059
5060 NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt );
5061 if ( !Notify( aNEvt ) )
5062 mpWindowImpl->mbCommand = sal_True;
5063 }
5064
5065 // -----------------------------------------------------------------------
5066
Tracking(const TrackingEvent & rTEvt)5067 void Window::Tracking( const TrackingEvent& rTEvt )
5068 {
5069 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5070
5071 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
5072 if( pWrapper )
5073 pWrapper->Tracking( rTEvt );
5074 }
5075
5076 // -----------------------------------------------------------------------
5077
UserEvent(sal_uLong,void *)5078 void Window::UserEvent( sal_uLong, void* )
5079 {
5080 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5081 }
5082
5083 // -----------------------------------------------------------------------
5084
StateChanged(StateChangedType)5085 void Window::StateChanged( StateChangedType )
5086 {
5087 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5088 }
5089
5090 // -----------------------------------------------------------------------
5091
DataChanged(const DataChangedEvent &)5092 void Window::DataChanged( const DataChangedEvent& )
5093 {
5094 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5095 }
5096
5097 // -----------------------------------------------------------------------
5098
ImplNotifyKeyMouseCommandEventListeners(NotifyEvent & rNEvt)5099 void Window::ImplNotifyKeyMouseCommandEventListeners( NotifyEvent& rNEvt )
5100 {
5101 if( rNEvt.GetType() == EVENT_COMMAND )
5102 {
5103 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
5104 if ( pCEvt->GetCommand() != COMMAND_CONTEXTMENU )
5105 // non context menu events are not to be notified up the chain
5106 // so we return immediately
5107 return;
5108
5109 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5110 {
5111 if ( rNEvt.GetWindow() == this )
5112 // not interested in: The event listeners are already called in ::Command,
5113 // and calling them here a second time doesn't make sense
5114 ;
5115 else
5116 {
5117 CommandEvent aCommandEvent = ImplTranslateCommandEvent( *pCEvt, rNEvt.GetWindow(), this );
5118 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, &aCommandEvent );
5119 }
5120 }
5121 }
5122
5123 // #82968# notify event listeners for mouse and key events separately and
5124 // not in PreNotify ( as for focus listeners )
5125 // this allows for processing those events internally first and pass it to
5126 // the toolkit later
5127
5128 ImplDelData aDelData;
5129 ImplAddDel( &aDelData );
5130
5131 if( rNEvt.GetType() == EVENT_MOUSEMOVE )
5132 {
5133 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5134 {
5135 if ( rNEvt.GetWindow() == this )
5136 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
5137 else
5138 {
5139 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5140 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &aMouseEvent );
5141 }
5142 }
5143 }
5144 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
5145 {
5146 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5147 {
5148 if ( rNEvt.GetWindow() == this )
5149 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
5150 else
5151 {
5152 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5153 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &aMouseEvent );
5154 }
5155 }
5156 }
5157 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5158 {
5159 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5160 {
5161 if ( rNEvt.GetWindow() == this )
5162 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
5163 else
5164 {
5165 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5166 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &aMouseEvent );
5167 }
5168 }
5169 }
5170 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5171 {
5172 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5173 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
5174 }
5175 else if( rNEvt.GetType() == EVENT_KEYUP )
5176 {
5177 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5178 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
5179 }
5180
5181 if ( aDelData.IsDelete() )
5182 return;
5183 ImplRemoveDel( &aDelData );
5184
5185 // #106721# check if we're part of a compound control and notify
5186 Window *pParent = ImplGetParent();
5187 while( pParent )
5188 {
5189 if( pParent->IsCompoundControl() )
5190 {
5191 pParent->ImplNotifyKeyMouseCommandEventListeners( rNEvt );
5192 break;
5193 }
5194 pParent = pParent->ImplGetParent();
5195 }
5196 }
5197
5198 // -----------------------------------------------------------------------
5199
PreNotify(NotifyEvent & rNEvt)5200 long Window::PreNotify( NotifyEvent& rNEvt )
5201 {
5202 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
5203 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5204 }
5205
5206 long bDone = sal_False;
5207 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
5208 bDone = mpWindowImpl->mpParent->PreNotify( rNEvt );
5209
5210 if ( !bDone )
5211 {
5212 if( rNEvt.GetType() == EVENT_GETFOCUS )
5213 {
5214 sal_Bool bCompoundFocusChanged = sal_False;
5215 if ( mpWindowImpl->mbCompoundControl && !mpWindowImpl->mbCompoundControlHasFocus && HasChildPathFocus() )
5216 {
5217 mpWindowImpl->mbCompoundControlHasFocus = sal_True;
5218 bCompoundFocusChanged = sal_True;
5219 }
5220
5221 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
5222 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
5223 }
5224 else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
5225 {
5226 sal_Bool bCompoundFocusChanged = sal_False;
5227 if ( mpWindowImpl->mbCompoundControl && mpWindowImpl->mbCompoundControlHasFocus && !HasChildPathFocus() )
5228 {
5229 mpWindowImpl->mbCompoundControlHasFocus = sal_False ;
5230 bCompoundFocusChanged = sal_True;
5231 }
5232
5233 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
5234 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
5235 }
5236
5237 // #82968# mouse and key events will be notified after processing ( in ImplNotifyKeyMouseCommandEventListeners() )!
5238 // see also ImplHandleMouseEvent(), ImplHandleKey()
5239
5240 /*
5241 else if( rNEvt.GetType() == EVENT_MOUSEMOVE )
5242 {
5243 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5244 {
5245 if ( rNEvt.GetWindow() == this )
5246 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
5247 else
5248 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
5249 }
5250 }
5251 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
5252 {
5253 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5254 {
5255 if ( rNEvt.GetWindow() == this )
5256 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
5257 else
5258 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
5259 }
5260 }
5261 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5262 {
5263 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5264 {
5265 if ( rNEvt.GetWindow() == this )
5266 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
5267 else
5268 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
5269 }
5270 }
5271 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5272 {
5273 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5274 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
5275 }
5276 else if( rNEvt.GetType() == EVENT_KEYUP )
5277 {
5278 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5279 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
5280 }
5281 */
5282 }
5283
5284 return bDone;
5285 }
5286
5287 // -----------------------------------------------------------------------
5288
Notify(NotifyEvent & rNEvt)5289 long Window::Notify( NotifyEvent& rNEvt )
5290 {
5291 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
5292 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5293 }
5294
5295 long nRet = sal_False;
5296
5297 // check for docking window
5298 // but do nothing if window is docked and locked
5299 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
5300 if( pWrapper && !( !pWrapper->IsFloatingMode() && pWrapper->IsLocked() ) )
5301 {
5302 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5303 {
5304 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
5305 sal_Bool bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
5306 if ( pMEvt->IsLeft() )
5307 {
5308 if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
5309 {
5310 // ctrl double click toggles floating mode
5311 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
5312 return sal_True;
5313 }
5314 else if ( pMEvt->GetClicks() == 1 && bHit)
5315 {
5316 // allow start docking during mouse move
5317 pWrapper->ImplEnableStartDocking();
5318 return sal_True;
5319 }
5320 }
5321 }
5322 else if ( rNEvt.GetType() == EVENT_MOUSEMOVE )
5323 {
5324 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
5325 sal_Bool bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
5326 if ( pMEvt->IsLeft() )
5327 {
5328 // check if a single click initiated this sequence ( ImplStartDockingEnabled() )
5329 // check if window is docked and
5330 if( pWrapper->ImplStartDockingEnabled() && !pWrapper->IsFloatingMode() &&
5331 !pWrapper->IsDocking() && bHit )
5332 {
5333 Point aPos = pMEvt->GetPosPixel();
5334 Window* pWindow = rNEvt.GetWindow();
5335 if ( pWindow != this )
5336 {
5337 aPos = pWindow->OutputToScreenPixel( aPos );
5338 aPos = ScreenToOutputPixel( aPos );
5339 }
5340 pWrapper->ImplStartDocking( aPos );
5341 }
5342 return sal_True;
5343 }
5344 }
5345 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5346 {
5347 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
5348 if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
5349 rKey.IsShift() && rKey.IsMod1() )
5350 {
5351 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
5352 /* At this point the floating toolbar frame does not have the
5353 * input focus since these frames don't get the focus per default
5354 * To enable keyboard handling of this toolbar set the input focus
5355 * to the frame. This needs to be done with ToTop since GrabFocus
5356 * would not notice any change since "this" already has the focus.
5357 */
5358 if( pWrapper->IsFloatingMode() )
5359 ToTop( TOTOP_GRABFOCUSONLY );
5360 return sal_True;
5361 }
5362 }
5363 }
5364
5365 // Dialog-Steuerung
5366 if ( (GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
5367 {
5368 // Wenn Parent auch DialogSteuerung aktiviert hat, uebernimmt dieser die Steuerung
5369 if ( (rNEvt.GetType() == EVENT_KEYINPUT) || (rNEvt.GetType() == EVENT_KEYUP) )
5370 {
5371 if ( ImplIsOverlapWindow() ||
5372 ((ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
5373 {
5374 nRet = ImplDlgCtrl( *rNEvt.GetKeyEvent(), rNEvt.GetType() == EVENT_KEYINPUT );
5375 }
5376 }
5377 else if ( (rNEvt.GetType() == EVENT_GETFOCUS) || (rNEvt.GetType() == EVENT_LOSEFOCUS) )
5378 {
5379 ImplDlgCtrlFocusChanged( rNEvt.GetWindow(), rNEvt.GetType() == EVENT_GETFOCUS );
5380 if ( (rNEvt.GetWindow() == this) && (rNEvt.GetType() == EVENT_GETFOCUS) &&
5381 !(GetStyle() & WB_TABSTOP) && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
5382 {
5383 sal_uInt16 n = 0;
5384 Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
5385 if ( pFirstChild )
5386 pFirstChild->ImplControlFocus();
5387 }
5388 }
5389 }
5390
5391 if ( !nRet )
5392 {
5393 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
5394 nRet = mpWindowImpl->mpParent->Notify( rNEvt );
5395 }
5396
5397 return nRet;
5398 }
5399
NotifyVCLEvent(sal_uLong nEvent,void * pData)5400 void Window::NotifyVCLEvent( sal_uLong nEvent ,void* pData /*= NULL*/)
5401 {
5402 ImplCallEventListeners( nEvent ,pData);
5403 }
GetAccFlowToSequence()5404 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > Window::GetAccFlowToSequence()
5405 {
5406 return ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >();
5407 }
5408 // -----------------------------------------------------------------------
5409
ImplCallEventListeners(sal_uLong nEvent,void * pData)5410 void Window::ImplCallEventListeners( sal_uLong nEvent, void* pData )
5411 {
5412 // The implementation was moved to CallEventListeners(),
5413 // because derived classes in svtools must be able to
5414 // call the event listeners and ImplCallEventListeners()
5415 // is not exported.
5416 // TODO: replace ImplCallEventListeners() by CallEventListeners() in vcl
5417
5418 CallEventListeners( nEvent, pData );
5419 }
5420
5421 // -----------------------------------------------------------------------
5422
CallEventListeners(sal_uLong nEvent,void * pData)5423 void Window::CallEventListeners( sal_uLong nEvent, void* pData )
5424 {
5425 VclWindowEvent aEvent( this, nEvent, pData );
5426
5427 ImplDelData aDelData;
5428 ImplAddDel( &aDelData );
5429
5430 ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent );
5431
5432 if ( aDelData.IsDelete() )
5433 return;
5434
5435 if ( !mpWindowImpl->maEventListeners.empty() )
5436 mpWindowImpl->maEventListeners.Call( &aEvent );
5437
5438 if ( aDelData.IsDelete() )
5439 return;
5440
5441 ImplRemoveDel( &aDelData );
5442
5443 Window* pWindow = this;
5444 while ( pWindow )
5445 {
5446 pWindow->ImplAddDel( &aDelData );
5447
5448 if ( !pWindow->mpWindowImpl->maChildEventListeners.empty() )
5449 pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent );
5450
5451 if ( aDelData.IsDelete() )
5452 return;
5453
5454 pWindow->ImplRemoveDel( &aDelData );
5455
5456 pWindow = pWindow->GetParent();
5457 }
5458 }
5459
FireVclEvent(VclSimpleEvent * pEvent)5460 void Window::FireVclEvent( VclSimpleEvent* pEvent )
5461 {
5462 ImplGetSVData()->mpApp->ImplCallEventListeners(pEvent);
5463 }
5464
5465 // -----------------------------------------------------------------------
5466
AddEventListener(const Link & rEventListener)5467 void Window::AddEventListener( const Link& rEventListener )
5468 {
5469 mpWindowImpl->maEventListeners.push_back( rEventListener );
5470 }
5471
5472 // -----------------------------------------------------------------------
5473
RemoveEventListener(const Link & rEventListener)5474 void Window::RemoveEventListener( const Link& rEventListener )
5475 {
5476 mpWindowImpl->maEventListeners.remove( rEventListener );
5477 }
5478
5479 // -----------------------------------------------------------------------
5480
AddChildEventListener(const Link & rEventListener)5481 void Window::AddChildEventListener( const Link& rEventListener )
5482 {
5483 mpWindowImpl->maChildEventListeners.push_back( rEventListener );
5484 }
5485
5486 // -----------------------------------------------------------------------
5487
RemoveChildEventListener(const Link & rEventListener)5488 void Window::RemoveChildEventListener( const Link& rEventListener )
5489 {
5490 mpWindowImpl->maChildEventListeners.remove( rEventListener );
5491 }
5492
5493 // -----------------------------------------------------------------------
5494
PostUserEvent(sal_uLong nEvent,void * pEventData)5495 sal_uLong Window::PostUserEvent( sal_uLong nEvent, void* pEventData )
5496 {
5497 sal_uLong nEventId;
5498 PostUserEvent( nEventId, nEvent, pEventData );
5499 return nEventId;
5500 }
5501
5502 // -----------------------------------------------------------------------
5503
PostUserEvent(const Link & rLink,void * pCaller)5504 sal_uLong Window::PostUserEvent( const Link& rLink, void* pCaller )
5505 {
5506 sal_uLong nEventId;
5507 PostUserEvent( nEventId, rLink, pCaller );
5508 return nEventId;
5509 }
5510
5511 // -----------------------------------------------------------------------
5512
PostUserEvent(sal_uLong & rEventId,sal_uLong nEvent,void * pEventData)5513 sal_Bool Window::PostUserEvent( sal_uLong& rEventId, sal_uLong nEvent, void* pEventData )
5514 {
5515 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5516
5517 ImplSVEvent* pSVEvent = new ImplSVEvent;
5518 pSVEvent->mnEvent = nEvent;
5519 pSVEvent->mpData = pEventData;
5520 pSVEvent->mpLink = NULL;
5521 pSVEvent->mpWindow = this;
5522 pSVEvent->mbCall = sal_True;
5523 ImplAddDel( &(pSVEvent->maDelData) );
5524 rEventId = (sal_uLong)pSVEvent;
5525 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
5526 return sal_True;
5527 else
5528 {
5529 rEventId = 0;
5530 ImplRemoveDel( &(pSVEvent->maDelData) );
5531 delete pSVEvent;
5532 return sal_False;
5533 }
5534 }
5535
5536 // -----------------------------------------------------------------------
5537
PostUserEvent(sal_uLong & rEventId,const Link & rLink,void * pCaller)5538 sal_Bool Window::PostUserEvent( sal_uLong& rEventId, const Link& rLink, void* pCaller )
5539 {
5540 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5541
5542 ImplSVEvent* pSVEvent = new ImplSVEvent;
5543 pSVEvent->mnEvent = 0;
5544 pSVEvent->mpData = pCaller;
5545 pSVEvent->mpLink = new Link( rLink );
5546 pSVEvent->mpWindow = this;
5547 pSVEvent->mbCall = sal_True;
5548 ImplAddDel( &(pSVEvent->maDelData) );
5549 rEventId = (sal_uLong)pSVEvent;
5550 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
5551 return sal_True;
5552 else
5553 {
5554 rEventId = 0;
5555 ImplRemoveDel( &(pSVEvent->maDelData) );
5556 delete pSVEvent;
5557 return sal_False;
5558 }
5559 }
5560
5561 // -----------------------------------------------------------------------
5562
RemoveUserEvent(sal_uLong nUserEvent)5563 void Window::RemoveUserEvent( sal_uLong nUserEvent )
5564 {
5565 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5566
5567 ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent;
5568
5569 DBG_ASSERT( pSVEvent->mpWindow == this,
5570 "Window::RemoveUserEvent(): Event doesn't send to this window or is already removed" );
5571 DBG_ASSERT( pSVEvent->mbCall,
5572 "Window::RemoveUserEvent(): Event is already removed" );
5573
5574 if ( pSVEvent->mpWindow )
5575 {
5576 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
5577 pSVEvent->mpWindow = NULL;
5578 }
5579
5580 pSVEvent->mbCall = sal_False;
5581 }
5582
5583 // -----------------------------------------------------------------------
5584
IMPL_LINK(Window,ImplAsyncStateChangedHdl,void *,pState)5585 IMPL_LINK( Window, ImplAsyncStateChangedHdl, void*, pState )
5586 {
5587 StateChanged( (StateChangedType)(sal_uLong)pState );
5588 return 0;
5589 }
5590
5591 // -----------------------------------------------------------------------
5592
PostStateChanged(StateChangedType nState)5593 void Window::PostStateChanged( StateChangedType nState )
5594 {
5595 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5596
5597 PostUserEvent( LINK( this, Window, ImplAsyncStateChangedHdl ), (void*)(sal_uLong)nState );
5598 }
5599
5600 // -----------------------------------------------------------------------
5601
IsLocked(sal_Bool bChilds) const5602 sal_Bool Window::IsLocked( sal_Bool bChilds ) const
5603 {
5604 if ( mpWindowImpl->mnLockCount != 0 )
5605 return sal_True;
5606
5607 if ( bChilds || mpWindowImpl->mbChildNotify )
5608 {
5609 Window* pChild = mpWindowImpl->mpFirstChild;
5610 while ( pChild )
5611 {
5612 if ( pChild->IsLocked( sal_True ) )
5613 return sal_True;
5614 pChild = pChild->mpWindowImpl->mpNext;
5615 }
5616 }
5617
5618 return sal_False;
5619 }
5620
5621 // -----------------------------------------------------------------------
5622
SetStyle(WinBits nStyle)5623 void Window::SetStyle( WinBits nStyle )
5624 {
5625 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5626
5627 if ( mpWindowImpl->mnStyle != nStyle )
5628 {
5629 mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
5630 mpWindowImpl->mnStyle = nStyle;
5631 StateChanged( STATE_CHANGE_STYLE );
5632 }
5633 }
5634
5635 // -----------------------------------------------------------------------
5636
SetExtendedStyle(WinBits nExtendedStyle)5637 void Window::SetExtendedStyle( WinBits nExtendedStyle )
5638 {
5639 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5640
5641 if ( mpWindowImpl->mnExtendedStyle != nExtendedStyle )
5642 {
5643 Window* pWindow = ImplGetBorderWindow();
5644 if( ! pWindow )
5645 pWindow = this;
5646 if( pWindow->mpWindowImpl->mbFrame )
5647 {
5648 SalExtStyle nExt = 0;
5649 if( (nExtendedStyle & WB_EXT_DOCUMENT) )
5650 nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
5651 if( (nExtendedStyle & WB_EXT_DOCMODIFIED) )
5652 nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;
5653
5654 pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
5655 }
5656 mpWindowImpl->mnPrevExtendedStyle = mpWindowImpl->mnExtendedStyle;
5657 mpWindowImpl->mnExtendedStyle = nExtendedStyle;
5658 StateChanged( STATE_CHANGE_EXTENDEDSTYLE );
5659 }
5660 }
5661
5662 // -----------------------------------------------------------------------
5663
GetSystemWindow() const5664 SystemWindow* Window::GetSystemWindow() const
5665 {
5666 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5667
5668 const Window* pWin = this;
5669 while ( pWin && !pWin->IsSystemWindow() )
5670 pWin = pWin->GetParent();
5671 return (SystemWindow*)pWin;
5672 }
5673
5674 // -----------------------------------------------------------------------
5675
SetBorderStyle(sal_uInt16 nBorderStyle)5676 void Window::SetBorderStyle( sal_uInt16 nBorderStyle )
5677 {
5678 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5679
5680 if ( mpWindowImpl->mpBorderWindow )
5681 {
5682 if( nBorderStyle == WINDOW_BORDER_REMOVEBORDER &&
5683 ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
5684 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
5685 )
5686 {
5687 // this is a little awkward: some controls (e.g. svtools ProgressBar)
5688 // cannot avoid getting constructed with WB_BORDER but want to disable
5689 // borders in case of NWF drawing. So they need a method to remove their border window
5690 Window* pBorderWin = mpWindowImpl->mpBorderWindow;
5691 // remove us as border window's client
5692 pBorderWin->mpWindowImpl->mpClientWindow = NULL;
5693 mpWindowImpl->mpBorderWindow = NULL;
5694 mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
5695 // reparent us above the border window
5696 SetParent( pBorderWin->mpWindowImpl->mpParent );
5697 // set us to the position and size of our previous border
5698 Point aBorderPos( pBorderWin->GetPosPixel() );
5699 Size aBorderSize( pBorderWin->GetSizePixel() );
5700 SetPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
5701 // release border window
5702 delete pBorderWin;
5703
5704 // set new style bits
5705 SetStyle( GetStyle() & (~WB_BORDER) );
5706 }
5707 else
5708 {
5709 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5710 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetBorderStyle( nBorderStyle );
5711 else
5712 mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
5713 }
5714 }
5715 }
5716
5717 // -----------------------------------------------------------------------
5718
GetBorderStyle() const5719 sal_uInt16 Window::GetBorderStyle() const
5720 {
5721 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5722
5723 if ( mpWindowImpl->mpBorderWindow )
5724 {
5725 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5726 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorderStyle();
5727 else
5728 return mpWindowImpl->mpBorderWindow->GetBorderStyle();
5729 }
5730
5731 return 0;
5732 }
5733
5734 // -----------------------------------------------------------------------
5735
CalcTitleWidth() const5736 long Window::CalcTitleWidth() const
5737 {
5738 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5739
5740 if ( mpWindowImpl->mpBorderWindow )
5741 {
5742 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5743 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->CalcTitleWidth();
5744 else
5745 return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
5746 }
5747 else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
5748 {
5749 // Fuer Frame-Fenster raten wir die Breite, da wir den Border fuer
5750 // externe Dialoge nicht kennen
5751 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
5752 Font aFont = GetFont();
5753 ((Window*)this)->SetPointFont( rStyleSettings.GetTitleFont() );
5754 long nTitleWidth = GetTextWidth( GetText() );
5755 ((Window*)this)->SetFont( aFont );
5756 nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
5757 nTitleWidth += rStyleSettings.GetBorderSize() * 2;
5758 nTitleWidth += 10;
5759 return nTitleWidth;
5760 }
5761
5762 return 0;
5763 }
5764
5765 // -----------------------------------------------------------------------
5766
EnableClipSiblings(sal_Bool bClipSiblings)5767 void Window::EnableClipSiblings( sal_Bool bClipSiblings )
5768 {
5769 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5770
5771 if ( mpWindowImpl->mpBorderWindow )
5772 mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings );
5773
5774 mpWindowImpl->mbClipSiblings = bClipSiblings;
5775 }
5776
5777 // -----------------------------------------------------------------------
5778
SetMouseTransparent(sal_Bool bTransparent)5779 void Window::SetMouseTransparent( sal_Bool bTransparent )
5780 {
5781 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5782
5783 if ( mpWindowImpl->mpBorderWindow )
5784 mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
5785
5786 if( mpWindowImpl->mpSysObj )
5787 mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
5788
5789 mpWindowImpl->mbMouseTransparent = bTransparent;
5790 }
5791
5792 // -----------------------------------------------------------------------
5793
SetPaintTransparent(sal_Bool bTransparent)5794 void Window::SetPaintTransparent( sal_Bool bTransparent )
5795 {
5796 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5797
5798 // transparency is not useful for frames as the background would have to be provided by a different frame
5799 if( bTransparent && mpWindowImpl->mbFrame )
5800 return;
5801
5802 if ( mpWindowImpl->mpBorderWindow )
5803 mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
5804
5805 mpWindowImpl->mbPaintTransparent = bTransparent;
5806 }
5807
5808 // -----------------------------------------------------------------------
5809
SetInputContext(const InputContext & rInputContext)5810 void Window::SetInputContext( const InputContext& rInputContext )
5811 {
5812 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5813
5814 mpWindowImpl->maInputContext = rInputContext;
5815 if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
5816 ImplNewInputContext();
5817 }
5818
5819 // -----------------------------------------------------------------------
5820
EndExtTextInput(sal_uInt16 nFlags)5821 void Window::EndExtTextInput( sal_uInt16 nFlags )
5822 {
5823 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5824
5825 if ( mpWindowImpl->mbExtTextInput )
5826 ImplGetFrame()->EndExtTextInput( nFlags );
5827 }
5828
5829 // -----------------------------------------------------------------------
5830
SetCursorRect(const Rectangle * pRect,long nExtTextInputWidth)5831 void Window::SetCursorRect( const Rectangle* pRect, long nExtTextInputWidth )
5832 {
5833 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5834
5835 ImplWinData* pWinData = ImplGetWinData();
5836 if ( pWinData->mpCursorRect )
5837 {
5838 if ( pRect )
5839 *pWinData->mpCursorRect = *pRect;
5840 else
5841 {
5842 delete pWinData->mpCursorRect;
5843 pWinData->mpCursorRect = NULL;
5844 }
5845 }
5846 else
5847 {
5848 if ( pRect )
5849 pWinData->mpCursorRect = new Rectangle( *pRect );
5850 }
5851
5852 pWinData->mnCursorExtWidth = nExtTextInputWidth;
5853
5854 }
5855
5856 // -----------------------------------------------------------------------
5857
GetCursorRect() const5858 const Rectangle* Window::GetCursorRect() const
5859 {
5860 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5861
5862 ImplWinData* pWinData = ImplGetWinData();
5863 return pWinData->mpCursorRect;
5864 }
5865
5866 // -----------------------------------------------------------------------
5867
GetCursorExtTextInputWidth() const5868 long Window::GetCursorExtTextInputWidth() const
5869 {
5870 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5871
5872 ImplWinData* pWinData = ImplGetWinData();
5873 return pWinData->mnCursorExtWidth;
5874 }
5875
5876 // -----------------------------------------------------------------------
SetSettings(const AllSettings & rSettings)5877 void Window::SetSettings( const AllSettings& rSettings )
5878 {
5879 SetSettings( rSettings, sal_False );
5880 }
5881
SetSettings(const AllSettings & rSettings,sal_Bool bChild)5882 void Window::SetSettings( const AllSettings& rSettings, sal_Bool bChild )
5883 {
5884 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5885
5886 if ( mpWindowImpl->mpBorderWindow )
5887 {
5888 mpWindowImpl->mpBorderWindow->SetSettings( rSettings, sal_False );
5889 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
5890 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
5891 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, sal_True );
5892 }
5893
5894 AllSettings aOldSettings = maSettings;
5895 OutputDevice::SetSettings( rSettings );
5896 sal_uLong nChangeFlags = aOldSettings.GetChangeFlags( rSettings );
5897
5898 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
5899 ImplInitResolutionSettings();
5900
5901 if ( nChangeFlags )
5902 {
5903 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
5904 DataChanged( aDCEvt );
5905 }
5906
5907 if ( bChild || mpWindowImpl->mbChildNotify )
5908 {
5909 Window* pChild = mpWindowImpl->mpFirstChild;
5910 while ( pChild )
5911 {
5912 pChild->SetSettings( rSettings, bChild );
5913 pChild = pChild->mpWindowImpl->mpNext;
5914 }
5915 }
5916 }
5917
5918 // -----------------------------------------------------------------------
5919
UpdateSettings(const AllSettings & rSettings,sal_Bool bChild)5920 void Window::UpdateSettings( const AllSettings& rSettings, sal_Bool bChild )
5921 {
5922 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5923
5924 if ( mpWindowImpl->mpBorderWindow )
5925 {
5926 mpWindowImpl->mpBorderWindow->UpdateSettings( rSettings, sal_False );
5927 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
5928 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
5929 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, sal_True );
5930 }
5931
5932 AllSettings aOldSettings = maSettings;
5933 sal_uLong nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings );
5934 nChangeFlags |= SETTINGS_IN_UPDATE_SETTINGS; // Set this flag so the receiver of the data changed
5935 // event can distinguish between the changing of global
5936 // setting and a local change ( with SetSettings )
5937
5938 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
5939 ImplInitResolutionSettings();
5940
5941 /* #i73785#
5942 * do not overwrite a WheelBehavior with false
5943 * this looks kind of a hack, but WheelBehavior
5944 * is always a local change, not a system property,
5945 * so we can spare all our users the hassle of reacting on
5946 * this in their respective DataChanged.
5947 */
5948 MouseSettings aSet( maSettings.GetMouseSettings() );
5949 aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() );
5950 maSettings.SetMouseSettings( aSet );
5951
5952 if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() )
5953 {
5954 Wallpaper aWallpaper = GetBackground();
5955 if( !aWallpaper.IsBitmap() && !aWallpaper.IsGradient() )
5956 {
5957 if ( mpWindowImpl->mnStyle & WB_3DLOOK )
5958 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetFaceColor() ) );
5959 else
5960 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetWindowColor() ) );
5961 }
5962 }
5963
5964 if ( nChangeFlags )
5965 {
5966 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
5967 DataChanged( aDCEvt );
5968 // notify data change handler
5969 ImplCallEventListeners( VCLEVENT_WINDOW_DATACHANGED, &aDCEvt);
5970 }
5971
5972 if ( bChild || mpWindowImpl->mbChildNotify )
5973 {
5974 Window* pChild = mpWindowImpl->mpFirstChild;
5975 while ( pChild )
5976 {
5977 pChild->UpdateSettings( rSettings, bChild );
5978 pChild = pChild->mpWindowImpl->mpNext;
5979 }
5980 }
5981 }
5982
5983 // -----------------------------------------------------------------------
5984
NotifyAllChilds(DataChangedEvent & rDCEvt)5985 void Window::NotifyAllChilds( DataChangedEvent& rDCEvt )
5986 {
5987 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5988
5989 DataChanged( rDCEvt );
5990
5991 Window* pChild = mpWindowImpl->mpFirstChild;
5992 while ( pChild )
5993 {
5994 pChild->NotifyAllChilds( rDCEvt );
5995 pChild = pChild->mpWindowImpl->mpNext;
5996 }
5997 }
5998
5999 // -----------------------------------------------------------------------
6000
SetPointFont(const Font & rFont)6001 void Window::SetPointFont( const Font& rFont )
6002 {
6003 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6004
6005 Font aFont = rFont;
6006 ImplPointToLogic( aFont );
6007 SetFont( aFont );
6008 }
6009
6010 // -----------------------------------------------------------------------
6011
GetPointFont() const6012 Font Window::GetPointFont() const
6013 {
6014 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6015
6016 Font aFont = GetFont();
6017 ImplLogicToPoint( aFont );
6018 return aFont;
6019 }
6020
6021 // -----------------------------------------------------------------------
6022
6023 // TODO: remove in next incompatible build
GetFontResolution(sal_Int32 & nDPIX,sal_Int32 & nDPIY) const6024 void Window::GetFontResolution( sal_Int32& nDPIX, sal_Int32& nDPIY ) const
6025 {
6026 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6027
6028 nDPIX = mpWindowImpl->mpFrameData->mnDPIX;
6029 nDPIY = mpWindowImpl->mpFrameData->mnDPIY;
6030 }
6031
6032 // -----------------------------------------------------------------------
6033
SetParentClipMode(sal_uInt16 nMode)6034 void Window::SetParentClipMode( sal_uInt16 nMode )
6035 {
6036 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6037
6038 if ( mpWindowImpl->mpBorderWindow )
6039 mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode );
6040 else
6041 {
6042 if ( !ImplIsOverlapWindow() )
6043 {
6044 mpWindowImpl->mnParentClipMode = nMode;
6045 if ( nMode & PARENTCLIPMODE_CLIP )
6046 mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = sal_True;
6047 }
6048 }
6049 }
6050
6051 // -----------------------------------------------------------------------
6052
GetParentClipMode() const6053 sal_uInt16 Window::GetParentClipMode() const
6054 {
6055 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6056
6057 if ( mpWindowImpl->mpBorderWindow )
6058 return mpWindowImpl->mpBorderWindow->GetParentClipMode();
6059 else
6060 return mpWindowImpl->mnParentClipMode;
6061 }
6062
6063 // -----------------------------------------------------------------------
6064
SetWindowRegionPixel()6065 void Window::SetWindowRegionPixel()
6066 {
6067 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6068
6069 if ( mpWindowImpl->mpBorderWindow )
6070 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
6071 else if( mpWindowImpl->mbFrame )
6072 {
6073 mpWindowImpl->maWinRegion = Region(true);
6074 mpWindowImpl->mbWinRegion = sal_False;
6075 mpWindowImpl->mpFrame->ResetClipRegion();
6076 }
6077 else
6078 {
6079 if ( mpWindowImpl->mbWinRegion )
6080 {
6081 mpWindowImpl->maWinRegion = Region(true);
6082 mpWindowImpl->mbWinRegion = sal_False;
6083 ImplSetClipFlag();
6084
6085 if ( IsReallyVisible() )
6086 {
6087 // Hintergrund-Sicherung zuruecksetzen
6088 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
6089 ImplDeleteOverlapBackground();
6090 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6091 ImplInvalidateAllOverlapBackgrounds();
6092 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6093 Region aRegion( aRect );
6094 ImplInvalidateParentFrameRegion( aRegion );
6095 }
6096 }
6097 }
6098 }
6099
6100 // -----------------------------------------------------------------------
6101
SetWindowRegionPixel(const Region & rRegion)6102 void Window::SetWindowRegionPixel( const Region& rRegion )
6103 {
6104 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6105
6106 if ( mpWindowImpl->mpBorderWindow )
6107 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
6108 else if( mpWindowImpl->mbFrame )
6109 {
6110 if( !rRegion.IsNull() )
6111 {
6112 mpWindowImpl->maWinRegion = rRegion;
6113 mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
6114
6115 if( mpWindowImpl->mbWinRegion )
6116 {
6117 // ClipRegion setzen/updaten
6118 RectangleVector aRectangles;
6119 mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
6120 mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
6121
6122 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
6123 {
6124 mpWindowImpl->mpFrame->UnionClipRegion(
6125 aRectIter->Left(),
6126 aRectIter->Top(),
6127 aRectIter->GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does
6128 aRectIter->GetHeight()); // same for height
6129 }
6130
6131 mpWindowImpl->mpFrame->EndSetClipRegion();
6132
6133 //long nX;
6134 //long nY;
6135 //long nWidth;
6136 //long nHeight;
6137 //sal_uLong nRectCount;
6138 //ImplRegionInfo aInfo;
6139 //sal_Bool bRegionRect;
6140 //
6141 //nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
6142 //mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
6143 //bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
6144 //while ( bRegionRect )
6145 //{
6146 // mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
6147 // bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
6148 //}
6149 //mpWindowImpl->mpFrame->EndSetClipRegion();
6150 }
6151 else
6152 SetWindowRegionPixel();
6153 }
6154 else
6155 SetWindowRegionPixel();
6156 }
6157 else
6158 {
6159 sal_Bool bInvalidate = sal_False;
6160
6161 if ( rRegion.IsNull() )
6162 {
6163 if ( mpWindowImpl->mbWinRegion )
6164 {
6165 mpWindowImpl->maWinRegion = Region(true);
6166 mpWindowImpl->mbWinRegion = sal_False;
6167 ImplSetClipFlag();
6168 bInvalidate = sal_True;
6169 }
6170 }
6171 else
6172 {
6173 mpWindowImpl->maWinRegion = rRegion;
6174 mpWindowImpl->mbWinRegion = sal_True;
6175 ImplSetClipFlag();
6176 bInvalidate = sal_True;
6177 }
6178
6179 if ( IsReallyVisible() )
6180 {
6181 // Hintergrund-Sicherung zuruecksetzen
6182 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
6183 ImplDeleteOverlapBackground();
6184 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6185 ImplInvalidateAllOverlapBackgrounds();
6186 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6187 Region aRegion( aRect );
6188 ImplInvalidateParentFrameRegion( aRegion );
6189 }
6190 }
6191 }
6192
6193 // -----------------------------------------------------------------------
6194
GetWindowRegionPixel() const6195 const Region& Window::GetWindowRegionPixel() const
6196 {
6197 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6198
6199 if ( mpWindowImpl->mpBorderWindow )
6200 return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel();
6201 else
6202 return mpWindowImpl->maWinRegion;
6203 }
6204
6205 // -----------------------------------------------------------------------
6206
IsWindowRegionPixel() const6207 sal_Bool Window::IsWindowRegionPixel() const
6208 {
6209 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6210
6211 if ( mpWindowImpl->mpBorderWindow )
6212 return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel();
6213 else
6214 return mpWindowImpl->mbWinRegion;
6215 }
6216
6217 // -----------------------------------------------------------------------
6218
GetWindowClipRegionPixel(sal_uInt16 nFlags) const6219 Region Window::GetWindowClipRegionPixel( sal_uInt16 nFlags ) const
6220 {
6221 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6222
6223 Region aWinClipRegion;
6224
6225 if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN )
6226 {
6227 if ( mpWindowImpl->mbInitWinClipRegion )
6228 ((Window*)this)->ImplInitWinClipRegion();
6229 aWinClipRegion = mpWindowImpl->maWinClipRegion;
6230 }
6231 else
6232 {
6233 Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion();
6234 aWinClipRegion = *pWinChildClipRegion;
6235 // --- RTL --- remirror clip region before passing it to somebody
6236 if( ImplIsAntiparallel() )
6237 ImplReMirror( aWinClipRegion );
6238 }
6239
6240 if ( nFlags & WINDOW_GETCLIPREGION_NULL )
6241 {
6242 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6243 Region aWinRegion( aWinRect );
6244
6245 if ( aWinRegion == aWinClipRegion )
6246 aWinClipRegion.SetNull();
6247 }
6248
6249 aWinClipRegion.Move( -mnOutOffX, -mnOutOffY );
6250
6251 return aWinClipRegion;
6252 }
6253
6254 // -----------------------------------------------------------------------
6255
GetPaintRegion() const6256 Region Window::GetPaintRegion() const
6257 {
6258 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6259
6260 if ( mpWindowImpl->mpPaintRegion )
6261 {
6262 Region aRegion = *mpWindowImpl->mpPaintRegion;
6263 aRegion.Move( -mnOutOffX, -mnOutOffY );
6264 return PixelToLogic( aRegion );
6265 }
6266 else
6267 {
6268 Region aPaintRegion(true);
6269 return aPaintRegion;
6270 }
6271 }
6272
6273 // -----------------------------------------------------------------------
6274
ExpandPaintClipRegion(const Region & rRegion)6275 void Window::ExpandPaintClipRegion( const Region& rRegion )
6276 {
6277 if( mpWindowImpl->mpPaintRegion )
6278 {
6279 Region aPixRegion = LogicToPixel( rRegion );
6280 Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion );
6281
6282 Region aWinChildRegion = *ImplGetWinChildClipRegion();
6283 // --- RTL -- only this region is in frame coordinates, so re-mirror it
6284 if( ImplIsAntiparallel() )
6285 ImplReMirror( aWinChildRegion );
6286 aDevPixRegion.Intersect( aWinChildRegion );
6287 if( ! aDevPixRegion.IsEmpty() )
6288 {
6289 mpWindowImpl->mpPaintRegion->Union( aDevPixRegion );
6290 mbInitClipRegion = sal_True;
6291 }
6292 }
6293 }
6294
6295 // -----------------------------------------------------------------------
6296
ImplGetLastSystemWindow(Window * pWin)6297 static SystemWindow *ImplGetLastSystemWindow( Window *pWin )
6298 {
6299 // get the most top-level system window, the one that contains the taskpanelist
6300 SystemWindow *pSysWin = NULL;
6301 if( !pWin )
6302 return pSysWin;
6303 Window *pMyParent = pWin;
6304 while ( pMyParent )
6305 {
6306 if ( pMyParent->IsSystemWindow() )
6307 pSysWin = (SystemWindow*)pMyParent;
6308 pMyParent = pMyParent->GetParent();
6309 }
6310 return pSysWin;
6311 }
6312
SetParent(Window * pNewParent)6313 void Window::SetParent( Window* pNewParent )
6314 {
6315 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6316 DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" );
6317 DBG_ASSERT( pNewParent != this, "someone tried to reparent a window to itself" );
6318
6319 if( pNewParent == this )
6320 return;
6321
6322 // check if the taskpanelist would change and move the window pointer accordingly
6323 SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
6324 SystemWindow *pNewSysWin = NULL;
6325 sal_Bool bChangeTaskPaneList = sal_False;
6326 if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
6327 {
6328 pNewSysWin = ImplGetLastSystemWindow( pNewParent );
6329 if( pNewSysWin && pNewSysWin != pSysWin )
6330 {
6331 bChangeTaskPaneList = sal_True;
6332 pSysWin->GetTaskPaneList()->RemoveWindow( this );
6333 }
6334 }
6335 // remove ownerdraw decorated windows from list in the top-most frame window
6336 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
6337 {
6338 ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
6339 ::std::vector< Window* >::iterator p;
6340 p = ::std::find( rList.begin(), rList.end(), this );
6341 if( p != rList.end() )
6342 rList.erase( p );
6343 }
6344
6345 ImplSetFrameParent( pNewParent );
6346
6347 if ( mpWindowImpl->mpBorderWindow )
6348 {
6349 mpWindowImpl->mpRealParent = pNewParent;
6350 mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
6351 return;
6352 }
6353
6354 if ( mpWindowImpl->mpParent == pNewParent )
6355 return;
6356
6357 if ( mpWindowImpl->mbFrame )
6358 mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
6359
6360 sal_Bool bVisible = IsVisible();
6361 Show( sal_False, SHOW_NOFOCUSCHANGE );
6362
6363 // Testen, ob sich das Overlap-Window aendert
6364 Window* pOldOverlapWindow;
6365 Window* pNewOverlapWindow = NULL;
6366 if ( ImplIsOverlapWindow() )
6367 pOldOverlapWindow = NULL;
6368 else
6369 {
6370 pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
6371 if ( mpWindowImpl->mpOverlapWindow != pNewOverlapWindow )
6372 pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
6373 else
6374 pOldOverlapWindow = NULL;
6375 }
6376
6377 // Fenster in der Hierachie umsetzen
6378 sal_Bool bFocusOverlapWin = HasChildPathFocus( sal_True );
6379 sal_Bool bFocusWin = HasChildPathFocus();
6380 sal_Bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
6381 if ( bNewFrame )
6382 {
6383 if ( mpWindowImpl->mpFrameData->mpFocusWin )
6384 {
6385 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
6386 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
6387 }
6388 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
6389 {
6390 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
6391 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
6392 }
6393 if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
6394 {
6395 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
6396 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
6397 }
6398 }
6399 ImplRemoveWindow( bNewFrame );
6400 ImplInsertWindow( pNewParent );
6401 if ( mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP )
6402 pNewParent->mpWindowImpl->mbClipChildren = sal_True;
6403 ImplUpdateWindowPtr();
6404 if ( ImplUpdatePos() )
6405 ImplUpdateSysObjPos();
6406
6407 // Wenn sich das Overlap-Window geaendert hat, dann muss getestet werden,
6408 // ob auch OverlapWindow die das Child-Fenster als Parent gehabt haben
6409 // in der Window-Hierachie umgesetzt werden muessen
6410 if ( ImplIsOverlapWindow() )
6411 {
6412 if ( bNewFrame )
6413 {
6414 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
6415 while ( pOverlapWindow )
6416 {
6417 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
6418 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
6419 pOverlapWindow = pNextOverlapWindow;
6420 }
6421 }
6422 }
6423 else if ( pOldOverlapWindow )
6424 {
6425 // Focus-Save zuruecksetzen
6426 if ( bFocusWin ||
6427 (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
6428 IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
6429 pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
6430
6431 Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
6432 while ( pOverlapWindow )
6433 {
6434 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
6435 if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
6436 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
6437 pOverlapWindow = pNextOverlapWindow;
6438 }
6439
6440 // Activate-Status beim naechsten Overlap-Window updaten
6441 if ( HasChildPathFocus( sal_True ) )
6442 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
6443 }
6444
6445 // Activate-Status mit umsetzen
6446 if ( bNewFrame )
6447 {
6448 if ( (GetType() == WINDOW_BORDERWINDOW) &&
6449 (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
6450 ((ImplBorderWindow*)this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
6451 }
6452
6453 // Focus evtl. auf den neuen Frame umsetzen, wenn FocusWindow mit
6454 // SetParent() umgesetzt wird
6455 if ( bFocusOverlapWin )
6456 {
6457 mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
6458 if ( !mpWindowImpl->mpFrameData->mbHasFocus )
6459 {
6460 mpWindowImpl->mpFrame->ToTop( 0 );
6461 }
6462 }
6463
6464 // Assure DragSource and DropTarget members are created
6465 if ( bNewFrame )
6466 {
6467 GetDropTarget();
6468 }
6469
6470 if( bChangeTaskPaneList )
6471 pNewSysWin->GetTaskPaneList()->AddWindow( this );
6472
6473 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
6474 ImplGetOwnerDrawList().push_back( this );
6475
6476 if ( bVisible )
6477 Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
6478 }
6479
6480 // -----------------------------------------------------------------------
6481
Show(sal_Bool bVisible,sal_uInt16 nFlags)6482 void Window::Show( sal_Bool bVisible, sal_uInt16 nFlags )
6483 {
6484 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6485
6486 if ( mpWindowImpl->mbVisible == bVisible )
6487 return;
6488
6489 ImplDelData aDogTag( this );
6490
6491 sal_Bool bRealVisibilityChanged = sal_False;
6492 mpWindowImpl->mbVisible = (bVisible != 0);
6493
6494 if ( !bVisible )
6495 {
6496 ImplHideAllOverlaps();
6497 if( aDogTag.IsDelete() )
6498 return;
6499
6500 if ( mpWindowImpl->mpBorderWindow )
6501 {
6502 sal_Bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
6503 if ( mpWindowImpl->mbNoParentUpdate )
6504 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = sal_True;
6505 mpWindowImpl->mpBorderWindow->Show( sal_False, nFlags );
6506 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
6507 }
6508 else if ( mpWindowImpl->mbFrame )
6509 {
6510 mpWindowImpl->mbSuppressAccessibilityEvents = sal_True;
6511 mpWindowImpl->mpFrame->Show( sal_False, sal_False );
6512 }
6513
6514 StateChanged( STATE_CHANGE_VISIBLE );
6515
6516 if ( mpWindowImpl->mbReallyVisible )
6517 {
6518 Region aInvRegion;
6519 sal_Bool bSaveBack = sal_False;
6520
6521 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
6522 {
6523 if ( ImplRestoreOverlapBackground( aInvRegion ) )
6524 bSaveBack = sal_True;
6525 }
6526
6527 if ( !bSaveBack )
6528 {
6529 if ( mpWindowImpl->mbInitWinClipRegion )
6530 ImplInitWinClipRegion();
6531 aInvRegion = mpWindowImpl->maWinClipRegion;
6532 }
6533
6534 if( aDogTag.IsDelete() )
6535 return;
6536
6537 bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
6538 ImplResetReallyVisible();
6539 ImplSetClipFlag();
6540
6541 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
6542 {
6543 // Focus umsetzen
6544 if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() )
6545 {
6546 if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
6547 mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
6548 ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
6549 )
6550 mpWindowImpl->mpOverlapWindow->GrabFocus();
6551 }
6552 }
6553
6554 if ( !mpWindowImpl->mbFrame )
6555 {
6556 if( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget )
6557 {
6558 /*
6559 * #i48371# native theming: some themes draw outside the control
6560 * area we tell them to (bad thing, but we cannot do much about it ).
6561 * On hiding these controls they get invalidated with their window rectangle
6562 * which leads to the parts outside the control area being left and not
6563 * invalidated. Workaround: invalidate an area on the parent, too
6564 */
6565 const int workaround_border = 5;
6566 Rectangle aBounds( aInvRegion.GetBoundRect() );
6567 aBounds.Left() -= workaround_border;
6568 aBounds.Top() -= workaround_border;
6569 aBounds.Right() += workaround_border;
6570 aBounds.Bottom() += workaround_border;
6571 aInvRegion = aBounds;
6572 }
6573 if ( !mpWindowImpl->mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) )
6574 {
6575 if ( !aInvRegion.IsEmpty() )
6576 ImplInvalidateParentFrameRegion( aInvRegion );
6577 }
6578 ImplGenerateMouseMove();
6579 }
6580 }
6581 }
6582 else
6583 {
6584 // inherit native widget flag for form controls
6585 // required here, because frames never show up in the child hierarchy - which should be fixed...
6586 // e.g. the drop down of a combobox which is a system floating window
6587 if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() &&
6588 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() )
6589 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
6590
6591 if ( mpWindowImpl->mbCallMove )
6592 {
6593 ImplCallMove();
6594 }
6595 if ( mpWindowImpl->mbCallResize )
6596 {
6597 ImplCallResize();
6598 }
6599
6600 StateChanged( STATE_CHANGE_VISIBLE );
6601
6602 Window* pTestParent;
6603 if ( ImplIsOverlapWindow() )
6604 pTestParent = mpWindowImpl->mpOverlapWindow;
6605 else
6606 pTestParent = ImplGetParent();
6607 if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
6608 {
6609 // Wenn ein Window gerade sichtbar wird, schicken wir allen
6610 // Child-Fenstern ein StateChanged, damit diese sich
6611 // initialisieren koennen
6612 ImplCallInitShow();
6613
6614 // Wenn es ein SystemWindow ist, dann kommt es auch automatisch
6615 // nach vorne, wenn es gewuenscht ist
6616 if ( ImplIsOverlapWindow() && !(nFlags & SHOW_NOACTIVATE) )
6617 {
6618 ImplStartToTop(( nFlags & SHOW_FOREGROUNDTASK ) ? TOTOP_FOREGROUNDTASK : 0 );
6619 ImplFocusToTop( 0, sal_False );
6620 }
6621
6622 // Hintergrund sichern
6623 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mbSaveBack )
6624 ImplSaveOverlapBackground();
6625 // adjust mpWindowImpl->mbReallyVisible
6626 bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
6627 ImplSetReallyVisible();
6628
6629 // Dafuer sorgen, das Clip-Rechtecke neu berechnet werden
6630 ImplSetClipFlag();
6631
6632 if ( !mpWindowImpl->mbFrame )
6633 {
6634 sal_uInt16 nInvalidateFlags = INVALIDATE_CHILDREN;
6635 if( ! IsPaintTransparent() )
6636 nInvalidateFlags |= INVALIDATE_NOTRANSPARENT;
6637 ImplInvalidate( NULL, nInvalidateFlags );
6638 ImplGenerateMouseMove();
6639 }
6640 }
6641
6642 if ( mpWindowImpl->mpBorderWindow )
6643 mpWindowImpl->mpBorderWindow->Show( sal_True, nFlags );
6644 else if ( mpWindowImpl->mbFrame )
6645 {
6646 ImplSVData* pSVData = ImplGetSVData();
6647 // #106431#, hide SplashScreen
6648 if( pSVData->mpIntroWindow && !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
6649 pSVData->mpIntroWindow->Hide();
6650
6651 //DBG_ASSERT( !mpWindowImpl->mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated");
6652 mpWindowImpl->mbSuppressAccessibilityEvents = sal_False;
6653
6654 mpWindowImpl->mbPaintFrame = sal_True;
6655 sal_Bool bNoActivate = (nFlags & (SHOW_NOACTIVATE|SHOW_NOFOCUSCHANGE)) ? sal_True : sal_False;
6656 mpWindowImpl->mpFrame->Show( sal_True, bNoActivate );
6657 if( aDogTag.IsDelete() )
6658 return;
6659
6660 // Query the correct size of the window, if we are waiting for
6661 // a system resize
6662 if ( mpWindowImpl->mbWaitSystemResize )
6663 {
6664 long nOutWidth;
6665 long nOutHeight;
6666 mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
6667 ImplHandleResize( this, nOutWidth, nOutHeight );
6668 }
6669 }
6670
6671 if( aDogTag.IsDelete() )
6672 return;
6673
6674 #ifdef DBG_UTIL
6675 if ( IsDialog() || (GetType() == WINDOW_TABPAGE) || (GetType() == WINDOW_DOCKINGWINDOW) )
6676 {
6677 DBG_DIALOGTEST( this );
6678 }
6679 #endif
6680
6681 ImplShowAllOverlaps();
6682 }
6683
6684 if( aDogTag.IsDelete() )
6685 return;
6686 // invalidate all saved backgrounds
6687 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6688 ImplInvalidateAllOverlapBackgrounds();
6689
6690 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
6691 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
6692 // we re-use the SHOW/HIDE events this way, with this particular semantics).
6693 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
6694 // now only notify with a NULL data pointer, for all other clients except the access bridge.
6695 if ( !bRealVisibilityChanged )
6696 ImplCallEventListeners( mpWindowImpl->mbVisible ? VCLEVENT_WINDOW_SHOW : VCLEVENT_WINDOW_HIDE, NULL );
6697 if( aDogTag.IsDelete() )
6698 return;
6699
6700 // #107575#, if a floating windows is shown that grabs the focus, we have to notify the toolkit about it
6701 // ImplGrabFocus() is not called in this case
6702 // Because this might lead to problems the task will be shifted to 6.y
6703 // Note: top-level context menus are registered at the access bridge after being shown,
6704 // so this will probably not help here....
6705 /*
6706 if( mpWindowImpl->mbFloatWin && ((FloatingWindow*) this )->GrabsFocus() )
6707 {
6708 ImplSVData* pSVData = ImplGetSVData();
6709 if( !mpWindowImpl->mbVisible )
6710 {
6711 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
6712 if( pSVData->maWinData.mpFocusWin )
6713 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
6714 }
6715 else
6716 {
6717 if( pSVData->maWinData.mpFocusWin )
6718 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
6719 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
6720 }
6721 }
6722 */
6723 }
6724
6725 // -----------------------------------------------------------------------
6726
GetSizePixel() const6727 Size Window::GetSizePixel() const
6728 {
6729 // #i43257# trigger pending resize handler to assure correct window sizes
6730 if( mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
6731 {
6732 ImplDelData aDogtag( this );
6733 mpWindowImpl->mpFrameData->maResizeTimer.Stop();
6734 mpWindowImpl->mpFrameData->maResizeTimer.GetTimeoutHdl().Call( NULL );
6735 if( aDogtag.IsDelete() )
6736 return Size(0,0);
6737 }
6738
6739 return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
6740 mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
6741 }
6742
GetBorder(sal_Int32 & rLeftBorder,sal_Int32 & rTopBorder,sal_Int32 & rRightBorder,sal_Int32 & rBottomBorder) const6743 void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
6744 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
6745 {
6746 rLeftBorder = mpWindowImpl->mnLeftBorder;
6747 rTopBorder = mpWindowImpl->mnTopBorder;
6748 rRightBorder = mpWindowImpl->mnRightBorder;
6749 rBottomBorder = mpWindowImpl->mnBottomBorder;
6750 }
6751
6752
6753 // -----------------------------------------------------------------------
6754
Enable(bool bEnable,bool bChild)6755 void Window::Enable( bool bEnable, bool bChild )
6756 {
6757 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6758
6759 if ( !bEnable )
6760 {
6761 // Wenn ein Fenster disabled wird, wird automatisch der Tracking-Modus
6762 // beendet oder der Capture geklaut
6763 if ( IsTracking() )
6764 EndTracking( ENDTRACK_CANCEL );
6765 if ( IsMouseCaptured() )
6766 ReleaseMouse();
6767 // Wenn Fenster den Focus hat und in der Dialog-Steuerung enthalten,
6768 // wird versucht, den Focus auf das naechste Control weiterzuschalten
6769 // mpWindowImpl->mbDisabled darf erst nach Aufruf von ImplDlgCtrlNextWindow() gesetzt
6770 // werden. Ansonsten muss ImplDlgCtrlNextWindow() umgestellt werden
6771 if ( HasFocus() )
6772 ImplDlgCtrlNextWindow();
6773 }
6774
6775 if ( mpWindowImpl->mpBorderWindow )
6776 {
6777 mpWindowImpl->mpBorderWindow->Enable( bEnable, sal_False );
6778 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
6779 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
6780 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, sal_True );
6781 }
6782
6783 // #i56102# restore app focus win in case the
6784 // window was disabled when the frame focus changed
6785 ImplSVData* pSVData = ImplGetSVData();
6786 if( bEnable &&
6787 pSVData->maWinData.mpFocusWin == NULL &&
6788 mpWindowImpl->mpFrameData->mbHasFocus &&
6789 mpWindowImpl->mpFrameData->mpFocusWin == this )
6790 pSVData->maWinData.mpFocusWin = this;
6791
6792 if ( mpWindowImpl->mbDisabled != !bEnable )
6793 {
6794 mpWindowImpl->mbDisabled = !bEnable;
6795 if ( mpWindowImpl->mpSysObj )
6796 mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
6797 // if ( mpWindowImpl->mbFrame )
6798 // mpWindowImpl->mpFrame->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
6799 StateChanged( STATE_CHANGE_ENABLE );
6800
6801 ImplCallEventListeners( bEnable ? VCLEVENT_WINDOW_ENABLED : VCLEVENT_WINDOW_DISABLED );
6802 }
6803
6804 if ( bChild || mpWindowImpl->mbChildNotify )
6805 {
6806 Window* pChild = mpWindowImpl->mpFirstChild;
6807 while ( pChild )
6808 {
6809 pChild->Enable( bEnable, bChild );
6810 pChild = pChild->mpWindowImpl->mpNext;
6811 }
6812 }
6813
6814 if ( IsReallyVisible() )
6815 ImplGenerateMouseMove();
6816 }
6817
6818 // -----------------------------------------------------------------------
6819
SetCallHandlersOnInputDisabled(bool bCall)6820 void Window::SetCallHandlersOnInputDisabled( bool bCall )
6821 {
6822 mpWindowImpl->mbCallHandlersDuringInputDisabled = bCall ? sal_True : sal_False;
6823
6824 Window* pChild = mpWindowImpl->mpFirstChild;
6825 while ( pChild )
6826 {
6827 pChild->SetCallHandlersOnInputDisabled( bCall );
6828 pChild = pChild->mpWindowImpl->mpNext;
6829 }
6830 }
6831
6832 // -----------------------------------------------------------------------
6833
IsCallHandlersOnInputDisabled() const6834 bool Window::IsCallHandlersOnInputDisabled() const
6835 {
6836 return mpWindowImpl->mbCallHandlersDuringInputDisabled ? true : false;
6837 }
6838
6839 // -----------------------------------------------------------------------
6840
EnableInput(sal_Bool bEnable,sal_Bool bChild)6841 void Window::EnableInput( sal_Bool bEnable, sal_Bool bChild )
6842 {
6843 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6844
6845 sal_Bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
6846 if ( mpWindowImpl->mpBorderWindow )
6847 {
6848 mpWindowImpl->mpBorderWindow->EnableInput( bEnable, sal_False );
6849 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
6850 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
6851 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, sal_True );
6852 }
6853
6854 if ( (! bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) ||
6855 ( bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled) )
6856 {
6857 // Wenn ein Fenster disabled wird, wird automatisch der
6858 // Tracking-Modus beendet oder der Capture geklaut
6859 if ( !bEnable )
6860 {
6861 if ( IsTracking() )
6862 EndTracking( ENDTRACK_CANCEL );
6863 if ( IsMouseCaptured() )
6864 ReleaseMouse();
6865 }
6866
6867 if ( mpWindowImpl->mbInputDisabled != !bEnable )
6868 {
6869 mpWindowImpl->mbInputDisabled = !bEnable;
6870 if ( mpWindowImpl->mpSysObj )
6871 mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
6872 // if ( mpWindowImpl->mbFrame )
6873 // mpWindowImpl->mpFrame->Enable( !mpWindowImpl->mbDisabled && bEnable );
6874 }
6875 }
6876
6877 // #i56102# restore app focus win in case the
6878 // window was disabled when the frame focus changed
6879 ImplSVData* pSVData = ImplGetSVData();
6880 if( bEnable &&
6881 pSVData->maWinData.mpFocusWin == NULL &&
6882 mpWindowImpl->mpFrameData->mbHasFocus &&
6883 mpWindowImpl->mpFrameData->mpFocusWin == this )
6884 pSVData->maWinData.mpFocusWin = this;
6885
6886 if ( bChild || mpWindowImpl->mbChildNotify )
6887 {
6888 Window* pChild = mpWindowImpl->mpFirstChild;
6889 while ( pChild )
6890 {
6891 pChild->EnableInput( bEnable, bChild );
6892 pChild = pChild->mpWindowImpl->mpNext;
6893 }
6894 }
6895
6896 if ( IsReallyVisible() )
6897 ImplGenerateMouseMove();
6898
6899 // #104827# notify parent
6900 if ( bNotify )
6901 {
6902 NotifyEvent aNEvt( bEnable ? EVENT_INPUTENABLE : EVENT_INPUTDISABLE, this );
6903 Notify( aNEvt );
6904 }
6905 }
6906
6907 // -----------------------------------------------------------------------
6908
EnableInput(sal_Bool bEnable,sal_Bool bChild,sal_Bool bSysWin,const Window * pExcludeWindow)6909 void Window::EnableInput( sal_Bool bEnable, sal_Bool bChild, sal_Bool bSysWin,
6910 const Window* pExcludeWindow )
6911 {
6912 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6913
6914 EnableInput( bEnable, bChild );
6915 if ( bSysWin )
6916 {
6917 // pExculeWindow is the first Overlap-Frame --> if this
6918 // shouldn't be the case, than this must be changed in dialog.cxx
6919 if( pExcludeWindow )
6920 pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
6921 Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
6922 while ( pSysWin )
6923 {
6924 // Is Window in the path from this window
6925 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, sal_True ) )
6926 {
6927 // Is Window not in the exclude window path or not the
6928 // exclude window, than change the status
6929 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, sal_True ) )
6930 pSysWin->EnableInput( bEnable, bChild );
6931 }
6932 pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
6933 }
6934
6935 // enable/disable floating system windows as well
6936 Window* pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
6937 while ( pFrameWin )
6938 {
6939 if( pFrameWin->ImplIsFloatingWindow() )
6940 {
6941 // Is Window in the path from this window
6942 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, sal_True ) )
6943 {
6944 // Is Window not in the exclude window path or not the
6945 // exclude window, than change the status
6946 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, sal_True ) )
6947 pFrameWin->EnableInput( bEnable, bChild );
6948 }
6949 }
6950 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
6951 }
6952
6953 // the same for ownerdraw floating windows
6954 if( mpWindowImpl->mbFrame )
6955 {
6956 ::std::vector< Window* >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
6957 ::std::vector< Window* >::iterator p = rList.begin();
6958 while( p != rList.end() )
6959 {
6960 // Is Window in the path from this window
6961 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( (*p), sal_True ) )
6962 {
6963 // Is Window not in the exclude window path or not the
6964 // exclude window, than change the status
6965 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( (*p), sal_True ) )
6966 (*p)->EnableInput( bEnable, bChild );
6967 }
6968 p++;
6969 }
6970 }
6971 }
6972 }
6973
6974 // -----------------------------------------------------------------------
6975
AlwaysEnableInput(sal_Bool bAlways,sal_Bool bChild)6976 void Window::AlwaysEnableInput( sal_Bool bAlways, sal_Bool bChild )
6977 {
6978 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6979
6980 if ( mpWindowImpl->mpBorderWindow )
6981 mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, sal_False );
6982
6983 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
6984 {
6985 mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
6986
6987 if ( bAlways )
6988 EnableInput( sal_True, sal_False );
6989 }
6990 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
6991 {
6992 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
6993 }
6994
6995 if ( bChild || mpWindowImpl->mbChildNotify )
6996 {
6997 Window* pChild = mpWindowImpl->mpFirstChild;
6998 while ( pChild )
6999 {
7000 pChild->AlwaysEnableInput( bAlways, bChild );
7001 pChild = pChild->mpWindowImpl->mpNext;
7002 }
7003 }
7004 }
7005
7006 // -----------------------------------------------------------------------
7007
AlwaysDisableInput(sal_Bool bAlways,sal_Bool bChild)7008 void Window::AlwaysDisableInput( sal_Bool bAlways, sal_Bool bChild )
7009 {
7010 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7011
7012 if ( mpWindowImpl->mpBorderWindow )
7013 mpWindowImpl->mpBorderWindow->AlwaysDisableInput( bAlways, sal_False );
7014
7015 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled )
7016 {
7017 mpWindowImpl->meAlwaysInputMode = AlwaysInputDisabled;
7018
7019 if ( bAlways )
7020 EnableInput( sal_False, sal_False );
7021 }
7022 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled )
7023 {
7024 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
7025 }
7026
7027 if ( bChild || mpWindowImpl->mbChildNotify )
7028 {
7029 Window* pChild = mpWindowImpl->mpFirstChild;
7030 while ( pChild )
7031 {
7032 pChild->AlwaysDisableInput( bAlways, bChild );
7033 pChild = pChild->mpWindowImpl->mpNext;
7034 }
7035 }
7036 }
7037
7038 // -----------------------------------------------------------------------
7039
SetActivateMode(sal_uInt16 nMode)7040 void Window::SetActivateMode( sal_uInt16 nMode )
7041 {
7042 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7043
7044 if ( mpWindowImpl->mpBorderWindow )
7045 mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
7046
7047 if ( mpWindowImpl->mnActivateMode != nMode )
7048 {
7049 mpWindowImpl->mnActivateMode = nMode;
7050
7051 // Evtl. ein Decativate/Activate ausloesen
7052 if ( mpWindowImpl->mnActivateMode )
7053 {
7054 if ( (mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW)) &&
7055 !HasChildPathFocus( sal_True ) )
7056 {
7057 mpWindowImpl->mbActive = sal_False;
7058 Deactivate();
7059 }
7060 }
7061 else
7062 {
7063 if ( !mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW) )
7064 {
7065 mpWindowImpl->mbActive = sal_True;
7066 Activate();
7067 }
7068 }
7069 }
7070 }
7071
7072 // -----------------------------------------------------------------------
7073
ToTop(sal_uInt16 nFlags)7074 void Window::ToTop( sal_uInt16 nFlags )
7075 {
7076 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7077
7078 ImplStartToTop( nFlags );
7079 ImplFocusToTop( nFlags, IsReallyVisible() );
7080 }
7081
7082 // -----------------------------------------------------------------------
7083
SetZOrder(Window * pRefWindow,sal_uInt16 nFlags)7084 void Window::SetZOrder( Window* pRefWindow, sal_uInt16 nFlags )
7085 {
7086 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7087
7088 if ( mpWindowImpl->mpBorderWindow )
7089 {
7090 mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
7091 return;
7092 }
7093
7094 if ( nFlags & WINDOW_ZORDER_FIRST )
7095 {
7096 if ( ImplIsOverlapWindow() )
7097 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
7098 else
7099 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
7100 nFlags |= WINDOW_ZORDER_BEFOR;
7101 }
7102 else if ( nFlags & WINDOW_ZORDER_LAST )
7103 {
7104 if ( ImplIsOverlapWindow() )
7105 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
7106 else
7107 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
7108 nFlags |= WINDOW_ZORDER_BEHIND;
7109 }
7110
7111 while ( pRefWindow->mpWindowImpl->mpBorderWindow )
7112 pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
7113 if ( (pRefWindow == this) || mpWindowImpl->mbFrame )
7114 return;
7115
7116 DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" );
7117 if ( nFlags & WINDOW_ZORDER_BEFOR )
7118 {
7119 if ( pRefWindow->mpWindowImpl->mpPrev == this )
7120 return;
7121
7122 if ( ImplIsOverlapWindow() )
7123 {
7124 if ( mpWindowImpl->mpPrev )
7125 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7126 else
7127 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
7128 if ( mpWindowImpl->mpNext )
7129 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7130 else
7131 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
7132 if ( !pRefWindow->mpWindowImpl->mpPrev )
7133 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
7134 }
7135 else
7136 {
7137 if ( mpWindowImpl->mpPrev )
7138 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7139 else
7140 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
7141 if ( mpWindowImpl->mpNext )
7142 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7143 else
7144 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
7145 if ( !pRefWindow->mpWindowImpl->mpPrev )
7146 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
7147 }
7148
7149 mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev;
7150 mpWindowImpl->mpNext = pRefWindow;
7151 if ( mpWindowImpl->mpPrev )
7152 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
7153 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
7154 }
7155 else if ( nFlags & WINDOW_ZORDER_BEHIND )
7156 {
7157 if ( pRefWindow->mpWindowImpl->mpNext == this )
7158 return;
7159
7160 if ( ImplIsOverlapWindow() )
7161 {
7162 if ( mpWindowImpl->mpPrev )
7163 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7164 else
7165 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
7166 if ( mpWindowImpl->mpNext )
7167 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7168 else
7169 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
7170 if ( !pRefWindow->mpWindowImpl->mpNext )
7171 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
7172 }
7173 else
7174 {
7175 if ( mpWindowImpl->mpPrev )
7176 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7177 else
7178 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
7179 if ( mpWindowImpl->mpNext )
7180 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7181 else
7182 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
7183 if ( !pRefWindow->mpWindowImpl->mpNext )
7184 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
7185 }
7186
7187 mpWindowImpl->mpPrev = pRefWindow;
7188 mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
7189 if ( mpWindowImpl->mpNext )
7190 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
7191 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
7192 }
7193
7194 if ( IsReallyVisible() )
7195 {
7196 // Hintergrund-Sicherung zuruecksetzen
7197 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
7198 ImplInvalidateAllOverlapBackgrounds();
7199
7200 if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
7201 {
7202 sal_Bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion;
7203 ImplSetClipFlag();
7204
7205 // Wenn ClipRegion noch nicht initialisiert wurde, dann
7206 // gehen wir davon aus, das das Fenster noch nicht
7207 // ausgegeben wurde und loesen somit auch keine
7208 // Invalidates aus. Dies ist eine Optimierung fuer
7209 // HTML-Dokumenten mit vielen Controls. Wenn es mal
7210 // Probleme mit dieser Abfrage gibt, sollte man ein
7211 // Flag einfuehren, ob das Fenster nach Show schon
7212 // einmal ausgegeben wurde.
7213 if ( !bInitWinClipRegion )
7214 {
7215 // Alle nebeneinanderliegenden Fenster invalidieren
7216 // Noch nicht komplett implementiert !!!
7217 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
7218 Window* pWindow = NULL;
7219 if ( ImplIsOverlapWindow() )
7220 {
7221 if ( mpWindowImpl->mpOverlapWindow )
7222 pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
7223 }
7224 else
7225 pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
7226 // Alle Fenster, die vor uns liegen und von uns verdeckt wurden,
7227 // invalidieren
7228 while ( pWindow )
7229 {
7230 if ( pWindow == this )
7231 break;
7232 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
7233 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
7234 if ( aWinRect.IsOver( aCompRect ) )
7235 pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
7236 pWindow = pWindow->mpWindowImpl->mpNext;
7237 }
7238 // Wenn uns ein Fenster, welches im Hinterund liegt verdeckt hat,
7239 // dann muessen wir uns neu ausgeben
7240 while ( pWindow )
7241 {
7242 if ( pWindow != this )
7243 {
7244 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
7245 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
7246 if ( aWinRect.IsOver( aCompRect ) )
7247 {
7248 Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
7249 break;
7250 }
7251 }
7252 pWindow = pWindow->mpWindowImpl->mpNext;
7253 }
7254 }
7255 }
7256 }
7257 }
7258
7259 // -----------------------------------------------------------------------
7260
EnableAlwaysOnTop(sal_Bool bEnable)7261 void Window::EnableAlwaysOnTop( sal_Bool bEnable )
7262 {
7263 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7264
7265 mpWindowImpl->mbAlwaysOnTop = bEnable;
7266
7267 if ( mpWindowImpl->mpBorderWindow )
7268 mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable );
7269 else if ( bEnable && IsReallyVisible() )
7270 ToTop();
7271
7272 if ( mpWindowImpl->mbFrame )
7273 mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable );
7274 }
7275
7276 // -----------------------------------------------------------------------
7277
SetPosSizePixel(long nX,long nY,long nWidth,long nHeight,sal_uInt16 nFlags)7278 void Window::SetPosSizePixel( long nX, long nY,
7279 long nWidth, long nHeight, sal_uInt16 nFlags )
7280 {
7281 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7282
7283 sal_Bool bHasValidSize = !mpWindowImpl->mbDefSize;
7284
7285 if ( nFlags & WINDOW_POSSIZE_POS )
7286 mpWindowImpl->mbDefPos = sal_False;
7287 if ( nFlags & WINDOW_POSSIZE_SIZE )
7288 mpWindowImpl->mbDefSize = sal_False;
7289
7290 // Oberstes BorderWindow ist das Window, welches positioniert werden soll
7291 Window* pWindow = this;
7292 while ( pWindow->mpWindowImpl->mpBorderWindow )
7293 pWindow = pWindow->mpWindowImpl->mpBorderWindow;
7294
7295 if ( pWindow->mpWindowImpl->mbFrame )
7296 {
7297 // Note: if we're positioning a frame, the coordinates are interpreted
7298 // as being the top-left corner of the window's client area and NOT
7299 // as the position of the border ! (due to limitations of several UNIX window managers)
7300 long nOldWidth = pWindow->mnOutWidth;
7301
7302 if ( !(nFlags & WINDOW_POSSIZE_WIDTH) )
7303 nWidth = pWindow->mnOutWidth;
7304 if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) )
7305 nHeight = pWindow->mnOutHeight;
7306
7307
7308 sal_uInt16 nSysFlags=0;
7309 if( nFlags & WINDOW_POSSIZE_WIDTH )
7310 nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
7311 if( nFlags & WINDOW_POSSIZE_HEIGHT )
7312 nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
7313 if( nFlags & WINDOW_POSSIZE_X )
7314 {
7315 nSysFlags |= SAL_FRAME_POSSIZE_X;
7316 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
7317 {
7318 Window* pParent = pWindow->GetParent();
7319 nX += pParent->mnOutOffX;
7320 }
7321 if( GetParent() && GetParent()->ImplIsAntiparallel() )
7322 {
7323 // --- RTL --- (re-mirror at parent window)
7324 Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
7325 GetParent()->ImplReMirror( aRect );
7326 nX = aRect.nLeft;
7327 }
7328 }
7329 if( !(nFlags & WINDOW_POSSIZE_X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth )
7330 {
7331 // --- RTL --- make sure the old right aligned position is not changed
7332 // system windows will always grow to the right
7333 if( pWindow->GetParent() && pWindow->GetParent()->ImplHasMirroredGraphics() )
7334 {
7335 long myWidth = nOldWidth;
7336 if( !myWidth )
7337 myWidth = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth;
7338 if( !myWidth )
7339 myWidth = nWidth;
7340 nFlags |= WINDOW_POSSIZE_X;
7341 nSysFlags |= SAL_FRAME_POSSIZE_X;
7342 nX = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX -
7343 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration;
7344 nX = pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration +
7345 pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth - myWidth - 1 - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX;
7346 if(!(nFlags & WINDOW_POSSIZE_Y))
7347 {
7348 nFlags |= WINDOW_POSSIZE_Y;
7349 nSysFlags |= SAL_FRAME_POSSIZE_Y;
7350 nY = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY -
7351 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nTopDecoration;
7352 }
7353 }
7354 }
7355 if( nFlags & WINDOW_POSSIZE_Y )
7356 {
7357 nSysFlags |= SAL_FRAME_POSSIZE_Y;
7358 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
7359 {
7360 Window* pParent = pWindow->GetParent();
7361 nY += pParent->mnOutOffY;
7362 }
7363 }
7364
7365 if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
7366 {
7367 // check for min/max client size and adjust size accordingly
7368 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
7369 // unchanged but ImplHandleResize() is called with the wrong size
7370 SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow );
7371 if( pSystemWindow )
7372 {
7373 Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
7374 Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
7375 if( nWidth < aMinSize.Width() )
7376 nWidth = aMinSize.Width();
7377 if( nHeight < aMinSize.Height() )
7378 nHeight = aMinSize.Height();
7379
7380 if( nWidth > aMaxSize.Width() )
7381 nWidth = aMaxSize.Width();
7382 if( nHeight > aMaxSize.Height() )
7383 nHeight = aMaxSize.Height();
7384 }
7385 }
7386
7387 pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
7388
7389 // Resize should be called directly. If we haven't
7390 // set the correct size, we get a second resize from
7391 // the system with the correct size. This can happen
7392 // if the size is to small or to large.
7393 ImplHandleResize( pWindow, nWidth, nHeight );
7394 }
7395 else
7396 {
7397 pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
7398 if ( IsReallyVisible() )
7399 ImplGenerateMouseMove();
7400 }
7401 }
7402
7403 // -----------------------------------------------------------------------
7404
GetPosPixel() const7405 Point Window::GetPosPixel() const
7406 {
7407 return mpWindowImpl->maPos;
7408 }
7409
7410 // -----------------------------------------------------------------------
7411
GetDesktopRectPixel() const7412 Rectangle Window::GetDesktopRectPixel() const
7413 {
7414 Rectangle rRect;
7415 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
7416 return rRect;
7417 }
7418
7419 // -----------------------------------------------------------------------
7420
OutputToScreenPixel(const Point & rPos) const7421 Point Window::OutputToScreenPixel( const Point& rPos ) const
7422 {
7423 // relative to top level parent
7424 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
7425 }
7426
7427 // -----------------------------------------------------------------------
7428
ScreenToOutputPixel(const Point & rPos) const7429 Point Window::ScreenToOutputPixel( const Point& rPos ) const
7430 {
7431 // relative to top level parent
7432 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
7433 }
7434
7435 // -----------------------------------------------------------------------
7436
ImplGetUnmirroredOutOffX()7437 long Window::ImplGetUnmirroredOutOffX()
7438 {
7439 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
7440 long offx = mnOutOffX;
7441 if( ImplHasMirroredGraphics() )
7442 {
7443 if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
7444 {
7445 if ( !ImplIsOverlapWindow() )
7446 offx -= mpWindowImpl->mpParent->mnOutOffX;
7447
7448 offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx;
7449
7450 if ( !ImplIsOverlapWindow() )
7451 offx += mpWindowImpl->mpParent->mnOutOffX;
7452
7453 }
7454 }
7455 return offx;
7456 }
7457
7458 // normalized screen pixel are independent of mirroring
OutputToNormalizedScreenPixel(const Point & rPos) const7459 Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
7460 {
7461 // relative to top level parent
7462 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
7463 return Point( rPos.X()+offx, rPos.Y()+mnOutOffY );
7464 }
7465
NormalizedScreenToOutputPixel(const Point & rPos) const7466 Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
7467 {
7468 // relative to top level parent
7469 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
7470 return Point( rPos.X()-offx, rPos.Y()-mnOutOffY );
7471 }
7472
7473 // -----------------------------------------------------------------------
7474
OutputToAbsoluteScreenPixel(const Point & rPos) const7475 Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
7476 {
7477 // relative to the screen
7478 Point p = OutputToScreenPixel( rPos );
7479 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7480 p.X() += g.nX;
7481 p.Y() += g.nY;
7482 return p;
7483 }
7484
7485 // -----------------------------------------------------------------------
7486
AbsoluteScreenToOutputPixel(const Point & rPos) const7487 Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const
7488 {
7489 // relative to the screen
7490 Point p = ScreenToOutputPixel( rPos );
7491 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7492 p.X() -= g.nX;
7493 p.Y() -= g.nY;
7494 return p;
7495 }
7496
7497 // -----------------------------------------------------------------------
7498
ImplOutputToUnmirroredAbsoluteScreenPixel(const Rectangle & rRect) const7499 Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle &rRect ) const
7500 {
7501 // this method creates unmirrored screen coordinates to be compared with the desktop
7502 // and is used for positioning of RTL popup windows correctly on the screen
7503 SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
7504
7505 Point p1 = OutputToScreenPixel( rRect.TopRight() );
7506 p1.X() = g.nX+g.nWidth-p1.X();
7507 p1.Y() += g.nY;
7508
7509 Point p2 = OutputToScreenPixel( rRect.BottomLeft() );
7510 p2.X() = g.nX+g.nWidth-p2.X();
7511 p2.Y() += g.nY;
7512
7513 return Rectangle( p1, p2 );
7514 }
7515
7516
7517 // -----------------------------------------------------------------------
7518
GetWindowExtentsRelative(Window * pRelativeWindow) const7519 Rectangle Window::GetWindowExtentsRelative( Window *pRelativeWindow ) const
7520 {
7521 // with decoration
7522 return ImplGetWindowExtentsRelative( pRelativeWindow, sal_False );
7523 }
7524
GetClientWindowExtentsRelative(Window * pRelativeWindow) const7525 Rectangle Window::GetClientWindowExtentsRelative( Window *pRelativeWindow ) const
7526 {
7527 // without decoration
7528 return ImplGetWindowExtentsRelative( pRelativeWindow, sal_True );
7529 }
7530
7531 // -----------------------------------------------------------------------
7532
ImplGetWindowExtentsRelative(Window * pRelativeWindow,sal_Bool bClientOnly) const7533 Rectangle Window::ImplGetWindowExtentsRelative( Window *pRelativeWindow, sal_Bool bClientOnly ) const
7534 {
7535 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7536 // make sure we use the extent of our border window,
7537 // otherwise we miss a few pixels
7538 const Window *pWin = (!bClientOnly && mpWindowImpl->mpBorderWindow) ? mpWindowImpl->mpBorderWindow : this;
7539
7540 Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) );
7541 aPos.X() += g.nX;
7542 aPos.Y() += g.nY;
7543 Size aSize ( pWin->GetSizePixel() );
7544 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
7545 if( !bClientOnly && (mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WINDOW_WORKWINDOW)) )
7546 {
7547 aPos.X() -= g.nLeftDecoration;
7548 aPos.Y() -= g.nTopDecoration;
7549 aSize.Width() += g.nLeftDecoration + g.nRightDecoration;
7550 aSize.Height() += g.nTopDecoration + g.nBottomDecoration;
7551 }
7552 if( pRelativeWindow )
7553 {
7554 // #106399# express coordinates relative to borderwindow
7555 Window *pRelWin = (!bClientOnly && pRelativeWindow->mpWindowImpl->mpBorderWindow) ? pRelativeWindow->mpWindowImpl->mpBorderWindow : pRelativeWindow;
7556 aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos );
7557 }
7558 return Rectangle( aPos, aSize );
7559 }
7560
7561 // -----------------------------------------------------------------------
7562
Scroll(long nHorzScroll,long nVertScroll,sal_uInt16 nFlags)7563 void Window::Scroll( long nHorzScroll, long nVertScroll, sal_uInt16 nFlags )
7564 {
7565 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7566
7567 ImplScroll( Rectangle( Point( mnOutOffX, mnOutOffY ),
7568 Size( mnOutWidth, mnOutHeight ) ),
7569 nHorzScroll, nVertScroll, nFlags & ~SCROLL_CLIP );
7570 }
7571
7572 // -----------------------------------------------------------------------
7573
Scroll(long nHorzScroll,long nVertScroll,const Rectangle & rRect,sal_uInt16 nFlags)7574 void Window::Scroll( long nHorzScroll, long nVertScroll,
7575 const Rectangle& rRect, sal_uInt16 nFlags )
7576 {
7577 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7578
7579 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7580 aRect.Intersection( Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) );
7581 if ( !aRect.IsEmpty() )
7582 ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
7583 }
7584
7585 // -----------------------------------------------------------------------
7586
Invalidate(sal_uInt16 nFlags)7587 void Window::Invalidate( sal_uInt16 nFlags )
7588 {
7589 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7590
7591 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7592 return;
7593
7594 ImplInvalidate( NULL, nFlags );
7595 }
7596
7597 // -----------------------------------------------------------------------
7598
Invalidate(const Rectangle & rRect,sal_uInt16 nFlags)7599 void Window::Invalidate( const Rectangle& rRect, sal_uInt16 nFlags )
7600 {
7601 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7602
7603 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7604 return;
7605
7606 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7607 if ( !aRect.IsEmpty() )
7608 {
7609 Region aRegion( aRect );
7610 ImplInvalidate( &aRegion, nFlags );
7611 }
7612 }
7613
7614 // -----------------------------------------------------------------------
7615
Invalidate(const Region & rRegion,sal_uInt16 nFlags)7616 void Window::Invalidate( const Region& rRegion, sal_uInt16 nFlags )
7617 {
7618 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7619
7620 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7621 return;
7622
7623 if ( rRegion.IsNull() )
7624 ImplInvalidate( NULL, nFlags );
7625 else
7626 {
7627 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
7628 if ( !aRegion.IsEmpty() )
7629 ImplInvalidate( &aRegion, nFlags );
7630 }
7631 }
7632
7633 // -----------------------------------------------------------------------
7634
Validate(sal_uInt16 nFlags)7635 void Window::Validate( sal_uInt16 nFlags )
7636 {
7637 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7638
7639 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7640 return;
7641
7642 ImplValidate( NULL, nFlags );
7643 }
7644
7645 // -----------------------------------------------------------------------
7646
Validate(const Rectangle & rRect,sal_uInt16 nFlags)7647 void Window::Validate( const Rectangle& rRect, sal_uInt16 nFlags )
7648 {
7649 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7650
7651 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7652 return;
7653
7654 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7655 if ( !aRect.IsEmpty() )
7656 {
7657 Region aRegion( aRect );
7658 ImplValidate( &aRegion, nFlags );
7659 }
7660 }
7661
7662 // -----------------------------------------------------------------------
7663
Validate(const Region & rRegion,sal_uInt16 nFlags)7664 void Window::Validate( const Region& rRegion, sal_uInt16 nFlags )
7665 {
7666 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7667
7668 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7669 return;
7670
7671 if ( rRegion.IsNull() )
7672 ImplValidate( NULL, nFlags );
7673 else
7674 {
7675 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
7676 if ( !aRegion.IsEmpty() )
7677 ImplValidate( &aRegion, nFlags );
7678 }
7679 }
7680
7681 // -----------------------------------------------------------------------
7682
HasPaintEvent() const7683 sal_Bool Window::HasPaintEvent() const
7684 {
7685 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7686
7687 if ( !mpWindowImpl->mbReallyVisible )
7688 return sal_False;
7689
7690 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
7691 return sal_True;
7692
7693 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
7694 return sal_True;
7695
7696 if ( !ImplIsOverlapWindow() )
7697 {
7698 const Window* pTempWindow = this;
7699 do
7700 {
7701 pTempWindow = pTempWindow->ImplGetParent();
7702 if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDS | IMPL_PAINT_PAINTALLCHILDS) )
7703 return sal_True;
7704 }
7705 while ( !pTempWindow->ImplIsOverlapWindow() );
7706 }
7707
7708 return sal_False;
7709 }
7710
7711 // -----------------------------------------------------------------------
7712
Update()7713 void Window::Update()
7714 {
7715 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7716
7717 if ( mpWindowImpl->mpBorderWindow )
7718 {
7719 mpWindowImpl->mpBorderWindow->Update();
7720 return;
7721 }
7722
7723 if ( !mpWindowImpl->mbReallyVisible )
7724 return;
7725
7726 sal_Bool bFlush = sal_False;
7727 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
7728 {
7729 Point aPoint( 0, 0 );
7730 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
7731 ImplInvalidateOverlapFrameRegion( aRegion );
7732 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
7733 bFlush = sal_True;
7734 }
7735
7736 // Zuerst muessen wir alle Fenster ueberspringen, die Paint-Transparent
7737 // sind
7738 Window* pUpdateWindow = this;
7739 Window* pWindow = pUpdateWindow;
7740 while ( !pWindow->ImplIsOverlapWindow() )
7741 {
7742 if ( !pWindow->mpWindowImpl->mbPaintTransparent )
7743 {
7744 pUpdateWindow = pWindow;
7745 break;
7746 }
7747 pWindow = pWindow->ImplGetParent();
7748 }
7749 // Ein Update wirkt immer auf das Window, wo PAINTALLCHILDS gesetzt
7750 // ist, damit nicht zuviel gemalt wird
7751 pWindow = pUpdateWindow;
7752 do
7753 {
7754 if ( pWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
7755 pUpdateWindow = pWindow;
7756 if ( pWindow->ImplIsOverlapWindow() )
7757 break;
7758 pWindow = pWindow->ImplGetParent();
7759 }
7760 while ( pWindow );
7761
7762 // Wenn es etwas zu malen gibt, dann ein Paint ausloesen
7763 if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
7764 {
7765 // und fuer alle ueber uns stehende System-Fenster auch ein Update
7766 // ausloesen, damit nicht die ganze Zeit Luecken stehen bleiben
7767 Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap;
7768 while ( pUpdateOverlapWindow )
7769 {
7770 pUpdateOverlapWindow->Update();
7771 pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
7772 }
7773
7774 pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags );
7775 }
7776
7777 if ( bFlush )
7778 Flush();
7779 }
7780
7781 // -----------------------------------------------------------------------
7782
Flush()7783 void Window::Flush()
7784 {
7785 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7786
7787 const Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
7788 mpWindowImpl->mpFrame->Flush( aWinRect );
7789 }
7790
7791 // -----------------------------------------------------------------------
7792
Sync()7793 void Window::Sync()
7794 {
7795 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7796
7797 mpWindowImpl->mpFrame->Sync();
7798 }
7799
7800 // -----------------------------------------------------------------------
7801
SetUpdateMode(sal_Bool bUpdate)7802 void Window::SetUpdateMode( sal_Bool bUpdate )
7803 {
7804 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7805
7806 mpWindowImpl->mbNoUpdate = !bUpdate;
7807 StateChanged( STATE_CHANGE_UPDATEMODE );
7808 }
7809
7810 // -----------------------------------------------------------------------
7811
GrabFocus()7812 void Window::GrabFocus()
7813 {
7814 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7815
7816 ImplGrabFocus( 0 );
7817 }
7818
7819 // -----------------------------------------------------------------------
7820
HasFocus() const7821 sal_Bool Window::HasFocus() const
7822 {
7823 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7824
7825 // #107575# the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
7826 // task was shifted to 6.y, so its commented out
7827 /*
7828 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
7829 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
7830 pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
7831 else
7832 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7833
7834 return (this == pFocusWin);
7835 */
7836
7837 return (this == ImplGetSVData()->maWinData.mpFocusWin);
7838 }
7839
7840 // -----------------------------------------------------------------------
7841
GrabFocusToDocument()7842 void Window::GrabFocusToDocument()
7843 {
7844 Window *pWin = this;
7845 while( pWin )
7846 {
7847 if( !pWin->GetParent() )
7848 {
7849 pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
7850 return;
7851 }
7852 pWin = pWin->GetParent();
7853 }
7854 }
7855
SetFakeFocus(bool bFocus)7856 void Window::SetFakeFocus( bool bFocus )
7857 {
7858 ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
7859 }
7860
7861 // -----------------------------------------------------------------------
7862
HasChildPathFocus(sal_Bool bSystemWindow) const7863 sal_Bool Window::HasChildPathFocus( sal_Bool bSystemWindow ) const
7864 {
7865 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7866
7867 // #107575#, the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
7868 // task was shifted to 6.y, so it's commented out
7869 /*
7870 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
7871 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
7872 pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
7873 else
7874 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7875 */
7876 Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7877 if ( pFocusWin )
7878 return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
7879 return sal_False;
7880 }
7881
7882 // -----------------------------------------------------------------------
7883
CaptureMouse()7884 void Window::CaptureMouse()
7885 {
7886 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7887
7888 ImplSVData* pSVData = ImplGetSVData();
7889
7890 // Tracking evt. beenden
7891 if ( pSVData->maWinData.mpTrackWin != this )
7892 {
7893 if ( pSVData->maWinData.mpTrackWin )
7894 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
7895 }
7896
7897 if ( pSVData->maWinData.mpCaptureWin != this )
7898 {
7899 pSVData->maWinData.mpCaptureWin = this;
7900 mpWindowImpl->mpFrame->CaptureMouse( sal_True );
7901 }
7902 }
7903
7904 // -----------------------------------------------------------------------
7905
ReleaseMouse()7906 void Window::ReleaseMouse()
7907 {
7908 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7909
7910 ImplSVData* pSVData = ImplGetSVData();
7911
7912 DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this,
7913 "Window::ReleaseMouse(): window doesn't have the mouse capture" );
7914
7915 if ( pSVData->maWinData.mpCaptureWin == this )
7916 {
7917 pSVData->maWinData.mpCaptureWin = NULL;
7918 mpWindowImpl->mpFrame->CaptureMouse( sal_False );
7919 ImplGenerateMouseMove();
7920 }
7921 }
7922
7923 // -----------------------------------------------------------------------
7924
IsMouseCaptured() const7925 sal_Bool Window::IsMouseCaptured() const
7926 {
7927 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7928
7929 return (this == ImplGetSVData()->maWinData.mpCaptureWin);
7930 }
7931
7932 // -----------------------------------------------------------------------
7933
SetPointer(const Pointer & rPointer)7934 void Window::SetPointer( const Pointer& rPointer )
7935 {
7936 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7937
7938 if ( mpWindowImpl->maPointer == rPointer )
7939 return;
7940
7941 mpWindowImpl->maPointer = rPointer;
7942
7943 // Pointer evt. direkt umsetzen
7944 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7945 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7946 }
7947
7948 // -----------------------------------------------------------------------
7949
EnableChildPointerOverwrite(sal_Bool bOverwrite)7950 void Window::EnableChildPointerOverwrite( sal_Bool bOverwrite )
7951 {
7952 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7953
7954 if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
7955 return;
7956
7957 mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
7958
7959 // Pointer evt. direkt umsetzen
7960 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7961 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7962 }
7963
7964 // -----------------------------------------------------------------------
7965
SetPointerPosPixel(const Point & rPos)7966 void Window::SetPointerPosPixel( const Point& rPos )
7967 {
7968 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7969
7970 Point aPos = ImplOutputToFrame( rPos );
7971 if( ImplHasMirroredGraphics() )
7972 {
7973 if( !IsRTLEnabled() )
7974 {
7975 // --- RTL --- (re-mirror mouse pos at this window)
7976 ImplReMirror( aPos );
7977 }
7978 // mirroring is required here, SetPointerPos bypasses SalGraphics
7979 mpGraphics->mirror( aPos.X(), this );
7980 }
7981 else if( ImplIsAntiparallel() )
7982 {
7983 ImplReMirror( aPos );
7984 }
7985 mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
7986 }
7987
7988 // -----------------------------------------------------------------------
7989
GetPointerPosPixel()7990 Point Window::GetPointerPosPixel()
7991 {
7992 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7993
7994 Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
7995 if( ImplIsAntiparallel() )
7996 {
7997 // --- RTL --- (re-mirror mouse pos at this window)
7998 ImplReMirror( aPos );
7999 }
8000 return ImplFrameToOutput( aPos );
8001 }
8002
8003 // -----------------------------------------------------------------------
8004
GetLastPointerPosPixel()8005 Point Window::GetLastPointerPosPixel()
8006 {
8007 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8008
8009 Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
8010 if( ImplIsAntiparallel() )
8011 {
8012 // --- RTL --- (re-mirror mouse pos at this window)
8013 ImplReMirror( aPos );
8014 }
8015 return ImplFrameToOutput( aPos );
8016 }
8017
8018 // -----------------------------------------------------------------------
8019
ShowPointer(sal_Bool bVisible)8020 void Window::ShowPointer( sal_Bool bVisible )
8021 {
8022 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8023
8024 if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
8025 {
8026 mpWindowImpl->mbNoPtrVisible = !bVisible;
8027
8028 // Pointer evt. direkt umsetzen
8029 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
8030 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
8031 }
8032 }
8033
8034 // -----------------------------------------------------------------------
8035
GetPointerState()8036 Window::PointerState Window::GetPointerState()
8037 {
8038 PointerState aState;
8039 aState.mnState = 0;
8040
8041 if (mpWindowImpl->mpFrame)
8042 {
8043 SalFrame::SalPointerState aSalPointerState;
8044
8045 aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
8046 if( ImplIsAntiparallel() )
8047 {
8048 // --- RTL --- (re-mirror mouse pos at this window)
8049 ImplReMirror( aSalPointerState.maPos );
8050 }
8051 aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
8052 aState.mnState = aSalPointerState.mnState;
8053 }
8054 return aState;
8055 }
8056
8057 // -----------------------------------------------------------------------
8058
IsMouseOver()8059 sal_Bool Window::IsMouseOver()
8060 {
8061 return ImplGetWinData()->mbMouseOver;
8062 }
8063
8064 // -----------------------------------------------------------------------
8065
EnterWait()8066 void Window::EnterWait()
8067 {
8068 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8069
8070 mpWindowImpl->mnWaitCount++;
8071
8072 if ( mpWindowImpl->mnWaitCount == 1 )
8073 {
8074 // Pointer evt. direkt umsetzen
8075 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
8076 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
8077 }
8078 }
8079
8080 // -----------------------------------------------------------------------
8081
LeaveWait()8082 void Window::LeaveWait()
8083 {
8084 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8085
8086 if ( mpWindowImpl->mnWaitCount )
8087 {
8088 mpWindowImpl->mnWaitCount--;
8089
8090 if ( !mpWindowImpl->mnWaitCount )
8091 {
8092 // Pointer evt. direkt umsetzen
8093 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
8094 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
8095 }
8096 }
8097 }
8098
8099 // -----------------------------------------------------------------------
8100
SetCursor(Cursor * pCursor)8101 void Window::SetCursor( Cursor* pCursor )
8102 {
8103 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8104
8105 if ( mpWindowImpl->mpCursor != pCursor )
8106 {
8107 if ( mpWindowImpl->mpCursor )
8108 mpWindowImpl->mpCursor->ImplHide( true );
8109 mpWindowImpl->mpCursor = pCursor;
8110 if ( pCursor )
8111 pCursor->ImplShow();
8112 }
8113 }
8114
8115 // -----------------------------------------------------------------------
8116
SetText(const XubString & rStr)8117 void Window::SetText( const XubString& rStr )
8118 {
8119 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8120
8121 String oldTitle( mpWindowImpl->maText );
8122 mpWindowImpl->maText = rStr;
8123
8124 if ( mpWindowImpl->mpBorderWindow )
8125 mpWindowImpl->mpBorderWindow->SetText( rStr );
8126 else if ( mpWindowImpl->mbFrame )
8127 mpWindowImpl->mpFrame->SetTitle( rStr );
8128
8129 ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
8130
8131 // #107247# needed for accessibility
8132 // The VCLEVENT_WINDOW_FRAMETITLECHANGED is (mis)used to notify accessible name changes.
8133 // Therefore a window, which is labeled by this window, must also notify an accessible
8134 // name change.
8135 if ( IsReallyVisible() )
8136 {
8137 Window* pWindow = GetAccessibleRelationLabelFor();
8138 if ( pWindow && pWindow != this )
8139 pWindow->ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
8140 }
8141
8142 StateChanged( STATE_CHANGE_TEXT );
8143 }
8144
8145 // -----------------------------------------------------------------------
8146
GetText() const8147 String Window::GetText() const
8148 {
8149 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8150
8151 return mpWindowImpl->maText;
8152 }
8153
8154 // -----------------------------------------------------------------------
8155
GetDisplayText() const8156 String Window::GetDisplayText() const
8157 {
8158 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8159
8160 return GetText();
8161 }
8162
8163 // -----------------------------------------------------------------------
8164
GetDisplayBackground() const8165 const Wallpaper& Window::GetDisplayBackground() const
8166 {
8167 // FIXME: fix issue 52349, need to fix this really in
8168 // all NWF enabled controls
8169 const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
8170 if( pTB )
8171 {
8172 if( IsNativeWidgetEnabled() )
8173 return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
8174 }
8175
8176 if( !IsBackground() )
8177 {
8178 if( mpWindowImpl->mpParent )
8179 return mpWindowImpl->mpParent->GetDisplayBackground();
8180 }
8181
8182 const Wallpaper& rBack = GetBackground();
8183 if( ! rBack.IsBitmap() &&
8184 ! rBack.IsGradient() &&
8185 rBack.GetColor().GetColor() == COL_TRANSPARENT &&
8186 mpWindowImpl->mpParent )
8187 return mpWindowImpl->mpParent->GetDisplayBackground();
8188 return rBack;
8189 }
8190
8191 // -----------------------------------------------------------------------
8192
GetHelpText() const8193 const XubString& Window::GetHelpText() const
8194 {
8195 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8196
8197 String aStrHelpId( rtl::OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
8198 bool bStrHelpId = (aStrHelpId.Len() > 0);
8199
8200 if ( !mpWindowImpl->maHelpText.Len() && bStrHelpId )
8201 {
8202 if ( !IsDialog() && (mpWindowImpl->mnType != WINDOW_TABPAGE) && (mpWindowImpl->mnType != WINDOW_FLOATINGWINDOW) )
8203 {
8204 Help* pHelp = Application::GetHelp();
8205 if ( pHelp )
8206 {
8207 ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this );
8208 mpWindowImpl->mbHelpTextDynamic = sal_False;
8209 }
8210 }
8211 }
8212 else if( mpWindowImpl->mbHelpTextDynamic && bStrHelpId )
8213 {
8214 static const char* pEnv = getenv( "HELP_DEBUG" );
8215 if( pEnv && *pEnv )
8216 {
8217 rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() );
8218 aTxt.append( mpWindowImpl->maHelpText );
8219 aTxt.appendAscii( "\n------------------\n" );
8220 aTxt.append( rtl::OUString( aStrHelpId ) );
8221 mpWindowImpl->maHelpText = aTxt.makeStringAndClear();
8222 }
8223 mpWindowImpl->mbHelpTextDynamic = sal_False;
8224 }
8225
8226 return mpWindowImpl->maHelpText;
8227 }
8228
8229 // -----------------------------------------------------------------------
8230
FindWindow(const Point & rPos) const8231 Window* Window::FindWindow( const Point& rPos ) const
8232 {
8233 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8234
8235 Point aPos = OutputToScreenPixel( rPos );
8236 return ((Window*)this)->ImplFindWindow( aPos );
8237 }
8238
8239 // -----------------------------------------------------------------------
8240
GetChildCount() const8241 sal_uInt16 Window::GetChildCount() const
8242 {
8243 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8244
8245 sal_uInt16 nChildCount = 0;
8246 Window* pChild = mpWindowImpl->mpFirstChild;
8247 while ( pChild )
8248 {
8249 nChildCount++;
8250 pChild = pChild->mpWindowImpl->mpNext;
8251 }
8252
8253 return nChildCount;
8254 }
8255
8256 // -----------------------------------------------------------------------
8257
GetChild(sal_uInt16 nChild) const8258 Window* Window::GetChild( sal_uInt16 nChild ) const
8259 {
8260 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8261
8262 sal_uInt16 nChildCount = 0;
8263 Window* pChild = mpWindowImpl->mpFirstChild;
8264 while ( pChild )
8265 {
8266 if ( nChild == nChildCount )
8267 return pChild;
8268 pChild = pChild->mpWindowImpl->mpNext;
8269 nChildCount++;
8270 }
8271
8272 return NULL;
8273 }
8274
8275 // -----------------------------------------------------------------------
8276
GetWindow(sal_uInt16 nType) const8277 Window* Window::GetWindow( sal_uInt16 nType ) const
8278 {
8279 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8280
8281 switch ( nType )
8282 {
8283 case WINDOW_PARENT:
8284 return mpWindowImpl->mpRealParent;
8285
8286 case WINDOW_FIRSTCHILD:
8287 return mpWindowImpl->mpFirstChild;
8288
8289 case WINDOW_LASTCHILD:
8290 return mpWindowImpl->mpLastChild;
8291
8292 case WINDOW_PREV:
8293 return mpWindowImpl->mpPrev;
8294
8295 case WINDOW_NEXT:
8296 return mpWindowImpl->mpNext;
8297
8298 case WINDOW_FIRSTOVERLAP:
8299 return mpWindowImpl->mpFirstOverlap;
8300
8301 case WINDOW_LASTOVERLAP:
8302 return mpWindowImpl->mpLastOverlap;
8303
8304 case WINDOW_OVERLAP:
8305 if ( ImplIsOverlapWindow() )
8306 return (Window*)this;
8307 else
8308 return mpWindowImpl->mpOverlapWindow;
8309
8310 case WINDOW_PARENTOVERLAP:
8311 if ( ImplIsOverlapWindow() )
8312 return mpWindowImpl->mpOverlapWindow;
8313 else
8314 return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
8315
8316 case WINDOW_CLIENT:
8317 return ((Window*)this)->ImplGetWindow();
8318
8319 case WINDOW_REALPARENT:
8320 return ImplGetParent();
8321
8322 case WINDOW_FRAME:
8323 return mpWindowImpl->mpFrameWindow;
8324
8325 case WINDOW_BORDER:
8326 if ( mpWindowImpl->mpBorderWindow )
8327 return mpWindowImpl->mpBorderWindow->GetWindow( WINDOW_BORDER );
8328 return (Window*)this;
8329
8330 case WINDOW_FIRSTTOPWINDOWCHILD:
8331 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.begin();
8332
8333 case WINDOW_LASTTOPWINDOWCHILD:
8334 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.rbegin();
8335
8336 case WINDOW_PREVTOPWINDOWSIBLING:
8337 {
8338 if ( !mpWindowImpl->mpRealParent )
8339 return NULL;
8340 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
8341 ::std::list< Window* >::const_iterator myPos =
8342 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
8343 if ( myPos == rTopWindows.end() )
8344 return NULL;
8345 if ( myPos == rTopWindows.begin() )
8346 return NULL;
8347 return *--myPos;
8348 }
8349
8350 case WINDOW_NEXTTOPWINDOWSIBLING:
8351 {
8352 if ( !mpWindowImpl->mpRealParent )
8353 return NULL;
8354 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
8355 ::std::list< Window* >::const_iterator myPos =
8356 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
8357 if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
8358 return NULL;
8359 return *myPos;
8360 }
8361
8362 }
8363
8364 return NULL;
8365 }
8366
8367 // -----------------------------------------------------------------------
8368
IsChild(const Window * pWindow,sal_Bool bSystemWindow) const8369 sal_Bool Window::IsChild( const Window* pWindow, sal_Bool bSystemWindow ) const
8370 {
8371 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8372 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
8373
8374 do
8375 {
8376 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
8377 break;
8378
8379 pWindow = pWindow->ImplGetParent();
8380
8381 if ( pWindow == this )
8382 return sal_True;
8383 }
8384 while ( pWindow );
8385
8386 return sal_False;
8387 }
8388
8389 // -----------------------------------------------------------------------
8390
IsWindowOrChild(const Window * pWindow,sal_Bool bSystemWindow) const8391 sal_Bool Window::IsWindowOrChild( const Window* pWindow, sal_Bool bSystemWindow ) const
8392 {
8393 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8394 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
8395
8396 if ( this == pWindow )
8397 return sal_True;
8398 return ImplIsChild( pWindow, bSystemWindow );
8399 }
8400
8401 // -----------------------------------------------------------------------
8402
GetSystemData() const8403 const SystemEnvData* Window::GetSystemData() const
8404 {
8405 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8406
8407 return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : NULL;
8408 }
8409
GetSystemDataAny() const8410 ::com::sun::star::uno::Any Window::GetSystemDataAny() const
8411 {
8412 ::com::sun::star::uno::Any aRet;
8413 const SystemEnvData* pSysData = GetSystemData();
8414 if( pSysData )
8415 {
8416 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)pSysData, pSysData->nSize );
8417 aRet <<= aSeq;
8418 }
8419 return aRet;
8420 }
8421
8422 // -----------------------------------------------------------------------
8423
SetWindowPeer(::com::sun::star::uno::Reference<::com::sun::star::awt::XWindowPeer> xPeer,VCLXWindow * pVCLXWindow)8424 void Window::SetWindowPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer, VCLXWindow* pVCLXWindow )
8425 {
8426 // be safe against re-entrance: first clear the old ref, then assign the new one
8427 // #133706# / 2006-03-30 / frank.schoenheit@sun.com
8428 mpWindowImpl->mxWindowPeer.clear();
8429 mpWindowImpl->mxWindowPeer = xPeer;
8430
8431 mpWindowImpl->mpVCLXWindow = pVCLXWindow;
8432 }
8433
8434 // -----------------------------------------------------------------------
8435
GetComponentInterface(sal_Bool bCreate)8436 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( sal_Bool bCreate )
8437 {
8438 if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
8439 {
8440 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
8441 if ( pWrapper )
8442 mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True );
8443 }
8444 return mpWindowImpl->mxWindowPeer;
8445 }
8446
8447 // -----------------------------------------------------------------------
8448
SetComponentInterface(::com::sun::star::uno::Reference<::com::sun::star::awt::XWindowPeer> xIFace)8449 void Window::SetComponentInterface( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xIFace )
8450 {
8451 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
8452 DBG_ASSERT( pWrapper, "SetComponentInterface: No Wrapper!" );
8453 if ( pWrapper )
8454 pWrapper->SetWindowInterface( this, xIFace );
8455 }
8456
8457 // -----------------------------------------------------------------------
8458
ImplCallDeactivateListeners(Window * pNew)8459 void Window::ImplCallDeactivateListeners( Window *pNew )
8460 {
8461 // no deactivation if the newly activated window is my child
8462 if ( !pNew || !ImplIsChild( pNew ) )
8463 {
8464 ImplDelData aDogtag( this );
8465 ImplCallEventListeners( VCLEVENT_WINDOW_DEACTIVATE );
8466 if( aDogtag.IsDelete() )
8467 return;
8468
8469 // #100759#, avoid walking the wrong frame's hierarchy
8470 // e.g. undocked docking windows (ImplDockFloatWin)
8471 if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
8472 ImplGetParent()->ImplCallDeactivateListeners( pNew );
8473 }
8474 }
8475
8476 // -----------------------------------------------------------------------
8477
ImplCallActivateListeners(Window * pOld)8478 void Window::ImplCallActivateListeners( Window *pOld )
8479 {
8480 // no activation if the old active window is my child
8481 if ( !pOld || !ImplIsChild( pOld ) )
8482 {
8483 ImplDelData aDogtag( this );
8484 ImplCallEventListeners( VCLEVENT_WINDOW_ACTIVATE, pOld );
8485 if( aDogtag.IsDelete() )
8486 return;
8487
8488 // #106298# revoke the change for 105369, because this change
8489 // disabled the activate event for the parent,
8490 // if the parent is a compound control
8491 //if( !GetParent() || !GetParent()->IsCompoundControl() )
8492 //{
8493 // #100759#, avoid walking the wrong frame's hierarchy
8494 // e.g. undocked docking windows (ImplDockFloatWin)
8495 // #104714#, revert the changes for 100759 because it has a side effect when pOld is a dialog
8496 // additionally the gallery is not dockable anymore, so 100759 cannot occur
8497 if ( ImplGetParent() ) /* && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow ) */
8498 ImplGetParent()->ImplCallActivateListeners( pOld );
8499 else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
8500 {
8501 // top level frame reached: store hint for DefModalDialogParent
8502 ImplGetSVData()->maWinData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
8503 }
8504 //}
8505 }
8506 }
8507
8508 // -----------------------------------------------------------------------
8509
ImplStopDnd()8510 bool Window::ImplStopDnd()
8511 {
8512 bool bRet = false;
8513 if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
8514 {
8515 bRet = true;
8516 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8517 mpWindowImpl->mpFrameData->mxDragSource.clear();
8518 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
8519 }
8520
8521 return bRet;
8522 }
8523
8524 // -----------------------------------------------------------------------
8525
ImplStartDnd()8526 void Window::ImplStartDnd()
8527 {
8528 GetDropTarget();
8529 }
8530
8531 // -----------------------------------------------------------------------
8532
GetDropTarget()8533 uno::Reference< XDropTarget > Window::GetDropTarget()
8534 {
8535 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8536
8537 if( ! mpWindowImpl->mxDNDListenerContainer.is() )
8538 {
8539 sal_Int8 nDefaultActions = 0;
8540
8541 if( mpWindowImpl->mpFrameData )
8542 {
8543 if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
8544 {
8545 // initialization is done in GetDragSource
8546 uno::Reference< XDragSource > xDragSource = GetDragSource();
8547 }
8548
8549 if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
8550 {
8551 nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
8552
8553 if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
8554 {
8555 mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
8556
8557 try
8558 {
8559 mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
8560
8561 // register also as drag gesture listener if directly supported by drag source
8562 uno::Reference< XDragGestureRecognizer > xDragGestureRecognizer =
8563 uno::Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
8564
8565 if( xDragGestureRecognizer.is() )
8566 {
8567 xDragGestureRecognizer->addDragGestureListener(
8568 uno::Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
8569 }
8570 else
8571 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = sal_True;
8572
8573 }
8574
8575 catch( RuntimeException&)
8576 {
8577 // release all instances
8578 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8579 mpWindowImpl->mpFrameData->mxDragSource.clear();
8580 }
8581 }
8582 }
8583
8584 }
8585
8586 mpWindowImpl->mxDNDListenerContainer = static_cast < XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
8587 }
8588
8589 // this object is located in the same process, so there will be no runtime exception
8590 return uno::Reference< XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
8591 }
8592
8593 // -----------------------------------------------------------------------
8594
GetDragSource()8595 uno::Reference< XDragSource > Window::GetDragSource()
8596 {
8597 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8598
8599 if( mpWindowImpl->mpFrameData )
8600 {
8601 if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
8602 {
8603 try
8604 {
8605 uno::Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
8606 if ( xFactory.is() )
8607 {
8608 const SystemEnvData * pEnvData = GetSystemData();
8609
8610 if( pEnvData )
8611 {
8612 Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
8613 OUString aDragSourceSN, aDropTargetSN;
8614 #if defined WNT || defined OS2
8615 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" );
8616 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" );
8617 aDragSourceAL[ 1 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
8618 aDropTargetAL[ 0 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
8619 #elif defined QUARTZ
8620 /* FIXME: Mac OS X specific dnd interface does not exist! *
8621 * Using Windows based dnd as a temporary solution */
8622 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" );
8623 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" );
8624 aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) ) );
8625 aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) ) );
8626 #elif defined UNX
8627 aDropTargetAL.realloc( 3 );
8628 aDragSourceAL.realloc( 3 );
8629 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DragSource" );
8630 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DropTarget" );
8631
8632 aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
8633 aDragSourceAL[ 2 ] = makeAny( vcl::createBmpConverter() );
8634 aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
8635 aDropTargetAL[ 1 ] = makeAny( (sal_Size)(pEnvData->aShellWindow) );
8636 aDropTargetAL[ 2 ] = makeAny( vcl::createBmpConverter() );
8637 #endif
8638 if( aDragSourceSN.getLength() )
8639 mpWindowImpl->mpFrameData->mxDragSource = uno::Reference< XDragSource > ( xFactory->createInstanceWithArguments( aDragSourceSN, aDragSourceAL ), UNO_QUERY );
8640
8641 if( aDropTargetSN.getLength() )
8642 mpWindowImpl->mpFrameData->mxDropTarget = uno::Reference< XDropTarget > ( xFactory->createInstanceWithArguments( aDropTargetSN, aDropTargetAL ), UNO_QUERY );
8643 }
8644 }
8645 }
8646
8647 // createInstance can throw any exception
8648 catch( Exception&)
8649 {
8650 // release all instances
8651 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8652 mpWindowImpl->mpFrameData->mxDragSource.clear();
8653 }
8654 }
8655
8656 return mpWindowImpl->mpFrameData->mxDragSource;
8657 }
8658
8659 return uno::Reference< XDragSource > ();
8660 }
8661
8662 // -----------------------------------------------------------------------
8663
GetDragSourceDropTarget(uno::Reference<XDragSource> & xDragSource,uno::Reference<XDropTarget> & xDropTarget)8664 void Window::GetDragSourceDropTarget(uno::Reference< XDragSource >& xDragSource, uno::Reference< XDropTarget > &xDropTarget )
8665 // only for RVP transmission
8666 {
8667 if( mpWindowImpl->mpFrameData )
8668 {
8669 // initialization is done in GetDragSource
8670 xDragSource = GetDragSource();
8671 xDropTarget = mpWindowImpl->mpFrameData->mxDropTarget;
8672 }
8673 else
8674 {
8675 xDragSource.clear();
8676 xDropTarget.clear();
8677 }
8678 }
8679
8680 // -----------------------------------------------------------------------
8681
GetDragGestureRecognizer()8682 uno::Reference< XDragGestureRecognizer > Window::GetDragGestureRecognizer()
8683 {
8684 return uno::Reference< XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
8685 }
8686
8687 // -----------------------------------------------------------------------
8688
GetClipboard()8689 uno::Reference< XClipboard > Window::GetClipboard()
8690 {
8691 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8692
8693 if( mpWindowImpl->mpFrameData )
8694 {
8695 if( ! mpWindowImpl->mpFrameData->mxClipboard.is() )
8696 {
8697 try
8698 {
8699 uno::Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
8700
8701 if( xFactory.is() )
8702 {
8703 mpWindowImpl->mpFrameData->mxClipboard = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboardExt" ) ), UNO_QUERY );
8704
8705 if( !mpWindowImpl->mpFrameData->mxClipboard.is() )
8706 mpWindowImpl->mpFrameData->mxClipboard = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY );
8707
8708 #if defined(UNX) && !defined(QUARTZ) // unix clipboard needs to be initialized
8709 if( mpWindowImpl->mpFrameData->mxClipboard.is() )
8710 {
8711 uno::Reference< XInitialization > xInit = uno::Reference< XInitialization >( mpWindowImpl->mpFrameData->mxClipboard, UNO_QUERY );
8712
8713 if( xInit.is() )
8714 {
8715 Sequence< Any > aArgumentList( 3 );
8716 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
8717 aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "CLIPBOARD" ) );
8718 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
8719
8720 xInit->initialize( aArgumentList );
8721 }
8722 }
8723 #endif
8724 }
8725 }
8726
8727 // createInstance can throw any exception
8728 catch( Exception&)
8729 {
8730 // release all instances
8731 mpWindowImpl->mpFrameData->mxClipboard.clear();
8732 }
8733 }
8734
8735 return mpWindowImpl->mpFrameData->mxClipboard;
8736 }
8737
8738 return static_cast < XClipboard * > (0);
8739 }
8740
8741 // -----------------------------------------------------------------------
8742
GetPrimarySelection()8743 uno::Reference< XClipboard > Window::GetPrimarySelection()
8744 {
8745 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8746
8747 if( mpWindowImpl->mpFrameData )
8748 {
8749 if( ! mpWindowImpl->mpFrameData->mxSelection.is() )
8750 {
8751 try
8752 {
8753 uno::Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
8754
8755 if( xFactory.is() )
8756 {
8757 #if defined(UNX) && !defined(QUARTZ)
8758 Sequence< Any > aArgumentList( 3 );
8759 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
8760 aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "PRIMARY" ) );
8761 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
8762
8763 mpWindowImpl->mpFrameData->mxSelection = uno::Reference< XClipboard >( xFactory->createInstanceWithArguments(
8764 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ), aArgumentList ), UNO_QUERY );
8765 # else
8766 static uno::Reference< XClipboard > s_xSelection;
8767
8768 if ( !s_xSelection.is() )
8769 s_xSelection = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboardExt" ) ), UNO_QUERY );
8770
8771 if ( !s_xSelection.is() )
8772 s_xSelection = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ) ), UNO_QUERY );
8773
8774 mpWindowImpl->mpFrameData->mxSelection = s_xSelection;
8775 # endif
8776 }
8777 }
8778
8779 // createInstance can throw any exception
8780 catch( Exception&)
8781 {
8782 // release all instances
8783 mpWindowImpl->mpFrameData->mxSelection.clear();
8784 }
8785 }
8786
8787 return mpWindowImpl->mpFrameData->mxSelection;
8788 }
8789
8790 return static_cast < XClipboard * > (0);
8791 }
8792
8793 // -----------------------------------------------------------------------
8794 // Accessibility
8795 // -----------------------------------------------------------------------
8796
GetAccessible(sal_Bool bCreate)8797 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::GetAccessible( sal_Bool bCreate )
8798 {
8799 // do not optimize hierarchy for the top level border win (i.e. when there is no parent)
8800 /* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy
8801 if ( GetParent() && ( GetType() == WINDOW_BORDERWINDOW ) && ( GetChildCount() == 1 ) )
8802 //if( !ImplIsAccessibleCandidate() )
8803 {
8804 Window* pChild = GetAccessibleChildWindow( 0 );
8805 if ( pChild )
8806 return pChild->GetAccessible();
8807 }
8808 */
8809 if ( !mpWindowImpl->mxAccessible.is() && bCreate )
8810 mpWindowImpl->mxAccessible = CreateAccessible();
8811
8812 return mpWindowImpl->mxAccessible;
8813 }
8814
CreateAccessible()8815 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
8816 {
8817 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( sal_True ), ::com::sun::star::uno::UNO_QUERY );
8818 return xAcc;
8819 }
8820
SetAccessible(::com::sun::star::uno::Reference<::com::sun::star::accessibility::XAccessible> x)8821 void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x )
8822 {
8823 mpWindowImpl->mxAccessible = x;
8824 }
8825
8826 // skip all border windows that are no top level frames
ImplIsAccessibleCandidate() const8827 sal_Bool Window::ImplIsAccessibleCandidate() const
8828 {
8829 if( !mpWindowImpl->mbBorderWin )
8830 return sal_True;
8831 else
8832 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
8833 if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) )
8834 return sal_True;
8835 else
8836 return sal_False;
8837 }
8838
ImplIsAccessibleNativeFrame() const8839 sal_Bool Window::ImplIsAccessibleNativeFrame() const
8840 {
8841 if( mpWindowImpl->mbFrame )
8842 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
8843 if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
8844 return sal_True;
8845 else
8846 return sal_False;
8847 else
8848 return sal_False;
8849 }
8850
ImplGetAccessibleCandidateChildWindowCount(sal_uInt16 nFirstWindowType) const8851 sal_uInt16 Window::ImplGetAccessibleCandidateChildWindowCount( sal_uInt16 nFirstWindowType ) const
8852 {
8853 sal_uInt16 nChildren = 0;
8854 Window* pChild = GetWindow( nFirstWindowType );
8855 while ( pChild )
8856 {
8857 if( pChild->ImplIsAccessibleCandidate() )
8858 nChildren++;
8859 else
8860 nChildren = sal::static_int_cast<sal_uInt16>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD ));
8861 pChild = pChild->mpWindowImpl->mpNext;
8862 }
8863 return nChildren;
8864 }
8865
ImplGetAccessibleCandidateChild(sal_uInt16 nChild,sal_uInt16 & rChildCount,sal_uInt16 nFirstWindowType,sal_Bool bTopLevel) const8866 Window* Window::ImplGetAccessibleCandidateChild( sal_uInt16 nChild, sal_uInt16& rChildCount, sal_uInt16 nFirstWindowType, sal_Bool bTopLevel ) const
8867 {
8868 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8869
8870 if( bTopLevel )
8871 rChildCount = 0;
8872
8873 Window* pChild = GetWindow( nFirstWindowType );
8874 while ( pChild )
8875 {
8876 Window *pTmpChild = pChild;
8877
8878 if( !pChild->ImplIsAccessibleCandidate() )
8879 pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, WINDOW_FIRSTCHILD, sal_False );
8880
8881 if ( nChild == rChildCount )
8882 return pTmpChild;
8883 pChild = pChild->mpWindowImpl->mpNext;
8884 rChildCount++;
8885 }
8886
8887 return NULL;
8888 }
8889
8890 /*
8891 Window* Window::GetAccessibleParentWindow() const
8892 {
8893 Window* pParent = GetParent();
8894 while ( pParent )
8895 if( pParent->ImplIsAccessibleCandidate() )
8896 break;
8897 else
8898 pParent = pParent->GetParent();
8899 return pParent;
8900 }
8901 */
8902
GetAccessibleParentWindow() const8903 Window* Window::GetAccessibleParentWindow() const
8904 {
8905 if ( ImplIsAccessibleNativeFrame() )
8906 return NULL;
8907
8908 Window* pParent = mpWindowImpl->mpParent;
8909 if( GetType() == WINDOW_MENUBARWINDOW )
8910 {
8911 // report the menubar as a child of THE workwindow
8912 Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild;
8913 while( pWorkWin && (pWorkWin == this) )
8914 pWorkWin = pWorkWin->mpWindowImpl->mpNext;
8915 pParent = pWorkWin;
8916 }
8917 // If this a floating window which has a native boarder window, this one should be reported as
8918 // accessible parent
8919 else if( GetType() == WINDOW_FLOATINGWINDOW &&
8920 mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame)
8921 {
8922 pParent = mpWindowImpl->mpBorderWindow;
8923 }
8924 else if( pParent && !pParent->ImplIsAccessibleCandidate() )
8925 {
8926 pParent = pParent->mpWindowImpl->mpParent;
8927 }
8928 return pParent;
8929 }
8930
8931 /*
8932 sal_uInt16 Window::GetAccessibleChildWindowCount()
8933 {
8934 sal_uInt16 nChildren = ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD );
8935
8936 // Search also for SystemWindows.
8937 Window* pOverlap = GetWindow( WINDOW_OVERLAP );
8938 nChildren += pOverlap->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTOVERLAP );
8939
8940 return nChildren;
8941 }
8942 */
8943
GetAccessibleChildWindowCount()8944 sal_uInt16 Window::GetAccessibleChildWindowCount()
8945 {
8946 sal_uInt16 nChildren = 0;
8947 Window* pChild = mpWindowImpl->mpFirstChild;
8948 while( pChild )
8949 {
8950 if( pChild->IsVisible() )
8951 nChildren++;
8952 pChild = pChild->mpWindowImpl->mpNext;
8953 }
8954
8955 // #107176# ignore overlapwindows
8956 // this only affects non-system floating windows
8957 // which are either not accessible (like the HelpAgent) or should be changed to system windows anyway
8958 /*
8959 if( ImplIsOverlapWindow() )
8960 {
8961 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
8962 while ( pOverlap )
8963 {
8964 if( pOverlap->IsVisible() )
8965 nChildren++;
8966 pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
8967 }
8968 }
8969 */
8970
8971 // report the menubarwindow as a child of THE workwindow
8972 if( GetType() == WINDOW_BORDERWINDOW )
8973 {
8974 if( ((ImplBorderWindow *) this)->mpMenuBarWindow &&
8975 ((ImplBorderWindow *) this)->mpMenuBarWindow->IsVisible()
8976 )
8977 --nChildren;
8978 }
8979 else if( GetType() == WINDOW_WORKWINDOW )
8980 {
8981 if( ((WorkWindow *) this)->GetMenuBar() &&
8982 ((WorkWindow *) this)->GetMenuBar()->GetWindow() &&
8983 ((WorkWindow *) this)->GetMenuBar()->GetWindow()->IsVisible()
8984 )
8985 ++nChildren;
8986 }
8987
8988 return nChildren;
8989 }
8990
8991 /*
8992 Window* Window::GetAccessibleChildWindow( sal_uInt16 n )
8993 {
8994 sal_uInt16 nChildCount; // will be set in ImplGetAccessibleCandidateChild(...)
8995 Window* pChild = ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTCHILD, sal_True );
8996 if ( !pChild && ( n >= nChildCount ) )
8997 {
8998 Window* pOverlap = GetWindow( WINDOW_OVERLAP );
8999 pChild = pOverlap->ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTOVERLAP, sal_False );
9000 }
9001
9002 return pChild;
9003 }
9004 */
9005
GetAccessibleChildWindow(sal_uInt16 n)9006 Window* Window::GetAccessibleChildWindow( sal_uInt16 n )
9007 {
9008 // report the menubarwindow as a the first child of THE workwindow
9009 if( GetType() == WINDOW_WORKWINDOW && ((WorkWindow *) this)->GetMenuBar() )
9010 {
9011 if( n == 0 )
9012 {
9013 MenuBar *pMenuBar = ((WorkWindow *) this)->GetMenuBar();
9014 if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
9015 return pMenuBar->GetWindow();
9016 }
9017 else
9018 --n;
9019 }
9020
9021 // transform n to child number including invisible children
9022 sal_uInt16 nChildren = n;
9023 Window* pChild = mpWindowImpl->mpFirstChild;
9024 while( pChild )
9025 {
9026 if( pChild->IsVisible() )
9027 {
9028 if( ! nChildren )
9029 break;
9030 nChildren--;
9031 }
9032 pChild = pChild->mpWindowImpl->mpNext;
9033 }
9034
9035 if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
9036 {
9037 do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() );
9038 DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
9039 }
9040 if ( !pChild )
9041 {
9042 // #107176# ignore overlapwindows
9043 /*
9044 if( ImplIsOverlapWindow() )
9045 {
9046 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
9047 while ( !pChild && pOverlap )
9048 {
9049 if ( !nChildren && pOverlap->IsVisible() )
9050 {
9051 pChild = pOverlap;
9052 break;
9053 }
9054 pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
9055 if( pOverlap && pOverlap->IsVisible() )
9056 nChildren--;
9057 }
9058 }
9059 */
9060
9061 }
9062 if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
9063 {
9064 pChild = pChild->GetChild( 0 );
9065 }
9066 return pChild;
9067 }
9068
9069
SetAccessibleRole(sal_uInt16 nRole)9070 void Window::SetAccessibleRole( sal_uInt16 nRole )
9071 {
9072 if ( !mpWindowImpl->mpAccessibleInfos )
9073 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9074
9075 DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
9076 mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole;
9077 }
9078
GetAccessibleRole() const9079 sal_uInt16 Window::GetAccessibleRole() const
9080 {
9081 using namespace ::com::sun::star;
9082
9083 sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF;
9084 if ( nRole == 0xFFFF )
9085 {
9086 switch ( GetType() )
9087 {
9088 case WINDOW_MESSBOX: // MT: Would be nice to have special roles!
9089 case WINDOW_INFOBOX:
9090 case WINDOW_WARNINGBOX:
9091 case WINDOW_ERRORBOX:
9092 case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break;
9093
9094 case WINDOW_MODELESSDIALOG:
9095 case WINDOW_MODALDIALOG:
9096 case WINDOW_SYSTEMDIALOG:
9097 case WINDOW_PRINTERSETUPDIALOG:
9098 case WINDOW_PRINTDIALOG:
9099 case WINDOW_TABDIALOG:
9100 case WINDOW_BUTTONDIALOG:
9101 case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break;
9102
9103 case WINDOW_PUSHBUTTON:
9104 case WINDOW_OKBUTTON:
9105 case WINDOW_CANCELBUTTON:
9106 case WINDOW_HELPBUTTON:
9107 case WINDOW_IMAGEBUTTON:
9108 //case WINDOW_MENUBUTTON:
9109 case WINDOW_MOREBUTTON:
9110 case WINDOW_SPINBUTTON:
9111 case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break;
9112 case WINDOW_MENUBUTTON: nRole = accessibility::AccessibleRole::BUTTON_MENU; break;
9113
9114 case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
9115 case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
9116 case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break;
9117 case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break;
9118
9119 case WINDOW_IMAGERADIOBUTTON:
9120 case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break;
9121 case WINDOW_TRISTATEBOX:
9122 case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break;
9123
9124 case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
9125
9126 case WINDOW_PATTERNFIELD:
9127 // Need to set the role of those window control to spinbox
9128 /*
9129 case WINDOW_NUMERICFIELD:
9130 case WINDOW_METRICFIELD:
9131 case WINDOW_CURRENCYFIELD:
9132 case WINDOW_LONGCURRENCYFIELD:
9133 */
9134 case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break;
9135
9136 case WINDOW_PATTERNBOX:
9137 case WINDOW_NUMERICBOX:
9138 case WINDOW_METRICBOX:
9139 case WINDOW_CURRENCYBOX:
9140 case WINDOW_LONGCURRENCYBOX:
9141 case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break;
9142
9143 case WINDOW_LISTBOX:
9144 case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
9145
9146 case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break;
9147
9148 case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
9149 case WINDOW_FIXEDBORDER:
9150 nRole = accessibility::AccessibleRole::SEPARATOR; break;
9151 case WINDOW_FIXEDLINE:
9152 { if( GetText().Len() > 0 )
9153 nRole = accessibility::AccessibleRole::LABEL;
9154 else
9155 nRole = accessibility::AccessibleRole::SEPARATOR;
9156 break;
9157 }
9158 //case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break;
9159 case WINDOW_FIXEDBITMAP:
9160 case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
9161 case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break;
9162 case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
9163
9164 case WINDOW_SLIDER:
9165 case WINDOW_SPLITTER:
9166 case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
9167
9168 case WINDOW_DATEBOX:
9169 case WINDOW_TIMEBOX:
9170 case WINDOW_DATEFIELD:
9171 case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
9172
9173 // Need to set the role of those window control to spinbox
9174 case WINDOW_NUMERICFIELD:
9175 case WINDOW_METRICFIELD:
9176 case WINDOW_CURRENCYFIELD:
9177 case WINDOW_LONGCURRENCYFIELD:
9178 case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
9179
9180 case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
9181 case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break;
9182
9183 case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break;
9184 case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
9185
9186 case WINDOW_DOCKINGWINDOW:
9187 case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME :
9188 accessibility::AccessibleRole::PANEL; break;
9189
9190 case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame ||
9191 (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ||
9192 (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME :
9193 accessibility::AccessibleRole::WINDOW; break;
9194
9195 case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break;
9196
9197
9198 case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
9199
9200 case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break;
9201
9202 case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break;
9203 case WINDOW_WINDOW:
9204 case WINDOW_CONTROL:
9205 case WINDOW_BORDERWINDOW:
9206 case WINDOW_SYSTEMCHILDWINDOW:
9207 default:
9208 if (ImplIsAccessibleNativeFrame() )
9209 nRole = accessibility::AccessibleRole::FRAME;
9210 else if( IsScrollable() )
9211 nRole = accessibility::AccessibleRole::SCROLL_PANE;
9212 else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() )
9213 nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenus are windows (i.e. toplevel)
9214 else
9215 // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead
9216 // a WINDOW is interpreted as a top-level window, which is typically not the case
9217 //nRole = accessibility::AccessibleRole::WINDOW;
9218 nRole = accessibility::AccessibleRole::PANEL;
9219 }
9220 }
9221 return nRole;
9222 }
9223
SetAccessibleName(const String & rName)9224 void Window::SetAccessibleName( const String& rName )
9225 {
9226 if ( !mpWindowImpl->mpAccessibleInfos )
9227 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9228
9229 String oldName = GetAccessibleName();
9230 delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
9231 mpWindowImpl->mpAccessibleInfos->pAccessibleName = new String( rName );
9232 ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldName );
9233 }
9234
GetAccessibleName() const9235 String Window::GetAccessibleName() const
9236 {
9237 String aAccessibleName;
9238 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName )
9239 {
9240 aAccessibleName = *mpWindowImpl->mpAccessibleInfos->pAccessibleName;
9241 }
9242 else
9243 {
9244 switch ( GetType() )
9245 {
9246 // case WINDOW_IMAGERADIOBUTTON:
9247 // case WINDOW_RADIOBUTTON:
9248 // case WINDOW_TRISTATEBOX:
9249 // case WINDOW_CHECKBOX:
9250
9251 case WINDOW_MULTILINEEDIT:
9252 case WINDOW_PATTERNFIELD:
9253 case WINDOW_NUMERICFIELD:
9254 case WINDOW_METRICFIELD:
9255 case WINDOW_CURRENCYFIELD:
9256 case WINDOW_LONGCURRENCYFIELD:
9257 case WINDOW_EDIT:
9258
9259 case WINDOW_DATEBOX:
9260 case WINDOW_TIMEBOX:
9261 case WINDOW_CURRENCYBOX:
9262 case WINDOW_LONGCURRENCYBOX:
9263 case WINDOW_DATEFIELD:
9264 case WINDOW_TIMEFIELD:
9265 case WINDOW_SPINFIELD:
9266
9267 case WINDOW_COMBOBOX:
9268 case WINDOW_LISTBOX:
9269 case WINDOW_MULTILISTBOX:
9270 case WINDOW_TREELISTBOX:
9271 case WINDOW_METRICBOX:
9272 {
9273 Window *pLabel = GetAccessibleRelationLabeledBy();
9274 if ( pLabel && pLabel != this )
9275 aAccessibleName = pLabel->GetText();
9276 }
9277 if ( !aAccessibleName.Len() )
9278 {
9279 aAccessibleName = GetQuickHelpText();
9280 }
9281 break;
9282
9283 case WINDOW_IMAGEBUTTON:
9284 case WINDOW_PUSHBUTTON:
9285 aAccessibleName = GetText();
9286 if ( !aAccessibleName.Len() )
9287 {
9288 aAccessibleName = GetQuickHelpText();
9289 if ( !aAccessibleName.Len() )
9290 aAccessibleName = GetHelpText();
9291 }
9292 break;
9293
9294 case WINDOW_TOOLBOX:
9295 aAccessibleName = GetText();
9296 if( aAccessibleName.Len() == 0 )
9297 aAccessibleName =XubString( RTL_CONSTASCII_USTRINGPARAM( "Tool Bar" ) );
9298 break;
9299 case WINDOW_MOREBUTTON:
9300 aAccessibleName = mpWindowImpl->maText;
9301 break;
9302 default:
9303 aAccessibleName = GetText();
9304 break;
9305 }
9306
9307 aAccessibleName = GetNonMnemonicString( aAccessibleName );
9308 }
9309
9310 return aAccessibleName;
9311 }
9312
SetAccessibleDescription(const String & rDescription)9313 void Window::SetAccessibleDescription( const String& rDescription )
9314 {
9315 if ( ! mpWindowImpl->mpAccessibleInfos )
9316 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9317
9318 DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
9319 delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
9320 mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new String( rDescription );
9321 }
9322
GetAccessibleDescription() const9323 String Window::GetAccessibleDescription() const
9324 {
9325 String aAccessibleDescription;
9326 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
9327 {
9328 aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
9329 }
9330 else
9331 {
9332 // Special code for help text windows. ZT asks the border window for the
9333 // description so we have to forward this request to our inner window.
9334 const Window* pWin = ((Window *)this)->ImplGetWindow();
9335 if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW )
9336 aAccessibleDescription = pWin->GetHelpText();
9337 else
9338 aAccessibleDescription = GetHelpText();
9339 }
9340
9341 return aAccessibleDescription;
9342 }
9343
SetAccessibleRelationLabeledBy(Window * pLabeledBy)9344 void Window::SetAccessibleRelationLabeledBy( Window* pLabeledBy )
9345 {
9346 if ( !mpWindowImpl->mpAccessibleInfos )
9347 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9348 mpWindowImpl->mpAccessibleInfos->pLabeledByWindow = pLabeledBy;
9349 }
9350
SetAccessibleRelationLabelFor(Window * pLabelFor)9351 void Window::SetAccessibleRelationLabelFor( Window* pLabelFor )
9352 {
9353 if ( !mpWindowImpl->mpAccessibleInfos )
9354 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9355 mpWindowImpl->mpAccessibleInfos->pLabelForWindow = pLabelFor;
9356 }
9357
SetAccessibleRelationMemberOf(Window * pMemberOfWin)9358 void Window::SetAccessibleRelationMemberOf( Window* pMemberOfWin )
9359 {
9360 if ( !mpWindowImpl->mpAccessibleInfos )
9361 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9362 mpWindowImpl->mpAccessibleInfos->pMemberOfWindow = pMemberOfWin;
9363 }
9364
IsAccessibilityEventsSuppressed(sal_Bool bTraverseParentPath)9365 sal_Bool Window::IsAccessibilityEventsSuppressed( sal_Bool bTraverseParentPath )
9366 {
9367 if( !bTraverseParentPath )
9368 return mpWindowImpl->mbSuppressAccessibilityEvents;
9369 else
9370 {
9371 Window *pParent = this;
9372 while ( pParent && pParent->mpWindowImpl)
9373 {
9374 if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents )
9375 return sal_True;
9376 else
9377 pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
9378 }
9379 return sal_False;
9380 }
9381 }
9382
SetAccessibilityEventsSuppressed(sal_Bool bSuppressed)9383 void Window::SetAccessibilityEventsSuppressed(sal_Bool bSuppressed)
9384 {
9385 mpWindowImpl->mbSuppressAccessibilityEvents = bSuppressed;
9386 }
9387
RecordLayoutData(vcl::ControlLayoutData * pLayout,const Rectangle & rRect)9388 void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const Rectangle& rRect )
9389 {
9390 if( ! mpOutDevData )
9391 ImplInitOutDevData();
9392 mpOutDevData->mpRecordLayout = pLayout;
9393 mpOutDevData->maRecordRect = rRect;
9394 Paint( rRect );
9395 mpOutDevData->mpRecordLayout = NULL;
9396 }
9397
9398 // -----------------------------------------------------------------------
9399 // -----------------------------------------------------------------------
9400
9401
9402 // returns background color used in this control
9403 // false: could not determine color
ImplGetCurrentBackgroundColor(Color & rCol)9404 sal_Bool Window::ImplGetCurrentBackgroundColor( Color& rCol )
9405 {
9406 sal_Bool bRet = sal_True;
9407
9408 switch ( GetType() )
9409 {
9410 // perform special handling here
9411 case WINDOW_PUSHBUTTON:
9412 case WINDOW_OKBUTTON:
9413 case WINDOW_CANCELBUTTON:
9414 // etc.
9415 default:
9416 if( IsControlBackground() )
9417 rCol = GetControlBackground();
9418 else if( IsBackground() )
9419 {
9420 Wallpaper aWall = GetBackground();
9421 if( !aWall.IsGradient() && !aWall.IsBitmap() )
9422 rCol = aWall.GetColor();
9423 else
9424 bRet = sal_False;
9425 }
9426 else
9427 rCol = GetSettings().GetStyleSettings().GetFaceColor();
9428 break;
9429 }
9430 return bRet;
9431 }
9432
DrawSelectionBackground(const Rectangle & rRect,sal_uInt16 highlight,sal_Bool bChecked,sal_Bool bDrawBorder,sal_Bool bDrawExtBorderOnly)9433 void Window::DrawSelectionBackground( const Rectangle& rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bDrawBorder, sal_Bool bDrawExtBorderOnly )
9434 {
9435 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, NULL, NULL );
9436 }
9437
DrawSelectionBackground(const Rectangle & rRect,sal_uInt16 highlight,sal_Bool bChecked,sal_Bool bDrawBorder,sal_Bool bDrawExtBorderOnly,Color * pSelectionTextColor)9438 void Window::DrawSelectionBackground( const Rectangle& rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bDrawBorder, sal_Bool bDrawExtBorderOnly, Color* pSelectionTextColor )
9439 {
9440 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, pSelectionTextColor, NULL );
9441 }
9442
DrawSelectionBackground(const Rectangle & rRect,sal_uInt16 highlight,sal_Bool bChecked,sal_Bool bDrawBorder,sal_Bool bDrawExtBorderOnly,long nCornerRadius,Color * pSelectionTextColor,Color * pPaintColor)9443 void Window::DrawSelectionBackground( const Rectangle& rRect,
9444 sal_uInt16 highlight,
9445 sal_Bool bChecked,
9446 sal_Bool bDrawBorder,
9447 sal_Bool bDrawExtBorderOnly,
9448 long nCornerRadius,
9449 Color* pSelectionTextColor,
9450 Color* pPaintColor
9451 )
9452 {
9453 if( rRect.IsEmpty() )
9454 return;
9455
9456 bool bRoundEdges = nCornerRadius > 0;
9457
9458 const StyleSettings& rStyles = GetSettings().GetStyleSettings();
9459
9460
9461 // colors used for item highlighting
9462 Color aSelectionBorderCol( pPaintColor ? *pPaintColor : rStyles.GetHighlightColor() );
9463 Color aSelectionFillCol( aSelectionBorderCol );
9464
9465 sal_Bool bDark = rStyles.GetFaceColor().IsDark();
9466 sal_Bool bBright = ( rStyles.GetFaceColor() == Color( COL_WHITE ) );
9467
9468 int c1 = aSelectionBorderCol.GetLuminance();
9469 int c2 = GetDisplayBackground().GetColor().GetLuminance();
9470
9471 if( !bDark && !bBright && abs( c2-c1 ) < (pPaintColor ? 40 : 75) )
9472 {
9473 // contrast too low
9474 sal_uInt16 h,s,b;
9475 aSelectionFillCol.RGBtoHSB( h, s, b );
9476 if( b > 50 ) b -= 40;
9477 else b += 40;
9478 aSelectionFillCol.SetColor( Color::HSBtoRGB( h, s, b ) );
9479 aSelectionBorderCol = aSelectionFillCol;
9480 }
9481
9482 if( bRoundEdges )
9483 {
9484 if( aSelectionBorderCol.IsDark() )
9485 aSelectionBorderCol.IncreaseLuminance( 128 );
9486 else
9487 aSelectionBorderCol.DecreaseLuminance( 128 );
9488 }
9489
9490 Rectangle aRect( rRect );
9491 if( bDrawExtBorderOnly )
9492 {
9493 aRect.nLeft -= 1;
9494 aRect.nTop -= 1;
9495 aRect.nRight += 1;
9496 aRect.nBottom += 1;
9497 }
9498 Color oldFillCol = GetFillColor();
9499 Color oldLineCol = GetLineColor();
9500
9501 if( bDrawBorder )
9502 SetLineColor( bDark ? Color(COL_WHITE) : ( bBright ? Color(COL_BLACK) : aSelectionBorderCol ) );
9503 else
9504 SetLineColor();
9505
9506 sal_uInt16 nPercent = 0;
9507 if( !highlight )
9508 {
9509 if( bDark )
9510 aSelectionFillCol = COL_BLACK;
9511 else
9512 nPercent = 80; // just checked (light)
9513 }
9514 else
9515 {
9516 if( bChecked && highlight == 2 )
9517 {
9518 if( bDark )
9519 aSelectionFillCol = COL_LIGHTGRAY;
9520 else if ( bBright )
9521 {
9522 aSelectionFillCol = COL_BLACK;
9523 SetLineColor( COL_BLACK );
9524 nPercent = 0;
9525 }
9526 else
9527 nPercent = bRoundEdges ? 40 : 20; // selected, pressed or checked ( very dark )
9528 }
9529 else if( bChecked || highlight == 1 )
9530 {
9531 if( bDark )
9532 aSelectionFillCol = COL_GRAY;
9533 else if ( bBright )
9534 {
9535 aSelectionFillCol = COL_BLACK;
9536 SetLineColor( COL_BLACK );
9537 nPercent = 0;
9538 }
9539 else
9540 nPercent = bRoundEdges ? 60 : 35; // selected, pressed or checked ( very dark )
9541 }
9542 else
9543 {
9544 if( bDark )
9545 aSelectionFillCol = COL_LIGHTGRAY;
9546 else if ( bBright )
9547 {
9548 aSelectionFillCol = COL_BLACK;
9549 SetLineColor( COL_BLACK );
9550 if( highlight == 3 )
9551 nPercent = 80;
9552 else
9553 nPercent = 0;
9554 }
9555 else
9556 nPercent = 70; // selected ( dark )
9557 }
9558 }
9559
9560 if( bDark && bDrawExtBorderOnly )
9561 {
9562 SetFillColor();
9563 if( pSelectionTextColor )
9564 *pSelectionTextColor = rStyles.GetHighlightTextColor();
9565 }
9566 else
9567 {
9568 SetFillColor( aSelectionFillCol );
9569 if( pSelectionTextColor )
9570 {
9571 Color aTextColor = IsControlBackground() ? GetControlForeground() : rStyles.GetButtonTextColor();
9572 Color aHLTextColor = rStyles.GetHighlightTextColor();
9573 int nTextDiff = abs(aSelectionFillCol.GetLuminance() - aTextColor.GetLuminance());
9574 int nHLDiff = abs(aSelectionFillCol.GetLuminance() - aHLTextColor.GetLuminance());
9575 *pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor;
9576 }
9577 }
9578
9579
9580 if( bDark )
9581 {
9582 DrawRect( aRect );
9583 }
9584 else
9585 {
9586 if( bRoundEdges )
9587 {
9588 Polygon aPoly( aRect, nCornerRadius, nCornerRadius );
9589 PolyPolygon aPolyPoly( aPoly );
9590 DrawTransparent( aPolyPoly, nPercent );
9591 }
9592 else
9593 {
9594 Polygon aPoly( aRect );
9595 PolyPolygon aPolyPoly( aPoly );
9596 DrawTransparent( aPolyPoly, nPercent );
9597 }
9598 }
9599
9600 SetFillColor( oldFillCol );
9601 SetLineColor( oldLineCol );
9602 }
9603
9604 /*
9605 void Window::DbgAssertNoEventListeners()
9606 {
9607 VclWindowEvent aEvent( this, 0, NULL );
9608 DBG_ASSERT( mpWindowImpl->maEventListeners.empty(), "Eventlistener: Who is still listening???" )
9609 if ( !mpWindowImpl->maEventListeners.empty() )
9610 mpWindowImpl->maEventListeners.Call( &aEvent );
9611
9612 DBG_ASSERT( mpWindowImpl->maChildEventListeners.empty(), "ChildEventlistener: Who is still listening???" )
9613 if ( !mpWindowImpl->maChildEventListeners.empty() )
9614 mpWindowImpl->maChildEventListeners.Call( &aEvent );
9615 }
9616 */
9617
9618 // controls should return the window that gets the
9619 // focus by default, so keyevents can be sent to that window directly
GetPreferredKeyInputWindow()9620 Window* Window::GetPreferredKeyInputWindow()
9621 {
9622 return this;
9623 }
9624
9625
IsScrollable() const9626 sal_Bool Window::IsScrollable() const
9627 {
9628 // check for scrollbars
9629 Window *pChild = mpWindowImpl->mpFirstChild;
9630 while( pChild )
9631 {
9632 if( pChild->GetType() == WINDOW_SCROLLBAR )
9633 return true;
9634 else
9635 pChild = pChild->mpWindowImpl->mpNext;
9636 }
9637 return false;
9638 }
9639
IsTopWindow() const9640 sal_Bool Window::IsTopWindow() const
9641 {
9642 if ( mpWindowImpl->mbInDtor )
9643 return sal_False;
9644
9645 // topwindows must be frames or they must have a borderwindow which is a frame
9646 if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) )
9647 return sal_False;
9648
9649 ImplGetWinData();
9650 if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized
9651 {
9652 // #113722#, cache result of expensive queryInterface call
9653 Window *pThisWin = (Window*)this;
9654 uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
9655 pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
9656 }
9657 return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? sal_True : sal_False;
9658 }
9659
ImplMirrorFramePos(Point & pt) const9660 void Window::ImplMirrorFramePos( Point &pt ) const
9661 {
9662 pt.X() = mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X();
9663 }
9664
9665 // frame based modal counter (dialogs are not modal to the whole application anymore)
IsInModalMode() const9666 sal_Bool Window::IsInModalMode() const
9667 {
9668 return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
9669 }
ImplIncModalCount()9670 void Window::ImplIncModalCount()
9671 {
9672 Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
9673 Window* pParent = pFrameWindow;
9674 while( pFrameWindow )
9675 {
9676 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
9677 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
9678 {
9679 pParent = pParent->GetParent();
9680 }
9681 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
9682 }
9683 }
ImplDecModalCount()9684 void Window::ImplDecModalCount()
9685 {
9686 Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
9687 Window* pParent = pFrameWindow;
9688 while( pFrameWindow )
9689 {
9690 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
9691 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
9692 {
9693 pParent = pParent->GetParent();
9694 }
9695 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
9696 }
9697 }
ImplIsInTaskPaneList()9698 sal_Bool Window::ImplIsInTaskPaneList()
9699 {
9700 return mpWindowImpl->mbIsInTaskPaneList;
9701 }
ImplIsInTaskPaneList(sal_Bool mbIsInTaskList)9702 void Window::ImplIsInTaskPaneList( sal_Bool mbIsInTaskList )
9703 {
9704 mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
9705 }
9706
ImplNotifyIconifiedState(sal_Bool bIconified)9707 void Window::ImplNotifyIconifiedState( sal_Bool bIconified )
9708 {
9709 mpWindowImpl->mpFrameWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
9710 // #109206# notify client window as well to have toolkit topwindow listeners notified
9711 if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
9712 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
9713 }
9714
HasActiveChildFrame()9715 sal_Bool Window::HasActiveChildFrame()
9716 {
9717 sal_Bool bRet = sal_False;
9718 Window *pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
9719 while( pFrameWin )
9720 {
9721 if( pFrameWin != mpWindowImpl->mpFrameWindow )
9722 {
9723 sal_Bool bDecorated = sal_False;
9724 Window *pChildFrame = pFrameWin->ImplGetWindow();
9725 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
9726 // be removed for ToolBoxes to influence the keyboard accessibility
9727 // thus WB_MOVEABLE is no indicator for decoration anymore
9728 // but FloatingWindows carry this information in their TitleType...
9729 // TODO: avoid duplicate WinBits !!!
9730 if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
9731 bDecorated = ((FloatingWindow*) pChildFrame)->GetTitleType() != FLOATWIN_TITLE_NONE;
9732 if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
9733 if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
9734 {
9735 if( ImplIsChild( pChildFrame, sal_True ) )
9736 {
9737 bRet = sal_True;
9738 break;
9739 }
9740 }
9741 }
9742 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
9743 }
9744 return bRet;
9745 }
9746
GetInputLanguage() const9747 LanguageType Window::GetInputLanguage() const
9748 {
9749 return mpWindowImpl->mpFrame->GetInputLanguage();
9750 }
9751
EnableNativeWidget(sal_Bool bEnable)9752 void Window::EnableNativeWidget( sal_Bool bEnable )
9753 {
9754 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
9755 if( pNoNWF && *pNoNWF )
9756 bEnable = sal_False;
9757
9758 if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
9759 {
9760 ImplGetWinData()->mbEnableNativeWidget = bEnable;
9761
9762 // send datachanged event to allow for internal changes required for NWF
9763 // like clipmode, transparency, etc.
9764 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &maSettings, SETTINGS_STYLE );
9765 DataChanged( aDCEvt );
9766
9767 // sometimes the borderwindow is queried, so keep it in sync
9768 if( mpWindowImpl->mpBorderWindow )
9769 mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
9770 }
9771
9772 // push down, useful for compound controls
9773 Window *pChild = mpWindowImpl->mpFirstChild;
9774 while( pChild )
9775 {
9776 pChild->EnableNativeWidget( bEnable );
9777 pChild = pChild->mpWindowImpl->mpNext;
9778 }
9779 }
9780
IsNativeWidgetEnabled() const9781 sal_Bool Window::IsNativeWidgetEnabled() const
9782 {
9783 return ImplGetWinData()->mbEnableNativeWidget;
9784 }
9785
9786 #ifdef WNT // see #140456#
9787 #include <win/salframe.h>
9788 #endif
9789
ImplGetCanvas(const Size & rFullscreenSize,bool bFullscreen,bool bSpriteCanvas) const9790 uno::Reference< rendering::XCanvas > Window::ImplGetCanvas( const Size& rFullscreenSize,
9791 bool bFullscreen,
9792 bool bSpriteCanvas ) const
9793 {
9794 // try to retrieve hard reference from weak member
9795 uno::Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
9796
9797 // canvas still valid? Then we're done.
9798 if( xCanvas.is() )
9799 return xCanvas;
9800
9801 Sequence< Any > aArg(6);
9802
9803 // Feed any with operating system's window handle
9804 // ==============================================
9805
9806 // common: first any is VCL pointer to window (for VCL canvas)
9807 aArg[ 0 ] = makeAny( reinterpret_cast<sal_Int64>(this) );
9808
9809 // TODO(Q1): Make GetSystemData method virtual
9810
9811 // check whether we're a SysChild: have to fetch system data
9812 // directly from SystemChildWindow, because the GetSystemData
9813 // method is unfortunately not virtual
9814 const SystemChildWindow* pSysChild = dynamic_cast< const SystemChildWindow* >( this );
9815 if( pSysChild )
9816 {
9817 aArg[ 1 ] = pSysChild->GetSystemDataAny();
9818 aArg[ 5 ] = pSysChild->GetSystemGfxDataAny();
9819 }
9820 else
9821 {
9822 aArg[ 1 ] = GetSystemDataAny();
9823 aArg[ 5 ] = GetSystemGfxDataAny();
9824 }
9825
9826 if( bFullscreen )
9827 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( 0, 0,
9828 rFullscreenSize.Width(),
9829 rFullscreenSize.Height() ) );
9830 else
9831 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
9832
9833 aArg[ 3 ] = makeAny( mpWindowImpl->mbAlwaysOnTop ? sal_True : sal_False );
9834 aArg[ 4 ] = makeAny( uno::Reference< awt::XWindow >(
9835 const_cast<Window*>(this)->GetComponentInterface(),
9836 uno::UNO_QUERY ));
9837
9838 uno::Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
9839
9840 // Create canvas instance with window handle
9841 // =========================================
9842 if ( xFactory.is() )
9843 {
9844 static ::vcl::DeleteUnoReferenceOnDeinit<lang::XMultiServiceFactory> xStaticCanvasFactory(
9845 uno::Reference<lang::XMultiServiceFactory>(
9846 xFactory->createInstance(
9847 OUString( RTL_CONSTASCII_USTRINGPARAM(
9848 "com.sun.star.rendering.CanvasFactory") ) ),
9849 UNO_QUERY ));
9850 uno::Reference<lang::XMultiServiceFactory> xCanvasFactory(xStaticCanvasFactory.get());
9851
9852 if(xCanvasFactory.is())
9853 {
9854 #ifdef WNT
9855 // see #140456# - if we're running on a multiscreen setup,
9856 // request special, multi-screen safe sprite canvas
9857 // implementation (not DX5 canvas, as it cannot cope with
9858 // surfaces spanning multiple displays). Note: canvas
9859 // (without sprite) stays the same)
9860 const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay;
9861 if( (nDisplay >= Application::GetScreenCount()) )
9862 {
9863 xCanvas.set( xCanvasFactory->createInstanceWithArguments(
9864 bSpriteCanvas ?
9865 OUString( RTL_CONSTASCII_USTRINGPARAM(
9866 "com.sun.star.rendering.SpriteCanvas.MultiScreen" )) :
9867 OUString( RTL_CONSTASCII_USTRINGPARAM(
9868 "com.sun.star.rendering.Canvas.MultiScreen" )),
9869 aArg ),
9870 UNO_QUERY );
9871
9872 }
9873 else
9874 {
9875 #endif
9876 xCanvas.set( xCanvasFactory->createInstanceWithArguments(
9877 bSpriteCanvas ?
9878 OUString( RTL_CONSTASCII_USTRINGPARAM(
9879 "com.sun.star.rendering.SpriteCanvas" )) :
9880 OUString( RTL_CONSTASCII_USTRINGPARAM(
9881 "com.sun.star.rendering.Canvas" )),
9882 aArg ),
9883 UNO_QUERY );
9884
9885 #ifdef WNT
9886 }
9887 #endif
9888
9889 mpWindowImpl->mxCanvas = xCanvas;
9890 }
9891 }
9892
9893 // no factory??? Empty reference, then.
9894 return xCanvas;
9895 }
9896
GetCanvas() const9897 uno::Reference< rendering::XCanvas > Window::GetCanvas() const
9898 {
9899 return ImplGetCanvas( Size(), false, false );
9900 }
9901
GetSpriteCanvas() const9902 uno::Reference< rendering::XSpriteCanvas > Window::GetSpriteCanvas() const
9903 {
9904 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas(
9905 ImplGetCanvas( Size(), false, true ), uno::UNO_QUERY );
9906 return xSpriteCanvas;
9907 }
9908
GetFullscreenSpriteCanvas(const Size & rFullscreenSize) const9909 uno::Reference< ::com::sun::star::rendering::XSpriteCanvas > Window::GetFullscreenSpriteCanvas( const Size& rFullscreenSize ) const
9910 {
9911 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas(
9912 ImplGetCanvas( rFullscreenSize, true, true ), uno::UNO_QUERY );
9913 return xSpriteCanvas;
9914 }
9915
ImplPaintToDevice(OutputDevice * i_pTargetOutDev,const Point & i_rPos)9916 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
9917 {
9918 sal_Bool bRVisible = mpWindowImpl->mbReallyVisible;
9919 mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
9920 sal_Bool bDevOutput = mbDevOutput;
9921 mbDevOutput = sal_True;
9922
9923 long nOldDPIX = ImplGetDPIX();
9924 long nOldDPIY = ImplGetDPIY();
9925 mnDPIX = i_pTargetOutDev->ImplGetDPIX();
9926 mnDPIY = i_pTargetOutDev->ImplGetDPIY();
9927 sal_Bool bOutput = IsOutputEnabled();
9928 EnableOutput();
9929
9930 DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
9931 if ( GetMapMode().GetMapUnit() != MAP_PIXEL )
9932 return;
9933
9934 // preserve graphicsstate
9935 Push();
9936 Region aClipRegion( GetClipRegion() );
9937 SetClipRegion();
9938
9939 GDIMetaFile* pOldMtf = GetConnectMetaFile();
9940 GDIMetaFile aMtf;
9941 SetConnectMetaFile( &aMtf );
9942
9943 // put a push action to metafile
9944 Push();
9945 // copy graphics state to metafile
9946 Font aCopyFont = GetFont();
9947 if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY )
9948 {
9949 aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY );
9950 aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX );
9951 }
9952 SetFont( aCopyFont );
9953 SetTextColor( GetTextColor() );
9954 if( IsLineColor() )
9955 SetLineColor( GetLineColor() );
9956 else
9957 SetLineColor();
9958 if( IsFillColor() )
9959 SetFillColor( GetFillColor() );
9960 else
9961 SetFillColor();
9962 if( IsTextLineColor() )
9963 SetTextLineColor( GetTextLineColor() );
9964 else
9965 SetTextLineColor();
9966 if( IsOverlineColor() )
9967 SetOverlineColor( GetOverlineColor() );
9968 else
9969 SetOverlineColor();
9970 if( IsTextFillColor() )
9971 SetTextFillColor( GetTextFillColor() );
9972 else
9973 SetTextFillColor();
9974 SetTextAlign( GetTextAlign() );
9975 SetRasterOp( GetRasterOp() );
9976 if( IsRefPoint() )
9977 SetRefPoint( GetRefPoint() );
9978 else
9979 SetRefPoint();
9980 SetLayoutMode( GetLayoutMode() );
9981 SetDigitLanguage( GetDigitLanguage() );
9982 Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() );
9983 aClipRegion.Intersect( aPaintRect );
9984 SetClipRegion( aClipRegion );
9985
9986 // do the actual paint
9987
9988 // background
9989 if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & PARENTCLIPMODE_NOCLIP ) )
9990 Erase();
9991 // foreground
9992 Paint( aPaintRect );
9993 // put a pop action to metafile
9994 Pop();
9995
9996 SetConnectMetaFile( pOldMtf );
9997 EnableOutput( bOutput );
9998 mpWindowImpl->mbReallyVisible = bRVisible;
9999
10000 // paint metafile to VDev
10001 VirtualDevice* pMaskedDevice = new VirtualDevice( *i_pTargetOutDev, 0, 0 );
10002 pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
10003 pMaskedDevice->EnableRTL( IsRTLEnabled() );
10004 aMtf.WindStart();
10005 aMtf.Play( pMaskedDevice );
10006 BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) );
10007 i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
10008 // get rid of virtual device now so they don't pile up during recursive calls
10009 delete pMaskedDevice, pMaskedDevice = NULL;
10010
10011
10012 for( Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
10013 {
10014 if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
10015 {
10016 long nDeltaX = pChild->mnOutOffX - mnOutOffX;
10017 if( ImplHasMirroredGraphics() )
10018 nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth;
10019 long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
10020 Point aPos( i_rPos );
10021 Point aDelta( nDeltaX, nDeltaY );
10022 aPos += aDelta;
10023 pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
10024 }
10025 }
10026
10027 // restore graphics state
10028 Pop();
10029
10030 EnableOutput( bOutput );
10031 mpWindowImpl->mbReallyVisible = bRVisible;
10032 mbDevOutput = bDevOutput;
10033 mnDPIX = nOldDPIX;
10034 mnDPIY = nOldDPIY;
10035 }
10036
PaintToDevice(OutputDevice * pDev,const Point & rPos,const Size &)10037 void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ )
10038 {
10039 // FIXME: scaling: currently this is for pixel copying only
10040
10041 DBG_ASSERT( ! pDev->ImplHasMirroredGraphics(), "PaintToDevice to mirroring graphics" );
10042 DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" );
10043
10044
10045 Point aPos = pDev->LogicToPixel( rPos );
10046
10047 Window* pRealParent = NULL;
10048 if( ! mpWindowImpl->mbVisible )
10049 {
10050 Window* pTempParent = ImplGetDefaultWindow();
10051 if( pTempParent )
10052 pTempParent->EnableChildTransparentMode();
10053 pRealParent = GetParent();
10054 SetParent( pTempParent );
10055 // trigger correct visibility flags for children
10056 Show();
10057 Hide();
10058 }
10059
10060 sal_Bool bVisible = mpWindowImpl->mbVisible;
10061 mpWindowImpl->mbVisible = sal_True;
10062
10063 if( mpWindowImpl->mpBorderWindow )
10064 mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
10065 else
10066 ImplPaintToDevice( pDev, rPos );
10067
10068 mpWindowImpl->mbVisible = bVisible;
10069
10070 if( pRealParent )
10071 SetParent( pRealParent );
10072 }
10073
GetSurroundingText() const10074 XubString Window::GetSurroundingText() const
10075 {
10076 return XubString::EmptyString();
10077 }
10078
GetSurroundingTextSelection() const10079 Selection Window::GetSurroundingTextSelection() const
10080 {
10081 return Selection( 0, 0 );
10082 }
10083