1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svtools/tabbar.hxx>
22 #include <tools/time.hxx>
23 #include <tools/debug.hxx>
24 #include <tools/poly.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/help.hxx>
27 #include <vcl/decoview.hxx>
28 #include <vcl/button.hxx>
29 #include <vcl/edit.hxx>
30 #include <vcl/image.hxx>
31 #include "svtaccessiblefactory.hxx"
32 #include <filectrl.hrc>
33 #include <svtools/svtresid.hxx>
34 #include <svtools/svtools.hrc>
37 // =======================================================================
39 #define TABBAR_OFFSET_X 7
40 #define TABBAR_OFFSET_X2 2
41 #define TABBAR_DRAG_SCROLLOFF 5
42 #define TABBAR_MINSIZE 5
44 const sal_uInt16 ADDNEWPAGE_AREAWIDTH
= 10;
46 // =======================================================================
51 TabBarPageBits mnBits
;
63 ImplTabBarItem( sal_uInt16 nItemId
, const OUString
& rText
,
64 TabBarPageBits nPageBits
) :
73 maTabBgColor
= Color( COL_AUTO
);
74 maTabTextColor
= Color( COL_AUTO
);
77 bool IsDefaultTabBgColor() const
79 return maTabBgColor
== Color(COL_AUTO
);
82 bool IsDefaultTabTextColor() const
84 return maTabTextColor
== Color(COL_AUTO
);
87 bool IsSelected(ImplTabBarItem
* pCurItem
) const
89 return mbSelect
|| (pCurItem
== this);
93 // =======================================================================
99 class ImplTabButton
: public PushButton
102 ImplTabButton( TabBar
* pParent
, WinBits nWinStyle
= 0 ) :
103 PushButton( pParent
, nWinStyle
| WB_RECTSTYLE
| WB_SMALLSTYLE
| WB_NOLIGHTBORDER
| WB_NOPOINTERFOCUS
) {}
105 TabBar
* GetParent() const { return (TabBar
*)Window::GetParent(); }
107 virtual long PreNotify( NotifyEvent
& rNEvt
);
109 virtual void MouseButtonDown( const MouseEvent
& rMEvt
);
111 virtual void Command( const CommandEvent
& rCEvt
);
114 void ImplTabButton::MouseButtonDown( const MouseEvent
& rMEvt
)
116 PushButton::MouseButtonDown(rMEvt
);
119 void ImplTabButton::Command( const CommandEvent
& rCEvt
)
121 sal_uInt16 nCmd
= rCEvt
.GetCommand();
122 if ( nCmd
== COMMAND_CONTEXTMENU
)
124 TabBar
*pParent
= GetParent();
125 pParent
->maScrollAreaContextHdl
.Call((void*)&rCEvt
);
127 PushButton::Command(rCEvt
);
130 // =======================================================================
132 long ImplTabButton::PreNotify( NotifyEvent
& rNEvt
)
134 if ( rNEvt
.GetType() == EVENT_MOUSEBUTTONDOWN
)
136 if ( GetParent()->IsInEditMode() )
138 GetParent()->EndEditMode();
143 return PushButton::PreNotify( rNEvt
);
146 // =======================================================================
152 class ImplTabSizer
: public Window
155 ImplTabSizer( TabBar
* pParent
, WinBits nWinStyle
= 0 );
157 TabBar
* GetParent() const { return (TabBar
*)Window::GetParent(); }
160 void ImplTrack( const Point
& rScreenPos
);
162 virtual void MouseButtonDown( const MouseEvent
& rMEvt
);
163 virtual void Tracking( const TrackingEvent
& rTEvt
);
164 virtual void Paint( const Rectangle
& rRect
);
170 // -----------------------------------------------------------------------
172 ImplTabSizer::ImplTabSizer( TabBar
* pParent
, WinBits nWinStyle
)
173 : Window( pParent
, nWinStyle
& WB_3DLOOK
)
176 SetPointer( Pointer( POINTER_HSIZEBAR
) );
177 SetSizePixel( Size( 7, 0 ) );
180 // -----------------------------------------------------------------------
182 void ImplTabSizer::ImplTrack( const Point
& rScreenPos
)
184 TabBar
* pParent
= GetParent();
185 long nDiff
= rScreenPos
.X() - maStartPos
.X();
186 pParent
->mnSplitSize
= mnStartWidth
+ (pParent
->IsMirrored() ? -nDiff
: nDiff
);
187 if ( pParent
->mnSplitSize
< TABBAR_MINSIZE
)
188 pParent
->mnSplitSize
= TABBAR_MINSIZE
;
193 // -----------------------------------------------------------------------
195 void ImplTabSizer::MouseButtonDown( const MouseEvent
& rMEvt
)
197 if ( GetParent()->IsInEditMode() )
199 GetParent()->EndEditMode();
203 if ( rMEvt
.IsLeft() )
205 maStartPos
= OutputToScreenPixel( rMEvt
.GetPosPixel() );
206 mnStartWidth
= GetParent()->GetSizePixel().Width();
211 // -----------------------------------------------------------------------
213 void ImplTabSizer::Tracking( const TrackingEvent
& rTEvt
)
215 if ( rTEvt
.IsTrackingEnded() )
217 if ( rTEvt
.IsTrackingCanceled() )
218 ImplTrack( maStartPos
);
219 GetParent()->mnSplitSize
= 0;
222 ImplTrack( OutputToScreenPixel( rTEvt
.GetMouseEvent().GetPosPixel() ) );
225 // -----------------------------------------------------------------------
227 void ImplTabSizer::Paint( const Rectangle
& )
229 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
230 DecorationView
aDecoView( this );
232 Size aOutputSize
= GetOutputSizePixel();
234 if ( !(rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
) )
236 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
237 DrawLine( Point( 0, 0 ), Point( 0, aOutputSize
.Height()-1 ) );
239 aOutputSize
.Width()--;
241 aDecoView
.DrawButton( Rectangle( Point( nOffX
, 0 ), aOutputSize
), BUTTON_DRAW_NOLIGHTBORDER
);
244 // =======================================================================
246 // Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar
252 class TabBarEdit
: public Edit
255 Timer maLoseFocusTimer
;
258 DECL_LINK( ImplEndEditHdl
, void* );
259 DECL_LINK( ImplEndTimerHdl
, void* );
262 TabBarEdit( TabBar
* pParent
, WinBits nWinStyle
= 0 );
264 TabBar
* GetParent() const { return (TabBar
*)Window::GetParent(); }
266 void SetPostEvent() { mbPostEvt
= sal_True
; }
267 void ResetPostEvent() { mbPostEvt
= sal_False
; }
269 virtual long PreNotify( NotifyEvent
& rNEvt
);
270 virtual void LoseFocus();
273 // -----------------------------------------------------------------------
275 TabBarEdit::TabBarEdit( TabBar
* pParent
, WinBits nWinStyle
) :
276 Edit( pParent
, nWinStyle
)
278 mbPostEvt
= sal_False
;
281 // -----------------------------------------------------------------------
283 long TabBarEdit::PreNotify( NotifyEvent
& rNEvt
)
285 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
287 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
288 if ( !pKEvt
->GetKeyCode().GetModifier() )
290 if ( pKEvt
->GetKeyCode().GetCode() == KEY_RETURN
)
294 if ( PostUserEvent( LINK( this, TabBarEdit
, ImplEndEditHdl
), (void*)sal_False
) )
295 mbPostEvt
= sal_True
;
299 else if ( pKEvt
->GetKeyCode().GetCode() == KEY_ESCAPE
)
303 if ( PostUserEvent( LINK( this, TabBarEdit
, ImplEndEditHdl
), (void*)sal_True
) )
304 mbPostEvt
= sal_True
;
311 return Edit::PreNotify( rNEvt
);
314 // -----------------------------------------------------------------------
316 void TabBarEdit::LoseFocus()
320 if ( PostUserEvent( LINK( this, TabBarEdit
, ImplEndEditHdl
), (void*)sal_False
) )
321 mbPostEvt
= sal_True
;
327 // -----------------------------------------------------------------------
329 IMPL_LINK( TabBarEdit
, ImplEndEditHdl
, void*, pCancel
)
332 maLoseFocusTimer
.Stop();
334 // We need this query, because the edit get a losefous event,
335 // when it shows the context menu or the insert symbol dialog
336 if ( !HasFocus() && HasChildPathFocus( sal_True
) )
338 maLoseFocusTimer
.SetTimeout( 30 );
339 maLoseFocusTimer
.SetTimeoutHdl( LINK( this, TabBarEdit
, ImplEndTimerHdl
) );
340 maLoseFocusTimer
.Start();
343 GetParent()->EndEditMode( pCancel
!= 0 );
348 // -----------------------------------------------------------------------
350 IMPL_LINK_NOARG(TabBarEdit
, ImplEndTimerHdl
)
355 // We need this query, because the edit get a losefous event,
356 // when it shows the context menu or the insert symbol dialog
357 if ( HasChildPathFocus( sal_True
) )
358 maLoseFocusTimer
.Start();
360 GetParent()->EndEditMode( sal_True
);
365 // =======================================================================
368 ImplTabSizer
* mpSizer
;
369 ::svt::AccessibleFactoryAccess maAccessibleFactory
;
381 // =======================================================================
383 const sal_uInt16
TabBar::APPEND
= ::std::numeric_limits
<sal_uInt16
>::max();
384 const sal_uInt16
TabBar::PAGE_NOT_FOUND
= ::std::numeric_limits
<sal_uInt16
>::max();
385 const sal_uInt16
TabBar::INSERT_TAB_POS
= ::std::numeric_limits
<sal_uInt16
>::max() - 1;
387 void TabBar::ImplInit( WinBits nWinStyle
)
389 mpItemList
= new ImplTabBarList
;
394 mpImpl
= new TabBar_Impl
;
403 mnWinStyle
= nWinStyle
;
410 mbFirstFormat
= sal_True
;
411 mbSizeFormat
= sal_True
;
412 mbAutoMaxWidth
= sal_True
;
413 mbInSwitching
= sal_False
;
414 mbAutoEditMode
= sal_False
;
415 mbEditCanceled
= sal_False
;
416 mbDropPos
= sal_False
;
417 mbInSelect
= sal_False
;
418 mbSelColor
= sal_False
;
419 mbSelTextColor
= sal_False
;
420 mbMirrored
= sal_False
;
421 mbMirrored
= sal_False
;
422 mbScrollAlwaysEnabled
= false;
424 if ( nWinStyle
& WB_3DTAB
)
430 mpFirstBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVET0HOME
));
432 mpPrevBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVELEFT
));
434 mpNextBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVERIGHT
));
436 mpLastBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVETOEND
));
438 SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
439 ImplInitSettings( sal_True
, sal_True
);
442 // -----------------------------------------------------------------------
444 TabBar::TabBar( Window
* pParent
, WinBits nWinStyle
) :
445 Window( pParent
, (nWinStyle
& WB_3DLOOK
) | WB_CLIPCHILDREN
)
447 ImplInit( nWinStyle
);
448 maCurrentItemList
= 0;
451 // -----------------------------------------------------------------------
455 EndEditMode( sal_True
);
468 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
) {
469 delete (*mpItemList
)[ i
];
474 // -----------------------------------------------------------------------
475 ImplTabBarItem
* TabBar::seek( size_t i
)
477 if ( i
< mpItemList
->size() )
479 maCurrentItemList
= i
;
480 return (*mpItemList
)[ maCurrentItemList
];
485 ImplTabBarItem
* TabBar::prev()
487 if ( maCurrentItemList
> 0 ) {
488 return (*mpItemList
)[ --maCurrentItemList
];
493 ImplTabBarItem
* TabBar::next()
495 if ( maCurrentItemList
+1 < mpItemList
->size() ) {
496 return (*mpItemList
)[ ++maCurrentItemList
];
501 // -----------------------------------------------------------------------
503 void TabBar::ImplInitSettings( sal_Bool bFont
, sal_Bool bBackground
)
505 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
510 aToolFont
= rStyleSettings
.GetToolFont();
511 if ( IsControlFont() )
512 aToolFont
.Merge( GetControlFont() );
513 aToolFont
.SetWeight( WEIGHT_BOLD
);
514 SetZoomedPointFont( aToolFont
);
516 // Font in der groesse Anpassen, wenn Fenster zu klein?
517 while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
519 Font aFont
= GetFont();
520 if ( aFont
.GetHeight() <= 6 )
522 aFont
.SetHeight( aFont
.GetHeight()-1 );
530 if ( IsControlBackground() )
531 aColor
= GetControlBackground();
533 aColor
= rStyleSettings
.GetFaceColor();
534 SetBackground( aColor
);
538 // -----------------------------------------------------------------------
540 void TabBar::ImplGetColors( Color
& rFaceColor
, Color
& rFaceTextColor
,
541 Color
& rSelectColor
, Color
& rSelectTextColor
)
543 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
545 if ( IsControlBackground() )
546 rFaceColor
= GetControlBackground();
548 rFaceColor
= rStyleSettings
.GetInactiveTabColor();
549 if ( IsControlForeground() )
550 rFaceTextColor
= GetControlForeground();
552 rFaceTextColor
= rStyleSettings
.GetButtonTextColor();
554 rSelectColor
= maSelColor
;
556 rSelectColor
= rStyleSettings
.GetActiveTabColor();
557 if ( mbSelTextColor
)
558 rSelectTextColor
= maSelTextColor
;
560 rSelectTextColor
= rStyleSettings
.GetWindowTextColor();
562 // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
563 // selektierten Tabs in 3D erscheinen sollen
564 if ( mnWinStyle
& WB_3DTAB
)
566 Color aTempColor
= rFaceColor
;
567 rFaceColor
= rSelectColor
;
568 rSelectColor
= aTempColor
;
569 aTempColor
= rFaceTextColor
;
570 rFaceTextColor
= rSelectTextColor
;
571 rSelectTextColor
= rFaceTextColor
;
575 // -----------------------------------------------------------------------
577 sal_Bool
TabBar::ImplCalcWidth()
579 // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
580 // wenn der Font geaendert wurde
584 // Breiten der Tabs mit dem fetten Font ermitteln
585 Font aFont
= GetFont();
586 if ( aFont
.GetWeight() != WEIGHT_BOLD
)
588 aFont
.SetWeight( WEIGHT_BOLD
);
592 if ( mnMaxPageWidth
)
593 mnCurMaxWidth
= mnMaxPageWidth
;
594 else if ( mbAutoMaxWidth
)
596 mnCurMaxWidth
= mnLastOffX
-mnOffX
-
597 TABBAR_OFFSET_X
-TABBAR_OFFSET_X
-
598 TABBAR_OFFSET_X2
-TABBAR_OFFSET_X2
-TABBAR_OFFSET_X2
;
599 if ( mnCurMaxWidth
< 1 )
605 sal_Bool bChanged
= sal_False
;
606 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
608 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
609 long nNewWidth
= GetTextWidth( pItem
->maText
);
610 if ( mnCurMaxWidth
&& (nNewWidth
> mnCurMaxWidth
) )
612 pItem
->mbShort
= sal_True
;
613 nNewWidth
= mnCurMaxWidth
;
616 pItem
->mbShort
= sal_False
;
617 nNewWidth
+= TABBAR_OFFSET_X
+TABBAR_OFFSET_X2
;
618 if ( pItem
->mnWidth
!= nNewWidth
)
620 pItem
->mnWidth
= nNewWidth
;
621 if ( !pItem
->maRect
.IsEmpty() )
625 mbSizeFormat
= sal_False
;
630 // -----------------------------------------------------------------------
632 void TabBar::ImplFormat()
641 for ( size_t i
= 0, nL
= mpItemList
->size(); i
< nL
; ++i
)
643 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
644 // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
646 if ( (n
+1 < mnFirstPos
) || (x
> mnLastOffX
) )
647 pItem
->maRect
.SetEmpty();
650 // Etwas von der Tab vor der ersten sichtbaren Page
651 // muss auch zu sehen sein
652 if ( n
+1 == mnFirstPos
)
653 pItem
->maRect
.Left() = x
-pItem
->mnWidth
;
656 pItem
->maRect
.Left() = x
;
659 pItem
->maRect
.Right() = x
+TABBAR_OFFSET_X
+TABBAR_OFFSET_X2
;
660 pItem
->maRect
.Bottom() = maWinSize
.Height()-1;
664 long nTmp
= mnOffX
+ mnLastOffX
- pItem
->maRect
.Right();
665 pItem
->maRect
.Right() = mnOffX
+ mnLastOffX
- pItem
->maRect
.Left();
666 pItem
->maRect
.Left() = nTmp
;
673 mbFormat
= sal_False
;
675 // Button enablen/disablen
676 ImplEnableControls();
679 // -----------------------------------------------------------------------
681 sal_uInt16
TabBar::ImplGetLastFirstPos()
683 sal_uInt16 nCount
= (sal_uInt16
)(mpItemList
->size());
684 if ( !nCount
|| mbSizeFormat
|| mbFormat
)
687 sal_uInt16 nLastFirstPos
= nCount
-1;
688 long nWinWidth
= mnLastOffX
-mnOffX
-TABBAR_OFFSET_X
-ADDNEWPAGE_AREAWIDTH
;
689 long nWidth
= (*mpItemList
)[ nLastFirstPos
]->mnWidth
;
690 while ( nLastFirstPos
&& (nWidth
< nWinWidth
) )
693 nWidth
+= (*mpItemList
)[ nLastFirstPos
]->mnWidth
;
695 if ( (nLastFirstPos
!= (sal_uInt16
)(mpItemList
->size()-1)) &&
696 (nWidth
> nWinWidth
) )
698 return nLastFirstPos
;
701 // -----------------------------------------------------------------------
703 void TabBar::ImplInitControls()
705 if ( mnWinStyle
& WB_SIZEABLE
)
707 if ( !mpImpl
->mpSizer
)
708 mpImpl
->mpSizer
= new ImplTabSizer( this, mnWinStyle
& (WB_DRAG
| WB_3DLOOK
) );
709 mpImpl
->mpSizer
->Show();
713 DELETEZ( mpImpl
->mpSizer
);
716 Link aLink
= LINK( this, TabBar
, ImplClickHdl
);
718 if ( mnWinStyle
& (WB_MINSCROLL
| WB_SCROLL
) )
722 mpPrevBtn
= new ImplTabButton( this, WB_REPEAT
);
723 mpPrevBtn
->SetClickHdl( aLink
);
725 mpPrevBtn
->SetSymbol( mbMirrored
? SYMBOL_NEXT
: SYMBOL_PREV
);
730 mpNextBtn
= new ImplTabButton( this, WB_REPEAT
);
731 mpNextBtn
->SetClickHdl( aLink
);
733 mpNextBtn
->SetSymbol( mbMirrored
? SYMBOL_PREV
: SYMBOL_NEXT
);
738 DELETEZ( mpPrevBtn
);
739 DELETEZ( mpNextBtn
);
742 if ( mnWinStyle
& WB_SCROLL
)
746 mpFirstBtn
= new ImplTabButton( this );
747 mpFirstBtn
->SetClickHdl( aLink
);
749 mpFirstBtn
->SetSymbol( mbMirrored
? SYMBOL_LAST
: SYMBOL_FIRST
);
754 mpLastBtn
= new ImplTabButton( this );
755 mpLastBtn
->SetClickHdl( aLink
);
757 mpLastBtn
->SetSymbol( mbMirrored
? SYMBOL_FIRST
: SYMBOL_LAST
);
762 DELETEZ( mpFirstBtn
);
763 DELETEZ( mpLastBtn
);
766 mbHasInsertTab
= (mnWinStyle
& WB_INSERTTAB
);
769 // -----------------------------------------------------------------------
771 void TabBar::ImplEnableControls()
773 if ( mbSizeFormat
|| mbFormat
)
776 // Buttons enablen/disblen
777 sal_Bool bEnableBtn
= mbScrollAlwaysEnabled
|| mnFirstPos
> 0;
779 mpFirstBtn
->Enable( bEnableBtn
);
781 mpPrevBtn
->Enable( bEnableBtn
);
783 bEnableBtn
= mbScrollAlwaysEnabled
|| mnFirstPos
< ImplGetLastFirstPos();
785 mpNextBtn
->Enable( bEnableBtn
);
787 mpLastBtn
->Enable( bEnableBtn
);
790 void TabBar::SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled
)
792 mbScrollAlwaysEnabled
= bScrollAlwaysEnabled
;
793 ImplEnableControls();
796 // -----------------------------------------------------------------------
798 void TabBar::ImplShowPage( sal_uInt16 nPos
)
801 long nWidth
= GetOutputSizePixel().Width();
802 if ( nWidth
>= TABBAR_OFFSET_X
)
803 nWidth
-= TABBAR_OFFSET_X
;
804 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
805 if ( nPos
< mnFirstPos
)
806 SetFirstPageId( pItem
->mnId
);
807 else if ( pItem
->maRect
.Right() > nWidth
)
809 while ( pItem
->maRect
.Right() > nWidth
)
811 sal_uInt16 nNewPos
= mnFirstPos
+1;
812 SetFirstPageId( GetPageId( nNewPos
) );
814 if ( nNewPos
!= mnFirstPos
)
820 // -----------------------------------------------------------------------
822 IMPL_LINK( TabBar
, ImplClickHdl
, ImplTabButton
*, pBtn
)
826 sal_uInt16 nNewPos
= mnFirstPos
;
828 if ( pBtn
== mpFirstBtn
)
830 else if ( pBtn
== mpPrevBtn
)
833 nNewPos
= mnFirstPos
-1;
835 else if ( pBtn
== mpNextBtn
)
837 sal_uInt16 nCount
= GetPageCount();
838 if ( mnFirstPos
< nCount
)
839 nNewPos
= mnFirstPos
+1;
843 sal_uInt16 nCount
= GetPageCount();
848 if ( nNewPos
!= mnFirstPos
)
849 SetFirstPageId( GetPageId( nNewPos
) );
853 // -----------------------------------------------------------------------
855 void TabBar::MouseMove( const MouseEvent
& rMEvt
)
857 if ( rMEvt
.IsLeaveWindow() )
858 mbInSelect
= sal_False
;
860 Window::MouseMove( rMEvt
);
863 // -----------------------------------------------------------------------
865 void TabBar::MouseButtonDown( const MouseEvent
& rMEvt
)
867 // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht
869 if ( IsInEditMode() )
875 ImplTabBarItem
* pItem
;
876 sal_uInt16 nSelId
= GetPageId( rMEvt
.GetPosPixel() );
878 if ( !rMEvt
.IsLeft() )
880 Window::MouseButtonDown( rMEvt
);
881 if ( (nSelId
> 0) && (nSelId
!= mnCurPageId
) )
883 sal_uInt16 nPos
= GetPagePos( nSelId
);
884 pItem
= (*mpItemList
)[ nPos
];
886 if ( pItem
->mbEnable
)
888 if ( ImplDeactivatePage() )
890 SetCurPageId( nSelId
);
895 mbInSelect
= sal_True
;
901 if ( rMEvt
.IsMod2() && mbAutoEditMode
&& nSelId
)
903 if ( StartEditMode( nSelId
) )
907 if ( (rMEvt
.GetMode() & (MOUSE_MULTISELECT
| MOUSE_RANGESELECT
)) && (rMEvt
.GetClicks() == 1) )
911 sal_uInt16 nPos
= GetPagePos( nSelId
);
912 sal_Bool bSelectTab
= sal_False
;
913 pItem
= (*mpItemList
)[ nPos
];
915 if ( pItem
->mbEnable
)
917 if ( (rMEvt
.GetMode() & MOUSE_MULTISELECT
) && (mnWinStyle
& WB_MULTISELECT
) )
919 if ( nSelId
!= mnCurPageId
)
921 SelectPage( nSelId
, !IsPageSelected( nSelId
) );
922 bSelectTab
= sal_True
;
925 else if ( mnWinStyle
& (WB_MULTISELECT
| WB_RANGESELECT
) )
927 bSelectTab
= sal_True
;
930 sal_uInt16 nCurPos
= GetPagePos( mnCurPageId
);
931 if ( nPos
<= nCurPos
)
933 // Alle Tabs bis zur angeklickten Tab deselektieren
934 // und alle Tabs von der angeklickten Tab bis
935 // zur aktuellen Position selektieren
937 while ( n
< nCurPos
)
939 pItem
= (*mpItemList
)[ n
];
945 if ( pItem
->mbSelect
!= bSelect
)
947 pItem
->mbSelect
= bSelect
;
948 if ( !pItem
->maRect
.IsEmpty() )
949 Invalidate( pItem
->maRect
);
956 if ( nPos
>= nCurPos
)
958 // Alle Tabs von der aktuellen bis zur angeklickten
959 // Tab selektieren und alle Tabs von der angeklickten
960 // Tab bis zur letzten Tab deselektieren
961 sal_uInt16 nCount
= (sal_uInt16
)mpItemList
->size();
965 pItem
= (*mpItemList
)[ n
];
972 if ( pItem
->mbSelect
!= bSelect
)
974 pItem
->mbSelect
= bSelect
;
975 if ( !pItem
->maRect
.IsEmpty() )
976 Invalidate( pItem
->maRect
);
984 // Gegebenenfalls muss die selektierte Tab gescrollt werden
987 ImplShowPage( nPos
);
993 ImplShowPage( nPos
);
994 mbInSelect
= sal_True
;
999 else if ( rMEvt
.GetClicks() == 2 )
1001 // Gegebenenfalls den Double-Click-Handler rufen
1002 if ( !rMEvt
.GetModifier() && (!nSelId
|| (nSelId
== mnCurPageId
)) )
1004 sal_uInt16 nOldCurId
= mnCurPageId
;
1005 mnCurPageId
= nSelId
;
1007 // Abfrage, da im DoubleClick-Handler die aktuelle Seite
1008 // umgeschaltet werden konnte
1009 if ( mnCurPageId
== nSelId
)
1010 mnCurPageId
= nOldCurId
;
1019 // Nur Select ausfuehren, wenn noch nicht aktuelle Page
1020 if ( nSelId
!= mnCurPageId
)
1022 sal_uInt16 nPos
= GetPagePos( nSelId
);
1023 pItem
= (*mpItemList
)[ nPos
];
1025 if ( pItem
->mbEnable
)
1027 if ( !pItem
->mbSelect
)
1029 // Muss invalidiert werden
1030 sal_Bool bUpdate
= sal_False
;
1031 if ( IsReallyVisible() && IsUpdateMode() )
1034 // Alle selektierten Items deselektieren
1035 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
1037 pItem
= (*mpItemList
)[ i
];
1038 if ( pItem
->mbSelect
|| (pItem
->mnId
== mnCurPageId
) )
1040 pItem
->mbSelect
= sal_False
;
1042 Invalidate( pItem
->maRect
);
1047 if ( ImplDeactivatePage() )
1049 SetCurPageId( nSelId
);
1056 ImplShowPage( nPos
);
1057 mbInSelect
= sal_True
;
1064 Window::MouseButtonDown( rMEvt
);
1067 // -----------------------------------------------------------------------
1069 void TabBar::MouseButtonUp( const MouseEvent
& rMEvt
)
1071 mbInSelect
= sal_False
;
1072 Window::MouseButtonUp( rMEvt
);
1076 // -----------------------------------------------------------------------
1080 class TabBarPaintGuard
1083 explicit TabBarPaintGuard(TabBar
& rParent
) :
1085 maFont(rParent
.GetFont())
1087 // #i36013# exclude push buttons from painting area
1088 mrParent
.SetClipRegion( Region(mrParent
.GetPageArea()) );
1093 // Restore original font.
1094 mrParent
.SetFont(maFont
);
1095 // remove clip region
1096 mrParent
.SetClipRegion();
1107 explicit TabDrawer(TabBar
& rParent
) :
1109 mpStyleSettings(&mrParent
.GetSettings().GetStyleSettings()),
1112 mbCustomColored(false),
1113 mbSpecialTab(false),
1118 void drawOutputAreaBorder()
1120 WinBits nWinStyle
= mrParent
.GetStyle();
1122 // Bei Border oben und unten einen Strich extra malen
1123 if ( (nWinStyle
& WB_BORDER
) || (nWinStyle
& WB_TOPBORDER
) )
1125 Size aOutputSize
= mrParent
.GetOutputSizePixel();
1126 Rectangle aOutRect
= mrParent
.GetPageArea();
1128 // Bei 3D-Tabs wird auch der Border in 3D gemalt
1129 if ( nWinStyle
& WB_3DTAB
)
1131 mrParent
.SetLineColor( mpStyleSettings
->GetShadowColor() );
1132 mrParent
.DrawLine( Point( aOutRect
.Left(), 0 ), Point( aOutputSize
.Width(), 0 ) );
1135 // Border malen (Strich oben und Strich unten)
1136 mrParent
.SetLineColor( mpStyleSettings
->GetDarkShadowColor() );
1137 mrParent
.DrawLine( aOutRect
.TopLeft(), Point( aOutputSize
.Width()-1, aOutRect
.Top() ) );
1141 void drawOuterFrame()
1143 mrParent
.DrawPolygon(maPoly
);
1146 void drawLeftShadow()
1148 Point p1
= maPoly
[0], p2
= maPoly
[1];
1152 mrParent
.DrawLine(p1
, p2
);
1155 void drawRightShadow()
1157 Point p1
= maPoly
[2];
1158 Point p2
= maPoly
[3];
1161 mrParent
.DrawLine(p1
, p2
);
1164 void drawTopInnerShadow()
1166 Point p1
= maPoly
[0], p2
= maPoly
[3];
1169 mrParent
.DrawLine(p1
, p2
);
1172 void drawBottomShadow(bool bColored
)
1174 Point p1
= maPoly
[1], p2
= maPoly
[2];
1179 mrParent
.DrawLine(p1
, p2
);
1182 p1
+= Point(-1, -1);
1184 mrParent
.DrawLine(p1
, p2
);
1188 void drawText(const OUString
& aText
)
1190 Rectangle aRect
= maRect
;
1191 long nTextWidth
= mrParent
.GetTextWidth(aText
);
1192 long nTextHeight
= mrParent
.GetTextHeight();
1193 Point aPos
= aRect
.TopLeft();
1194 aPos
.X() += (aRect
.getWidth() - nTextWidth
) / 2;
1195 aPos
.Y() += (aRect
.getHeight() - nTextHeight
) / 2;
1198 mrParent
.DrawText(aPos
, aText
);
1200 mrParent
.DrawCtrlText(
1201 aPos
, aText
, 0, STRING_LEN
, (TEXT_DRAW_DISABLE
| TEXT_DRAW_MNEMONIC
));
1204 void drawOverTopBorder(bool b3DTab
)
1206 Point p1
= maPoly
[0], p2
= maPoly
[3];
1209 Rectangle
aDelRect(p1
, p2
);
1210 mrParent
.DrawRect(aDelRect
);
1214 mrParent
.DrawRect(aDelRect
);
1220 mrParent
.SetLineColor(mpStyleSettings
->GetDarkShadowColor());
1222 // Je nach Status die richtige FillInBrush setzen
1223 // Set the correct FillInBrush depending upon status
1226 // Currently selected Tab
1227 mrParent
.SetFillColor( maSelectedColor
);
1229 else if ( mbCustomColored
)
1231 mrParent
.SetFillColor( maCustomColor
);
1235 mrParent
.SetFillColor( maUnselectedColor
);
1240 // If this is the current tab, draw the left inner shadow the default color,
1241 // otherwise make it the same as the custom background color
1242 Color aColor
= mpStyleSettings
->GetLightColor();
1243 if (mbCustomColored
&& !mbSelected
)
1244 aColor
= maCustomColor
;
1246 mrParent
.SetLineColor(aColor
);
1250 drawTopInnerShadow();
1252 mrParent
.SetLineColor( mpStyleSettings
->GetShadowColor() );
1254 if ( mbCustomColored
&& mbSelected
)
1256 mrParent
.SetLineColor(maCustomColor
);
1257 drawBottomShadow(true);
1260 drawBottomShadow(false);
1262 // Draw the outer frame once more. In some environments, the outer frame
1263 // gets overpainted.
1264 mrParent
.SetLineColor( mpStyleSettings
->GetDarkShadowColor() );
1265 mrParent
.SetFillColor();
1269 void drawPlusImage()
1271 SvtResId
id( BMP_LIST_ADD
);
1272 Image
aPlusImg( id
);
1273 // Center the image within the bounding rectangle.
1274 Size aSize
= aPlusImg
.GetSizePixel();
1275 Point pt
= maRect
.TopLeft();
1276 long nXOffSet
= (maRect
.GetWidth() - aSize
.Width()) / 2;
1277 long nYOffset
= (maRect
.GetHeight() - aSize
.Height()) / 2;
1278 pt
+= Point(nXOffSet
, nYOffset
);
1280 mrParent
.DrawImage(pt
, aPlusImg
);
1283 void setRect(const Rectangle
& rRect
)
1287 long nOffY
= mrParent
.GetPageArea().getY();
1289 // Zuerst geben wir das Polygon gefuellt aus
1290 maPoly
[0] = Point( rRect
.Left(), nOffY
);
1291 maPoly
[1] = Point( rRect
.Left()+TABBAR_OFFSET_X
, rRect
.Bottom() );
1292 maPoly
[2] = Point( rRect
.Right()-TABBAR_OFFSET_X
, rRect
.Bottom() );
1293 maPoly
[3] = Point( rRect
.Right(), nOffY
);
1296 void setSelected(bool b
)
1301 void setCustomColored(bool b
)
1303 mbCustomColored
= b
;
1306 void setSpecialTab(bool b
)
1311 void setEnabled(bool b
)
1316 void setSelectedFillColor(const Color
& rColor
)
1318 maSelectedColor
= rColor
;
1321 void setUnselectedFillColor(const Color
& rColor
)
1323 maUnselectedColor
= rColor
;
1326 void setCustomColor(const Color
& rColor
)
1328 maCustomColor
= rColor
;
1333 const StyleSettings
* mpStyleSettings
;
1338 Color maSelectedColor
;
1339 Color maCustomColor
;
1340 Color maUnselectedColor
;
1343 bool mbCustomColored
:1;
1344 bool mbSpecialTab
:1;
1350 void TabBar::Paint( const Rectangle
& rect
)
1352 if(IsNativeControlSupported(CTRL_WINDOW_BACKGROUND
,PART_ENTIRE_CONTROL
))
1353 DrawNativeControl(CTRL_WINDOW_BACKGROUND
,PART_ENTIRE_CONTROL
,rect
,
1354 CTRL_STATE_ENABLED
,ImplControlValue(0),OUString());
1356 // Items berechnen und ausgeben
1357 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
1363 Color aFaceColor
, aSelectColor
, aFaceTextColor
, aSelectTextColor
;
1364 ImplGetColors( aFaceColor
, aFaceTextColor
, aSelectColor
, aSelectTextColor
);
1367 Font aFont
= GetFont();
1368 Font aLightFont
= aFont
;
1369 aLightFont
.SetWeight( WEIGHT_NORMAL
);
1371 TabBarPaintGuard
aGuard(*this);
1372 TabDrawer
aDrawer(*this);
1373 aDrawer
.setSelectedFillColor(aSelectColor
);
1374 aDrawer
.setUnselectedFillColor(aFaceColor
);
1375 aDrawer
.drawOutputAreaBorder();
1377 // Now, start drawing the tabs.
1379 ImplTabBarItem
* pItem
= ImplGetLastTabBarItem(nItemCount
);
1381 if (pItem
&& mbHasInsertTab
)
1383 // Draw the insert tab at the right end.
1384 Rectangle aRect
= ImplGetInsertTabRect(pItem
);
1385 aDrawer
.setRect(aRect
);
1387 aDrawer
.drawPlusImage();
1390 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1391 ImplTabBarItem
* pCurItem
= NULL
;
1394 // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
1395 if ( !pCurItem
&& (pItem
->mnId
== mnCurPageId
) )
1404 bool bCurrent
= pItem
== pCurItem
;
1406 if ( !pItem
->maRect
.IsEmpty() )
1408 Rectangle aRect
= pItem
->maRect
;
1409 bool bSelected
= pItem
->IsSelected(pCurItem
);
1410 // We disable custom background color in high contrast mode.
1411 bool bCustomBgColor
= !pItem
->IsDefaultTabBgColor() && !rStyleSettings
.GetHighContrastMode();
1412 bool bSpecialTab
= (pItem
->mnBits
& TPB_SPECIAL
);
1413 bool bEnabled
= pItem
->mbEnable
;
1414 OUString aText
= pItem
->mbShort
?
1415 GetEllipsisString(pItem
->maText
, mnCurMaxWidth
, TEXT_DRAW_ENDELLIPSIS
) : pItem
->maText
;
1417 aDrawer
.setRect(aRect
);
1418 aDrawer
.setSelected(bSelected
);
1419 aDrawer
.setCustomColored(bCustomBgColor
);
1420 aDrawer
.setSpecialTab(bSpecialTab
);
1421 aDrawer
.setEnabled(bEnabled
);
1422 aDrawer
.setCustomColor(pItem
->maTabBgColor
);
1425 // Aktuelle Page wird mit einem fetten Font ausgegeben
1429 SetFont( aLightFont
);
1431 // Je nach Status die richtige FillInBrush setzen
1432 // Set the correct FillInBrush depending upon status
1434 SetTextColor( aSelectTextColor
);
1435 else if ( bCustomBgColor
)
1436 SetTextColor( pItem
->maTabTextColor
);
1438 SetTextColor( aFaceTextColor
);
1440 // This tab is "special", and a special tab needs a blue text.
1442 SetTextColor(Color(COL_LIGHTBLUE
));
1444 aDrawer
.drawText(aText
);
1449 SetFillColor(aSelectColor
);
1450 aDrawer
.drawOverTopBorder(mnWinStyle
& WB_3DTAB
);
1469 // -----------------------------------------------------------------------
1470 void TabBar::Resize()
1472 Size aNewSize
= GetOutputSizePixel();
1474 long nSizerWidth
= 0;
1475 long nButtonWidth
= 0;
1478 if ( mpImpl
->mpSizer
)
1480 Size aSizerSize
= mpImpl
->mpSizer
->GetSizePixel();
1481 Point
aNewSizerPos( mbMirrored
? 0 : (aNewSize
.Width()-aSizerSize
.Width()), 0 );
1482 Size
aNewSizerSize( aSizerSize
.Width(), aNewSize
.Height() );
1483 mpImpl
->mpSizer
->SetPosSizePixel( aNewSizerPos
, aNewSizerSize
);
1484 nSizerWidth
= aSizerSize
.Width();
1487 // Scroll-Buttons anordnen
1488 long nHeight
= aNewSize
.Height();
1489 // Font in der groesse Anpassen?
1490 ImplInitSettings( sal_True
, sal_False
);
1492 long nX
= mbMirrored
? (aNewSize
.Width()-nHeight
) : 0;
1493 long nXDiff
= mbMirrored
? -nHeight
: nHeight
;
1495 Size
aBtnSize( nHeight
, nHeight
);
1498 mpFirstBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1500 nButtonWidth
+= nHeight
;
1504 mpPrevBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1506 nButtonWidth
+= nHeight
;
1510 mpNextBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1512 nButtonWidth
+= nHeight
;
1516 mpLastBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1518 nButtonWidth
+= nHeight
;
1522 maWinSize
= aNewSize
;
1526 mnOffX
= nSizerWidth
;
1527 mnLastOffX
= maWinSize
.Width() - nButtonWidth
- 1;
1531 mnOffX
= nButtonWidth
;
1532 mnLastOffX
= maWinSize
.Width() - nSizerWidth
- 1;
1536 mbSizeFormat
= sal_True
;
1537 if ( IsReallyVisible() )
1539 if ( ImplCalcWidth() )
1544 // Button enablen/disablen
1545 ImplEnableControls();
1548 // -----------------------------------------------------------------------
1550 void TabBar::RequestHelp( const HelpEvent
& rHEvt
)
1552 sal_uInt16 nItemId
= GetPageId( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ) );
1555 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
1557 OUString aStr
= GetHelpText( nItemId
);
1558 if (!aStr
.isEmpty())
1560 Rectangle aItemRect
= GetPageRect( nItemId
);
1561 Point aPt
= OutputToScreenPixel( aItemRect
.TopLeft() );
1562 aItemRect
.Left() = aPt
.X();
1563 aItemRect
.Top() = aPt
.Y();
1564 aPt
= OutputToScreenPixel( aItemRect
.BottomRight() );
1565 aItemRect
.Right() = aPt
.X();
1566 aItemRect
.Bottom() = aPt
.Y();
1567 Help::ShowBalloon( this, aItemRect
.Center(), aItemRect
, aStr
);
1571 else if ( rHEvt
.GetMode() & HELPMODE_EXTENDED
)
1573 OUString
aHelpId( OStringToOUString( GetHelpId( nItemId
), RTL_TEXTENCODING_UTF8
) );
1574 if ( !aHelpId
.isEmpty() )
1576 // Wenn eine Hilfe existiert, dann ausloesen
1577 Help
* pHelp
= Application::GetHelp();
1579 pHelp
->Start( aHelpId
, this );
1584 // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
1585 // wenn dieser abgeschnitten oder nicht voll sichtbar ist
1586 if ( rHEvt
.GetMode() & (HELPMODE_QUICK
| HELPMODE_BALLOON
) )
1588 sal_uInt16 nPos
= GetPagePos( nItemId
);
1589 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
1590 if ( pItem
->mbShort
||
1591 (pItem
->maRect
.Right()-TABBAR_OFFSET_X
-5 > mnLastOffX
) )
1593 Rectangle aItemRect
= GetPageRect( nItemId
);
1594 Point aPt
= OutputToScreenPixel( aItemRect
.TopLeft() );
1595 aItemRect
.Left() = aPt
.X();
1596 aItemRect
.Top() = aPt
.Y();
1597 aPt
= OutputToScreenPixel( aItemRect
.BottomRight() );
1598 aItemRect
.Right() = aPt
.X();
1599 aItemRect
.Bottom() = aPt
.Y();
1600 OUString aStr
= (*mpItemList
)[ nPos
]->maText
;
1601 if (!aStr
.isEmpty())
1603 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
1604 Help::ShowBalloon( this, aItemRect
.Center(), aItemRect
, aStr
);
1606 Help::ShowQuickHelp( this, aItemRect
, aStr
);
1613 Window::RequestHelp( rHEvt
);
1616 // -----------------------------------------------------------------------
1618 void TabBar::StateChanged( StateChangedType nType
)
1620 Window::StateChanged( nType
);
1622 if ( nType
== STATE_CHANGE_INITSHOW
)
1624 if ( (mbSizeFormat
|| mbFormat
) && !mpItemList
->empty() )
1627 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
1628 (nType
== STATE_CHANGE_CONTROLFONT
) )
1630 ImplInitSettings( sal_True
, sal_False
);
1633 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
1635 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
1637 ImplInitSettings( sal_False
, sal_True
);
1640 else if ( nType
== STATE_CHANGE_MIRRORING
)
1642 // reacts on calls of EnableRTL, have to mirror all child controls
1643 if( mpFirstBtn
) mpFirstBtn
->EnableRTL( IsRTLEnabled() );
1644 if( mpPrevBtn
) mpPrevBtn
->EnableRTL( IsRTLEnabled() );
1645 if( mpNextBtn
) mpNextBtn
->EnableRTL( IsRTLEnabled() );
1646 if( mpLastBtn
) mpLastBtn
->EnableRTL( IsRTLEnabled() );
1647 if( mpImpl
->mpSizer
) mpImpl
->mpSizer
->EnableRTL( IsRTLEnabled() );
1648 if( mpEdit
) mpEdit
->EnableRTL( IsRTLEnabled() );
1652 // -----------------------------------------------------------------------
1654 void TabBar::DataChanged( const DataChangedEvent
& rDCEvt
)
1656 Window::DataChanged( rDCEvt
);
1658 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1659 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1660 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1661 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
1663 ImplInitSettings( sal_True
, sal_True
);
1668 // -----------------------------------------------------------------------
1670 void TabBar::ImplSelect()
1674 CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(mnCurPageId
)) );
1677 // -----------------------------------------------------------------------
1679 void TabBar::Select()
1681 maSelectHdl
.Call( this );
1684 // -----------------------------------------------------------------------
1686 void TabBar::DoubleClick()
1688 maDoubleClickHdl
.Call( this );
1691 // -----------------------------------------------------------------------
1693 void TabBar::Split()
1695 maSplitHdl
.Call( this );
1698 // -----------------------------------------------------------------------
1700 void TabBar::ImplActivatePage()
1704 CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(mnCurPageId
)) );
1707 // -----------------------------------------------------------------------
1709 void TabBar::ActivatePage()
1711 maActivatePageHdl
.Call( this );
1714 // -----------------------------------------------------------------------
1716 long TabBar::ImplDeactivatePage()
1718 long nRet
= DeactivatePage();
1720 CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(mnCurPageId
)) );
1725 void TabBar::ImplPrePaint()
1727 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
1731 ImplTabBarItem
* pItem
;
1733 // TabBar muss formatiert sein
1736 // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
1738 if ( mbFirstFormat
)
1740 mbFirstFormat
= sal_False
;
1742 if ( mnCurPageId
&& (mnFirstPos
== 0) && !mbDropPos
)
1744 pItem
= (*mpItemList
)[ GetPagePos( mnCurPageId
) ];
1745 if ( pItem
->maRect
.IsEmpty() )
1747 // mbDropPos setzen (bzw. misbrauchen) um Invalidate()
1749 mbDropPos
= sal_True
;
1750 SetFirstPageId( mnCurPageId
);
1751 mbDropPos
= sal_False
;
1752 if ( mnFirstPos
!= 0 )
1759 ImplTabBarItem
* TabBar::ImplGetLastTabBarItem( sal_uInt16 nItemCount
)
1761 // letzten sichtbaren Eintrag suchen
1762 sal_uInt16 n
= mnFirstPos
+1;
1763 if ( n
>= nItemCount
)
1765 ImplTabBarItem
* pItem
= seek( n
);
1768 if ( !pItem
->maRect
.IsEmpty() )
1777 // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
1780 else if ( n
>= nItemCount
)
1786 Rectangle
TabBar::ImplGetInsertTabRect(ImplTabBarItem
* pItem
) const
1788 if (mbHasInsertTab
&& pItem
)
1790 Rectangle aInsTabRect
= pItem
->maRect
;
1793 aInsTabRect
.getX() + aInsTabRect
.getWidth() - TABBAR_OFFSET_X
- TABBAR_OFFSET_X2
);
1796 aInsTabRect
.getX() - 3*TABBAR_OFFSET_X
- TABBAR_OFFSET_X2
);
1797 aInsTabRect
.setWidth(32);
1803 // -----------------------------------------------------------------------
1805 long TabBar::DeactivatePage()
1807 if ( maDeactivatePageHdl
.IsSet() )
1808 return maDeactivatePageHdl
.Call( this );
1813 // -----------------------------------------------------------------------
1815 long TabBar::StartRenaming()
1817 if ( maStartRenamingHdl
.IsSet() )
1818 return maStartRenamingHdl
.Call( this );
1823 // -----------------------------------------------------------------------
1825 long TabBar::AllowRenaming()
1827 if ( maAllowRenamingHdl
.IsSet() )
1828 return maAllowRenamingHdl
.Call( this );
1833 // -----------------------------------------------------------------------
1835 void TabBar::EndRenaming()
1837 maEndRenamingHdl
.Call( this );
1840 // -----------------------------------------------------------------------
1842 void TabBar::Mirror()
1847 // -----------------------------------------------------------------------
1849 void TabBar::InsertPage( sal_uInt16 nPageId
, const OUString
& rText
,
1850 TabBarPageBits nBits
, sal_uInt16 nPos
)
1852 DBG_ASSERT( nPageId
, "TabBar::InsertPage(): PageId == 0" );
1853 DBG_ASSERT( GetPagePos( nPageId
) == PAGE_NOT_FOUND
,
1854 "TabBar::InsertPage(): PageId already exists" );
1855 DBG_ASSERT( nBits
<= TPB_SPECIAL
, "TabBar::InsertPage(): nBits is wrong" );
1857 // PageItem anlegen und in die Item-Liste eintragen
1858 ImplTabBarItem
* pItem
= new ImplTabBarItem( nPageId
, rText
, nBits
);
1859 if ( nPos
< mpItemList
->size() ) {
1860 ImplTabBarList::iterator it
= mpItemList
->begin();
1861 ::std::advance( it
, nPos
);
1862 mpItemList
->insert( it
, pItem
);
1864 mpItemList
->push_back( pItem
);
1866 mbSizeFormat
= sal_True
;
1868 // CurPageId gegebenenfalls setzen
1870 mnCurPageId
= nPageId
;
1872 // Leiste neu ausgeben
1873 if ( IsReallyVisible() && IsUpdateMode() )
1876 CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(nPageId
)) );
1879 // -----------------------------------------------------------------------
1881 Color
TabBar::GetTabBgColor( sal_uInt16 nPageId
) const
1883 sal_uInt16 nPos
= GetPagePos( nPageId
);
1885 if ( nPos
!= PAGE_NOT_FOUND
)
1886 return (*mpItemList
)[ nPos
]->maTabBgColor
;
1888 return Color( COL_AUTO
);
1891 void TabBar::SetTabBgColor( sal_uInt16 nPageId
, const Color
& aTabBgColor
)
1893 sal_uInt16 nPos
= GetPagePos( nPageId
);
1894 ImplTabBarItem
* pItem
;
1895 if ( nPos
!= PAGE_NOT_FOUND
)
1897 pItem
= (*mpItemList
)[ nPos
];
1898 if ( aTabBgColor
!= Color( COL_AUTO
) )
1900 pItem
->maTabBgColor
= aTabBgColor
;
1901 if ( aTabBgColor
.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
1902 pItem
->maTabTextColor
= Color( COL_WHITE
);
1904 pItem
->maTabTextColor
= Color( COL_BLACK
);
1908 pItem
->maTabBgColor
= Color( COL_AUTO
);
1909 pItem
->maTabTextColor
= Color( COL_AUTO
);
1914 // -----------------------------------------------------------------------
1916 void TabBar::RemovePage( sal_uInt16 nPageId
)
1918 sal_uInt16 nPos
= GetPagePos( nPageId
);
1921 if ( nPos
!= PAGE_NOT_FOUND
)
1923 if ( mnCurPageId
== nPageId
)
1926 // Testen, ob erste sichtbare Seite verschoben werden muss
1927 if ( mnFirstPos
> nPos
)
1930 // Item-Daten loeschen
1931 ImplTabBarList::iterator it
= mpItemList
->begin();
1932 ::std::advance( it
, nPos
);
1934 mpItemList
->erase( it
);
1936 // Leiste neu ausgeben
1937 if ( IsReallyVisible() && IsUpdateMode() )
1940 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(nPageId
)) );
1944 // -----------------------------------------------------------------------
1946 void TabBar::MovePage( sal_uInt16 nPageId
, sal_uInt16 nNewPos
)
1948 sal_uInt16 nPos
= GetPagePos( nPageId
);
1949 Pair
aPair( nPos
, nNewPos
);
1951 if ( nPos
< nNewPos
)
1954 if ( nPos
== nNewPos
)
1958 if ( nPos
!= PAGE_NOT_FOUND
)
1960 // TabBar-Item in der Liste verschieben
1961 ImplTabBarList::iterator it
= mpItemList
->begin();
1962 ::std::advance( it
, nPos
);
1963 ImplTabBarItem
* pItem
= *it
;
1964 mpItemList
->erase( it
);
1965 if ( nNewPos
< mpItemList
->size() ) {
1966 it
= mpItemList
->begin();
1967 ::std::advance( it
, nNewPos
);
1968 mpItemList
->insert( it
, pItem
);
1970 mpItemList
->push_back( pItem
);
1973 // Leiste neu ausgeben
1974 if ( IsReallyVisible() && IsUpdateMode() )
1977 CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED
, (void*) &aPair
);
1981 // -----------------------------------------------------------------------
1983 void TabBar::Clear()
1985 // Alle Items loeschen
1986 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
) {
1987 delete (*mpItemList
)[ i
];
1989 mpItemList
->clear();
1991 // Items aus der Liste loeschen
1992 mbSizeFormat
= sal_True
;
1995 maCurrentItemList
= 0;
1997 // Leiste neu ausgeben
1998 if ( IsReallyVisible() && IsUpdateMode() )
2001 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(PAGE_NOT_FOUND
)) );
2004 // -----------------------------------------------------------------------
2006 sal_Bool
TabBar::IsPageEnabled( sal_uInt16 nPageId
) const
2008 sal_uInt16 nPos
= GetPagePos( nPageId
);
2010 if ( nPos
!= PAGE_NOT_FOUND
)
2011 return (*mpItemList
)[ nPos
]->mbEnable
;
2016 // -----------------------------------------------------------------------
2018 void TabBar::SetPageBits( sal_uInt16 nPageId
, TabBarPageBits nBits
)
2020 sal_uInt16 nPos
= GetPagePos( nPageId
);
2022 if ( nPos
!= PAGE_NOT_FOUND
)
2024 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2026 if ( pItem
->mnBits
!= nBits
)
2028 pItem
->mnBits
= nBits
;
2030 // Leiste neu ausgeben
2031 if ( IsReallyVisible() && IsUpdateMode() )
2032 Invalidate( pItem
->maRect
);
2037 // -----------------------------------------------------------------------
2039 TabBarPageBits
TabBar::GetPageBits( sal_uInt16 nPageId
) const
2041 sal_uInt16 nPos
= GetPagePos( nPageId
);
2043 if ( nPos
!= PAGE_NOT_FOUND
)
2044 return (*mpItemList
)[ nPos
]->mnBits
;
2049 // -----------------------------------------------------------------------
2051 sal_uInt16
TabBar::GetPageCount() const
2053 return (sal_uInt16
)mpItemList
->size();
2056 // -----------------------------------------------------------------------
2058 sal_uInt16
TabBar::GetPageId( sal_uInt16 nPos
) const
2060 return ( nPos
< mpItemList
->size() ) ? (*mpItemList
)[ nPos
]->mnId
: 0;
2063 // -----------------------------------------------------------------------
2065 sal_uInt16
TabBar::GetPagePos( sal_uInt16 nPageId
) const
2067 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
) {
2068 if ( (*mpItemList
)[ i
]->mnId
== nPageId
) {
2069 return sal_uInt16( i
);
2072 return PAGE_NOT_FOUND
;
2075 // -----------------------------------------------------------------------
2077 sal_uInt16
TabBar::GetPageId( const Point
& rPos
, bool bCheckInsTab
) const
2079 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
2081 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
2082 if ( pItem
->maRect
.IsInside( rPos
) )
2086 if (bCheckInsTab
&& mbHasInsertTab
&& !mpItemList
->empty())
2088 ImplTabBarItem
* pItem
= mpItemList
->back();
2089 if (ImplGetInsertTabRect(pItem
).IsInside(rPos
))
2090 return INSERT_TAB_POS
;
2096 // -----------------------------------------------------------------------
2098 Rectangle
TabBar::GetPageRect( sal_uInt16 nPageId
) const
2100 sal_uInt16 nPos
= GetPagePos( nPageId
);
2102 if ( nPos
!= PAGE_NOT_FOUND
)
2103 return (*mpItemList
)[ nPos
]->maRect
;
2108 // -----------------------------------------------------------------------
2110 void TabBar::SetCurPageId( sal_uInt16 nPageId
)
2112 sal_uInt16 nPos
= GetPagePos( nPageId
);
2114 // Wenn Item nicht existiert, dann nichts machen
2115 if ( nPos
!= PAGE_NOT_FOUND
)
2117 // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
2118 // jetzt nichts mehr machen
2119 if ( nPageId
== mnCurPageId
)
2122 // Muss invalidiert werden
2123 sal_Bool bUpdate
= sal_False
;
2124 if ( IsReallyVisible() && IsUpdateMode() )
2127 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2128 ImplTabBarItem
* pOldItem
;
2131 pOldItem
= (*mpItemList
)[ GetPagePos( mnCurPageId
) ];
2135 // Wenn Page nicht selektiert, dann vorher selektierte Seite
2136 // deselktieren, wenn dies die einzige selektierte Seite ist
2137 if ( !pItem
->mbSelect
&& pOldItem
)
2139 sal_uInt16 nSelPageCount
= GetSelectPageCount();
2140 if ( nSelPageCount
== 1 )
2141 pOldItem
->mbSelect
= sal_False
;
2142 pItem
->mbSelect
= sal_True
;
2145 mnCurPageId
= nPageId
;
2146 mbFormat
= sal_True
;
2148 // Dafuer sorgen, das aktuelle Page sichtbar wird
2149 if ( IsReallyVisible() )
2151 if ( nPos
< mnFirstPos
)
2152 SetFirstPageId( nPageId
);
2155 // sichtbare Breite berechnen
2156 long nWidth
= mnLastOffX
;
2157 if ( nWidth
> TABBAR_OFFSET_X
)
2158 nWidth
-= TABBAR_OFFSET_X
;
2159 if ( nWidth
> ADDNEWPAGE_AREAWIDTH
)
2160 nWidth
-= ADDNEWPAGE_AREAWIDTH
;
2162 if ( pItem
->maRect
.IsEmpty() )
2165 while ( (mbMirrored
? (pItem
->maRect
.Left() < mnOffX
) : (pItem
->maRect
.Right() > nWidth
)) ||
2166 pItem
->maRect
.IsEmpty() )
2168 sal_uInt16 nNewPos
= mnFirstPos
+1;
2169 // Dafuer sorgen, das min. die aktuelle TabPages als
2170 // erste TabPage sichtbar ist
2171 if ( nNewPos
>= nPos
)
2173 SetFirstPageId( nPageId
);
2177 SetFirstPageId( GetPageId( nNewPos
) );
2179 // Falls erste Seite nicht weitergeschaltet wird, dann
2180 // koennen wir abbrechen
2181 if ( nNewPos
!= mnFirstPos
)
2187 // Leiste neu ausgeben
2190 Invalidate( pItem
->maRect
);
2192 Invalidate( pOldItem
->maRect
);
2197 // -----------------------------------------------------------------------
2199 void TabBar::MakeVisible( sal_uInt16 nPageId
)
2201 if ( !IsReallyVisible() )
2204 sal_uInt16 nPos
= GetPagePos( nPageId
);
2206 // Wenn Item nicht existiert, dann nichts machen
2207 if ( nPos
!= PAGE_NOT_FOUND
)
2209 if ( nPos
< mnFirstPos
)
2210 SetFirstPageId( nPageId
);
2213 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2215 // sichtbare Breite berechnen
2216 long nWidth
= mnLastOffX
;
2217 if ( nWidth
> TABBAR_OFFSET_X
)
2218 nWidth
-= TABBAR_OFFSET_X
;
2220 if ( mbFormat
|| pItem
->maRect
.IsEmpty() )
2222 mbFormat
= sal_True
;
2226 while ( (pItem
->maRect
.Right() > nWidth
) ||
2227 pItem
->maRect
.IsEmpty() )
2229 sal_uInt16 nNewPos
= mnFirstPos
+1;
2230 // Dafuer sorgen, das min. die aktuelle TabPages als
2231 // erste TabPage sichtbar ist
2232 if ( nNewPos
>= nPos
)
2234 SetFirstPageId( nPageId
);
2238 SetFirstPageId( GetPageId( nNewPos
) );
2240 // Falls erste Seite nicht weitergeschaltet wird, dann
2241 // koennen wir abbrechen
2242 if ( nNewPos
!= mnFirstPos
)
2249 // -----------------------------------------------------------------------
2251 void TabBar::SetFirstPageId( sal_uInt16 nPageId
)
2253 sal_uInt16 nPos
= GetPagePos( nPageId
);
2255 // Wenn Item nicht existiert, dann sal_False zurueckgeben
2256 if ( nPos
!= PAGE_NOT_FOUND
)
2258 if ( nPos
!= mnFirstPos
)
2260 // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
2261 // moeglich sichtbar sind
2263 sal_uInt16 nLastFirstPos
= ImplGetLastFirstPos();
2265 if ( nPos
> nLastFirstPos
)
2266 nNewPos
= nLastFirstPos
;
2270 if ( nNewPos
!= mnFirstPos
)
2272 mnFirstPos
= nNewPos
;
2273 mbFormat
= sal_True
;
2275 // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
2276 // dieses Flag gesetzt ist, wird direkt gepaintet)
2277 if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos
)
2284 // -----------------------------------------------------------------------
2286 void TabBar::SelectPage( sal_uInt16 nPageId
, sal_Bool bSelect
)
2288 sal_uInt16 nPos
= GetPagePos( nPageId
);
2290 if ( nPos
!= PAGE_NOT_FOUND
)
2292 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2294 if ( pItem
->mbSelect
!= bSelect
)
2296 pItem
->mbSelect
= bSelect
;
2298 // Leiste neu ausgeben
2299 if ( IsReallyVisible() && IsUpdateMode() )
2300 Invalidate( pItem
->maRect
);
2305 // -----------------------------------------------------------------------
2307 sal_uInt16
TabBar::GetSelectPageCount() const
2309 sal_uInt16 nSelected
= 0;
2310 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
2312 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
2313 if ( pItem
->mbSelect
)
2320 // -----------------------------------------------------------------------
2322 sal_Bool
TabBar::IsPageSelected( sal_uInt16 nPageId
) const
2324 sal_uInt16 nPos
= GetPagePos( nPageId
);
2325 if ( nPos
!= PAGE_NOT_FOUND
)
2326 return (*mpItemList
)[ nPos
]->mbSelect
;
2331 // -----------------------------------------------------------------------
2333 sal_Bool
TabBar::StartEditMode( sal_uInt16 nPageId
)
2335 sal_uInt16 nPos
= GetPagePos( nPageId
);
2336 if ( mpEdit
|| (nPos
== PAGE_NOT_FOUND
) || (mnLastOffX
< 8) )
2340 if ( StartRenaming() )
2342 ImplShowPage( nPos
);
2346 mpEdit
= new TabBarEdit( this, WB_CENTER
);
2347 Rectangle aRect
= GetPageRect( mnEditId
);
2348 long nX
= aRect
.Left()+TABBAR_OFFSET_X
+(TABBAR_OFFSET_X2
/2);
2349 long nWidth
= aRect
.GetWidth()-(TABBAR_OFFSET_X
*2)-TABBAR_OFFSET_X2
;
2350 if ( mnEditId
!= GetCurPageId() )
2352 if ( nX
+nWidth
> mnLastOffX
)
2353 nWidth
= mnLastOffX
-nX
;
2357 nWidth
= aRect
.GetWidth();
2359 mpEdit
->SetText( GetPageText( mnEditId
) );
2360 mpEdit
->setPosSizePixel( nX
, aRect
.Top()+mnOffY
+1, nWidth
, aRect
.GetHeight()-3 );
2361 Font aFont
= GetPointFont();
2362 Color aForegroundColor
;
2363 Color aBackgroundColor
;
2366 Color aFaceTextColor
;
2367 Color aSelectTextColor
;
2368 ImplGetColors( aFaceColor
, aFaceTextColor
, aSelectColor
, aSelectTextColor
);
2369 if ( mnEditId
!= GetCurPageId() )
2370 aFont
.SetWeight( WEIGHT_LIGHT
);
2371 if ( IsPageSelected( mnEditId
) || (mnEditId
== GetCurPageId()) )
2373 aForegroundColor
= aSelectTextColor
;
2374 aBackgroundColor
= aSelectColor
;
2378 aForegroundColor
= aFaceTextColor
;
2379 aBackgroundColor
= aFaceColor
;
2381 if ( GetPageBits( mnEditId
) & TPB_SPECIAL
)
2382 aForegroundColor
= Color( COL_LIGHTBLUE
);
2383 mpEdit
->SetControlFont( aFont
);
2384 mpEdit
->SetControlForeground( aForegroundColor
);
2385 mpEdit
->SetControlBackground( aBackgroundColor
);
2386 mpEdit
->GrabFocus();
2387 mpEdit
->SetSelection( Selection( 0, mpEdit
->GetText().getLength() ) );
2398 // -----------------------------------------------------------------------
2400 void TabBar::EndEditMode( sal_Bool bCancel
)
2405 sal_Bool bEnd
= sal_True
;
2406 mbEditCanceled
= bCancel
;
2407 maEditText
= mpEdit
->GetText();
2408 mpEdit
->SetPostEvent();
2411 long nAllowRenaming
= AllowRenaming();
2412 if ( nAllowRenaming
== TABBAR_RENAMING_YES
)
2413 SetPageText( mnEditId
, maEditText
);
2414 else if ( nAllowRenaming
== TABBAR_RENAMING_NO
)
2416 else // nAllowRenaming == TABBAR_RENAMING_CANCEL
2417 mbEditCanceled
= sal_True
;
2420 // renaming not allowed, than reset edit data
2423 mpEdit
->ResetPostEvent();
2424 mpEdit
->GrabFocus();
2428 // close edit and call end hdl
2436 maEditText
= OUString();
2437 mbEditCanceled
= false;
2441 // -----------------------------------------------------------------------
2443 void TabBar::SetMirrored(bool bMirrored
)
2445 if( mbMirrored
!= bMirrored
)
2447 mbMirrored
= bMirrored
;
2448 mbSizeFormat
= true;
2449 ImplInitControls(); // for button images
2450 Resize(); // recalculates control positions
2455 void TabBar::SetEffectiveRTL( bool bRTL
)
2457 SetMirrored( bRTL
!= Application::GetSettings().GetLayoutRTL() );
2460 bool TabBar::IsEffectiveRTL() const
2462 return IsMirrored() != Application::GetSettings().GetLayoutRTL();
2465 // -----------------------------------------------------------------------
2467 void TabBar::SetMaxPageWidth( long nMaxWidth
)
2469 if ( mnMaxPageWidth
!= nMaxWidth
)
2471 mnMaxPageWidth
= nMaxWidth
;
2472 mbSizeFormat
= sal_True
;
2474 // Leiste neu ausgeben
2475 if ( IsReallyVisible() && IsUpdateMode() )
2480 // -----------------------------------------------------------------------
2482 void TabBar::SetPageText( sal_uInt16 nPageId
, const OUString
& rText
)
2484 sal_uInt16 nPos
= GetPagePos( nPageId
);
2485 if ( nPos
!= PAGE_NOT_FOUND
)
2487 (*mpItemList
)[ nPos
]->maText
= rText
;
2488 mbSizeFormat
= sal_True
;
2490 // Leiste neu ausgeben
2491 if ( IsReallyVisible() && IsUpdateMode() )
2494 CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(nPageId
)) );
2498 // -----------------------------------------------------------------------
2500 OUString
TabBar::GetPageText( sal_uInt16 nPageId
) const
2502 sal_uInt16 nPos
= GetPagePos( nPageId
);
2503 if ( nPos
!= PAGE_NOT_FOUND
)
2504 return (*mpItemList
)[ nPos
]->maText
;
2508 // -----------------------------------------------------------------------
2510 OUString
TabBar::GetHelpText( sal_uInt16 nPageId
) const
2512 sal_uInt16 nPos
= GetPagePos( nPageId
);
2513 if ( nPos
!= PAGE_NOT_FOUND
)
2515 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2516 if (pItem
->maHelpText
.isEmpty() && !pItem
->maHelpId
.isEmpty())
2518 Help
* pHelp
= Application::GetHelp();
2520 pItem
->maHelpText
= pHelp
->GetHelpText( OStringToOUString( pItem
->maHelpId
, RTL_TEXTENCODING_UTF8
), this );
2523 return pItem
->maHelpText
;
2528 // -----------------------------------------------------------------------
2530 OString
TabBar::GetHelpId( sal_uInt16 nPageId
) const
2532 sal_uInt16 nPos
= GetPagePos( nPageId
);
2534 if ( nPos
!= PAGE_NOT_FOUND
)
2535 return (*mpItemList
)[ nPos
]->maHelpId
;
2539 // -----------------------------------------------------------------------
2541 sal_Bool
TabBar::StartDrag( const CommandEvent
& rCEvt
, Region
& rRegion
)
2543 if ( !(mnWinStyle
& WB_DRAG
) || (rCEvt
.GetCommand() != COMMAND_STARTDRAG
) )
2546 // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
2547 // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
2548 // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
2549 // dies nur bei einer Mausaktion.
2550 // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
2551 // da der Select schon den Bereich gescrollt haben kann
2552 if ( rCEvt
.IsMouseEvent() && !mbInSelect
)
2554 sal_uInt16 nSelId
= GetPageId( rCEvt
.GetMousePosPixel() );
2556 // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
2560 // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
2561 // Seite setzen und Select rufen.
2562 if ( !IsPageSelected( nSelId
) )
2564 if ( ImplDeactivatePage() )
2566 SetCurPageId( nSelId
);
2575 mbInSelect
= sal_False
;
2585 // -----------------------------------------------------------------------
2587 sal_uInt16
TabBar::ShowDropPos( const Point
& rPos
)
2589 ImplTabBarItem
* pItem
;
2591 sal_uInt16 nNewDropPos
;
2592 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
2595 if ( rPos
.X() > mnLastOffX
-TABBAR_DRAG_SCROLLOFF
)
2597 pItem
= (*mpItemList
)[ mpItemList
->size()-1 ];
2598 if ( !pItem
->maRect
.IsEmpty() && (rPos
.X() > pItem
->maRect
.Right()) )
2599 nNewDropPos
= (sal_uInt16
)mpItemList
->size();
2602 nNewDropPos
= mnFirstPos
+1;
2606 else if ( (rPos
.X() <= mnOffX
) ||
2607 (!mnOffX
&& (rPos
.X() <= TABBAR_DRAG_SCROLLOFF
)) )
2611 nNewDropPos
= mnFirstPos
;
2619 nDropId
= GetPageId( rPos
);
2622 nNewDropPos
= GetPagePos( nDropId
);
2623 if ( mnFirstPos
&& (nNewDropPos
== mnFirstPos
-1) )
2627 nNewDropPos
= nItemCount
;
2630 if ( mbDropPos
&& (nNewDropPos
== mnDropPos
) && !nScroll
)
2635 mbDropPos
= sal_True
;
2636 mnDropPos
= nNewDropPos
;
2640 sal_uInt16 nOldFirstPos
= mnFirstPos
;
2641 SetFirstPageId( GetPageId( mnFirstPos
+nScroll
) );
2643 // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
2644 if ( nOldFirstPos
!= mnFirstPos
)
2646 Rectangle
aRect( mnOffX
, 0, mnLastOffX
, maWinSize
.Height() );
2647 SetFillColor( GetBackground().GetColor() );
2653 // Drop-Position-Pfeile ausgeben
2654 Color
aBlackColor( COL_BLACK
);
2656 long nY
= (maWinSize
.Height()/2)-1;
2657 sal_uInt16 nCurPos
= GetPagePos( mnCurPageId
);
2659 SetLineColor( aBlackColor
);
2660 if ( mnDropPos
< nItemCount
)
2662 pItem
= (*mpItemList
)[ mnDropPos
];
2663 nX
= pItem
->maRect
.Left()+TABBAR_OFFSET_X
;
2664 if ( mnDropPos
== nCurPos
)
2668 if ( !pItem
->IsDefaultTabBgColor() && !pItem
->mbSelect
)
2669 SetLineColor( pItem
->maTabTextColor
);
2670 DrawLine( Point( nX
, nY
), Point( nX
, nY
) );
2671 DrawLine( Point( nX
+1, nY
-1 ), Point( nX
+1, nY
+1 ) );
2672 DrawLine( Point( nX
+2, nY
-2 ), Point( nX
+2, nY
+2 ) );
2673 SetLineColor( aBlackColor
);
2675 if ( (mnDropPos
> 0) && (mnDropPos
< nItemCount
+1) )
2677 pItem
= (*mpItemList
)[ mnDropPos
-1 ];
2678 nX
= pItem
->maRect
.Right()-TABBAR_OFFSET_X
;
2679 if ( mnDropPos
== nCurPos
)
2681 if ( !pItem
->IsDefaultTabBgColor() && !pItem
->mbSelect
)
2682 SetLineColor( pItem
->maTabTextColor
);
2683 DrawLine( Point( nX
, nY
), Point( nX
, nY
) );
2684 DrawLine( Point( nX
-1, nY
-1 ), Point( nX
-1, nY
+1 ) );
2685 DrawLine( Point( nX
-2, nY
-2 ), Point( nX
-2, nY
+2 ) );
2691 // -----------------------------------------------------------------------
2693 void TabBar::HideDropPos()
2697 ImplTabBarItem
* pItem
;
2699 long nY1
= (maWinSize
.Height()/2)-3;
2701 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
2703 if ( mnDropPos
< nItemCount
)
2705 pItem
= (*mpItemList
)[ mnDropPos
];
2706 nX
= pItem
->maRect
.Left()+TABBAR_OFFSET_X
;
2707 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2709 Rectangle
aRect( nX
-1, nY1
, nX
+3, nY2
);
2710 Region
aRegion( aRect
);
2711 SetClipRegion( aRegion
);
2715 if ( (mnDropPos
> 0) && (mnDropPos
< nItemCount
+1) )
2717 pItem
= (*mpItemList
)[ mnDropPos
-1 ];
2718 nX
= pItem
->maRect
.Right()-TABBAR_OFFSET_X
;
2719 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2721 Rectangle
aRect( nX
-2, nY1
, nX
+1, nY2
);
2722 Region
aRegion( aRect
);
2723 SetClipRegion( aRegion
);
2728 mbDropPos
= sal_False
;
2733 // -----------------------------------------------------------------------
2735 sal_Bool
TabBar::SwitchPage( const Point
& rPos
)
2737 sal_Bool bSwitch
= sal_False
;
2738 sal_uInt16 nSwitchId
= GetPageId( rPos
);
2743 if ( nSwitchId
!= mnSwitchId
)
2745 mnSwitchId
= nSwitchId
;
2746 mnSwitchTime
= Time::GetSystemTicks();
2750 // Erst nach 500 ms umschalten
2751 if ( mnSwitchId
!= GetCurPageId() )
2753 if ( Time::GetSystemTicks() > mnSwitchTime
+500 )
2755 mbInSwitching
= sal_True
;
2756 if ( ImplDeactivatePage() )
2758 SetCurPageId( mnSwitchId
);
2764 mbInSwitching
= sal_False
;
2773 // -----------------------------------------------------------------------
2775 void TabBar::EndSwitchPage()
2781 // -----------------------------------------------------------------------
2783 void TabBar::SetStyle( WinBits nStyle
)
2785 mnWinStyle
= nStyle
;
2787 // Evt. Controls neu anordnen
2788 if ( IsReallyVisible() && IsUpdateMode() )
2792 // -----------------------------------------------------------------------
2794 Size
TabBar::CalcWindowSizePixel() const
2798 if ( mpItemList
->size() )
2800 ((TabBar
*)this)->ImplCalcWidth();
2801 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
2803 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
2804 nWidth
+= pItem
->mnWidth
;
2806 nWidth
+= TABBAR_OFFSET_X
+TABBAR_OFFSET_X2
;
2809 return Size( nWidth
, GetSettings().GetStyleSettings().GetScrollBarSize() );
2811 // -----------------------------------------------------------------------
2813 Rectangle
TabBar::GetPageArea() const
2815 return Rectangle( Point( mnOffX
, mnOffY
), Size( mnLastOffX
-mnOffX
+1, GetSizePixel().Height()-mnOffY
) );
2818 // -----------------------------------------------------------------------
2820 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> TabBar::CreateAccessible()
2822 return mpImpl
->maAccessibleFactory
.getFactory().createAccessibleTabBar( *this );
2825 // -----------------------------------------------------------------------
2827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */