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