LCOV - code coverage report
Current view: top level - svtools/source/control - tabbar.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 694 1367 50.8 %
Date: 2014-11-03 Functions: 76 133 57.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10