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