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