LCOV - code coverage report
Current view: top level - svtools/source/control - tabbar.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 668 1358 49.2 %
Date: 2015-06-13 12:38:46 Functions: 74 139 53.2 %
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             : 
      21             : #include <svtools/tabbar.hxx>
      22             : #include <tools/time.hxx>
      23             : #include <tools/debug.hxx>
      24             : #include <tools/poly.hxx>
      25             : #include <vcl/svapp.hxx>
      26             : #include <vcl/help.hxx>
      27             : #include <vcl/decoview.hxx>
      28             : #include <vcl/button.hxx>
      29             : #include <vcl/edit.hxx>
      30             : #include <vcl/image.hxx>
      31             : #include <vcl/settings.hxx>
      32             : #include "svtaccessiblefactory.hxx"
      33             : #include <filectrl.hrc>
      34             : #include <svtools/svtresid.hxx>
      35             : #include <svtools/svtools.hrc>
      36             : #include <limits>
      37             : #include <utility>
      38             : 
      39             : namespace
      40             : {
      41             : 
      42             : #define TABBAR_DRAG_SCROLLOFF   5
      43             : #define TABBAR_MINSIZE          5
      44             : 
      45             : const sal_uInt16 ADDNEWPAGE_AREAWIDTH = 10;
      46             : const sal_uInt16 BUTTON_MARGIN = 6;
      47             : 
      48             : class TabDrawer
      49             : {
      50             : private:
      51             :     TabBar& mrParent;
      52             :     vcl::RenderContext& mrRenderContext;
      53             :     const StyleSettings&  mrStyleSettings;
      54             : 
      55             :     Rectangle maRect;
      56             : 
      57             :     Color maSelectedColor;
      58             :     Color maCustomColor;
      59             :     Color maUnselectedColor;
      60             : 
      61             :     bool mbSelected:1;
      62             :     bool mbCustomColored:1;
      63             :     bool mbSpecialTab:1;
      64             :     bool mbEnabled:1;
      65             : 
      66             : public:
      67         409 :     explicit TabDrawer(TabBar& rParent, vcl::RenderContext& rRenderContext)
      68             :         : mrParent(rParent)
      69             :         , mrRenderContext(rRenderContext)
      70         409 :         , mrStyleSettings(rRenderContext.GetSettings().GetStyleSettings())
      71             :         , mbSelected(false)
      72             :         , mbCustomColored(false)
      73             :         , mbSpecialTab(false)
      74         818 :         , mbEnabled(false)
      75             :     {
      76         409 :     }
      77             : 
      78         409 :     void drawOutputAreaBorder()
      79             :     {
      80         409 :         WinBits nWinStyle = mrParent.GetStyle();
      81             : 
      82             :         // draw extra line if above and below border
      83         409 :         if ((nWinStyle & WB_BORDER) || (nWinStyle & WB_TOPBORDER))
      84             :         {
      85          91 :             Size aOutputSize = mrRenderContext.GetOutputSizePixel();
      86          91 :             Rectangle aOutRect = mrParent.GetPageArea();
      87             : 
      88             :             // also draw border in 3D for 3D-tabs
      89          91 :             if (nWinStyle & WB_3DTAB)
      90             :             {
      91           0 :                 mrRenderContext.SetLineColor(mrStyleSettings.GetShadowColor());
      92           0 :                 mrRenderContext.DrawLine(Point(aOutRect.Left(), 0), Point(aOutputSize.Width(), 0));
      93             :             }
      94             : 
      95             :             // draw border (line above and line below)
      96          91 :             mrRenderContext.SetLineColor(mrStyleSettings.GetDarkShadowColor());
      97          91 :             mrRenderContext.DrawLine(aOutRect.TopLeft(), Point(aOutputSize.Width() - 1, aOutRect.Top()));
      98             :         }
      99         409 :     }
     100             : 
     101         793 :     void drawOuterFrame()
     102             :     {
     103         793 :         mrRenderContext.SetLineColor(mrStyleSettings.GetDarkShadowColor());
     104             : 
     105             :         // set correct FillInBrush depending on status
     106         793 :         if (mbSelected)
     107             :         {
     108             :             // Currently selected Tab
     109         408 :             mrRenderContext.SetFillColor(maSelectedColor);
     110             :         }
     111         385 :         else if (mbCustomColored)
     112             :         {
     113           0 :             mrRenderContext.SetFillColor(maCustomColor);
     114             :         }
     115             :         else
     116             :         {
     117         385 :             mrRenderContext.SetFillColor(maUnselectedColor);
     118             :         }
     119             : 
     120         793 :         mrRenderContext.DrawRect(maRect);
     121         793 :     }
     122             : 
     123         793 :     void drawText(const OUString& aText)
     124             :     {
     125         793 :         Rectangle aRect = maRect;
     126         793 :         long nTextWidth = mrRenderContext.GetTextWidth(aText);
     127         793 :         long nTextHeight = mrRenderContext.GetTextHeight();
     128         793 :         Point aPos = aRect.TopLeft();
     129         793 :         aPos.X() += (aRect.getWidth()  - nTextWidth) / 2;
     130         793 :         aPos.Y() += (aRect.getHeight() - nTextHeight) / 2;
     131             : 
     132         793 :         if (mbEnabled)
     133         793 :             mrRenderContext.DrawText(aPos, aText);
     134             :         else
     135           0 :             mrRenderContext.DrawCtrlText(aPos, aText, 0, aText.getLength(), (DrawTextFlags::Disable | DrawTextFlags::Mnemonic));
     136         793 :     }
     137             : 
     138         408 :     void drawOverTopBorder()
     139             :     {
     140         408 :         Point aTopLeft  = maRect.TopLeft()  + Point(1, 0);
     141         408 :         Point aTopRight = maRect.TopRight() + Point(-1, 0);
     142             : 
     143         408 :         Rectangle aDelRect(aTopLeft, aTopRight);
     144         408 :         mrRenderContext.DrawRect(aDelRect);
     145         408 :     }
     146             : 
     147           0 :     void drawColorLine()
     148             :     {
     149           0 :         mrRenderContext.SetFillColor(maCustomColor);
     150           0 :         mrRenderContext.SetLineColor(maCustomColor);
     151             : 
     152           0 :         Rectangle aLineRect(maRect.BottomLeft(), maRect.BottomRight());
     153           0 :         aLineRect.Top() -= 3;
     154             : 
     155           0 :         mrRenderContext.DrawRect(aLineRect);
     156           0 :     }
     157             : 
     158         793 :     void drawTab()
     159             :     {
     160         793 :         drawOuterFrame();
     161             : 
     162         793 :         if (mbCustomColored && mbSelected)
     163             :         {
     164           0 :             drawColorLine();
     165             :         }
     166         793 :     }
     167             : 
     168         793 :     void setRect(const Rectangle& rRect)
     169             :     {
     170         793 :         maRect = rRect;
     171         793 :     }
     172             : 
     173         793 :     void setSelected(bool bSelected)
     174             :     {
     175         793 :         mbSelected = bSelected;
     176         793 :     }
     177             : 
     178         793 :     void setCustomColored(bool bCustomColored)
     179             :     {
     180         793 :         mbCustomColored = bCustomColored;
     181         793 :     }
     182             : 
     183         793 :     void setSpecialTab(bool bSpecialTab)
     184             :     {
     185         793 :         mbSpecialTab = bSpecialTab;
     186         793 :     }
     187             : 
     188         793 :     void setEnabled(bool bEnabled)
     189             :     {
     190         793 :         mbEnabled = bEnabled;
     191         793 :     }
     192             : 
     193         409 :     void setSelectedFillColor(const Color& rColor)
     194             :     {
     195         409 :         maSelectedColor = rColor;
     196         409 :     }
     197             : 
     198         409 :     void setUnselectedFillColor(const Color& rColor)
     199             :     {
     200         409 :         maUnselectedColor = rColor;
     201         409 :     }
     202             : 
     203         793 :     void setCustomColor(const Color& rColor)
     204             :     {
     205         793 :         maCustomColor = rColor;
     206         793 :     }
     207             : };
     208             : 
     209             : } // anonymous namespace
     210             : 
     211        2683 : struct ImplTabBarItem
     212             : {
     213             :     sal_uInt16 mnId;
     214             :     TabBarPageBits mnBits;
     215             :     OUString maText;
     216             :     OUString maHelpText;
     217             :     Rectangle maRect;
     218             :     long mnWidth;
     219             :     OString maHelpId;
     220             :     bool mbShort : 1;
     221             :     bool mbSelect : 1;
     222             :     bool mbEnable : 1;
     223             :     Color maTabBgColor;
     224             :     Color maTabTextColor;
     225             : 
     226        2689 :     ImplTabBarItem(sal_uInt16 nItemId, const OUString& rText, TabBarPageBits nPageBits)
     227             :         : mnId(nItemId)
     228             :         , mnBits(nPageBits)
     229             :         , maText(rText)
     230             :         , mnWidth(0)
     231             :         , mbShort(false)
     232             :         , mbSelect(false)
     233             :         , mbEnable(true)
     234             :         , maTabBgColor(Color(COL_AUTO))
     235        2689 :         , maTabTextColor(Color(COL_AUTO))
     236             :     {
     237        2689 :     }
     238             : 
     239         793 :     bool IsDefaultTabBgColor() const
     240             :     {
     241         793 :         return maTabBgColor == Color(COL_AUTO);
     242             :     }
     243             : 
     244         793 :     bool IsSelected(ImplTabBarItem* pCurItem) const
     245             :     {
     246         793 :         return mbSelect || (pCurItem == this);
     247             :     }
     248             : };
     249             : 
     250        3804 : class ImplTabButton : public PushButton
     251             : {
     252             :     bool mbModKey : 1;
     253             : 
     254             : public:
     255        1910 :     ImplTabButton(TabBar* pParent, WinBits nWinStyle = 0)
     256             :         : PushButton(pParent, nWinStyle | WB_FLATBUTTON | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS)
     257        1910 :         , mbModKey(false)
     258        1910 :     {}
     259             : 
     260           0 :     TabBar* GetParent() const
     261             :     {
     262           0 :         return static_cast<TabBar*>(Window::GetParent());
     263             :     }
     264             : 
     265           0 :     bool isModKeyPressed()
     266             :     {
     267           0 :         return mbModKey;
     268             :     }
     269             : 
     270             :     virtual bool PreNotify(NotifyEvent& rNotifyEvent) SAL_OVERRIDE;
     271             :     virtual void MouseButtonDown(const MouseEvent& rMouseEvent) SAL_OVERRIDE;
     272             :     virtual void MouseButtonUp(const MouseEvent& rMouseEvent) SAL_OVERRIDE;
     273             :     virtual void Command(const CommandEvent& rCommandEvent) SAL_OVERRIDE;
     274             : };
     275             : 
     276           0 : void ImplTabButton::MouseButtonDown(const MouseEvent& rMouseEvent)
     277             : {
     278           0 :     mbModKey = rMouseEvent.IsMod1();
     279           0 :     PushButton::MouseButtonDown(rMouseEvent);
     280           0 : }
     281             : 
     282           0 : void ImplTabButton::MouseButtonUp(const MouseEvent& rMouseEvent)
     283             : {
     284           0 :     mbModKey = false;
     285           0 :     PushButton::MouseButtonUp(rMouseEvent);
     286           0 : }
     287             : 
     288           0 : void ImplTabButton::Command(const CommandEvent& rCommandEvent)
     289             : {
     290           0 :     if (rCommandEvent.GetCommand() == CommandEventId::ContextMenu)
     291             :     {
     292           0 :         TabBar* pParent = GetParent();
     293           0 :         pParent->maScrollAreaContextHdl.Call(const_cast<CommandEvent *>(&rCommandEvent));
     294             :     }
     295           0 :     PushButton::Command(rCommandEvent);
     296           0 : }
     297             : 
     298           0 : bool ImplTabButton::PreNotify(NotifyEvent& rNotifyEvent)
     299             : {
     300           0 :     if (rNotifyEvent.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN)
     301             :     {
     302           0 :         if (GetParent()->IsInEditMode())
     303             :         {
     304           0 :             GetParent()->EndEditMode();
     305           0 :             return true;
     306             :         }
     307             :     }
     308             : 
     309           0 :     return PushButton::PreNotify(rNotifyEvent);
     310             : }
     311             : 
     312         266 : class ImplTabSizer : public vcl::Window
     313             : {
     314             : public:
     315             :                     ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 );
     316             : 
     317           0 :     TabBar*         GetParent() const { return static_cast<TabBar*>(Window::GetParent()); }
     318             : 
     319             : private:
     320             :     void            ImplTrack( const Point& rScreenPos );
     321             : 
     322             :     virtual void    dispose() SAL_OVERRIDE;
     323             :     virtual void    MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     324             :     virtual void    Tracking( const TrackingEvent& rTEvt ) SAL_OVERRIDE;
     325             :     virtual void    Paint( vcl::RenderContext& /*rRenderContext*/, const Rectangle& rRect ) SAL_OVERRIDE;
     326             : 
     327             :     Point           maStartPos;
     328             :     long            mnStartWidth;
     329             : };
     330             : 
     331         133 : ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle )
     332             :     : Window( pParent, nWinStyle & WB_3DLOOK )
     333         133 :     , mnStartWidth(0)
     334             : {
     335         133 :     sal_Int32 nScaleFactor = GetDPIScaleFactor();
     336         133 :     SetPointer(Pointer(PointerStyle::HSizeBar));
     337         133 :     SetSizePixel(Size(7 * nScaleFactor, 0));
     338         133 : }
     339             : 
     340         133 : void ImplTabSizer::dispose()
     341             : {
     342         133 :     vcl::Window::dispose();
     343         133 : }
     344             : 
     345           0 : void ImplTabSizer::ImplTrack( const Point& rScreenPos )
     346             : {
     347           0 :     TabBar* pParent = GetParent();
     348           0 :     long nDiff = rScreenPos.X() - maStartPos.X();
     349           0 :     pParent->mnSplitSize = mnStartWidth + (pParent->IsMirrored() ? -nDiff : nDiff);
     350           0 :     if ( pParent->mnSplitSize < TABBAR_MINSIZE )
     351           0 :         pParent->mnSplitSize = TABBAR_MINSIZE;
     352           0 :     pParent->Split();
     353           0 :     pParent->Update();
     354           0 : }
     355             : 
     356           0 : void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt )
     357             : {
     358           0 :     if ( GetParent()->IsInEditMode() )
     359             :     {
     360           0 :         GetParent()->EndEditMode();
     361           0 :         return;
     362             :     }
     363             : 
     364           0 :     if ( rMEvt.IsLeft() )
     365             :     {
     366           0 :         maStartPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
     367           0 :         mnStartWidth = GetParent()->GetSizePixel().Width();
     368           0 :         StartTracking();
     369             :     }
     370             : }
     371             : 
     372           0 : void ImplTabSizer::Tracking( const TrackingEvent& rTEvt )
     373             : {
     374           0 :     if ( rTEvt.IsTrackingEnded() )
     375             :     {
     376           0 :         if ( rTEvt.IsTrackingCanceled() )
     377           0 :             ImplTrack( maStartPos );
     378           0 :         GetParent()->mnSplitSize = 0;
     379             :     }
     380             :     else
     381           0 :         ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
     382           0 : }
     383             : 
     384           0 : void ImplTabSizer::Paint( vcl::RenderContext& rRenderContext, const Rectangle& )
     385             : {
     386           0 :     DecorationView aDecoView(&rRenderContext);
     387           0 :     Rectangle aOutputRect(Point(0, 0), rRenderContext.GetOutputSizePixel());
     388           0 :     aDecoView.DrawHandle(aOutputRect, true);
     389           0 : }
     390             : 
     391             : // Is not named Impl. as it may be both instantiated and derived from
     392           0 : class TabBarEdit : public Edit
     393             : {
     394             : private:
     395             :     Idle            maLoseFocusIdle;
     396             :     bool            mbPostEvt;
     397             : 
     398             :                     DECL_LINK( ImplEndEditHdl, void* );
     399             :                     DECL_LINK_TYPED( ImplEndTimerHdl, Idle*, void );
     400             : 
     401             : public:
     402             :                     TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 );
     403             : 
     404           0 :     TabBar*         GetParent() const { return static_cast<TabBar*>(Window::GetParent()); }
     405             : 
     406           0 :     void            SetPostEvent() { mbPostEvt = true; }
     407           0 :     void            ResetPostEvent() { mbPostEvt = false; }
     408             : 
     409             :     virtual bool    PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
     410             :     virtual void    LoseFocus() SAL_OVERRIDE;
     411             : };
     412             : 
     413           0 : TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) :
     414           0 :     Edit( pParent, nWinStyle )
     415             : {
     416           0 :     mbPostEvt = false;
     417           0 : }
     418             : 
     419           0 : bool TabBarEdit::PreNotify( NotifyEvent& rNEvt )
     420             : {
     421           0 :     if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
     422             :     {
     423           0 :         const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
     424           0 :         if ( !pKEvt->GetKeyCode().GetModifier() )
     425             :         {
     426           0 :             if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
     427             :             {
     428           0 :                 if ( !mbPostEvt )
     429             :                 {
     430           0 :                     if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), reinterpret_cast<void*>(sal_False), true ) )
     431           0 :                         mbPostEvt = true;
     432             :                 }
     433           0 :                 return true;
     434             :             }
     435           0 :             else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE )
     436             :             {
     437           0 :                 if ( !mbPostEvt )
     438             :                 {
     439           0 :                     if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), reinterpret_cast<void*>(sal_True), true ) )
     440           0 :                         mbPostEvt = true;
     441             :                 }
     442           0 :                 return true;
     443             :             }
     444             :         }
     445             :     }
     446             : 
     447           0 :     return Edit::PreNotify( rNEvt );
     448             : }
     449             : 
     450           0 : void TabBarEdit::LoseFocus()
     451             : {
     452           0 :     if ( !mbPostEvt )
     453             :     {
     454           0 :         if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), reinterpret_cast<void*>(sal_False), true ) )
     455           0 :             mbPostEvt = true;
     456             :     }
     457             : 
     458           0 :     Edit::LoseFocus();
     459           0 : }
     460             : 
     461           0 : IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel )
     462             : {
     463           0 :     ResetPostEvent();
     464           0 :     maLoseFocusIdle.Stop();
     465             : 
     466             :     // We need this query, because the edit gets a losefocus event,
     467             :     // when it shows the context menu or the insert symbol dialog
     468           0 :     if ( !HasFocus() && HasChildPathFocus( true ) )
     469             :     {
     470           0 :         maLoseFocusIdle.SetPriority( SchedulerPriority::REPAINT );
     471           0 :         maLoseFocusIdle.SetIdleHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) );
     472           0 :         maLoseFocusIdle.Start();
     473             :     }
     474             :     else
     475           0 :         GetParent()->EndEditMode( pCancel != 0 );
     476             : 
     477           0 :     return 0;
     478             : }
     479             : 
     480           0 : IMPL_LINK_NOARG_TYPED(TabBarEdit, ImplEndTimerHdl, Idle *, void)
     481             : {
     482           0 :     if ( HasFocus() )
     483           0 :         return;
     484             : 
     485             :     // We need this query, because the edit gets a losefocus event,
     486             :     // when it shows the context menu or the insert symbol dialog
     487           0 :     if ( HasChildPathFocus( true ) )
     488           0 :         maLoseFocusIdle.Start();
     489             :     else
     490           0 :         GetParent()->EndEditMode( true );
     491             : }
     492             : 
     493             : struct TabBar_Impl
     494             : {
     495             :     ScopedVclPtr<ImplTabSizer>  mpSizer;
     496             :     ScopedVclPtr<ImplTabButton> mpFirstButton;
     497             :     ScopedVclPtr<ImplTabButton> mpPrevButton;
     498             :     ScopedVclPtr<ImplTabButton> mpNextButton;
     499             :     ScopedVclPtr<ImplTabButton> mpLastButton;
     500             :     ScopedVclPtr<ImplTabButton> mpAddButton;
     501             :     ScopedVclPtr<TabBarEdit>    mpEdit;
     502             :     ImplTabBarList              mpItemList;
     503             : 
     504             :     svt::AccessibleFactoryAccess  maAccessibleFactory;
     505             : 
     506         567 :     TabBar_Impl() {}
     507             : 
     508         564 :     ~TabBar_Impl()
     509         564 :     {
     510        1521 :         for (size_t i = 0; i < mpItemList.size(); ++i)
     511             :         {
     512         957 :             delete mpItemList[i];
     513             :         }
     514         564 :         mpItemList.clear();
     515         564 :     }
     516             : 
     517        6699 :     sal_uInt16 getItemSize()
     518             :     {
     519        6699 :         return static_cast<sal_uInt16>(mpItemList.size());
     520             :     }
     521             : };
     522             : 
     523         567 : TabBar::TabBar( vcl::Window* pParent, WinBits nWinStyle ) :
     524         567 :     Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
     525             : {
     526         567 :     ImplInit( nWinStyle );
     527         567 :     maCurrentItemList = 0;
     528         567 : }
     529             : 
     530        1128 : TabBar::~TabBar()
     531             : {
     532         564 :     disposeOnce();
     533         564 : }
     534             : 
     535         564 : void TabBar::dispose()
     536             : {
     537         564 :     EndEditMode( true );
     538         564 :     mpImpl.reset();
     539         564 :     Window::dispose();
     540         564 : }
     541             : 
     542             : const sal_uInt16 TabBar::APPEND         = ::std::numeric_limits<sal_uInt16>::max();
     543             : const sal_uInt16 TabBar::PAGE_NOT_FOUND = ::std::numeric_limits<sal_uInt16>::max();
     544             : 
     545         567 : void TabBar::ImplInit( WinBits nWinStyle )
     546             : {
     547         567 :     mpImpl.reset(new TabBar_Impl);
     548             : 
     549         567 :     mnMaxPageWidth  = 0;
     550         567 :     mnCurMaxWidth   = 0;
     551         567 :     mnOffX          = 0;
     552         567 :     mnOffY          = 0;
     553         567 :     mnLastOffX      = 0;
     554         567 :     mnSplitSize     = 0;
     555         567 :     mnSwitchTime    = 0;
     556         567 :     mnWinStyle      = nWinStyle;
     557         567 :     mnCurPageId     = 0;
     558         567 :     mnFirstPos      = 0;
     559         567 :     mnDropPos       = 0;
     560         567 :     mnSwitchId      = 0;
     561         567 :     mnEditId        = 0;
     562         567 :     mbFormat        = true;
     563         567 :     mbFirstFormat   = true;
     564         567 :     mbSizeFormat    = true;
     565         567 :     mbAutoMaxWidth  = true;
     566         567 :     mbInSwitching   = false;
     567         567 :     mbAutoEditMode  = false;
     568         567 :     mbEditCanceled  = false;
     569         567 :     mbDropPos       = false;
     570         567 :     mbInSelect      = false;
     571         567 :     mbSelColor      = false;
     572         567 :     mbSelTextColor  = false;
     573         567 :     mbMirrored      = false;
     574         567 :     mbScrollAlwaysEnabled = false;
     575             : 
     576         567 :     if ( nWinStyle & WB_3DTAB )
     577           0 :         mnOffY++;
     578             : 
     579         567 :     ImplInitControls();
     580             : 
     581         567 :     if (mpImpl->mpFirstButton)
     582         219 :         mpImpl->mpFirstButton->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVET0HOME));
     583         567 :     if (mpImpl->mpPrevButton)
     584         567 :         mpImpl->mpPrevButton->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVELEFT));
     585         567 :     if (mpImpl->mpNextButton)
     586         567 :         mpImpl->mpNextButton->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVERIGHT));
     587         567 :     if (mpImpl->mpLastButton)
     588         219 :         mpImpl->mpLastButton->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVETOEND));
     589             : 
     590         567 :     if (mpImpl->mpAddButton)
     591           0 :         mpImpl->mpAddButton->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_ADDTAB));
     592             : 
     593         567 :     SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
     594         567 :     ImplInitSettings( true, true );
     595         567 : }
     596             : 
     597         818 : ImplTabBarItem* TabBar::seek( size_t i )
     598             : {
     599         818 :     if ( i < mpImpl->mpItemList.size() )
     600             :     {
     601         818 :         maCurrentItemList = i;
     602         818 :         return mpImpl->mpItemList[maCurrentItemList];
     603             :     }
     604           0 :     return NULL;
     605             : }
     606             : 
     607         794 : ImplTabBarItem* TabBar::prev()
     608             : {
     609         794 :     if ( maCurrentItemList > 0 )
     610             :     {
     611         385 :         return mpImpl->mpItemList[--maCurrentItemList];
     612             :     }
     613         409 :     return NULL;
     614             : }
     615             : 
     616         559 : ImplTabBarItem* TabBar::next()
     617             : {
     618         559 :     if ( maCurrentItemList + 1 < mpImpl->mpItemList.size() )
     619             :     {
     620         151 :         return mpImpl->mpItemList[++maCurrentItemList];
     621             :     }
     622         408 :     return NULL;
     623             : }
     624             : 
     625        2754 : void TabBar::ImplInitSettings( bool bFont, bool bBackground )
     626             : {
     627             :     // FIXME RenderContext
     628             : 
     629        2754 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     630             : 
     631        2754 :     if (bFont)
     632             :     {
     633        2754 :         vcl::Font aToolFont;
     634        2754 :         aToolFont = rStyleSettings.GetToolFont();
     635        2754 :         aToolFont.SetWeight( WEIGHT_BOLD );
     636        2754 :         ApplyControlFont(*this, aToolFont);
     637             : 
     638             :         // Adapt font size if window too small?
     639        8408 :         while (GetTextHeight() > (GetOutputSizePixel().Height() - 1))
     640             :         {
     641        3478 :             vcl::Font aFont = GetFont();
     642        3478 :             if (aFont.GetHeight() <= 6)
     643         578 :                 break;
     644        2900 :             aFont.SetHeight(aFont.GetHeight() - 1);
     645        2900 :             SetFont(aFont);
     646        5654 :         }
     647             :     }
     648             : 
     649        2754 :     if (bBackground)
     650             :     {
     651         599 :         ApplyControlBackground(*this, rStyleSettings.GetFaceColor());
     652             :     }
     653        2754 : }
     654             : 
     655         409 : void TabBar::ImplGetColors(const StyleSettings& rStyleSettings,
     656             :                            Color& rFaceColor, Color& rFaceTextColor,
     657             :                            Color& rSelectColor, Color& rSelectTextColor)
     658             : {
     659         409 :     if (IsControlBackground())
     660           0 :         rFaceColor = GetControlBackground();
     661             :     else
     662         409 :         rFaceColor = rStyleSettings.GetInactiveTabColor();
     663         409 :     if (IsControlForeground())
     664           0 :         rFaceTextColor = GetControlForeground();
     665             :     else
     666         409 :         rFaceTextColor = rStyleSettings.GetButtonTextColor();
     667         409 :     if (mbSelColor)
     668           0 :         rSelectColor = maSelColor;
     669             :     else
     670         409 :         rSelectColor = rStyleSettings.GetActiveTabColor();
     671         409 :     if (mbSelTextColor)
     672           0 :         rSelectTextColor = maSelTextColor;
     673             :     else
     674         409 :         rSelectTextColor = rStyleSettings.GetWindowTextColor();
     675             : 
     676             :     // For 3D-tabs the selection- and face-colours are swapped,
     677             :     // as the selected tabs should appear in 3D
     678         409 :     if (mnWinStyle & WB_3DTAB)
     679             :     {
     680             :         using std::swap;
     681           0 :         swap(rFaceColor, rSelectColor);
     682           0 :         swap(rFaceTextColor, rSelectTextColor);
     683             :     }
     684         409 : }
     685             : 
     686        4541 : bool TabBar::ImplCalcWidth()
     687             : {
     688             :     // Sizes should only be retrieved if the text or the font was changed
     689        4541 :     if (!mbSizeFormat)
     690        2551 :         return false;
     691             : 
     692             :     // retrieve width of tabs with bold font
     693        1990 :     vcl::Font aFont = GetFont();
     694        1990 :     if (aFont.GetWeight() != WEIGHT_BOLD)
     695             :     {
     696           0 :         aFont.SetWeight(WEIGHT_BOLD);
     697           0 :         SetFont(aFont);
     698             :     }
     699             : 
     700        1990 :     if (mnMaxPageWidth)
     701         329 :         mnCurMaxWidth = mnMaxPageWidth;
     702        1661 :     else if (mbAutoMaxWidth)
     703             :     {
     704        1661 :         mnCurMaxWidth = mnLastOffX - mnOffX;
     705        1661 :         if (mnCurMaxWidth < 1)
     706           0 :             mnCurMaxWidth = 1;
     707             :     }
     708             :     else
     709           0 :         mnCurMaxWidth = 0;
     710             : 
     711        1990 :     bool bChanged = false;
     712        5894 :     for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
     713             :     {
     714        3904 :         ImplTabBarItem* pItem = mpImpl->mpItemList[i];
     715        3904 :         long nNewWidth = GetTextWidth(pItem->maText);
     716        3904 :         if (mnCurMaxWidth && (nNewWidth > mnCurMaxWidth))
     717             :         {
     718           2 :             pItem->mbShort = true;
     719           2 :             nNewWidth = mnCurMaxWidth;
     720             :         }
     721             :         else
     722             :         {
     723        3902 :             pItem->mbShort = false;
     724             :         }
     725             : 
     726             :         // Padding is dependent on font height - bigger font = bigger padding
     727        3904 :         long nFontWidth = aFont.GetHeight();
     728        3904 :         nNewWidth += nFontWidth * 2;
     729             : 
     730        3904 :         if (pItem->mnWidth != nNewWidth)
     731             :         {
     732        1448 :             pItem->mnWidth = nNewWidth;
     733        1448 :             if (!pItem->maRect.IsEmpty())
     734         150 :                 bChanged = true;
     735             :         }
     736             :     }
     737        1990 :     mbSizeFormat = false;
     738        1990 :     mbFormat = true;
     739        1990 :     return bChanged;
     740             : }
     741             : 
     742        3379 : void TabBar::ImplFormat()
     743             : {
     744        3379 :     ImplCalcWidth();
     745             : 
     746        3379 :     if (!mbFormat)
     747        4666 :         return;
     748             : 
     749        2092 :     sal_uInt16 n = 0;
     750        2092 :     long x = mnOffX;
     751        6334 :     for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
     752             :     {
     753        4242 :         ImplTabBarItem* pItem = mpImpl->mpItemList[i];
     754             :         // At all non-visible tabs an empty rectangle is set
     755        4242 :         if ((n + 1 < mnFirstPos) || (x > mnLastOffX))
     756         555 :             pItem->maRect.SetEmpty();
     757             :         else
     758             :         {
     759             :             // Slightly before the tab before the first visible page
     760             :             // should also be visible
     761        3687 :             if (n + 1 == mnFirstPos)
     762          20 :                 pItem->maRect.Left() = x-pItem->mnWidth;
     763             :             else
     764             :             {
     765        3667 :                 pItem->maRect.Left() = x;
     766        3667 :                 x += pItem->mnWidth;
     767             :             }
     768        3687 :             pItem->maRect.Right() = x;
     769        3687 :             pItem->maRect.Bottom() = maWinSize.Height() - 1;
     770             : 
     771        3687 :             if (mbMirrored)
     772             :             {
     773           1 :                 long nTmp = mnOffX + mnLastOffX - pItem->maRect.Right();
     774           1 :                 pItem->maRect.Right() = mnOffX + mnLastOffX - pItem->maRect.Left();
     775           1 :                 pItem->maRect.Left() = nTmp;
     776             :             }
     777             :         }
     778             : 
     779        4242 :         n++;
     780             :     }
     781             : 
     782        2092 :     mbFormat = false;
     783             : 
     784             :     //  enable/disable button
     785        2092 :     ImplEnableControls();
     786             : }
     787             : 
     788        1566 : sal_uInt16 TabBar::ImplGetLastFirstPos()
     789             : {
     790        1566 :     sal_uInt16 nCount = mpImpl->getItemSize();
     791        1566 :     if (!nCount || mbSizeFormat || mbFormat)
     792           6 :         return 0;
     793             : 
     794        1560 :     sal_uInt16  nLastFirstPos = nCount - 1;
     795        1560 :     long nWinWidth = mnLastOffX - mnOffX - ADDNEWPAGE_AREAWIDTH;
     796        1560 :     long nWidth = mpImpl->mpItemList[nLastFirstPos]->mnWidth;
     797             : 
     798        4801 :     while (nLastFirstPos && (nWidth < nWinWidth))
     799             :     {
     800        1681 :         nLastFirstPos--;
     801        1681 :         nWidth += mpImpl->mpItemList[nLastFirstPos]->mnWidth;
     802             :     }
     803        1560 :     if ((nLastFirstPos != static_cast<sal_uInt16>(mpImpl->mpItemList.size() - 1)) && (nWidth > nWinWidth))
     804         221 :         nLastFirstPos++;
     805        1560 :     return nLastFirstPos;
     806             : }
     807             : 
     808        1860 : void TabBar::ImplInitControls()
     809             : {
     810        1860 :     if (mnWinStyle & WB_SIZEABLE)
     811             :     {
     812         133 :         if (!mpImpl->mpSizer)
     813             :         {
     814         133 :             mpImpl->mpSizer.reset(VclPtr<ImplTabSizer>::Create( this, mnWinStyle & (WB_DRAG | WB_3DLOOK)));
     815             :         }
     816         133 :         mpImpl->mpSizer->Show();
     817             :     }
     818             :     else
     819             :     {
     820        1727 :         mpImpl->mpSizer.disposeAndClear();
     821             :     }
     822             : 
     823        1860 :     if ((mnWinStyle & WB_INSERTTAB) && !mpImpl->mpAddButton)
     824             :     {
     825         338 :         Link<> aLink = LINK(this, TabBar, ImplAddClickHandler);
     826         338 :         mpImpl->mpAddButton.reset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT));
     827         338 :         mpImpl->mpAddButton->SetClickHdl(aLink);
     828         338 :         mpImpl->mpAddButton->SetSymbol(SymbolType::PLUS);
     829         338 :         mpImpl->mpAddButton->Show();
     830             :     }
     831             : 
     832        1860 :     Link<> aLink = LINK( this, TabBar, ImplClickHdl );
     833             : 
     834        1860 :     if (mnWinStyle & (WB_MINSCROLL | WB_SCROLL))
     835             :     {
     836        1860 :         if (!mpImpl->mpPrevButton)
     837             :         {
     838         567 :             mpImpl->mpPrevButton.reset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT));
     839         567 :             mpImpl->mpPrevButton->SetClickHdl(aLink);
     840             :         }
     841        1860 :         mpImpl->mpPrevButton->SetSymbol(mbMirrored ? SymbolType::NEXT : SymbolType::PREV);
     842        1860 :         mpImpl->mpPrevButton->Show();
     843             : 
     844        1860 :         if (!mpImpl->mpNextButton)
     845             :         {
     846         567 :             mpImpl->mpNextButton.reset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT));
     847         567 :             mpImpl->mpNextButton->SetClickHdl(aLink);
     848             :         }
     849        1860 :         mpImpl->mpNextButton->SetSymbol(mbMirrored ? SymbolType::PREV : SymbolType::NEXT);
     850        1860 :         mpImpl->mpNextButton->Show();
     851             :     }
     852             :     else
     853             :     {
     854           0 :         mpImpl->mpPrevButton.disposeAndClear();
     855           0 :         mpImpl->mpNextButton.disposeAndClear();
     856             :     }
     857             : 
     858        1860 :     if (mnWinStyle & WB_SCROLL)
     859             :     {
     860         219 :         if (!mpImpl->mpFirstButton)
     861             :         {
     862         219 :             mpImpl->mpFirstButton.reset(VclPtr<ImplTabButton>::Create(this));
     863         219 :             mpImpl->mpFirstButton->SetClickHdl(aLink);
     864             :         }
     865         219 :         mpImpl->mpFirstButton->SetSymbol(mbMirrored ? SymbolType::LAST : SymbolType::FIRST);
     866         219 :         mpImpl->mpFirstButton->Show();
     867             : 
     868         219 :         if (!mpImpl->mpLastButton)
     869             :         {
     870         219 :             mpImpl->mpLastButton.reset(VclPtr<ImplTabButton>::Create(this));
     871         219 :             mpImpl->mpLastButton->SetClickHdl(aLink);
     872             :         }
     873         219 :         mpImpl->mpLastButton->SetSymbol(mbMirrored ? SymbolType::FIRST : SymbolType::LAST);
     874         219 :         mpImpl->mpLastButton->Show();
     875             :     }
     876             :     else
     877             :     {
     878        1641 :         mpImpl->mpFirstButton.disposeAndClear();
     879        1641 :         mpImpl->mpLastButton.disposeAndClear();
     880             :     }
     881        1860 : }
     882             : 
     883        4595 : void TabBar::ImplEnableControls()
     884             : {
     885        4595 :     if (mbSizeFormat || mbFormat)
     886        5936 :         return;
     887             : 
     888             :     // enable/disable buttons
     889        3254 :     bool bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos > 0;
     890        3254 :     if (mpImpl->mpFirstButton)
     891         386 :         mpImpl->mpFirstButton->Enable(bEnableBtn);
     892        3254 :     if (mpImpl->mpPrevButton)
     893        3254 :         mpImpl->mpPrevButton->Enable(bEnableBtn);
     894             : 
     895        3254 :     bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos < ImplGetLastFirstPos();
     896        3254 :     if (mpImpl->mpNextButton)
     897        3254 :         mpImpl->mpNextButton->Enable(bEnableBtn);
     898        3254 :     if (mpImpl->mpLastButton)
     899         386 :         mpImpl->mpLastButton->Enable(bEnableBtn);
     900             : }
     901             : 
     902         348 : void TabBar::SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled)
     903             : {
     904         348 :     mbScrollAlwaysEnabled = bScrollAlwaysEnabled;
     905         348 :     ImplEnableControls();
     906         348 : }
     907             : 
     908        1162 : void TabBar::ImplShowPage( sal_uInt16 nPos )
     909             : {
     910        1162 :     if (nPos >= mpImpl->getItemSize())
     911        1164 :         return;
     912             : 
     913             :     // calculate width
     914        1160 :     long nWidth = GetOutputSizePixel().Width();
     915             : 
     916        1160 :     ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
     917        1160 :     if (nPos < mnFirstPos)
     918           0 :         SetFirstPageId( pItem->mnId );
     919        1160 :     else if (pItem->maRect.Right() > nWidth)
     920             :     {
     921          12 :         while (pItem->maRect.Right() > nWidth)
     922             :         {
     923           6 :             sal_uInt16 nNewPos = mnFirstPos + 1;
     924           6 :             SetFirstPageId(GetPageId(nNewPos));
     925           6 :             ImplFormat();
     926           6 :             if (nNewPos != mnFirstPos)
     927           6 :                 break;
     928             :         }
     929             :     }
     930             : }
     931             : 
     932           0 : IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn )
     933             : {
     934           0 :     EndEditMode();
     935             : 
     936           0 :     sal_uInt16 nNewPos = mnFirstPos;
     937             : 
     938           0 :     if (pBtn == mpImpl->mpFirstButton.get() || (pBtn == mpImpl->mpPrevButton.get() && pBtn->isModKeyPressed()))
     939             :     {
     940           0 :         nNewPos = 0;
     941             :     }
     942           0 :     else if (pBtn == mpImpl->mpLastButton.get() || (pBtn == mpImpl->mpNextButton.get() && pBtn->isModKeyPressed()))
     943             :     {
     944           0 :         sal_uInt16 nCount = GetPageCount();
     945           0 :         if (nCount)
     946           0 :             nNewPos = nCount - 1;
     947             :     }
     948           0 :     else if (pBtn == mpImpl->mpPrevButton.get())
     949             :     {
     950           0 :         if (mnFirstPos)
     951           0 :             nNewPos = mnFirstPos - 1;
     952             :     }
     953           0 :     else if (pBtn == mpImpl->mpNextButton.get())
     954             :     {
     955           0 :         sal_uInt16 nCount = GetPageCount();
     956           0 :         if (mnFirstPos <  nCount)
     957           0 :             nNewPos = mnFirstPos+1;
     958             :     }
     959             :     else
     960             :     {
     961           0 :         return 0;
     962             :     }
     963             : 
     964           0 :     if (nNewPos != mnFirstPos)
     965           0 :         SetFirstPageId(GetPageId(nNewPos));
     966             : 
     967           0 :     return 0;
     968             : }
     969             : 
     970           0 : IMPL_LINK_NOARG(TabBar, ImplAddClickHandler)
     971             : {
     972           0 :     AddTabClick();
     973           0 :     return 0;
     974             : }
     975             : 
     976           0 : void TabBar::MouseMove(const MouseEvent& rMEvt)
     977             : {
     978           0 :     if (rMEvt.IsLeaveWindow())
     979           0 :         mbInSelect = false;
     980             : 
     981           0 :     Window::MouseMove(rMEvt);
     982           0 : }
     983             : 
     984           0 : void TabBar::MouseButtonDown(const MouseEvent& rMEvt)
     985             : {
     986             :     // Only terminate EditModus and do not execute click
     987             :     // if clicked inside our window,
     988           0 :     if (IsInEditMode())
     989             :     {
     990           0 :         EndEditMode();
     991           0 :         return;
     992             :     }
     993             : 
     994             :     ImplTabBarItem* pItem;
     995           0 :     sal_uInt16 nSelId = GetPageId(rMEvt.GetPosPixel());
     996             : 
     997           0 :     if (!rMEvt.IsLeft())
     998             :     {
     999           0 :         Window::MouseButtonDown(rMEvt);
    1000           0 :         if (nSelId > 0 && nSelId != mnCurPageId)
    1001             :         {
    1002           0 :             sal_uInt16 nPos = GetPagePos( nSelId );
    1003           0 :             pItem = mpImpl->mpItemList[nPos];
    1004             : 
    1005           0 :             if (pItem->mbEnable)
    1006             :             {
    1007           0 :                 if (ImplDeactivatePage())
    1008             :                 {
    1009           0 :                     SetCurPageId(nSelId);
    1010           0 :                     Update();
    1011           0 :                     ImplActivatePage();
    1012           0 :                     ImplSelect();
    1013             :                 }
    1014           0 :                 mbInSelect = true;
    1015             :             }
    1016             :         }
    1017           0 :         return;
    1018             :     }
    1019             : 
    1020           0 :     if (rMEvt.IsMod2() && mbAutoEditMode && nSelId)
    1021             :     {
    1022           0 :         if (StartEditMode(nSelId))
    1023           0 :             return;
    1024             :     }
    1025             : 
    1026           0 :     if ((rMEvt.GetMode() & (MouseEventModifiers::MULTISELECT | MouseEventModifiers::RANGESELECT)) && (rMEvt.GetClicks() == 1))
    1027             :     {
    1028           0 :         if (nSelId)
    1029             :         {
    1030           0 :             sal_uInt16  nPos = GetPagePos(nSelId);
    1031           0 :             pItem = mpImpl->mpItemList[nPos];
    1032             : 
    1033           0 :             if (pItem->mbEnable)
    1034             :             {
    1035           0 :                 bool bSelectTab = false;
    1036             : 
    1037           0 :                 if ((rMEvt.GetMode() & MouseEventModifiers::MULTISELECT) && (mnWinStyle & WB_MULTISELECT))
    1038             :                 {
    1039           0 :                     if (nSelId != mnCurPageId)
    1040             :                     {
    1041           0 :                         SelectPage(nSelId, !IsPageSelected(nSelId));
    1042           0 :                         bSelectTab = true;
    1043             :                     }
    1044             :                 }
    1045           0 :                 else if (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT))
    1046             :                 {
    1047           0 :                     bSelectTab = true;
    1048             :                     sal_uInt16 n;
    1049             :                     bool bSelect;
    1050           0 :                     sal_uInt16 nCurPos = GetPagePos(mnCurPageId);
    1051           0 :                     if (nPos <= nCurPos)
    1052             :                     {
    1053             :                         // Deselect all tabs till the clicked tab
    1054             :                         // and select all tabs from the clicked tab
    1055             :                         // 'till the actual position
    1056           0 :                         n = 0;
    1057           0 :                         while (n < nCurPos)
    1058             :                         {
    1059           0 :                             pItem = mpImpl->mpItemList[n];
    1060           0 :                             if (n < nPos)
    1061           0 :                                 bSelect = false;
    1062             :                             else
    1063           0 :                                 bSelect = true;
    1064             : 
    1065           0 :                             if (pItem->mbSelect != bSelect)
    1066             :                             {
    1067           0 :                                 pItem->mbSelect = bSelect;
    1068           0 :                                 if (!pItem->maRect.IsEmpty())
    1069           0 :                                     Invalidate(pItem->maRect);
    1070             :                             }
    1071             : 
    1072           0 :                             n++;
    1073             :                         }
    1074             :                     }
    1075             : 
    1076           0 :                     if (nPos >= nCurPos)
    1077             :                     {
    1078             :                         // Select all tabs from the actual position till the clicked tab
    1079             :                         // and deselect all tabs from the actual position
    1080             :                         // till the last tab
    1081           0 :                         sal_uInt16 nCount = mpImpl->getItemSize();
    1082           0 :                         n = nCurPos;
    1083           0 :                         while (n < nCount)
    1084             :                         {
    1085           0 :                             pItem = mpImpl->mpItemList[n];
    1086             : 
    1087           0 :                             if (n <= nPos)
    1088           0 :                                 bSelect = true;
    1089             :                             else
    1090           0 :                                 bSelect = false;
    1091             : 
    1092           0 :                             if (pItem->mbSelect != bSelect)
    1093             :                             {
    1094           0 :                                 pItem->mbSelect = bSelect;
    1095           0 :                                 if (!pItem->maRect.IsEmpty())
    1096           0 :                                     Invalidate(pItem->maRect);
    1097             :                             }
    1098             : 
    1099           0 :                             n++;
    1100             :                         }
    1101             :                     }
    1102             :                 }
    1103             : 
    1104             :                 // scroll the selected tab if required
    1105           0 :                 if (bSelectTab)
    1106             :                 {
    1107           0 :                     ImplShowPage(nPos);
    1108           0 :                     Update();
    1109           0 :                     ImplSelect();
    1110             :                 }
    1111             :             }
    1112             :             else
    1113           0 :                 ImplShowPage(nPos);
    1114           0 :             mbInSelect = true;
    1115             : 
    1116           0 :             return;
    1117             :         }
    1118             :     }
    1119           0 :     else if (rMEvt.GetClicks() == 2)
    1120             :     {
    1121             :         // call double-click-handler if required
    1122           0 :         if (!rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)))
    1123             :         {
    1124           0 :             sal_uInt16 nOldCurId = mnCurPageId;
    1125           0 :             mnCurPageId = nSelId;
    1126           0 :             DoubleClick();
    1127             :             // check, as actual page could be switched inside
    1128             :             // the doubleclick-handler
    1129           0 :             if (mnCurPageId == nSelId)
    1130           0 :                 mnCurPageId = nOldCurId;
    1131             :         }
    1132             : 
    1133           0 :         return;
    1134             :     }
    1135             :     else
    1136             :     {
    1137           0 :         if (nSelId)
    1138             :         {
    1139             :             // execute Select if not actual page
    1140           0 :             if (nSelId != mnCurPageId)
    1141             :             {
    1142           0 :                 sal_uInt16 nPos = GetPagePos(nSelId);
    1143           0 :                 pItem = mpImpl->mpItemList[nPos];
    1144             : 
    1145           0 :                 if (pItem->mbEnable)
    1146             :                 {
    1147           0 :                     if (!pItem->mbSelect)
    1148             :                     {
    1149             :                         // make not valid
    1150           0 :                         bool bUpdate = false;
    1151           0 :                         if (IsReallyVisible() && IsUpdateMode())
    1152           0 :                             bUpdate = true;
    1153             : 
    1154             :                         // deselect all selected items
    1155           0 :                         for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
    1156             :                         {
    1157           0 :                             pItem = mpImpl->mpItemList[i];
    1158           0 :                             if (pItem->mbSelect || (pItem->mnId == mnCurPageId))
    1159             :                             {
    1160           0 :                                 pItem->mbSelect = false;
    1161           0 :                                 if (bUpdate)
    1162           0 :                                     Invalidate(pItem->maRect);
    1163             :                             }
    1164             :                         }
    1165             :                     }
    1166             : 
    1167           0 :                     if (ImplDeactivatePage())
    1168             :                     {
    1169           0 :                         SetCurPageId(nSelId);
    1170           0 :                         Update();
    1171           0 :                         ImplActivatePage();
    1172           0 :                         ImplSelect();
    1173             :                     }
    1174             :                 }
    1175             :                 else
    1176           0 :                     ImplShowPage(nPos);
    1177           0 :                 mbInSelect = true;
    1178             :             }
    1179             : 
    1180           0 :             return;
    1181             :         }
    1182             :     }
    1183             : 
    1184           0 :     Window::MouseButtonDown(rMEvt);
    1185             : }
    1186             : 
    1187           0 : void TabBar::MouseButtonUp(const MouseEvent& rMEvt)
    1188             : {
    1189           0 :     mbInSelect = false;
    1190           0 :     Window::MouseButtonUp(rMEvt);
    1191           0 : }
    1192             : 
    1193         409 : void TabBar::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rect)
    1194             : {
    1195         409 :     if (rRenderContext.IsNativeControlSupported(CTRL_WINDOW_BACKGROUND,PART_ENTIRE_CONTROL))
    1196             :     {
    1197             :         rRenderContext.DrawNativeControl(CTRL_WINDOW_BACKGROUND,PART_ENTIRE_CONTROL,rect,
    1198           0 :                                          ControlState::ENABLED,ImplControlValue(0),OUString());
    1199             :     }
    1200             :     // calculate items and emit
    1201         409 :     sal_uInt16 nItemCount = mpImpl->getItemSize();
    1202         409 :     if (!nItemCount)
    1203         409 :         return;
    1204             : 
    1205         409 :     ImplPrePaint(rRenderContext);
    1206             : 
    1207         409 :     Color aFaceColor, aSelectColor, aFaceTextColor, aSelectTextColor;
    1208         409 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
    1209         409 :     ImplGetColors(rStyleSettings, aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor);
    1210             : 
    1211         409 :     rRenderContext.Push(PushFlags::FONT | PushFlags::CLIPREGION);
    1212         409 :     rRenderContext.SetClipRegion(vcl::Region(GetPageArea()));
    1213             : 
    1214             :     // select font
    1215         409 :     vcl::Font aFont = rRenderContext.GetFont();
    1216         818 :     vcl::Font aLightFont = aFont;
    1217         409 :     aLightFont.SetWeight(WEIGHT_NORMAL);
    1218             : 
    1219         409 :     TabDrawer aDrawer(*this, rRenderContext);
    1220             : 
    1221         409 :     aDrawer.setSelectedFillColor(aSelectColor);
    1222         409 :     aDrawer.setUnselectedFillColor(aFaceColor);
    1223             : 
    1224         409 :     aDrawer.drawOutputAreaBorder();
    1225             : 
    1226             :     // Now, start drawing the tabs.
    1227             : 
    1228         409 :     ImplTabBarItem* pItem = ImplGetLastTabBarItem(nItemCount);
    1229         409 :     ImplTabBarItem* pCurItem = NULL;
    1230        1612 :     while (pItem)
    1231             :     {
    1232             :         // emit CurrentItem last, as it covers all others
    1233        1203 :         if (!pCurItem && (pItem->mnId == mnCurPageId))
    1234             :         {
    1235         409 :             pCurItem = pItem;
    1236         409 :             pItem = prev();
    1237         409 :             if (!pItem)
    1238         374 :                 pItem = pCurItem;
    1239         409 :             continue;
    1240             :         }
    1241             : 
    1242         794 :         bool bCurrent = pItem == pCurItem;
    1243             : 
    1244         794 :         if (!pItem->maRect.IsEmpty())
    1245             :         {
    1246         793 :             Rectangle aRect = pItem->maRect;
    1247         793 :             bool bSelected = pItem->IsSelected(pCurItem);
    1248             :             // We disable custom background color in high contrast mode.
    1249         793 :             bool bCustomBgColor = !pItem->IsDefaultTabBgColor() && !rStyleSettings.GetHighContrastMode();
    1250         793 :             bool bSpecialTab = (pItem->mnBits & TPB_SPECIAL);
    1251         793 :             bool bEnabled = pItem->mbEnable;
    1252         793 :             OUString aText = pItem->mbShort ? rRenderContext.GetEllipsisString(pItem->maText, mnCurMaxWidth, DrawTextFlags::EndEllipsis) : pItem->maText;
    1253             : 
    1254         793 :             aDrawer.setRect(aRect);
    1255         793 :             aDrawer.setSelected(bSelected);
    1256         793 :             aDrawer.setCustomColored(bCustomBgColor);
    1257         793 :             aDrawer.setSpecialTab(bSpecialTab);
    1258         793 :             aDrawer.setEnabled(bEnabled);
    1259         793 :             aDrawer.setCustomColor(pItem->maTabBgColor);
    1260         793 :             aDrawer.drawTab();
    1261             : 
    1262             :             // actual page is drawn using a bold font
    1263         793 :             if (bCurrent)
    1264         408 :                 rRenderContext.SetFont(aFont);
    1265             :             else
    1266         385 :                 rRenderContext.SetFont(aLightFont);
    1267             : 
    1268             :             // Set the correct FillInBrush depending on status
    1269             : 
    1270         793 :             if (bSelected)
    1271         408 :                 rRenderContext.SetTextColor(aSelectTextColor);
    1272         385 :             else if (bCustomBgColor)
    1273           0 :                 rRenderContext.SetTextColor(pItem->maTabTextColor);
    1274             :             else
    1275         385 :                 rRenderContext.SetTextColor(aFaceTextColor);
    1276             : 
    1277             :             // This tab is "special", and a special tab needs a blue text.
    1278         793 :             if (bSpecialTab)
    1279           0 :                 rRenderContext.SetTextColor(Color(COL_LIGHTBLUE));
    1280             : 
    1281         793 :             aDrawer.drawText(aText);
    1282             : 
    1283         793 :             if (bCurrent)
    1284             :             {
    1285         408 :                 rRenderContext.SetLineColor();
    1286         408 :                 rRenderContext.SetFillColor(aSelectColor);
    1287         408 :                 aDrawer.drawOverTopBorder();
    1288         408 :                 break;
    1289             :             }
    1290             : 
    1291         385 :             pItem = prev();
    1292             :         }
    1293             :         else
    1294             :         {
    1295           1 :             if (bCurrent)
    1296           1 :                 break;
    1297             : 
    1298           0 :             pItem = NULL;
    1299             :         }
    1300             : 
    1301         385 :         if (!pItem)
    1302          35 :             pItem = pCurItem;
    1303             :     }
    1304         818 :     rRenderContext.Pop();
    1305             : }
    1306             : 
    1307        2155 : void TabBar::Resize()
    1308             : {
    1309        2155 :     Size aNewSize = GetOutputSizePixel();
    1310             : 
    1311        2155 :     long nSizerWidth = 0;
    1312        2155 :     long nButtonWidth = 0;
    1313             : 
    1314             :     // Sizer anordnen
    1315        2155 :     if ( mpImpl->mpSizer )
    1316             :     {
    1317         133 :         Size    aSizerSize = mpImpl->mpSizer->GetSizePixel();
    1318         133 :         Point   aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 );
    1319         133 :         Size    aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
    1320         133 :         mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
    1321         133 :         nSizerWidth = aSizerSize.Width();
    1322             :     }
    1323             : 
    1324             :     // order the scroll buttons
    1325        2155 :     long nHeight = aNewSize.Height();
    1326             :     // adapt font height?
    1327        2155 :     ImplInitSettings( true, false );
    1328             : 
    1329        2155 :     long nButtonMargin = BUTTON_MARGIN * GetDPIScaleFactor();
    1330             : 
    1331        2155 :     long nX = mbMirrored ? (aNewSize.Width() - nHeight - nButtonMargin) : nButtonMargin;
    1332        2155 :     long nXDiff = mbMirrored ? -nHeight : nHeight;
    1333             : 
    1334        2155 :     nButtonWidth += nButtonMargin;
    1335             : 
    1336        2155 :     Size aBtnSize( nHeight, nHeight );
    1337        2155 :     if (mpImpl->mpFirstButton)
    1338             :     {
    1339         362 :         mpImpl->mpFirstButton->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
    1340         362 :         nX += nXDiff;
    1341         362 :         nButtonWidth += nHeight;
    1342             :     }
    1343        2155 :     if (mpImpl->mpPrevButton)
    1344             :     {
    1345        2155 :         mpImpl->mpPrevButton->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
    1346        2155 :         nX += nXDiff;
    1347        2155 :         nButtonWidth += nHeight;
    1348             :     }
    1349        2155 :     if (mpImpl->mpNextButton)
    1350             :     {
    1351        2155 :         mpImpl->mpNextButton->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
    1352        2155 :         nX += nXDiff;
    1353        2155 :         nButtonWidth += nHeight;
    1354             :     }
    1355        2155 :     if (mpImpl->mpLastButton)
    1356             :     {
    1357         362 :         mpImpl->mpLastButton->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
    1358         362 :         nX += nXDiff;
    1359         362 :         nButtonWidth += nHeight;
    1360             :     }
    1361             : 
    1362        2155 :     nButtonWidth += nButtonMargin;
    1363        2155 :     nX += mbMirrored ? -nButtonMargin : nButtonMargin;
    1364             : 
    1365        2155 :     if (mpImpl->mpAddButton)
    1366             :     {
    1367        1783 :         mpImpl->mpAddButton->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
    1368        1783 :         nX += nXDiff;
    1369        1783 :         nButtonWidth += nHeight;
    1370             :     }
    1371             : 
    1372        2155 :     nButtonWidth += nButtonMargin;
    1373             : 
    1374             :     // store size
    1375        2155 :     maWinSize = aNewSize;
    1376             : 
    1377        2155 :     if( mbMirrored )
    1378             :     {
    1379           1 :         mnOffX = nSizerWidth;
    1380           1 :         mnLastOffX = maWinSize.Width() - nButtonWidth - 1;
    1381             :     }
    1382             :     else
    1383             :     {
    1384        2154 :         mnOffX = nButtonWidth;
    1385        2154 :         mnLastOffX = maWinSize.Width() - nSizerWidth - 1;
    1386             :     }
    1387             : 
    1388             :     // reformat
    1389        2155 :     mbSizeFormat = true;
    1390        2155 :     if ( IsReallyVisible() )
    1391             :     {
    1392        1162 :         if ( ImplCalcWidth() )
    1393           2 :             Invalidate();
    1394             : 
    1395        1162 :         ImplFormat();
    1396             : 
    1397             :         // Ensure as many tabs as possible are visible:
    1398        1162 :         sal_uInt16 nLastFirstPos = ImplGetLastFirstPos();
    1399        1162 :         if ( mnFirstPos > nLastFirstPos )
    1400             :         {
    1401           1 :             mnFirstPos = nLastFirstPos;
    1402           1 :             mbFormat = true;
    1403           1 :             Invalidate();
    1404             :         }
    1405             :         // Ensure the currently selected page is visible
    1406        1162 :         ImplShowPage(GetPagePos(mnCurPageId));
    1407             : 
    1408        1162 :         ImplFormat();
    1409             :     }
    1410             : 
    1411             :     // enable/disable button
    1412        2155 :     ImplEnableControls();
    1413        2155 : }
    1414             : 
    1415           0 : bool TabBar::PreNotify(NotifyEvent& rNEvt)
    1416             : {
    1417           0 :     if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
    1418             :     {
    1419           0 :         if (rNEvt.GetCommandEvent()->GetCommand() == CommandEventId::Wheel)
    1420             :         {
    1421           0 :             const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
    1422           0 :             sal_uInt16 nNewPos = mnFirstPos;
    1423           0 :             if (pData->GetNotchDelta() > 0)
    1424             :             {
    1425           0 :                 if (mnFirstPos)
    1426           0 :                     nNewPos = mnFirstPos - 1;
    1427             :             }
    1428           0 :             else if (pData->GetNotchDelta() < 0)
    1429             :             {
    1430           0 :                 sal_uInt16 nCount = GetPageCount();
    1431           0 :                 if (mnFirstPos <  nCount)
    1432           0 :                     nNewPos = mnFirstPos + 1;
    1433             :             }
    1434           0 :             if (nNewPos != mnFirstPos)
    1435           0 :                 SetFirstPageId(GetPageId(nNewPos));
    1436             :         }
    1437             :     }
    1438           0 :     return Window::PreNotify(rNEvt);
    1439             : }
    1440             : 
    1441           0 : void TabBar::RequestHelp(const HelpEvent& rHEvt)
    1442             : {
    1443           0 :     sal_uInt16 nItemId = GetPageId(ScreenToOutputPixel(rHEvt.GetMousePosPixel()));
    1444           0 :     if (nItemId)
    1445             :     {
    1446           0 :         if (rHEvt.GetMode() & HelpEventMode::BALLOON)
    1447             :         {
    1448           0 :             OUString aStr = GetHelpText(nItemId);
    1449           0 :             if (!aStr.isEmpty())
    1450             :             {
    1451           0 :                 Rectangle aItemRect = GetPageRect(nItemId);
    1452           0 :                 Point aPt = OutputToScreenPixel(aItemRect.TopLeft());
    1453           0 :                 aItemRect.Left()   = aPt.X();
    1454           0 :                 aItemRect.Top()    = aPt.Y();
    1455           0 :                 aPt = OutputToScreenPixel(aItemRect.BottomRight());
    1456           0 :                 aItemRect.Right()  = aPt.X();
    1457           0 :                 aItemRect.Bottom() = aPt.Y();
    1458           0 :                 Help::ShowBalloon(this, aItemRect.Center(), aItemRect, aStr);
    1459           0 :                 return;
    1460           0 :             }
    1461             :         }
    1462           0 :         else if (rHEvt.GetMode() & HelpEventMode::EXTENDED)
    1463             :         {
    1464           0 :             OUString aHelpId(OStringToOUString(GetHelpId(nItemId), RTL_TEXTENCODING_UTF8));
    1465           0 :             if ( !aHelpId.isEmpty() )
    1466             :             {
    1467             :                 // trigger Help if available
    1468           0 :                 Help* pHelp = Application::GetHelp();
    1469           0 :                 if (pHelp)
    1470           0 :                     pHelp->Start(aHelpId, this);
    1471           0 :                 return;
    1472           0 :             }
    1473             :         }
    1474             : 
    1475             :         // show text for quick- or balloon-help
    1476             :         // if this is isolated or not fully visible
    1477           0 :         if (rHEvt.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON))
    1478             :         {
    1479           0 :             sal_uInt16 nPos = GetPagePos(nItemId);
    1480           0 :             ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    1481           0 :             if (pItem->mbShort || (pItem->maRect.Right() - 5 > mnLastOffX))
    1482             :             {
    1483           0 :                 Rectangle aItemRect = GetPageRect(nItemId);
    1484           0 :                 Point aPt = OutputToScreenPixel(aItemRect.TopLeft());
    1485           0 :                 aItemRect.Left()   = aPt.X();
    1486           0 :                 aItemRect.Top()    = aPt.Y();
    1487           0 :                 aPt = OutputToScreenPixel(aItemRect.BottomRight());
    1488           0 :                 aItemRect.Right()  = aPt.X();
    1489           0 :                 aItemRect.Bottom() = aPt.Y();
    1490           0 :                 OUString aStr = mpImpl->mpItemList[nPos]->maText;
    1491           0 :                 if (!aStr.isEmpty())
    1492             :                 {
    1493           0 :                     if (rHEvt.GetMode() & HelpEventMode::BALLOON)
    1494           0 :                         Help::ShowBalloon(this, aItemRect.Center(), aItemRect, aStr);
    1495             :                     else
    1496           0 :                         Help::ShowQuickHelp(this, aItemRect, aStr);
    1497           0 :                     return;
    1498           0 :                 }
    1499             :             }
    1500             :         }
    1501             :     }
    1502             : 
    1503           0 :     Window::RequestHelp(rHEvt);
    1504             : }
    1505             : 
    1506        1730 : void TabBar::StateChanged(StateChangedType nType)
    1507             : {
    1508        1730 :     Window::StateChanged(nType);
    1509             : 
    1510        1730 :     if (nType == StateChangedType::InitShow)
    1511             :     {
    1512         567 :         if ( (mbSizeFormat || mbFormat) && !mpImpl->mpItemList.empty() )
    1513         563 :             ImplFormat();
    1514             :     }
    1515        1163 :     else if (nType == StateChangedType::Zoom ||
    1516             :              nType == StateChangedType::ControlFont)
    1517             :     {
    1518           0 :         ImplInitSettings(true, false);
    1519           0 :         Invalidate();
    1520             :     }
    1521        1163 :     else if (nType == StateChangedType::ControlForeground)
    1522           0 :         Invalidate();
    1523        1163 :     else if (nType == StateChangedType::ControlBackground)
    1524             :     {
    1525           0 :         ImplInitSettings(false, true);
    1526           0 :         Invalidate();
    1527             :     }
    1528        1163 :     else if (nType == StateChangedType::Mirroring)
    1529             :     {
    1530             :         // reacts on calls of EnableRTL, have to mirror all child controls
    1531         348 :         if (mpImpl->mpFirstButton)
    1532           0 :             mpImpl->mpFirstButton->EnableRTL(IsRTLEnabled());
    1533         348 :         if (mpImpl->mpPrevButton)
    1534         348 :             mpImpl->mpPrevButton->EnableRTL(IsRTLEnabled());
    1535         348 :         if (mpImpl->mpNextButton)
    1536         348 :             mpImpl->mpNextButton->EnableRTL(IsRTLEnabled());
    1537         348 :         if (mpImpl->mpLastButton)
    1538           0 :             mpImpl->mpLastButton->EnableRTL(IsRTLEnabled());
    1539         348 :         if (mpImpl->mpSizer)
    1540           0 :             mpImpl->mpSizer->EnableRTL(IsRTLEnabled());
    1541         348 :         if (mpImpl->mpAddButton)
    1542         338 :             mpImpl->mpAddButton->EnableRTL(IsRTLEnabled());
    1543         348 :         if (mpImpl->mpEdit)
    1544           0 :             mpImpl->mpEdit->EnableRTL(IsRTLEnabled());
    1545             :     }
    1546        1730 : }
    1547             : 
    1548          32 : void TabBar::DataChanged(const DataChangedEvent& rDCEvt)
    1549             : {
    1550          32 :     Window::DataChanged(rDCEvt);
    1551             : 
    1552          96 :     if (rDCEvt.GetType() == DataChangedEventType::FONTS
    1553          32 :         || rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION
    1554         128 :         || (rDCEvt.GetType() == DataChangedEventType::SETTINGS
    1555          96 :             && rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
    1556             :     {
    1557          32 :         ImplInitSettings(true, true);
    1558          32 :         Invalidate();
    1559             :     }
    1560          32 : }
    1561             : 
    1562           0 : void TabBar::ImplSelect()
    1563             : {
    1564           0 :     Select();
    1565           0 :     CallEventListeners(VCLEVENT_TABBAR_PAGESELECTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)));
    1566           0 : }
    1567             : 
    1568           0 : void TabBar::Select()
    1569             : {
    1570           0 :     maSelectHdl.Call(this);
    1571           0 : }
    1572             : 
    1573           0 : void TabBar::DoubleClick()
    1574             : {
    1575           0 : }
    1576             : 
    1577           0 : void TabBar::Split()
    1578             : {
    1579           0 :     maSplitHdl.Call(this);
    1580           0 : }
    1581             : 
    1582           0 : void TabBar::ImplActivatePage()
    1583             : {
    1584           0 :     ActivatePage();
    1585             : 
    1586           0 :     CallEventListeners(VCLEVENT_TABBAR_PAGEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)));
    1587           0 : }
    1588             : 
    1589           0 : void TabBar::ActivatePage()
    1590           0 : {}
    1591             : 
    1592           0 : bool TabBar::ImplDeactivatePage()
    1593             : {
    1594           0 :     bool nRet = DeactivatePage();
    1595             : 
    1596           0 :     CallEventListeners(VCLEVENT_TABBAR_PAGEDEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)));
    1597             : 
    1598           0 :     return nRet;
    1599             : }
    1600             : 
    1601         409 : void TabBar::ImplPrePaint(vcl::RenderContext& /*rRenderContext*/)
    1602             : {
    1603         409 :     sal_uInt16 nItemCount = mpImpl->getItemSize();
    1604         409 :     if (!nItemCount)
    1605         409 :         return;
    1606             : 
    1607             :     // tabbar should be formatted
    1608         409 :     ImplFormat();
    1609             : 
    1610             :     // assure the actual tabpage becomes visible at first format
    1611         409 :     if (mbFirstFormat)
    1612             :     {
    1613         231 :         mbFirstFormat = false;
    1614             : 
    1615         231 :         if (mnCurPageId && (mnFirstPos == 0) && !mbDropPos)
    1616             :         {
    1617         231 :             ImplTabBarItem* pItem = mpImpl->mpItemList[GetPagePos(mnCurPageId)];
    1618         231 :             if (pItem->maRect.IsEmpty())
    1619             :             {
    1620             :                 // set mbDropPos (or misuse) to prevent Invalidate()
    1621           1 :                 mbDropPos = true;
    1622           1 :                 SetFirstPageId(mnCurPageId);
    1623           1 :                 mbDropPos = false;
    1624           1 :                 if (mnFirstPos != 0)
    1625           0 :                     ImplFormat();
    1626             :             }
    1627             :         }
    1628             :     }
    1629             : }
    1630             : 
    1631         409 : ImplTabBarItem* TabBar::ImplGetLastTabBarItem( sal_uInt16 nItemCount )
    1632             : {
    1633             :     // find last visible entry
    1634         409 :     sal_uInt16 n = mnFirstPos + 1;
    1635         409 :     if (n >= nItemCount)
    1636         174 :         n = nItemCount-1;
    1637         409 :     ImplTabBarItem* pItem = seek(n);
    1638        1377 :     while (pItem)
    1639             :     {
    1640         560 :         if (!pItem->maRect.IsEmpty())
    1641             :         {
    1642         559 :             n++;
    1643         559 :             pItem = next();
    1644             :         }
    1645             :         else
    1646           1 :             break;
    1647             :     }
    1648             : 
    1649             :     // draw all tabs (from back to front and actual last)
    1650         409 :     if (pItem)
    1651           1 :         n--;
    1652         408 :     else if (n >= nItemCount)
    1653         408 :         n = nItemCount-1;
    1654         409 :     pItem = seek(n);
    1655         409 :     return pItem;
    1656             : }
    1657             : 
    1658           0 : bool TabBar::DeactivatePage()
    1659             : {
    1660           0 :     return true;
    1661             : }
    1662             : 
    1663           0 : bool TabBar::StartRenaming()
    1664             : {
    1665           0 :     return true;
    1666             : }
    1667             : 
    1668           0 : TabBarAllowRenamingReturnCode TabBar::AllowRenaming()
    1669             : {
    1670           0 :     return TABBAR_RENAMING_YES;
    1671             : }
    1672             : 
    1673           0 : void TabBar::EndRenaming()
    1674             : {
    1675           0 : }
    1676             : 
    1677           2 : void TabBar::Mirror()
    1678             : {
    1679             : 
    1680           2 : }
    1681             : 
    1682           0 : void TabBar::AddTabClick()
    1683             : {
    1684             : 
    1685           0 : }
    1686             : 
    1687        2689 : void TabBar::InsertPage(sal_uInt16 nPageId, const OUString& rText,
    1688             :                         TabBarPageBits nBits, sal_uInt16 nPos)
    1689             : {
    1690             :     DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
    1691             :     DBG_ASSERT( GetPagePos( nPageId ) == PAGE_NOT_FOUND,
    1692             :                 "TabBar::InsertPage(): PageId already exists" );
    1693             :     DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
    1694             : 
    1695             :     // create PageItem and insert in the item list
    1696        2689 :     ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
    1697        2689 :     if (nPos < mpImpl->mpItemList.size())
    1698             :     {
    1699           0 :         ImplTabBarList::iterator it = mpImpl->mpItemList.begin();
    1700           0 :         std::advance(it, nPos);
    1701           0 :         mpImpl->mpItemList.insert(it, pItem);
    1702             :     }
    1703             :     else
    1704             :     {
    1705        2689 :         mpImpl->mpItemList.push_back(pItem);
    1706             :     }
    1707        2689 :     mbSizeFormat = true;
    1708             : 
    1709             :     // set CurPageId if required
    1710        2689 :     if (!mnCurPageId)
    1711        1602 :         mnCurPageId = nPageId;
    1712             : 
    1713             :     // redraw bar
    1714        2689 :     if (IsReallyVisible() && IsUpdateMode())
    1715         322 :         Invalidate();
    1716             : 
    1717        2689 :     CallEventListeners(VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)));
    1718        2689 : }
    1719             : 
    1720        3690 : Color TabBar::GetTabBgColor(sal_uInt16 nPageId) const
    1721             : {
    1722        3690 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1723             : 
    1724        3690 :     if (nPos != PAGE_NOT_FOUND)
    1725        3687 :         return mpImpl->mpItemList[nPos]->maTabBgColor;
    1726             :     else
    1727           3 :         return Color(COL_AUTO);
    1728             : }
    1729             : 
    1730           1 : void TabBar::SetTabBgColor(sal_uInt16 nPageId, const Color& aTabBgColor)
    1731             : {
    1732           1 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1733           1 :     if (nPos != PAGE_NOT_FOUND)
    1734             :     {
    1735           1 :         ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    1736           1 :         if (aTabBgColor != Color(COL_AUTO))
    1737             :         {
    1738           1 :             pItem->maTabBgColor = aTabBgColor;
    1739           1 :             if (aTabBgColor.GetLuminance() <= 128) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
    1740           0 :                 pItem->maTabTextColor = Color(COL_WHITE);
    1741             :             else
    1742           1 :                 pItem->maTabTextColor = Color(COL_BLACK);
    1743             :         }
    1744             :         else
    1745             :         {
    1746           0 :             pItem->maTabBgColor = Color(COL_AUTO);
    1747           0 :             pItem->maTabTextColor = Color(COL_AUTO);
    1748             :         }
    1749             :     }
    1750           1 : }
    1751             : 
    1752           0 : void TabBar::RemovePage(sal_uInt16 nPageId)
    1753             : {
    1754           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1755             : 
    1756             :     // does item exist
    1757           0 :     if (nPos != PAGE_NOT_FOUND)
    1758             :     {
    1759           0 :         if (mnCurPageId == nPageId)
    1760           0 :             mnCurPageId = 0;
    1761             : 
    1762             :         // check if first visibale page should be moved
    1763           0 :         if (mnFirstPos > nPos)
    1764           0 :             mnFirstPos--;
    1765             : 
    1766             :         // delete item data
    1767           0 :         ImplTabBarList::iterator it = mpImpl->mpItemList.begin();
    1768           0 :         std::advance(it, nPos);
    1769           0 :         delete *it;
    1770           0 :         mpImpl->mpItemList.erase(it);
    1771             : 
    1772             :         // redraw bar
    1773           0 :         if (IsReallyVisible() && IsUpdateMode())
    1774           0 :             Invalidate();
    1775             : 
    1776           0 :         CallEventListeners(VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)));
    1777             :     }
    1778           0 : }
    1779             : 
    1780           0 : void TabBar::MovePage(sal_uInt16 nPageId, sal_uInt16 nNewPos)
    1781             : {
    1782           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1783           0 :     Pair aPair(nPos, nNewPos);
    1784             : 
    1785           0 :     if (nPos < nNewPos)
    1786           0 :         nNewPos--;
    1787             : 
    1788           0 :     if (nPos == nNewPos)
    1789           0 :         return;
    1790             : 
    1791             :     // does item exit
    1792           0 :     if (nPos != PAGE_NOT_FOUND)
    1793             :     {
    1794             :         // move tabbar item in the list
    1795           0 :         ImplTabBarList::iterator it = mpImpl->mpItemList.begin();
    1796           0 :         std::advance(it, nPos);
    1797           0 :         ImplTabBarItem* pItem = *it;
    1798           0 :         mpImpl->mpItemList.erase(it);
    1799           0 :         if (nNewPos < mpImpl->mpItemList.size())
    1800             :         {
    1801           0 :             it = mpImpl->mpItemList.begin();
    1802           0 :             std::advance(it, nNewPos);
    1803           0 :             mpImpl->mpItemList.insert(it, pItem);
    1804             :         }
    1805             :         else
    1806             :         {
    1807           0 :             mpImpl->mpItemList.push_back(pItem);
    1808             :         }
    1809             : 
    1810             :         // redraw bar
    1811           0 :         if (IsReallyVisible() && IsUpdateMode())
    1812           0 :             Invalidate();
    1813             : 
    1814           0 :         CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, static_cast<void*>(&aPair) );
    1815             :     }
    1816             : }
    1817             : 
    1818        1254 : void TabBar::Clear()
    1819             : {
    1820             :     // delete all items
    1821        2980 :     for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
    1822             :     {
    1823        1726 :         delete mpImpl->mpItemList[i];
    1824             :     }
    1825        1254 :     mpImpl->mpItemList.clear();
    1826             : 
    1827             :     // remove items from the list
    1828        1254 :     mbSizeFormat = true;
    1829        1254 :     mnCurPageId = 0;
    1830        1254 :     mnFirstPos = 0;
    1831        1254 :     maCurrentItemList = 0;
    1832             : 
    1833             :     // redraw bar
    1834        1254 :     if (IsReallyVisible() && IsUpdateMode())
    1835         140 :         Invalidate();
    1836             : 
    1837        1254 :     CallEventListeners(VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(PAGE_NOT_FOUND)));
    1838        1254 : }
    1839             : 
    1840           0 : bool TabBar::IsPageEnabled(sal_uInt16 nPageId) const
    1841             : {
    1842           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1843             : 
    1844           0 :     if (nPos != PAGE_NOT_FOUND)
    1845           0 :         return mpImpl->mpItemList[nPos]->mbEnable;
    1846             :     else
    1847           0 :         return false;
    1848             : }
    1849             : 
    1850         954 : void TabBar::SetPageBits(sal_uInt16 nPageId, TabBarPageBits nBits)
    1851             : {
    1852         954 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1853             : 
    1854         954 :     if (nPos != PAGE_NOT_FOUND)
    1855             :     {
    1856         954 :         ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    1857             : 
    1858         954 :         if (pItem->mnBits != nBits)
    1859             :         {
    1860           0 :             pItem->mnBits = nBits;
    1861             : 
    1862             :             // redraw bar
    1863           0 :             if (IsReallyVisible() && IsUpdateMode())
    1864           0 :                 Invalidate(pItem->maRect);
    1865             :         }
    1866             :     }
    1867         954 : }
    1868             : 
    1869           0 : TabBarPageBits TabBar::GetPageBits(sal_uInt16 nPageId) const
    1870             : {
    1871           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1872             : 
    1873           0 :     if (nPos != PAGE_NOT_FOUND)
    1874           0 :         return mpImpl->mpItemList[nPos]->mnBits;
    1875             :     else
    1876           0 :         return 0;
    1877             : }
    1878             : 
    1879        3153 : sal_uInt16 TabBar::GetPageCount() const
    1880             : {
    1881        3153 :     return mpImpl->getItemSize();
    1882             : }
    1883             : 
    1884        2844 : sal_uInt16 TabBar::GetPageId(sal_uInt16 nPos) const
    1885             : {
    1886        2844 :     return nPos < mpImpl->mpItemList.size() ? mpImpl->mpItemList[nPos]->mnId : 0;
    1887             : }
    1888             : 
    1889       19994 : sal_uInt16 TabBar::GetPagePos(sal_uInt16 nPageId) const
    1890             : {
    1891       27447 :     for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
    1892             :     {
    1893       27420 :         if (mpImpl->mpItemList[i]->mnId == nPageId)
    1894             :         {
    1895       19967 :             return static_cast<sal_uInt16>(i);
    1896             :         }
    1897             :     }
    1898          27 :     return PAGE_NOT_FOUND;
    1899             : }
    1900             : 
    1901           0 : sal_uInt16 TabBar::GetPageId(const Point& rPos) const
    1902             : {
    1903           0 :     for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
    1904             :     {
    1905           0 :         ImplTabBarItem* pItem = mpImpl->mpItemList[i];
    1906           0 :         if (pItem->maRect.IsInside(rPos))
    1907           0 :             return pItem->mnId;
    1908             :     }
    1909             : 
    1910           0 :     return 0;
    1911             : }
    1912             : 
    1913           0 : Rectangle TabBar::GetPageRect(sal_uInt16 nPageId) const
    1914             : {
    1915           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1916             : 
    1917           0 :     if (nPos != PAGE_NOT_FOUND)
    1918           0 :         return mpImpl->mpItemList[nPos]->maRect;
    1919             :     else
    1920           0 :         return Rectangle();
    1921             : }
    1922             : 
    1923        4663 : void TabBar::SetCurPageId(sal_uInt16 nPageId)
    1924             : {
    1925        4663 :     sal_uInt16 nPos = GetPagePos(nPageId);
    1926             : 
    1927             :     // do nothing if item does not exit
    1928        4663 :     if (nPos != PAGE_NOT_FOUND)
    1929             :     {
    1930             :         // do nothing if the actual page did not change
    1931        4663 :         if (nPageId == mnCurPageId)
    1932        9098 :             return;
    1933             : 
    1934             :         // make invalide
    1935         228 :         bool bUpdate = false;
    1936         228 :         if (IsReallyVisible() && IsUpdateMode())
    1937         216 :             bUpdate = true;
    1938             : 
    1939         228 :         ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    1940             :         ImplTabBarItem* pOldItem;
    1941             : 
    1942         228 :         if (mnCurPageId)
    1943         228 :             pOldItem = mpImpl->mpItemList[GetPagePos(mnCurPageId)];
    1944             :         else
    1945           0 :             pOldItem = NULL;
    1946             : 
    1947             :         // deselect previous page if page was not selected, if this is the
    1948             :         // only selected page
    1949         228 :         if (!pItem->mbSelect && pOldItem)
    1950             :         {
    1951         228 :             sal_uInt16 nSelPageCount = GetSelectPageCount();
    1952         228 :             if (nSelPageCount == 1)
    1953         180 :                 pOldItem->mbSelect = false;
    1954         228 :             pItem->mbSelect = true;
    1955             :         }
    1956             : 
    1957         228 :         mnCurPageId = nPageId;
    1958         228 :         mbFormat = true;
    1959             : 
    1960             :         // assure the actual page becomes visible
    1961         228 :         if (IsReallyVisible())
    1962             :         {
    1963         216 :             if (nPos < mnFirstPos)
    1964           0 :                 SetFirstPageId(nPageId);
    1965             :             else
    1966             :             {
    1967             :                 // calculate visible width
    1968         216 :                 long nWidth = mnLastOffX;
    1969         216 :                 if (nWidth > ADDNEWPAGE_AREAWIDTH)
    1970         212 :                     nWidth -= ADDNEWPAGE_AREAWIDTH;
    1971             : 
    1972         216 :                 if (pItem->maRect.IsEmpty())
    1973          44 :                     ImplFormat();
    1974             : 
    1975         677 :                 while ((mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) ||
    1976         230 :                         pItem->maRect.IsEmpty())
    1977             :                 {
    1978          20 :                     sal_uInt16 nNewPos = mnFirstPos + 1;
    1979             :                     // assure at least the actual tabpages are visible as first tabpage
    1980          20 :                     if (nNewPos >= nPos)
    1981             :                     {
    1982           5 :                         SetFirstPageId(nPageId);
    1983           5 :                         break;
    1984             :                     }
    1985             :                     else
    1986          15 :                         SetFirstPageId(GetPageId(nNewPos));
    1987          15 :                     ImplFormat();
    1988             :                     // abort if first page is not forwarded
    1989          15 :                     if (nNewPos != mnFirstPos)
    1990           0 :                         break;
    1991             :                 }
    1992             :             }
    1993             :         }
    1994             : 
    1995             :         // redraw bar
    1996         228 :         if (bUpdate)
    1997             :         {
    1998         216 :             Invalidate(pItem->maRect);
    1999         216 :             if (pOldItem)
    2000         216 :                 Invalidate(pOldItem->maRect);
    2001             :         }
    2002             :     }
    2003             : }
    2004             : 
    2005           0 : void TabBar::MakeVisible(sal_uInt16 nPageId)
    2006             : {
    2007           0 :     if (!IsReallyVisible())
    2008           0 :         return;
    2009             : 
    2010           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2011             : 
    2012             :     // do nothing if item does not exist
    2013           0 :     if (nPos != PAGE_NOT_FOUND)
    2014             :     {
    2015           0 :         if (nPos < mnFirstPos)
    2016           0 :             SetFirstPageId(nPageId);
    2017             :         else
    2018             :         {
    2019           0 :             ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    2020             : 
    2021             :             // calculate visible area
    2022           0 :             long nWidth = mnLastOffX;
    2023             : 
    2024           0 :             if (mbFormat || pItem->maRect.IsEmpty())
    2025             :             {
    2026           0 :                 mbFormat = true;
    2027           0 :                 ImplFormat();
    2028             :             }
    2029             : 
    2030           0 :             while ((pItem->maRect.Right() > nWidth) ||
    2031           0 :                     pItem->maRect.IsEmpty())
    2032             :             {
    2033           0 :                 sal_uInt16 nNewPos = mnFirstPos+1;
    2034             :                 // assure at least the actual tabpages are visible as first tabpage
    2035           0 :                 if (nNewPos >= nPos)
    2036             :                 {
    2037           0 :                     SetFirstPageId(nPageId);
    2038           0 :                     break;
    2039             :                 }
    2040             :                 else
    2041           0 :                     SetFirstPageId(GetPageId(nNewPos));
    2042           0 :                 ImplFormat();
    2043             :                 // abort if first page is not forwarded
    2044           0 :                 if (nNewPos != mnFirstPos)
    2045           0 :                     break;
    2046             :             }
    2047             :         }
    2048             :     }
    2049             : }
    2050             : 
    2051          27 : void TabBar::SetFirstPageId(sal_uInt16 nPageId)
    2052             : {
    2053          27 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2054             : 
    2055             :     // return false if item does not exist
    2056          27 :     if (nPos != PAGE_NOT_FOUND)
    2057             :     {
    2058          21 :         if (nPos != mnFirstPos)
    2059             :         {
    2060             :             // assure as much pages are visible as possible
    2061          18 :             ImplFormat();
    2062          18 :             sal_uInt16 nLastFirstPos = ImplGetLastFirstPos();
    2063             :             sal_uInt16 nNewPos;
    2064          18 :             if (nPos > nLastFirstPos)
    2065           0 :                 nNewPos = nLastFirstPos;
    2066             :             else
    2067          18 :                 nNewPos = nPos;
    2068             : 
    2069          18 :             if (nNewPos != mnFirstPos)
    2070             :             {
    2071          18 :                 mnFirstPos = nNewPos;
    2072          18 :                 mbFormat = true;
    2073             : 
    2074             :                 // redraw bar (attention: check mbDropPos,
    2075             :                 // as if this flag was set, we do not re-paint immediately
    2076          18 :                 if (IsReallyVisible() && IsUpdateMode() && !mbDropPos)
    2077          18 :                     Invalidate();
    2078             :             }
    2079             :         }
    2080             :     }
    2081          27 : }
    2082             : 
    2083         569 : void TabBar::SelectPage(sal_uInt16 nPageId, bool bSelect)
    2084             : {
    2085         569 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2086             : 
    2087         569 :     if (nPos != PAGE_NOT_FOUND)
    2088             :     {
    2089         568 :         ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    2090             : 
    2091         568 :         if (pItem->mbSelect != bSelect)
    2092             :         {
    2093         399 :             pItem->mbSelect = bSelect;
    2094             : 
    2095             :             // redraw bar
    2096         399 :             if (IsReallyVisible() && IsUpdateMode())
    2097         202 :                 Invalidate(pItem->maRect);
    2098             :         }
    2099             :     }
    2100         569 : }
    2101             : 
    2102         228 : sal_uInt16 TabBar::GetSelectPageCount() const
    2103             : {
    2104         228 :     sal_uInt16 nSelected = 0;
    2105         755 :     for (size_t i = 0; i < mpImpl->mpItemList.size();  ++i)
    2106             :     {
    2107         527 :         ImplTabBarItem* pItem = mpImpl->mpItemList[i];
    2108         527 :         if (pItem->mbSelect)
    2109         180 :             nSelected++;
    2110             :     }
    2111             : 
    2112         228 :     return nSelected;
    2113             : }
    2114             : 
    2115        3702 : bool TabBar::IsPageSelected(sal_uInt16 nPageId) const
    2116             : {
    2117        3702 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2118        3702 :     if (nPos != PAGE_NOT_FOUND)
    2119        3699 :         return mpImpl->mpItemList[nPos]->mbSelect;
    2120             :     else
    2121           3 :         return false;
    2122             : }
    2123             : 
    2124           0 : bool TabBar::StartEditMode(sal_uInt16 nPageId)
    2125             : {
    2126           0 :     sal_uInt16 nPos = GetPagePos( nPageId );
    2127           0 :     if (mpImpl->mpEdit || (nPos == PAGE_NOT_FOUND) || (mnLastOffX < 8))
    2128           0 :         return false;
    2129             : 
    2130           0 :     mnEditId = nPageId;
    2131           0 :     if (StartRenaming())
    2132             :     {
    2133           0 :         ImplShowPage(nPos);
    2134           0 :         ImplFormat();
    2135           0 :         Update();
    2136             : 
    2137           0 :         mpImpl->mpEdit.reset(VclPtr<TabBarEdit>::Create(this, WB_CENTER));
    2138           0 :         Rectangle aRect = GetPageRect( mnEditId );
    2139           0 :         long nX = aRect.Left();
    2140           0 :         long nWidth = aRect.GetWidth();
    2141           0 :         if (mnEditId != GetCurPageId())
    2142           0 :             nX += 1;
    2143           0 :         if (nX + nWidth > mnLastOffX)
    2144           0 :             nWidth = mnLastOffX-nX;
    2145           0 :         if (nWidth < 3)
    2146             :         {
    2147           0 :             nX = aRect.Left();
    2148           0 :             nWidth = aRect.GetWidth();
    2149             :         }
    2150           0 :         mpImpl->mpEdit->SetText(GetPageText(mnEditId));
    2151           0 :         mpImpl->mpEdit->setPosSizePixel(nX, aRect.Top() + mnOffY + 1, nWidth, aRect.GetHeight() - 3);
    2152           0 :         vcl::Font aFont = GetPointFont(*this); // FIXME RenderContext
    2153             : 
    2154           0 :         Color   aForegroundColor;
    2155           0 :         Color   aBackgroundColor;
    2156           0 :         Color   aFaceColor;
    2157           0 :         Color   aSelectColor;
    2158           0 :         Color   aFaceTextColor;
    2159           0 :         Color   aSelectTextColor;
    2160             : 
    2161           0 :         ImplGetColors(Application::GetSettings().GetStyleSettings(), aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor);
    2162             : 
    2163           0 :         if (mnEditId != GetCurPageId())
    2164             :         {
    2165           0 :             aFont.SetWeight(WEIGHT_LIGHT);
    2166             :         }
    2167           0 :         if (IsPageSelected(mnEditId) || mnEditId == GetCurPageId())
    2168             :         {
    2169           0 :             aForegroundColor = aSelectTextColor;
    2170           0 :             aBackgroundColor = aSelectColor;
    2171             :         }
    2172             :         else
    2173             :         {
    2174           0 :             aForegroundColor = aFaceTextColor;
    2175           0 :             aBackgroundColor = aFaceColor;
    2176             :         }
    2177           0 :         if (GetPageBits( mnEditId ) & TPB_SPECIAL)
    2178             :         {
    2179           0 :             aForegroundColor = Color(COL_LIGHTBLUE);
    2180             :         }
    2181           0 :         mpImpl->mpEdit->SetControlFont(aFont);
    2182           0 :         mpImpl->mpEdit->SetControlForeground(aForegroundColor);
    2183           0 :         mpImpl->mpEdit->SetControlBackground(aBackgroundColor);
    2184           0 :         mpImpl->mpEdit->GrabFocus();
    2185           0 :         mpImpl->mpEdit->SetSelection(Selection(0, mpImpl->mpEdit->GetText().getLength()));
    2186           0 :         mpImpl->mpEdit->Show();
    2187           0 :         return true;
    2188             :     }
    2189             :     else
    2190             :     {
    2191           0 :         mnEditId = 0;
    2192           0 :         return false;
    2193             :     }
    2194             : }
    2195             : 
    2196           0 : bool TabBar::IsInEditMode() const
    2197             : {
    2198           0 :     return mpImpl->mpEdit.get() != NULL;
    2199             : }
    2200             : 
    2201        1197 : void TabBar::EndEditMode(bool bCancel)
    2202             : {
    2203        1197 :     if (mpImpl->mpEdit)
    2204             :     {
    2205             :         // call hdl
    2206           0 :         bool bEnd = true;
    2207           0 :         mbEditCanceled = bCancel;
    2208           0 :         maEditText = mpImpl->mpEdit->GetText();
    2209           0 :         mpImpl->mpEdit->SetPostEvent();
    2210           0 :         if (!bCancel)
    2211             :         {
    2212           0 :             TabBarAllowRenamingReturnCode nAllowRenaming = AllowRenaming();
    2213           0 :             if (nAllowRenaming == TABBAR_RENAMING_YES)
    2214           0 :                 SetPageText(mnEditId, maEditText);
    2215           0 :             else if (nAllowRenaming == TABBAR_RENAMING_NO)
    2216           0 :                 bEnd = false;
    2217             :             else // nAllowRenaming == TABBAR_RENAMING_CANCEL
    2218           0 :                 mbEditCanceled = true;
    2219             :         }
    2220             : 
    2221             :         // renaming not allowed, than reset edit data
    2222           0 :         if (!bEnd)
    2223             :         {
    2224           0 :             mpImpl->mpEdit->ResetPostEvent();
    2225           0 :             mpImpl->mpEdit->GrabFocus();
    2226             :         }
    2227             :         else
    2228             :         {
    2229             :             // close edit and call end hdl
    2230           0 :             mpImpl->mpEdit.disposeAndClear();
    2231             : 
    2232           0 :             EndRenaming();
    2233           0 :             mnEditId = 0;
    2234             :         }
    2235             : 
    2236             :         // reset
    2237           0 :         maEditText.clear();
    2238           0 :         mbEditCanceled = false;
    2239             :     }
    2240        1197 : }
    2241             : 
    2242        1866 : void TabBar::SetMirrored(bool bMirrored)
    2243             : {
    2244        1866 :     if (mbMirrored != bMirrored)
    2245             :     {
    2246           2 :         mbMirrored = bMirrored;
    2247           2 :         mbSizeFormat = true;
    2248           2 :         ImplInitControls();     // for button images
    2249           2 :         Resize();               // recalculates control positions
    2250           2 :         Mirror();
    2251             :     }
    2252        1866 : }
    2253             : 
    2254        1866 : void TabBar::SetEffectiveRTL(bool bRTL)
    2255             : {
    2256        1866 :     SetMirrored( bRTL != AllSettings::GetLayoutRTL() );
    2257        1866 : }
    2258             : 
    2259           0 : bool TabBar::IsEffectiveRTL() const
    2260             : {
    2261           0 :     return IsMirrored() != AllSettings::GetLayoutRTL();
    2262             : }
    2263             : 
    2264         219 : void TabBar::SetMaxPageWidth(long nMaxWidth)
    2265             : {
    2266         219 :     if (mnMaxPageWidth != nMaxWidth)
    2267             :     {
    2268         219 :         mnMaxPageWidth = nMaxWidth;
    2269         219 :         mbSizeFormat = true;
    2270             : 
    2271             :         // redraw bar
    2272         219 :         if (IsReallyVisible() && IsUpdateMode())
    2273           0 :             Invalidate();
    2274             :     }
    2275         219 : }
    2276             : 
    2277           0 : void TabBar::SetPageText(sal_uInt16 nPageId, const OUString& rText)
    2278             : {
    2279           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2280           0 :     if (nPos != PAGE_NOT_FOUND)
    2281             :     {
    2282           0 :         mpImpl->mpItemList[nPos]->maText = rText;
    2283           0 :         mbSizeFormat = true;
    2284             : 
    2285             :         // redraw bar
    2286           0 :         if (IsReallyVisible() && IsUpdateMode())
    2287           0 :             Invalidate();
    2288             : 
    2289           0 :         CallEventListeners(VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)));
    2290             :     }
    2291           0 : }
    2292             : 
    2293        4767 : OUString TabBar::GetPageText(sal_uInt16 nPageId) const
    2294             : {
    2295        4767 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2296        4767 :     if (nPos != PAGE_NOT_FOUND)
    2297        4755 :         return mpImpl->mpItemList[nPos]->maText;
    2298          12 :     return OUString();
    2299             : }
    2300             : 
    2301           0 : OUString TabBar::GetHelpText(sal_uInt16 nPageId) const
    2302             : {
    2303           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2304           0 :     if (nPos != PAGE_NOT_FOUND)
    2305             :     {
    2306           0 :         ImplTabBarItem* pItem = mpImpl->mpItemList[nPos];
    2307           0 :         if (pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty())
    2308             :         {
    2309           0 :             Help* pHelp = Application::GetHelp();
    2310           0 :             if (pHelp)
    2311           0 :                 pItem->maHelpText = pHelp->GetHelpText(OStringToOUString(pItem->maHelpId, RTL_TEXTENCODING_UTF8), this);
    2312             :         }
    2313             : 
    2314           0 :         return pItem->maHelpText;
    2315             :     }
    2316           0 :     return OUString();
    2317             : }
    2318             : 
    2319           0 : OString TabBar::GetHelpId(sal_uInt16 nPageId) const
    2320             : {
    2321           0 :     sal_uInt16 nPos = GetPagePos(nPageId);
    2322           0 :     OString aRet;
    2323           0 :     if (nPos != PAGE_NOT_FOUND)
    2324           0 :         return mpImpl->mpItemList[nPos]->maHelpId;
    2325           0 :     return aRet;
    2326             : }
    2327             : 
    2328           0 : bool TabBar::StartDrag(const CommandEvent& rCEvt, vcl::Region& rRegion)
    2329             : {
    2330           0 :     if (!(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != CommandEventId::StartDrag))
    2331           0 :         return false;
    2332             : 
    2333             :     // Check if the clicked page was selected. If this is not the case
    2334             :     // set it as actual entry. We check for this only at a mouse action
    2335             :     // if Drag and Drop can be triggered from the keyboard.
    2336             :     // We only do this, if Select() was not triggered, as the Select()
    2337             :     // could have scrolled the area
    2338           0 :     if (rCEvt.IsMouseEvent() && !mbInSelect)
    2339             :     {
    2340           0 :         sal_uInt16 nSelId = GetPageId(rCEvt.GetMousePosPixel());
    2341             : 
    2342             :         // do not start dragging if no entry was clicked
    2343           0 :         if (!nSelId)
    2344           0 :             return false;
    2345             : 
    2346             :         // check if page was selected. If not set it as actual
    2347             :         // page and call Select()
    2348           0 :         if (!IsPageSelected(nSelId))
    2349             :         {
    2350           0 :             if (ImplDeactivatePage())
    2351             :             {
    2352           0 :                 SetCurPageId(nSelId);
    2353           0 :                 Update();
    2354           0 :                 ImplActivatePage();
    2355           0 :                 ImplSelect();
    2356             :             }
    2357             :             else
    2358           0 :                 return false;
    2359             :         }
    2360             :     }
    2361           0 :     mbInSelect = false;
    2362             : 
    2363           0 :     vcl::Region aRegion;
    2364             : 
    2365             :     // assign region
    2366           0 :     rRegion = aRegion;
    2367             : 
    2368           0 :     return true;
    2369             : }
    2370             : 
    2371           0 : sal_uInt16 TabBar::ShowDropPos(const Point& rPos)
    2372             : {
    2373             :     ImplTabBarItem* pItem;
    2374             :     sal_uInt16 nDropId;
    2375             :     sal_uInt16 nNewDropPos;
    2376           0 :     sal_uInt16 nItemCount = mpImpl->getItemSize();
    2377           0 :     sal_Int16 nScroll = 0;
    2378             : 
    2379           0 :     if (rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF)
    2380             :     {
    2381           0 :         pItem = mpImpl->mpItemList[mpImpl->mpItemList.size() - 1];
    2382           0 :         if (!pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()))
    2383           0 :             nNewDropPos = mpImpl->getItemSize();
    2384             :         else
    2385             :         {
    2386           0 :             nNewDropPos = mnFirstPos + 1;
    2387           0 :             nScroll = 1;
    2388             :         }
    2389             :     }
    2390           0 :     else if ((rPos.X() <= mnOffX) ||
    2391           0 :              (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)))
    2392             :     {
    2393           0 :         if (mnFirstPos)
    2394             :         {
    2395           0 :             nNewDropPos = mnFirstPos;
    2396           0 :             nScroll = -1;
    2397             :         }
    2398             :         else
    2399           0 :             nNewDropPos = 0;
    2400             :     }
    2401             :     else
    2402             :     {
    2403           0 :         nDropId = GetPageId(rPos);
    2404           0 :         if (nDropId)
    2405             :         {
    2406           0 :             nNewDropPos = GetPagePos(nDropId);
    2407           0 :             if (mnFirstPos && (nNewDropPos == mnFirstPos - 1))
    2408           0 :                 nScroll = -1;
    2409             :         }
    2410             :         else
    2411           0 :             nNewDropPos = nItemCount;
    2412             :     }
    2413             : 
    2414           0 :     if (mbDropPos && (nNewDropPos == mnDropPos) && !nScroll)
    2415           0 :         return mnDropPos;
    2416             : 
    2417           0 :     if (mbDropPos)
    2418           0 :         HideDropPos();
    2419           0 :     mbDropPos = true;
    2420           0 :     mnDropPos = nNewDropPos;
    2421             : 
    2422           0 :     if (nScroll)
    2423             :     {
    2424           0 :         sal_uInt16 nOldFirstPos = mnFirstPos;
    2425           0 :         SetFirstPageId(GetPageId(mnFirstPos + nScroll));
    2426             : 
    2427             :         // draw immediately, as Paint not possible during Drag and Drop
    2428           0 :         if (nOldFirstPos != mnFirstPos)
    2429             :         {
    2430           0 :             Rectangle aRect(mnOffX, 0, mnLastOffX, maWinSize.Height());
    2431           0 :             SetFillColor(GetBackground().GetColor());
    2432           0 :             DrawRect(aRect);
    2433           0 :             Invalidate(aRect);
    2434             :         }
    2435             :     }
    2436             : 
    2437             :     // draw drop position arrows
    2438           0 :     Color aBlackColor(COL_BLACK);
    2439             :     long nX;
    2440           0 :     long nY = (maWinSize.Height() / 2) - 1;
    2441           0 :     sal_uInt16 nCurPos = GetPagePos(mnCurPageId);
    2442             : 
    2443           0 :     sal_Int32 nTriangleWidth = 3 * GetDPIScaleFactor();
    2444             : 
    2445           0 :     if (mnDropPos < nItemCount)
    2446             :     {
    2447           0 :         SetLineColor(aBlackColor);
    2448           0 :         SetFillColor(aBlackColor);
    2449             : 
    2450           0 :         pItem = mpImpl->mpItemList[mnDropPos];
    2451           0 :         nX = pItem->maRect.Left();
    2452           0 :         if ( mnDropPos == nCurPos )
    2453           0 :             nX--;
    2454             :         else
    2455           0 :             nX++;
    2456             : 
    2457           0 :         if (!pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
    2458             :         {
    2459           0 :             SetLineColor(pItem->maTabTextColor);
    2460           0 :             SetFillColor(pItem->maTabTextColor);
    2461             :         }
    2462             : 
    2463           0 :         Polygon aPoly(3);
    2464           0 :         aPoly.SetPoint(Point(nX, nY), 0);
    2465           0 :         aPoly.SetPoint(Point(nX + nTriangleWidth, nY - nTriangleWidth), 1);
    2466           0 :         aPoly.SetPoint(Point(nX + nTriangleWidth, nY + nTriangleWidth), 2);
    2467           0 :         DrawPolygon(aPoly);
    2468             :     }
    2469           0 :     if (mnDropPos > 0 && mnDropPos < nItemCount + 1)
    2470             :     {
    2471           0 :         SetLineColor(aBlackColor);
    2472           0 :         SetFillColor(aBlackColor);
    2473             : 
    2474           0 :         pItem = mpImpl->mpItemList[mnDropPos - 1];
    2475           0 :         nX = pItem->maRect.Right();
    2476           0 :         if (mnDropPos == nCurPos)
    2477           0 :             nX++;
    2478           0 :         if (!pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
    2479             :         {
    2480           0 :             SetLineColor(pItem->maTabTextColor);
    2481           0 :             SetFillColor(pItem->maTabTextColor);
    2482             :         }
    2483           0 :         Polygon aPoly(3);
    2484           0 :         aPoly.SetPoint(Point(nX, nY), 0);
    2485           0 :         aPoly.SetPoint(Point(nX - nTriangleWidth, nY - nTriangleWidth), 1);
    2486           0 :         aPoly.SetPoint(Point(nX - nTriangleWidth, nY + nTriangleWidth), 2);
    2487           0 :         DrawPolygon(aPoly);
    2488             :     }
    2489             : 
    2490           0 :     return mnDropPos;
    2491             : }
    2492             : 
    2493           0 : void TabBar::HideDropPos()
    2494             : {
    2495           0 :     if (mbDropPos)
    2496             :     {
    2497             :         ImplTabBarItem* pItem;
    2498             :         long nX;
    2499           0 :         long nY1 = (maWinSize.Height() / 2) - 3;
    2500           0 :         long nY2 = nY1 + 5;
    2501           0 :         sal_uInt16 nItemCount = mpImpl->getItemSize();
    2502             : 
    2503           0 :         if (mnDropPos < nItemCount)
    2504             :         {
    2505           0 :             pItem = mpImpl->mpItemList[mnDropPos];
    2506           0 :             nX = pItem->maRect.Left();
    2507             :             // immediately call Paint, as it is not possible during drag and drop
    2508           0 :             Rectangle aRect( nX-1, nY1, nX+3, nY2 );
    2509           0 :             vcl::Region aRegion( aRect );
    2510           0 :             SetClipRegion( aRegion );
    2511           0 :             Invalidate(aRect);
    2512           0 :             SetClipRegion();
    2513             :         }
    2514           0 :         if (mnDropPos > 0 && mnDropPos < nItemCount + 1)
    2515             :         {
    2516           0 :             pItem = mpImpl->mpItemList[mnDropPos - 1];
    2517           0 :             nX = pItem->maRect.Right();
    2518             :             // immediately call Paint, as it is not possible during drag and drop
    2519           0 :             Rectangle aRect(nX - 2, nY1, nX + 1, nY2);
    2520           0 :             vcl::Region aRegion(aRect);
    2521           0 :             SetClipRegion(aRegion);
    2522           0 :             Invalidate(aRect);
    2523           0 :             SetClipRegion();
    2524             :         }
    2525             : 
    2526           0 :         mbDropPos = false;
    2527           0 :         mnDropPos = 0;
    2528             :     }
    2529           0 : }
    2530             : 
    2531           0 : bool TabBar::SwitchPage(const Point& rPos)
    2532             : {
    2533           0 :     bool bSwitch = false;
    2534           0 :     sal_uInt16 nSwitchId = GetPageId(rPos);
    2535           0 :     if (!nSwitchId)
    2536           0 :         EndSwitchPage();
    2537             :     else
    2538             :     {
    2539           0 :         if (nSwitchId != mnSwitchId)
    2540             :         {
    2541           0 :             mnSwitchId = nSwitchId;
    2542           0 :             mnSwitchTime = tools::Time::GetSystemTicks();
    2543             :         }
    2544             :         else
    2545             :         {
    2546             :             // change only after 500 ms
    2547           0 :             if (mnSwitchId != GetCurPageId())
    2548             :             {
    2549           0 :                 if (tools::Time::GetSystemTicks() > mnSwitchTime + 500)
    2550             :                 {
    2551           0 :                     mbInSwitching = true;
    2552           0 :                     if (ImplDeactivatePage())
    2553             :                     {
    2554           0 :                         SetCurPageId( mnSwitchId );
    2555           0 :                         Update();
    2556           0 :                         ImplActivatePage();
    2557           0 :                         ImplSelect();
    2558           0 :                         bSwitch = true;
    2559             :                     }
    2560           0 :                     mbInSwitching = false;
    2561             :                 }
    2562             :             }
    2563             :         }
    2564             :     }
    2565             : 
    2566           0 :     return bSwitch;
    2567             : }
    2568             : 
    2569           0 : void TabBar::EndSwitchPage()
    2570             : {
    2571           0 :     mnSwitchTime = 0;
    2572           0 :     mnSwitchId = 0;
    2573           0 : }
    2574             : 
    2575        1291 : void TabBar::SetStyle(WinBits nStyle)
    2576             : {
    2577        1291 :     mnWinStyle = nStyle;
    2578        1291 :     ImplInitControls();
    2579             :     // order possible controls
    2580        1291 :     if (IsReallyVisible() && IsUpdateMode())
    2581         557 :         Resize();
    2582        1291 : }
    2583             : 
    2584         567 : Size TabBar::CalcWindowSizePixel() const
    2585             : {
    2586         567 :     long nWidth = 0;
    2587             : 
    2588         567 :     if (mpImpl->mpItemList.size() > 0)
    2589             :     {
    2590           0 :         const_cast<TabBar*>(this)->ImplCalcWidth();
    2591           0 :         for (size_t i = 0; i < mpImpl->mpItemList.size(); ++i)
    2592             :         {
    2593           0 :             ImplTabBarItem* pItem = mpImpl->mpItemList[i];
    2594           0 :             nWidth += pItem->mnWidth;
    2595             :         }
    2596             :     }
    2597             : 
    2598         567 :     return Size(nWidth, GetSettings().GetStyleSettings().GetScrollBarSize());
    2599             : }
    2600             : 
    2601         500 : Rectangle TabBar::GetPageArea() const
    2602             : {
    2603             :     return Rectangle(Point(mnOffX, mnOffY),
    2604         500 :                      Size(mnLastOffX - mnOffX + 1, GetSizePixel().Height() - mnOffY));
    2605             : }
    2606             : 
    2607           0 : css::uno::Reference<css::accessibility::XAccessible> TabBar::CreateAccessible()
    2608             : {
    2609           0 :     return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar(*this);
    2610         798 : }
    2611             : 
    2612             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11