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