LCOV - code coverage report
Current view: top level - vcl/source/window - status.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 493 798 61.8 %
Date: 2015-06-13 12:38:46 Functions: 50 68 73.5 %
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 <tools/debug.hxx>
      21             : #include <tools/rc.h>
      22             : 
      23             : #include <vcl/event.hxx>
      24             : #include <vcl/decoview.hxx>
      25             : #include <vcl/svapp.hxx>
      26             : #include <vcl/help.hxx>
      27             : #include <vcl/status.hxx>
      28             : #include <vcl/virdev.hxx>
      29             : #include <vcl/settings.hxx>
      30             : 
      31             : #include <svdata.hxx>
      32             : #include <window.h>
      33             : 
      34             : #define STATUSBAR_OFFSET_X      STATUSBAR_OFFSET
      35             : #define STATUSBAR_OFFSET_Y      2
      36             : #define STATUSBAR_OFFSET_TEXTY  3
      37             : 
      38             : #define STATUSBAR_PRGS_OFFSET   3
      39             : #define STATUSBAR_PRGS_COUNT    100
      40             : #define STATUSBAR_PRGS_MIN      5
      41             : 
      42             : class StatusBar::ImplData
      43             : {
      44             : public:
      45             :     ImplData();
      46             :     ~ImplData();
      47             : 
      48             :     VclPtr<VirtualDevice> mpVirDev;
      49             :     long                mnItemBorderWidth;
      50             :     bool                mbDrawItemFrames:1;
      51             : };
      52             : 
      53        6495 : StatusBar::ImplData::ImplData()
      54             : {
      55        6495 :     mpVirDev = NULL;
      56        6495 :     mbDrawItemFrames = false;
      57        6495 :     mnItemBorderWidth = 0;
      58        6495 : }
      59             : 
      60        6486 : StatusBar::ImplData::~ImplData()
      61             : {
      62        6486 : }
      63             : 
      64       12916 : struct ImplStatusItem
      65             : {
      66             :     sal_uInt16              mnId;
      67             :     StatusBarItemBits   mnBits;
      68             :     long                mnWidth;
      69             :     long                mnOffset;
      70             :     long                mnExtraWidth;
      71             :     long                mnX;
      72             :     OUString            maText;
      73             :     OUString            maHelpText;
      74             :     OUString            maQuickHelpText;
      75             :     OString             maHelpId;
      76             :     void*               mpUserData;
      77             :     bool            mbVisible;
      78             :     OUString            maAccessibleName;
      79             :     OUString            maCommand;
      80             : };
      81             : 
      82      322011 : inline long ImplCalcProgessWidth( sal_uInt16 nMax, long nSize )
      83             : {
      84      322011 :     return ((nMax*(nSize+(nSize/2)))-(nSize/2)+(STATUSBAR_PRGS_OFFSET*2));
      85             : }
      86             : 
      87       51054 : static Point ImplGetItemTextPos( const Size& rRectSize, const Size& rTextSize,
      88             :                                  sal_uInt16 nStyle )
      89             : {
      90             :     long nX;
      91             :     long nY;
      92       51054 :     long delta = (rTextSize.Height()/4) + 1;
      93       51054 :     if( delta + rTextSize.Width() > rRectSize.Width() )
      94        2576 :         delta = 0;
      95             : 
      96       51054 :     if ( nStyle & SIB_LEFT )
      97       18655 :         nX = delta;
      98       32399 :     else if ( nStyle & SIB_RIGHT )
      99          22 :         nX = rRectSize.Width()-rTextSize.Width()-delta;
     100             :     else // SIB_CENTER
     101       32377 :         nX = (rRectSize.Width()-rTextSize.Width())/2;
     102       51054 :     nY = (rRectSize.Height()-rTextSize.Height())/2 + 1;
     103       51054 :     return Point( nX, nY );
     104             : }
     105             : 
     106       16057 : bool StatusBar::ImplIsItemUpdate()
     107             : {
     108       16057 :     if ( !mbProgressMode && mbVisibleItems && IsReallyVisible() && IsUpdateMode() )
     109        3132 :         return true;
     110             :     else
     111       12925 :         return false;
     112             : }
     113             : 
     114        6495 : void StatusBar::ImplInit( vcl::Window* pParent, WinBits nStyle )
     115             : {
     116        6495 :     mpImplData = new ImplData;
     117             : 
     118             :     // default: RightAlign
     119        6495 :     if ( !(nStyle & (WB_LEFT | WB_RIGHT)) )
     120           0 :         nStyle |= WB_RIGHT;
     121             : 
     122        6495 :     Window::ImplInit( pParent, nStyle & ~WB_BORDER, NULL );
     123             : 
     124             :     // remember WinBits
     125        6495 :     mpItemList      = new ImplStatusItemList;
     126        6495 :     mpImplData->mpVirDev = VclPtr<VirtualDevice>::Create( *this );
     127        6495 :     mnCurItemId     = 0;
     128        6495 :     mbFormat        = true;
     129        6495 :     mbVisibleItems  = true;
     130        6495 :     mbProgressMode  = false;
     131        6495 :     mbInUserDraw    = false;
     132        6495 :     mbAdjustHiDPI   = false;
     133        6495 :     mnItemsWidth    = STATUSBAR_OFFSET_X;
     134        6495 :     mnDX            = 0;
     135        6495 :     mnDY            = 0;
     136        6495 :     mnCalcHeight    = 0;
     137        6495 :     mnItemY         = STATUSBAR_OFFSET_Y;
     138        6495 :     mnTextY         = STATUSBAR_OFFSET_TEXTY;
     139             : 
     140        6495 :     ImplInitSettings();
     141             : 
     142        6495 :     SetOutputSizePixel( CalcWindowSizePixel() );
     143        6495 : }
     144             : 
     145        6495 : StatusBar::StatusBar( vcl::Window* pParent, WinBits nStyle ) :
     146        6495 :     Window( WINDOW_STATUSBAR )
     147             : {
     148        6495 :     ImplInit( pParent, nStyle );
     149        6495 : }
     150             : 
     151       16251 : StatusBar::~StatusBar()
     152             : {
     153        6486 :     disposeOnce();
     154        9765 : }
     155             : 
     156        6486 : void StatusBar::dispose()
     157             : {
     158             :     // delete all items
     159       12944 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
     160        6458 :         delete (*mpItemList)[ i ];
     161             :     }
     162        6486 :     delete mpItemList;
     163             : 
     164             :     // delete VirtualDevice
     165        6486 :     mpImplData->mpVirDev.disposeAndClear();
     166        6486 :     delete mpImplData;
     167        6486 :     Window::dispose();
     168        6486 : }
     169             : 
     170        3213 : void StatusBar::AdjustItemWidthsForHiDPI(bool bAdjustHiDPI)
     171             : {
     172        3213 :     mbAdjustHiDPI = bAdjustHiDPI;
     173        3213 : }
     174             : 
     175       21498 : void StatusBar::ApplySettings(vcl::RenderContext& rRenderContext)
     176             : {
     177       21498 :     rRenderContext.SetLineColor();
     178             : 
     179       21498 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     180       21498 :     vcl::Font aFont = rStyleSettings.GetToolFont();
     181       21498 :     if (IsControlFont())
     182           0 :         aFont.Merge(GetControlFont());
     183       21498 :     SetZoomedPointFont(rRenderContext, aFont);
     184             : 
     185       21498 :     Color aColor;
     186       21498 :     if (IsControlForeground())
     187           0 :         aColor = GetControlForeground();
     188       21498 :     else if (GetStyle() & WB_3DLOOK)
     189       21498 :         aColor = rStyleSettings.GetButtonTextColor();
     190             :     else
     191           0 :         aColor = rStyleSettings.GetWindowTextColor();
     192             : 
     193       21498 :     rRenderContext.SetTextColor(aColor);
     194       21498 :     rRenderContext.SetTextFillColor();
     195             : 
     196       21498 :     if (IsControlBackground())
     197           0 :         aColor = GetControlBackground();
     198       21498 :     else if (GetStyle() & WB_3DLOOK)
     199       21498 :         aColor = rStyleSettings.GetFaceColor();
     200             :     else
     201           0 :         aColor = rStyleSettings.GetWindowColor();
     202       21498 :     rRenderContext.SetBackground(aColor);
     203             : 
     204             :     // NWF background
     205       42996 :     if (!IsControlBackground() &&
     206       21498 :           rRenderContext.IsNativeControlSupported(CTRL_WINDOW_BACKGROUND, PART_BACKGROUND_WINDOW))
     207             :     {
     208          17 :         ImplGetWindowImpl()->mnNativeBackground = PART_BACKGROUND_WINDOW;
     209          17 :         EnableChildTransparentMode(true);
     210       21498 :     }
     211       21498 : }
     212             : 
     213        6561 : void StatusBar::ImplInitSettings()
     214             : {
     215        6561 :     ApplySettings(*this);
     216             : 
     217        6561 :     mpImplData->mpVirDev->SetFont(GetFont());
     218        6561 :     mpImplData->mpVirDev->SetTextColor(GetTextColor());
     219        6561 :     mpImplData->mpVirDev->SetTextAlign(GetTextAlign());
     220        6561 :     mpImplData->mpVirDev->SetTextFillColor();
     221        6561 :     mpImplData->mpVirDev->SetBackground(GetBackground());
     222        6561 : }
     223             : 
     224       10391 : void StatusBar::ImplFormat()
     225             : {
     226             :     ImplStatusItem* pItem;
     227             :     long            nExtraWidth;
     228             :     long            nExtraWidth2;
     229             :     long            nX;
     230       10391 :     sal_uInt16          nAutoSizeItems = 0;
     231             : 
     232             :     // sum up widths
     233       10391 :     mnItemsWidth = STATUSBAR_OFFSET_X;
     234       10391 :     long nOffset = 0;
     235       47535 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
     236       37144 :         pItem = (*mpItemList)[ i ];
     237       37144 :         if ( pItem->mbVisible )
     238             :         {
     239       37144 :             if ( pItem->mnBits & SIB_AUTOSIZE ) {
     240       14805 :                 nAutoSizeItems++;
     241             :             }
     242             : 
     243       37144 :             mnItemsWidth += pItem->mnWidth + nOffset;
     244       37144 :             nOffset = pItem->mnOffset;
     245             :         }
     246             :     }
     247             : 
     248       10391 :     if ( GetStyle() & WB_RIGHT )
     249             :     {
     250             :         // AutoSize isn't computed for right-alignment,
     251             :         // because we show the text that is declared by SetText on the left side
     252           0 :         nX              = mnDX - mnItemsWidth;
     253           0 :         nExtraWidth     = 0;
     254           0 :         nExtraWidth2    = 0;
     255             :     }
     256             :     else
     257             :     {
     258       10391 :         mnItemsWidth += STATUSBAR_OFFSET_X;
     259             : 
     260             :         // calling AutoSize is potentially necessary for left-aligned text,
     261       10391 :         if ( nAutoSizeItems && (mnDX > (mnItemsWidth - STATUSBAR_OFFSET)) )
     262             :         {
     263         534 :             nExtraWidth  = (mnDX - mnItemsWidth - 1) / nAutoSizeItems;
     264         534 :             nExtraWidth2 = (mnDX - mnItemsWidth - 1) % nAutoSizeItems;
     265             :         }
     266             :         else
     267             :         {
     268        9857 :             nExtraWidth  = 0;
     269        9857 :             nExtraWidth2 = 0;
     270             :         }
     271       10391 :         nX = STATUSBAR_OFFSET_X;
     272             : 
     273       10391 :         if( HasMirroredGraphics() && IsRTLEnabled() )
     274           0 :             nX += ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
     275             :     }
     276             : 
     277       47535 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
     278       37144 :         pItem = (*mpItemList)[ i ];
     279       37144 :         if ( pItem->mbVisible ) {
     280       37144 :             if ( pItem->mnBits & SIB_AUTOSIZE ) {
     281       14805 :                 pItem->mnExtraWidth = nExtraWidth;
     282       14805 :                 if ( nExtraWidth2 ) {
     283         331 :                     pItem->mnExtraWidth++;
     284         331 :                     nExtraWidth2--;
     285             :                 }
     286             :             } else {
     287       22339 :                 pItem->mnExtraWidth = 0;
     288             :             }
     289             : 
     290       37144 :             pItem->mnX = nX;
     291       37144 :             nX += pItem->mnWidth + pItem->mnExtraWidth + pItem->mnOffset;
     292             :         }
     293             :     }
     294             : 
     295       10391 :     mbFormat = false;
     296       10391 : }
     297             : 
     298       71210 : Rectangle StatusBar::ImplGetItemRectPos( sal_uInt16 nPos ) const
     299             : {
     300       71210 :     Rectangle       aRect;
     301             :     ImplStatusItem* pItem;
     302       71210 :     pItem = ( nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ] : NULL;
     303       71210 :     if ( pItem )
     304             :     {
     305       71210 :         if ( pItem->mbVisible )
     306             :         {
     307       71210 :             aRect.Left()   = pItem->mnX;
     308       71210 :             aRect.Right()  = aRect.Left() + pItem->mnWidth + pItem->mnExtraWidth;
     309       71210 :             aRect.Top()    = mnItemY;
     310       71210 :             aRect.Bottom() = mnCalcHeight - STATUSBAR_OFFSET_Y;
     311             :         }
     312             :     }
     313             : 
     314       71210 :     return aRect;
     315             : }
     316             : 
     317       46991 : sal_uInt16 StatusBar::ImplGetFirstVisiblePos() const
     318             : {
     319       46991 :     for( size_t nPos = 0; nPos < mpItemList->size(); nPos++ )
     320             :     {
     321       46991 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
     322       46991 :         if ( pItem )
     323             :         {
     324       46991 :             if ( pItem->mbVisible )
     325       46991 :                 return sal_uInt16(nPos);
     326             :         }
     327             :     }
     328             : 
     329           0 :     return SAL_MAX_UINT16;
     330             : }
     331             : 
     332           0 : void StatusBar::ImplDrawText(vcl::RenderContext& rRenderContext, bool bOffScreen, long nOldTextWidth)
     333             : {
     334             :     // prevent item box from being overwritten
     335           0 :     Rectangle aTextRect;
     336           0 :     aTextRect.Left() = STATUSBAR_OFFSET_X + 1;
     337           0 :     aTextRect.Top() = mnTextY;
     338           0 :     if (mbVisibleItems && (GetStyle() & WB_RIGHT))
     339           0 :         aTextRect.Right() = mnDX - mnItemsWidth - 1;
     340             :     else
     341           0 :         aTextRect.Right() = mnDX - 1;
     342           0 :     if (aTextRect.Right() > aTextRect.Left())
     343             :     {
     344             :         // compute position
     345           0 :         OUString aStr = GetText();
     346           0 :         sal_Int32 nPos = aStr.indexOf('\n');
     347           0 :         if (nPos != -1)
     348           0 :             aStr = aStr.copy(0, nPos);
     349             : 
     350           0 :         aTextRect.Bottom() = aTextRect.Top()+GetTextHeight()+1;
     351             : 
     352           0 :         if (bOffScreen)
     353             :         {
     354           0 :             long nMaxWidth = std::max(nOldTextWidth, GetTextWidth(aStr));
     355           0 :             Size aVirDevSize(nMaxWidth, aTextRect.GetHeight());
     356           0 :             mpImplData->mpVirDev->SetOutputSizePixel( aVirDevSize );
     357           0 :             Rectangle aTempRect = aTextRect;
     358           0 :             aTempRect.SetPos(Point(0, 0));
     359           0 :             mpImplData->mpVirDev->DrawText( aTempRect, aStr, DrawTextFlags::Left | DrawTextFlags::Top | DrawTextFlags::Clip | DrawTextFlags::EndEllipsis );
     360           0 :             rRenderContext.DrawOutDev(aTextRect.TopLeft(), aVirDevSize, Point(), aVirDevSize, *mpImplData->mpVirDev);
     361             :         }
     362             :         else
     363             :         {
     364           0 :             rRenderContext.DrawText(aTextRect, aStr, DrawTextFlags::Left | DrawTextFlags::Top | DrawTextFlags::Clip | DrawTextFlags::EndEllipsis);
     365           0 :         }
     366             :     }
     367           0 : }
     368             : 
     369       46991 : void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen, sal_uInt16 nPos, bool bDrawText, bool bDrawFrame)
     370             : {
     371       46991 :     Rectangle aRect = ImplGetItemRectPos(nPos);
     372             : 
     373       46991 :     if (aRect.IsEmpty())
     374       46991 :         return;
     375             : 
     376             :     // compute output region
     377       46991 :     ImplStatusItem* pItem = (*mpItemList)[nPos];
     378       46991 :     long nW = mpImplData->mnItemBorderWidth + 1;
     379       93982 :     Rectangle aTextRect(aRect.Left() + nW, aRect.Top() + nW,
     380      140973 :                         aRect.Right() - nW, aRect.Bottom() - nW);
     381             : 
     382       46991 :     Size aTextRectSize(aTextRect.GetSize());
     383             : 
     384       46991 :     if (bOffScreen)
     385             :     {
     386       44531 :         mpImplData->mpVirDev->SetOutputSizePixel(aTextRectSize);
     387             :     }
     388             :     else
     389             :     {
     390        2460 :         vcl::Region aRegion(aTextRect);
     391        2460 :         rRenderContext.SetClipRegion(aRegion);
     392             :     }
     393             : 
     394             :     // print text
     395       46991 :     if (bDrawText)
     396             :     {
     397       46991 :         Size aTextSize(rRenderContext.GetTextWidth(pItem->maText), rRenderContext.GetTextHeight());
     398       46991 :         Point aTextPos = ImplGetItemTextPos(aTextRectSize, aTextSize, pItem->mnBits);
     399       46991 :         if (bOffScreen)
     400             :         {
     401       44531 :             mpImplData->mpVirDev->DrawText(aTextPos, pItem->maText);
     402             :         }
     403             :         else
     404             :         {
     405        2460 :             aTextPos.X() += aTextRect.Left();
     406        2460 :             aTextPos.Y() += aTextRect.Top();
     407        2460 :             rRenderContext.DrawText(aTextPos, pItem->maText);
     408             :         }
     409             :     }
     410             : 
     411             :     // call DrawItem if necessary
     412       46991 :     if (pItem->mnBits & SIB_USERDRAW)
     413             :     {
     414       23628 :         if (bOffScreen)
     415             :         {
     416       22398 :             mbInUserDraw = true;
     417       22398 :             mpImplData->mpVirDev->EnableRTL( IsRTLEnabled() );
     418       22398 :             UserDrawEvent aODEvt(mpImplData->mpVirDev, Rectangle(Point(), aTextRectSize), pItem->mnId);
     419       22398 :             UserDraw(aODEvt);
     420       22398 :             mpImplData->mpVirDev->EnableRTL(false);
     421       22398 :             mbInUserDraw = false;
     422             :         }
     423             :         else
     424             :         {
     425        1230 :             UserDrawEvent aODEvt(&rRenderContext, aTextRect, pItem->mnId);
     426        1230 :             UserDraw(aODEvt);
     427             :         }
     428             :     }
     429             : 
     430       46991 :     if (bOffScreen)
     431       44531 :         rRenderContext.DrawOutDev(aTextRect.TopLeft(), aTextRectSize, Point(), aTextRectSize, *mpImplData->mpVirDev);
     432             :     else
     433        2460 :         rRenderContext.SetClipRegion();
     434             : 
     435             :     // show frame
     436       46991 :     if (bDrawFrame)
     437             :     {
     438       46991 :         if (mpImplData->mbDrawItemFrames)
     439             :         {
     440           0 :             if (!(pItem->mnBits & SIB_FLAT))
     441             :             {
     442             :                 DrawFrameStyle nStyle;
     443             : 
     444           0 :                 if (pItem->mnBits & SIB_IN)
     445           0 :                     nStyle = DrawFrameStyle::In;
     446             :                 else
     447           0 :                     nStyle = DrawFrameStyle::Out;
     448             : 
     449           0 :                 DecorationView aDecoView(&rRenderContext);
     450           0 :                 aDecoView.DrawFrame(aRect, nStyle);
     451             :             }
     452             :         }
     453       46991 :         else if (nPos != ImplGetFirstVisiblePos())
     454             :         {
     455             :             // draw separator
     456       42856 :             Point aFrom(aRect.TopLeft());
     457       42856 :             aFrom.X() -= 4;
     458       42856 :             aFrom.Y()++;
     459       42856 :             Point aTo(aRect.BottomLeft());
     460       42856 :             aTo.X() -= 4;
     461       42856 :             aTo.Y()--;
     462             : 
     463       42856 :             DecorationView aDecoView(&rRenderContext);
     464       42856 :             aDecoView.DrawSeparator(aFrom, aTo);
     465             :         }
     466             :     }
     467             : 
     468       46991 :     if (!rRenderContext.ImplIsRecordLayout())
     469       44531 :         CallEventListeners(VCLEVENT_STATUSBAR_DRAWITEM, reinterpret_cast<void*>(pItem->mnId));
     470             : }
     471             : 
     472        3498 : void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
     473             :                   long nOffset, long nPrgsWidth, long nPrgsHeight,
     474             :                   sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
     475             :                   const Rectangle& rFramePosSize)
     476             : {
     477        3498 :     if (rRenderContext.IsNativeControlSupported(CTRL_PROGRESS, PART_ENTIRE_CONTROL))
     478             :     {
     479           0 :         bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
     480             : 
     481           0 :         long nFullWidth = (nPrgsWidth + nOffset) * (10000 / nPercentCount);
     482           0 :         long nPerc = (nPercent2 > 10000) ? 10000 : nPercent2;
     483           0 :         ImplControlValue aValue(nFullWidth * long(nPerc) / 10000);
     484           0 :         Rectangle aDrawRect(rPos, Size(nFullWidth, nPrgsHeight));
     485           0 :         Rectangle aControlRegion(aDrawRect);
     486             : 
     487           0 :         if(bNeedErase)
     488             :         {
     489           0 :             vcl::Window* pEraseWindow = pWindow;
     490           0 :             while (pEraseWindow->IsPaintTransparent() && !pEraseWindow->ImplGetWindowImpl()->mbFrame)
     491             :             {
     492           0 :                 pEraseWindow = pEraseWindow->ImplGetWindowImpl()->mpParent;
     493             :             }
     494             : 
     495           0 :             if (pEraseWindow == pWindow)
     496             :             {
     497             :                 // restore background of pWindow
     498           0 :                 rRenderContext.Erase(rFramePosSize);
     499             :             }
     500             :             else
     501             :             {
     502             :                 // restore transparent background
     503           0 :                 Point aTL(pWindow->OutputToAbsoluteScreenPixel(rFramePosSize.TopLeft()));
     504           0 :                 aTL = pEraseWindow->AbsoluteScreenToOutputPixel(aTL);
     505           0 :                 Rectangle aRect(aTL, rFramePosSize.GetSize());
     506             :                 pEraseWindow->Invalidate(aRect, InvalidateFlags::NoChildren     |
     507           0 :                                                 InvalidateFlags::NoClipChildren |
     508           0 :                                                 InvalidateFlags::Transparent);
     509           0 :                 pEraseWindow->Update();
     510             :             }
     511           0 :             rRenderContext.Push(PushFlags::CLIPREGION);
     512           0 :             rRenderContext.IntersectClipRegion(rFramePosSize);
     513             :         }
     514             : 
     515             :         bool bNativeOK = rRenderContext.DrawNativeControl(CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
     516           0 :                                                           ControlState::ENABLED, aValue, OUString());
     517           0 :         if (bNeedErase)
     518           0 :             rRenderContext.Pop();
     519           0 :         if (bNativeOK)
     520        3498 :             return;
     521             :     }
     522             : 
     523             :     // precompute values
     524        3498 :     sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
     525        3498 :     sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
     526             : 
     527        3498 :     if (nPerc1 > nPerc2)
     528             :     {
     529             :         // support progress that can also decrease
     530             : 
     531             :         // compute rectangle
     532           0 :         long nDX = nPrgsWidth + nOffset;
     533           0 :         long nLeft = rPos.X() + ((nPerc1 - 1) * nDX);
     534           0 :         Rectangle aRect(nLeft, rPos.Y(), nLeft + nPrgsWidth, rPos.Y() + nPrgsHeight);
     535             : 
     536           0 :         do
     537             :         {
     538           0 :             rRenderContext.Erase(aRect);
     539           0 :             aRect.Left()  -= nDX;
     540           0 :             aRect.Right() -= nDX;
     541           0 :             nPerc1--;
     542             :         }
     543             :         while (nPerc1 > nPerc2);
     544             :     }
     545        3498 :     else if (nPerc1 < nPerc2)
     546             :     {
     547             :         // draw Percent rectangle
     548             :         // if Percent2 greater than 100%, adapt values
     549        2406 :         if (nPercent2 > 10000)
     550             :         {
     551           0 :             nPerc2 = 10000 / nPercentCount;
     552           0 :             if (nPerc1 >= nPerc2)
     553           0 :                 nPerc1 = nPerc2 - 1;
     554             :         }
     555             : 
     556             :         // compute rectangle
     557        2406 :         long nDX = nPrgsWidth + nOffset;
     558        2406 :         long nLeft = rPos.X() + (nPerc1 * nDX);
     559        2406 :         Rectangle aRect(nLeft, rPos.Y(), nLeft + nPrgsWidth, rPos.Y() + nPrgsHeight);
     560             : 
     561       58592 :         do
     562             :         {
     563       58592 :             rRenderContext.DrawRect(aRect);
     564       58592 :             aRect.Left()  += nDX;
     565       58592 :             aRect.Right() += nDX;
     566       58592 :             nPerc1++;
     567             :         }
     568             :         while (nPerc1 < nPerc2);
     569             : 
     570             :         // if greater than 100%, set rectangle to blink
     571        2406 :         if (nPercent2 > 10000)
     572             :         {
     573             :             // define on/off status
     574           0 :             if (((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01))
     575             :             {
     576           0 :                 aRect.Left()  -= nDX;
     577           0 :                 aRect.Right() -= nDX;
     578           0 :                 rRenderContext.Erase(aRect);
     579             :             }
     580             :         }
     581             :     }
     582             : }
     583             : 
     584        3498 : void StatusBar::ImplDrawProgress(vcl::RenderContext& rRenderContext, bool bPaint,
     585             :                                  sal_uInt16 nPercent1, sal_uInt16 nPercent2)
     586             : {
     587        3498 :     bool bNative = rRenderContext.IsNativeControlSupported(CTRL_PROGRESS, PART_ENTIRE_CONTROL);
     588             :     // bPaint: draw text also, else only update progress
     589        3498 :     if (bPaint)
     590             :     {
     591        3498 :         rRenderContext.DrawText(maPrgsTxtPos, maPrgsTxt);
     592        3498 :         if (!bNative)
     593             :         {
     594        3498 :             DecorationView aDecoView(&rRenderContext);
     595        3498 :             aDecoView.DrawFrame(maPrgsFrameRect, DrawFrameStyle::In);
     596             :         }
     597             :     }
     598             : 
     599        3498 :     Point aPos(maPrgsFrameRect.Left() + STATUSBAR_PRGS_OFFSET,
     600        6996 :                maPrgsFrameRect.Top()  + STATUSBAR_PRGS_OFFSET);
     601        3498 :     long nPrgsHeight = mnPrgsSize;
     602        3498 :     if (bNative)
     603             :     {
     604           0 :         aPos = maPrgsFrameRect.TopLeft();
     605           0 :         nPrgsHeight = maPrgsFrameRect.GetHeight();
     606             :     }
     607             :     DrawProgress(this, rRenderContext, aPos, mnPrgsSize / 2, mnPrgsSize, nPrgsHeight,
     608        3498 :                  nPercent1 * 100, nPercent2 * 100, mnPercentCount, maPrgsFrameRect);
     609        3498 : }
     610             : 
     611        3812 : void StatusBar::ImplCalcProgressRect()
     612             : {
     613             :     // calculate text size
     614        3812 :     Size aPrgsTxtSize( GetTextWidth( maPrgsTxt ), GetTextHeight() );
     615        3812 :     maPrgsTxtPos.X()    = STATUSBAR_OFFSET_X+1;
     616             : 
     617             :     // calculate progress frame
     618        3812 :     maPrgsFrameRect.Left()      = maPrgsTxtPos.X()+aPrgsTxtSize.Width()+STATUSBAR_OFFSET;
     619        3812 :     maPrgsFrameRect.Top()       = mnItemY;
     620        3812 :     maPrgsFrameRect.Bottom()    = mnCalcHeight - STATUSBAR_OFFSET_Y;
     621             : 
     622             :     // calculate size of progress rects
     623        3812 :     mnPrgsSize = maPrgsFrameRect.Bottom()-maPrgsFrameRect.Top()-(STATUSBAR_PRGS_OFFSET*2);
     624        3812 :     sal_uInt16 nMaxPercent = STATUSBAR_PRGS_COUNT;
     625             : 
     626        3812 :     long nMaxWidth = mnDX-STATUSBAR_OFFSET-1;
     627             : 
     628             :     // make smaller if there are too many rects
     629      322011 :     while ( maPrgsFrameRect.Left()+ImplCalcProgessWidth( nMaxPercent, mnPrgsSize ) > nMaxWidth )
     630             :     {
     631      317098 :         nMaxPercent--;
     632      317098 :         if ( nMaxPercent <= STATUSBAR_PRGS_MIN )
     633        2711 :             break;
     634             :     }
     635        3812 :     maPrgsFrameRect.Right() = maPrgsFrameRect.Left() + ImplCalcProgessWidth( nMaxPercent, mnPrgsSize );
     636             : 
     637             :     // save the divisor for later
     638        3812 :     mnPercentCount = 10000 / nMaxPercent;
     639        3812 :     bool bNativeOK = false;
     640        3812 :     if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
     641             :     {
     642           0 :         ImplControlValue aValue;
     643           0 :         Rectangle aControlRegion( Rectangle( (const Point&)Point(), maPrgsFrameRect.GetSize() ) );
     644           0 :         Rectangle aNativeControlRegion, aNativeContentRegion;
     645           0 :         if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
     646             :                                                  ControlState::ENABLED, aValue, OUString(),
     647           0 :                                                  aNativeControlRegion, aNativeContentRegion ) ) )
     648             :         {
     649           0 :             long nProgressHeight = aNativeControlRegion.GetHeight();
     650           0 :             if( nProgressHeight > maPrgsFrameRect.GetHeight() )
     651             :             {
     652           0 :                 long nDelta = nProgressHeight - maPrgsFrameRect.GetHeight();
     653           0 :                 maPrgsFrameRect.Top() -= (nDelta - nDelta/2);
     654           0 :                 maPrgsFrameRect.Bottom() += nDelta/2;
     655             :             }
     656           0 :             maPrgsTxtPos.Y() = maPrgsFrameRect.Top() + (nProgressHeight - GetTextHeight())/2;
     657           0 :         }
     658             :     }
     659        3812 :     if( ! bNativeOK )
     660        3812 :         maPrgsTxtPos.Y()    = mnTextY;
     661        3812 : }
     662             : 
     663           0 : void StatusBar::MouseButtonDown( const MouseEvent& rMEvt )
     664             : {
     665             :     // trigger toolbox only for left mouse button
     666           0 :     if ( rMEvt.IsLeft() )
     667             :     {
     668           0 :         if ( mbVisibleItems )
     669             :         {
     670           0 :             Point  aMousePos = rMEvt.GetPosPixel();
     671             : 
     672             :             // search for clicked item
     673           0 :             for ( size_t i = 0; i < mpItemList->size(); ++i )
     674             :             {
     675           0 :                 ImplStatusItem* pItem = (*mpItemList)[ i ];
     676             :                 // check item for being clicked
     677           0 :                 if ( ImplGetItemRectPos( sal_uInt16(i) ).IsInside( aMousePos ) )
     678             :                 {
     679           0 :                     mnCurItemId = pItem->mnId;
     680           0 :                     if ( rMEvt.GetClicks() == 2 )
     681           0 :                         DoubleClick();
     682             :                     else
     683           0 :                         Click();
     684           0 :                     mnCurItemId = 0;
     685             : 
     686             :                     // Item found
     687           0 :                     return;
     688             :                 }
     689             :             }
     690             :         }
     691             : 
     692             :         // if there's no item, trigger Click or DoubleClick
     693           0 :         if ( rMEvt.GetClicks() == 2 )
     694           0 :             DoubleClick();
     695             :         else
     696           0 :             Click();
     697             :     }
     698             : }
     699             : 
     700       15142 : void StatusBar::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
     701             : {
     702       15142 :     if (mbFormat)
     703        5274 :         ImplFormat();
     704             : 
     705       15142 :     sal_uInt16 nItemCount = sal_uInt16( mpItemList->size() );
     706             : 
     707       15142 :     if (mbProgressMode)
     708             :     {
     709        3498 :         rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
     710             : 
     711        3498 :         const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     712        3498 :         Color aProgressColor = rStyleSettings.GetHighlightColor();
     713        3498 :         if (aProgressColor == rStyleSettings.GetFaceColor())
     714           0 :             aProgressColor = rStyleSettings.GetDarkShadowColor();
     715        3498 :         rRenderContext.SetLineColor();
     716        3498 :         rRenderContext.SetFillColor(aProgressColor);
     717             : 
     718        3498 :         ImplDrawProgress(rRenderContext, true, 0, mnPercent);
     719             : 
     720        3498 :         rRenderContext.Pop();
     721             :     }
     722             :     else
     723             :     {
     724             :         // draw text
     725       11644 :         if (!mbVisibleItems || (GetStyle() & WB_RIGHT))
     726           0 :             ImplDrawText(rRenderContext, false, 0);
     727             : 
     728             :         // draw items
     729       11644 :         if (mbVisibleItems)
     730             :         {
     731             :             // Do offscreen only when we are not recording layout..
     732       11644 :             bool bOffscreen = !rRenderContext.ImplIsRecordLayout();
     733             : 
     734       58635 :             for (sal_uInt16 i = 0; i < nItemCount; i++)
     735             :             {
     736       46991 :                 ImplDrawItem(rRenderContext, bOffscreen, i, true, true);
     737             :             }
     738             :         }
     739             :     }
     740             : 
     741             :     // draw line at the top of the status bar (to visually distinguish it from
     742             :     // shell / docking area)
     743       15142 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     744       15142 :     rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
     745       15142 :     rRenderContext.DrawLine(Point(0, 0), Point(mnDX-1, 0));
     746       15142 : }
     747             : 
     748        9041 : void StatusBar::Move()
     749             : {
     750        9041 :     Window::Move();
     751        9041 : }
     752             : 
     753       11404 : void StatusBar::Resize()
     754             : {
     755             :     // save width and height
     756       11404 :     Size aSize = GetOutputSizePixel();
     757       11404 :     mnDX = aSize.Width() - ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset;
     758       11404 :     mnDY = aSize.Height();
     759       11404 :     mnCalcHeight = mnDY;
     760             : 
     761       11404 :     mnItemY = STATUSBAR_OFFSET_Y;
     762       11404 :     mnTextY = (mnCalcHeight-GetTextHeight())/2;
     763             : 
     764             :     // provoke re-formatting
     765       11404 :     mbFormat = true;
     766             : 
     767       11404 :     if ( mbProgressMode )
     768         315 :         ImplCalcProgressRect();
     769             : 
     770       11404 :     Invalidate();
     771       11404 : }
     772             : 
     773           0 : void StatusBar::RequestHelp( const HelpEvent& rHEvt )
     774             : {
     775             :     // no keyboard help in status bar
     776           0 :     if( rHEvt.KeyboardActivated() )
     777           0 :         return;
     778             : 
     779           0 :     sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
     780             : 
     781           0 :     if ( nItemId )
     782             :     {
     783           0 :         Rectangle aItemRect = GetItemRect( nItemId );
     784           0 :         Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
     785           0 :         aItemRect.Left()   = aPt.X();
     786           0 :         aItemRect.Top()    = aPt.Y();
     787           0 :         aPt = OutputToScreenPixel( aItemRect.BottomRight() );
     788           0 :         aItemRect.Right()  = aPt.X();
     789           0 :         aItemRect.Bottom() = aPt.Y();
     790             : 
     791           0 :         if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
     792             :         {
     793           0 :             OUString aStr = GetHelpText( nItemId );
     794           0 :             Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
     795           0 :             return;
     796             :         }
     797           0 :         else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
     798             :         {
     799           0 :             OUString aStr(GetQuickHelpText(nItemId));
     800             :             // show quickhelp if available
     801           0 :             if (!aStr.isEmpty())
     802             :             {
     803           0 :                 Help::ShowQuickHelp( this, aItemRect, aStr );
     804           0 :                 return;
     805             :             }
     806           0 :             aStr = GetItemText( nItemId );
     807             :             // show a quick help if item text doesn't fit
     808           0 :             if ( GetTextWidth( aStr ) > aItemRect.GetWidth() )
     809             :             {
     810           0 :                 Help::ShowQuickHelp( this, aItemRect, aStr );
     811           0 :                 return;
     812           0 :             }
     813             :         }
     814           0 :         else if ( rHEvt.GetMode() & HelpEventMode::EXTENDED )
     815             :         {
     816           0 :             OUString aCommand = GetItemCommand( nItemId );
     817           0 :             OString aHelpId( GetHelpId( nItemId ) );
     818             : 
     819           0 :             if ( !aCommand.isEmpty() || !aHelpId.isEmpty() )
     820             :             {
     821             :                 // show help text if there is one
     822           0 :                 Help* pHelp = Application::GetHelp();
     823           0 :                 if ( pHelp )
     824             :                 {
     825           0 :                     if ( !aCommand.isEmpty() )
     826           0 :                         pHelp->Start( aCommand, this );
     827           0 :                     else if ( !aHelpId.isEmpty() )
     828           0 :                         pHelp->Start( OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this );
     829             :                 }
     830           0 :                 return;
     831           0 :             }
     832             :         }
     833             :     }
     834             : 
     835           0 :     Window::RequestHelp( rHEvt );
     836             : }
     837             : 
     838        7881 : void StatusBar::StateChanged( StateChangedType nType )
     839             : {
     840        7881 :     Window::StateChanged( nType );
     841             : 
     842        7881 :     if ( nType == StateChangedType::InitShow )
     843        2365 :         ImplFormat();
     844        5516 :     else if ( nType == StateChangedType::UpdateMode )
     845         784 :         Invalidate();
     846        4732 :     else if ( (nType == StateChangedType::Zoom) ||
     847             :               (nType == StateChangedType::ControlFont) )
     848             :     {
     849           0 :         mbFormat = true;
     850           0 :         ImplInitSettings();
     851           0 :         Invalidate();
     852             :     }
     853        4732 :     else if ( nType == StateChangedType::ControlForeground )
     854             :     {
     855           0 :         ImplInitSettings();
     856           0 :         Invalidate();
     857             :     }
     858        4732 :     else if ( nType == StateChangedType::ControlBackground )
     859             :     {
     860           0 :         ImplInitSettings();
     861           0 :         Invalidate();
     862             :     }
     863        7881 : }
     864             : 
     865          69 : void StatusBar::DataChanged( const DataChangedEvent& rDCEvt )
     866             : {
     867          69 :     Window::DataChanged( rDCEvt );
     868             : 
     869         207 :     if (  (rDCEvt.GetType() == DataChangedEventType::DISPLAY         )
     870          69 :        || (rDCEvt.GetType() == DataChangedEventType::FONTS           )
     871          69 :        || (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION)
     872         273 :        || (  (rDCEvt.GetType() == DataChangedEventType::SETTINGS)
     873         207 :           && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
     874             :           )
     875             :        )
     876             :     {
     877          66 :         mbFormat = true;
     878          66 :         ImplInitSettings();
     879          66 :         long nFudge = GetTextHeight() / 4;
     880          66 :         for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
     881             :         {
     882           0 :             ImplStatusItem* pItem = (*mpItemList)[ i ];
     883           0 :             long nWidth = GetTextWidth( pItem->maText ) + nFudge;
     884           0 :             if( nWidth > pItem->mnWidth + STATUSBAR_OFFSET )
     885           0 :                 pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
     886             :         }
     887          66 :         Size aSize = GetSizePixel();
     888             :         // do not disturb current width, since
     889             :         // CalcWindowSizePixel calculates a minimum width
     890          66 :         aSize.Height() = CalcWindowSizePixel().Height();
     891          66 :         SetSizePixel( aSize );
     892          66 :         Invalidate();
     893             :     }
     894          69 : }
     895             : 
     896           0 : void StatusBar::Click()
     897             : {
     898           0 :     CallEventListeners( VCLEVENT_STATUSBAR_CLICK );
     899           0 :     maClickHdl.Call( this );
     900           0 : }
     901             : 
     902           0 : void StatusBar::DoubleClick()
     903             : {
     904           0 :     CallEventListeners( VCLEVENT_STATUSBAR_DOUBLECLICK );
     905           0 :     maDoubleClickHdl.Call( this );
     906           0 : }
     907             : 
     908           0 : void StatusBar::UserDraw( const UserDrawEvent& )
     909             : {
     910           0 : }
     911             : 
     912        6458 : void StatusBar::InsertItem( sal_uInt16 nItemId, sal_uLong nWidth,
     913             :                             StatusBarItemBits nBits,
     914             :                             long nOffset, sal_uInt16 nPos )
     915             : {
     916             :     DBG_ASSERT( nItemId, "StatusBar::InsertItem(): ItemId == 0" );
     917             :     DBG_ASSERT( GetItemPos( nItemId ) == STATUSBAR_ITEM_NOTFOUND,
     918             :                 "StatusBar::InsertItem(): ItemId already exists" );
     919             : 
     920             :     // default: IN and CENTER
     921        6458 :     if ( !(nBits & (SIB_IN | SIB_OUT | SIB_FLAT)) )
     922           0 :         nBits |= SIB_IN;
     923        6458 :     if ( !(nBits & (SIB_LEFT | SIB_RIGHT | SIB_CENTER)) )
     924           0 :         nBits |= SIB_CENTER;
     925             : 
     926             :     // create item
     927        6458 :     if (mbAdjustHiDPI && GetDPIScaleFactor() != 1)
     928             :     {
     929           0 :         nWidth *= GetDPIScaleFactor();
     930             :     }
     931        6458 :     long nFudge = GetTextHeight()/4;
     932        6458 :     ImplStatusItem* pItem   = new ImplStatusItem;
     933        6458 :     pItem->mnId             = nItemId;
     934        6458 :     pItem->mnBits           = nBits;
     935        6458 :     pItem->mnWidth          = (long)nWidth+nFudge+STATUSBAR_OFFSET;
     936        6458 :     pItem->mnOffset         = nOffset;
     937        6458 :     pItem->mpUserData       = 0;
     938        6458 :     pItem->mbVisible        = true;
     939             : 
     940             :     // add item to list
     941        6458 :     if ( nPos < mpItemList->size() ) {
     942           0 :         mpItemList->insert( mpItemList->begin() + nPos, pItem );
     943             :     } else {
     944        6458 :         mpItemList->push_back( pItem );
     945             :     }
     946             : 
     947        6458 :     mbFormat = true;
     948        6458 :     if ( ImplIsItemUpdate() )
     949           0 :         Invalidate();
     950             : 
     951        6458 :     CallEventListeners( VCLEVENT_STATUSBAR_ITEMADDED, reinterpret_cast<void*>(nItemId) );
     952        6458 : }
     953             : 
     954           0 : void StatusBar::RemoveItem( sal_uInt16 nItemId )
     955             : {
     956           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
     957           0 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
     958             :     {
     959           0 :         delete (*mpItemList)[ nPos ];
     960           0 :         mpItemList->erase( mpItemList->begin() + nPos );
     961             : 
     962           0 :         mbFormat = true;
     963           0 :         if ( ImplIsItemUpdate() )
     964           0 :             Invalidate();
     965             : 
     966           0 :         CallEventListeners( VCLEVENT_STATUSBAR_ITEMREMOVED, reinterpret_cast<void*>(nItemId) );
     967             :     }
     968           0 : }
     969             : 
     970           0 : void StatusBar::ShowItem( sal_uInt16 nItemId )
     971             : {
     972           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
     973             : 
     974           0 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
     975             :     {
     976           0 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
     977           0 :         if ( !pItem->mbVisible )
     978             :         {
     979           0 :             pItem->mbVisible = true;
     980             : 
     981           0 :             mbFormat = true;
     982           0 :             if ( ImplIsItemUpdate() )
     983           0 :                 Invalidate();
     984             : 
     985           0 :             CallEventListeners( VCLEVENT_STATUSBAR_SHOWITEM, reinterpret_cast<void*>(nItemId) );
     986             :         }
     987             :     }
     988           0 : }
     989             : 
     990           0 : void StatusBar::HideItem( sal_uInt16 nItemId )
     991             : {
     992           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
     993             : 
     994           0 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
     995             :     {
     996           0 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
     997           0 :         if ( pItem->mbVisible )
     998             :         {
     999           0 :             pItem->mbVisible = false;
    1000             : 
    1001           0 :             mbFormat = true;
    1002           0 :             if ( ImplIsItemUpdate() )
    1003           0 :                 Invalidate();
    1004             : 
    1005           0 :             CallEventListeners( VCLEVENT_STATUSBAR_HIDEITEM, reinterpret_cast<void*>(nItemId) );
    1006             :         }
    1007             :     }
    1008           0 : }
    1009             : 
    1010           2 : bool StatusBar::IsItemVisible( sal_uInt16 nItemId ) const
    1011             : {
    1012           2 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1013             : 
    1014           2 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1015           2 :         return (*mpItemList)[ nPos ]->mbVisible;
    1016             :     else
    1017           0 :         return false;
    1018             : }
    1019             : 
    1020         606 : void StatusBar::Clear()
    1021             : {
    1022             :     // delete all items
    1023         606 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
    1024           0 :         delete (*mpItemList)[ i ];
    1025             :     }
    1026         606 :     mpItemList->clear();
    1027             : 
    1028         606 :     mbFormat = true;
    1029         606 :     if ( ImplIsItemUpdate() )
    1030           0 :         Invalidate();
    1031             : 
    1032         606 :     CallEventListeners( VCLEVENT_STATUSBAR_ALLITEMSREMOVED );
    1033         606 : }
    1034             : 
    1035       16730 : sal_uInt16 StatusBar::GetItemCount() const
    1036             : {
    1037       16730 :     return (sal_uInt16)mpItemList->size();
    1038             : }
    1039             : 
    1040       12918 : sal_uInt16 StatusBar::GetItemId( sal_uInt16 nPos ) const
    1041             : {
    1042       12918 :     if ( nPos < mpItemList->size() )
    1043       12918 :         return (*mpItemList)[ nPos ]->mnId;
    1044           0 :     return 0;
    1045             : }
    1046             : 
    1047       95060 : sal_uInt16 StatusBar::GetItemPos( sal_uInt16 nItemId ) const
    1048             : {
    1049      686979 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
    1050      680781 :         if ( (*mpItemList)[ i ]->mnId == nItemId ) {
    1051       88862 :             return sal_uInt16( i );
    1052             :         }
    1053             :     }
    1054             : 
    1055        6198 :     return STATUSBAR_ITEM_NOTFOUND;
    1056             : }
    1057             : 
    1058           0 : sal_uInt16 StatusBar::GetItemId( const Point& rPos ) const
    1059             : {
    1060           0 :     if ( AreItemsVisible() && !mbFormat )
    1061             :     {
    1062           0 :         sal_uInt16 nItemCount = GetItemCount();
    1063             :         sal_uInt16 nPos;
    1064           0 :         for ( nPos = 0; nPos < nItemCount; nPos++ )
    1065             :         {
    1066             :             // get rectangle
    1067           0 :             Rectangle aRect = ImplGetItemRectPos( nPos );
    1068           0 :             if ( aRect.IsInside( rPos ) )
    1069           0 :                 return (*mpItemList)[ nPos ]->mnId;
    1070             :         }
    1071             :     }
    1072             : 
    1073           0 :     return 0;
    1074             : }
    1075             : 
    1076       17047 : Rectangle StatusBar::GetItemRect( sal_uInt16 nItemId ) const
    1077             : {
    1078       17047 :     Rectangle aRect;
    1079             : 
    1080       17047 :     if ( AreItemsVisible() && !mbFormat )
    1081             :     {
    1082       17024 :         sal_uInt16 nPos = GetItemPos( nItemId );
    1083       17024 :         if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1084             :         {
    1085             :             // get rectangle and subtract frame
    1086       17024 :             aRect = ImplGetItemRectPos( nPos );
    1087       17024 :             long nW = mpImplData->mnItemBorderWidth+1;
    1088       17024 :             aRect.Top() += nW-1;
    1089       17024 :             aRect.Bottom() -= nW-1;
    1090       17024 :             aRect.Left() += nW;
    1091       17024 :             aRect.Right() -= nW;
    1092       17024 :             return aRect;
    1093             :         }
    1094             :     }
    1095             : 
    1096          23 :     return aRect;
    1097             : }
    1098             : 
    1099        4063 : Point StatusBar::GetItemTextPos( sal_uInt16 nItemId ) const
    1100             : {
    1101        4063 :     if ( !mbFormat )
    1102             :     {
    1103        4063 :         sal_uInt16 nPos = GetItemPos( nItemId );
    1104        4063 :         if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1105             :         {
    1106             :             // get rectangle
    1107        4063 :             ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1108        4063 :             Rectangle aRect = ImplGetItemRectPos( nPos );
    1109        4063 :             long nW = mpImplData->mnItemBorderWidth + 1;
    1110        8126 :             Rectangle           aTextRect( aRect.Left()+nW, aRect.Top()+nW,
    1111       12189 :                                            aRect.Right()-nW, aRect.Bottom()-nW );
    1112             :             Point aPos = ImplGetItemTextPos( aTextRect.GetSize(),
    1113             :                                              Size( GetTextWidth( pItem->maText ), GetTextHeight() ),
    1114        4063 :                                              pItem->mnBits );
    1115        4063 :             if ( !mbInUserDraw )
    1116             :             {
    1117         205 :                 aPos.X() += aTextRect.Left();
    1118         205 :                 aPos.Y() += aTextRect.Top();
    1119             :             }
    1120        4063 :             return aPos;
    1121             :         }
    1122             :     }
    1123             : 
    1124           0 :     return Point();
    1125             : }
    1126             : 
    1127           0 : sal_uLong StatusBar::GetItemWidth( sal_uInt16 nItemId ) const
    1128             : {
    1129           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1130             : 
    1131           0 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1132           0 :         return (*mpItemList)[ nPos ]->mnWidth;
    1133             : 
    1134           0 :     return 0;
    1135             : }
    1136             : 
    1137        6458 : StatusBarItemBits StatusBar::GetItemBits( sal_uInt16 nItemId ) const
    1138             : {
    1139        6458 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1140             : 
    1141        6458 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1142        6458 :         return (*mpItemList)[ nPos ]->mnBits;
    1143             : 
    1144           0 :     return 0;
    1145             : }
    1146             : 
    1147           0 : long StatusBar::GetItemOffset( sal_uInt16 nItemId ) const
    1148             : {
    1149           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1150             : 
    1151           0 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1152           0 :         return (*mpItemList)[ nPos ]->mnOffset;
    1153             : 
    1154           0 :     return 0;
    1155             : }
    1156             : 
    1157       12204 : void StatusBar::SetItemText( sal_uInt16 nItemId, const OUString& rText )
    1158             : {
    1159       12204 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1160             : 
    1161       12204 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1162             :     {
    1163       12097 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1164             : 
    1165       12097 :         if ( pItem->maText != rText )
    1166             :         {
    1167        3562 :             pItem->maText = rText;
    1168             : 
    1169             :             // adjust item width - see also DataChanged()
    1170        3562 :             long nFudge = GetTextHeight()/4;
    1171        3562 :             long nWidth = GetTextWidth( pItem->maText ) + nFudge;
    1172        6332 :             if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) ||
    1173        4762 :                 ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth  ))
    1174             :             {
    1175        2752 :                 pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
    1176        2752 :                 ImplFormat();
    1177        2752 :                 Invalidate();
    1178             :             }
    1179             : 
    1180             :             // re-draw item if StatusBar is visible and UpdateMode active
    1181        3562 :             if ( pItem->mbVisible && !mbFormat && ImplIsItemUpdate() )
    1182             :             {
    1183         628 :                 Update();
    1184         628 :                 Rectangle aRect = ImplGetItemRectPos(nPos);
    1185         628 :                 Invalidate(aRect);
    1186         628 :                 Flush();
    1187             :             }
    1188             :         }
    1189             :     }
    1190       12204 : }
    1191             : 
    1192           0 : const OUString& StatusBar::GetItemText( sal_uInt16 nItemId ) const
    1193             : {
    1194           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1195             : 
    1196             :     assert( nPos != STATUSBAR_ITEM_NOTFOUND );
    1197             : 
    1198           0 :     return (*mpItemList)[ nPos ]->maText;
    1199             : }
    1200             : 
    1201        6458 : void StatusBar::SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand )
    1202             : {
    1203        6458 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1204             : 
    1205        6458 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1206             :     {
    1207        6458 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1208             : 
    1209        6458 :         if ( pItem->maCommand != rCommand )
    1210        6458 :             pItem->maCommand = rCommand;
    1211             :     }
    1212        6458 : }
    1213             : 
    1214        6458 : const OUString StatusBar::GetItemCommand( sal_uInt16 nItemId )
    1215             : {
    1216        6458 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1217             : 
    1218        6458 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1219        6458 :         return (*mpItemList)[ nPos ]->maCommand;
    1220             : 
    1221           0 :     return OUString();
    1222             : }
    1223             : 
    1224        6470 : void StatusBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
    1225             : {
    1226        6470 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1227             : 
    1228        6470 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1229             :     {
    1230        6470 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1231        6470 :         pItem->mpUserData = pNewData;
    1232             : 
    1233             :         // call Draw-Item if it's a User-Item
    1234       25880 :         if ( (pItem->mnBits & SIB_USERDRAW) && pItem->mbVisible &&
    1235       19063 :              !mbFormat && ImplIsItemUpdate() )
    1236             :         {
    1237        2504 :             Update();
    1238        2504 :             Rectangle aRect = ImplGetItemRectPos(nPos);
    1239        2504 :             Invalidate(aRect, InvalidateFlags::NoErase);
    1240        2504 :             Flush();
    1241             :         }
    1242             :     }
    1243        6470 : }
    1244             : 
    1245       12916 : void* StatusBar::GetItemData( sal_uInt16 nItemId ) const
    1246             : {
    1247       12916 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1248             : 
    1249       12916 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1250       12916 :         return (*mpItemList)[ nPos ]->mpUserData;
    1251             : 
    1252           0 :     return NULL;
    1253             : }
    1254             : 
    1255           0 : void StatusBar::RedrawItem(sal_uInt16 nItemId)
    1256             : {
    1257           0 :     if ( mbFormat )
    1258           0 :         return;
    1259             : 
    1260           0 :     sal_uInt16 nPos = GetItemPos(nItemId);
    1261           0 :     if ( nPos == STATUSBAR_ITEM_NOTFOUND )
    1262           0 :         return;
    1263             : 
    1264           0 :     ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1265           0 :     if (pItem && (pItem->mnBits & SIB_USERDRAW) &&
    1266           0 :         pItem->mbVisible && ImplIsItemUpdate())
    1267             :     {
    1268           0 :         Update();
    1269           0 :         Rectangle aRect = ImplGetItemRectPos(nPos);
    1270           0 :         Invalidate(aRect);
    1271           0 :         Flush();
    1272             :     }
    1273             : }
    1274             : 
    1275        2839 : void StatusBar::SetHelpText( sal_uInt16 nItemId, const OUString& rText )
    1276             : {
    1277        2839 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1278             : 
    1279        2839 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1280        2839 :         (*mpItemList)[ nPos ]->maHelpText = rText;
    1281        2839 : }
    1282             : 
    1283           0 : const OUString& StatusBar::GetHelpText( sal_uInt16 nItemId ) const
    1284             : {
    1285           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1286             : 
    1287             :     assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
    1288             : 
    1289           0 :     ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1290           0 :     if ( pItem->maHelpText.isEmpty() && ( !pItem->maHelpId.isEmpty() || !pItem->maCommand.isEmpty() ))
    1291             :     {
    1292           0 :         Help* pHelp = Application::GetHelp();
    1293           0 :         if ( pHelp )
    1294             :         {
    1295           0 :             if ( !pItem->maCommand.isEmpty() )
    1296           0 :                 pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this );
    1297           0 :             if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
    1298           0 :                 pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
    1299             :         }
    1300             :     }
    1301             : 
    1302           0 :     return pItem->maHelpText;
    1303             : }
    1304             : 
    1305        5693 : void StatusBar::SetQuickHelpText( sal_uInt16 nItemId, const OUString& rText )
    1306             : {
    1307        5693 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1308             : 
    1309        5693 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1310        5693 :         (*mpItemList)[ nPos ]->maQuickHelpText = rText;
    1311        5693 : }
    1312             : 
    1313           0 : const OUString& StatusBar::GetQuickHelpText( sal_uInt16 nItemId ) const
    1314             : {
    1315           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1316             : 
    1317             :     assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
    1318             : 
    1319           0 :     ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1320           0 :     return pItem->maQuickHelpText;
    1321             : }
    1322             : 
    1323        8015 : void StatusBar::SetHelpId( sal_uInt16 nItemId, const OString& rHelpId )
    1324             : {
    1325        8015 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1326             : 
    1327        8015 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1328        1924 :         (*mpItemList)[ nPos ]->maHelpId = rHelpId;
    1329        8015 : }
    1330             : 
    1331           0 : OString StatusBar::GetHelpId( sal_uInt16 nItemId ) const
    1332             : {
    1333           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1334             : 
    1335           0 :     OString aRet;
    1336           0 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1337             :     {
    1338           0 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1339           0 :         if ( !pItem->maHelpId.isEmpty() )
    1340           0 :             aRet = pItem->maHelpId;
    1341             :         else
    1342           0 :             aRet = OUStringToOString( pItem->maCommand, RTL_TEXTENCODING_UTF8 );
    1343             :     }
    1344             : 
    1345           0 :     return aRet;
    1346             : }
    1347             : 
    1348        3497 : void StatusBar::StartProgressMode( const OUString& rText )
    1349             : {
    1350             :     DBG_ASSERT( !mbProgressMode, "StatusBar::StartProgressMode(): progress mode is active" );
    1351             : 
    1352        3497 :     mbProgressMode  = true;
    1353        3497 :     mnPercent       = 0;
    1354        3497 :     maPrgsTxt       = rText;
    1355             : 
    1356             :     // compute size
    1357        3497 :     ImplCalcProgressRect();
    1358             : 
    1359             :     // trigger Paint, which draws text and frame
    1360        3497 :     if ( IsReallyVisible() )
    1361             :     {
    1362        3496 :         Invalidate();
    1363        3496 :         Update();
    1364        3496 :         Flush();
    1365             :     }
    1366        3497 : }
    1367             : 
    1368       32952 : void StatusBar::SetProgressValue( sal_uInt16 nNewPercent )
    1369             : {
    1370             :     DBG_ASSERT( mbProgressMode, "StatusBar::SetProgressValue(): no progrss mode" );
    1371             :     DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" );
    1372             : 
    1373       32952 :     if ( mbProgressMode
    1374       32952 :     &&   IsReallyVisible()
    1375       65813 :     &&   (!mnPercent || (mnPercent != nNewPercent)) )
    1376             :     {
    1377       32861 :         Update();
    1378       32861 :         Invalidate();
    1379       32861 :         Flush();
    1380             :     }
    1381       32952 :     mnPercent = nNewPercent;
    1382       32952 : }
    1383             : 
    1384        3497 : void StatusBar::EndProgressMode()
    1385             : {
    1386             :     DBG_ASSERT( mbProgressMode, "StatusBar::EndProgressMode(): no progress mode" );
    1387             : 
    1388        3497 :     mbProgressMode = false;
    1389        3497 :     maPrgsTxt.clear();
    1390             : 
    1391        3497 :     if ( IsReallyVisible() )
    1392             :     {
    1393        3496 :         Invalidate();
    1394        3496 :         Update();
    1395        3496 :         Flush();
    1396             :     }
    1397        3497 : }
    1398             : 
    1399           0 : void StatusBar::SetText(const OUString& rText)
    1400             : {
    1401           0 :     if ((!mbVisibleItems || (GetStyle() & WB_RIGHT)) && !mbProgressMode && IsReallyVisible() && IsUpdateMode())
    1402             :     {
    1403           0 :         if (mbFormat)
    1404             :         {
    1405           0 :             Invalidate();
    1406           0 :             Window::SetText(rText);
    1407             :         }
    1408             :         else
    1409             :         {
    1410           0 :             Update();
    1411           0 :             Window::SetText(rText);
    1412           0 :             Invalidate();
    1413           0 :             Flush();
    1414             :         }
    1415             :     }
    1416           0 :     else if (mbProgressMode)
    1417             :     {
    1418           0 :         maPrgsTxt = rText;
    1419           0 :         if (IsReallyVisible())
    1420             :         {
    1421           0 :             Invalidate();
    1422           0 :             Update();
    1423           0 :             Flush();
    1424             :         }
    1425             :     }
    1426             :     else
    1427             :     {
    1428           0 :         Window::SetText(rText);
    1429             :     }
    1430           0 : }
    1431             : 
    1432        9774 : Size StatusBar::CalcWindowSizePixel() const
    1433             : {
    1434        9774 :     size_t  i = 0;
    1435        9774 :     size_t  nCount = mpItemList->size();
    1436        9774 :     long    nOffset = 0;
    1437        9774 :     long    nCalcWidth = (STATUSBAR_OFFSET_X*2);
    1438             :     long    nCalcHeight;
    1439             : 
    1440       19548 :     while ( i < nCount )
    1441             :     {
    1442           0 :         ImplStatusItem* pItem = (*mpItemList)[ i ];
    1443           0 :         nCalcWidth += pItem->mnWidth + nOffset;
    1444           0 :         nOffset = pItem->mnOffset;
    1445           0 :         i++;
    1446             :     }
    1447             : 
    1448        9774 :     long nMinHeight = GetTextHeight();
    1449        9774 :     const long nBarTextOffset = STATUSBAR_OFFSET_TEXTY*2;
    1450        9774 :     long nProgressHeight = nMinHeight + nBarTextOffset;
    1451             : 
    1452        9774 :     if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
    1453             :     {
    1454          19 :         ImplControlValue aValue;
    1455          19 :         Rectangle aControlRegion( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) );
    1456          19 :         Rectangle aNativeControlRegion, aNativeContentRegion;
    1457          38 :         if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL,
    1458             :                     aControlRegion, ControlState::ENABLED, aValue, OUString(),
    1459          38 :                     aNativeControlRegion, aNativeContentRegion ) )
    1460             :         {
    1461           0 :             nProgressHeight = aNativeControlRegion.GetHeight();
    1462          19 :         }
    1463             :     }
    1464             : 
    1465        9774 :     if( mpImplData->mbDrawItemFrames &&
    1466           0 :         IsNativeControlSupported( CTRL_FRAME, PART_BORDER ) )
    1467             :     {
    1468           0 :         ImplControlValue aControlValue( static_cast<long>(DrawFrameFlags::NoDraw) );
    1469           0 :         Rectangle aBound, aContent;
    1470           0 :         Rectangle aNatRgn( Point( 0, 0 ), Size( 150, 50 ) );
    1471           0 :         if( GetNativeControlRegion(CTRL_FRAME, PART_BORDER,
    1472           0 :                     aNatRgn, ControlState::NONE, aControlValue, OUString(), aBound, aContent) )
    1473             :         {
    1474             :             mpImplData->mnItemBorderWidth =
    1475           0 :                 ( aBound.GetHeight() - aContent.GetHeight() ) / 2;
    1476           0 :         }
    1477             :     }
    1478             : 
    1479        9774 :     nCalcHeight = nMinHeight+nBarTextOffset + 2*mpImplData->mnItemBorderWidth;
    1480        9774 :     if( nCalcHeight < nProgressHeight+2 )
    1481        9774 :         nCalcHeight = nProgressHeight+2;
    1482             : 
    1483        9774 :     return Size( nCalcWidth, nCalcHeight );
    1484             : }
    1485             : 
    1486        6458 : void StatusBar::SetAccessibleName( sal_uInt16 nItemId, const OUString& rName )
    1487             : {
    1488        6458 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1489             : 
    1490        6458 :     if ( nPos != STATUSBAR_ITEM_NOTFOUND )
    1491             :     {
    1492        6458 :         ImplStatusItem* pItem = (*mpItemList)[ nPos ];
    1493             : 
    1494        6458 :         if ( pItem->maAccessibleName != rName )
    1495             :         {
    1496        5016 :             pItem->maAccessibleName = rName;
    1497        5016 :             CallEventListeners( VCLEVENT_STATUSBAR_NAMECHANGED, reinterpret_cast<void*>(pItem->mnId) );
    1498             :         }
    1499             :     }
    1500        6458 : }
    1501             : 
    1502           2 : const OUString& StatusBar::GetAccessibleName( sal_uInt16 nItemId ) const
    1503             : {
    1504           2 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1505             : 
    1506             :     assert ( nPos != STATUSBAR_ITEM_NOTFOUND );
    1507             : 
    1508           2 :     return (*mpItemList)[ nPos ]->maAccessibleName;
    1509             : }
    1510             : 
    1511             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11