LCOV - code coverage report
Current view: top level - svtools/source/control - headbar.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 256 827 31.0 %
Date: 2014-11-03 Functions: 23 57 40.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <svtools/headbar.hxx>
      21             : #include <vclxaccessibleheaderbar.hxx>
      22             : #include <tools/debug.hxx>
      23             : 
      24             : #include <vcl/svapp.hxx>
      25             : #include <vcl/help.hxx>
      26             : #include <vcl/image.hxx>
      27             : #include <vcl/salnativewidgets.hxx>
      28             : #include <vcl/settings.hxx>
      29             : #include <com/sun/star/accessibility/AccessibleRole.hpp>
      30             : #include <com/sun/star/accessibility/XAccessible.hpp>
      31             : 
      32         280 : class ImplHeadItem
      33             : {
      34             : public:
      35             :     sal_uInt16          mnId;
      36             :     HeaderBarItemBits   mnBits;
      37             :     long                mnSize;
      38             :     OString             maHelpId;
      39             :     Image               maImage;
      40             :     OUString            maOutText;
      41             :     OUString            maText;
      42             :     OUString            maHelpText;
      43             : };
      44             : 
      45             : 
      46             : 
      47             : #define HEAD_ARROWSIZE1             4
      48             : #define HEAD_ARROWSIZE2             7
      49             : 
      50             : #define HEADERBAR_TEXTOFF           2
      51             : #define HEADERBAR_ARROWOFF          5
      52             : #define HEADERBAR_SPLITOFF          3
      53             : 
      54             : #define HEADERBAR_DRAGOUTOFF        15
      55             : 
      56             : #define HEAD_HITTEST_ITEM           ((sal_uInt16)0x0001)
      57             : #define HEAD_HITTEST_DIVIDER        ((sal_uInt16)0x0002)
      58             : 
      59             : 
      60             : 
      61          82 : void HeaderBar::ImplInit( WinBits nWinStyle )
      62             : {
      63          82 :     mpItemList      = new ImplHeadItemList;
      64          82 :     mnBorderOff1    = 0;
      65          82 :     mnBorderOff2    = 0;
      66          82 :     mnOffset        = 0;
      67          82 :     mnDX            = 0;
      68          82 :     mnDY            = 0;
      69          82 :     mnDragSize      = 0;
      70          82 :     mnStartPos      = 0;
      71          82 :     mnDragPos       = 0;
      72          82 :     mnMouseOff      = 0;
      73          82 :     mnCurItemId     = 0;
      74          82 :     mnItemDragPos   = HEADERBAR_ITEM_NOTFOUND;
      75          82 :     mbDrag          = false;
      76          82 :     mbItemDrag      = false;
      77          82 :     mbOutDrag       = false;
      78          82 :     mbItemMode      = false;
      79             : 
      80          82 :     m_pVCLXHeaderBar = NULL;
      81             :     // StyleBits auswerten
      82          82 :     if ( nWinStyle & WB_DRAG )
      83          82 :         mbDragable = true;
      84             :     else
      85           0 :         mbDragable = false;
      86          82 :     if ( nWinStyle & WB_BUTTONSTYLE )
      87          82 :         mbButtonStyle = true;
      88             :     else
      89           0 :         mbButtonStyle = false;
      90          82 :     if ( nWinStyle & WB_BORDER )
      91             :     {
      92           0 :         mnBorderOff1 = 1;
      93           0 :         mnBorderOff2 = 1;
      94             :     }
      95             :     else
      96             :     {
      97          82 :         if ( nWinStyle & WB_BOTTOMBORDER )
      98          82 :             mnBorderOff2 = 1;
      99             :     }
     100             : 
     101          82 :     ImplInitSettings( true, true, true );
     102          82 : }
     103             : 
     104             : 
     105             : 
     106          82 : HeaderBar::HeaderBar( vcl::Window* pParent, WinBits nWinStyle ) :
     107          82 :     Window( pParent, nWinStyle & WB_3DLOOK )
     108             : {
     109          82 :     ImplInit( nWinStyle );
     110          82 :     SetSizePixel( CalcWindowSizePixel() );
     111          82 : }
     112             : 
     113             : 
     114             : 
     115         164 : HeaderBar::~HeaderBar()
     116             : {
     117             :     // Alle Items loeschen
     118          82 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
     119           0 :         delete (*mpItemList)[ i ];
     120             :     }
     121          82 :     mpItemList->clear();
     122          82 :     delete mpItemList;
     123          82 : }
     124             : 
     125             : 
     126             : 
     127         124 : void HeaderBar::ImplInitSettings( bool bFont,
     128             :                                   bool bForeground, bool bBackground )
     129             : {
     130         124 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     131             : 
     132         124 :     if ( bFont )
     133             :     {
     134         124 :         vcl::Font aFont;
     135         124 :         aFont = rStyleSettings.GetToolFont();
     136         124 :         if ( IsControlFont() )
     137           0 :             aFont.Merge( GetControlFont() );
     138         124 :         SetZoomedPointFont( aFont );
     139             :     }
     140             : 
     141         124 :     if ( bForeground || bFont )
     142             :     {
     143         124 :         Color aColor;
     144         124 :         if ( IsControlForeground() )
     145           0 :             aColor = GetControlForeground();
     146             :         else
     147         124 :             aColor = rStyleSettings.GetButtonTextColor();
     148         124 :         SetTextColor( aColor );
     149         124 :         SetTextFillColor();
     150             :     }
     151             : 
     152         124 :     if ( bBackground )
     153             :     {
     154         124 :         Color aColor;
     155         124 :         if ( IsControlBackground() )
     156           0 :             aColor = GetControlBackground();
     157             :         else
     158         124 :             aColor = rStyleSettings.GetFaceColor();
     159         124 :         SetBackground( aColor );
     160             :     }
     161         124 : }
     162             : 
     163             : 
     164             : 
     165         298 : long HeaderBar::ImplGetItemPos( sal_uInt16 nPos ) const
     166             : {
     167         298 :     long nX = -mnOffset;
     168        2261 :     for ( size_t i = 0; i < nPos; i++ )
     169        1963 :         nX += (*mpItemList)[ i ]->mnSize;
     170         298 :     return nX;
     171             : }
     172             : 
     173             : 
     174             : 
     175         298 : Rectangle HeaderBar::ImplGetItemRect( sal_uInt16 nPos ) const
     176             : {
     177         298 :     Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
     178         298 :     aRect.Right() = aRect.Left() + (*mpItemList)[ nPos ]->mnSize - 1;
     179             :     // check for overflow on various systems
     180         298 :     if ( aRect.Right() > 16000 )
     181           0 :         aRect.Right() = 16000;
     182         298 :     return aRect;
     183             : }
     184             : 
     185             : 
     186             : 
     187           0 : sal_uInt16 HeaderBar::ImplHitTest( const Point& rPos,
     188             :                                long& nMouseOff, sal_uInt16& nPos ) const
     189             : {
     190             :     ImplHeadItem*   pItem;
     191           0 :     size_t          nCount = (sal_uInt16)mpItemList->size();
     192           0 :     bool            bLastFixed = true;
     193           0 :     long            nX = -mnOffset;
     194             : 
     195           0 :     for ( size_t i = 0; i < nCount; i++ )
     196             :     {
     197           0 :         pItem = (*mpItemList)[ i ];
     198             : 
     199           0 :         if ( rPos.X() < (nX+pItem->mnSize) )
     200             :         {
     201             :             sal_uInt16 nMode;
     202             : 
     203           0 :             if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
     204             :             {
     205           0 :                 nMode = HEAD_HITTEST_DIVIDER;
     206           0 :                 nPos = i-1;
     207           0 :                 nMouseOff = rPos.X()-nX+1;
     208             :             }
     209             :             else
     210             :             {
     211           0 :                 nPos = i;
     212             : 
     213           0 :                 if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) )
     214             :                 {
     215           0 :                     nMode = HEAD_HITTEST_DIVIDER;
     216           0 :                     nMouseOff = rPos.X()-(nX+pItem->mnSize);
     217             :                 }
     218             :                 else
     219             :                 {
     220           0 :                     nMode = HEAD_HITTEST_ITEM;
     221           0 :                     nMouseOff = rPos.X()-nX;
     222             :                 }
     223             :             }
     224             : 
     225           0 :             return nMode;
     226             :         }
     227             : 
     228           0 :         if ( pItem->mnBits & HIB_FIXED )
     229           0 :             bLastFixed = true;
     230             :         else
     231           0 :             bLastFixed = false;
     232             : 
     233           0 :         nX += pItem->mnSize;
     234             :     }
     235             : 
     236           0 :     if ( !bLastFixed )
     237             :     {
     238           0 :         pItem = (*mpItemList)[ nCount-1 ];
     239           0 :         if ( (pItem->mnSize < 4)  && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
     240             :         {
     241           0 :             nPos = nCount-1;
     242           0 :             nMouseOff = rPos.X()-nX+1;
     243           0 :             return HEAD_HITTEST_DIVIDER;
     244             :         }
     245             :     }
     246             : 
     247           0 :     return 0;
     248             : }
     249             : 
     250             : 
     251             : 
     252           0 : void HeaderBar::ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos )
     253             : {
     254           0 :     Rectangle aRect1 = ImplGetItemRect( nStartPos );
     255           0 :     Rectangle aRect2 = ImplGetItemRect( nEndPos );
     256           0 :     Point     aStartPos = aRect1.Center();
     257           0 :     Point     aEndPos = aStartPos;
     258           0 :     Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
     259           0 :                           aStartPos.X()+2, aStartPos.Y()+2 );
     260             : 
     261           0 :     if ( nEndPos > nStartPos )
     262             :     {
     263           0 :         aStartPos.X() += 3;
     264           0 :         aEndPos.X() = aRect2.Right()-6;
     265             :     }
     266             :     else
     267             :     {
     268           0 :         aStartPos.X() -= 3;
     269           0 :         aEndPos.X() = aRect2.Left()+6;
     270             :     }
     271             : 
     272           0 :     SetRasterOp( ROP_INVERT );
     273           0 :     DrawRect( aStartRect );
     274           0 :     DrawLine( aStartPos, aEndPos );
     275           0 :     if ( nEndPos > nStartPos )
     276             :     {
     277           0 :         DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
     278           0 :                   Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
     279           0 :         DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
     280           0 :                   Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
     281           0 :         DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
     282           0 :                   Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
     283           0 :         DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
     284             :     }
     285             :     else
     286             :     {
     287           0 :         DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
     288           0 :                   Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
     289           0 :         DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
     290           0 :                   Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
     291           0 :         DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
     292           0 :                   Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
     293           0 :         DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
     294             :     }
     295           0 :     SetRasterOp( ROP_OVERPAINT );
     296           0 : }
     297             : 
     298             : 
     299             : 
     300         158 : void HeaderBar::ImplDrawItem( OutputDevice* pDev,
     301             :                               sal_uInt16 nPos, bool bHigh, bool bDrag,
     302             :                               const Rectangle& rItemRect,
     303             :                               const Rectangle* pRect,
     304             :                               sal_uLong )
     305             : {
     306         158 :     vcl::Window *const pWin = (pDev->GetOutDevType()==OUTDEV_WINDOW) ? static_cast<vcl::Window*>(pDev) : NULL;
     307         158 :     ImplControlValue aControlValue(0);
     308         158 :     Rectangle aCtrlRegion;
     309         158 :     ControlState nState(0);
     310             : 
     311         158 :     Rectangle aRect = rItemRect;
     312             : 
     313             :     // do not display if there is no space
     314         158 :     if ( aRect.GetWidth() <= 1 )
     315           0 :         return;
     316             : 
     317             :     // check of rectangle is visible
     318         158 :     if ( pRect )
     319             :     {
     320         158 :         if ( aRect.Right() < pRect->Left() )
     321           0 :             return;
     322         158 :         else if ( aRect.Left() > pRect->Right() )
     323          52 :             return;
     324             :     }
     325             :     else
     326             :     {
     327           0 :         if ( aRect.Right() < 0 )
     328           0 :             return;
     329           0 :         else if ( aRect.Left() > mnDX )
     330           0 :             return;
     331             :     }
     332             : 
     333         106 :     ImplHeadItem*           pItem  = (*mpItemList)[ nPos ];
     334         106 :     HeaderBarItemBits       nBits = pItem->mnBits;
     335         106 :     const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
     336             : 
     337         106 :     if( pWin && pWin->IsNativeControlSupported(CTRL_WINDOW_BACKGROUND, PART_ENTIRE_CONTROL) )
     338             :     {
     339           0 :         aCtrlRegion=aRect;
     340             :         pWin->DrawNativeControl( CTRL_WINDOW_BACKGROUND, PART_ENTIRE_CONTROL,
     341             :                                  aCtrlRegion, nState, aControlValue,
     342           0 :                                  OUString() );
     343             : 
     344             :     }
     345             :     else
     346             :     {
     347             :         // do not draw border
     348         106 :         aRect.Top()     += mnBorderOff1;
     349         106 :         aRect.Bottom()  -= mnBorderOff2;
     350             : 
     351             :         // delete background
     352         106 :         if ( !pRect || bDrag )
     353             :         {
     354           0 :             if ( bDrag )
     355             :             {
     356           0 :                 pDev->SetLineColor();
     357           0 :                 pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
     358           0 :                 pDev->DrawRect( aRect );
     359             :             }
     360             :             else
     361           0 :                 pDev->DrawWallpaper( aRect, GetBackground() );
     362             :         }
     363             :     }
     364             : 
     365         106 :     Color aSelectionTextColor( COL_TRANSPARENT );
     366             : 
     367         106 :     if( pWin && pWin->IsNativeControlSupported(CTRL_LISTHEADER, PART_BUTTON) )
     368             :     {
     369           0 :         aCtrlRegion=aRect;
     370           0 :         aControlValue.setTristateVal(BUTTONVALUE_ON);
     371           0 :         nState|=CTRL_STATE_ENABLED;
     372           0 :         if(bHigh)
     373           0 :             nState|=CTRL_STATE_PRESSED;
     374             :         pWin->DrawNativeControl( CTRL_LISTHEADER, PART_BUTTON,
     375             :                                  aCtrlRegion, nState, aControlValue,
     376           0 :                                  OUString() );
     377             :     }
     378             :     else
     379             :     {
     380             :         // draw separation line
     381         106 :         pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
     382         212 :         pDev->DrawLine( Point( aRect.Right(), aRect.Top() ),
     383         318 :                         Point( aRect.Right(), aRect.Bottom() ) );
     384             : 
     385             :         // draw ButtonStyle
     386             :         // avoid 3D borders
     387         106 :         if( bHigh )
     388           0 :             DrawSelectionBackground( aRect, 1, true, false, false, &aSelectionTextColor );
     389         106 :         else if ( !mbButtonStyle || (nBits & HIB_FLAT) )
     390           0 :             DrawSelectionBackground( aRect, 0, true, false, false, &aSelectionTextColor );
     391             :     }
     392             : 
     393             :     // do not draw if there is no space
     394         106 :     if ( aRect.GetWidth() < 1 )
     395           0 :         return;
     396             : 
     397             :     // calculate size and position and draw content
     398         106 :     pItem->maOutText = pItem->maText;
     399         106 :     Size aImageSize = pItem->maImage.GetSizePixel();
     400         106 :     Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0  );
     401         106 :     if (!pItem->maOutText.isEmpty())
     402          10 :         aTxtSize.Height() = pDev->GetTextHeight();
     403         106 :     long nArrowWidth = 0;
     404         106 :     if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
     405           0 :         nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF;
     406             : 
     407             :     // do not draw if there is not enough space for the image
     408         106 :     long nTestHeight = aImageSize.Height();
     409         106 :     if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
     410         106 :         nTestHeight += aTxtSize.Height();
     411         106 :     if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) )
     412             :     {
     413           0 :         aImageSize.Width() = 0;
     414           0 :         aImageSize.Height() = 0;
     415             :     }
     416             : 
     417             :     // cut text to correct length
     418         106 :     bool bLeftText = false;
     419         106 :     long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth;
     420         106 :     if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
     421           0 :         nMaxTxtWidth -= aImageSize.Width();
     422         106 :     long nTxtWidth = aTxtSize.Width();
     423         106 :     if ( nTxtWidth > nMaxTxtWidth )
     424             :     {
     425           4 :         bLeftText = true;
     426           4 :         OUStringBuffer aBuf(pItem->maOutText);
     427           4 :         aBuf.append("...");
     428          18 :         do
     429             :         {
     430          18 :             aBuf.remove(aBuf.getLength()-3-1, 1);
     431          18 :             nTxtWidth = pDev->GetTextWidth( aBuf.toString() );
     432             :         }
     433          18 :         while ( (nTxtWidth > nMaxTxtWidth) && (aBuf.getLength() > 3) );
     434           4 :         pItem->maOutText = aBuf.makeStringAndClear();
     435           4 :         if ( pItem->maOutText.getLength() == 3 )
     436             :         {
     437           0 :             nTxtWidth = 0;
     438           0 :             pItem->maOutText = OUString();
     439           4 :         }
     440             :     }
     441             : 
     442             :     // calculate text/imageposition
     443             :     long nTxtPos;
     444         106 :     if ( !bLeftText && (nBits & HIB_RIGHT) )
     445             :     {
     446           0 :         nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF;
     447           0 :         if ( nBits & HIB_RIGHTIMAGE )
     448           0 :             nTxtPos -= aImageSize.Width();
     449             :     }
     450         106 :     else if ( !bLeftText && (nBits & HIB_CENTER) )
     451             :     {
     452         102 :         long nTempWidth = nTxtWidth;
     453         102 :         if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
     454           0 :             nTempWidth += aImageSize.Width();
     455         102 :         nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2;
     456         102 :         if ( nBits & HIB_LEFTIMAGE )
     457           0 :             nTxtPos += aImageSize.Width();
     458         102 :         if ( nArrowWidth )
     459             :         {
     460           0 :             if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() )
     461             :             {
     462           0 :                 nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
     463           0 :                 if ( nBits & HIB_LEFTIMAGE )
     464           0 :                     nTxtPos += aImageSize.Width();
     465             :             }
     466         102 :         }
     467             :     }
     468             :     else
     469             :     {
     470           4 :         nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
     471           4 :         if ( nBits & HIB_LEFTIMAGE )
     472           0 :             nTxtPos += aImageSize.Width();
     473           4 :         if ( nBits & HIB_RIGHT )
     474           0 :             nTxtPos += nArrowWidth;
     475             :     }
     476             : 
     477             :     // calculate text/imageposition
     478         106 :     long nTxtPosY = 0;
     479         106 :     if ( !pItem->maOutText.isEmpty() || (nArrowWidth && aTxtSize.Height()) )
     480             :     {
     481          10 :         if ( nBits & HIB_TOP )
     482             :         {
     483           0 :             nTxtPosY = aRect.Top();
     484           0 :             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
     485           0 :                 nTxtPosY += aImageSize.Height();
     486             :         }
     487          10 :         else if ( nBits & HIB_BOTTOM )
     488           0 :             nTxtPosY = aRect.Bottom()-aTxtSize.Height();
     489             :         else
     490             :         {
     491          10 :             long nTempHeight = aTxtSize.Height();
     492          10 :             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
     493          10 :                 nTempHeight += aImageSize.Height();
     494          10 :             nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
     495          10 :             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
     496          10 :                 nTxtPosY += aImageSize.Height();
     497             :         }
     498             :     }
     499             : 
     500             :     // display text
     501         106 :     if (!pItem->maOutText.isEmpty())
     502             :     {
     503          10 :         if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
     504             :         {
     505           0 :             pDev->Push( PushFlags::TEXTCOLOR );
     506           0 :             pDev->SetTextColor( aSelectionTextColor );
     507             :         }
     508          10 :         if ( IsEnabled() )
     509          10 :             pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText );
     510             :         else
     511           0 :             pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, pItem->maOutText.getLength(), TEXT_DRAW_DISABLE );
     512          10 :         if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
     513           0 :             pDev->Pop();
     514             :     }
     515             : 
     516             :     // calculate the position and draw image if it is available
     517         106 :     long nImagePosY = 0;
     518         106 :     if ( aImageSize.Width() && aImageSize.Height() )
     519             :     {
     520           0 :         long nImagePos = nTxtPos;
     521           0 :         if ( nBits & HIB_LEFTIMAGE )
     522             :         {
     523           0 :             nImagePos -= aImageSize.Width();
     524           0 :             if ( nBits & HIB_RIGHT )
     525           0 :                 nImagePos -= nArrowWidth;
     526             :         }
     527           0 :         else if ( nBits & HIB_RIGHTIMAGE )
     528             :         {
     529           0 :             nImagePos += nTxtWidth;
     530           0 :             if ( !(nBits & HIB_RIGHT) )
     531           0 :                 nImagePos += nArrowWidth;
     532             :         }
     533             :         else
     534             :         {
     535           0 :             if ( nBits & HIB_RIGHT )
     536           0 :                 nImagePos = aRect.Right()-aImageSize.Width();
     537           0 :             else if ( nBits & HIB_CENTER )
     538           0 :                 nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2;
     539             :             else
     540           0 :                 nImagePos = aRect.Left()+HEADERBAR_TEXTOFF;
     541             :         }
     542             : 
     543           0 :         if ( nBits & HIB_TOP )
     544           0 :             nImagePosY = aRect.Top();
     545           0 :         else if ( nBits & HIB_BOTTOM )
     546             :         {
     547           0 :             nImagePosY = aRect.Bottom()-aImageSize.Height();
     548           0 :             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
     549           0 :                 nImagePosY -= aTxtSize.Height();
     550             :         }
     551             :         else
     552             :         {
     553           0 :             long nTempHeight = aImageSize.Height();
     554           0 :             if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
     555           0 :                 nTempHeight += aTxtSize.Height();
     556           0 :             nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
     557             :         }
     558           0 :         if ( nImagePos+aImageSize.Width() <= aRect.Right() )
     559             :         {
     560           0 :             sal_uInt16 nStyle = 0;
     561           0 :             if ( !IsEnabled() )
     562           0 :                 nStyle |= IMAGE_DRAW_DISABLE;
     563           0 :             pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle );
     564             :         }
     565             :     }
     566             : 
     567         106 :     if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
     568             :     {
     569           0 :         long nArrowX = nTxtPos;
     570           0 :         if ( nBits & HIB_RIGHT )
     571           0 :             nArrowX -= nArrowWidth;
     572             :         else
     573           0 :             nArrowX += nTxtWidth+HEADERBAR_ARROWOFF;
     574           0 :         if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.isEmpty() )
     575             :         {
     576           0 :             if ( nBits & HIB_RIGHT )
     577           0 :                 nArrowX -= aImageSize.Width();
     578             :             else
     579           0 :                 nArrowX += aImageSize.Width();
     580             :         }
     581             : 
     582             :         // is there enough space to draw the item?
     583           0 :         bool bDraw = true;
     584           0 :         if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF )
     585           0 :             bDraw = false;
     586           0 :         else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() )
     587           0 :             bDraw = false;
     588             : 
     589           0 :         if ( bDraw )
     590             :         {
     591           0 :             if( pWin && pWin->IsNativeControlSupported(CTRL_LISTHEADER, PART_ARROW) )
     592             :             {
     593           0 :                 aCtrlRegion=Rectangle(Point(nArrowX,aRect.Top()),Size(nArrowWidth,aRect.GetHeight()));
     594             :                 // control value passes 1 if arrow points down, 0 otherwise
     595           0 :                 aControlValue.setNumericVal((nBits&HIB_DOWNARROW)?1:0);
     596           0 :                 nState|=CTRL_STATE_ENABLED;
     597           0 :                 if(bHigh)
     598           0 :                     nState|=CTRL_STATE_PRESSED;
     599             :                 pWin->DrawNativeControl( CTRL_LISTHEADER, PART_ARROW,
     600             :                                          aCtrlRegion, nState, aControlValue,
     601           0 :                                          OUString() );
     602             :             }
     603             :             else
     604             :             {
     605             :                 long nArrowY;
     606           0 :                 if ( aTxtSize.Height() )
     607           0 :                     nArrowY = nTxtPosY+(aTxtSize.Height()/2);
     608           0 :                 else if ( aImageSize.Width() && aImageSize.Height() )
     609           0 :                     nArrowY = nImagePosY+(aImageSize.Height()/2);
     610             :                 else
     611             :                 {
     612           0 :                     if ( nBits & HIB_TOP )
     613           0 :                         nArrowY = aRect.Top()+1;
     614           0 :                     else if ( nBits & HIB_BOTTOM )
     615           0 :                         nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1;
     616             :                     else
     617           0 :                         nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);
     618             :                 }
     619           0 :                 nArrowY -= HEAD_ARROWSIZE1-1;
     620           0 :                 if ( nBits & HIB_DOWNARROW )
     621             :                 {
     622           0 :                     pDev->SetLineColor( rStyleSettings.GetLightColor() );
     623             :                     pDev->DrawLine( Point( nArrowX, nArrowY ),
     624           0 :                                     Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
     625             :                     pDev->DrawLine( Point( nArrowX, nArrowY ),
     626           0 :                                     Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) );
     627           0 :                     pDev->SetLineColor( rStyleSettings.GetShadowColor() );
     628             :                     pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ),
     629           0 :                                     Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
     630             :                 }
     631             :                 else
     632             :                 {
     633           0 :                     pDev->SetLineColor( rStyleSettings.GetLightColor() );
     634             :                     pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
     635           0 :                                     Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
     636           0 :                     pDev->SetLineColor( rStyleSettings.GetShadowColor() );
     637             :                     pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
     638           0 :                                     Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) );
     639             :                     pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ),
     640           0 :                                     Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
     641             :                 }
     642             :             }
     643             :         }
     644             :     }
     645             : 
     646             :     // all UserDraw if required
     647         106 :     if ( nBits & HIB_USERDRAW )
     648             :     {
     649           0 :         vcl::Region aRegion( aRect );
     650           0 :         if ( pRect )
     651           0 :             aRegion.Intersect( *pRect );
     652           0 :         pDev->SetClipRegion( aRegion );
     653           0 :         UserDrawEvent aODEvt( pDev, aRect, pItem->mnId );
     654           0 :         UserDraw( aODEvt );
     655           0 :         pDev->SetClipRegion();
     656         106 :     }
     657             : }
     658             : 
     659             : 
     660             : 
     661         158 : void HeaderBar::ImplDrawItem( sal_uInt16 nPos, bool bHigh, bool bDrag,
     662             :                               const Rectangle* pRect )
     663             : {
     664         158 :     Rectangle aRect = ImplGetItemRect( nPos );
     665         158 :     ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 );
     666         158 : }
     667             : 
     668             : 
     669             : 
     670         183 : void HeaderBar::ImplUpdate( sal_uInt16 nPos, bool bEnd, bool bDirect )
     671             : {
     672         183 :     if ( IsVisible() && IsUpdateMode() )
     673             :     {
     674         183 :         if ( !bDirect )
     675             :         {
     676         183 :             Rectangle   aRect;
     677         183 :             size_t      nItemCount = mpItemList->size();
     678         183 :             if ( nPos < nItemCount )
     679         102 :                 aRect = ImplGetItemRect( nPos );
     680             :             else
     681             :             {
     682          81 :                 aRect.Bottom() = mnDY-1;
     683          81 :                 if ( nItemCount )
     684          38 :                     aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right();
     685             :             }
     686         183 :             if ( bEnd )
     687         183 :                 aRect.Right() = mnDX-1;
     688         183 :             aRect.Top()     += mnBorderOff1;
     689         183 :             aRect.Bottom()  -= mnBorderOff2;
     690         183 :             Invalidate( aRect );
     691             :         }
     692             :         else
     693             :         {
     694           0 :             for ( size_t i = nPos; i < mpItemList->size(); i++ )
     695           0 :                 ImplDrawItem( i );
     696           0 :             if ( bEnd )
     697             :             {
     698           0 :                 Rectangle aRect = ImplGetItemRect( (sal_uInt16)mpItemList->size() );
     699           0 :                 aRect.Left()  = aRect.Right();
     700           0 :                 aRect.Right() = mnDX-1;
     701           0 :                 if ( aRect.Left() < aRect.Right() )
     702             :                 {
     703           0 :                     aRect.Top()     += mnBorderOff1;
     704           0 :                     aRect.Bottom()  -= mnBorderOff2;
     705           0 :                     Erase( aRect );
     706             :                 }
     707             :             }
     708             :         }
     709             :     }
     710         183 : }
     711             : 
     712             : 
     713             : 
     714           0 : void HeaderBar::ImplStartDrag( const Point& rMousePos, bool bCommand )
     715             : {
     716             :     sal_uInt16  nPos;
     717           0 :     sal_uInt16  nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
     718           0 :     if ( nHitTest )
     719             :     {
     720           0 :         mbDrag = false;
     721           0 :         ImplHeadItem* pItem = (*mpItemList)[ nPos ];
     722           0 :         if ( nHitTest & HEAD_HITTEST_DIVIDER )
     723           0 :             mbDrag = true;
     724             :         else
     725             :         {
     726           0 :             if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) ||
     727           0 :                  (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) )
     728             :             {
     729           0 :                 mbItemMode = true;
     730           0 :                 mbDrag = true;
     731           0 :                 if ( bCommand )
     732             :                 {
     733           0 :                     if ( mbDragable )
     734           0 :                         mbItemDrag = true;
     735             :                     else
     736             :                     {
     737           0 :                         mbItemMode = false;
     738           0 :                         mbDrag = false;
     739             :                     }
     740             :                 }
     741             :             }
     742             :             else
     743             :             {
     744           0 :                 if ( !bCommand )
     745             :                 {
     746           0 :                     mnCurItemId = pItem->mnId;
     747           0 :                     Select();
     748           0 :                     mnCurItemId = 0;
     749             :                 }
     750             :             }
     751             :         }
     752             : 
     753           0 :         if ( mbDrag )
     754             :         {
     755           0 :             mbOutDrag = false;
     756           0 :             mnCurItemId = pItem->mnId;
     757           0 :             mnItemDragPos = nPos;
     758           0 :             StartTracking();
     759           0 :             mnStartPos = rMousePos.X()-mnMouseOff;
     760           0 :             mnDragPos = mnStartPos;
     761           0 :             StartDrag();
     762           0 :             if ( mbItemMode )
     763           0 :                 ImplDrawItem( nPos, true, mbItemDrag );
     764             :             else
     765             :             {
     766           0 :                 Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
     767           0 :                 ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
     768             :             }
     769             :         }
     770             :         else
     771           0 :             mnMouseOff = 0;
     772             :     }
     773           0 : }
     774             : 
     775             : 
     776             : 
     777           0 : void HeaderBar::ImplDrag( const Point& rMousePos )
     778             : {
     779             :     bool        bNewOutDrag;
     780           0 :     sal_uInt16  nPos = GetItemPos( mnCurItemId );
     781             : 
     782           0 :     mnDragPos = rMousePos.X()-mnMouseOff;
     783           0 :     if ( mbItemMode )
     784             :     {
     785           0 :         Rectangle aItemRect = ImplGetItemRect( nPos );
     786           0 :         if ( aItemRect.IsInside( rMousePos ) )
     787           0 :             bNewOutDrag = false;
     788             :         else
     789           0 :             bNewOutDrag = true;
     790             : 
     791             :         //  if needed switch on ItemDrag
     792           0 :         if ( bNewOutDrag && mbDragable && !mbItemDrag &&
     793           0 :              !((*mpItemList)[ nPos ]->mnBits & HIB_FIXEDPOS) )
     794             :         {
     795           0 :             if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
     796             :             {
     797           0 :                 mbItemDrag = true;
     798           0 :                 ImplDrawItem( nPos, true, mbItemDrag );
     799             :             }
     800             :         }
     801             : 
     802           0 :         sal_uInt16 nOldItemDragPos = mnItemDragPos;
     803           0 :         if ( mbItemDrag )
     804             :         {
     805           0 :             if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) )
     806           0 :                 bNewOutDrag = true;
     807             :             else
     808           0 :                 bNewOutDrag = false;
     809             : 
     810           0 :             if ( bNewOutDrag )
     811           0 :                 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
     812             :             else
     813             :             {
     814           0 :                 sal_uInt16 nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
     815           0 :                 if ( nTempId )
     816           0 :                     mnItemDragPos = GetItemPos( nTempId );
     817             :                 else
     818             :                 {
     819           0 :                     if ( rMousePos.X() <= 0 )
     820           0 :                         mnItemDragPos = 0;
     821             :                     else
     822           0 :                         mnItemDragPos = GetItemCount()-1;
     823             :                 }
     824             : 
     825             :                 // do not use non-movable items
     826           0 :                 if ( mnItemDragPos < nPos )
     827             :                 {
     828           0 :                     while ( ((*mpItemList)[ mnItemDragPos ]->mnBits & HIB_FIXEDPOS) &&
     829           0 :                             (mnItemDragPos < nPos) )
     830           0 :                         mnItemDragPos++;
     831             :                 }
     832           0 :                 else if ( mnItemDragPos > nPos )
     833             :                 {
     834           0 :                     while ( ((*mpItemList)[ mnItemDragPos ]->mnBits & HIB_FIXEDPOS) &&
     835           0 :                             (mnItemDragPos > nPos) )
     836           0 :                         mnItemDragPos--;
     837             :                 }
     838             :             }
     839             : 
     840           0 :             if ( (mnItemDragPos != nOldItemDragPos) &&
     841           0 :                  (nOldItemDragPos != nPos) &&
     842             :                  (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
     843             :             {
     844           0 :                 ImplInvertDrag( nPos, nOldItemDragPos );
     845           0 :                 ImplDrawItem( nOldItemDragPos );
     846             :             }
     847             :         }
     848             : 
     849           0 :         if ( bNewOutDrag != mbOutDrag )
     850           0 :             ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag );
     851             : 
     852           0 :         if ( mbItemDrag  )
     853             :         {
     854           0 :             if ( (mnItemDragPos != nOldItemDragPos) &&
     855           0 :                  (mnItemDragPos != nPos) &&
     856           0 :                  (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
     857             :             {
     858           0 :                 ImplDrawItem( mnItemDragPos, false, true );
     859           0 :                 ImplInvertDrag( nPos, mnItemDragPos );
     860             :             }
     861             :         }
     862             : 
     863           0 :         mbOutDrag = bNewOutDrag;
     864             :     }
     865             :     else
     866             :     {
     867           0 :         Rectangle aItemRect = ImplGetItemRect( nPos );
     868           0 :         if ( mnDragPos < aItemRect.Left() )
     869           0 :             mnDragPos = aItemRect.Left();
     870           0 :         if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
     871           0 :             HideTracking();
     872             :         else
     873             :         {
     874           0 :             Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
     875           0 :             ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
     876             :         }
     877             :     }
     878             : 
     879           0 :     Drag();
     880           0 : }
     881             : 
     882             : 
     883             : 
     884           0 : void HeaderBar::ImplEndDrag( bool bCancel )
     885             : {
     886           0 :     HideTracking();
     887             : 
     888           0 :     if ( bCancel || mbOutDrag )
     889             :     {
     890           0 :         if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
     891             :         {
     892           0 :             sal_uInt16 nPos = GetItemPos( mnCurItemId );
     893           0 :             ImplDrawItem( nPos );
     894             :         }
     895             : 
     896           0 :         mnCurItemId = 0;
     897             :     }
     898             :     else
     899             :     {
     900           0 :         sal_uInt16 nPos = GetItemPos( mnCurItemId );
     901           0 :         if ( mbItemMode )
     902             :         {
     903           0 :             if ( mbItemDrag )
     904             :             {
     905           0 :                 Pointer aPointer( POINTER_ARROW );
     906           0 :                 SetPointer( aPointer );
     907           0 :                 if ( (mnItemDragPos != nPos) &&
     908           0 :                      (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
     909             :                 {
     910           0 :                     ImplInvertDrag( nPos, mnItemDragPos );
     911           0 :                     MoveItem( mnCurItemId, mnItemDragPos );
     912             :                 }
     913             :                 else
     914           0 :                     ImplDrawItem( nPos );
     915             :             }
     916             :             else
     917             :             {
     918           0 :                 Select();
     919           0 :                 ImplUpdate( nPos );
     920             :             }
     921             :         }
     922             :         else
     923             :         {
     924           0 :             long nDelta = mnDragPos - mnStartPos;
     925           0 :             if ( nDelta )
     926             :             {
     927           0 :                 ImplHeadItem* pItem = (*mpItemList)[ nPos ];
     928           0 :                 pItem->mnSize += nDelta;
     929           0 :                 ImplUpdate( nPos, true );
     930             :             }
     931             :         }
     932             :     }
     933             : 
     934           0 :     mbDrag          = false;
     935           0 :     EndDrag();
     936           0 :     mnCurItemId     = 0;
     937           0 :     mnItemDragPos   = HEADERBAR_ITEM_NOTFOUND;
     938           0 :     mbOutDrag       = false;
     939           0 :     mbItemMode      = false;
     940           0 :     mbItemDrag      = false;
     941           0 : }
     942             : 
     943             : 
     944             : 
     945           0 : void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
     946             : {
     947           0 :     if ( rMEvt.IsLeft() )
     948             :     {
     949           0 :         if ( rMEvt.GetClicks() == 2 )
     950             :         {
     951             :             long    nTemp;
     952             :             sal_uInt16  nPos;
     953           0 :             sal_uInt16  nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
     954           0 :             if ( nHitTest )
     955             :             {
     956           0 :                 ImplHeadItem* pItem = (*mpItemList)[ nPos ];
     957           0 :                 if ( nHitTest & HEAD_HITTEST_DIVIDER )
     958           0 :                     mbItemMode = false;
     959             :                 else
     960           0 :                     mbItemMode = true;
     961           0 :                 mnCurItemId = pItem->mnId;
     962           0 :                 DoubleClick();
     963           0 :                 mbItemMode = false;
     964           0 :                 mnCurItemId = 0;
     965             :             }
     966             :         }
     967             :         else
     968           0 :             ImplStartDrag( rMEvt.GetPosPixel(), false );
     969             :     }
     970           0 : }
     971             : 
     972             : 
     973             : 
     974           0 : void HeaderBar::MouseMove( const MouseEvent& rMEvt )
     975             : {
     976             :     long            nTemp1;
     977             :     sal_uInt16          nTemp2;
     978           0 :     PointerStyle    eStyle = POINTER_ARROW;
     979           0 :     sal_uInt16          nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );
     980             : 
     981           0 :     if ( nHitTest & HEAD_HITTEST_DIVIDER )
     982           0 :         eStyle = POINTER_HSIZEBAR;
     983           0 :     Pointer aPtr( eStyle );
     984           0 :     SetPointer( aPtr );
     985           0 : }
     986             : 
     987             : 
     988             : 
     989           0 : void HeaderBar::Tracking( const TrackingEvent& rTEvt )
     990             : {
     991           0 :     Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
     992             : 
     993           0 :     if ( rTEvt.IsTrackingEnded() )
     994           0 :         ImplEndDrag( rTEvt.IsTrackingCanceled() );
     995             :     else
     996           0 :         ImplDrag( aMousePos );
     997           0 : }
     998             : 
     999             : 
    1000             : 
    1001          72 : void HeaderBar::Paint( const Rectangle& rRect )
    1002             : {
    1003          72 :     if ( mnBorderOff1 || mnBorderOff2 )
    1004             :     {
    1005          72 :         SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
    1006          72 :         if ( mnBorderOff1 )
    1007           0 :             DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
    1008          72 :         if ( mnBorderOff2 )
    1009          72 :             DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
    1010             :         // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
    1011          72 :         if ( mnBorderOff1 && mnBorderOff2 )
    1012             :         {
    1013           0 :             DrawLine( Point( 0, 0 ), Point( 0, mnDY-1 ) );
    1014           0 :             DrawLine( Point( mnDX-1, 0 ), Point( mnDX-1, mnDY-1 ) );
    1015             :         }
    1016             :     }
    1017             : 
    1018             :     sal_uInt16 nCurItemPos;
    1019          72 :     if ( mbDrag )
    1020           0 :         nCurItemPos = GetItemPos( mnCurItemId );
    1021             :     else
    1022          72 :         nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
    1023          72 :     sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
    1024         230 :     for ( sal_uInt16 i = 0; i < nItemCount; i++ )
    1025         158 :         ImplDrawItem( i, (i == nCurItemPos), false, &rRect );
    1026          72 : }
    1027             : 
    1028             : 
    1029             : 
    1030           0 : void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
    1031             :                       sal_uLong nFlags )
    1032             : {
    1033           0 :     Point       aPos  = pDev->LogicToPixel( rPos );
    1034           0 :     Size        aSize = pDev->LogicToPixel( rSize );
    1035           0 :     Rectangle   aRect( aPos, aSize );
    1036           0 :     vcl::Font   aFont = GetDrawPixelFont( pDev );
    1037             : 
    1038           0 :     pDev->Push();
    1039           0 :     pDev->SetMapMode();
    1040           0 :     pDev->SetFont( aFont );
    1041           0 :     if ( nFlags & WINDOW_DRAW_MONO )
    1042           0 :         pDev->SetTextColor( Color( COL_BLACK ) );
    1043             :     else
    1044           0 :         pDev->SetTextColor( GetTextColor() );
    1045           0 :     pDev->SetTextFillColor();
    1046             : 
    1047           0 :     if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) )
    1048             :     {
    1049           0 :         pDev->DrawWallpaper( aRect, GetBackground() );
    1050           0 :         if ( mnBorderOff1 || mnBorderOff2 )
    1051             :         {
    1052           0 :             pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
    1053           0 :             if ( mnBorderOff1 )
    1054           0 :                 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
    1055           0 :             if ( mnBorderOff2 )
    1056           0 :                 pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
    1057             :             // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
    1058           0 :             if ( mnBorderOff1 && mnBorderOff2 )
    1059             :             {
    1060           0 :                 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
    1061           0 :                 pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) );
    1062             :             }
    1063             :         }
    1064             :     }
    1065             : 
    1066           0 :     Rectangle aItemRect( aRect );
    1067           0 :     size_t nItemCount = mpItemList->size();
    1068           0 :     for ( size_t i = 0; i < nItemCount; i++ )
    1069             :     {
    1070           0 :         aItemRect.Left() = aRect.Left()+ImplGetItemPos( i );
    1071           0 :         aItemRect.Right() = aItemRect.Left() + (*mpItemList)[ i ]->mnSize - 1;
    1072             :         // check for overflow on some systems
    1073           0 :         if ( aItemRect.Right() > 16000 )
    1074           0 :             aItemRect.Right() = 16000;
    1075           0 :         vcl::Region aRegion( aRect );
    1076           0 :         pDev->SetClipRegion( aRegion );
    1077           0 :         ImplDrawItem( pDev, i, false, false, aItemRect, &aRect, nFlags );
    1078           0 :         pDev->SetClipRegion();
    1079           0 :     }
    1080             : 
    1081           0 :     pDev->Pop();
    1082           0 : }
    1083             : 
    1084             : 
    1085             : 
    1086         136 : void HeaderBar::Resize()
    1087             : {
    1088         136 :     Size aSize = GetOutputSizePixel();
    1089         136 :     if ( IsVisible() && (mnDY != aSize.Height()) )
    1090          82 :         Invalidate();
    1091         136 :     mnDX = aSize.Width();
    1092         136 :     mnDY = aSize.Height();
    1093         136 : }
    1094             : 
    1095             : 
    1096             : 
    1097           0 : void HeaderBar::Command( const CommandEvent& rCEvt )
    1098             : {
    1099           0 :     if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag )
    1100             :     {
    1101           0 :         ImplStartDrag( rCEvt.GetMousePosPixel(), true );
    1102           0 :         return;
    1103             :     }
    1104             : 
    1105           0 :     Window::Command( rCEvt );
    1106             : }
    1107             : 
    1108             : 
    1109             : 
    1110           0 : void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
    1111             : {
    1112           0 :     sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
    1113           0 :     if ( nItemId )
    1114             :     {
    1115           0 :         if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
    1116             :         {
    1117           0 :             Rectangle aItemRect = GetItemRect( nItemId );
    1118           0 :             Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
    1119           0 :             aItemRect.Left()   = aPt.X();
    1120           0 :             aItemRect.Top()    = aPt.Y();
    1121           0 :             aPt = OutputToScreenPixel( aItemRect.BottomRight() );
    1122           0 :             aItemRect.Right()  = aPt.X();
    1123           0 :             aItemRect.Bottom() = aPt.Y();
    1124             : 
    1125           0 :             OUString aStr = GetHelpText( nItemId );
    1126           0 :             if ( aStr.isEmpty() || !(rHEvt.GetMode() & HELPMODE_BALLOON) )
    1127             :             {
    1128           0 :                 ImplHeadItem* pItem = (*mpItemList)[ GetItemPos( nItemId ) ];
    1129             :                 // Quick-help is only displayed if the text is not fully visible.
    1130             :                 // Otherwise we display Helptext only if the items do not contain text
    1131           0 :                 if ( pItem->maOutText != pItem->maText )
    1132           0 :                     aStr = pItem->maText;
    1133           0 :                 else if (!pItem->maText.isEmpty())
    1134           0 :                     aStr = OUString();
    1135             :             }
    1136             : 
    1137           0 :             if (!aStr.isEmpty())
    1138             :             {
    1139           0 :                 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
    1140           0 :                     Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
    1141             :                 else
    1142           0 :                     Help::ShowQuickHelp( this, aItemRect, aStr );
    1143           0 :                 return;
    1144           0 :             }
    1145             :         }
    1146           0 :         else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
    1147             :         {
    1148           0 :             OUString aHelpId( OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) );
    1149           0 :             if ( !aHelpId.isEmpty() )
    1150             :             {
    1151             :                 // display it if help is available
    1152           0 :                 Help* pHelp = Application::GetHelp();
    1153           0 :                 if ( pHelp )
    1154           0 :                     pHelp->Start( aHelpId, this );
    1155           0 :                 return;
    1156           0 :             }
    1157             :         }
    1158             :     }
    1159             : 
    1160           0 :     Window::RequestHelp( rHEvt );
    1161             : }
    1162             : 
    1163             : 
    1164             : 
    1165         232 : void HeaderBar::StateChanged( StateChangedType nType )
    1166             : {
    1167         232 :     Window::StateChanged( nType );
    1168             : 
    1169         232 :     if ( nType == StateChangedType::ENABLE )
    1170          12 :         Invalidate();
    1171         220 :     else if ( (nType == StateChangedType::ZOOM) ||
    1172             :               (nType == StateChangedType::CONTROLFONT) )
    1173             :     {
    1174           0 :         ImplInitSettings( true, false, false );
    1175           0 :         Invalidate();
    1176             :     }
    1177         220 :     else if ( nType == StateChangedType::CONTROLFOREGROUND )
    1178             :     {
    1179           0 :         ImplInitSettings( false, true, false );
    1180           0 :         Invalidate();
    1181             :     }
    1182         220 :     else if ( nType == StateChangedType::CONTROLBACKGROUND )
    1183             :     {
    1184           0 :         ImplInitSettings( false, false, true );
    1185           0 :         Invalidate();
    1186             :     }
    1187         232 : }
    1188             : 
    1189             : 
    1190             : 
    1191          42 : void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
    1192             : {
    1193          42 :     Window::DataChanged( rDCEvt );
    1194             : 
    1195         126 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
    1196         126 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
    1197          84 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
    1198          42 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    1199             :     {
    1200          42 :         ImplInitSettings( true, true, true );
    1201          42 :         Invalidate();
    1202             :     }
    1203          42 : }
    1204             : 
    1205             : 
    1206             : 
    1207           0 : void HeaderBar::UserDraw( const UserDrawEvent& )
    1208             : {
    1209           0 : }
    1210             : 
    1211             : 
    1212             : 
    1213           0 : void HeaderBar::StartDrag()
    1214             : {
    1215           0 :     maStartDragHdl.Call( this );
    1216           0 : }
    1217             : 
    1218             : 
    1219             : 
    1220           0 : void HeaderBar::Drag()
    1221             : {
    1222           0 :     maDragHdl.Call( this );
    1223           0 : }
    1224             : 
    1225             : 
    1226             : 
    1227           0 : void HeaderBar::EndDrag()
    1228             : {
    1229           0 :     maEndDragHdl.Call( this );
    1230           0 : }
    1231             : 
    1232             : 
    1233             : 
    1234           0 : void HeaderBar::Select()
    1235             : {
    1236           0 :     maSelectHdl.Call( this );
    1237           0 : }
    1238             : 
    1239             : 
    1240             : 
    1241           0 : void HeaderBar::DoubleClick()
    1242             : {
    1243           0 :     maDoubleClickHdl.Call( this );
    1244           0 : }
    1245             : 
    1246             : 
    1247             : 
    1248         140 : void HeaderBar::InsertItem( sal_uInt16 nItemId, const OUString& rText,
    1249             :                             long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
    1250             : {
    1251             :     DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
    1252             :     DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
    1253             :                 "HeaderBar::InsertItem(): ItemId already exists" );
    1254             : 
    1255             :     // create item and insert in the list
    1256         140 :     ImplHeadItem* pItem = new ImplHeadItem;
    1257         140 :     pItem->mnId         = nItemId;
    1258         140 :     pItem->mnBits       = nBits;
    1259         140 :     pItem->mnSize       = nSize;
    1260         140 :     pItem->maText       = rText;
    1261         140 :     if ( nPos < mpItemList->size() ) {
    1262           6 :         ImplHeadItemList::iterator it = mpItemList->begin();
    1263           6 :         ::std::advance( it, nPos );
    1264           6 :         mpItemList->insert( it, pItem );
    1265             :     } else {
    1266         134 :         mpItemList->push_back( pItem );
    1267             :     }
    1268             : 
    1269             :     // update display
    1270         140 :     ImplUpdate( nPos, true );
    1271         140 : }
    1272             : 
    1273             : 
    1274             : 
    1275          20 : void HeaderBar::RemoveItem( sal_uInt16 nItemId )
    1276             : {
    1277          20 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1278          20 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1279             :     {
    1280          20 :         if ( nPos < mpItemList->size() ) {
    1281          20 :             ImplHeadItemList::iterator it = mpItemList->begin();
    1282          20 :             ::std::advance( it, nPos );
    1283          20 :             delete *it;
    1284          20 :             mpItemList->erase( it );
    1285             :         }
    1286             :     }
    1287          20 : }
    1288             : 
    1289             : 
    1290             : 
    1291           0 : void HeaderBar::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos )
    1292             : {
    1293           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1294           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1295             :     {
    1296           0 :         if ( nPos != nNewPos )
    1297             :         {
    1298           0 :             ImplHeadItemList::iterator it = mpItemList->begin();
    1299           0 :             ::std::advance( it, nPos );
    1300           0 :             ImplHeadItem* pItem = *it;
    1301           0 :             mpItemList->erase( it );
    1302           0 :             if ( nNewPos < nPos )
    1303           0 :                 nPos = nNewPos;
    1304           0 :             it = mpItemList->begin();
    1305           0 :             ::std::advance( it, nPos );
    1306           0 :             mpItemList->insert( it, pItem );
    1307             :         }
    1308             :     }
    1309           0 : }
    1310             : 
    1311             : 
    1312             : 
    1313          43 : void HeaderBar::Clear()
    1314             : {
    1315             :     // delete all items
    1316         163 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
    1317         120 :         delete (*mpItemList)[ i ];
    1318             :     }
    1319          43 :     mpItemList->clear();
    1320             : 
    1321          43 :     ImplUpdate( 0, true );
    1322          43 : }
    1323             : 
    1324             : 
    1325             : 
    1326         511 : void HeaderBar::SetOffset( long nNewOffset )
    1327             : {
    1328             :     // move area
    1329         511 :     Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
    1330         511 :     long nDelta = mnOffset-nNewOffset;
    1331         511 :     mnOffset = nNewOffset;
    1332         511 :     Scroll( nDelta, 0, aRect );
    1333         511 : }
    1334             : 
    1335             : 
    1336             : 
    1337           0 : sal_uInt16 HeaderBar::GetItemCount() const
    1338             : {
    1339           0 :     return (sal_uInt16)mpItemList->size();
    1340             : }
    1341             : 
    1342             : 
    1343             : 
    1344          20 : sal_uInt16 HeaderBar::GetItemPos( sal_uInt16 nItemId ) const
    1345             : {
    1346          46 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
    1347          46 :         ImplHeadItem* pItem = (*mpItemList)[ i ];
    1348          46 :         if ( pItem->mnId == nItemId )
    1349          20 :             return (sal_uInt16)i;
    1350             :     }
    1351           0 :     return HEADERBAR_ITEM_NOTFOUND;
    1352             : }
    1353             : 
    1354             : 
    1355             : 
    1356           0 : sal_uInt16 HeaderBar::GetItemId( sal_uInt16 nPos ) const
    1357             : {
    1358           0 :     ImplHeadItem* pItem = (nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ] : NULL;
    1359           0 :     if ( pItem )
    1360           0 :         return pItem->mnId;
    1361             :     else
    1362           0 :         return 0;
    1363             : }
    1364             : 
    1365             : 
    1366             : 
    1367           0 : sal_uInt16 HeaderBar::GetItemId( const Point& rPos ) const
    1368             : {
    1369           0 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
    1370           0 :         if ( ImplGetItemRect( i ).IsInside( rPos ) ) {
    1371           0 :             return GetItemId( i );
    1372             :         }
    1373             :     }
    1374           0 :     return 0;
    1375             : }
    1376             : 
    1377             : 
    1378             : 
    1379           0 : Rectangle HeaderBar::GetItemRect( sal_uInt16 nItemId ) const
    1380             : {
    1381           0 :     Rectangle aRect;
    1382           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1383           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1384           0 :         aRect = ImplGetItemRect( nPos );
    1385           0 :     return aRect;
    1386             : }
    1387             : 
    1388             : 
    1389             : 
    1390           0 : void HeaderBar::SetItemSize( sal_uInt16 nItemId, long nNewSize )
    1391             : {
    1392           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1393           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1394             :     {
    1395           0 :         ImplHeadItem* pItem = (*mpItemList)[ nPos ];
    1396           0 :         if ( pItem->mnSize != nNewSize )
    1397             :         {
    1398           0 :             pItem->mnSize = nNewSize;
    1399           0 :             ImplUpdate( nPos, true );
    1400             :         }
    1401             :     }
    1402           0 : }
    1403             : 
    1404             : 
    1405             : 
    1406           0 : long HeaderBar::GetItemSize( sal_uInt16 nItemId ) const
    1407             : {
    1408           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1409           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1410           0 :         return (*mpItemList)[ nPos ]->mnSize;
    1411             :     else
    1412           0 :         return 0;
    1413             : }
    1414             : 
    1415             : 
    1416             : 
    1417           0 : void HeaderBar::SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits )
    1418             : {
    1419           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1420           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1421             :     {
    1422           0 :         ImplHeadItem* pItem = (*mpItemList)[ nPos ];
    1423           0 :         if ( pItem->mnBits != nNewBits )
    1424             :         {
    1425           0 :             pItem->mnBits = nNewBits;
    1426           0 :             ImplUpdate( nPos );
    1427             :         }
    1428             :     }
    1429           0 : }
    1430             : 
    1431             : 
    1432             : 
    1433           0 : HeaderBarItemBits HeaderBar::GetItemBits( sal_uInt16 nItemId ) const
    1434             : {
    1435           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1436           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1437           0 :         return (*mpItemList)[ nPos ]->mnBits;
    1438             :     else
    1439           0 :         return 0;
    1440             : }
    1441             : 
    1442             : 
    1443             : 
    1444           0 : void HeaderBar::SetItemText( sal_uInt16 nItemId, const OUString& rText )
    1445             : {
    1446           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1447           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1448             :     {
    1449           0 :         (*mpItemList)[ nPos ]->maText = rText;
    1450           0 :         ImplUpdate( nPos );
    1451             :     }
    1452           0 : }
    1453             : 
    1454             : 
    1455             : 
    1456           0 : OUString HeaderBar::GetItemText( sal_uInt16 nItemId ) const
    1457             : {
    1458           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1459           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1460           0 :         return (*mpItemList)[ nPos ]->maText;
    1461           0 :     return OUString();
    1462             : }
    1463             : 
    1464             : 
    1465             : 
    1466           0 : OUString HeaderBar::GetHelpText( sal_uInt16 nItemId ) const
    1467             : {
    1468           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1469           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1470             :     {
    1471           0 :         ImplHeadItem* pItem = (*mpItemList)[ nPos ];
    1472           0 :         if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
    1473             :         {
    1474           0 :             Help* pHelp = Application::GetHelp();
    1475           0 :             if ( pHelp )
    1476           0 :                 pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
    1477             :         }
    1478             : 
    1479           0 :         return pItem->maHelpText;
    1480             :     }
    1481             : 
    1482           0 :     return OUString();
    1483             : }
    1484             : 
    1485             : 
    1486             : 
    1487           0 : OString HeaderBar::GetHelpId( sal_uInt16 nItemId ) const
    1488             : {
    1489           0 :     sal_uInt16 nPos = GetItemPos( nItemId );
    1490           0 :     OString aRet;
    1491           0 :     if ( nPos != HEADERBAR_ITEM_NOTFOUND )
    1492           0 :         return (*mpItemList)[ nPos ]->maHelpId;
    1493           0 :     return aRet;
    1494             : }
    1495             : 
    1496             : 
    1497             : 
    1498          82 : Size HeaderBar::CalcWindowSizePixel() const
    1499             : {
    1500          82 :     long nMaxImageSize = 0;
    1501          82 :     Size aSize( 0, GetTextHeight() );
    1502             : 
    1503          82 :     for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
    1504             :     {
    1505           0 :         ImplHeadItem* pItem = (*mpItemList)[ i ];
    1506             :         // take image size into account
    1507           0 :         long nImageHeight = pItem->maImage.GetSizePixel().Height();
    1508           0 :         if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.isEmpty() )
    1509           0 :             nImageHeight += aSize.Height();
    1510           0 :         if ( nImageHeight > nMaxImageSize )
    1511           0 :             nMaxImageSize = nImageHeight;
    1512             : 
    1513             :         // add width
    1514           0 :         aSize.Width() += pItem->mnSize;
    1515             :     }
    1516             : 
    1517          82 :     if ( nMaxImageSize > aSize.Height() )
    1518           0 :         aSize.Height() = nMaxImageSize;
    1519             : 
    1520             :     // add border
    1521          82 :     if ( mbButtonStyle )
    1522          82 :         aSize.Height() += 4;
    1523             :     else
    1524           0 :         aSize.Height() += 2;
    1525          82 :     aSize.Height() += mnBorderOff1+mnBorderOff2;
    1526             : 
    1527          82 :     return aSize;
    1528             : }
    1529             : 
    1530           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HeaderBar::CreateAccessible()
    1531             : {
    1532           0 :     if ( !mxAccessible.is() )
    1533             :     {
    1534           0 :         if ( maCreateAccessibleHdl.IsSet() )
    1535           0 :             maCreateAccessibleHdl.Call( this );
    1536             : 
    1537           0 :         if ( !mxAccessible.is() )
    1538           0 :             mxAccessible = Window::CreateAccessible();
    1539             :     }
    1540             : 
    1541           0 :     return mxAccessible;
    1542             : }
    1543             : 
    1544           0 : void HeaderBar::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > _xAccessible )
    1545             : {
    1546           0 :     mxAccessible = _xAccessible;
    1547           0 : }
    1548             : 
    1549           0 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > HeaderBar::GetComponentInterface( bool bCreate )
    1550             : {
    1551             :     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer
    1552           0 :         (Window::GetComponentInterface(false));
    1553           0 :     if ( !xPeer.is() && bCreate )
    1554             :     {
    1555           0 :         ::com::sun::star::awt::XWindowPeer* mxPeer = new VCLXHeaderBar(this);
    1556           0 :         m_pVCLXHeaderBar = static_cast<VCLXHeaderBar*>(mxPeer);
    1557           0 :         SetComponentInterface(mxPeer);
    1558           0 :         return mxPeer;
    1559             :     }
    1560             :     else
    1561           0 :         return xPeer;
    1562        1227 : }
    1563             : 
    1564             : 
    1565             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10