LCOV - code coverage report
Current view: top level - vcl/source/window - stacking.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 355 621 57.2 %
Date: 2014-11-03 Functions: 30 35 85.7 %
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             : 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: */

Generated by: LCOV version 1.10