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

Generated by: LCOV version 1.10