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

Generated by: LCOV version 1.10