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