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