LCOV - code coverage report
Current view: top level - vcl/source/window - stacking.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 364 629 57.9 %
Date: 2015-06-13 12:38:46 Functions: 32 37 86.5 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.11