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

Generated by: LCOV version 1.10