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

Generated by: LCOV version 1.11