LCOV - code coverage report
Current view: top level - vcl/source/window - floatwin.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 226 433 52.2 %
Date: 2015-06-13 12:38:46 Functions: 22 33 66.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 <svdata.hxx>
      21             : #include <brdwin.hxx>
      22             : #include <window.h>
      23             : #include <salframe.hxx>
      24             : 
      25             : #include <vcl/layout.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <vcl/wrkwin.hxx>
      28             : #include <vcl/event.hxx>
      29             : #include <vcl/toolbox.hxx>
      30             : #include <vcl/floatwin.hxx>
      31             : #include <vcl/settings.hxx>
      32             : 
      33             : #include <tools/rc.h>
      34             : #include <tools/debug.hxx>
      35             : 
      36             : class FloatingWindow::ImplData
      37             : {
      38             : public:
      39             :     ImplData();
      40             :     ~ImplData();
      41             : 
      42             :     VclPtr<ToolBox> mpBox;
      43             :     Rectangle       maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
      44             : };
      45             : 
      46        3290 : FloatingWindow::ImplData::ImplData()
      47             : {
      48        3290 :     mpBox = NULL;
      49        3290 : }
      50             : 
      51        3288 : FloatingWindow::ImplData::~ImplData()
      52             : {
      53        3288 : }
      54             : 
      55           0 : Rectangle& FloatingWindow::ImplGetItemEdgeClipRect()
      56             : {
      57           0 :     return mpImplData->maItemEdgeClipRect;
      58             : }
      59             : 
      60        3290 : void FloatingWindow::ImplInit( vcl::Window* pParent, WinBits nStyle )
      61             : {
      62        3290 :     mpImplData = new ImplData;
      63             : 
      64        3290 :     mpWindowImpl->mbFloatWin = true;
      65        3290 :     mbInCleanUp = false;
      66        3290 :     mbGrabFocus = false;
      67             : 
      68             :     DBG_ASSERT(pParent, "FloatWindow::FloatingWindow(): - pParent == NULL!");
      69             : 
      70        3290 :     if (!pParent)
      71           0 :         pParent = ImplGetSVData()->maWinData.mpAppWin;
      72             : 
      73             :     DBG_ASSERT(pParent, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists");
      74             : 
      75             :     // no Border, then we dont need a border window
      76        3290 :     if (!nStyle)
      77             :     {
      78           0 :         mpWindowImpl->mbOverlapWin = true;
      79           0 :         nStyle |= WB_DIALOGCONTROL;
      80           0 :         SystemWindow::ImplInit(pParent, nStyle, NULL);
      81             :     }
      82             :     else
      83             :     {
      84        3290 :         if (!(nStyle & WB_NODIALOGCONTROL))
      85        3290 :             nStyle |= WB_DIALOGCONTROL;
      86             : 
      87        3290 :         if (nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE)
      88           0 :             && !(nStyle & WB_OWNERDRAWDECORATION))
      89             :         {
      90           0 :             WinBits nFloatWinStyle = nStyle;
      91             :             // #99154# floaters are not closeable by default anymore, eg fullscreen floater
      92             :             // nFloatWinStyle |= WB_CLOSEABLE;
      93           0 :             mpWindowImpl->mbFrame = true;
      94           0 :             mpWindowImpl->mbOverlapWin = true;
      95           0 :             SystemWindow::ImplInit(pParent, nFloatWinStyle & ~WB_BORDER, NULL);
      96             :         }
      97             :         else
      98             :         {
      99             :             ImplBorderWindow* pBorderWin;
     100        3290 :             sal_uInt16 nBorderStyle = BORDERWINDOW_STYLE_BORDER | BORDERWINDOW_STYLE_FLOAT;
     101             : 
     102        3290 :             if (nStyle & WB_OWNERDRAWDECORATION)
     103           0 :                 nBorderStyle |= BORDERWINDOW_STYLE_FRAME;
     104             :             else
     105        3290 :                 nBorderStyle |= BORDERWINDOW_STYLE_OVERLAP;
     106             : 
     107        3290 :             if ((nStyle & WB_SYSTEMWINDOW) && !(nStyle & (WB_MOVEABLE | WB_SIZEABLE)))
     108             :             {
     109        3290 :                 nBorderStyle |= BORDERWINDOW_STYLE_FRAME;
     110        3290 :                 nStyle |= WB_CLOSEABLE; // make undecorated floaters closeable
     111             :             }
     112        3290 :             pBorderWin  = VclPtr<ImplBorderWindow>::Create(pParent, nStyle, nBorderStyle);
     113        3290 :             SystemWindow::ImplInit(pBorderWin, nStyle & ~WB_BORDER, NULL);
     114        3290 :             pBorderWin->mpWindowImpl->mpClientWindow = this;
     115             :             pBorderWin->GetBorder(mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder,
     116        3290 :                                   mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder);
     117        3290 :             pBorderWin->SetDisplayActive(true);
     118        3290 :             mpWindowImpl->mpBorderWindow = pBorderWin;
     119        3290 :             mpWindowImpl->mpRealParent = pParent;
     120             :         }
     121             :     }
     122        3290 :     SetActivateMode( ActivateModeFlags::NONE );
     123             : 
     124        3290 :     mpNextFloat             = NULL;
     125        3290 :     mpFirstPopupModeWin     = NULL;
     126        3290 :     mnPostId                = 0;
     127        3290 :     mnTitle                 = (nStyle & (WB_MOVEABLE | WB_POPUP)) ? FloatWinTitleType::Normal : FloatWinTitleType::NONE;
     128        3290 :     mnOldTitle              = mnTitle;
     129        3290 :     mnPopupModeFlags        = FloatWinPopupFlags::NONE;
     130        3290 :     mbInPopupMode           = false;
     131        3290 :     mbPopupMode             = false;
     132        3290 :     mbPopupModeCanceled     = false;
     133        3290 :     mbPopupModeTearOff      = false;
     134        3290 :     mbMouseDown             = false;
     135             : 
     136        3290 :     ImplInitSettings();
     137        3290 : }
     138             : 
     139        3290 : void FloatingWindow::ImplInitSettings()
     140             : {
     141        3290 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     142             : 
     143        3290 :     Color aColor;
     144        3290 :     if (IsControlBackground())
     145           0 :         aColor = GetControlBackground();
     146        3290 :     else if (Window::GetStyle() & WB_3DLOOK)
     147           0 :         aColor = rStyleSettings.GetFaceColor();
     148             :     else
     149        3290 :         aColor = rStyleSettings.GetWindowColor();
     150        3290 :     SetBackground(aColor);
     151        3290 : }
     152             : 
     153        3290 : FloatingWindow::FloatingWindow(vcl::Window* pParent, WinBits nStyle) :
     154        3290 :     SystemWindow(WINDOW_FLOATINGWINDOW)
     155             : {
     156        3290 :     ImplInit(pParent, nStyle);
     157        3290 : }
     158             : 
     159           0 : FloatingWindow::FloatingWindow(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription, const css::uno::Reference<css::frame::XFrame> &rFrame)
     160             :     : SystemWindow(WINDOW_FLOATINGWINDOW)
     161             :     , mpNextFloat(0)
     162             :     , mpFirstPopupModeWin(0)
     163             :     , mpImplData(0)
     164             :     , mnPostId(0)
     165             :     , mnPopupModeFlags(FloatWinPopupFlags::NONE)
     166             :     , mnTitle(FloatWinTitleType::Unknown)
     167             :     , mnOldTitle(FloatWinTitleType::Unknown)
     168             :     , mbInPopupMode(false)
     169             :     , mbPopupMode(false)
     170             :     , mbPopupModeCanceled(false)
     171             :     , mbPopupModeTearOff(false)
     172             :     , mbMouseDown(false)
     173             :     , mbOldSaveBackMode(false)
     174             :     , mbGrabFocus(false)
     175           0 :     , mbInCleanUp(false)
     176             : {
     177           0 :     loadUI(pParent, rID, rUIXMLDescription, rFrame);
     178           0 : }
     179             : 
     180             : //Find the real parent stashed in mpDialogParent.
     181           0 : void FloatingWindow::doDeferredInit(WinBits nBits)
     182             : {
     183           0 :     vcl::Window *pParent = mpDialogParent;
     184           0 :     mpDialogParent = NULL;
     185           0 :     ImplInit(pParent, nBits);
     186           0 :     mbIsDefferedInit = false;
     187           0 : }
     188             : 
     189          20 : void FloatingWindow::ApplySettings(vcl::RenderContext& rRenderContext)
     190             : {
     191          20 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     192             : 
     193          20 :     Color aColor;
     194          20 :     if (Window::GetStyle() & WB_3DLOOK)
     195           0 :         aColor = rStyleSettings.GetFaceColor();
     196             :     else
     197          20 :         aColor = rStyleSettings.GetWindowColor();
     198             : 
     199          20 :     ApplyControlBackground(rRenderContext, aColor);
     200          20 : }
     201             : 
     202        6576 : FloatingWindow::~FloatingWindow()
     203             : {
     204        3288 :     disposeOnce();
     205             : 
     206             :     // Unfortunately the vclwidgets clang plug-in says: "OutputDevice
     207             :     // subclass should have nothing in its destructor but a call to
     208             :     // disposeOnce()."
     209             :     // assert (!mnPostId);
     210        3288 : }
     211             : 
     212        3288 : void FloatingWindow::dispose()
     213             : {
     214        3288 :     if (mpImplData)
     215             :     {
     216        3288 :         if( mbPopupModeCanceled )
     217             :             // indicates that ESC key was pressed
     218             :             // will be handled in Window::ImplGrabFocus()
     219           0 :             SetDialogControlFlags( GetDialogControlFlags() | DialogControlFlags::FloatWinPopupModeEndCancel );
     220             : 
     221        3288 :         if ( IsInPopupMode() )
     222          10 :             EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll | FloatWinPopupEndFlags::DontCallHdl );
     223             : 
     224        3288 :         if ( mnPostId )
     225           8 :             Application::RemoveUserEvent( mnPostId );
     226        3288 :         mnPostId = 0;
     227             :     }
     228             : 
     229        3288 :     delete mpImplData;
     230        3288 :     mpImplData = NULL;
     231             : 
     232        3288 :     mpNextFloat.clear();
     233        3288 :     mpFirstPopupModeWin.clear();
     234        3288 :     SystemWindow::dispose();
     235        3288 : }
     236             : 
     237           0 : Point FloatingWindow::CalcFloatingPosition( vcl::Window* pWindow, const Rectangle& rRect, FloatWinPopupFlags nFlags, sal_uInt16& rArrangeIndex )
     238             : {
     239           0 :     return ImplCalcPos( pWindow, rRect, nFlags, rArrangeIndex );
     240             : }
     241             : 
     242          12 : Point FloatingWindow::ImplCalcPos( vcl::Window* pWindow,
     243             :                                    const Rectangle& rRect, FloatWinPopupFlags nFlags,
     244             :                                    sal_uInt16& rArrangeIndex )
     245             : {
     246             :     // get window position
     247          12 :     Point       aPos;
     248          12 :     Size        aSize = pWindow->GetSizePixel();
     249          12 :     Rectangle   aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel();
     250          12 :     FloatingWindow *pFloatingWindow = dynamic_cast<FloatingWindow*>( pWindow );
     251             : 
     252             :     // convert....
     253          12 :     vcl::Window* pW = pWindow;
     254          12 :     if ( pW->mpWindowImpl->mpRealParent )
     255          12 :         pW = pW->mpWindowImpl->mpRealParent;
     256             : 
     257          12 :     Rectangle normRect( rRect );  // rRect is already relative to top-level window
     258          12 :     normRect.SetPos( pW->ScreenToOutputPixel( normRect.TopLeft() ) );
     259             : 
     260          12 :     bool bRTL = AllSettings::GetLayoutRTL();
     261             : 
     262          24 :     Rectangle devRect(  pW->OutputToAbsoluteScreenPixel( normRect.TopLeft() ),
     263          36 :                         pW->OutputToAbsoluteScreenPixel( normRect.BottomRight() ) );
     264             : 
     265          12 :     Rectangle devRectRTL( devRect );
     266          12 :     if( bRTL )
     267             :         // create a rect that can be compared to desktop coordinates
     268           0 :         devRectRTL = pW->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect );
     269          12 :     if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
     270             :         aScreenRect = Application::GetScreenPosSizePixel(
     271           0 :             Application::GetBestScreen( bRTL ? devRectRTL : devRect ) );
     272             : 
     273             :     FloatWinPopupFlags nArrangeAry[5];
     274             :     sal_uInt16        nArrangeIndex;
     275          12 :     Point             e1,e2;  // the common edge between the item rect and the floating window
     276             : 
     277          12 :     if ( nFlags & FloatWinPopupFlags::Left )
     278             :     {
     279           0 :         nArrangeAry[0]  = FloatWinPopupFlags::Left;
     280           0 :         nArrangeAry[1]  = FloatWinPopupFlags::Right;
     281           0 :         nArrangeAry[2]  = FloatWinPopupFlags::Up;
     282           0 :         nArrangeAry[3]  = FloatWinPopupFlags::Down;
     283           0 :         nArrangeAry[4]  = FloatWinPopupFlags::Left;
     284             :     }
     285          12 :     else if ( nFlags & FloatWinPopupFlags::Right )
     286             :     {
     287           0 :         nArrangeAry[0]  = FloatWinPopupFlags::Right;
     288           0 :         nArrangeAry[1]  = FloatWinPopupFlags::Left;
     289           0 :         nArrangeAry[2]  = FloatWinPopupFlags::Up;
     290           0 :         nArrangeAry[3]  = FloatWinPopupFlags::Down;
     291           0 :         nArrangeAry[4]  = FloatWinPopupFlags::Right;
     292             :     }
     293          12 :     else if ( nFlags & FloatWinPopupFlags::Up )
     294             :     {
     295           0 :         nArrangeAry[0]  = FloatWinPopupFlags::Up;
     296           0 :         nArrangeAry[1]  = FloatWinPopupFlags::Down;
     297           0 :         nArrangeAry[2]  = FloatWinPopupFlags::Right;
     298           0 :         nArrangeAry[3]  = FloatWinPopupFlags::Left;
     299           0 :         nArrangeAry[4]  = FloatWinPopupFlags::Up;
     300             :     }
     301             :     else
     302             :     {
     303          12 :         nArrangeAry[0]  = FloatWinPopupFlags::Down;
     304          12 :         nArrangeAry[1]  = FloatWinPopupFlags::Up;
     305          12 :         nArrangeAry[2]  = FloatWinPopupFlags::Right;
     306          12 :         nArrangeAry[3]  = FloatWinPopupFlags::Left;
     307          12 :         nArrangeAry[4]  = FloatWinPopupFlags::Down;
     308             :     }
     309          12 :     if ( nFlags & FloatWinPopupFlags::NoAutoArrange )
     310           0 :         nArrangeIndex = 4;
     311             :     else
     312          12 :         nArrangeIndex = 0;
     313             : 
     314          12 :     for ( ; nArrangeIndex < 5; nArrangeIndex++ )
     315             :     {
     316          12 :         bool bBreak = true;
     317          12 :         switch ( nArrangeAry[nArrangeIndex] )
     318             :         {
     319             : 
     320             :             case FloatWinPopupFlags::Left:
     321           0 :                 aPos.X() = devRect.Left()-aSize.Width()+1;
     322           0 :                 aPos.Y() = devRect.Top();
     323           0 :                 aPos.Y() -= pWindow->mpWindowImpl->mnTopBorder;
     324           0 :                 if( bRTL ) // --- RTL --- we're comparing screen coordinates here
     325             :                 {
     326           0 :                     if( (devRectRTL.Right()+aSize.Width()) > aScreenRect.Right() )
     327           0 :                         bBreak = false;
     328             :                 }
     329             :                 else
     330             :                 {
     331           0 :                     if ( aPos.X() < aScreenRect.Left() )
     332           0 :                         bBreak = false;
     333             :                 }
     334           0 :                 if( bBreak )
     335             :                 {
     336           0 :                     e1 = devRect.TopLeft();
     337           0 :                     e2 = devRect.BottomLeft();
     338             :                     // set non-zero width
     339           0 :                     e2.X()++;
     340             :                     // don't clip corners
     341           0 :                     e1.Y()++;
     342           0 :                     e2.Y()--;
     343             :                 }
     344           0 :                 break;
     345             :             case FloatWinPopupFlags::Right:
     346           0 :                 aPos     = devRect.TopRight();
     347           0 :                 aPos.Y() -= pWindow->mpWindowImpl->mnTopBorder;
     348           0 :                 if( bRTL ) // --- RTL --- we're comparing screen coordinates here
     349             :                 {
     350           0 :                     if( (devRectRTL.Left() - aSize.Width()) < aScreenRect.Left() )
     351           0 :                         bBreak = false;
     352             :                 }
     353             :                 else
     354             :                 {
     355           0 :                     if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
     356           0 :                         bBreak = false;
     357             :                 }
     358           0 :                 if( bBreak )
     359             :                 {
     360           0 :                     e1 = devRect.TopRight();
     361           0 :                     e2 = devRect.BottomRight();
     362             :                     // set non-zero width
     363           0 :                     e2.X()++;
     364             :                     // don't clip corners
     365           0 :                     e1.Y()++;
     366           0 :                     e2.Y()--;
     367             :                 }
     368           0 :                 break;
     369             :             case FloatWinPopupFlags::Up:
     370           0 :                 aPos.X() = devRect.Left();
     371           0 :                 aPos.Y() = devRect.Top()-aSize.Height()+1;
     372           0 :                 if ( aPos.Y() < aScreenRect.Top() )
     373           0 :                     bBreak = false;
     374           0 :                 if( bBreak )
     375             :                 {
     376           0 :                     e1 = devRect.TopLeft();
     377           0 :                     e2 = devRect.TopRight();
     378             :                     // set non-zero height
     379           0 :                     e2.Y()++;
     380             :                     // don't clip corners
     381           0 :                     e1.X()++;
     382           0 :                     e2.X()--;
     383             :                 }
     384           0 :                 break;
     385             :             case FloatWinPopupFlags::Down:
     386          12 :                 aPos = devRect.BottomLeft();
     387          12 :                 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
     388           0 :                     bBreak = false;
     389          12 :                 if( bBreak )
     390             :                 {
     391          12 :                     e1 = devRect.BottomLeft();
     392          12 :                     e2 = devRect.BottomRight();
     393             :                     // set non-zero height
     394          12 :                     e2.Y()++;
     395             :                     // don't clip corners
     396          12 :                     e1.X()++;
     397          12 :                     e2.X()--;
     398             :                 }
     399          12 :                 break;
     400           0 :             default: break;
     401             :         }
     402             : 
     403             :         // adjust if necessary
     404          12 :         if ( bBreak && !(nFlags & FloatWinPopupFlags::NoAutoArrange) )
     405             :         {
     406          24 :             if ( (nArrangeAry[nArrangeIndex] == FloatWinPopupFlags::Left)  ||
     407          12 :                  (nArrangeAry[nArrangeIndex] == FloatWinPopupFlags::Right) )
     408             :             {
     409           0 :                 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
     410             :                 {
     411           0 :                     aPos.Y() = devRect.Bottom()-aSize.Height()+1;
     412           0 :                     if ( aPos.Y() < aScreenRect.Top() )
     413           0 :                         aPos.Y() = aScreenRect.Top();
     414             :                 }
     415             :             }
     416             :             else
     417             :             {
     418          12 :                 if( bRTL ) // --- RTL --- we're comparing screen coordinates here
     419             :                 {
     420           0 :                     if( devRectRTL.Right()-aSize.Width()+1 < aScreenRect.Left() )
     421           0 :                         aPos.X() -= aScreenRect.Left() - devRectRTL.Right() + aSize.Width() - 1;
     422             :                 }
     423          12 :                 else if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
     424             :                 {
     425           0 :                     aPos.X() = devRect.Right()-aSize.Width()+1;
     426           0 :                     if ( aPos.X() < aScreenRect.Left() )
     427           0 :                         aPos.X() = aScreenRect.Left();
     428             :                 }
     429             :             }
     430             :         }
     431             : 
     432          12 :         if ( bBreak )
     433          12 :             break;
     434             :     }
     435          12 :     if ( nArrangeIndex > 4 )
     436           0 :         nArrangeIndex = 4;
     437             : 
     438          12 :     rArrangeIndex = nArrangeIndex;
     439             : 
     440          12 :     aPos = pW->AbsoluteScreenToOutputPixel( aPos );
     441             : 
     442             :     // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
     443          12 :     if( pFloatingWindow )
     444             :     {
     445             :         pFloatingWindow->mpImplData->maItemEdgeClipRect =
     446          12 :             Rectangle( e1, e2 );
     447             :     }
     448             : 
     449             :     // caller expects cordinates relative to top-level win
     450          12 :     return pW->OutputToScreenPixel( aPos );
     451             : }
     452             : 
     453           0 : FloatingWindow* FloatingWindow::ImplFloatHitTest( vcl::Window* pReference, const Point& rPos, HitTest& rHitTest )
     454             : {
     455           0 :     FloatingWindow* pWin = this;
     456             : 
     457           0 :     Point aAbsolute( rPos );
     458             : 
     459           0 :     const OutputDevice *pWindowOutDev = pReference->GetOutDev();
     460             : 
     461             :     // compare coordinates in absolute screen coordinates
     462           0 :     if( pReference->HasMirroredGraphics()  )
     463             :     {
     464           0 :         if(!pReference->IsRTLEnabled() )
     465             :             // --- RTL --- re-mirror back to get device coordiantes
     466           0 :             pWindowOutDev->ReMirror( aAbsolute );
     467             : 
     468           0 :         Rectangle aRect( pReference->ScreenToOutputPixel(aAbsolute), Size(1,1) ) ;
     469           0 :         aRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect );
     470           0 :         aAbsolute = aRect.TopLeft();
     471             :     }
     472             :     else
     473             :         aAbsolute = Point( pReference->OutputToAbsoluteScreenPixel(
     474           0 :             pReference->ScreenToOutputPixel(rPos) ) );
     475             : 
     476           0 :     do
     477             :     {
     478             :         // compute the floating window's size in absolute screen coordinates
     479             : 
     480             :         // use the border window to have the exact position
     481           0 :         vcl::Window *pBorderWin = pWin->GetWindow( GetWindowType::Border );
     482             : 
     483           0 :         Point aPt;  // the top-left corner in output coordinates ie (0,0)
     484           0 :         Rectangle devRect( pBorderWin->ImplOutputToUnmirroredAbsoluteScreenPixel( Rectangle( aPt, pBorderWin->GetSizePixel()) ) ) ;
     485           0 :         if ( devRect.IsInside( aAbsolute ) )
     486             :         {
     487           0 :             rHitTest = HITTEST_WINDOW;
     488           0 :             return pWin;
     489             :         }
     490             : 
     491             :         // test, if mouse is in rectangle, (this is typically the rect of the active
     492             :         // toolbox item or similar)
     493             :         // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
     494             :         //       is already in absolute device coordinates
     495           0 :         if ( pWin->maFloatRect.IsInside( aAbsolute ) )
     496             :         {
     497           0 :             rHitTest = HITTEST_RECT;
     498           0 :             return pWin;
     499             :         }
     500             : 
     501           0 :         pWin = pWin->mpNextFloat;
     502             :     }
     503             :     while ( pWin );
     504             : 
     505           0 :     rHitTest = HITTEST_OUTSIDE;
     506           0 :     return NULL;
     507             : }
     508             : 
     509           0 : FloatingWindow* FloatingWindow::ImplFindLastLevelFloat()
     510             : {
     511           0 :     FloatingWindow* pWin = this;
     512           0 :     FloatingWindow* pLastFoundWin = pWin;
     513             : 
     514           0 :     do
     515             :     {
     516           0 :         if ( pWin->GetPopupModeFlags() & FloatWinPopupFlags::NewLevel )
     517           0 :             pLastFoundWin = pWin;
     518             : 
     519           0 :         pWin = pWin->mpNextFloat;
     520             :     }
     521             :     while ( pWin );
     522             : 
     523           0 :     return pLastFoundWin;
     524             : }
     525             : 
     526           0 : bool FloatingWindow::ImplIsFloatPopupModeWindow( const vcl::Window* pWindow )
     527             : {
     528           0 :     FloatingWindow* pWin = this;
     529             : 
     530           0 :     do
     531             :     {
     532           0 :         if ( pWin->mpFirstPopupModeWin == pWindow )
     533           0 :             return true;
     534             : 
     535           0 :         pWin = pWin->mpNextFloat;
     536             :     }
     537             :     while ( pWin );
     538             : 
     539           0 :     return false;
     540             : }
     541             : 
     542           4 : IMPL_LINK_NOARG(FloatingWindow, ImplEndPopupModeHdl)
     543             : {
     544           2 :     VclPtr<FloatingWindow> pThis(this);
     545           2 :     mnPostId            = 0;
     546           2 :     mnPopupModeFlags    = FloatWinPopupFlags::NONE;
     547           2 :     mbPopupMode         = false;
     548           2 :     PopupModeEnd();
     549           2 :     return 0;
     550             : }
     551             : 
     552       16401 : bool FloatingWindow::Notify( NotifyEvent& rNEvt )
     553             : {
     554             :     // call Base Class first for tab control
     555       16401 :     bool nRet = SystemWindow::Notify( rNEvt );
     556       16401 :     if ( !nRet )
     557             :     {
     558       16401 :         if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
     559             :         {
     560           0 :             const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
     561           0 :             vcl::KeyCode    aKeyCode = pKEvt->GetKeyCode();
     562           0 :             sal_uInt16      nKeyCode = aKeyCode.GetCode();
     563             : 
     564           0 :             if ( (nKeyCode == KEY_ESCAPE) && (GetStyle() & WB_CLOSEABLE) )
     565             :             {
     566           0 :                 Close();
     567           0 :                 return true;
     568             :             }
     569             :         }
     570             :     }
     571             : 
     572       16401 :     return nRet;
     573             : }
     574             : 
     575          36 : void FloatingWindow::StateChanged( StateChangedType nType )
     576             : {
     577          36 :     if (nType == StateChangedType::InitShow)
     578             :     {
     579          12 :         DoInitialLayout();
     580             :     }
     581             : 
     582          36 :     SystemWindow::StateChanged( nType );
     583             : 
     584          36 :     if ( nType == StateChangedType::ControlBackground )
     585             :     {
     586           0 :         ImplInitSettings();
     587           0 :         Invalidate();
     588             :     }
     589          36 : }
     590             : 
     591           0 : void FloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
     592             : {
     593           0 :     SystemWindow::DataChanged( rDCEvt );
     594             : 
     595           0 :     if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
     596           0 :          (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
     597             :     {
     598           0 :         ImplInitSettings();
     599           0 :         Invalidate();
     600             :     }
     601           0 : }
     602             : 
     603          10 : void FloatingWindow::ImplCallPopupModeEnd()
     604             : {
     605             :     // PopupMode is finished
     606          10 :     mbInPopupMode = false;
     607             : 
     608             :     // call Handler asynchronously.
     609          10 :     if ( mpImplData && !mnPostId )
     610          10 :         mnPostId = Application::PostUserEvent( LINK( this, FloatingWindow, ImplEndPopupModeHdl ), NULL, true );
     611          10 : }
     612             : 
     613           2 : void FloatingWindow::PopupModeEnd()
     614             : {
     615           2 :     maPopupModeEndHdl.Call( this );
     616           2 : }
     617             : 
     618          24 : void FloatingWindow::SetTitleType( FloatWinTitleType nTitle )
     619             : {
     620          24 :     if ( (mnTitle != nTitle) && mpWindowImpl->mpBorderWindow )
     621             :     {
     622           0 :         mnTitle = nTitle;
     623           0 :         Size aOutSize = GetOutputSizePixel();
     624             :         sal_uInt16 nTitleStyle;
     625           0 :         if ( nTitle == FloatWinTitleType::Normal )
     626           0 :             nTitleStyle = BORDERWINDOW_TITLE_SMALL;
     627           0 :         else if ( nTitle == FloatWinTitleType::TearOff )
     628           0 :             nTitleStyle = BORDERWINDOW_TITLE_TEAROFF;
     629           0 :         else if ( nTitle == FloatWinTitleType::Popup )
     630           0 :             nTitleStyle = BORDERWINDOW_TITLE_POPUP;
     631             :         else // nTitle == FloatWinTitleType::NONE
     632           0 :             nTitleStyle = BORDERWINDOW_TITLE_NONE;
     633           0 :         static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetTitleType( nTitleStyle, aOutSize );
     634           0 :         static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
     635             :     }
     636          24 : }
     637             : 
     638          12 : void FloatingWindow::StartPopupMode( const Rectangle& rRect, FloatWinPopupFlags nFlags )
     639             : {
     640          12 :     if ( IsRollUp() )
     641           0 :         RollDown();
     642             : 
     643             :     // remove title
     644          12 :     mnOldTitle = mnTitle;
     645          12 :     if ( ( mpWindowImpl->mnStyle & WB_POPUP ) && !GetText().isEmpty() )
     646           0 :         SetTitleType( FloatWinTitleType::Popup );
     647          12 :     else if ( nFlags & FloatWinPopupFlags::AllowTearOff )
     648           0 :         SetTitleType( FloatWinTitleType::TearOff );
     649             :     else
     650          12 :         SetTitleType( FloatWinTitleType::NONE );
     651             : 
     652             :     // avoid close on focus change for decorated floating windows only
     653          12 :     if( mpWindowImpl->mbFrame && (GetStyle() & WB_MOVEABLE) )
     654           0 :         nFlags |= FloatWinPopupFlags::NoAppFocusClose;
     655             : 
     656             :     // #102010# For debugging Accessibility
     657          12 :     static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
     658          12 :     if( pEnv && *pEnv )
     659           0 :         nFlags |= FloatWinPopupFlags::NoAppFocusClose;
     660             : 
     661             :     // compute window position according to flags and arrangement
     662             :     sal_uInt16 nArrangeIndex;
     663          12 :     Point aPos = ImplCalcPos( this, rRect, nFlags, nArrangeIndex );
     664          12 :     SetPosPixel( aPos );
     665             : 
     666             :     // set data and display window
     667             :     // convert maFloatRect to absolute device coordinates
     668             :     // so they can be compared across different frames
     669             :     // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
     670          12 :     maFloatRect             = rRect;
     671             : 
     672          12 :     vcl::Window *pReference =  GetParent();
     673          12 :     const OutputDevice *pParentWinOutDev = pReference->GetOutDev();
     674             : 
     675             :     // compare coordinates in absolute screen coordinates
     676             :     // Keep in sync with FloatingWindow::ImplFloatHitTest, e.g. fdo#33509
     677          12 :     if( pReference->HasMirroredGraphics()  )
     678             :     {
     679           0 :         if(!pReference->IsRTLEnabled() )
     680             :             // --- RTL --- re-mirror back to get device coordiantes
     681           0 :             pParentWinOutDev->ReMirror(maFloatRect);
     682             : 
     683           0 :         maFloatRect.SetPos(pReference->ScreenToOutputPixel(maFloatRect.TopLeft()));
     684           0 :         maFloatRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel(maFloatRect);
     685             :     }
     686             :     else
     687          12 :         maFloatRect.SetPos(pReference->OutputToAbsoluteScreenPixel(pReference->ScreenToOutputPixel(rRect.TopLeft())));
     688             : 
     689          12 :     maFloatRect.Left()     -= 2;
     690          12 :     maFloatRect.Top()      -= 2;
     691          12 :     maFloatRect.Right()    += 2;
     692          12 :     maFloatRect.Bottom()   += 2;
     693          12 :     mnPopupModeFlags        = nFlags;
     694          12 :     mbInPopupMode           = true;
     695          12 :     mbPopupMode             = true;
     696          12 :     mbPopupModeCanceled     = false;
     697          12 :     mbPopupModeTearOff      = false;
     698          12 :     mbMouseDown             = false;
     699             : 
     700          12 :     mbOldSaveBackMode       = IsSaveBackgroundEnabled();
     701          12 :     EnableSaveBackground();
     702             : 
     703             :     // add FloatingWindow to list of windows that are in popup mode
     704          12 :     ImplSVData* pSVData = ImplGetSVData();
     705          12 :     mpNextFloat = pSVData->maWinData.mpFirstFloat;
     706          12 :     pSVData->maWinData.mpFirstFloat = this;
     707          12 :     if( nFlags & FloatWinPopupFlags::GrabFocus )
     708             :     {
     709             :         // force key input even without focus (useful for menus)
     710           8 :         mbGrabFocus = true;
     711             :     }
     712          12 :     Show( true, ShowFlags::NoActivate );
     713          12 : }
     714             : 
     715           0 : void FloatingWindow::StartPopupMode( ToolBox* pBox, FloatWinPopupFlags nFlags )
     716             : {
     717             :     // get selected button
     718           0 :     sal_uInt16 nItemId = pBox->GetDownItemId();
     719           0 :     if ( !nItemId )
     720           0 :         return;
     721             : 
     722           0 :     mpImplData->mpBox = pBox;
     723           0 :     pBox->ImplFloatControl( true, this );
     724             : 
     725             :     // retrieve some data from the ToolBox
     726           0 :     Rectangle aRect = pBox->GetItemRect( nItemId );
     727           0 :     Point aPos;
     728             :     // convert to parent's screen coordinates
     729           0 :     aPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
     730           0 :     aRect.SetPos( aPos );
     731             : 
     732           0 :     nFlags |=
     733             :         FloatWinPopupFlags::NoFocusClose     |
     734             : //        FloatWinPopupFlags::NoMouseClose       |
     735             :         FloatWinPopupFlags::AllMouseButtonClose |
     736             : //        FloatWinPopupFlags::NoMouseRectClose   |   // #105968# floating toolboxes should close when clicked in (parent's) float rect
     737           0 :         FloatWinPopupFlags::NoMouseUpClose;
     738             : //          |      FloatWinPopupFlags::NoAppFocusClose;
     739             : 
     740             : /*
     741             :  *  FloatWinPopupFlags::NoKeyClose       |
     742             :  *  don't set since it disables closing floaters with escape
     743             :  */
     744             : 
     745             :     // set Flags for positioning
     746           0 :     if ( !(nFlags & (FloatWinPopupFlags::Down | FloatWinPopupFlags::Up |
     747             :                      FloatWinPopupFlags::Left | FloatWinPopupFlags::Right |
     748           0 :                      FloatWinPopupFlags::NoAutoArrange)) )
     749             :     {
     750           0 :          if ( pBox->IsHorizontal() )
     751           0 :              nFlags |= FloatWinPopupFlags::Down;
     752             :          else
     753           0 :              nFlags |= FloatWinPopupFlags::Right;
     754             :     }
     755             : 
     756             :     // start FloatingMode
     757           0 :     StartPopupMode( aRect, nFlags );
     758             : }
     759             : 
     760          20 : void FloatingWindow::ImplEndPopupMode( FloatWinPopupEndFlags nFlags, sal_uLong nFocusId )
     761             : {
     762          20 :     if ( !mbInPopupMode )
     763          28 :         return;
     764             : 
     765          12 :     ImplSVData* pSVData = ImplGetSVData();
     766             : 
     767          12 :     mbInCleanUp = true; // prevent killing this window due to focus change while working with it
     768             : 
     769             :     // stop the PopupMode also for all following PopupMode windows
     770          24 :     while ( pSVData->maWinData.mpFirstFloat && pSVData->maWinData.mpFirstFloat.get() != this )
     771           0 :         pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel );
     772             : 
     773             :     // delete window from the list
     774          12 :     pSVData->maWinData.mpFirstFloat = mpNextFloat;
     775          12 :     mpNextFloat = NULL;
     776             : 
     777          12 :     FloatWinPopupFlags nPopupModeFlags = mnPopupModeFlags;
     778             : 
     779             :     // hide window again if it was not deleted
     780          24 :     if ( !(nFlags & FloatWinPopupEndFlags::TearOff) ||
     781          12 :          !(nPopupModeFlags & FloatWinPopupFlags::AllowTearOff) )
     782             :     {
     783          12 :         Show( false, ShowFlags::NoFocusChange );
     784             : 
     785             :         // maybe pass focus on to a suitable FloatingWindow
     786          12 :         if ( nFocusId )
     787           0 :             Window::EndSaveFocus( nFocusId );
     788          12 :         else if ( pSVData->maWinData.mpFocusWin && pSVData->maWinData.mpFirstFloat &&
     789           0 :                   ImplIsWindowOrChild( pSVData->maWinData.mpFocusWin ) )
     790           0 :             pSVData->maWinData.mpFirstFloat->GrabFocus();
     791          12 :         mbPopupModeTearOff = false;
     792             :     }
     793             :     else
     794             :     {
     795           0 :         mbPopupModeTearOff = true;
     796           0 :         if ( nFocusId )
     797           0 :             Window::EndSaveFocus( nFocusId, false );
     798             :     }
     799          12 :     EnableSaveBackground( mbOldSaveBackMode );
     800             : 
     801          12 :     mbPopupModeCanceled = bool(nFlags & FloatWinPopupEndFlags::Cancel);
     802             : 
     803             :     // redo title
     804          12 :     SetTitleType( mnOldTitle );
     805             : 
     806             :     // set ToolBox again to normal
     807          12 :     if ( mpImplData->mpBox )
     808             :     {
     809           0 :         mpImplData->mpBox->ImplFloatControl( false, this );
     810           0 :         mpImplData->mpBox = NULL;
     811             :     }
     812             : 
     813             :     // call PopupModeEnd-Handler depending on parameter
     814          12 :     if ( !(nFlags & FloatWinPopupEndFlags::DontCallHdl) )
     815          10 :         ImplCallPopupModeEnd();
     816             : 
     817             :     // close all other windows depending on parameter
     818          12 :     if ( nFlags & FloatWinPopupEndFlags::CloseAll )
     819             :     {
     820           2 :         if ( !(nPopupModeFlags & FloatWinPopupFlags::NewLevel) )
     821             :         {
     822           2 :             if ( pSVData->maWinData.mpFirstFloat )
     823             :             {
     824           0 :                 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
     825           0 :                 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
     826             :             }
     827             :         }
     828             :     }
     829             : 
     830          12 :     mbInCleanUp = false;
     831             : }
     832             : 
     833          12 : void FloatingWindow::EndPopupMode( FloatWinPopupEndFlags nFlags )
     834             : {
     835          12 :     ImplEndPopupMode( nFlags );
     836          12 : }
     837             : 
     838           8 : void FloatingWindow::AddPopupModeWindow( vcl::Window* pWindow )
     839             : {
     840             :     // !!! up-to-now only 1 window and not yet a list
     841           8 :     mpFirstPopupModeWin = pWindow;
     842           8 : }
     843             : 
     844           0 : void FloatingWindow::setPosSizeOnContainee(Size aSize, Window &rBox)
     845             : {
     846           0 :     sal_Int32 nBorderWidth = get_border_width();
     847             : 
     848           0 :     aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder + 2 * nBorderWidth;
     849           0 :     aSize.Height() -= nBorderWidth + mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder + 2 * nBorderWidth;
     850             : 
     851           0 :     Point aPos(nBorderWidth, nBorderWidth);
     852           0 :     VclContainer::setLayoutAllocation(rBox, aPos, aSize);
     853         801 : }
     854             : 
     855             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11