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 : struct ImplCalcToTopData
48 : {
49 : ImplCalcToTopData* mpNext;
50 : 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 470280 : void Window::ImplInsertWindow( vcl::Window* pParent )
65 : {
66 470280 : mpWindowImpl->mpParent = pParent;
67 470280 : mpWindowImpl->mpRealParent = pParent;
68 :
69 470280 : if ( pParent && !mpWindowImpl->mbFrame )
70 : {
71 : // search frame window and set window frame data
72 457824 : vcl::Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
73 457824 : mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
74 457824 : mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
75 457824 : mpWindowImpl->mpFrameWindow = pFrameParent;
76 457824 : mpWindowImpl->mbFrame = false;
77 :
78 : // search overlap window and insert window in list
79 457824 : 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 457824 : if ( pParent->ImplIsOverlapWindow() )
100 17992 : mpWindowImpl->mpOverlapWindow = pParent;
101 : else
102 439832 : mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
103 457824 : mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
104 457824 : pParent->mpWindowImpl->mpLastChild = this;
105 457824 : if ( !pParent->mpWindowImpl->mpFirstChild )
106 167395 : pParent->mpWindowImpl->mpFirstChild = this;
107 : else
108 290429 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
109 : }
110 : }
111 470280 : }
112 :
113 472948 : void Window::ImplRemoveWindow( bool bRemoveFrameData )
114 : {
115 : // remove window from the lists
116 472948 : if ( !mpWindowImpl->mbFrame )
117 : {
118 460510 : if ( ImplIsOverlapWindow() )
119 : {
120 0 : if ( mpWindowImpl->mpFrameData->mpFirstOverlap == 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 != 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 460510 : if ( mpWindowImpl->mpPrev )
142 198894 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
143 261616 : else if ( mpWindowImpl->mpParent )
144 261616 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
145 460510 : if ( mpWindowImpl->mpNext )
146 177631 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
147 282879 : else if ( mpWindowImpl->mpParent )
148 282879 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
149 : }
150 :
151 460510 : mpWindowImpl->mpPrev = NULL;
152 460510 : mpWindowImpl->mpNext = NULL;
153 : }
154 :
155 472948 : if ( bRemoveFrameData )
156 : {
157 : // release the graphic
158 448376 : OutputDevice *pOutDev = GetOutDev();
159 448376 : pOutDev->ReleaseGraphics();
160 : }
161 472948 : }
162 :
163 38548 : void Window::reorderWithinParent(sal_uInt16 nNewPosition)
164 : {
165 38548 : sal_uInt16 nChildCount = 0;
166 38548 : vcl::Window *pSource = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
167 118692 : while (pSource)
168 : {
169 80144 : if (nChildCount == nNewPosition)
170 38548 : break;
171 41596 : pSource = pSource->mpWindowImpl->mpNext;
172 41596 : nChildCount++;
173 : }
174 :
175 38548 : if (pSource == this) //already at the right place
176 74102 : return;
177 :
178 2994 : ImplRemoveWindow(false);
179 :
180 2994 : if (pSource)
181 : {
182 2994 : mpWindowImpl->mpNext = pSource;
183 2994 : mpWindowImpl->mpPrev = pSource->mpWindowImpl->mpPrev;
184 2994 : pSource->mpWindowImpl->mpPrev = this;
185 : }
186 : else
187 0 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
188 :
189 2994 : if (mpWindowImpl->mpPrev)
190 1480 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
191 : else
192 1514 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
193 : }
194 :
195 10954 : void Window::ImplToBottomChild()
196 : {
197 10954 : if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) )
198 : {
199 : // put the window to the end of the list
200 1662 : if ( mpWindowImpl->mpPrev )
201 0 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
202 : else
203 1662 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
204 1662 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
205 1662 : mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
206 1662 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
207 1662 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
208 1662 : mpWindowImpl->mpNext = NULL;
209 : }
210 10954 : }
211 :
212 6854 : void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
213 : {
214 : DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
215 :
216 6854 : 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 6854 : }
238 :
239 6854 : void Window::ImplToTop( sal_uInt16 nFlags )
240 : {
241 : DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
242 :
243 6854 : 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 12303 : if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
248 10898 : !mpWindowImpl->mpFrameData->mbSysObjFocus &&
249 10898 : !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
250 5449 : !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
251 : {
252 : // do not bring floating windows on the client to top
253 5449 : if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
254 : {
255 5449 : sal_uInt16 nSysFlags = 0;
256 5449 : if ( nFlags & TOTOP_RESTOREWHENMIN )
257 19 : nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN;
258 5449 : if ( nFlags & TOTOP_FOREGROUNDTASK )
259 0 : nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK;
260 5449 : if ( nFlags & TOTOP_GRABFOCUSONLY )
261 0 : nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY;
262 5449 : mpWindowImpl->mpFrame->ToTop( nSysFlags );
263 : }
264 : }
265 : }
266 : else
267 : {
268 0 : if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != 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 6854 : }
328 :
329 6854 : void Window::ImplStartToTop( sal_uInt16 nFlags )
330 : {
331 : ImplCalcToTopData aStartData;
332 : ImplCalcToTopData* pCurData;
333 : ImplCalcToTopData* pNextData;
334 : vcl::Window* pOverlapWindow;
335 6854 : if ( ImplIsOverlapWindow() )
336 5510 : pOverlapWindow = this;
337 : else
338 1344 : pOverlapWindow = mpWindowImpl->mpOverlapWindow;
339 :
340 : // first calculate paint areas
341 6854 : vcl::Window* pTempOverlapWindow = pOverlapWindow;
342 6854 : aStartData.mpNext = NULL;
343 6854 : pCurData = &aStartData;
344 6854 : do
345 : {
346 6854 : pTempOverlapWindow->ImplCalcToTop( pCurData );
347 6854 : if ( pCurData->mpNext )
348 0 : pCurData = pCurData->mpNext;
349 6854 : pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
350 : }
351 6854 : while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
352 : // next calculate the paint areas of the ChildOverlap windows
353 6854 : pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
354 13708 : 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 6854 : pTempOverlapWindow = pOverlapWindow;
364 6854 : do
365 : {
366 6854 : pTempOverlapWindow->ImplToTop( nFlags );
367 6854 : pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
368 : }
369 6854 : while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
370 : // as last step invalidate the invalid areas
371 6854 : pCurData = aStartData.mpNext;
372 13708 : while ( pCurData )
373 : {
374 0 : pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN );
375 0 : pNextData = pCurData->mpNext;
376 0 : delete pCurData->mpInvalidateRegion;
377 0 : delete pCurData;
378 0 : pCurData = pNextData;
379 : }
380 6854 : }
381 :
382 6854 : void Window::ImplFocusToTop( sal_uInt16 nFlags, bool bReallyVisible )
383 : {
384 : // do we need to fetch the focus?
385 6854 : if ( !(nFlags & TOTOP_NOGRABFOCUS) )
386 : {
387 : // first window with GrabFocus-Activate gets the focus
388 6854 : vcl::Window* pFocusWindow = this;
389 15052 : while ( !pFocusWindow->ImplIsOverlapWindow() )
390 : {
391 : // if the window has no BorderWindow, we
392 : // should always find the belonging BorderWindow
393 1344 : if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
394 : {
395 0 : if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS )
396 0 : break;
397 : }
398 1344 : pFocusWindow = pFocusWindow->ImplGetParent();
399 : }
400 13700 : if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) &&
401 6846 : !pFocusWindow->HasChildPathFocus( true ) )
402 5449 : pFocusWindow->GrabFocus();
403 : }
404 :
405 6854 : if ( bReallyVisible )
406 1330 : ImplGenerateMouseMove();
407 6854 : }
408 :
409 311645 : void Window::ImplShowAllOverlaps()
410 : {
411 311645 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
412 623290 : while ( pOverlapWindow )
413 : {
414 0 : if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
415 : {
416 0 : pOverlapWindow->Show( true, SHOW_NOACTIVATE );
417 0 : pOverlapWindow->mpWindowImpl->mbOverlapVisible = false;
418 : }
419 :
420 0 : pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
421 : }
422 311645 : }
423 :
424 311485 : void Window::ImplHideAllOverlaps()
425 : {
426 311485 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
427 622970 : 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 311485 : }
438 :
439 1344 : void Window::ToTop( sal_uInt16 nFlags )
440 : {
441 :
442 1344 : ImplStartToTop( nFlags );
443 1344 : ImplFocusToTop( nFlags, IsReallyVisible() );
444 1344 : }
445 :
446 70 : void Window::SetZOrder( vcl::Window* pRefWindow, sal_uInt16 nFlags )
447 : {
448 :
449 70 : if ( mpWindowImpl->mpBorderWindow )
450 : {
451 10 : mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
452 10 : return;
453 : }
454 :
455 60 : if ( nFlags & WINDOW_ZORDER_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 |= WINDOW_ZORDER_BEFOR;
462 : }
463 60 : else if ( nFlags & WINDOW_ZORDER_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 |= WINDOW_ZORDER_BEHIND;
470 : }
471 :
472 130 : while ( pRefWindow && pRefWindow->mpWindowImpl->mpBorderWindow )
473 10 : pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
474 60 : 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 60 : if ( nFlags & WINDOW_ZORDER_BEFOR )
479 : {
480 0 : if ( pRefWindow->mpWindowImpl->mpPrev == 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 60 : else if ( nFlags & WINDOW_ZORDER_BEHIND )
517 : {
518 60 : if ( pRefWindow->mpWindowImpl->mpNext == this )
519 52 : return;
520 :
521 8 : 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 8 : if ( mpWindowImpl->mpPrev )
537 4 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
538 : else
539 4 : mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
540 8 : if ( mpWindowImpl->mpNext )
541 8 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
542 : else
543 0 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
544 8 : if ( !pRefWindow->mpWindowImpl->mpNext )
545 6 : mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
546 : }
547 :
548 8 : mpWindowImpl->mpPrev = pRefWindow;
549 8 : mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
550 8 : if ( mpWindowImpl->mpNext )
551 2 : mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
552 8 : mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
553 : }
554 :
555 8 : if ( IsReallyVisible() )
556 : {
557 : // restore background storage
558 8 : if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
559 0 : ImplInvalidateAllOverlapBackgrounds();
560 :
561 8 : if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
562 : {
563 8 : bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion;
564 8 : 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 8 : 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( INVALIDATE_CHILDREN | INVALIDATE_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( INVALIDATE_CHILDREN | INVALIDATE_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 922528 : bool Window::IsTopWindow() const
634 : {
635 922528 : if ( mpWindowImpl->mbInDtor )
636 0 : return false;
637 :
638 : // topwindows must be frames or they must have a borderwindow which is a frame
639 922528 : if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) )
640 32 : return false;
641 :
642 922496 : ImplGetWinData();
643 922496 : if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized
644 : {
645 : // #113722#, cache result of expensive queryInterface call
646 23748 : vcl::Window *pThisWin = (vcl::Window*)this;
647 23748 : uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
648 23748 : pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
649 : }
650 922496 : return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? true : false;
651 : }
652 :
653 0 : vcl::Window* Window::FindWindow( const Point& rPos ) const
654 : {
655 :
656 0 : Point aPos = OutputToScreenPixel( rPos );
657 0 : return ((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 525038 : bool Window::ImplIsRealParentPath( const vcl::Window* pWindow ) const
702 : {
703 525038 : pWindow = pWindow->GetParent();
704 2708134 : while ( pWindow )
705 : {
706 1667996 : if ( pWindow == this )
707 9938 : return true;
708 1658058 : pWindow = pWindow->GetParent();
709 : }
710 :
711 515100 : return false;
712 : }
713 :
714 1579079 : bool Window::ImplIsChild( const vcl::Window* pWindow, bool bSystemWindow ) const
715 : {
716 1193268 : do
717 : {
718 1579079 : if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
719 309116 : break;
720 :
721 1269963 : pWindow = pWindow->ImplGetParent();
722 :
723 1269963 : if ( pWindow == this )
724 76695 : return true;
725 : }
726 : while ( pWindow );
727 :
728 342146 : return false;
729 : }
730 :
731 125363 : bool Window::ImplIsWindowOrChild( const vcl::Window* pWindow, bool bSystemWindow ) const
732 : {
733 125363 : if ( this == pWindow )
734 6234 : return true;
735 119129 : return ImplIsChild( pWindow, bSystemWindow );
736 : }
737 :
738 269288 : void Window::ImplResetReallyVisible()
739 : {
740 269288 : bool bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
741 :
742 269288 : mbDevOutput = false;
743 269288 : mpWindowImpl->mbReallyVisible = false;
744 269288 : 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 269288 : if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
750 253168 : ImplCallEventListeners( 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 269288 : vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
755 538576 : while ( pWindow )
756 : {
757 0 : if ( pWindow->mpWindowImpl->mbReallyVisible )
758 0 : pWindow->ImplResetReallyVisible();
759 0 : pWindow = pWindow->mpWindowImpl->mpNext;
760 : }
761 :
762 269288 : pWindow = mpWindowImpl->mpFirstChild;
763 744484 : while ( pWindow )
764 : {
765 205908 : if ( pWindow->mpWindowImpl->mbReallyVisible )
766 141953 : pWindow->ImplResetReallyVisible();
767 205908 : pWindow = pWindow->mpWindowImpl->mpNext;
768 : }
769 269288 : }
770 :
771 92926 : void Window::ImplUpdateWindowPtr( vcl::Window* pWindow )
772 : {
773 92926 : if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
774 : {
775 : // release graphic
776 10138 : OutputDevice *pOutDev = GetOutDev();
777 10138 : pOutDev->ReleaseGraphics();
778 : }
779 :
780 92926 : mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData;
781 92926 : mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
782 92926 : mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow;
783 92926 : if ( pWindow->ImplIsOverlapWindow() )
784 56 : mpWindowImpl->mpOverlapWindow = pWindow;
785 : else
786 92870 : mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
787 :
788 92926 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
789 256196 : while ( pChild )
790 : {
791 70344 : pChild->ImplUpdateWindowPtr( pWindow );
792 70344 : pChild = pChild->mpWindowImpl->mpNext;
793 : }
794 92926 : }
795 :
796 27128 : void Window::ImplUpdateWindowPtr()
797 : {
798 27128 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
799 76838 : while ( pChild )
800 : {
801 22582 : pChild->ImplUpdateWindowPtr( this );
802 22582 : pChild = pChild->mpWindowImpl->mpNext;
803 : }
804 27128 : }
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 24252 : SystemWindow* Window::GetSystemWindow() const
834 : {
835 :
836 24252 : const vcl::Window* pWin = this;
837 77268 : while ( pWin && !pWin->IsSystemWindow() )
838 28764 : pWin = pWin->GetParent();
839 24252 : return static_cast<SystemWindow*>(const_cast<Window*>(pWin));
840 : }
841 :
842 42146 : static SystemWindow *ImplGetLastSystemWindow( vcl::Window *pWin )
843 : {
844 : // get the most top-level system window, the one that contains the taskpanelist
845 42146 : SystemWindow *pSysWin = NULL;
846 42146 : if( !pWin )
847 0 : return pSysWin;
848 42146 : vcl::Window *pMyParent = pWin;
849 240558 : while ( pMyParent )
850 : {
851 156266 : if ( pMyParent->IsSystemWindow() )
852 42134 : pSysWin = static_cast<SystemWindow*>(pMyParent);
853 156266 : pMyParent = pMyParent->GetParent();
854 : }
855 42146 : return pSysWin;
856 : }
857 :
858 30604 : 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 30604 : if( pNewParent == this )
864 0 : return;
865 :
866 : // check if the taskpanelist would change and move the window pointer accordingly
867 30604 : SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
868 30604 : SystemWindow *pNewSysWin = NULL;
869 30604 : bool bChangeTaskPaneList = false;
870 30604 : if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
871 : {
872 11542 : pNewSysWin = ImplGetLastSystemWindow( pNewParent );
873 11542 : 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 30604 : if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
881 : {
882 0 : ::std::vector< vcl::Window* >& rList = ImplGetOwnerDrawList();
883 0 : ::std::vector< vcl::Window* >::iterator p;
884 0 : p = ::std::find( rList.begin(), rList.end(), this );
885 0 : if( p != rList.end() )
886 0 : rList.erase( p );
887 : }
888 :
889 30604 : ImplSetFrameParent( pNewParent );
890 :
891 30604 : if ( mpWindowImpl->mpBorderWindow )
892 : {
893 3454 : mpWindowImpl->mpRealParent = pNewParent;
894 3454 : mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
895 3454 : return;
896 : }
897 :
898 27150 : if ( mpWindowImpl->mpParent == pNewParent )
899 22 : return;
900 :
901 27128 : if ( mpWindowImpl->mbFrame )
902 20 : mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
903 :
904 27128 : bool bVisible = IsVisible();
905 27128 : Show( false, SHOW_NOFOCUSCHANGE );
906 :
907 : // check if the overlap window changes
908 : vcl::Window* pOldOverlapWindow;
909 27128 : vcl::Window* pNewOverlapWindow = NULL;
910 27128 : if ( ImplIsOverlapWindow() )
911 20 : pOldOverlapWindow = NULL;
912 : else
913 : {
914 27108 : pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
915 27108 : if ( mpWindowImpl->mpOverlapWindow != pNewOverlapWindow )
916 5530 : pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
917 : else
918 21578 : pOldOverlapWindow = NULL;
919 : }
920 :
921 : // convert windows in the hierarchy
922 27128 : bool bFocusOverlapWin = HasChildPathFocus( true );
923 27128 : bool bFocusWin = HasChildPathFocus();
924 27128 : bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
925 27128 : if ( bNewFrame )
926 : {
927 5550 : if ( mpWindowImpl->mpFrameData->mpFocusWin )
928 : {
929 3017 : if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
930 0 : mpWindowImpl->mpFrameData->mpFocusWin = NULL;
931 : }
932 5550 : if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
933 : {
934 0 : if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
935 0 : mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
936 : }
937 5550 : if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
938 : {
939 0 : if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
940 0 : mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
941 : }
942 : }
943 27128 : ImplRemoveWindow( bNewFrame );
944 27128 : ImplInsertWindow( pNewParent );
945 27128 : if ( mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP )
946 0 : pNewParent->mpWindowImpl->mbClipChildren = true;
947 27128 : ImplUpdateWindowPtr();
948 27128 : if ( ImplUpdatePos() )
949 0 : ImplUpdateSysObjPos();
950 :
951 : // If the Overlap-Window has changed, we need to test whether
952 : // OverlapWindows that had the Child window as their parent
953 : // need to be put into the window hierarchy.
954 27128 : if ( ImplIsOverlapWindow() )
955 : {
956 20 : if ( bNewFrame )
957 : {
958 20 : vcl::Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
959 40 : while ( pOverlapWindow )
960 : {
961 0 : vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
962 0 : pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
963 0 : pOverlapWindow = pNextOverlapWindow;
964 : }
965 : }
966 : }
967 27108 : else if ( pOldOverlapWindow )
968 : {
969 : // reset Focus-Save
970 5530 : if ( bFocusWin ||
971 3017 : (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
972 3017 : IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
973 0 : pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
974 :
975 5530 : vcl::Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
976 11060 : while ( pOverlapWindow )
977 : {
978 0 : vcl::Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
979 0 : if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
980 0 : pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
981 0 : pOverlapWindow = pNextOverlapWindow;
982 : }
983 :
984 : // update activate-status at next overlap window
985 5530 : if ( HasChildPathFocus( true ) )
986 0 : ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
987 : }
988 :
989 : // also convert Activate-Status
990 27128 : if ( bNewFrame )
991 : {
992 9000 : if ( (GetType() == WINDOW_BORDERWINDOW) &&
993 3450 : (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
994 16 : static_cast<ImplBorderWindow*>(this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
995 : }
996 :
997 : // when required give focus to new frame if
998 : // FocusWindow is changed with SetParent()
999 27128 : if ( bFocusOverlapWin )
1000 : {
1001 138 : mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
1002 138 : if ( !mpWindowImpl->mpFrameData->mbHasFocus )
1003 : {
1004 0 : mpWindowImpl->mpFrame->ToTop( 0 );
1005 : }
1006 : }
1007 :
1008 : // Assure DragSource and DropTarget members are created
1009 27128 : if ( bNewFrame )
1010 : {
1011 5550 : GetDropTarget();
1012 : }
1013 :
1014 27128 : if( bChangeTaskPaneList )
1015 0 : pNewSysWin->GetTaskPaneList()->AddWindow( this );
1016 :
1017 27128 : if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
1018 0 : ImplGetOwnerDrawList().push_back( this );
1019 :
1020 27128 : if ( bVisible )
1021 193 : Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
1022 : }
1023 :
1024 14268 : sal_uInt16 Window::GetChildCount() const
1025 : {
1026 :
1027 14268 : sal_uInt16 nChildCount = 0;
1028 14268 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
1029 38286 : while ( pChild )
1030 : {
1031 9750 : nChildCount++;
1032 9750 : pChild = pChild->mpWindowImpl->mpNext;
1033 : }
1034 :
1035 14268 : return nChildCount;
1036 : }
1037 :
1038 9518 : vcl::Window* Window::GetChild( sal_uInt16 nChild ) const
1039 : {
1040 :
1041 9518 : sal_uInt16 nChildCount = 0;
1042 9518 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
1043 19124 : while ( pChild )
1044 : {
1045 9606 : if ( nChild == nChildCount )
1046 9518 : return pChild;
1047 88 : pChild = pChild->mpWindowImpl->mpNext;
1048 88 : nChildCount++;
1049 : }
1050 :
1051 0 : return NULL;
1052 : }
1053 :
1054 3687673 : vcl::Window* Window::GetWindow( sal_uInt16 nType ) const
1055 : {
1056 :
1057 3687673 : switch ( nType )
1058 : {
1059 : case WINDOW_PARENT:
1060 0 : return mpWindowImpl->mpRealParent;
1061 :
1062 : case WINDOW_FIRSTCHILD:
1063 1475327 : return mpWindowImpl->mpFirstChild;
1064 :
1065 : case WINDOW_LASTCHILD:
1066 31195 : return mpWindowImpl->mpLastChild;
1067 :
1068 : case WINDOW_PREV:
1069 7851 : return mpWindowImpl->mpPrev;
1070 :
1071 : case WINDOW_NEXT:
1072 548136 : return mpWindowImpl->mpNext;
1073 :
1074 : case WINDOW_FIRSTOVERLAP:
1075 442562 : return mpWindowImpl->mpFirstOverlap;
1076 :
1077 : case WINDOW_LASTOVERLAP:
1078 0 : return mpWindowImpl->mpLastOverlap;
1079 :
1080 : case WINDOW_OVERLAP:
1081 442562 : if ( ImplIsOverlapWindow() )
1082 12286 : return (vcl::Window*)this;
1083 : else
1084 430276 : return mpWindowImpl->mpOverlapWindow;
1085 :
1086 : case WINDOW_PARENTOVERLAP:
1087 0 : if ( ImplIsOverlapWindow() )
1088 0 : return mpWindowImpl->mpOverlapWindow;
1089 : else
1090 0 : return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
1091 :
1092 : case WINDOW_CLIENT:
1093 190864 : return ((vcl::Window*)this)->ImplGetWindow();
1094 :
1095 : case WINDOW_REALPARENT:
1096 0 : return ImplGetParent();
1097 :
1098 : case WINDOW_FRAME:
1099 0 : return mpWindowImpl->mpFrameWindow;
1100 :
1101 : case WINDOW_BORDER:
1102 106610 : if ( mpWindowImpl->mpBorderWindow )
1103 46644 : return mpWindowImpl->mpBorderWindow->GetWindow( WINDOW_BORDER );
1104 59966 : return (vcl::Window*)this;
1105 :
1106 : case WINDOW_FIRSTTOPWINDOWCHILD:
1107 442562 : return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.begin();
1108 :
1109 : case WINDOW_LASTTOPWINDOWCHILD:
1110 0 : return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.rbegin();
1111 :
1112 : case WINDOW_PREVTOPWINDOWSIBLING:
1113 : {
1114 0 : if ( !mpWindowImpl->mpRealParent )
1115 0 : return NULL;
1116 0 : const ::std::list< vcl::Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
1117 : ::std::list< vcl::Window* >::const_iterator myPos =
1118 0 : ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
1119 0 : if ( myPos == rTopWindows.end() )
1120 0 : return NULL;
1121 0 : if ( myPos == rTopWindows.begin() )
1122 0 : return NULL;
1123 0 : return *--myPos;
1124 : }
1125 :
1126 : case WINDOW_NEXTTOPWINDOWSIBLING:
1127 : {
1128 4 : if ( !mpWindowImpl->mpRealParent )
1129 0 : return NULL;
1130 4 : const ::std::list< vcl::Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
1131 : ::std::list< vcl::Window* >::const_iterator myPos =
1132 4 : ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
1133 4 : if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
1134 4 : return NULL;
1135 0 : return *myPos;
1136 : }
1137 :
1138 : }
1139 :
1140 0 : return NULL;
1141 : }
1142 :
1143 612 : bool Window::IsChild( const vcl::Window* pWindow, bool bSystemWindow ) const
1144 : {
1145 612 : do
1146 : {
1147 612 : if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
1148 0 : break;
1149 :
1150 612 : pWindow = pWindow->ImplGetParent();
1151 :
1152 612 : if ( pWindow == this )
1153 0 : return true;
1154 : }
1155 : while ( pWindow );
1156 :
1157 156 : return false;
1158 : }
1159 :
1160 182570 : bool Window::IsWindowOrChild( const vcl::Window* pWindow, bool bSystemWindow ) const
1161 : {
1162 :
1163 182570 : if ( this == pWindow )
1164 0 : return true;
1165 182570 : return ImplIsChild( pWindow, bSystemWindow );
1166 : }
1167 :
1168 30604 : void Window::ImplSetFrameParent( const vcl::Window* pParent )
1169 : {
1170 30604 : vcl::Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
1171 181086 : while( pFrameWindow )
1172 : {
1173 : // search all frames that are children of this window
1174 : // and reparent them
1175 119878 : if( ImplIsRealParentPath( pFrameWindow ) )
1176 : {
1177 : DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" );
1178 : DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" );
1179 4508 : SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL;
1180 4508 : pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
1181 : }
1182 119878 : pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
1183 : }
1184 30604 : }
1185 :
1186 1233 : } /* namespace vcl */
1187 :
1188 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|