LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/control - tabctrl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 1177 0.0 %
Date: 2012-12-27 Functions: 0 84 0.0 %
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 "tools/debug.hxx"
      22             : #include "tools/rc.h"
      23             : 
      24             : #include "vcl/svapp.hxx"
      25             : #include "vcl/help.hxx"
      26             : #include "vcl/event.hxx"
      27             : #include "vcl/menu.hxx"
      28             : #include "vcl/button.hxx"
      29             : #include "vcl/tabpage.hxx"
      30             : #include "vcl/tabctrl.hxx"
      31             : #include "vcl/controllayout.hxx"
      32             : #include "vcl/lstbox.hxx"
      33             : 
      34             : #include "controldata.hxx"
      35             : #include "svdata.hxx"
      36             : #include "window.h"
      37             : 
      38             : #include <boost/unordered_map.hpp>
      39             : #include <vector>
      40             : 
      41             : // =======================================================================
      42             : 
      43           0 : struct ImplTabItem
      44             : {
      45             :     sal_uInt16          mnId;
      46             :     TabPage*            mpTabPage;
      47             :     String              maText;
      48             :     String              maFormatText;
      49             :     String              maHelpText;
      50             :     OString             maHelpId;
      51             :     OString             maTabName;
      52             :     Rectangle           maRect;
      53             :     sal_uInt16          mnLine;
      54             :     bool                mbFullVisible;
      55             :     bool                mbEnabled;
      56             :     Image               maTabImage;
      57             : 
      58           0 :     ImplTabItem()
      59             :     : mnId( 0 ), mpTabPage( NULL ),
      60           0 :       mnLine( 0 ), mbFullVisible( sal_False ), mbEnabled( true )
      61           0 :     {}
      62             : };
      63             : 
      64             : // -----------------------------------------------------------------------
      65             : 
      66           0 : struct ImplTabCtrlData
      67             : {
      68             :     boost::unordered_map< int, int >        maLayoutPageIdToLine;
      69             :     boost::unordered_map< int, int >        maLayoutLineToPageId;
      70             :     std::vector< Rectangle >        maTabRectangles;
      71             :     Point                           maItemsOffset;       // offset of the tabitems
      72             :     std::vector< ImplTabItem >      maItemList;
      73             :     ListBox*                        mpListBox;
      74             : };
      75             : 
      76             : // -----------------------------------------------------------------------
      77             : 
      78             : #define TAB_OFFSET          3
      79             : #define TAB_TABOFFSET_X     3
      80             : #define TAB_TABOFFSET_Y     3
      81             : #define TAB_EXTRASPACE_X    6
      82             : #define TAB_BORDER_LEFT     1
      83             : #define TAB_BORDER_TOP      1
      84             : #define TAB_BORDER_RIGHT    2
      85             : #define TAB_BORDER_BOTTOM   2
      86             : 
      87             : // Fuer die Ermittlung von den Tab-Positionen
      88             : #define TAB_PAGERECT        0xFFFF
      89             : 
      90             : // =======================================================================
      91             : 
      92           0 : void TabControl::ImplInit( Window* pParent, WinBits nStyle )
      93             : {
      94           0 :     mbLayoutDirty = true;
      95             : 
      96           0 :     if ( !(nStyle & WB_NOTABSTOP) )
      97           0 :         nStyle |= WB_TABSTOP;
      98           0 :     if ( !(nStyle & WB_NOGROUP) )
      99           0 :         nStyle |= WB_GROUP;
     100           0 :     if ( !(nStyle & WB_NODIALOGCONTROL) )
     101           0 :         nStyle |= WB_DIALOGCONTROL;
     102             : 
     103           0 :     Control::ImplInit( pParent, nStyle, NULL );
     104             : 
     105           0 :     mnLastWidth                 = 0;
     106           0 :     mnLastHeight                = 0;
     107           0 :     mnBtnSize                   = 0;
     108           0 :     mnMaxPageWidth              = 0;
     109           0 :     mnActPageId                 = 0;
     110           0 :     mnCurPageId                 = 0;
     111           0 :     mbFormat                    = sal_True;
     112           0 :     mbRestoreHelpId             = sal_False;
     113           0 :     mbRestoreUnqId              = sal_False;
     114           0 :     mbSmallInvalidate           = sal_False;
     115           0 :     mpTabCtrlData               = new ImplTabCtrlData;
     116           0 :     mpTabCtrlData->mpListBox    = NULL;
     117             : 
     118             : 
     119           0 :     ImplInitSettings( sal_True, sal_True, sal_True );
     120             : 
     121           0 :     if( (nStyle & WB_DROPDOWN) )
     122             :     {
     123           0 :         mpTabCtrlData->mpListBox = new ListBox( this, WB_DROPDOWN );
     124           0 :         mpTabCtrlData->mpListBox->SetPosSizePixel( Point( 0, 0 ), Size( 200, 20 ) );
     125           0 :         mpTabCtrlData->mpListBox->SetSelectHdl( LINK( this, TabControl, ImplListBoxSelectHdl ) );
     126           0 :         mpTabCtrlData->mpListBox->Show();
     127             :     }
     128             : 
     129             :     // if the tabcontrol is drawn (ie filled) by a native widget, make sure all contols will have transparent background
     130             :     // otherwise they will paint with a wrong background
     131           0 :     if( IsNativeControlSupported(CTRL_TAB_PANE, PART_ENTIRE_CONTROL) )
     132           0 :         EnableChildTransparentMode( sal_True );
     133             : 
     134           0 :     if ( pParent->IsDialog() )
     135           0 :         pParent->AddChildEventListener( LINK( this, TabControl, ImplWindowEventListener ) );
     136           0 : }
     137             : 
     138             : // -----------------------------------------------------------------
     139             : 
     140           0 : const Font& TabControl::GetCanonicalFont( const StyleSettings& _rStyle ) const
     141             : {
     142           0 :     return _rStyle.GetAppFont();
     143             : }
     144             : 
     145             : // -----------------------------------------------------------------
     146           0 : const Color& TabControl::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
     147             : {
     148           0 :     return _rStyle.GetButtonTextColor();
     149             : }
     150             : 
     151             : // -----------------------------------------------------------------------
     152             : 
     153           0 : void TabControl::ImplInitSettings( sal_Bool bFont,
     154             :                                    sal_Bool bForeground, sal_Bool bBackground )
     155             : {
     156           0 :     Control::ImplInitSettings( bFont, bForeground );
     157             : 
     158           0 :     if ( bBackground )
     159             :     {
     160           0 :         Window* pParent = GetParent();
     161           0 :         if ( !IsControlBackground() &&
     162           0 :             (pParent->IsChildTransparentModeEnabled()
     163           0 :             || IsNativeControlSupported(CTRL_TAB_PANE, PART_ENTIRE_CONTROL)
     164           0 :             || IsNativeControlSupported(CTRL_TAB_ITEM, PART_ENTIRE_CONTROL) ) )
     165             : 
     166             :         {
     167             :             // set transparent mode for NWF tabcontrols to have
     168             :             // the background always cleared properly
     169           0 :             EnableChildTransparentMode( sal_True );
     170           0 :             SetParentClipMode( PARENTCLIPMODE_NOCLIP );
     171           0 :             SetPaintTransparent( sal_True );
     172           0 :             SetBackground();
     173           0 :             ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
     174             :         }
     175             :         else
     176             :         {
     177           0 :             EnableChildTransparentMode( sal_False );
     178           0 :             SetParentClipMode( 0 );
     179           0 :             SetPaintTransparent( sal_False );
     180             : 
     181           0 :             if ( IsControlBackground() )
     182           0 :                 SetBackground( GetControlBackground() );
     183             :             else
     184           0 :                 SetBackground( pParent->GetBackground() );
     185             :         }
     186             :     }
     187           0 : }
     188             : 
     189             : // -----------------------------------------------------------------------
     190             : 
     191           0 : void TabControl::ImplFreeLayoutData()
     192             : {
     193           0 :     if( HasLayoutData() )
     194             :     {
     195           0 :         ImplClearLayoutData();
     196           0 :         mpTabCtrlData->maLayoutPageIdToLine.clear();
     197           0 :         mpTabCtrlData->maLayoutLineToPageId.clear();
     198             :     }
     199           0 : }
     200             : 
     201             : // -----------------------------------------------------------------------
     202             : 
     203           0 : TabControl::TabControl( Window* pParent, WinBits nStyle ) :
     204           0 :     Control( WINDOW_TABCONTROL )
     205             : {
     206           0 :     ImplInit( pParent, nStyle );
     207             :     OSL_TRACE("*** TABCONTROL no notabs? %s", ( GetStyle() & WB_NOBORDER ) ? "true" : "false" );
     208           0 : }
     209             : 
     210             : // -----------------------------------------------------------------------
     211             : 
     212           0 : TabControl::TabControl( Window* pParent, const ResId& rResId ) :
     213           0 :     Control( WINDOW_TABCONTROL )
     214             : {
     215           0 :     rResId.SetRT( RSC_TABCONTROL );
     216           0 :     WinBits nStyle = ImplInitRes( rResId );
     217           0 :     ImplInit( pParent, nStyle );
     218           0 :     ImplLoadRes( rResId );
     219             : 
     220           0 :     if ( !(nStyle & WB_HIDE) )
     221           0 :         Show();
     222           0 : }
     223             : 
     224             : // -----------------------------------------------------------------------
     225             : 
     226           0 : void TabControl::ImplLoadRes( const ResId& rResId )
     227             : {
     228           0 :     Control::ImplLoadRes( rResId );
     229             : 
     230           0 :     sal_uLong nObjMask = ReadLongRes();
     231             : 
     232           0 :     if ( nObjMask & RSC_TABCONTROL_ITEMLIST )
     233             :     {
     234           0 :         sal_uLong nEle = ReadLongRes();
     235             : 
     236             :         // Item hinzufuegen
     237           0 :         for( sal_uLong i = 0; i < nEle; i++ )
     238             :         {
     239           0 :             InsertPage( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
     240           0 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
     241             :         }
     242             :     }
     243           0 : }
     244             : 
     245             : // -----------------------------------------------------------------------
     246             : 
     247           0 : TabControl::~TabControl()
     248             : {
     249           0 :     if ( GetParent()->IsDialog() )
     250           0 :         GetParent()->RemoveChildEventListener( LINK( this, TabControl, ImplWindowEventListener ) );
     251             : 
     252           0 :     ImplFreeLayoutData();
     253             : 
     254             :     // TabCtrl-Daten loeschen
     255           0 :     if ( mpTabCtrlData )
     256             :     {
     257           0 :         if( mpTabCtrlData->mpListBox )
     258           0 :             delete mpTabCtrlData->mpListBox;
     259           0 :         delete mpTabCtrlData;
     260             :     }
     261           0 : }
     262             : 
     263             : // -----------------------------------------------------------------------
     264             : 
     265           0 : ImplTabItem* TabControl::ImplGetItem( sal_uInt16 nId ) const
     266             : {
     267           0 :     for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
     268           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
     269             :     {
     270           0 :         if( it->mnId == nId )
     271           0 :             return &(*it);
     272             :     }
     273             : 
     274           0 :     return NULL;
     275             : }
     276             : 
     277             : // -----------------------------------------------------------------------
     278             : 
     279           0 : Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth )
     280             : {
     281           0 :     pItem->maFormatText = pItem->maText;
     282           0 :     Size aSize( GetCtrlTextWidth( pItem->maFormatText ), GetTextHeight() );
     283           0 :     Size aImageSize( 0, 0 );
     284           0 :     if( !!pItem->maTabImage )
     285             :     {
     286           0 :         aImageSize = pItem->maTabImage.GetSizePixel();
     287           0 :         if( pItem->maFormatText.Len() )
     288           0 :             aImageSize.Width() += GetTextHeight()/4;
     289             :     }
     290           0 :     aSize.Width() += aImageSize.Width();
     291           0 :     if( aImageSize.Height() > aSize.Height() )
     292           0 :         aSize.Height() = aImageSize.Height();
     293             : 
     294           0 :     aSize.Width()  += TAB_TABOFFSET_X*2;
     295           0 :     aSize.Height() += TAB_TABOFFSET_Y*2;
     296             : 
     297           0 :     Rectangle aCtrlRegion( Point( 0, 0 ), aSize );
     298           0 :     Rectangle aBoundingRgn, aContentRgn;
     299           0 :     const ImplControlValue aControlValue;
     300           0 :     if(GetNativeControlRegion( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, aCtrlRegion,
     301             :                                            CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
     302           0 :                                            aBoundingRgn, aContentRgn ) )
     303             :     {
     304           0 :         return aContentRgn.GetSize();
     305             :     }
     306             : 
     307             :     // For languages with short names (e.g. Chinese), because the space is
     308             :     // normally only one pixel per char
     309           0 :     if ( pItem->maFormatText.Len() < TAB_EXTRASPACE_X )
     310           0 :         aSize.Width() += TAB_EXTRASPACE_X-pItem->maFormatText.Len();
     311             : 
     312             :     // Evt. den Text kuerzen
     313           0 :     if ( aSize.Width()+4 >= nMaxWidth )
     314             :     {
     315           0 :         rtl::OUString aAppendStr("...");
     316           0 :         pItem->maFormatText += aAppendStr;
     317           0 :         do
     318             :         {
     319           0 :             pItem->maFormatText.Erase( pItem->maFormatText.Len()-aAppendStr.getLength()-1, 1 );
     320           0 :             aSize.Width() = GetCtrlTextWidth( pItem->maFormatText );
     321           0 :             aSize.Width() += aImageSize.Width();
     322           0 :             aSize.Width() += TAB_TABOFFSET_X*2;
     323             :         }
     324           0 :         while ( (aSize.Width()+4 >= nMaxWidth) && (pItem->maFormatText.Len() > aAppendStr.getLength()) );
     325           0 :         if ( aSize.Width()+4 >= nMaxWidth )
     326             :         {
     327           0 :             pItem->maFormatText.Assign( '.' );
     328           0 :             aSize.Width() = 1;
     329           0 :         }
     330             :     }
     331             : 
     332           0 :     if( pItem->maFormatText.Len() == 0 )
     333             :     {
     334           0 :         if( aSize.Height() < aImageSize.Height()+4 ) //leave space for focus rect
     335           0 :             aSize.Height() = aImageSize.Height()+4;
     336             :     }
     337             : 
     338           0 :     return aSize;
     339             : }
     340             : 
     341             : // -----------------------------------------------------------------------
     342             : 
     343           0 : Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, long nHeight )
     344             : {
     345           0 :     Size aWinSize = Control::GetOutputSizePixel();
     346           0 :     if ( nWidth < 0 )
     347           0 :         nWidth = aWinSize.Width();
     348           0 :     if ( nHeight < 0 )
     349           0 :         nHeight = aWinSize.Height();
     350             : 
     351           0 :     if ( mpTabCtrlData->maItemList.empty() )
     352             :     {
     353           0 :         long nW = nWidth-TAB_OFFSET*2;
     354           0 :         long nH = nHeight-TAB_OFFSET*2;
     355             :         return (nW > 0 && nH > 0)
     356             :         ? Rectangle( Point( TAB_OFFSET, TAB_OFFSET ), Size( nW, nH ) )
     357           0 :         : Rectangle();
     358             :     }
     359             : 
     360           0 :     if ( nItemPos == TAB_PAGERECT )
     361             :     {
     362             :         sal_uInt16 nLastPos;
     363           0 :         if ( mnCurPageId )
     364           0 :             nLastPos = GetPagePos( mnCurPageId );
     365             :         else
     366           0 :             nLastPos = 0;
     367             : 
     368           0 :         Rectangle aRect = ImplGetTabRect( nLastPos, nWidth, nHeight );
     369           0 :         long nW = nWidth-TAB_OFFSET*2;
     370           0 :         long nH = nHeight-aRect.Bottom()-TAB_OFFSET*2;
     371             :         aRect = (nW > 0 && nH > 0)
     372           0 :         ? Rectangle( Point( TAB_OFFSET, aRect.Bottom()+TAB_OFFSET ), Size( nW, nH ) )
     373           0 :         : Rectangle();
     374           0 :         return aRect;
     375             :     }
     376             : 
     377           0 :     nWidth -= 1;
     378             : 
     379           0 :     if ( (nWidth <= 0) || (nHeight <= 0) )
     380           0 :         return Rectangle();
     381             : 
     382           0 :     if ( mbFormat || (mnLastWidth != nWidth) || (mnLastHeight != nHeight) )
     383             :     {
     384           0 :         Font aFont( GetFont() );
     385           0 :         aFont.SetTransparent( sal_True );
     386           0 :         SetFont( aFont );
     387             : 
     388           0 :         Size            aSize;
     389           0 :         const long      nOffsetX = 2 + GetItemsOffset().X();
     390           0 :         const long      nOffsetY = 2 + GetItemsOffset().Y();
     391           0 :         long            nX = nOffsetX;
     392           0 :         long            nY = nOffsetY;
     393           0 :         long            nMaxWidth = nWidth;
     394           0 :         sal_uInt16          nPos = 0;
     395             : 
     396           0 :         if ( (mnMaxPageWidth > 0) && (mnMaxPageWidth < nMaxWidth) )
     397           0 :             nMaxWidth = mnMaxPageWidth;
     398           0 :         nMaxWidth -= GetItemsOffset().X();
     399             : 
     400           0 :         sal_uInt16          nLines = 0;
     401           0 :         sal_uInt16          nCurLine = 0;
     402             :         long            nLineWidthAry[100];
     403             :         sal_uInt16          nLinePosAry[101];
     404             : 
     405           0 :         nLineWidthAry[0] = 0;
     406           0 :         nLinePosAry[0] = 0;
     407           0 :         for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin();
     408           0 :              it != mpTabCtrlData->maItemList.end(); ++it )
     409             :         {
     410           0 :             aSize = ImplGetItemSize( &(*it), nMaxWidth );
     411             : 
     412           0 :             if ( ((nX+aSize.Width()) > nWidth - 2) && (nWidth > 2+nOffsetX) )
     413             :             {
     414           0 :                 if ( nLines == 99 )
     415             :                     break;
     416             : 
     417           0 :                 nX  = nOffsetX;
     418           0 :                 nY += aSize.Height();
     419           0 :                 nLines++;
     420           0 :                 nLineWidthAry[nLines] = 0;
     421           0 :                 nLinePosAry[nLines] = nPos;
     422             :             }
     423             : 
     424           0 :             Rectangle aNewRect( Point( nX, nY ), aSize );
     425           0 :             if ( mbSmallInvalidate && (it->maRect != aNewRect) )
     426           0 :                 mbSmallInvalidate = sal_False;
     427           0 :             it->maRect = aNewRect;
     428           0 :             it->mnLine = nLines;
     429           0 :             it->mbFullVisible = sal_True;
     430             : 
     431           0 :             nLineWidthAry[nLines] += aSize.Width();
     432           0 :             nX += aSize.Width();
     433             : 
     434           0 :             if ( it->mnId == mnCurPageId )
     435           0 :                 nCurLine = nLines;
     436             : 
     437           0 :             nPos++;
     438             :         }
     439             : 
     440           0 :         if ( nLines && !mpTabCtrlData->maItemList.empty() )
     441             :         {
     442           0 :             long    nDX = 0;
     443           0 :             long    nModDX = 0;
     444           0 :             long    nIDX = 0;
     445             :             sal_uInt16  i;
     446             :             sal_uInt16  n;
     447             :             long    nLineHeightAry[100];
     448           0 :             long    nIH = mpTabCtrlData->maItemList[0].maRect.Bottom()-2;
     449             : 
     450           0 :             i = 0;
     451           0 :             while ( i < nLines+1 )
     452             :             {
     453           0 :                 if ( i <= nCurLine )
     454           0 :                     nLineHeightAry[i] = nIH*(nLines-(nCurLine-i)) + GetItemsOffset().Y();
     455             :                 else
     456           0 :                     nLineHeightAry[i] = nIH*(i-nCurLine-1) + GetItemsOffset().Y();
     457           0 :                 i++;
     458             :             }
     459             : 
     460           0 :             i = 0;
     461           0 :             n = 0;
     462           0 :             nLinePosAry[nLines+1] = (sal_uInt16)mpTabCtrlData->maItemList.size();
     463           0 :             for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
     464           0 :                  it != mpTabCtrlData->maItemList.end(); ++it )
     465             :             {
     466           0 :                 if ( i == nLinePosAry[n] )
     467             :                 {
     468           0 :                     if ( n == nLines+1 )
     469           0 :                         break;
     470             : 
     471           0 :                     nIDX = 0;
     472           0 :                     if( nLinePosAry[n+1]-i > 0 )
     473             :                     {
     474           0 :                         nDX = (nWidth-nOffsetX-nLineWidthAry[n]) / (nLinePosAry[n+1]-i);
     475           0 :                         nModDX = (nWidth-nOffsetX-nLineWidthAry[n]) % (nLinePosAry[n+1]-i);
     476             :                     }
     477             :                     else
     478             :                     {
     479             :                         // FIXME: this is a bad case of tabctrl way too small
     480           0 :                         nDX = 0;
     481           0 :                         nModDX = 0;
     482             :                     }
     483           0 :                     n++;
     484             :                 }
     485             : 
     486           0 :                 it->maRect.Left()   += nIDX;
     487           0 :                 it->maRect.Right()  += nIDX+nDX;
     488           0 :                 it->maRect.Top()     = nLineHeightAry[n-1];
     489           0 :                 it->maRect.Bottom()  = nLineHeightAry[n-1]+nIH;
     490           0 :                 nIDX += nDX;
     491             : 
     492           0 :                 if ( nModDX )
     493             :                 {
     494           0 :                     nIDX++;
     495           0 :                     it->maRect.Right()++;
     496           0 :                     nModDX--;
     497             :                 }
     498             : 
     499           0 :                 i++;
     500             :             }
     501             :         }
     502             :         else
     503             :         {//only one line
     504           0 :             if(ImplGetSVData()->maNWFData.mbCenteredTabs)
     505             :             {
     506           0 :                 int nRightSpace=nMaxWidth;//space left on the right by the tabs
     507           0 :                 for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
     508           0 :                      it != mpTabCtrlData->maItemList.end(); ++it )
     509             :                 {
     510           0 :                     nRightSpace-=it->maRect.Right()-it->maRect.Left();
     511             :                 }
     512           0 :                 for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
     513           0 :                      it != mpTabCtrlData->maItemList.end(); ++it )
     514             :                 {
     515           0 :                     it->maRect.Left()+=(int) (nRightSpace/2);
     516           0 :                     it->maRect.Right()+=(int) (nRightSpace/2);
     517             :                 }
     518             :             }
     519             :         }
     520             : 
     521           0 :         mnLastWidth     = nWidth;
     522           0 :         mnLastHeight    = nHeight;
     523           0 :         mbFormat        = sal_False;
     524             :     }
     525             : 
     526           0 :     return size_t(nItemPos) < mpTabCtrlData->maItemList.size() ? mpTabCtrlData->maItemList[nItemPos].maRect : Rectangle();
     527             : }
     528             : 
     529             : // -----------------------------------------------------------------------
     530             : 
     531           0 : void TabControl::ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId )
     532             : {
     533           0 :     ImplFreeLayoutData();
     534             : 
     535           0 :     ImplTabItem*    pOldItem = ImplGetItem( nOldId );
     536           0 :     ImplTabItem*    pItem = ImplGetItem( nId );
     537           0 :     TabPage*        pOldPage = (pOldItem) ? pOldItem->mpTabPage : NULL;
     538           0 :     TabPage*        pPage = (pItem) ? pItem->mpTabPage : NULL;
     539           0 :     Window*         pCtrlParent = GetParent();
     540             : 
     541           0 :     if ( IsReallyVisible() && IsUpdateMode() )
     542             :     {
     543           0 :         sal_uInt16 nPos = GetPagePos( nId );
     544           0 :         Rectangle aRect = ImplGetTabRect( nPos );
     545             : 
     546           0 :         if ( !pOldItem || (pOldItem->mnLine != pItem->mnLine) )
     547             :         {
     548           0 :             aRect.Left() = 0;
     549           0 :             aRect.Top() = 0;
     550           0 :             aRect.Right() = Control::GetOutputSizePixel().Width();
     551             :         }
     552             :         else
     553             :         {
     554           0 :             aRect.Left()    -= 3;
     555           0 :             aRect.Top()     -= 2;
     556           0 :             aRect.Right()   += 3;
     557           0 :             Invalidate( aRect );
     558           0 :             nPos = GetPagePos( nOldId );
     559           0 :             aRect = ImplGetTabRect( nPos );
     560           0 :             aRect.Left()    -= 3;
     561           0 :             aRect.Top()     -= 2;
     562           0 :             aRect.Right()   += 3;
     563             :         }
     564           0 :         Invalidate( aRect );
     565             :     }
     566             : 
     567           0 :     if ( pOldPage == pPage )
     568           0 :         return;
     569             : 
     570           0 :     Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
     571             : 
     572           0 :     if ( pOldPage )
     573             :     {
     574           0 :         if ( mbRestoreHelpId )
     575           0 :             pCtrlParent->SetHelpId( rtl::OString() );
     576           0 :         if ( mbRestoreUnqId )
     577           0 :             pCtrlParent->SetUniqueId( rtl::OString() );
     578           0 :         pOldPage->DeactivatePage();
     579             :     }
     580             : 
     581           0 :     if ( pPage )
     582             :     {
     583           0 :         if (  ( GetStyle() & WB_NOBORDER ) )
     584             :         {
     585           0 :             Rectangle aRectNoTab( (const Point&)Point( 0, 0 ), GetSizePixel() );
     586           0 :             pPage->SetPosSizePixel( aRectNoTab.TopLeft(), aRectNoTab.GetSize() );
     587             :         }
     588             :         else
     589           0 :             pPage->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
     590             : 
     591             :         // activate page here so the conbtrols can be switched
     592             :         // also set the help id of the parent window to that of the tab page
     593           0 :         if ( GetHelpId().isEmpty() )
     594             :         {
     595           0 :             mbRestoreHelpId = sal_True;
     596           0 :             pCtrlParent->SetHelpId( pPage->GetHelpId() );
     597             :         }
     598           0 :         if ( pCtrlParent->GetUniqueId().isEmpty() )
     599             :         {
     600           0 :             mbRestoreUnqId = sal_True;
     601           0 :             pCtrlParent->SetUniqueId( pPage->GetUniqueId() );
     602             :         }
     603             : 
     604           0 :         pPage->ActivatePage();
     605             : 
     606           0 :         if ( pOldPage && pOldPage->HasChildPathFocus() )
     607             :         {
     608           0 :             sal_uInt16  n = 0;
     609           0 :             Window* pFirstChild = pPage->ImplGetDlgWindow( n, DLGWINDOW_FIRST );
     610           0 :             if ( pFirstChild )
     611           0 :                 pFirstChild->ImplControlFocus( GETFOCUS_INIT );
     612             :             else
     613           0 :                 GrabFocus();
     614             :         }
     615             : 
     616           0 :         pPage->Show();
     617             :     }
     618             : 
     619           0 :     if ( pOldPage )
     620           0 :         pOldPage->Hide();
     621             : 
     622             :     // Invalidate the same region that will be send to NWF
     623             :     // to always allow for bitmap caching
     624             :     // see Window::DrawNativeControl()
     625           0 :     if( IsNativeControlSupported( CTRL_TAB_PANE, PART_ENTIRE_CONTROL ) )
     626             :     {
     627           0 :         aRect.Left()   -= TAB_OFFSET;
     628           0 :         aRect.Top()    -= TAB_OFFSET;
     629           0 :         aRect.Right()  += TAB_OFFSET;
     630           0 :         aRect.Bottom() += TAB_OFFSET;
     631             :     }
     632             : 
     633           0 :     Invalidate( aRect );
     634             : }
     635             : 
     636             : // -----------------------------------------------------------------------
     637             : 
     638           0 : sal_Bool TabControl::ImplPosCurTabPage()
     639             : {
     640             :     // Aktuelle TabPage resizen/positionieren
     641           0 :     ImplTabItem* pItem = ImplGetItem( GetCurPageId() );
     642           0 :     if ( pItem && pItem->mpTabPage )
     643             :     {
     644           0 :         if (  ( GetStyle() & WB_NOBORDER ) )
     645             :         {
     646           0 :             Rectangle aRectNoTab( (const Point&)Point( 0, 0 ), GetSizePixel() );
     647           0 :             pItem->mpTabPage->SetPosSizePixel( aRectNoTab.TopLeft(), aRectNoTab.GetSize() );
     648           0 :             return sal_True;
     649             :         }
     650           0 :         Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
     651           0 :         pItem->mpTabPage->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
     652           0 :         return sal_True;
     653             :     }
     654             : 
     655           0 :     return sal_False;
     656             : }
     657             : 
     658             : // -----------------------------------------------------------------------
     659             : 
     660           0 : void TabControl::ImplActivateTabPage( sal_Bool bNext )
     661             : {
     662           0 :     sal_uInt16 nCurPos = GetPagePos( GetCurPageId() );
     663             : 
     664           0 :     if ( bNext )
     665           0 :         nCurPos = (nCurPos + 1) % GetPageCount();
     666             :     else
     667             :     {
     668           0 :         if ( !nCurPos )
     669           0 :             nCurPos = GetPageCount()-1;
     670             :         else
     671           0 :             nCurPos--;
     672             :     }
     673             : 
     674           0 :     SelectTabPage( GetPageId( nCurPos ) );
     675           0 : }
     676             : 
     677             : // -----------------------------------------------------------------------
     678             : 
     679           0 : void TabControl::ImplShowFocus()
     680             : {
     681           0 :     if ( !GetPageCount() || mpTabCtrlData->mpListBox )
     682           0 :         return;
     683             : 
     684           0 :     sal_uInt16                   nCurPos     = GetPagePos( mnCurPageId );
     685           0 :     Rectangle                aRect       = ImplGetTabRect( nCurPos );
     686           0 :     const ImplTabItem&       rItem       = mpTabCtrlData->maItemList[ nCurPos ];
     687           0 :     Size                     aTabSize    = aRect.GetSize();
     688           0 :     Size aImageSize( 0, 0 );
     689           0 :     long                     nTextHeight = GetTextHeight();
     690           0 :     long                     nTextWidth  = GetCtrlTextWidth( rItem.maFormatText );
     691             :     sal_uInt16                   nOff;
     692             : 
     693           0 :     if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_MONO) )
     694           0 :         nOff = 1;
     695             :     else
     696           0 :         nOff = 0;
     697             : 
     698           0 :     if( !! rItem.maTabImage )
     699             :     {
     700           0 :         aImageSize = rItem.maTabImage.GetSizePixel();
     701           0 :         if( rItem.maFormatText.Len() )
     702           0 :             aImageSize.Width() += GetTextHeight()/4;
     703             :     }
     704             : 
     705           0 :     if( rItem.maFormatText.Len() )
     706             :     {
     707             :         // show focus around text
     708           0 :         aRect.Left()   = aRect.Left()+aImageSize.Width()+((aTabSize.Width()-nTextWidth-aImageSize.Width())/2)-nOff-1-1;
     709           0 :         aRect.Top()    = aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-1-1;
     710           0 :         aRect.Right()  = aRect.Left()+nTextWidth+2;
     711           0 :         aRect.Bottom() = aRect.Top()+nTextHeight+2;
     712             :     }
     713             :     else
     714             :     {
     715             :         // show focus around image
     716           0 :         long nXPos = aRect.Left()+((aTabSize.Width()-nTextWidth-aImageSize.Width())/2)-nOff-1;
     717           0 :         long nYPos = aRect.Top();
     718           0 :         if( aImageSize.Height() < aRect.GetHeight() )
     719           0 :             nYPos += (aRect.GetHeight() - aImageSize.Height())/2;
     720             : 
     721           0 :         aRect.Left() = nXPos - 2;
     722           0 :         aRect.Top() = nYPos - 2;
     723           0 :         aRect.Right() = aRect.Left() + aImageSize.Width() + 4;
     724           0 :         aRect.Bottom() = aRect.Top() + aImageSize.Height() + 4;
     725             :     }
     726           0 :     ShowFocus( aRect );
     727             : }
     728             : 
     729             : // -----------------------------------------------------------------------
     730             : 
     731           0 : void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bool bLayout, bool bFirstInGroup, bool bLastInGroup, bool /* bIsCurrentItem */ )
     732             : {
     733           0 :     if ( pItem->maRect.IsEmpty() )
     734           0 :         return;
     735             : 
     736           0 :     if( bLayout )
     737             :     {
     738           0 :         if( !HasLayoutData() )
     739             :         {
     740           0 :             mpControlData->mpLayoutData = new vcl::ControlLayoutData();
     741           0 :             mpTabCtrlData->maLayoutLineToPageId.clear();
     742           0 :             mpTabCtrlData->maLayoutPageIdToLine.clear();
     743           0 :             mpTabCtrlData->maTabRectangles.clear();
     744             :         }
     745             :     }
     746             : 
     747           0 :     const StyleSettings&    rStyleSettings  = GetSettings().GetStyleSettings();
     748           0 :     Rectangle               aRect = pItem->maRect;
     749           0 :     long                    nLeftBottom = aRect.Bottom();
     750           0 :     long                    nRightBottom = aRect.Bottom();
     751           0 :     sal_Bool                    bLeftBorder = sal_True;
     752           0 :     sal_Bool                    bRightBorder = sal_True;
     753             :     sal_uInt16                  nOff;
     754           0 :     sal_Bool                    bNativeOK = sal_False;
     755             : 
     756           0 :     sal_uInt16 nOff2 = 0;
     757           0 :     sal_uInt16 nOff3 = 0;
     758             : 
     759           0 :     if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
     760           0 :         nOff = 1;
     761             :     else
     762           0 :         nOff = 0;
     763             : 
     764             :     // Wenn wir die aktuelle Page sind, muessen wir etwas mehr zeichnen
     765           0 :     if ( pItem->mnId == mnCurPageId )
     766             :     {
     767           0 :         nOff2 = 2;
     768           0 :         if( ! ImplGetSVData()->maNWFData.mbNoActiveTabTextRaise )
     769           0 :             nOff3 = 1;
     770             :     }
     771             :     else
     772             :     {
     773           0 :         Point aLeftTestPos = aRect.BottomLeft();
     774           0 :         Point aRightTestPos = aRect.BottomRight();
     775           0 :         if ( aLeftTestPos.Y() == rCurRect.Bottom() )
     776             :         {
     777           0 :             aLeftTestPos.X() -= 2;
     778           0 :             if ( rCurRect.IsInside( aLeftTestPos ) )
     779           0 :                 bLeftBorder = sal_False;
     780           0 :             aRightTestPos.X() += 2;
     781           0 :             if ( rCurRect.IsInside( aRightTestPos ) )
     782           0 :                 bRightBorder = sal_False;
     783             :         }
     784             :         else
     785             :         {
     786           0 :             if ( rCurRect.IsInside( aLeftTestPos ) )
     787           0 :                 nLeftBottom -= 2;
     788           0 :             if ( rCurRect.IsInside( aRightTestPos ) )
     789           0 :                 nRightBottom -= 2;
     790             :         }
     791             :     }
     792             : 
     793           0 :     if( !bLayout && (bNativeOK = IsNativeControlSupported(CTRL_TAB_ITEM, PART_ENTIRE_CONTROL)) == sal_True )
     794             :     {
     795           0 :         Rectangle           aCtrlRegion( pItem->maRect );
     796           0 :         ControlState        nState = 0;
     797             : 
     798           0 :         if( pItem->mnId == mnCurPageId )
     799             :         {
     800           0 :             nState |= CTRL_STATE_SELECTED;
     801             :             // only the selected item can be focussed
     802           0 :             if ( HasFocus() )
     803           0 :                 nState |= CTRL_STATE_FOCUSED;
     804             :         }
     805           0 :         if ( IsEnabled() )
     806           0 :             nState |= CTRL_STATE_ENABLED;
     807           0 :         if( IsMouseOver() && pItem->maRect.IsInside( GetPointerPosPixel() ) )
     808             :         {
     809           0 :             nState |= CTRL_STATE_ROLLOVER;
     810           0 :             for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
     811           0 :                  it != mpTabCtrlData->maItemList.end(); ++it )
     812             :             {
     813           0 :                 if( (&(*it) != pItem) && (it->maRect.IsInside( GetPointerPosPixel() ) ) )
     814             :                 {
     815           0 :                     nState &= ~CTRL_STATE_ROLLOVER; // avoid multiple highlighted tabs
     816           0 :                     break;
     817             :                 }
     818             :             }
     819             :         }
     820             : 
     821           0 :         TabitemValue tiValue;
     822           0 :         if(pItem->maRect.Left() < 5)
     823           0 :             tiValue.mnAlignment |= TABITEM_LEFTALIGNED;
     824           0 :         if(pItem->maRect.Right() > mnLastWidth - 5)
     825           0 :             tiValue.mnAlignment |= TABITEM_RIGHTALIGNED;
     826           0 :         if ( bFirstInGroup )
     827           0 :             tiValue.mnAlignment |= TABITEM_FIRST_IN_GROUP;
     828           0 :         if ( bLastInGroup )
     829           0 :             tiValue.mnAlignment |= TABITEM_LAST_IN_GROUP;
     830             : 
     831             :         bNativeOK = DrawNativeControl( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
     832           0 :                     tiValue, rtl::OUString() );
     833             :     }
     834             : 
     835           0 :     if( ! bLayout && !bNativeOK )
     836             :     {
     837           0 :         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
     838             :         {
     839           0 :             SetLineColor( rStyleSettings.GetLightColor() );
     840           0 :             DrawPixel( Point( aRect.Left()+1-nOff2, aRect.Top()+1-nOff2 ) );    // diagonally indented top-left pixel
     841           0 :             if ( bLeftBorder )
     842             :             {
     843           0 :                 DrawLine( Point( aRect.Left()-nOff2, aRect.Top()+2-nOff2 ),
     844           0 :                           Point( aRect.Left()-nOff2, nLeftBottom-1 ) );
     845             :             }
     846           0 :             DrawLine( Point( aRect.Left()+2-nOff2, aRect.Top()-nOff2 ),         // top line starting 2px from left border
     847           0 :                       Point( aRect.Right()+nOff2-3, aRect.Top()-nOff2 ) );      // ending 3px from right border
     848             : 
     849           0 :             if ( bRightBorder )
     850             :             {
     851           0 :                 SetLineColor( rStyleSettings.GetShadowColor() );
     852           0 :                 DrawLine( Point( aRect.Right()+nOff2-2, aRect.Top()+1-nOff2 ),
     853           0 :                           Point( aRect.Right()+nOff2-2, nRightBottom-1 ) );
     854             : 
     855           0 :                 SetLineColor( rStyleSettings.GetDarkShadowColor() );
     856           0 :                 DrawLine( Point( aRect.Right()+nOff2-1, aRect.Top()+3-nOff2 ),
     857           0 :                           Point( aRect.Right()+nOff2-1, nRightBottom-1 ) );
     858             :             }
     859             :         }
     860             :         else
     861             :         {
     862           0 :             SetLineColor( Color( COL_BLACK ) );
     863           0 :             DrawPixel( Point( aRect.Left()+1-nOff2, aRect.Top()+1-nOff2 ) );
     864           0 :             DrawPixel( Point( aRect.Right()+nOff2-2, aRect.Top()+1-nOff2 ) );
     865           0 :             if ( bLeftBorder )
     866             :             {
     867           0 :                 DrawLine( Point( aRect.Left()-nOff2, aRect.Top()+2-nOff2 ),
     868           0 :                           Point( aRect.Left()-nOff2, nLeftBottom-1 ) );
     869             :             }
     870           0 :             DrawLine( Point( aRect.Left()+2-nOff2, aRect.Top()-nOff2 ),
     871           0 :                       Point( aRect.Right()-3, aRect.Top()-nOff2 ) );
     872           0 :             if ( bRightBorder )
     873             :             {
     874           0 :             DrawLine( Point( aRect.Right()+nOff2-1, aRect.Top()+2-nOff2 ),
     875           0 :                       Point( aRect.Right()+nOff2-1, nRightBottom-1 ) );
     876             :             }
     877             :         }
     878             :     }
     879             : 
     880           0 :     if( bLayout )
     881             :     {
     882           0 :         int nLine = mpControlData->mpLayoutData->m_aLineIndices.size();
     883           0 :         mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() );
     884           0 :         mpTabCtrlData->maLayoutPageIdToLine[ (int)pItem->mnId ] = nLine;
     885           0 :         mpTabCtrlData->maLayoutLineToPageId[ nLine ] = (int)pItem->mnId;
     886           0 :         mpTabCtrlData->maTabRectangles.push_back( aRect );
     887             :     }
     888             : 
     889             :     // set font accordingly, current item is painted bold
     890             :     // we set the font attributes always before drawing to be re-entrant (DrawNativeControl may trigger additional paints)
     891           0 :     Font aFont( GetFont() );
     892           0 :     aFont.SetTransparent( sal_True );
     893           0 :     SetFont( aFont );
     894             : 
     895           0 :     Size aTabSize = aRect.GetSize();
     896           0 :     Size aImageSize( 0, 0 );
     897           0 :     long nTextHeight = GetTextHeight();
     898           0 :     long nTextWidth = GetCtrlTextWidth( pItem->maFormatText );
     899           0 :     if( !! pItem->maTabImage )
     900             :     {
     901           0 :         aImageSize = pItem->maTabImage.GetSizePixel();
     902           0 :         if( pItem->maFormatText.Len() )
     903           0 :             aImageSize.Width() += GetTextHeight()/4;
     904             :     }
     905           0 :     long nXPos = aRect.Left()+((aTabSize.Width()-nTextWidth-aImageSize.Width())/2)-nOff-nOff3;
     906           0 :     long nYPos = aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-nOff3;
     907           0 :     if( pItem->maFormatText.Len() )
     908             :     {
     909           0 :         sal_uInt16 nStyle = TEXT_DRAW_MNEMONIC;
     910           0 :         if( ! pItem->mbEnabled )
     911           0 :             nStyle |= TEXT_DRAW_DISABLE;
     912           0 :         DrawCtrlText( Point( nXPos + aImageSize.Width(), nYPos ),
     913             :                       pItem->maFormatText,
     914             :                       0, STRING_LEN, nStyle,
     915             :                       bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL,
     916             :                       bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL
     917           0 :                       );
     918             :     }
     919             : 
     920           0 :     if( !! pItem->maTabImage )
     921             :     {
     922           0 :         Point aImgTL( nXPos, aRect.Top() );
     923           0 :         if( aImageSize.Height() < aRect.GetHeight() )
     924           0 :             aImgTL.Y() += (aRect.GetHeight() - aImageSize.Height())/2;
     925           0 :         DrawImage( aImgTL, pItem->maTabImage, pItem->mbEnabled ? 0 : IMAGE_DRAW_DISABLE );
     926           0 :     }
     927             : }
     928             : 
     929             : // -----------------------------------------------------------------------
     930             : 
     931           0 : long TabControl::ImplHandleKeyEvent( const KeyEvent& rKeyEvent )
     932             : {
     933           0 :     long nRet = 0;
     934             : 
     935           0 :     if ( GetPageCount() > 1 )
     936             :     {
     937           0 :         KeyCode         aKeyCode = rKeyEvent.GetKeyCode();
     938           0 :         sal_uInt16          nKeyCode = aKeyCode.GetCode();
     939             : 
     940           0 :         if ( aKeyCode.IsMod1() )
     941             :         {
     942           0 :             if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
     943             :             {
     944           0 :                 if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
     945             :                 {
     946           0 :                     ImplActivateTabPage( sal_False );
     947           0 :                     nRet = 1;
     948             :                 }
     949             :             }
     950             :             else
     951             :             {
     952           0 :                 if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
     953             :                 {
     954           0 :                     ImplActivateTabPage( sal_True );
     955           0 :                     nRet = 1;
     956             :                 }
     957             :             }
     958             :         }
     959             :     }
     960             : 
     961           0 :     return nRet;
     962             : }
     963             : 
     964             : 
     965             : // -----------------------------------------------------------------------
     966             : 
     967           0 : IMPL_LINK_NOARG(TabControl, ImplListBoxSelectHdl)
     968             : {
     969           0 :     SelectTabPage( GetPageId( mpTabCtrlData->mpListBox->GetSelectEntryPos() ) );
     970           0 :     return 0;
     971             : }
     972             : 
     973             : // -----------------------------------------------------------------------
     974             : 
     975           0 : IMPL_LINK( TabControl, ImplWindowEventListener, VclSimpleEvent*, pEvent )
     976             : {
     977           0 :     if ( pEvent && pEvent->ISA( VclWindowEvent ) && (pEvent->GetId() == VCLEVENT_WINDOW_KEYINPUT) )
     978             :     {
     979           0 :         VclWindowEvent* pWindowEvent = static_cast< VclWindowEvent* >(pEvent);
     980             :         // Do not handle events from TabControl or it's children, which is done in Notify(), where the events can be consumed.
     981           0 :         if ( !IsWindowOrChild( pWindowEvent->GetWindow() ) )
     982             :         {
     983           0 :             KeyEvent* pKeyEvent = static_cast< KeyEvent* >(pWindowEvent->GetData());
     984           0 :             ImplHandleKeyEvent( *pKeyEvent );
     985             :         }
     986             :     }
     987           0 :     return 0;
     988             : }
     989             : 
     990             : 
     991             : // -----------------------------------------------------------------------
     992             : 
     993           0 : void TabControl::MouseButtonDown( const MouseEvent& rMEvt )
     994             : {
     995           0 :     if( mpTabCtrlData->mpListBox == NULL )
     996             :     {
     997           0 :         if( rMEvt.IsLeft() )
     998             :         {
     999           0 :             sal_uInt16 nPageId = GetPageId( rMEvt.GetPosPixel() );
    1000           0 :             ImplTabItem* pItem = ImplGetItem( nPageId );
    1001           0 :             if( pItem && pItem->mbEnabled )
    1002           0 :                 SelectTabPage( nPageId );
    1003             :         }
    1004             :     }
    1005           0 : }
    1006             : 
    1007             : // -----------------------------------------------------------------------
    1008             : 
    1009           0 : void TabControl::KeyInput( const KeyEvent& rKEvt )
    1010             : {
    1011           0 :     if( mpTabCtrlData->mpListBox )
    1012           0 :         mpTabCtrlData->mpListBox->KeyInput( rKEvt );
    1013           0 :     else if ( GetPageCount() > 1 )
    1014             :     {
    1015           0 :         KeyCode aKeyCode = rKEvt.GetKeyCode();
    1016           0 :         sal_uInt16  nKeyCode = aKeyCode.GetCode();
    1017             : 
    1018           0 :         if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_RIGHT) )
    1019             :         {
    1020           0 :             sal_Bool bNext = (nKeyCode == KEY_RIGHT);
    1021           0 :             ImplActivateTabPage( bNext );
    1022             :         }
    1023             :     }
    1024             : 
    1025           0 :     Control::KeyInput( rKEvt );
    1026           0 : }
    1027             : 
    1028             : // -----------------------------------------------------------------------
    1029             : 
    1030           0 : void TabControl::Paint( const Rectangle& rRect )
    1031             : {
    1032           0 :     if (  !( GetStyle() & WB_NOBORDER ) )
    1033           0 :         ImplPaint( rRect, false );
    1034           0 : }
    1035             : 
    1036             : // -----------------------------------------------------------------------
    1037             : 
    1038           0 : void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout )
    1039             : {
    1040           0 :     if( ! bLayout )
    1041           0 :         HideFocus();
    1042             : 
    1043             :     // Hier wird gegebenenfalls auch neu formatiert
    1044           0 :     Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
    1045             : 
    1046             :     // find current item
    1047           0 :     ImplTabItem* pCurItem = NULL;
    1048           0 :     for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
    1049           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    1050             :     {
    1051           0 :         if ( it->mnId == mnCurPageId )
    1052             :         {
    1053           0 :             pCurItem = &(*it);
    1054           0 :             break;
    1055             :         }
    1056             :     }
    1057             : 
    1058             :     // Draw the TabPage border
    1059           0 :     const StyleSettings&    rStyleSettings  = GetSettings().GetStyleSettings();
    1060           0 :     Rectangle               aCurRect;
    1061           0 :     aRect.Left()   -= TAB_OFFSET;
    1062           0 :     aRect.Top()    -= TAB_OFFSET;
    1063           0 :     aRect.Right()  += TAB_OFFSET;
    1064           0 :     aRect.Bottom() += TAB_OFFSET;
    1065             : 
    1066             :     // if we have an invisible tabpage or no tabpage at all the tabpage rect should be
    1067             :     // increased to avoid round corners that might be drawn by a theme
    1068             :     // in this case we're only interested in the top border of the tabpage because the tabitems are used
    1069             :     // standalone (eg impress)
    1070           0 :     sal_Bool bNoTabPage = sal_False;
    1071           0 :     TabPage* pCurPage = pCurItem ? pCurItem->mpTabPage : NULL;
    1072           0 :     if( !pCurPage || !pCurPage->IsVisible() )
    1073             :     {
    1074           0 :         bNoTabPage = sal_True;
    1075           0 :         aRect.Left()-=10;
    1076           0 :         aRect.Right()+=10;
    1077             :     }
    1078             : 
    1079           0 :     sal_Bool bNativeOK = sal_False;
    1080           0 :     if( ! bLayout && (bNativeOK = IsNativeControlSupported( CTRL_TAB_PANE, PART_ENTIRE_CONTROL) ) == sal_True )
    1081             :     {
    1082           0 :         const ImplControlValue aControlValue;
    1083             : 
    1084           0 :         ControlState nState = CTRL_STATE_ENABLED;
    1085           0 :         int part = PART_ENTIRE_CONTROL;
    1086           0 :         if ( !IsEnabled() )
    1087           0 :             nState &= ~CTRL_STATE_ENABLED;
    1088           0 :         if ( HasFocus() )
    1089           0 :             nState |= CTRL_STATE_FOCUSED;
    1090             : 
    1091           0 :         Region aClipRgn( GetActiveClipRegion() );
    1092           0 :         aClipRgn.Intersect( aRect );
    1093           0 :         if( !rRect.IsEmpty() )
    1094           0 :             aClipRgn.Intersect( rRect );
    1095             : 
    1096           0 :         if( !aClipRgn.IsEmpty() )
    1097             :             bNativeOK = DrawNativeControl( CTRL_TAB_PANE, part, aRect, nState,
    1098           0 :                 aControlValue, rtl::OUString() );
    1099             :     }
    1100             :     else
    1101             :     {
    1102           0 :         long nTopOff = 1;
    1103           0 :         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
    1104           0 :             SetLineColor( rStyleSettings.GetLightColor() );
    1105             :         else
    1106           0 :             SetLineColor( Color( COL_BLACK ) );
    1107           0 :         if ( pCurItem && !pCurItem->maRect.IsEmpty() )
    1108             :         {
    1109           0 :             aCurRect = pCurItem->maRect;
    1110           0 :             if( ! bLayout )
    1111           0 :                 DrawLine( aRect.TopLeft(), Point( aCurRect.Left()-2, aRect.Top() ) );
    1112           0 :             if ( aCurRect.Right()+1 < aRect.Right() )
    1113             :             {
    1114           0 :                 if( ! bLayout )
    1115           0 :                     DrawLine( Point( aCurRect.Right(), aRect.Top() ), aRect.TopRight() );
    1116             :             }
    1117             :             else
    1118           0 :                 nTopOff = 0;
    1119             :         }
    1120             :         else
    1121           0 :             if( ! bLayout )
    1122           0 :                 DrawLine( aRect.TopLeft(), aRect.TopRight() );
    1123             : 
    1124           0 :         if( ! bLayout )
    1125             :         {
    1126           0 :             DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
    1127             : 
    1128           0 :             if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
    1129             :             {
    1130             :                 // if we have not tab page the bottom line of the tab page
    1131             :                 // directly touches the tab items, so choose a color that fits seamlessly
    1132           0 :                 if( bNoTabPage )
    1133           0 :                     SetLineColor( rStyleSettings.GetDialogColor() );
    1134             :                 else
    1135           0 :                     SetLineColor( rStyleSettings.GetShadowColor() );
    1136           0 :                 DrawLine( Point( 1, aRect.Bottom()-1 ),
    1137           0 :                         Point( aRect.Right()-1, aRect.Bottom()-1 ) );
    1138           0 :                 DrawLine( Point( aRect.Right()-1, aRect.Top()+nTopOff ),
    1139           0 :                         Point( aRect.Right()-1, aRect.Bottom()-1 ) );
    1140           0 :                 if( bNoTabPage )
    1141           0 :                     SetLineColor( rStyleSettings.GetDialogColor() );
    1142             :                 else
    1143           0 :                     SetLineColor( rStyleSettings.GetDarkShadowColor() );
    1144           0 :                 DrawLine( Point( 0, aRect.Bottom() ),
    1145           0 :                         Point( aRect.Right(), aRect.Bottom() ) );
    1146           0 :                 DrawLine( Point( aRect.Right(), aRect.Top()+nTopOff ),
    1147           0 :                         Point( aRect.Right(), aRect.Bottom() ) );
    1148             :             }
    1149             :             else
    1150             :             {
    1151           0 :                 DrawLine( aRect.TopRight(), aRect.BottomRight() );
    1152           0 :                 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
    1153             :             }
    1154             :         }
    1155             :     }
    1156             : 
    1157           0 :     if ( !mpTabCtrlData->maItemList.empty() && mpTabCtrlData->mpListBox == NULL )
    1158             :     {
    1159             :         // Some native toolkits (GTK+) draw tabs right-to-left, with an
    1160             :         // overlap between adjacent tabs
    1161           0 :         bool            bDrawTabsRTL = IsNativeControlSupported( CTRL_TAB_ITEM, PART_TABS_DRAW_RTL );
    1162           0 :         ImplTabItem *   pFirstTab = NULL;
    1163           0 :         ImplTabItem *   pLastTab = NULL;
    1164             :         size_t idx;
    1165             : 
    1166             :         // Event though there is a tab overlap with GTK+, the first tab is not
    1167             :         // overlapped on the left side.  Other tookits ignore this option.
    1168           0 :         if ( bDrawTabsRTL )
    1169             :         {
    1170           0 :             pFirstTab = &mpTabCtrlData->maItemList.front();
    1171           0 :             pLastTab = &mpTabCtrlData->maItemList.back();
    1172           0 :             idx = mpTabCtrlData->maItemList.size()-1;
    1173             :         }
    1174             :         else
    1175             :         {
    1176           0 :             pLastTab = &mpTabCtrlData->maItemList.back();
    1177           0 :             pFirstTab = &mpTabCtrlData->maItemList.front();
    1178           0 :             idx = 0;
    1179             :         }
    1180             : 
    1181           0 :         while ( idx < mpTabCtrlData->maItemList.size() )
    1182             :         {
    1183           0 :             ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx];
    1184           0 :             if ( pItem != pCurItem )
    1185             :             {
    1186           0 :                 Region aClipRgn( GetActiveClipRegion() );
    1187           0 :                 aClipRgn.Intersect( pItem->maRect );
    1188           0 :                 if( !rRect.IsEmpty() )
    1189           0 :                     aClipRgn.Intersect( rRect );
    1190           0 :                 if( bLayout || !aClipRgn.IsEmpty() )
    1191           0 :                     ImplDrawItem( pItem, aCurRect, bLayout, (pItem==pFirstTab), (pItem==pLastTab), sal_False );
    1192             :             }
    1193             : 
    1194           0 :             if ( bDrawTabsRTL )
    1195           0 :                 idx--;
    1196             :             else
    1197           0 :                 idx++;
    1198             :         }
    1199             : 
    1200           0 :         if ( pCurItem )
    1201             :         {
    1202           0 :             Region aClipRgn( GetActiveClipRegion() );
    1203           0 :             aClipRgn.Intersect( pCurItem->maRect );
    1204           0 :             if( !rRect.IsEmpty() )
    1205           0 :                 aClipRgn.Intersect( rRect );
    1206           0 :             if( bLayout || !aClipRgn.IsEmpty() )
    1207           0 :                 ImplDrawItem( pCurItem, aCurRect, bLayout, (pCurItem==pFirstTab), (pCurItem==pLastTab), sal_True );
    1208             :         }
    1209             :     }
    1210             : 
    1211           0 :     if ( !bLayout && HasFocus() )
    1212           0 :         ImplShowFocus();
    1213             : 
    1214           0 :     if( ! bLayout )
    1215           0 :         mbSmallInvalidate = sal_True;
    1216           0 : }
    1217             : 
    1218             : // -----------------------------------------------------------------------
    1219             : 
    1220           0 : void TabControl::setAllocation(const Size &rAllocation)
    1221             : {
    1222           0 :     ImplFreeLayoutData();
    1223             : 
    1224           0 :     if ( !IsReallyShown() )
    1225           0 :         return;
    1226             : 
    1227           0 :     if( mpTabCtrlData->mpListBox )
    1228             :     {
    1229             :         // get the listbox' preferred size
    1230           0 :         Size aTabCtrlSize( GetSizePixel() );
    1231           0 :         long nPrefWidth = mpTabCtrlData->mpListBox->get_preferred_size().Width();
    1232           0 :         if( nPrefWidth > aTabCtrlSize.Width() )
    1233           0 :             nPrefWidth = aTabCtrlSize.Width();
    1234           0 :         Size aNewSize( nPrefWidth, LogicToPixel( Size( 12, 12 ), MapMode( MAP_APPFONT ) ).Height() );
    1235           0 :         Point aNewPos( (aTabCtrlSize.Width() - nPrefWidth) / 2, 0 );
    1236           0 :         mpTabCtrlData->mpListBox->SetPosSizePixel( aNewPos, aNewSize );
    1237             :     }
    1238             : 
    1239           0 :     mbFormat = sal_True;
    1240             : 
    1241             :     // Aktuelle TabPage resizen/positionieren
    1242           0 :     sal_Bool bTabPage = ImplPosCurTabPage();
    1243             :     // Feststellen, was invalidiert werden muss
    1244           0 :     Size aNewSize = rAllocation;
    1245           0 :     long nNewWidth = aNewSize.Width();
    1246           0 :     for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
    1247           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    1248             :     {
    1249           0 :         if ( !it->mbFullVisible ||
    1250           0 :              (it->maRect.Right()-2 >= nNewWidth) )
    1251             :         {
    1252           0 :             mbSmallInvalidate = sal_False;
    1253           0 :             break;
    1254             :         }
    1255             :     }
    1256             : 
    1257           0 :     if ( mbSmallInvalidate )
    1258             :     {
    1259           0 :         Rectangle aRect = ImplGetTabRect( TAB_PAGERECT );
    1260           0 :         aRect.Left()   -= TAB_OFFSET+TAB_BORDER_LEFT;
    1261           0 :         aRect.Top()    -= TAB_OFFSET+TAB_BORDER_TOP;
    1262           0 :         aRect.Right()  += TAB_OFFSET+TAB_BORDER_RIGHT;
    1263           0 :         aRect.Bottom() += TAB_OFFSET+TAB_BORDER_BOTTOM;
    1264           0 :         if ( bTabPage )
    1265           0 :             Invalidate( aRect, INVALIDATE_NOCHILDREN );
    1266             :         else
    1267           0 :             Invalidate( aRect );
    1268             : 
    1269             :     }
    1270             :     else
    1271             :     {
    1272           0 :         if ( bTabPage )
    1273           0 :             Invalidate( INVALIDATE_NOCHILDREN );
    1274             :         else
    1275           0 :             Invalidate();
    1276             :     }
    1277             : 
    1278           0 :     mbLayoutDirty = false;
    1279             : }
    1280             : 
    1281           0 : void TabControl::SetPosSizePixel(const Point& rNewPos, const Size& rNewSize)
    1282             : {
    1283           0 :     Window::SetPosSizePixel(rNewPos, rNewSize);
    1284             :     //if size changed, TabControl::Resize got called already
    1285           0 :     if (mbLayoutDirty)
    1286           0 :         setAllocation(rNewSize);
    1287           0 : }
    1288             : 
    1289           0 : void TabControl::SetSizePixel(const Size& rNewSize)
    1290             : {
    1291           0 :     Window::SetSizePixel(rNewSize);
    1292             :     //if size changed, TabControl::Resize got called already
    1293           0 :     if (mbLayoutDirty)
    1294           0 :         setAllocation(rNewSize);
    1295           0 : }
    1296             : 
    1297           0 : void TabControl::SetPosPixel(const Point& rPos)
    1298             : {
    1299           0 :     Window::SetPosPixel(rPos);
    1300           0 :     if (mbLayoutDirty)
    1301           0 :         setAllocation(GetOutputSizePixel());
    1302           0 : }
    1303             : 
    1304           0 : void TabControl::Resize()
    1305             : {
    1306           0 :     setAllocation(Control::GetOutputSizePixel());
    1307           0 : }
    1308             : 
    1309             : // -----------------------------------------------------------------------
    1310             : 
    1311           0 : void TabControl::GetFocus()
    1312             : {
    1313           0 :     if( ! mpTabCtrlData->mpListBox )
    1314             :     {
    1315           0 :         ImplShowFocus();
    1316           0 :         SetInputContext( InputContext( GetFont() ) );
    1317             :     }
    1318             :     else
    1319             :     {
    1320           0 :         if( mpTabCtrlData->mpListBox->IsReallyVisible() )
    1321           0 :             mpTabCtrlData->mpListBox->GrabFocus();
    1322             :     }
    1323           0 :     Control::GetFocus();
    1324           0 : }
    1325             : 
    1326             : // -----------------------------------------------------------------------
    1327             : 
    1328           0 : void TabControl::LoseFocus()
    1329             : {
    1330           0 :     if( ! mpTabCtrlData->mpListBox )
    1331           0 :         HideFocus();
    1332           0 :     Control::LoseFocus();
    1333           0 : }
    1334             : 
    1335             : // -----------------------------------------------------------------------
    1336             : 
    1337           0 : void TabControl::RequestHelp( const HelpEvent& rHEvt )
    1338             : {
    1339           0 :     sal_uInt16 nItemId = rHEvt.KeyboardActivated() ? mnCurPageId : GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
    1340             : 
    1341           0 :     if ( nItemId )
    1342             :     {
    1343           0 :         if ( rHEvt.GetMode() & HELPMODE_BALLOON )
    1344             :         {
    1345           0 :             XubString aStr = GetHelpText( nItemId );
    1346           0 :             if ( aStr.Len() )
    1347             :             {
    1348           0 :                 Rectangle aItemRect = ImplGetTabRect( GetPagePos( nItemId ) );
    1349           0 :                 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
    1350           0 :                 aItemRect.Left()   = aPt.X();
    1351           0 :                 aItemRect.Top()    = aPt.Y();
    1352           0 :                 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
    1353           0 :                 aItemRect.Right()  = aPt.X();
    1354           0 :                 aItemRect.Bottom() = aPt.Y();
    1355           0 :                 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
    1356             :                 return;
    1357           0 :             }
    1358             :         }
    1359           0 :         else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
    1360             :         {
    1361           0 :             rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) );
    1362           0 :             if ( !aHelpId.isEmpty() )
    1363             :             {
    1364             :                 // Wenn eine Hilfe existiert, dann ausloesen
    1365           0 :                 Help* pHelp = Application::GetHelp();
    1366           0 :                 if ( pHelp )
    1367           0 :                     pHelp->Start( aHelpId, this );
    1368             :                 return;
    1369           0 :             }
    1370             :         }
    1371             : 
    1372             :         // Bei Quick- oder Balloon-Help zeigen wir den Text an,
    1373             :         // wenn dieser abgeschnitten ist
    1374           0 :         if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
    1375             :         {
    1376           0 :             ImplTabItem* pItem = ImplGetItem( nItemId );
    1377           0 :             const XubString& rStr = pItem->maText;
    1378           0 :             if ( rStr != pItem->maFormatText )
    1379             :             {
    1380           0 :                 Rectangle aItemRect = ImplGetTabRect( GetPagePos( nItemId ) );
    1381           0 :                 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
    1382           0 :                 aItemRect.Left()   = aPt.X();
    1383           0 :                 aItemRect.Top()    = aPt.Y();
    1384           0 :                 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
    1385           0 :                 aItemRect.Right()  = aPt.X();
    1386           0 :                 aItemRect.Bottom() = aPt.Y();
    1387           0 :                 if ( rStr.Len() )
    1388             :                 {
    1389           0 :                     if ( rHEvt.GetMode() & HELPMODE_BALLOON )
    1390           0 :                         Help::ShowBalloon( this, aItemRect.Center(), aItemRect, rStr );
    1391             :                     else
    1392           0 :                         Help::ShowQuickHelp( this, aItemRect, rStr );
    1393             :                     return;
    1394             :                 }
    1395             :             }
    1396             :         }
    1397             : 
    1398           0 :         if ( rHEvt.GetMode() & HELPMODE_QUICK )
    1399             :         {
    1400           0 :             ImplTabItem* pItem = ImplGetItem( nItemId );
    1401           0 :             const XubString& rHelpText = pItem->maHelpText;
    1402             :             // show tooltip if not text but image is set and helptext is available
    1403           0 :             if ( rHelpText.Len() > 0 && pItem->maText.Len() == 0 && !!pItem->maTabImage )
    1404             :             {
    1405           0 :                 Rectangle aItemRect = ImplGetTabRect( GetPagePos( nItemId ) );
    1406           0 :                 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
    1407           0 :                 aItemRect.Left()   = aPt.X();
    1408           0 :                 aItemRect.Top()    = aPt.Y();
    1409           0 :                 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
    1410           0 :                 aItemRect.Right()  = aPt.X();
    1411           0 :                 aItemRect.Bottom() = aPt.Y();
    1412           0 :                 Help::ShowQuickHelp( this, aItemRect, rHelpText );
    1413             :                 return;
    1414             :             }
    1415             :         }
    1416             :     }
    1417             : 
    1418           0 :     Control::RequestHelp( rHEvt );
    1419             : }
    1420             : 
    1421             : // -----------------------------------------------------------------------
    1422             : 
    1423           0 : void TabControl::Command( const CommandEvent& rCEvt )
    1424             : {
    1425           0 :     if( (mpTabCtrlData->mpListBox == NULL) && (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) && (GetPageCount() > 1) )
    1426             :     {
    1427           0 :         Point   aMenuPos;
    1428             :         sal_Bool    bMenu;
    1429           0 :         if ( rCEvt.IsMouseEvent() )
    1430             :         {
    1431           0 :             aMenuPos = rCEvt.GetMousePosPixel();
    1432           0 :             bMenu = GetPageId( aMenuPos ) != 0;
    1433             :         }
    1434             :         else
    1435             :         {
    1436           0 :             aMenuPos = ImplGetTabRect( GetPagePos( mnCurPageId ) ).Center();
    1437           0 :             bMenu = sal_True;
    1438             :         }
    1439             : 
    1440           0 :         if ( bMenu )
    1441             :         {
    1442           0 :             PopupMenu aMenu;
    1443           0 :             for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
    1444           0 :                  it != mpTabCtrlData->maItemList.end(); ++it )
    1445             :             {
    1446           0 :                 aMenu.InsertItem( it->mnId, it->maText, MIB_CHECKABLE | MIB_RADIOCHECK );
    1447           0 :                 if ( it->mnId == mnCurPageId )
    1448           0 :                     aMenu.CheckItem( it->mnId );
    1449           0 :                 aMenu.SetHelpId( it->mnId, it->maHelpId );
    1450             :             }
    1451             : 
    1452           0 :             sal_uInt16 nId = aMenu.Execute( this, aMenuPos );
    1453           0 :             if ( nId && (nId != mnCurPageId) )
    1454           0 :                 SelectTabPage( nId );
    1455           0 :             return;
    1456             :         }
    1457             :     }
    1458             : 
    1459           0 :     Control::Command( rCEvt );
    1460             : }
    1461             : 
    1462             : // -----------------------------------------------------------------------
    1463             : 
    1464           0 : void TabControl::StateChanged( StateChangedType nType )
    1465             : {
    1466           0 :     Control::StateChanged( nType );
    1467             : 
    1468           0 :     if ( nType == STATE_CHANGE_INITSHOW )
    1469             :     {
    1470           0 :         ImplPosCurTabPage();
    1471           0 :         if( mpTabCtrlData->mpListBox )
    1472           0 :             Resize();
    1473             :     }
    1474           0 :     else if ( nType == STATE_CHANGE_UPDATEMODE )
    1475             :     {
    1476           0 :         if ( IsUpdateMode() )
    1477           0 :             Invalidate();
    1478             :     }
    1479           0 :     else if ( (nType == STATE_CHANGE_ZOOM)  ||
    1480             :               (nType == STATE_CHANGE_CONTROLFONT) )
    1481             :     {
    1482           0 :         ImplInitSettings( sal_True, sal_False, sal_False );
    1483           0 :         Invalidate();
    1484             :     }
    1485           0 :     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
    1486             :     {
    1487           0 :         ImplInitSettings( sal_False, sal_True, sal_False );
    1488           0 :         Invalidate();
    1489             :     }
    1490           0 :     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    1491             :     {
    1492           0 :         ImplInitSettings( sal_False, sal_False, sal_True );
    1493           0 :         Invalidate();
    1494             :     }
    1495           0 : }
    1496             : 
    1497             : // -----------------------------------------------------------------------
    1498             : 
    1499           0 : void TabControl::DataChanged( const DataChangedEvent& rDCEvt )
    1500             : {
    1501           0 :     Control::DataChanged( rDCEvt );
    1502             : 
    1503           0 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
    1504           0 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
    1505           0 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
    1506           0 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    1507             :     {
    1508           0 :         ImplInitSettings( sal_True, sal_True, sal_True );
    1509           0 :         Invalidate();
    1510             :     }
    1511           0 : }
    1512             : 
    1513             : // -----------------------------------------------------------------------
    1514             : 
    1515           0 : Rectangle* TabControl::ImplFindPartRect( const Point& rPt )
    1516             : {
    1517           0 :     ImplTabItem* pFoundItem = NULL;
    1518           0 :     int nFound = 0;
    1519           0 :     for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
    1520           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    1521             :     {
    1522           0 :         if ( it->maRect.IsInside( rPt ) )
    1523             :         {
    1524             :             // assure that only one tab is highlighted at a time
    1525           0 :             nFound++;
    1526           0 :             pFoundItem = &(*it);
    1527             :         }
    1528             :     }
    1529             :     // assure that only one tab is highlighted at a time
    1530           0 :     return nFound == 1 ? &pFoundItem->maRect : NULL;
    1531             : }
    1532             : 
    1533           0 : long TabControl::PreNotify( NotifyEvent& rNEvt )
    1534             : {
    1535           0 :     long nDone = 0;
    1536           0 :     const MouseEvent* pMouseEvt = NULL;
    1537             : 
    1538           0 :     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
    1539             :     {
    1540           0 :         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
    1541             :         {
    1542             :             // trigger redraw if mouse over state has changed
    1543           0 :             if( IsNativeControlSupported(CTRL_TAB_ITEM, PART_ENTIRE_CONTROL) )
    1544             :             {
    1545           0 :                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
    1546           0 :                 Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() );
    1547           0 :                 if( pRect != pLastRect || (pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow()) )
    1548             :                 {
    1549           0 :                     Region aClipRgn;
    1550           0 :                     if( pLastRect )
    1551             :                     {
    1552             :                         // allow for slightly bigger tabitems
    1553             :                         // as used by gtk
    1554             :                         // TODO: query for the correct sizes
    1555           0 :                         Rectangle aRect(*pLastRect);
    1556           0 :                         aRect.Left()-=2;
    1557           0 :                         aRect.Right()+=2;
    1558           0 :                         aRect.Top()-=3;
    1559           0 :                         aClipRgn.Union( aRect );
    1560             :                     }
    1561           0 :                     if( pRect )
    1562             :                     {
    1563             :                         // allow for slightly bigger tabitems
    1564             :                         // as used by gtk
    1565             :                         // TODO: query for the correct sizes
    1566           0 :                         Rectangle aRect(*pRect);
    1567           0 :                         aRect.Left()-=2;
    1568           0 :                         aRect.Right()+=2;
    1569           0 :                         aRect.Top()-=3;
    1570           0 :                         aClipRgn.Union( aRect );
    1571             :                     }
    1572           0 :                     if( !aClipRgn.IsEmpty() )
    1573           0 :                         Invalidate( aClipRgn );
    1574             :                 }
    1575             :             }
    1576             :         }
    1577             :     }
    1578             : 
    1579           0 :     return nDone ? nDone : Control::PreNotify(rNEvt);
    1580             : }
    1581             : 
    1582             : // -----------------------------------------------------------------------
    1583             : 
    1584           0 : long TabControl::Notify( NotifyEvent& rNEvt )
    1585             : {
    1586           0 :     long nRet = 0;
    1587             : 
    1588           0 :     if ( rNEvt.GetType() == EVENT_KEYINPUT )
    1589           0 :         nRet = ImplHandleKeyEvent( *rNEvt.GetKeyEvent() );
    1590             : 
    1591           0 :     return nRet ? nRet : Control::Notify( rNEvt );
    1592             : }
    1593             : 
    1594             : // -----------------------------------------------------------------------
    1595             : 
    1596           0 : void TabControl::ActivatePage()
    1597             : {
    1598           0 :     maActivateHdl.Call( this );
    1599           0 : }
    1600             : 
    1601             : // -----------------------------------------------------------------------
    1602             : 
    1603           0 : long TabControl::DeactivatePage()
    1604             : {
    1605           0 :     if ( maDeactivateHdl.IsSet() )
    1606           0 :         return maDeactivateHdl.Call( this );
    1607             :     else
    1608           0 :         return sal_True;
    1609             : }
    1610             : 
    1611             : // -----------------------------------------------------------------------
    1612             : 
    1613           0 : void TabControl::SetTabPageSizePixel( const Size& rSize )
    1614             : {
    1615           0 :     ImplFreeLayoutData();
    1616             : 
    1617           0 :     Size aNewSize( rSize );
    1618           0 :     aNewSize.Width() += TAB_OFFSET*2;
    1619             :     Rectangle aRect = ImplGetTabRect( TAB_PAGERECT,
    1620           0 :                                       aNewSize.Width(), aNewSize.Height() );
    1621           0 :     aNewSize.Height() += aRect.Top()+TAB_OFFSET;
    1622           0 :     Window::SetOutputSizePixel( aNewSize );
    1623           0 : }
    1624             : 
    1625             : // -----------------------------------------------------------------------
    1626             : 
    1627           0 : Size TabControl::GetTabPageSizePixel() const
    1628             : {
    1629           0 :     Rectangle aRect = ((TabControl*)this)->ImplGetTabRect( TAB_PAGERECT );
    1630           0 :     return aRect.GetSize();
    1631             : }
    1632             : 
    1633             : // -----------------------------------------------------------------------
    1634             : 
    1635           0 : void TabControl::InsertPage( const ResId& rResId, sal_uInt16 nPos )
    1636             : {
    1637           0 :     GetRes( rResId.SetRT( RSC_TABCONTROLITEM ) );
    1638             : 
    1639           0 :     sal_uLong nObjMask = ReadLongRes();
    1640           0 :     sal_uInt16 nItemId  = 1;
    1641             : 
    1642             :     // ID
    1643           0 :     if ( nObjMask & RSC_TABCONTROLITEM_ID )
    1644           0 :         nItemId = sal::static_int_cast<sal_uInt16>(ReadLongRes());
    1645             : 
    1646             :     // Text
    1647           0 :     XubString aTmpStr;
    1648           0 :     if( nObjMask & RSC_TABCONTROLITEM_TEXT )
    1649           0 :         aTmpStr = ReadStringRes();
    1650           0 :     InsertPage( nItemId, aTmpStr, nPos );
    1651             : 
    1652             :     // PageResID
    1653           0 :     if ( nObjMask & RSC_TABCONTROLITEM_PAGERESID )
    1654             :     {
    1655             :         //skip unused TabPageResId value
    1656           0 :         ReadLongRes();
    1657           0 :     }
    1658           0 : }
    1659             : 
    1660             : // -----------------------------------------------------------------------
    1661             : 
    1662           0 : void TabControl::InsertPage( sal_uInt16 nPageId, const XubString& rText,
    1663             :                              sal_uInt16 nPos )
    1664             : {
    1665             :     DBG_ASSERT( nPageId, "TabControl::InsertPage(): PageId == 0" );
    1666             :     DBG_ASSERT( GetPagePos( nPageId ) == TAB_PAGE_NOTFOUND,
    1667             :                 "TabControl::InsertPage(): PageId already exists" );
    1668             : 
    1669             :     // insert new page item
    1670           0 :     ImplTabItem* pItem = NULL;
    1671           0 :     if( nPos == TAB_APPEND || size_t(nPos) >= mpTabCtrlData->maItemList.size() )
    1672             :     {
    1673           0 :         mpTabCtrlData->maItemList.push_back( ImplTabItem() );
    1674           0 :         pItem = &mpTabCtrlData->maItemList.back();
    1675           0 :         if( mpTabCtrlData->mpListBox )
    1676           0 :             mpTabCtrlData->mpListBox->InsertEntry( rText );
    1677             :     }
    1678             :     else
    1679             :     {
    1680             :         std::vector< ImplTabItem >::iterator new_it =
    1681           0 :             mpTabCtrlData->maItemList.insert( mpTabCtrlData->maItemList.begin() + nPos, ImplTabItem() );
    1682           0 :         pItem = &(*new_it);
    1683           0 :         if( mpTabCtrlData->mpListBox )
    1684           0 :             mpTabCtrlData->mpListBox->InsertEntry( rText, nPos);
    1685             :     }
    1686           0 :     if( mpTabCtrlData->mpListBox )
    1687             :     {
    1688           0 :         if( ! mnCurPageId )
    1689           0 :             mpTabCtrlData->mpListBox->SelectEntryPos( 0 );
    1690           0 :         mpTabCtrlData->mpListBox->SetDropDownLineCount( mpTabCtrlData->mpListBox->GetEntryCount() );
    1691             :     }
    1692             : 
    1693             :     // set current page id
    1694           0 :     if ( !mnCurPageId )
    1695           0 :         mnCurPageId = nPageId;
    1696             : 
    1697             :     // init new page item
    1698           0 :     pItem->mnId             = nPageId;
    1699           0 :     pItem->mpTabPage        = NULL;
    1700           0 :     pItem->maText           = rText;
    1701           0 :     pItem->mbFullVisible    = sal_False;
    1702             : 
    1703           0 :     mbFormat = sal_True;
    1704           0 :     if ( IsUpdateMode() )
    1705           0 :         Invalidate();
    1706             : 
    1707           0 :     ImplFreeLayoutData();
    1708           0 :     if( mpTabCtrlData->mpListBox ) // reposition/resize listbox
    1709           0 :         Resize();
    1710             : 
    1711           0 :     ImplCallEventListeners( VCLEVENT_TABPAGE_INSERTED, (void*) (sal_uLong)nPageId );
    1712           0 : }
    1713             : 
    1714             : // -----------------------------------------------------------------------
    1715             : 
    1716           0 : void TabControl::RemovePage( sal_uInt16 nPageId )
    1717             : {
    1718           0 :     sal_uInt16 nPos = GetPagePos( nPageId );
    1719             : 
    1720             :     // does the item exist ?
    1721           0 :     if ( nPos != TAB_PAGE_NOTFOUND )
    1722             :     {
    1723             :         //remove page item
    1724           0 :         std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin() + nPos;
    1725           0 :         bool bIsCurrentPage = (it->mnId == mnCurPageId);
    1726           0 :         mpTabCtrlData->maItemList.erase( it );
    1727           0 :         if( mpTabCtrlData->mpListBox )
    1728             :         {
    1729           0 :             mpTabCtrlData->mpListBox->RemoveEntry( nPos );
    1730           0 :             mpTabCtrlData->mpListBox->SetDropDownLineCount( mpTabCtrlData->mpListBox->GetEntryCount() );
    1731             :         }
    1732             : 
    1733             :         // If current page is removed, than first page gets the current page
    1734           0 :         if ( bIsCurrentPage  )
    1735             :         {
    1736           0 :             mnCurPageId = 0;
    1737             : 
    1738           0 :             if( ! mpTabCtrlData->maItemList.empty() )
    1739             :             {
    1740             :                 // don't do this by simply setting mnCurPageId to pFirstItem->mnId
    1741             :                 // this leaves a lot of stuff (such trivias as _showing_ the new current page) undone
    1742             :                 // instead, call SetCurPageId
    1743             :                 // without this, the next (outside) call to SetCurPageId with the id of the first page
    1744             :                 // will result in doing nothing (as we assume that nothing changed, then), and the page
    1745             :                 // will never be shown.
    1746             :                 // 86875 - 05/11/2001 - frank.schoenheit@germany.sun.com
    1747             : 
    1748           0 :                 SetCurPageId( mpTabCtrlData->maItemList[0].mnId );
    1749             :             }
    1750             :         }
    1751             : 
    1752           0 :         mbFormat = sal_True;
    1753           0 :         if ( IsUpdateMode() )
    1754           0 :             Invalidate();
    1755             : 
    1756           0 :         ImplFreeLayoutData();
    1757             : 
    1758           0 :         ImplCallEventListeners( VCLEVENT_TABPAGE_REMOVED, (void*) (sal_uLong) nPageId );
    1759             :     }
    1760           0 : }
    1761             : 
    1762             : // -----------------------------------------------------------------------
    1763             : 
    1764           0 : void TabControl::Clear()
    1765             : {
    1766             :     // clear item list
    1767           0 :     mpTabCtrlData->maItemList.clear();
    1768           0 :     mnCurPageId = 0;
    1769           0 :     if( mpTabCtrlData->mpListBox )
    1770           0 :         mpTabCtrlData->mpListBox->Clear();
    1771             : 
    1772           0 :     ImplFreeLayoutData();
    1773             : 
    1774           0 :     mbFormat = sal_True;
    1775           0 :     if ( IsUpdateMode() )
    1776           0 :         Invalidate();
    1777             : 
    1778           0 :     ImplCallEventListeners( VCLEVENT_TABPAGE_REMOVEDALL );
    1779           0 : }
    1780             : 
    1781             : // -----------------------------------------------------------------------
    1782             : 
    1783           0 : void TabControl::EnablePage( sal_uInt16 i_nPageId, bool i_bEnable )
    1784             : {
    1785           0 :     ImplTabItem* pItem = ImplGetItem( i_nPageId );
    1786             : 
    1787           0 :     if ( pItem && pItem->mbEnabled != i_bEnable )
    1788             :     {
    1789           0 :         pItem->mbEnabled = i_bEnable;
    1790           0 :         mbFormat = sal_True;
    1791           0 :         if( mpTabCtrlData->mpListBox )
    1792           0 :             mpTabCtrlData->mpListBox->SetEntryFlags( GetPagePos( i_nPageId ),
    1793           0 :                                                      i_bEnable ? 0 : (LISTBOX_ENTRY_FLAG_DISABLE_SELECTION | LISTBOX_ENTRY_FLAG_DRAW_DISABLED) );
    1794           0 :         if( pItem->mnId == mnCurPageId )
    1795             :         {
    1796             :              // SetCurPageId will change to an enabled page
    1797           0 :             SetCurPageId( mnCurPageId );
    1798             :         }
    1799           0 :         else if ( IsUpdateMode() )
    1800           0 :             Invalidate();
    1801             :     }
    1802           0 : }
    1803             : 
    1804             : // -----------------------------------------------------------------------
    1805             : 
    1806           0 : sal_uInt16 TabControl::GetPageCount() const
    1807             : {
    1808           0 :     return (sal_uInt16)mpTabCtrlData->maItemList.size();
    1809             : }
    1810             : 
    1811             : // -----------------------------------------------------------------------
    1812             : 
    1813           0 : sal_uInt16 TabControl::GetPageId( sal_uInt16 nPos ) const
    1814             : {
    1815           0 :     if( size_t(nPos) < mpTabCtrlData->maItemList.size() )
    1816           0 :         return mpTabCtrlData->maItemList[ nPos ].mnId;
    1817           0 :     return 0;
    1818             : }
    1819             : 
    1820             : // -----------------------------------------------------------------------
    1821             : 
    1822           0 : sal_uInt16 TabControl::GetPagePos( sal_uInt16 nPageId ) const
    1823             : {
    1824           0 :     for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
    1825           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    1826             :     {
    1827           0 :         if ( it->mnId == nPageId )
    1828           0 :             return (sal_uInt16)(it - mpTabCtrlData->maItemList.begin());
    1829             :     }
    1830             : 
    1831           0 :     return TAB_PAGE_NOTFOUND;
    1832             : }
    1833             : 
    1834             : // -----------------------------------------------------------------------
    1835             : 
    1836           0 : sal_uInt16 TabControl::GetPageId( const Point& rPos ) const
    1837             : {
    1838           0 :     for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i )
    1839             :     {
    1840           0 :         if ( ((TabControl*)this)->ImplGetTabRect( static_cast<sal_uInt16>(i) ).IsInside( rPos ) )
    1841           0 :             return mpTabCtrlData->maItemList[ i ].mnId;
    1842             :     }
    1843             : 
    1844           0 :     return 0;
    1845             : }
    1846             : 
    1847           0 : sal_uInt16 TabControl::GetPageId( const TabPage& rPage ) const
    1848             : {
    1849           0 :     for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
    1850           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    1851             :     {
    1852           0 :         if ( it->mpTabPage == &rPage )
    1853           0 :             return it->mnId;
    1854             :     }
    1855             : 
    1856           0 :     return 0;
    1857             : }
    1858             : 
    1859           0 : sal_uInt16 TabControl::GetPageId( const OString& rName ) const
    1860             : {
    1861           0 :     for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
    1862           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    1863             :     {
    1864           0 :         if ( it->maTabName == rName )
    1865           0 :             return it->mnId;
    1866             :     }
    1867             : 
    1868           0 :     return 0;
    1869             : }
    1870             : 
    1871             : // -----------------------------------------------------------------------
    1872             : 
    1873           0 : void TabControl::SetCurPageId( sal_uInt16 nPageId )
    1874             : {
    1875           0 :     sal_uInt16 nPos = GetPagePos( nPageId );
    1876           0 :     while( nPos != TAB_PAGE_NOTFOUND &&
    1877           0 :            ! mpTabCtrlData->maItemList[nPos].mbEnabled )
    1878             :     {
    1879           0 :         nPos++;
    1880           0 :         if( size_t(nPos) >= mpTabCtrlData->maItemList.size() )
    1881           0 :             nPos = 0;
    1882           0 :         if( mpTabCtrlData->maItemList[nPos].mnId == nPageId )
    1883           0 :             break;
    1884             :     }
    1885             : 
    1886           0 :     if( nPos != TAB_PAGE_NOTFOUND )
    1887             :     {
    1888           0 :         nPageId = mpTabCtrlData->maItemList[nPos].mnId;
    1889           0 :         if ( nPageId == mnCurPageId )
    1890             :         {
    1891           0 :             if ( mnActPageId )
    1892           0 :                 mnActPageId = nPageId;
    1893           0 :             return;
    1894             :         }
    1895             : 
    1896           0 :         if ( mnActPageId )
    1897           0 :             mnActPageId = nPageId;
    1898             :         else
    1899             :         {
    1900           0 :             mbFormat = sal_True;
    1901           0 :             sal_uInt16 nOldId = mnCurPageId;
    1902           0 :             mnCurPageId = nPageId;
    1903           0 :             ImplChangeTabPage( nPageId, nOldId );
    1904             :         }
    1905             :     }
    1906             : }
    1907             : 
    1908             : // -----------------------------------------------------------------------
    1909             : 
    1910           0 : sal_uInt16 TabControl::GetCurPageId() const
    1911             : {
    1912           0 :     if ( mnActPageId )
    1913           0 :         return mnActPageId;
    1914             :     else
    1915           0 :         return mnCurPageId;
    1916             : }
    1917             : 
    1918             : // -----------------------------------------------------------------------
    1919             : 
    1920           0 : void TabControl::SelectTabPage( sal_uInt16 nPageId )
    1921             : {
    1922           0 :     if ( nPageId && (nPageId != mnCurPageId) )
    1923             :     {
    1924           0 :         ImplFreeLayoutData();
    1925             : 
    1926           0 :         ImplCallEventListeners( VCLEVENT_TABPAGE_DEACTIVATE, (void*) (sal_uLong) mnCurPageId );
    1927           0 :         if ( DeactivatePage() )
    1928             :         {
    1929           0 :             mnActPageId = nPageId;
    1930           0 :             ActivatePage();
    1931             :             // Page koennte im Activate-Handler umgeschaltet wurden sein
    1932           0 :             nPageId = mnActPageId;
    1933           0 :             mnActPageId = 0;
    1934           0 :             SetCurPageId( nPageId );
    1935           0 :             if( mpTabCtrlData->mpListBox )
    1936           0 :                 mpTabCtrlData->mpListBox->SelectEntryPos( GetPagePos( nPageId ) );
    1937           0 :             ImplCallEventListeners( VCLEVENT_TABPAGE_ACTIVATE, (void*) (sal_uLong) nPageId );
    1938             :         }
    1939             :     }
    1940           0 : }
    1941             : 
    1942             : // -----------------------------------------------------------------------
    1943             : 
    1944           0 : void TabControl::SetTabPage( sal_uInt16 nPageId, TabPage* pTabPage )
    1945             : {
    1946           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    1947             : 
    1948           0 :     if ( pItem && (pItem->mpTabPage != pTabPage) )
    1949             :     {
    1950           0 :         if ( pTabPage )
    1951             :         {
    1952             :             DBG_ASSERT( !pTabPage->IsVisible() || pTabPage->isLayoutEnabled(),
    1953             :                 "TabControl::SetTabPage() - Non-Layout Enabled Page is visible" );
    1954             : 
    1955           0 :             if ( IsDefaultSize() )
    1956           0 :                 SetTabPageSizePixel( pTabPage->GetSizePixel() );
    1957             : 
    1958             :             // Erst hier setzen, damit Resize nicht TabPage umpositioniert
    1959           0 :             pItem->mpTabPage = pTabPage;
    1960           0 :             queue_resize();
    1961           0 :             if ( pItem->mnId == mnCurPageId )
    1962           0 :                 ImplChangeTabPage( pItem->mnId, 0 );
    1963             :         }
    1964             :         else
    1965             :         {
    1966           0 :             pItem->mpTabPage = NULL;
    1967           0 :             queue_resize();
    1968             :         }
    1969             :     }
    1970           0 : }
    1971             : 
    1972             : // -----------------------------------------------------------------------
    1973             : 
    1974           0 : TabPage* TabControl::GetTabPage( sal_uInt16 nPageId ) const
    1975             : {
    1976           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    1977             : 
    1978           0 :     if ( pItem )
    1979           0 :         return pItem->mpTabPage;
    1980             :     else
    1981           0 :         return NULL;
    1982             : }
    1983             : 
    1984             : // -----------------------------------------------------------------------
    1985             : 
    1986           0 : void TabControl::SetPageText( sal_uInt16 nPageId, const XubString& rText )
    1987             : {
    1988           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    1989             : 
    1990           0 :     if ( pItem && pItem->maText != rText )
    1991             :     {
    1992           0 :         pItem->maText = rText;
    1993           0 :         mbFormat = sal_True;
    1994           0 :         if( mpTabCtrlData->mpListBox )
    1995             :         {
    1996           0 :             sal_uInt16 nPos = GetPagePos( nPageId );
    1997           0 :             mpTabCtrlData->mpListBox->RemoveEntry( nPos );
    1998           0 :             mpTabCtrlData->mpListBox->InsertEntry( rText, nPos );
    1999             :         }
    2000           0 :         if ( IsUpdateMode() )
    2001           0 :             Invalidate();
    2002           0 :         ImplFreeLayoutData();
    2003           0 :         ImplCallEventListeners( VCLEVENT_TABPAGE_PAGETEXTCHANGED, (void*) (sal_uLong) nPageId );
    2004             :     }
    2005           0 : }
    2006             : 
    2007             : // -----------------------------------------------------------------------
    2008             : 
    2009           0 : XubString TabControl::GetPageText( sal_uInt16 nPageId ) const
    2010             : {
    2011           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2012             : 
    2013           0 :     if ( pItem )
    2014           0 :         return pItem->maText;
    2015             :     else
    2016           0 :         return ImplGetSVEmptyStr();
    2017             : }
    2018             : 
    2019             : // -----------------------------------------------------------------------
    2020             : 
    2021           0 : void TabControl::SetHelpText( sal_uInt16 nPageId, const XubString& rText )
    2022             : {
    2023           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2024             : 
    2025           0 :     if ( pItem )
    2026           0 :         pItem->maHelpText = rText;
    2027           0 : }
    2028             : 
    2029             : // -----------------------------------------------------------------------
    2030             : 
    2031           0 : const XubString& TabControl::GetHelpText( sal_uInt16 nPageId ) const
    2032             : {
    2033           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2034             : 
    2035           0 :     if ( pItem )
    2036             :     {
    2037           0 :         if ( !pItem->maHelpText.Len() && !pItem->maHelpId.isEmpty() )
    2038             :         {
    2039           0 :             Help* pHelp = Application::GetHelp();
    2040           0 :             if ( pHelp )
    2041           0 :                 pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
    2042             :         }
    2043             : 
    2044           0 :         return pItem->maHelpText;
    2045             :     }
    2046             :     else
    2047           0 :         return ImplGetSVEmptyStr();
    2048             : }
    2049             : 
    2050             : // -----------------------------------------------------------------------
    2051             : 
    2052           0 : void TabControl::SetHelpId( sal_uInt16 nPageId, const OString& rId ) const
    2053             : {
    2054           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2055             : 
    2056           0 :     if ( pItem )
    2057           0 :         pItem->maHelpId = rId;
    2058           0 : }
    2059             : 
    2060           0 : OString TabControl::GetHelpId( sal_uInt16 nPageId ) const
    2061             : {
    2062           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2063             : 
    2064           0 :     if (pItem)
    2065           0 :         return pItem->maHelpId;
    2066             : 
    2067           0 :     return OString();
    2068             : }
    2069             : 
    2070           0 : void TabControl::SetPageName( sal_uInt16 nPageId, const OString& rName ) const
    2071             : {
    2072           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2073             : 
    2074           0 :     if ( pItem )
    2075           0 :         pItem->maTabName = rName;
    2076           0 : }
    2077             : 
    2078           0 : OString TabControl::GetPageName( sal_uInt16 nPageId ) const
    2079             : {
    2080           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2081             : 
    2082           0 :     if (pItem)
    2083           0 :         return pItem->maTabName;
    2084             : 
    2085           0 :     return OString();
    2086             : }
    2087             : 
    2088             : // -----------------------------------------------------------------------
    2089             : 
    2090           0 : void TabControl::SetPageImage( sal_uInt16 i_nPageId, const Image& i_rImage )
    2091             : {
    2092           0 :     ImplTabItem* pItem = ImplGetItem( i_nPageId );
    2093             : 
    2094           0 :     if ( pItem )
    2095             :     {
    2096           0 :         pItem->maTabImage = i_rImage;
    2097           0 :         mbFormat = sal_True;
    2098           0 :         if ( IsUpdateMode() )
    2099           0 :             Invalidate();
    2100             :     }
    2101           0 : }
    2102             : 
    2103             : // -----------------------------------------------------------------------
    2104             : 
    2105           0 : Rectangle TabControl::GetCharacterBounds( sal_uInt16 nPageId, long nIndex ) const
    2106             : {
    2107           0 :     Rectangle aRet;
    2108             : 
    2109           0 :     if( !HasLayoutData() || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
    2110           0 :         FillLayoutData();
    2111             : 
    2112           0 :     if( HasLayoutData() )
    2113             :     {
    2114           0 :         boost::unordered_map< int, int >::const_iterator it = mpTabCtrlData->maLayoutPageIdToLine.find( (int)nPageId );
    2115           0 :         if( it != mpTabCtrlData->maLayoutPageIdToLine.end() )
    2116             :         {
    2117           0 :             Pair aPair = mpControlData->mpLayoutData->GetLineStartEnd( it->second );
    2118           0 :             if( (aPair.B() - aPair.A()) >= nIndex )
    2119           0 :                 aRet = mpControlData->mpLayoutData->GetCharacterBounds( aPair.A() + nIndex );
    2120             :         }
    2121             :     }
    2122             : 
    2123           0 :     return aRet;
    2124             : }
    2125             : 
    2126             : // -----------------------------------------------------------------------
    2127             : 
    2128           0 : long TabControl::GetIndexForPoint( const Point& rPoint, sal_uInt16& rPageId ) const
    2129             : {
    2130           0 :     long nRet = -1;
    2131             : 
    2132           0 :     if( !HasLayoutData() || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
    2133           0 :         FillLayoutData();
    2134             : 
    2135           0 :     if( HasLayoutData() )
    2136             :     {
    2137           0 :         int nIndex = mpControlData->mpLayoutData->GetIndexForPoint( rPoint );
    2138           0 :         if( nIndex != -1 )
    2139             :         {
    2140             :             // what line (->pageid) is this index in ?
    2141           0 :             int nLines = mpControlData->mpLayoutData->GetLineCount();
    2142           0 :             int nLine = -1;
    2143           0 :             while( ++nLine < nLines )
    2144             :             {
    2145           0 :                 Pair aPair = mpControlData->mpLayoutData->GetLineStartEnd( nLine );
    2146           0 :                 if( aPair.A() <= nIndex && aPair.B() >= nIndex )
    2147             :                 {
    2148           0 :                     nRet = nIndex - aPair.A();
    2149           0 :                     rPageId = (sal_uInt16)mpTabCtrlData->maLayoutLineToPageId[ nLine ];
    2150             :                     break;
    2151             :                 }
    2152             :             }
    2153             :         }
    2154             :     }
    2155             : 
    2156           0 :     return nRet;
    2157             : }
    2158             : 
    2159             : // -----------------------------------------------------------------------
    2160             : 
    2161           0 : void TabControl::FillLayoutData() const
    2162             : {
    2163           0 :     mpTabCtrlData->maLayoutLineToPageId.clear();
    2164           0 :     mpTabCtrlData->maLayoutPageIdToLine.clear();
    2165           0 :     const_cast<TabControl*>(this)->ImplPaint( Rectangle(), true );
    2166           0 : }
    2167             : 
    2168             : // -----------------------------------------------------------------------
    2169             : 
    2170           0 : Rectangle TabControl::GetTabBounds( sal_uInt16 nPageId ) const
    2171             : {
    2172           0 :     Rectangle aRet;
    2173             : 
    2174           0 :     ImplTabItem* pItem = ImplGetItem( nPageId );
    2175           0 :     if(pItem)
    2176           0 :         aRet = pItem->maRect;
    2177             : 
    2178           0 :     return aRet;
    2179             : }
    2180             : 
    2181             : // -----------------------------------------------------------------------
    2182             : 
    2183           0 : void TabControl::SetItemsOffset( const Point& rOffs )
    2184             : {
    2185           0 :     if( mpTabCtrlData )
    2186           0 :         mpTabCtrlData->maItemsOffset = rOffs;
    2187           0 : }
    2188             : 
    2189           0 : Point TabControl::GetItemsOffset() const
    2190             : {
    2191           0 :     if( mpTabCtrlData )
    2192           0 :         return mpTabCtrlData->maItemsOffset;
    2193             :     else
    2194           0 :         return Point();
    2195             : }
    2196             : 
    2197             : // -----------------------------------------------------------------------
    2198             : 
    2199           0 : Size TabControl::calculateRequisition() const
    2200             : {
    2201           0 :     Size aOptimalPageSize(0, 0);
    2202             : 
    2203           0 :     for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
    2204           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    2205             :     {
    2206           0 :         const TabPage *pPage = it->mpTabPage;
    2207             :         //it's a real nuisance if the page is not inserted yet :-(
    2208             :         //We need to force all tabs to exist to get overall optimal size for dialog
    2209           0 :         if (!pPage)
    2210             :         {
    2211           0 :             TabControl *pThis = const_cast<TabControl*>(this);
    2212           0 :             sal_uInt16 nLastPageId = pThis->GetCurPageId();
    2213           0 :             pThis->SetCurPageId(it->mnId);
    2214           0 :             pThis->ActivatePage();
    2215           0 :             pThis->SetCurPageId(nLastPageId);
    2216           0 :             pPage = it->mpTabPage;
    2217             :         }
    2218             : 
    2219           0 :         if (!pPage)
    2220           0 :             continue;
    2221             : 
    2222           0 :         Size aPageSize(pPage->GetOptimalSize(WINDOWSIZE_PREFERRED));
    2223             : 
    2224           0 :         if (aPageSize.Width() > aOptimalPageSize.Width())
    2225           0 :             aOptimalPageSize.Width() = aPageSize.Width();
    2226           0 :         if (aPageSize.Height() > aOptimalPageSize.Height())
    2227           0 :             aOptimalPageSize.Height() = aPageSize.Height();
    2228             :     }
    2229             : 
    2230           0 :     long nTabLabelsBottom = 0, nTabLabelsRight = 0;
    2231           0 :     for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin();
    2232           0 :          it != mpTabCtrlData->maItemList.end(); ++it )
    2233             :     {
    2234           0 :         TabControl* pThis = const_cast<TabControl*>(this);
    2235             : 
    2236           0 :         sal_uInt16 nPos = it - mpTabCtrlData->maItemList.begin();
    2237           0 :         Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aOptimalPageSize.Width(), LONG_MAX);
    2238           0 :         if (aTabRect.Bottom() > nTabLabelsBottom)
    2239           0 :             nTabLabelsBottom = aTabRect.Bottom();
    2240           0 :         if (aTabRect.Right() > nTabLabelsRight)
    2241           0 :             nTabLabelsRight = aTabRect.Right();
    2242             :     }
    2243             : 
    2244           0 :     Size aOptimalSize(aOptimalPageSize);
    2245           0 :     aOptimalSize.Height() += nTabLabelsBottom;
    2246           0 :     aOptimalSize.Width() = std::max(nTabLabelsRight, aOptimalSize.Width());
    2247             : 
    2248           0 :     aOptimalSize.Width() += TAB_OFFSET * 2;
    2249           0 :     aOptimalSize.Height() += TAB_OFFSET * 2;
    2250             : 
    2251           0 :     return aOptimalSize;
    2252             : }
    2253             : 
    2254           0 : Size TabControl::GetOptimalSize(WindowSizeType eType) const
    2255             : {
    2256           0 :     if (eType == WINDOWSIZE_MINIMUM)
    2257           0 :         return Size();
    2258           0 :     return calculateRequisition();
    2259             : }
    2260             : 
    2261             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10