diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2014-05-13 21:13:20 +1000 |
---|---|---|
committer | Chris Sherlock <chris.sherlock79@gmail.com> | 2014-05-13 21:30:46 +1000 |
commit | aa23a83999acf1f0cd8631cf6b314e83d1bde9fb (patch) | |
tree | 5c2866b95a2241003e4f32a8c769942829ccc0cc /vcl | |
parent | 70c355dc46caaf73c708c43d3eb744373e4d5ebc (diff) |
vcl: move window order and stack functions into stacking.cxx
Change-Id: I96eabf2507f2d365d589a436a30087adb9738f90
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/source/window/stacking.cxx | 707 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 596 |
3 files changed, 708 insertions, 596 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index bd9a541c35d5..27179eac742a 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -108,6 +108,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/window/accessibility \ vcl/source/window/legacyaccessibility \ vcl/source/window/clipping \ + vcl/source/window/stacking \ vcl/source/window/btndlg \ vcl/source/window/builder \ vcl/source/window/cmdevt \ diff --git a/vcl/source/window/stacking.cxx b/vcl/source/window/stacking.cxx new file mode 100644 index 000000000000..ef1d8b77a985 --- /dev/null +++ b/vcl/source/window/stacking.cxx @@ -0,0 +1,707 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <config_features.h> + +#include <i18nlangtag/mslangid.hxx> + +#include "tools/time.hxx" +#include "tools/debug.hxx" +#include "tools/rc.h" + +#include "unotools/fontcfg.hxx" +#include "unotools/confignode.hxx" + +#include "vcl/layout.hxx" +#include "vcl/salgtype.hxx" +#include "vcl/event.hxx" +#include "vcl/fixed.hxx" +#include "vcl/help.hxx" +#include "vcl/cursor.hxx" +#include "vcl/svapp.hxx" +#include "vcl/window.hxx" +#include "vcl/syswin.hxx" +#include "vcl/syschild.hxx" +#include "vcl/dockwin.hxx" +#include "vcl/menu.hxx" +#include "vcl/wrkwin.hxx" +#include "vcl/wall.hxx" +#include "vcl/gradient.hxx" +#include "vcl/button.hxx" +#include "vcl/taskpanelist.hxx" +#include "vcl/dialog.hxx" +#include "vcl/unowrap.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/pdfextoutdevdata.hxx" +#include "vcl/popupmenuwindow.hxx" +#include "vcl/lazydelete.hxx" +#include "vcl/virdev.hxx" +#include "vcl/settings.hxx" + +// declare system types in sysdata.hxx +#include "svsys.h" +#include "vcl/sysdata.hxx" + +#include "salframe.hxx" +#include "salobj.hxx" +#include "salinst.hxx" +#include "salgdi.hxx" +#include "svdata.hxx" +#include "dbggui.hxx" +#include "outfont.hxx" +#include "window.h" +#include "toolbox.h" +#include "outdev.h" +#include "PhysicalFontCollection.hxx" +#include "brdwin.hxx" +#include "helpwin.hxx" +#include "sallayout.hxx" +#include "dndlcon.hxx" +#include "dndevdis.hxx" + +#include "com/sun/star/accessibility/XAccessible.hpp" +#include "com/sun/star/accessibility/AccessibleRole.hpp" +#include "com/sun/star/awt/XWindowPeer.hpp" +#include "com/sun/star/awt/XTopWindow.hpp" +#include "com/sun/star/awt/XWindow.hpp" +#include "com/sun/star/awt/XDisplayConnection.hpp" +#include "com/sun/star/datatransfer/dnd/XDragSource.hpp" +#include "com/sun/star/datatransfer/dnd/XDropTarget.hpp" +#include "com/sun/star/datatransfer/clipboard/XClipboard.hpp" +#include "com/sun/star/datatransfer/clipboard/SystemClipboard.hpp" +#include "com/sun/star/lang/XInitialization.hpp" +#include "com/sun/star/lang/XComponent.hpp" +#include "com/sun/star/lang/XServiceName.hpp" +#include "com/sun/star/rendering/CanvasFactory.hpp" +#include "com/sun/star/rendering/XCanvas.hpp" +#include "com/sun/star/rendering/XSpriteCanvas.hpp" +#include "comphelper/processfactory.hxx" + +#include <sal/macros.h> +#include <rtl/strbuf.hxx> + +#include <set> +#include <typeinfo> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::datatransfer::clipboard; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::com::sun::star; +using namespace com::sun; + +using ::com::sun::star::awt::XTopWindow; + +struct ImplCalcToTopData +{ + ImplCalcToTopData* mpNext; + Window* mpWindow; + Region* mpInvalidateRegion; +}; + +void Window::ImplInsertWindow( Window* pParent ) +{ + mpWindowImpl->mpParent = pParent; + mpWindowImpl->mpRealParent = pParent; + + if ( pParent && !mpWindowImpl->mbFrame ) + { + // search frame window and set window frame data + Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow; + mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData; + mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame; + mpWindowImpl->mpFrameWindow = pFrameParent; + mpWindowImpl->mbFrame = false; + + // search overlap window and insert window in list + if ( ImplIsOverlapWindow() ) + { + Window* pFirstOverlapParent = pParent; + while ( !pFirstOverlapParent->ImplIsOverlapWindow() ) + pFirstOverlapParent = pFirstOverlapParent->ImplGetParent(); + mpWindowImpl->mpOverlapWindow = pFirstOverlapParent; + + mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap; + mpWindowImpl->mpFrameData->mpFirstOverlap = this; + + // Overlap-Windows are by default the uppermost + mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap; + pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this; + if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap ) + pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this; + else + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; + } + else + { + if ( pParent->ImplIsOverlapWindow() ) + mpWindowImpl->mpOverlapWindow = pParent; + else + mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow; + mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild; + pParent->mpWindowImpl->mpLastChild = this; + if ( !pParent->mpWindowImpl->mpFirstChild ) + pParent->mpWindowImpl->mpFirstChild = this; + else + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; + } + } +} + +void Window::ImplRemoveWindow( bool bRemoveFrameData ) +{ + // remove window from the lists + if ( !mpWindowImpl->mbFrame ) + { + if ( ImplIsOverlapWindow() ) + { + if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this ) + mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap; + else + { + Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap; + while ( pTempWin->mpWindowImpl->mpNextOverlap != this ) + pTempWin = pTempWin->mpWindowImpl->mpNextOverlap; + pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap; + } + + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; + } + else + { + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else if ( mpWindowImpl->mpParent ) + mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else if ( mpWindowImpl->mpParent ) + mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; + } + + mpWindowImpl->mpPrev = NULL; + mpWindowImpl->mpNext = NULL; + } + + if ( bRemoveFrameData ) + { + // release the graphic + OutputDevice *pOutDev = GetOutDev(); + pOutDev->ReleaseGraphics(); + } +} + +void Window::reorderWithinParent(sal_uInt16 nNewPosition) +{ + sal_uInt16 nChildCount = 0; + Window *pSource = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild; + while (pSource) + { + if (nChildCount == nNewPosition) + break; + pSource = pSource->mpWindowImpl->mpNext; + nChildCount++; + } + + if (pSource == this) //already at the right place + return; + + ImplRemoveWindow(false); + + if (pSource) + { + mpWindowImpl->mpNext = pSource; + mpWindowImpl->mpPrev = pSource->mpWindowImpl->mpPrev; + pSource->mpWindowImpl->mpPrev = this; + } + else + mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; + + if (mpWindowImpl->mpPrev) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; + else + mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this; +} + +void Window::ImplToBottomChild() +{ + if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) ) + { + // put the window to the end of the list + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else + mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild; + mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; + mpWindowImpl->mpNext = NULL; + } +} + +void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData ) +{ + DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" ); + + if ( !mpWindowImpl->mbFrame ) + { + if ( IsReallyVisible() ) + { + // calculate region, where the window overlaps with other windows + Point aPoint( mnOutOffX, mnOutOffY ); + Region aRegion( Rectangle( aPoint, + Size( mnOutWidth, mnOutHeight ) ) ); + Region aInvalidateRegion; + ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion ); + + if ( !aInvalidateRegion.IsEmpty() ) + { + ImplCalcToTopData* pData = new ImplCalcToTopData; + pPrevData->mpNext = pData; + pData->mpNext = NULL; + pData->mpWindow = this; + pData->mpInvalidateRegion = new Region( aInvalidateRegion ); + } + } + } +} + +void Window::ImplToTop( sal_uInt16 nFlags ) +{ + DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" ); + + if ( mpWindowImpl->mbFrame ) + { + // on a mouse click in the external window, it is the latter's + // responsibility to assure our frame is put in front + if ( !mpWindowImpl->mpFrameData->mbHasFocus && + !mpWindowImpl->mpFrameData->mbSysObjFocus && + !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl && + !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl ) + { + // do not bring floating windows on the client to top + if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) ) + { + sal_uInt16 nSysFlags = 0; + if ( nFlags & TOTOP_RESTOREWHENMIN ) + nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN; + if ( nFlags & TOTOP_FOREGROUNDTASK ) + nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK; + if ( nFlags & TOTOP_GRABFOCUSONLY ) + nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY; + mpWindowImpl->mpFrame->ToTop( nSysFlags ); + } + } + } + else + { + if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this ) + { + // remove window from the list + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; + + // take AlwaysOnTop into account + bool bOnTop = IsAlwaysOnTopEnabled(); + Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; + if ( !bOnTop ) + { + while ( pNextWin ) + { + if ( !pNextWin->IsAlwaysOnTopEnabled() ) + break; + pNextWin = pNextWin->mpWindowImpl->mpNext; + } + } + + // check TopLevel + sal_uInt8 nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel; + while ( pNextWin ) + { + if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) || + (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) ) + break; + pNextWin = pNextWin->mpWindowImpl->mpNext; + } + + // add the window to the list again + mpWindowImpl->mpNext = pNextWin; + if ( pNextWin ) + { + mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev; + pNextWin->mpWindowImpl->mpPrev = this; + } + else + { + mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this; + } + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this; + + // recalculate ClipRegion of this and all overlapping windows + if ( IsReallyVisible() ) + { + // reset background storage + if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows(); + } + } + } +} + +void Window::ImplStartToTop( sal_uInt16 nFlags ) +{ + ImplCalcToTopData aStartData; + ImplCalcToTopData* pCurData; + ImplCalcToTopData* pNextData; + Window* pOverlapWindow; + if ( ImplIsOverlapWindow() ) + pOverlapWindow = this; + else + pOverlapWindow = mpWindowImpl->mpOverlapWindow; + + // first calculate paint areas + Window* pTempOverlapWindow = pOverlapWindow; + aStartData.mpNext = NULL; + pCurData = &aStartData; + do + { + pTempOverlapWindow->ImplCalcToTop( pCurData ); + if ( pCurData->mpNext ) + pCurData = pCurData->mpNext; + pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow; + } + while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); + // next calculate the paint areas of the ChildOverlap windows + pTempOverlapWindow = mpWindowImpl->mpFirstOverlap; + while ( pTempOverlapWindow ) + { + pTempOverlapWindow->ImplCalcToTop( pCurData ); + if ( pCurData->mpNext ) + pCurData = pCurData->mpNext; + pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext; + } + + // and next change the windows list + pTempOverlapWindow = pOverlapWindow; + do + { + pTempOverlapWindow->ImplToTop( nFlags ); + pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow; + } + while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); + // as last step invalidate the invalid areas + pCurData = aStartData.mpNext; + while ( pCurData ) + { + pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN ); + pNextData = pCurData->mpNext; + delete pCurData->mpInvalidateRegion; + delete pCurData; + pCurData = pNextData; + } +} + +void Window::ImplFocusToTop( sal_uInt16 nFlags, bool bReallyVisible ) +{ + // do we need to fetch the focus? + if ( !(nFlags & TOTOP_NOGRABFOCUS) ) + { + // first window with GrabFocus-Activate gets the focus + Window* pFocusWindow = this; + while ( !pFocusWindow->ImplIsOverlapWindow() ) + { + // if the window has no BorderWindow, we + // should always find the belonging BorderWindow + if ( !pFocusWindow->mpWindowImpl->mpBorderWindow ) + { + if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS ) + break; + } + pFocusWindow = pFocusWindow->ImplGetParent(); + } + if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) && + !pFocusWindow->HasChildPathFocus( true ) ) + pFocusWindow->GrabFocus(); + } + + if ( bReallyVisible ) + ImplGenerateMouseMove(); +} + +void Window::ImplShowAllOverlaps() +{ + Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; + while ( pOverlapWindow ) + { + if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible ) + { + pOverlapWindow->Show( true, SHOW_NOACTIVATE ); + pOverlapWindow->mpWindowImpl->mbOverlapVisible = false; + } + + pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; + } +} + +void Window::ImplHideAllOverlaps() +{ + Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; + while ( pOverlapWindow ) + { + if ( pOverlapWindow->IsVisible() ) + { + pOverlapWindow->mpWindowImpl->mbOverlapVisible = true; + pOverlapWindow->Show( false ); + } + + pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; + } +} + +void Window::ToTop( sal_uInt16 nFlags ) +{ + + ImplStartToTop( nFlags ); + ImplFocusToTop( nFlags, IsReallyVisible() ); +} + +void Window::SetZOrder( Window* pRefWindow, sal_uInt16 nFlags ) +{ + + if ( mpWindowImpl->mpBorderWindow ) + { + mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags ); + return; + } + + if ( nFlags & WINDOW_ZORDER_FIRST ) + { + if ( ImplIsOverlapWindow() ) + pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; + else + pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild; + nFlags |= WINDOW_ZORDER_BEFOR; + } + else if ( nFlags & WINDOW_ZORDER_LAST ) + { + if ( ImplIsOverlapWindow() ) + pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; + else + pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild; + nFlags |= WINDOW_ZORDER_BEHIND; + } + + while ( pRefWindow && pRefWindow->mpWindowImpl->mpBorderWindow ) + pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow; + if (!pRefWindow || pRefWindow == this || mpWindowImpl->mbFrame) + return; + + DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" ); + if ( nFlags & WINDOW_ZORDER_BEFOR ) + { + if ( pRefWindow->mpWindowImpl->mpPrev == this ) + return; + + if ( ImplIsOverlapWindow() ) + { + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; + if ( !pRefWindow->mpWindowImpl->mpPrev ) + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this; + } + else + { + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else + mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else + mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; + if ( !pRefWindow->mpWindowImpl->mpPrev ) + mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this; + } + + mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev; + mpWindowImpl->mpNext = pRefWindow; + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; + } + else if ( nFlags & WINDOW_ZORDER_BEHIND ) + { + if ( pRefWindow->mpWindowImpl->mpNext == this ) + return; + + if ( ImplIsOverlapWindow() ) + { + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; + if ( !pRefWindow->mpWindowImpl->mpNext ) + mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this; + } + else + { + if ( mpWindowImpl->mpPrev ) + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; + else + mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; + else + mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; + if ( !pRefWindow->mpWindowImpl->mpNext ) + mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; + } + + mpWindowImpl->mpPrev = pRefWindow; + mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext; + if ( mpWindowImpl->mpNext ) + mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; + mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; + } + + if ( IsReallyVisible() ) + { + // restore background storage + if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) + ImplInvalidateAllOverlapBackgrounds(); + + if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() ) + { + bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion; + ImplSetClipFlag(); + + // When ClipRegion was not initialised, assume + // the window has not been sent, therefore do not + // trigger any Invalidates. This is an optimization + // for HTML documents with many controls. If this + // check gives problems, a flag should be introduced + // which tracks whether the window has already been + // emitted after Show + if ( !bInitWinClipRegion ) + { + // Invalidate all windows which are next to each other + // Is INCOMPLETE !!! + Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); + Window* pWindow = NULL; + if ( ImplIsOverlapWindow() ) + { + if ( mpWindowImpl->mpOverlapWindow ) + pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; + } + else + pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild; + // Invalidate all windows in front of us and which are covered by us + while ( pWindow ) + { + if ( pWindow == this ) + break; + Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), + Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); + if ( aWinRect.IsOver( aCompRect ) ) + pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); + pWindow = pWindow->mpWindowImpl->mpNext; + } + + // If we are covered by a window in the background + // we should redraw it + while ( pWindow ) + { + if ( pWindow != this ) + { + Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), + Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); + if ( aWinRect.IsOver( aCompRect ) ) + { + Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); + break; + } + } + pWindow = pWindow->mpWindowImpl->mpNext; + } + } + } + } +} + +void Window::EnableAlwaysOnTop( bool bEnable ) +{ + + mpWindowImpl->mbAlwaysOnTop = bEnable; + + if ( mpWindowImpl->mpBorderWindow ) + mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable ); + else if ( bEnable && IsReallyVisible() ) + ToTop(); + + if ( mpWindowImpl->mbFrame ) + mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable ); +} + +bool Window::IsTopWindow() const +{ + if ( mpWindowImpl->mbInDtor ) + return false; + + // topwindows must be frames or they must have a borderwindow which is a frame + if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) ) + return false; + + ImplGetWinData(); + if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized + { + // #113722#, cache result of expensive queryInterface call + Window *pThisWin = (Window*)this; + uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY ); + pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0; + } + return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? sal_True : sal_False; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 6bf7a674b57b..dd8a6c413f11 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -115,13 +115,6 @@ using ::com::sun::star::awt::XTopWindow; #define IMPL_PAINT_ERASE ((sal_uInt16)0x0010) #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020) -struct ImplCalcToTopData -{ - ImplCalcToTopData* mpNext; - Window* mpWindow; - Region* mpInvalidateRegion; -}; - WindowImpl::WindowImpl( WindowType nType ) { maZoom = Fraction( 1, 1 ); @@ -1157,137 +1150,6 @@ void Window::ImplSetFrameParent( const Window* pParent ) } } -void Window::ImplInsertWindow( Window* pParent ) -{ - mpWindowImpl->mpParent = pParent; - mpWindowImpl->mpRealParent = pParent; - - if ( pParent && !mpWindowImpl->mbFrame ) - { - // search frame window and set window frame data - Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow; - mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData; - mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame; - mpWindowImpl->mpFrameWindow = pFrameParent; - mpWindowImpl->mbFrame = false; - - // search overlap window and insert window in list - if ( ImplIsOverlapWindow() ) - { - Window* pFirstOverlapParent = pParent; - while ( !pFirstOverlapParent->ImplIsOverlapWindow() ) - pFirstOverlapParent = pFirstOverlapParent->ImplGetParent(); - mpWindowImpl->mpOverlapWindow = pFirstOverlapParent; - - mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap; - mpWindowImpl->mpFrameData->mpFirstOverlap = this; - - // Overlap-Windows are by default the uppermost - mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap; - pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this; - if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap ) - pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this; - else - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; - } - else - { - if ( pParent->ImplIsOverlapWindow() ) - mpWindowImpl->mpOverlapWindow = pParent; - else - mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow; - mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild; - pParent->mpWindowImpl->mpLastChild = this; - if ( !pParent->mpWindowImpl->mpFirstChild ) - pParent->mpWindowImpl->mpFirstChild = this; - else - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; - } - } -} - -void Window::ImplRemoveWindow( bool bRemoveFrameData ) -{ - // remove window from the lists - if ( !mpWindowImpl->mbFrame ) - { - if ( ImplIsOverlapWindow() ) - { - if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this ) - mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap; - else - { - Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap; - while ( pTempWin->mpWindowImpl->mpNextOverlap != this ) - pTempWin = pTempWin->mpWindowImpl->mpNextOverlap; - pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap; - } - - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; - } - else - { - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else if ( mpWindowImpl->mpParent ) - mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else if ( mpWindowImpl->mpParent ) - mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; - } - - mpWindowImpl->mpPrev = NULL; - mpWindowImpl->mpNext = NULL; - } - - if ( bRemoveFrameData ) - { - // release the graphic - OutputDevice *pOutDev = GetOutDev(); - pOutDev->ReleaseGraphics(); - } -} - -void Window::reorderWithinParent(sal_uInt16 nNewPosition) -{ - sal_uInt16 nChildCount = 0; - Window *pSource = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild; - while (pSource) - { - if (nChildCount == nNewPosition) - break; - pSource = pSource->mpWindowImpl->mpNext; - nChildCount++; - } - - if (pSource == this) //already at the right place - return; - - ImplRemoveWindow(false); - - if (pSource) - { - mpWindowImpl->mpNext = pSource; - mpWindowImpl->mpPrev = pSource->mpWindowImpl->mpPrev; - pSource->mpWindowImpl->mpPrev = this; - } - else - mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; - - if (mpWindowImpl->mpPrev) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; - else - mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this; -} - void Window::ImplCallResize() { mpWindowImpl->mbCallResize = false; @@ -3345,250 +3207,6 @@ void Window::ImplPosSizeWindow( long nX, long nY, delete pOldRegion; } -void Window::ImplToBottomChild() -{ - if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) ) - { - // put the window to the end of the list - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else - mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild; - mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; - mpWindowImpl->mpNext = NULL; - } -} - -void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData ) -{ - DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" ); - - if ( !mpWindowImpl->mbFrame ) - { - if ( IsReallyVisible() ) - { - // calculate region, where the window overlaps with other windows - Point aPoint( mnOutOffX, mnOutOffY ); - Region aRegion( Rectangle( aPoint, - Size( mnOutWidth, mnOutHeight ) ) ); - Region aInvalidateRegion; - ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion ); - - if ( !aInvalidateRegion.IsEmpty() ) - { - ImplCalcToTopData* pData = new ImplCalcToTopData; - pPrevData->mpNext = pData; - pData->mpNext = NULL; - pData->mpWindow = this; - pData->mpInvalidateRegion = new Region( aInvalidateRegion ); - } - } - } -} - -void Window::ImplToTop( sal_uInt16 nFlags ) -{ - DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" ); - - if ( mpWindowImpl->mbFrame ) - { - // on a mouse click in the external window, it is the latter's - // responsibility to assure our frame is put in front - if ( !mpWindowImpl->mpFrameData->mbHasFocus && - !mpWindowImpl->mpFrameData->mbSysObjFocus && - !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl && - !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl ) - { - // do not bring floating windows on the client to top - if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) ) - { - sal_uInt16 nSysFlags = 0; - if ( nFlags & TOTOP_RESTOREWHENMIN ) - nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN; - if ( nFlags & TOTOP_FOREGROUNDTASK ) - nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK; - if ( nFlags & TOTOP_GRABFOCUSONLY ) - nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY; - mpWindowImpl->mpFrame->ToTop( nSysFlags ); - } - } - } - else - { - if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this ) - { - // remove window from the list - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; - - // take AlwaysOnTop into account - bool bOnTop = IsAlwaysOnTopEnabled(); - Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; - if ( !bOnTop ) - { - while ( pNextWin ) - { - if ( !pNextWin->IsAlwaysOnTopEnabled() ) - break; - pNextWin = pNextWin->mpWindowImpl->mpNext; - } - } - - // check TopLevel - sal_uInt8 nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel; - while ( pNextWin ) - { - if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) || - (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) ) - break; - pNextWin = pNextWin->mpWindowImpl->mpNext; - } - - // add the window to the list again - mpWindowImpl->mpNext = pNextWin; - if ( pNextWin ) - { - mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev; - pNextWin->mpWindowImpl->mpPrev = this; - } - else - { - mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this; - } - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this; - - // recalculate ClipRegion of this and all overlapping windows - if ( IsReallyVisible() ) - { - // reset background storage - if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) - ImplInvalidateAllOverlapBackgrounds(); - mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows(); - } - } - } -} - -void Window::ImplStartToTop( sal_uInt16 nFlags ) -{ - ImplCalcToTopData aStartData; - ImplCalcToTopData* pCurData; - ImplCalcToTopData* pNextData; - Window* pOverlapWindow; - if ( ImplIsOverlapWindow() ) - pOverlapWindow = this; - else - pOverlapWindow = mpWindowImpl->mpOverlapWindow; - - // first calculate paint areas - Window* pTempOverlapWindow = pOverlapWindow; - aStartData.mpNext = NULL; - pCurData = &aStartData; - do - { - pTempOverlapWindow->ImplCalcToTop( pCurData ); - if ( pCurData->mpNext ) - pCurData = pCurData->mpNext; - pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow; - } - while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); - // next calculate the paint areas of the ChildOverlap windows - pTempOverlapWindow = mpWindowImpl->mpFirstOverlap; - while ( pTempOverlapWindow ) - { - pTempOverlapWindow->ImplCalcToTop( pCurData ); - if ( pCurData->mpNext ) - pCurData = pCurData->mpNext; - pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext; - } - - // and next change the windows list - pTempOverlapWindow = pOverlapWindow; - do - { - pTempOverlapWindow->ImplToTop( nFlags ); - pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow; - } - while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); - // as last step invalidate the invalid areas - pCurData = aStartData.mpNext; - while ( pCurData ) - { - pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN ); - pNextData = pCurData->mpNext; - delete pCurData->mpInvalidateRegion; - delete pCurData; - pCurData = pNextData; - } -} - -void Window::ImplFocusToTop( sal_uInt16 nFlags, bool bReallyVisible ) -{ - // do we need to fetch the focus? - if ( !(nFlags & TOTOP_NOGRABFOCUS) ) - { - // first window with GrabFocus-Activate gets the focus - Window* pFocusWindow = this; - while ( !pFocusWindow->ImplIsOverlapWindow() ) - { - // if the window has no BorderWindow, we - // should always find the belonging BorderWindow - if ( !pFocusWindow->mpWindowImpl->mpBorderWindow ) - { - if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS ) - break; - } - pFocusWindow = pFocusWindow->ImplGetParent(); - } - if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) && - !pFocusWindow->HasChildPathFocus( true ) ) - pFocusWindow->GrabFocus(); - } - - if ( bReallyVisible ) - ImplGenerateMouseMove(); -} - -void Window::ImplShowAllOverlaps() -{ - Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; - while ( pOverlapWindow ) - { - if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible ) - { - pOverlapWindow->Show( true, SHOW_NOACTIVATE ); - pOverlapWindow->mpWindowImpl->mbOverlapVisible = false; - } - - pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; - } -} - -void Window::ImplHideAllOverlaps() -{ - Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; - while ( pOverlapWindow ) - { - if ( pOverlapWindow->IsVisible() ) - { - pOverlapWindow->mpWindowImpl->mbOverlapVisible = true; - pOverlapWindow->Show( false ); - } - - pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; - } -} - void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, bool bModChanged ) { if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible ) @@ -6370,200 +5988,6 @@ void Window::SetActivateMode( sal_uInt16 nMode ) } } -void Window::ToTop( sal_uInt16 nFlags ) -{ - - ImplStartToTop( nFlags ); - ImplFocusToTop( nFlags, IsReallyVisible() ); -} - -void Window::SetZOrder( Window* pRefWindow, sal_uInt16 nFlags ) -{ - - if ( mpWindowImpl->mpBorderWindow ) - { - mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags ); - return; - } - - if ( nFlags & WINDOW_ZORDER_FIRST ) - { - if ( ImplIsOverlapWindow() ) - pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; - else - pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild; - nFlags |= WINDOW_ZORDER_BEFOR; - } - else if ( nFlags & WINDOW_ZORDER_LAST ) - { - if ( ImplIsOverlapWindow() ) - pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; - else - pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild; - nFlags |= WINDOW_ZORDER_BEHIND; - } - - while ( pRefWindow && pRefWindow->mpWindowImpl->mpBorderWindow ) - pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow; - if (!pRefWindow || pRefWindow == this || mpWindowImpl->mbFrame) - return; - - DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" ); - if ( nFlags & WINDOW_ZORDER_BEFOR ) - { - if ( pRefWindow->mpWindowImpl->mpPrev == this ) - return; - - if ( ImplIsOverlapWindow() ) - { - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; - if ( !pRefWindow->mpWindowImpl->mpPrev ) - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this; - } - else - { - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else - mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else - mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; - if ( !pRefWindow->mpWindowImpl->mpPrev ) - mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this; - } - - mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev; - mpWindowImpl->mpNext = pRefWindow; - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; - } - else if ( nFlags & WINDOW_ZORDER_BEHIND ) - { - if ( pRefWindow->mpWindowImpl->mpNext == this ) - return; - - if ( ImplIsOverlapWindow() ) - { - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; - if ( !pRefWindow->mpWindowImpl->mpNext ) - mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this; - } - else - { - if ( mpWindowImpl->mpPrev ) - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; - else - mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; - else - mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; - if ( !pRefWindow->mpWindowImpl->mpNext ) - mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; - } - - mpWindowImpl->mpPrev = pRefWindow; - mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext; - if ( mpWindowImpl->mpNext ) - mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; - mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; - } - - if ( IsReallyVisible() ) - { - // restore background storage - if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) - ImplInvalidateAllOverlapBackgrounds(); - - if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() ) - { - bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion; - ImplSetClipFlag(); - - // When ClipRegion was not initialised, assume - // the window has not been sent, therefore do not - // trigger any Invalidates. This is an optimization - // for HTML documents with many controls. If this - // check gives problems, a flag should be introduced - // which tracks whether the window has already been - // emitted after Show - if ( !bInitWinClipRegion ) - { - // Invalidate all windows which are next to each other - // Is INCOMPLETE !!! - Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); - Window* pWindow = NULL; - if ( ImplIsOverlapWindow() ) - { - if ( mpWindowImpl->mpOverlapWindow ) - pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; - } - else - pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild; - // Invalidate all windows in front of us and which are covered by us - while ( pWindow ) - { - if ( pWindow == this ) - break; - Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), - Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); - if ( aWinRect.IsOver( aCompRect ) ) - pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); - pWindow = pWindow->mpWindowImpl->mpNext; - } - - // If we are covered by a window in the background - // we should redraw it - while ( pWindow ) - { - if ( pWindow != this ) - { - Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), - Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); - if ( aWinRect.IsOver( aCompRect ) ) - { - Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); - break; - } - } - pWindow = pWindow->mpWindowImpl->mpNext; - } - } - } - } -} - -void Window::EnableAlwaysOnTop( bool bEnable ) -{ - - mpWindowImpl->mbAlwaysOnTop = bEnable; - - if ( mpWindowImpl->mpBorderWindow ) - mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable ); - else if ( bEnable && IsReallyVisible() ) - ToTop(); - - if ( mpWindowImpl->mbFrame ) - mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable ); -} - void Window::setPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) { @@ -8029,26 +7453,6 @@ bool Window::IsScrollable() const return false; } -bool Window::IsTopWindow() const -{ - if ( mpWindowImpl->mbInDtor ) - return false; - - // topwindows must be frames or they must have a borderwindow which is a frame - if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) ) - return false; - - ImplGetWinData(); - if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized - { - // #113722#, cache result of expensive queryInterface call - Window *pThisWin = (Window*)this; - uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY ); - pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0; - } - return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? sal_True : sal_False; -} - void Window::ImplMirrorFramePos( Point &pt ) const { pt.X() = mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X(); |