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