Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/window.hxx>
21 : #include <vcl/taskpanelist.hxx>
22 :
23 : // declare system types in sysdata.hxx
24 : #include <vcl/sysdata.hxx>
25 :
26 : #include <salframe.hxx>
27 : #include <salobj.hxx>
28 : #include <salgdi.hxx>
29 : #include <svdata.hxx>
30 : #include <window.h>
31 : #include <brdwin.hxx>
32 : #include <helpwin.hxx>
33 :
34 : #include <com/sun/star/awt/XTopWindow.hpp>
35 :
36 : #include <set>
37 : #include <typeinfo>
38 :
39 : using namespace ::com::sun::star::uno;
40 : using namespace ::com::sun::star::lang;
41 : using namespace ::com::sun::star::datatransfer::clipboard;
42 : using namespace ::com::sun::star::datatransfer::dnd;
43 : using namespace ::com::sun::star;
44 :
45 : using ::com::sun::star::awt::XTopWindow;
46 :
47 7614 : struct ImplCalcToTopData
48 : {
49 : ImplCalcToTopData* mpNext;
50 : VclPtr<vcl::Window> mpWindow;
51 : vcl::Region* mpInvalidateRegion;
52 : };
53 :
54 : namespace vcl {
55 :
56 0 : vcl::Window* Window::ImplGetTopmostFrameWindow()
57 : {
58 0 : vcl::Window *pTopmostParent = this;
59 0 : while( pTopmostParent->ImplGetParent() )
60 0 : pTopmostParent = pTopmostParent->ImplGetParent();
61 0 : return pTopmostParent->mpWindowImpl->mpFrameWindow;
62 : }
63 :
64 290235 : void Window::ImplInsertWindow( vcl::Window* pParent )
65 : {
66 290235 : mpWindowImpl->mpParent = pParent;
67 290235 : mpWindowImpl->mpRealParent = pParent;
68 :
69 290235 : if ( pParent && !mpWindowImpl->mbFrame )
70 : {
71 : // search frame window and set window frame data
72 283284 : vcl::Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
73 283284 : mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
74 283284 : mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
75 283284 : mpWindowImpl->mpFrameWindow = pFrameParent;
76 283284 : mpWindowImpl->mbFrame = false;
77 :
78 : // search overlap window and insert window in list
79 283284 : if ( ImplIsOverlapWindow() )
80 : {
81 0 : vcl::Window* pFirstOverlapParent = pParent;
82 0 : while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
83 0 : pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
84 0 : mpWindowImpl->mpOverlapWindow = pFirstOverlapParent;
85 :
86 0 : mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap;
87 0 : mpWindowImpl->mpFrameData->mpFirstOverlap = this;
88 :
89 : // Overlap-Windows are by default the uppermost
90 0 : mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap;
91 0 : pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this;
92 0 : if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap )
93 0 : pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this;
94 : else
95 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
96 : }
97 : else
98 : {
99 283284 : if ( pParent->ImplIsOverlapWindow() )
100 10171 : mpWindowImpl->mpOverlapWindow = pParent;
101 : else
102 273113 : mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
103 283284 : mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
104 283284 : pParent->mpWindowImpl->mpLastChild = this;
105 283284 : if ( !pParent->mpWindowImpl->mpFirstChild )
106 106484 : pParent->mpWindowImpl->mpFirstChild = this;
107 : else
108 176800 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
109 : }
110 : }
111 290235 : }
112 :
113 292144 : void Window::ImplRemoveWindow( bool bRemoveFrameData )
114 : {
115 : // remove window from the lists
116 292144 : if ( !mpWindowImpl->mbFrame )
117 : {
118 285212 : if ( ImplIsOverlapWindow() )
119 : {
120 0 : if ( mpWindowImpl->mpFrameData->mpFirstOverlap.get() == this )
121 0 : mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap;
122 : else
123 : {
124 0 : vcl::Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
125 0 : while ( pTempWin->mpWindowImpl->mpNextOverlap.get() != this )
126 0 : pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
127 0 : pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap;
128 : }
129 :
130 0 : if ( mpWindowImpl->mpPrev )
131 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
132 : else
133 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
134 0 : if ( mpWindowImpl->mpNext )
135 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
136 : else
137 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
138 : }
139 : else
140 : {
141 285212 : if ( mpWindowImpl->mpPrev )
142 123605 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
143 161607 : else if ( mpWindowImpl->mpParent )
144 161604 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
145 285212 : if ( mpWindowImpl->mpNext )
146 103498 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
147 181714 : else if ( mpWindowImpl->mpParent )
148 181711 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
149 : }
150 :
151 285212 : mpWindowImpl->mpPrev = NULL;
152 285212 : mpWindowImpl->mpNext = NULL;
153 : }
154 :
155 292144 : if ( bRemoveFrameData )
156 : {
157 : // release the graphic
158 276607 : OutputDevice *pOutDev = GetOutDev();
159 276607 : pOutDev->ReleaseGraphics();
160 : }
161 292144 : }
162 :
163 26687 : void Window::reorderWithinParent(sal_uInt16 nNewPosition)
164 : {
165 26687 : sal_uInt16 nChildCount = 0;
166 26687 : vcl::Window *pSource = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
167 80212 : while (pSource)
168 : {
169 53525 : if (nChildCount == nNewPosition)
170 26687 : break;
171 26838 : pSource = pSource->mpWindowImpl->mpNext;
172 26838 : nChildCount++;
173 : }
174 :
175 26687 : if (pSource == this) //already at the right place
176 51041 : return;
177 :
178 2333 : ImplRemoveWindow(false);
179 :
180 2333 : if (pSource)
181 : {
182 2333 : mpWindowImpl->mpNext = pSource;
183 2333 : mpWindowImpl->mpPrev = pSource->mpWindowImpl->mpPrev;
184 2333 : pSource->mpWindowImpl->mpPrev = this;
185 : }
186 : else
187 0 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
188 :
189 2333 : if (mpWindowImpl->mpPrev)
190 1169 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
191 : else
192 1164 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
193 : }
194 :
195 6393 : void Window::ImplToBottomChild()
196 : {
197 6393 : if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild.get() != this) )
198 : {
199 : // put the window to the end of the list
200 844 : if ( mpWindowImpl->mpPrev )
201 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
202 : else
203 844 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
204 844 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
205 844 : mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
206 844 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
207 844 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
208 844 : mpWindowImpl->mpNext = NULL;
209 : }
210 6393 : }
211 :
212 3807 : void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
213 : {
214 : DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
215 :
216 3807 : if ( !mpWindowImpl->mbFrame )
217 : {
218 0 : if ( IsReallyVisible() )
219 : {
220 : // calculate region, where the window overlaps with other windows
221 0 : Point aPoint( mnOutOffX, mnOutOffY );
222 : vcl::Region aRegion( Rectangle( aPoint,
223 0 : Size( mnOutWidth, mnOutHeight ) ) );
224 0 : vcl::Region aInvalidateRegion;
225 0 : ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
226 :
227 0 : if ( !aInvalidateRegion.IsEmpty() )
228 : {
229 0 : ImplCalcToTopData* pData = new ImplCalcToTopData;
230 0 : pPrevData->mpNext = pData;
231 0 : pData->mpNext = NULL;
232 0 : pData->mpWindow = this;
233 0 : pData->mpInvalidateRegion = new vcl::Region( aInvalidateRegion );
234 0 : }
235 : }
236 : }
237 3807 : }
238 :
239 3807 : void Window::ImplToTop( ToTopFlags nFlags )
240 : {
241 : DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
242 :
243 3807 : if ( mpWindowImpl->mbFrame )
244 : {
245 : // on a mouse click in the external window, it is the latter's
246 : // responsibility to assure our frame is put in front
247 6951 : if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
248 6288 : !mpWindowImpl->mpFrameData->mbSysObjFocus &&
249 6288 : !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
250 3144 : !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
251 : {
252 : // do not bring floating windows on the client to top
253 3144 : if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
254 : {
255 3144 : sal_uInt16 nSysFlags = 0;
256 3144 : if ( nFlags & ToTopFlags::RestoreWhenMin )
257 13 : nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN;
258 3144 : if ( nFlags & ToTopFlags::ForegroundTask )
259 0 : nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK;
260 3144 : if ( nFlags & ToTopFlags::GrabFocusOnly )
261 0 : nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY;
262 3144 : mpWindowImpl->mpFrame->ToTop( nSysFlags );
263 : }
264 : }
265 : }
266 : else
267 : {
268 0 : if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap.get() != this )
269 : {
270 : // remove window from the list
271 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
272 0 : if ( mpWindowImpl->mpNext )
273 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
274 : else
275 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
276 :
277 : // take AlwaysOnTop into account
278 0 : bool bOnTop = IsAlwaysOnTopEnabled();
279 0 : vcl::Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
280 0 : if ( !bOnTop )
281 : {
282 0 : while ( pNextWin )
283 : {
284 0 : if ( !pNextWin->IsAlwaysOnTopEnabled() )
285 0 : break;
286 0 : pNextWin = pNextWin->mpWindowImpl->mpNext;
287 : }
288 : }
289 :
290 : // check TopLevel
291 0 : sal_uInt8 nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel;
292 0 : while ( pNextWin )
293 : {
294 0 : if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) ||
295 0 : (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) )
296 0 : break;
297 0 : pNextWin = pNextWin->mpWindowImpl->mpNext;
298 : }
299 :
300 : // add the window to the list again
301 0 : mpWindowImpl->mpNext = pNextWin;
302 0 : if ( pNextWin )
303 : {
304 0 : mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
305 0 : pNextWin->mpWindowImpl->mpPrev = this;
306 : }
307 : else
308 : {
309 0 : mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
310 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
311 : }
312 0 : if ( mpWindowImpl->mpPrev )
313 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
314 : else
315 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
316 :
317 : // recalculate ClipRegion of this and all overlapping windows
318 0 : if ( IsReallyVisible() )
319 : {
320 : // reset background storage
321 0 : if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
322 0 : ImplInvalidateAllOverlapBackgrounds();
323 0 : mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
324 : }
325 : }
326 : }
327 3807 : }
328 :
329 3807 : void Window::ImplStartToTop( ToTopFlags nFlags )
330 : {
331 3807 : ImplCalcToTopData aStartData;
332 : ImplCalcToTopData* pCurData;
333 : ImplCalcToTopData* pNextData;
334 : vcl::Window* pOverlapWindow;
335 3807 : if ( ImplIsOverlapWindow() )
336 3183 : pOverlapWindow = this;
337 : else
338 624 : pOverlapWindow = mpWindowImpl->mpOverlapWindow;
339 :
340 : // first calculate paint areas
341 3807 : vcl::Window* pTempOverlapWindow = pOverlapWindow;
342 3807 : aStartData.mpNext = NULL;
343 3807 : pCurData = &aStartData;
344 3807 : do
345 : {
346 3807 : pTempOverlapWindow->ImplCalcToTop( pCurData );
347 3807 : if ( pCurData->mpNext )
348 0 : pCurData = pCurData->mpNext;
349 3807 : pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
350 : }
351 3807 : while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
352 : // next calculate the paint areas of the ChildOverlap windows
353 3807 : pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
354 7614 : while ( pTempOverlapWindow )
355 : {
356 0 : pTempOverlapWindow->ImplCalcToTop( pCurData );
357 0 : if ( pCurData->mpNext )
358 0 : pCurData = pCurData->mpNext;
359 0 : pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
360 : }
361 :
362 : // and next change the windows list
363 3807 : pTempOverlapWindow = pOverlapWindow;
364 3807 : do
365 : {
366 3807 : pTempOverlapWindow->ImplToTop( nFlags );
367 3807 : pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
368 : }
369 3807 : while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
370 : // as last step invalidate the invalid areas
371 3807 : pCurData = aStartData.mpNext;
372 7614 : while ( pCurData )
373 : {
374 0 : pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, InvalidateFlags::Children );
375 0 : pNextData = pCurData->mpNext;
376 0 : delete pCurData->mpInvalidateRegion;
377 0 : delete pCurData;
378 0 : pCurData = pNextData;
379 3807 : }
380 3807 : }
381 :
382 3807 : void Window::ImplFocusToTop( ToTopFlags nFlags, bool bReallyVisible )
383 : {
384 : // do we need to fetch the focus?
385 3807 : if ( !(nFlags & ToTopFlags::NoGrabFocus) )
386 : {
387 : // first window with GrabFocus-Activate gets the focus
388 3807 : vcl::Window* pFocusWindow = this;
389 8238 : while ( !pFocusWindow->ImplIsOverlapWindow() )
390 : {
391 : // if the window has no BorderWindow, we
392 : // should always find the belonging BorderWindow
393 624 : if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
394 : {
395 0 : if ( pFocusWindow->mpWindowImpl->mnActivateMode & ActivateModeFlags::GrabFocus )
396 0 : break;
397 : }
398 624 : pFocusWindow = pFocusWindow->ImplGetParent();
399 : }
400 11421 : if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ActivateModeFlags::GrabFocus) &&
401 7614 : !pFocusWindow->HasChildPathFocus( true ) )
402 3302 : pFocusWindow->GrabFocus();
403 : }
404 :
405 3807 : if ( bReallyVisible )
406 617 : ImplGenerateMouseMove();
407 3807 : }
408 :
409 181878 : void Window::ImplShowAllOverlaps()
410 : {
411 181878 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
412 363756 : while ( pOverlapWindow )
413 : {
414 0 : if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
415 : {
416 0 : pOverlapWindow->Show( true, ShowFlags::NoActivate );
417 0 : pOverlapWindow->mpWindowImpl->mbOverlapVisible = false;
418 : }
419 :
420 0 : pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
421 : }
422 181878 : }
423 :
424 181652 : void Window::ImplHideAllOverlaps()
425 : {
426 181652 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
427 363304 : while ( pOverlapWindow )
428 : {
429 0 : if ( pOverlapWindow->IsVisible() )
430 : {
431 0 : pOverlapWindow->mpWindowImpl->mbOverlapVisible = true;
432 0 : pOverlapWindow->Show( false );
433 : }
434 :
435 0 : pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
436 : }
437 181652 : }
438 :
439 624 : void Window::ToTop( ToTopFlags nFlags )
440 : {
441 :
442 624 : ImplStartToTop( nFlags );
443 624 : ImplFocusToTop( nFlags, IsReallyVisible() );
444 624 : }
445 :
446 54 : void Window::SetZOrder( vcl::Window* pRefWindow, ZOrderFlags nFlags )
447 : {
448 :
449 54 : if ( mpWindowImpl->mpBorderWindow )
450 : {
451 15 : mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
452 15 : return;
453 : }
454 :
455 39 : if ( nFlags & ZOrderFlags::First )
456 : {
457 0 : if ( ImplIsOverlapWindow() )
458 0 : pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
459 : else
460 0 : pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
461 0 : nFlags |= ZOrderFlags::Before;
462 : }
463 39 : else if ( nFlags & ZOrderFlags::Last )
464 : {
465 0 : if ( ImplIsOverlapWindow() )
466 0 : pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
467 : else
468 0 : pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
469 0 : nFlags |= ZOrderFlags::Behind;
470 : }
471 :
472 93 : while ( pRefWindow && pRefWindow->mpWindowImpl->mpBorderWindow )
473 15 : pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
474 39 : if (!pRefWindow || pRefWindow == this || mpWindowImpl->mbFrame)
475 0 : return;
476 :
477 : DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" );
478 39 : if ( nFlags & ZOrderFlags::Before )
479 : {
480 0 : if ( pRefWindow->mpWindowImpl->mpPrev.get() == this )
481 0 : return;
482 :
483 0 : if ( ImplIsOverlapWindow() )
484 : {
485 0 : if ( mpWindowImpl->mpPrev )
486 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
487 : else
488 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
489 0 : if ( mpWindowImpl->mpNext )
490 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
491 : else
492 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
493 0 : if ( !pRefWindow->mpWindowImpl->mpPrev )
494 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
495 : }
496 : else
497 : {
498 0 : if ( mpWindowImpl->mpPrev )
499 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
500 : else
501 0 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
502 0 : if ( mpWindowImpl->mpNext )
503 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
504 : else
505 0 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
506 0 : if ( !pRefWindow->mpWindowImpl->mpPrev )
507 0 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
508 : }
509 :
510 0 : mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev;
511 0 : mpWindowImpl->mpNext = pRefWindow;
512 0 : if ( mpWindowImpl->mpPrev )
513 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
514 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
515 : }
516 39 : else if ( nFlags & ZOrderFlags::Behind )
517 : {
518 39 : if ( pRefWindow->mpWindowImpl->mpNext.get() == this )
519 35 : return;
520 :
521 4 : if ( ImplIsOverlapWindow() )
522 : {
523 0 : if ( mpWindowImpl->mpPrev )
524 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
525 : else
526 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
527 0 : if ( mpWindowImpl->mpNext )
528 0 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
529 : else
530 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
531 0 : if ( !pRefWindow->mpWindowImpl->mpNext )
532 0 : mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
533 : }
534 : else
535 : {
536 4 : if ( mpWindowImpl->mpPrev )
537 2 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
538 : else
539 2 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
540 4 : if ( mpWindowImpl->mpNext )
541 4 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
542 : else
543 0 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
544 4 : if ( !pRefWindow->mpWindowImpl->mpNext )
545 3 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
546 : }
547 :
548 4 : mpWindowImpl->mpPrev = pRefWindow;
549 4 : mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
550 4 : if ( mpWindowImpl->mpNext )
551 1 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
552 4 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
553 : }
554 :
555 4 : if ( IsReallyVisible() )
556 : {
557 : // restore background storage
558 4 : if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
559 0 : ImplInvalidateAllOverlapBackgrounds();
560 :
561 4 : if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
562 : {
563 4 : bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion;
564 4 : ImplSetClipFlag();
565 :
566 : // When ClipRegion was not initialised, assume
567 : // the window has not been sent, therefore do not
568 : // trigger any Invalidates. This is an optimization
569 : // for HTML documents with many controls. If this
570 : // check gives problems, a flag should be introduced
571 : // which tracks whether the window has already been
572 : // emitted after Show
573 4 : if ( !bInitWinClipRegion )
574 : {
575 : // Invalidate all windows which are next to each other
576 : // Is INCOMPLETE !!!
577 0 : Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
578 0 : vcl::Window* pWindow = NULL;
579 0 : if ( ImplIsOverlapWindow() )
580 : {
581 0 : if ( mpWindowImpl->mpOverlapWindow )
582 0 : pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
583 : }
584 : else
585 0 : pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
586 : // Invalidate all windows in front of us and which are covered by us
587 0 : while ( pWindow )
588 : {
589 0 : if ( pWindow == this )
590 0 : break;
591 : Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
592 0 : Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
593 0 : if ( aWinRect.IsOver( aCompRect ) )
594 0 : pWindow->Invalidate( InvalidateFlags::Children | InvalidateFlags::NoTransparent );
595 0 : pWindow = pWindow->mpWindowImpl->mpNext;
596 : }
597 :
598 : // If we are covered by a window in the background
599 : // we should redraw it
600 0 : while ( pWindow )
601 : {
602 0 : if ( pWindow != this )
603 : {
604 : Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
605 0 : Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
606 0 : if ( aWinRect.IsOver( aCompRect ) )
607 : {
608 0 : Invalidate( InvalidateFlags::Children | InvalidateFlags::NoTransparent );
609 0 : break;
610 : }
611 : }
612 0 : pWindow = pWindow->mpWindowImpl->mpNext;
613 : }
614 : }
615 : }
616 : }
617 : }
618 :
619 0 : void Window::EnableAlwaysOnTop( bool bEnable )
620 : {
621 :
622 0 : mpWindowImpl->mbAlwaysOnTop = bEnable;
623 :
624 0 : if ( mpWindowImpl->mpBorderWindow )
625 0 : mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable );
626 0 : else if ( bEnable && IsReallyVisible() )
627 0 : ToTop();
628 :
629 0 : if ( mpWindowImpl->mbFrame )
630 0 : mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable );
631 0 : }
632 :
633 595260 : bool Window::IsTopWindow() const
634 : {
635 595260 : if ( !mpWindowImpl || mpWindowImpl->mbInDispose )
636 0 : return false;
637 :
638 : // topwindows must be frames or they must have a borderwindow which is a frame
639 595260 : if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) )
640 16 : return false;
641 :
642 595244 : ImplGetWinData();
643 595244 : if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized
644 : {
645 : // #113722#, cache result of expensive queryInterface call
646 13006 : vcl::Window *pThisWin = const_cast<vcl::Window*>(this);
647 13006 : uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
648 13006 : pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
649 : }
650 595244 : return mpWindowImpl->mpWinData->mnIsTopWindow == 1;
651 : }
652 :
653 0 : vcl::Window* Window::FindWindow( const Point& rPos ) const
654 : {
655 :
656 0 : Point aPos = OutputToScreenPixel( rPos );
657 0 : return const_cast<vcl::Window*>(this)->ImplFindWindow( aPos );
658 : }
659 :
660 0 : vcl::Window* Window::ImplFindWindow( const Point& rFramePos )
661 : {
662 : vcl::Window* pTempWindow;
663 : vcl::Window* pFindWindow;
664 :
665 : // first check all overlapping windows
666 0 : pTempWindow = mpWindowImpl->mpFirstOverlap;
667 0 : while ( pTempWindow )
668 : {
669 0 : pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
670 0 : if ( pFindWindow )
671 0 : return pFindWindow;
672 0 : pTempWindow = pTempWindow->mpWindowImpl->mpNext;
673 : }
674 :
675 : // then we check our window
676 0 : if ( !mpWindowImpl->mbVisible )
677 0 : return NULL;
678 :
679 0 : sal_uInt16 nHitTest = ImplHitTest( rFramePos );
680 0 : if ( nHitTest & WINDOW_HITTEST_INSIDE )
681 : {
682 : // and then we check all child windows
683 0 : pTempWindow = mpWindowImpl->mpFirstChild;
684 0 : while ( pTempWindow )
685 : {
686 0 : pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
687 0 : if ( pFindWindow )
688 0 : return pFindWindow;
689 0 : pTempWindow = pTempWindow->mpWindowImpl->mpNext;
690 : }
691 :
692 0 : if ( nHitTest & WINDOW_HITTEST_TRANSPARENT )
693 0 : return NULL;
694 : else
695 0 : return this;
696 : }
697 :
698 0 : return NULL;
699 : }
700 :
701 385416 : bool Window::ImplIsRealParentPath( const vcl::Window* pWindow ) const
702 : {
703 385416 : pWindow = pWindow->GetParent();
704 2219441 : while ( pWindow )
705 : {
706 1454166 : if ( pWindow == this )
707 5557 : return true;
708 1448609 : pWindow = pWindow->GetParent();
709 : }
710 :
711 379859 : return false;
712 : }
713 :
714 1025898 : bool Window::ImplIsChild( const vcl::Window* pWindow, bool bSystemWindow ) const
715 : {
716 787729 : do
717 : {
718 1025898 : if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
719 194484 : break;
720 :
721 831414 : pWindow = pWindow->ImplGetParent();
722 :
723 831414 : if ( pWindow == this )
724 43685 : return true;
725 : }
726 : while ( pWindow );
727 :
728 222159 : return false;
729 : }
730 :
731 81825 : bool Window::ImplIsWindowOrChild( const vcl::Window* pWindow, bool bSystemWindow ) const
732 : {
733 81825 : if ( this == pWindow )
734 2830 : return true;
735 78995 : return ImplIsChild( pWindow, bSystemWindow );
736 : }
737 :
738 108220 : void Window::ImplResetReallyVisible()
739 : {
740 108220 : bool bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
741 :
742 108220 : mbDevOutput = false;
743 108220 : mpWindowImpl->mbReallyVisible = false;
744 108220 : mpWindowImpl->mbReallyShown = false;
745 :
746 : // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
747 : // For this, the data member of the event must not be NULL.
748 : // Previously, we did this in Window::Show, but there some events got lost in certain situations.
749 108220 : if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
750 102835 : CallEventListeners( VCLEVENT_WINDOW_HIDE, this );
751 : // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_HIDE. Normally, we should
752 : // introduce another event which explicitly triggers the Accessibility implementations.
753 :
754 108220 : vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
755 216440 : while ( pWindow )
756 : {
757 0 : if ( pWindow->mpWindowImpl->mbReallyVisible )
758 0 : pWindow->ImplResetReallyVisible();
759 0 : pWindow = pWindow->mpWindowImpl->mpNext;
760 : }
761 :
762 108220 : pWindow = mpWindowImpl->mpFirstChild;
763 287260 : while ( pWindow )
764 : {
765 70820 : if ( pWindow->mpWindowImpl->mbReallyVisible )
766 39268 : pWindow->ImplResetReallyVisible();
767 70820 : pWindow = pWindow->mpWindowImpl->mpNext;
768 : }
769 108220 : }
770 :
771 72960 : void Window::ImplUpdateWindowPtr( vcl::Window* pWindow )
772 : {
773 72960 : if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
774 : {
775 : // release graphic
776 20516 : OutputDevice *pOutDev = GetOutDev();
777 20516 : pOutDev->ReleaseGraphics();
778 : }
779 :
780 72960 : mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData;
781 72960 : mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
782 72960 : mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow;
783 72960 : if ( pWindow->ImplIsOverlapWindow() )
784 28 : mpWindowImpl->mpOverlapWindow = pWindow;
785 : else
786 72932 : mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
787 :
788 72960 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
789 199998 : while ( pChild )
790 : {
791 54078 : pChild->ImplUpdateWindowPtr( pWindow );
792 54078 : pChild = pChild->mpWindowImpl->mpNext;
793 : }
794 72960 : }
795 :
796 22398 : void Window::ImplUpdateWindowPtr()
797 : {
798 22398 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
799 63678 : while ( pChild )
800 : {
801 18882 : pChild->ImplUpdateWindowPtr( this );
802 18882 : pChild = pChild->mpWindowImpl->mpNext;
803 : }
804 22398 : }
805 :
806 0 : void Window::ImplUpdateOverlapWindowPtr( bool bNewFrame )
807 : {
808 0 : bool bVisible = IsVisible();
809 0 : Show( false );
810 0 : ImplRemoveWindow( bNewFrame );
811 0 : vcl::Window* pRealParent = mpWindowImpl->mpRealParent;
812 0 : ImplInsertWindow( ImplGetParent() );
813 0 : mpWindowImpl->mpRealParent = pRealParent;
814 0 : ImplUpdateWindowPtr();
815 0 : if ( ImplUpdatePos() )
816 0 : ImplUpdateSysObjPos();
817 :
818 0 : if ( bNewFrame )
819 : {
820 0 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
821 0 : while ( pOverlapWindow )
822 : {
823 0 : vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
824 0 : pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
825 0 : pOverlapWindow = pNextOverlapWindow;
826 : }
827 : }
828 :
829 0 : if ( bVisible )
830 0 : Show( true );
831 0 : }
832 :
833 14927 : SystemWindow* Window::GetSystemWindow() const
834 : {
835 :
836 14927 : const vcl::Window* pWin = this;
837 47619 : while ( pWin && !pWin->IsSystemWindow() )
838 17765 : pWin = pWin->GetParent();
839 14927 : return static_cast<SystemWindow*>(const_cast<Window*>(pWin));
840 : }
841 :
842 35574 : static SystemWindow *ImplGetLastSystemWindow( vcl::Window *pWin )
843 : {
844 : // get the most top-level system window, the one that contains the taskpanelist
845 35574 : SystemWindow *pSysWin = NULL;
846 35574 : if( !pWin )
847 0 : return pSysWin;
848 35574 : vcl::Window *pMyParent = pWin;
849 211828 : while ( pMyParent )
850 : {
851 140680 : if ( pMyParent->IsSystemWindow() )
852 35566 : pSysWin = static_cast<SystemWindow*>(pMyParent);
853 140680 : pMyParent = pMyParent->GetParent();
854 : }
855 35574 : return pSysWin;
856 : }
857 :
858 28888 : void Window::SetParent( vcl::Window* pNewParent )
859 : {
860 : DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" );
861 : DBG_ASSERT( pNewParent != this, "someone tried to reparent a window to itself" );
862 :
863 28888 : if( pNewParent == this )
864 0 : return;
865 :
866 : // check if the taskpanelist would change and move the window pointer accordingly
867 28888 : SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
868 28888 : SystemWindow *pNewSysWin = NULL;
869 28888 : bool bChangeTaskPaneList = false;
870 28888 : if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
871 : {
872 6686 : pNewSysWin = ImplGetLastSystemWindow( pNewParent );
873 6686 : if( pNewSysWin && pNewSysWin != pSysWin )
874 : {
875 0 : bChangeTaskPaneList = true;
876 0 : pSysWin->GetTaskPaneList()->RemoveWindow( this );
877 : }
878 : }
879 : // remove ownerdraw decorated windows from list in the top-most frame window
880 28888 : if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
881 : {
882 0 : ::std::vector< VclPtr<vcl::Window> >& rList = ImplGetOwnerDrawList();
883 0 : auto p = ::std::find( rList.begin(), rList.end(), VclPtr<vcl::Window>(this) );
884 0 : if( p != rList.end() )
885 0 : rList.erase( p );
886 : }
887 :
888 28888 : ImplSetFrameParent( pNewParent );
889 :
890 28888 : if ( mpWindowImpl->mpBorderWindow )
891 : {
892 6478 : mpWindowImpl->mpRealParent = pNewParent;
893 6478 : mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
894 6478 : return;
895 : }
896 :
897 22410 : if ( mpWindowImpl->mpParent.get() == pNewParent )
898 12 : return;
899 :
900 22398 : if ( mpWindowImpl->mbFrame )
901 10 : mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
902 :
903 22398 : bool bVisible = IsVisible();
904 22398 : Show( false, ShowFlags::NoFocusChange );
905 :
906 : // check if the overlap window changes
907 : vcl::Window* pOldOverlapWindow;
908 22398 : vcl::Window* pNewOverlapWindow = NULL;
909 22398 : if ( ImplIsOverlapWindow() )
910 10 : pOldOverlapWindow = NULL;
911 : else
912 : {
913 22388 : pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
914 22388 : if ( mpWindowImpl->mpOverlapWindow.get() != pNewOverlapWindow )
915 9184 : pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
916 : else
917 13204 : pOldOverlapWindow = NULL;
918 : }
919 :
920 : // convert windows in the hierarchy
921 22398 : bool bFocusOverlapWin = HasChildPathFocus( true );
922 22398 : bool bFocusWin = HasChildPathFocus();
923 22398 : bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
924 22398 : if ( bNewFrame )
925 : {
926 9194 : if ( mpWindowImpl->mpFrameData->mpFocusWin )
927 : {
928 4708 : if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
929 0 : mpWindowImpl->mpFrameData->mpFocusWin = NULL;
930 : }
931 9194 : if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
932 : {
933 0 : if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
934 0 : mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
935 : }
936 9194 : if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
937 : {
938 0 : if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
939 0 : mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
940 : }
941 : }
942 22398 : ImplRemoveWindow( bNewFrame );
943 22398 : ImplInsertWindow( pNewParent );
944 22398 : if ( mpWindowImpl->mnParentClipMode & ParentClipMode::Clip )
945 0 : pNewParent->mpWindowImpl->mbClipChildren = true;
946 22398 : ImplUpdateWindowPtr();
947 22398 : if ( ImplUpdatePos() )
948 0 : ImplUpdateSysObjPos();
949 :
950 : // If the Overlap-Window has changed, we need to test whether
951 : // OverlapWindows that had the Child window as their parent
952 : // need to be put into the window hierarchy.
953 22398 : if ( ImplIsOverlapWindow() )
954 : {
955 10 : if ( bNewFrame )
956 : {
957 10 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
958 20 : while ( pOverlapWindow )
959 : {
960 0 : vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
961 0 : pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
962 0 : pOverlapWindow = pNextOverlapWindow;
963 : }
964 : }
965 : }
966 22388 : else if ( pOldOverlapWindow )
967 : {
968 : // reset Focus-Save
969 18368 : if ( bFocusWin ||
970 4708 : (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
971 13892 : IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
972 0 : pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
973 :
974 9184 : vcl::Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
975 18368 : while ( pOverlapWindow )
976 : {
977 0 : vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
978 0 : if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
979 0 : pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
980 0 : pOverlapWindow = pNextOverlapWindow;
981 : }
982 :
983 : // update activate-status at next overlap window
984 9184 : if ( HasChildPathFocus( true ) )
985 0 : ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
986 : }
987 :
988 : // also convert Activate-Status
989 22398 : if ( bNewFrame )
990 : {
991 15670 : if ( (GetType() == WINDOW_BORDERWINDOW) &&
992 6476 : (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
993 8 : static_cast<ImplBorderWindow*>(this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
994 : }
995 :
996 : // when required give focus to new frame if
997 : // FocusWindow is changed with SetParent()
998 22398 : if ( bFocusOverlapWin )
999 : {
1000 20 : mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
1001 20 : if ( !mpWindowImpl->mpFrameData->mbHasFocus )
1002 : {
1003 0 : mpWindowImpl->mpFrame->ToTop( 0 );
1004 : }
1005 : }
1006 :
1007 : // Assure DragSource and DropTarget members are created
1008 22398 : if ( bNewFrame )
1009 : {
1010 9194 : GetDropTarget();
1011 : }
1012 :
1013 22398 : if( bChangeTaskPaneList )
1014 0 : pNewSysWin->GetTaskPaneList()->AddWindow( this );
1015 :
1016 22398 : if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
1017 0 : ImplGetOwnerDrawList().push_back( this );
1018 :
1019 22398 : if ( bVisible )
1020 73 : Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
1021 : }
1022 :
1023 80 : sal_uInt16 Window::GetChildCount() const
1024 : {
1025 80 : if (!mpWindowImpl)
1026 1 : return 0;
1027 :
1028 79 : sal_uInt16 nChildCount = 0;
1029 79 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
1030 328 : while ( pChild )
1031 : {
1032 170 : nChildCount++;
1033 170 : pChild = pChild->mpWindowImpl->mpNext;
1034 : }
1035 :
1036 79 : return nChildCount;
1037 : }
1038 :
1039 56 : vcl::Window* Window::GetChild( sal_uInt16 nChild ) const
1040 : {
1041 56 : if (!mpWindowImpl)
1042 2 : return NULL;
1043 :
1044 54 : sal_uInt16 nChildCount = 0;
1045 54 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
1046 152 : while ( pChild )
1047 : {
1048 98 : if ( nChild == nChildCount )
1049 54 : return pChild;
1050 44 : pChild = pChild->mpWindowImpl->mpNext;
1051 44 : nChildCount++;
1052 : }
1053 :
1054 0 : return NULL;
1055 : }
1056 :
1057 2789612 : vcl::Window* Window::GetWindow( GetWindowType nType ) const
1058 : {
1059 2789612 : if (!mpWindowImpl)
1060 2 : return 0;
1061 :
1062 2789610 : switch ( nType )
1063 : {
1064 : case GetWindowType::Parent:
1065 0 : return mpWindowImpl->mpRealParent;
1066 :
1067 : case GetWindowType::FirstChild:
1068 1493277 : return mpWindowImpl->mpFirstChild;
1069 :
1070 : case GetWindowType::LastChild:
1071 19300 : return mpWindowImpl->mpLastChild;
1072 :
1073 : case GetWindowType::Prev:
1074 7436 : return mpWindowImpl->mpPrev;
1075 :
1076 : case GetWindowType::Next:
1077 309846 : return mpWindowImpl->mpNext;
1078 :
1079 : case GetWindowType::FirstOverlap:
1080 267224 : return mpWindowImpl->mpFirstOverlap;
1081 :
1082 : case GetWindowType::LastOverlap:
1083 0 : return mpWindowImpl->mpLastOverlap;
1084 :
1085 : case GetWindowType::Overlap:
1086 267227 : if ( ImplIsOverlapWindow() )
1087 6828 : return const_cast<vcl::Window*>(this);
1088 : else
1089 260399 : return mpWindowImpl->mpOverlapWindow;
1090 :
1091 : case GetWindowType::ParentOverlap:
1092 0 : if ( ImplIsOverlapWindow() )
1093 0 : return mpWindowImpl->mpOverlapWindow;
1094 : else
1095 0 : return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
1096 :
1097 : case GetWindowType::Client:
1098 105707 : return const_cast<vcl::Window*>(this)->ImplGetWindow();
1099 :
1100 : case GetWindowType::RealParent:
1101 0 : return ImplGetParent();
1102 :
1103 : case GetWindowType::Frame:
1104 0 : return mpWindowImpl->mpFrameWindow;
1105 :
1106 : case GetWindowType::Border:
1107 52364 : if ( mpWindowImpl->mpBorderWindow )
1108 25616 : return mpWindowImpl->mpBorderWindow->GetWindow( GetWindowType::Border );
1109 26748 : return const_cast<vcl::Window*>(this);
1110 :
1111 : case GetWindowType::FirstTopWindowChild:
1112 267227 : return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : (*ImplGetWinData()->maTopWindowChildren.begin()).get();
1113 :
1114 : case GetWindowType::LastTopWindowChild:
1115 0 : return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : (*ImplGetWinData()->maTopWindowChildren.rbegin()).get();
1116 :
1117 : case GetWindowType::PrevTopWindowSibling:
1118 : {
1119 0 : if ( !mpWindowImpl->mpRealParent )
1120 0 : return NULL;
1121 0 : const ::std::list< VclPtr<vcl::Window> >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
1122 : ::std::list< VclPtr<vcl::Window> >::const_iterator myPos =
1123 0 : ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
1124 0 : if ( myPos == rTopWindows.end() )
1125 0 : return NULL;
1126 0 : if ( myPos == rTopWindows.begin() )
1127 0 : return NULL;
1128 0 : return *--myPos;
1129 : }
1130 :
1131 : case GetWindowType::NextTopWindowSibling:
1132 : {
1133 2 : if ( !mpWindowImpl->mpRealParent )
1134 0 : return NULL;
1135 2 : const ::std::list< VclPtr<vcl::Window> >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
1136 : ::std::list< VclPtr<vcl::Window> >::const_iterator myPos =
1137 2 : ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
1138 2 : if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
1139 2 : return NULL;
1140 0 : return *myPos;
1141 : }
1142 :
1143 : }
1144 :
1145 0 : return NULL;
1146 : }
1147 :
1148 12267 : bool Window::IsChild( const vcl::Window* pWindow, bool bSystemWindow ) const
1149 : {
1150 12267 : do
1151 : {
1152 12267 : if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
1153 0 : break;
1154 :
1155 12267 : pWindow = pWindow->ImplGetParent();
1156 :
1157 12267 : if ( pWindow == this )
1158 0 : return true;
1159 : }
1160 : while ( pWindow );
1161 :
1162 12083 : return false;
1163 : }
1164 :
1165 117734 : bool Window::IsWindowOrChild( const vcl::Window* pWindow, bool bSystemWindow ) const
1166 : {
1167 :
1168 117734 : if ( this == pWindow )
1169 0 : return true;
1170 117734 : return ImplIsChild( pWindow, bSystemWindow );
1171 : }
1172 :
1173 28888 : void Window::ImplSetFrameParent( const vcl::Window* pParent )
1174 : {
1175 28888 : vcl::Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
1176 203368 : while( pFrameWindow )
1177 : {
1178 : // search all frames that are children of this window
1179 : // and reparent them
1180 145592 : if( ImplIsRealParentPath( pFrameWindow ) )
1181 : {
1182 : DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" );
1183 : DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" );
1184 2454 : SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL;
1185 2454 : pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
1186 : }
1187 145592 : pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
1188 : }
1189 28888 : }
1190 :
1191 801 : } /* namespace vcl */
1192 :
1193 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|