| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svtools.hxx" |
| |
| #include <svtools/tabbar.hxx> |
| #include <tools/time.hxx> |
| #include <tools/debug.hxx> |
| #include <tools/poly.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/help.hxx> |
| #include <vcl/decoview.hxx> |
| #include <vcl/button.hxx> |
| #include <vcl/edit.hxx> |
| #include "svtaccessiblefactory.hxx" |
| #include <filectrl.hrc> |
| #include <svtools/svtdata.hxx> |
| #include <limits> |
| |
| // ======================================================================= |
| |
| #define TABBAR_OFFSET_X 7 |
| #define TABBAR_OFFSET_X2 2 |
| #define TABBAR_DRAG_SCROLLOFF 5 |
| #define TABBAR_MINSIZE 5 |
| |
| const sal_uInt16 ADDNEWPAGE_AREAWIDTH = 10; |
| |
| // ======================================================================= |
| |
| struct ImplTabBarItem |
| { |
| sal_uInt16 mnId; |
| TabBarPageBits mnBits; |
| XubString maText; |
| XubString maHelpText; |
| Rectangle maRect; |
| long mnWidth; |
| rtl::OString maHelpId; |
| sal_Bool mbShort; |
| sal_Bool mbSelect; |
| sal_Bool mbEnable; |
| Color maTabBgColor; |
| bool IsDefaultTabBgColor() const { return maTabBgColor == Color(COL_AUTO) ? sal_True : sal_False; }; |
| Color maTabTextColor; |
| bool IsDefaultTabTextColor() const { return maTabTextColor == Color(COL_AUTO) ? sal_True : sal_False; }; |
| |
| ImplTabBarItem( sal_uInt16 nItemId, const XubString& rText, |
| TabBarPageBits nPageBits ) : |
| maText( rText ) |
| { |
| mnId = nItemId; |
| mnBits = nPageBits; |
| mnWidth = 0; |
| mbShort = sal_False; |
| mbSelect = sal_False; |
| mbEnable = sal_True; |
| maTabBgColor = Color( COL_AUTO ); |
| maTabTextColor = Color( COL_AUTO ); |
| } |
| }; |
| |
| DECLARE_LIST( ImplTabBarList, ImplTabBarItem* ) |
| |
| // ======================================================================= |
| |
| // ----------------- |
| // - ImplTabButton - |
| // ----------------- |
| |
| class ImplTabButton : public PushButton |
| { |
| public: |
| ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) : |
| PushButton( pParent, nWinStyle | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS ) {} |
| |
| TabBar* GetParent() const { return (TabBar*)Window::GetParent(); } |
| |
| virtual long PreNotify( NotifyEvent& rNEvt ); |
| }; |
| |
| // ======================================================================= |
| |
| long ImplTabButton::PreNotify( NotifyEvent& rNEvt ) |
| { |
| if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) |
| { |
| if ( GetParent()->IsInEditMode() ) |
| { |
| GetParent()->EndEditMode(); |
| return sal_True; |
| } |
| } |
| |
| return PushButton::PreNotify( rNEvt ); |
| } |
| |
| // ======================================================================= |
| |
| // ---------------- |
| // - ImplTabSizer - |
| // ---------------- |
| |
| class ImplTabSizer : public Window |
| { |
| public: |
| ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 ); |
| |
| TabBar* GetParent() const { return (TabBar*)Window::GetParent(); } |
| |
| private: |
| void ImplTrack( const Point& rScreenPos ); |
| |
| virtual void MouseButtonDown( const MouseEvent& rMEvt ); |
| virtual void Tracking( const TrackingEvent& rTEvt ); |
| virtual void Paint( const Rectangle& rRect ); |
| |
| Point maStartPos; |
| long mnStartWidth; |
| }; |
| |
| // ----------------------------------------------------------------------- |
| |
| ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle ) : |
| Window( pParent, nWinStyle & WB_3DLOOK ) |
| { |
| SetPointer( Pointer( POINTER_HSIZEBAR ) ); |
| SetSizePixel( Size( 7, 0 ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImplTabSizer::ImplTrack( const Point& rScreenPos ) |
| { |
| TabBar* pParent = GetParent(); |
| long nDiff = rScreenPos.X() - maStartPos.X(); |
| pParent->mnSplitSize = mnStartWidth + (pParent->IsMirrored() ? -nDiff : nDiff); |
| if ( pParent->mnSplitSize < TABBAR_MINSIZE ) |
| pParent->mnSplitSize = TABBAR_MINSIZE; |
| pParent->Split(); |
| pParent->Update(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt ) |
| { |
| if ( GetParent()->IsInEditMode() ) |
| { |
| GetParent()->EndEditMode(); |
| return; |
| } |
| |
| if ( rMEvt.IsLeft() ) |
| { |
| maStartPos = OutputToScreenPixel( rMEvt.GetPosPixel() ); |
| mnStartWidth = GetParent()->GetSizePixel().Width(); |
| StartTracking(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImplTabSizer::Tracking( const TrackingEvent& rTEvt ) |
| { |
| if ( rTEvt.IsTrackingEnded() ) |
| { |
| if ( rTEvt.IsTrackingCanceled() ) |
| ImplTrack( maStartPos ); |
| GetParent()->mnSplitSize = 0; |
| } |
| else |
| ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImplTabSizer::Paint( const Rectangle& ) |
| { |
| const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); |
| DecorationView aDecoView( this ); |
| long nOffX = 0; |
| Size aOutputSize = GetOutputSizePixel(); |
| |
| if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) |
| { |
| SetLineColor( rStyleSettings.GetDarkShadowColor() ); |
| DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) ); |
| nOffX++; |
| aOutputSize.Width()--; |
| } |
| aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER ); |
| } |
| |
| // ======================================================================= |
| |
| // Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar |
| |
| // -------------- |
| // - TabBarEdit - |
| // -------------- |
| |
| class TabBarEdit : public Edit |
| { |
| private: |
| Timer maLoseFocusTimer; |
| sal_Bool mbPostEvt; |
| |
| DECL_LINK( ImplEndEditHdl, void* ); |
| DECL_LINK( ImplEndTimerHdl, void* ); |
| |
| public: |
| TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 ); |
| |
| TabBar* GetParent() const { return (TabBar*)Window::GetParent(); } |
| |
| void SetPostEvent() { mbPostEvt = sal_True; } |
| void ResetPostEvent() { mbPostEvt = sal_False; } |
| |
| virtual long PreNotify( NotifyEvent& rNEvt ); |
| virtual void LoseFocus(); |
| }; |
| |
| // ----------------------------------------------------------------------- |
| |
| TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) : |
| Edit( pParent, nWinStyle ) |
| { |
| mbPostEvt = sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long TabBarEdit::PreNotify( NotifyEvent& rNEvt ) |
| { |
| if ( rNEvt.GetType() == EVENT_KEYINPUT ) |
| { |
| const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); |
| if ( !pKEvt->GetKeyCode().GetModifier() ) |
| { |
| if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN ) |
| { |
| if ( !mbPostEvt ) |
| { |
| if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)sal_False ) ) |
| mbPostEvt = sal_True; |
| } |
| return sal_True; |
| } |
| else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE ) |
| { |
| if ( !mbPostEvt ) |
| { |
| if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)sal_True ) ) |
| mbPostEvt = sal_True; |
| } |
| return sal_True; |
| } |
| } |
| } |
| |
| return Edit::PreNotify( rNEvt ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBarEdit::LoseFocus() |
| { |
| if ( !mbPostEvt ) |
| { |
| if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)sal_False ) ) |
| mbPostEvt = sal_True; |
| } |
| |
| Edit::LoseFocus(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel ) |
| { |
| ResetPostEvent(); |
| maLoseFocusTimer.Stop(); |
| |
| // We need this query, because the edit get a losefous event, |
| // when it shows the context menu or the insert symbol dialog |
| if ( !HasFocus() && HasChildPathFocus( sal_True ) ) |
| { |
| maLoseFocusTimer.SetTimeout( 30 ); |
| maLoseFocusTimer.SetTimeoutHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) ); |
| maLoseFocusTimer.Start(); |
| } |
| else |
| GetParent()->EndEditMode( pCancel != 0 ); |
| |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( TabBarEdit, ImplEndTimerHdl, void*, EMPTYARG ) |
| { |
| if ( HasFocus() ) |
| return 0; |
| |
| // We need this query, because the edit get a losefous event, |
| // when it shows the context menu or the insert symbol dialog |
| if ( HasChildPathFocus( sal_True ) ) |
| maLoseFocusTimer.Start(); |
| else |
| GetParent()->EndEditMode( sal_True ); |
| |
| return 0; |
| } |
| |
| // ======================================================================= |
| struct TabBar_Impl |
| { |
| ImplTabSizer* mpSizer; |
| ::svt::AccessibleFactoryAccess maAccessibleFactory; |
| |
| TabBar_Impl() |
| :mpSizer( NULL ) |
| { |
| } |
| ~TabBar_Impl() |
| { |
| delete mpSizer; |
| } |
| }; |
| |
| // ======================================================================= |
| |
| const sal_uInt16 TabBar::APPEND = ::std::numeric_limits<sal_uInt16>::max(); |
| const sal_uInt16 TabBar::PAGE_NOT_FOUND = ::std::numeric_limits<sal_uInt16>::max(); |
| |
| void TabBar::ImplInit( WinBits nWinStyle ) |
| { |
| mpItemList = new ImplTabBarList; |
| mpFirstBtn = NULL; |
| mpPrevBtn = NULL; |
| mpNextBtn = NULL; |
| mpLastBtn = NULL; |
| mpImpl = new TabBar_Impl; |
| mpEdit = NULL; |
| mnMaxPageWidth = 0; |
| mnCurMaxWidth = 0; |
| mnOffX = 0; |
| mnOffY = 0; |
| mnLastOffX = 0; |
| mnSplitSize = 0; |
| mnSwitchTime = 0; |
| mnWinStyle = nWinStyle; |
| mnCurPageId = 0; |
| mnFirstPos = 0; |
| mnDropPos = 0; |
| mnSwitchId = 0; |
| mnEditId = 0; |
| mbFormat = sal_True; |
| mbFirstFormat = sal_True; |
| mbSizeFormat = sal_True; |
| mbAutoMaxWidth = sal_True; |
| mbInSwitching = sal_False; |
| mbAutoEditMode = sal_False; |
| mbEditCanceled = sal_False; |
| mbDropPos = sal_False; |
| mbInSelect = sal_False; |
| mbSelColor = sal_False; |
| mbSelTextColor = sal_False; |
| mbMirrored = sal_False; |
| |
| if ( nWinStyle & WB_3DTAB ) |
| mnOffY++; |
| |
| ImplInitControls(); |
| |
| if(mpFirstBtn) |
| mpFirstBtn->SetAccessibleName(String(SvtResId(STR_TABBAR_PUSHBUTTON_MOVET0HOME))); |
| if(mpPrevBtn) |
| mpPrevBtn->SetAccessibleName( String(SvtResId(STR_TABBAR_PUSHBUTTON_MOVELEFT))); |
| if(mpNextBtn) |
| mpNextBtn->SetAccessibleName(String(SvtResId(STR_TABBAR_PUSHBUTTON_MOVERIGHT))); |
| if(mpLastBtn) |
| mpLastBtn->SetAccessibleName( String(SvtResId(STR_TABBAR_PUSHBUTTON_MOVETOEND))); |
| |
| SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) ); |
| ImplInitSettings( sal_True, sal_True ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| TabBar::TabBar( Window* pParent, WinBits nWinStyle ) : |
| Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN ) |
| { |
| ImplInit( nWinStyle ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| TabBar::~TabBar() |
| { |
| EndEditMode( sal_True ); |
| |
| // Controls loeschen |
| if ( mpPrevBtn ) |
| delete mpPrevBtn; |
| if ( mpNextBtn ) |
| delete mpNextBtn; |
| if ( mpFirstBtn ) |
| delete mpFirstBtn; |
| if ( mpLastBtn ) |
| delete mpLastBtn; |
| delete mpImpl; |
| |
| // Alle Items loeschen |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| delete pItem; |
| pItem = mpItemList->Next(); |
| } |
| |
| // Itemlist loeschen |
| delete mpItemList; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplInitSettings( sal_Bool bFont, sal_Bool bBackground ) |
| { |
| const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); |
| |
| if ( bFont ) |
| { |
| Font aToolFont; |
| aToolFont = rStyleSettings.GetToolFont(); |
| if ( IsControlFont() ) |
| aToolFont.Merge( GetControlFont() ); |
| aToolFont.SetWeight( WEIGHT_BOLD ); |
| SetZoomedPointFont( aToolFont ); |
| |
| // Font in der groesse Anpassen, wenn Fenster zu klein? |
| while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) ) |
| { |
| Font aFont = GetFont(); |
| if ( aFont.GetHeight() <= 6 ) |
| break; |
| aFont.SetHeight( aFont.GetHeight()-1 ); |
| SetFont( aFont ); |
| } |
| } |
| |
| if ( bBackground ) |
| { |
| Color aColor; |
| if ( IsControlBackground() ) |
| aColor = GetControlBackground(); |
| else |
| aColor = rStyleSettings.GetFaceColor(); |
| SetBackground( aColor ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor, |
| Color& rSelectColor, Color& rSelectTextColor ) |
| { |
| const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); |
| |
| if ( IsControlBackground() ) |
| rFaceColor = GetControlBackground(); |
| else |
| rFaceColor = rStyleSettings.GetInactiveTabColor(); |
| if ( IsControlForeground() ) |
| rFaceTextColor = GetControlForeground(); |
| else |
| rFaceTextColor = rStyleSettings.GetButtonTextColor(); |
| if ( mbSelColor ) |
| rSelectColor = maSelColor; |
| else |
| rSelectColor = rStyleSettings.GetActiveTabColor(); |
| if ( mbSelTextColor ) |
| rSelectTextColor = maSelTextColor; |
| else |
| rSelectTextColor = rStyleSettings.GetWindowTextColor(); |
| |
| // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die |
| // selektierten Tabs in 3D erscheinen sollen |
| if ( mnWinStyle & WB_3DTAB ) |
| { |
| Color aTempColor = rFaceColor; |
| rFaceColor = rSelectColor; |
| rSelectColor = aTempColor; |
| aTempColor = rFaceTextColor; |
| rFaceTextColor = rSelectTextColor; |
| rSelectTextColor = rFaceTextColor; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool TabBar::ImplCalcWidth() |
| { |
| // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder |
| // wenn der Font geaendert wurde |
| if ( !mbSizeFormat ) |
| return sal_False; |
| |
| // Breiten der Tabs mit dem fetten Font ermitteln |
| Font aFont = GetFont(); |
| if ( aFont.GetWeight() != WEIGHT_BOLD ) |
| { |
| aFont.SetWeight( WEIGHT_BOLD ); |
| SetFont( aFont ); |
| } |
| |
| if ( mnMaxPageWidth ) |
| mnCurMaxWidth = mnMaxPageWidth; |
| else if ( mbAutoMaxWidth ) |
| { |
| mnCurMaxWidth = mnLastOffX-mnOffX- |
| TABBAR_OFFSET_X-TABBAR_OFFSET_X- |
| TABBAR_OFFSET_X2-TABBAR_OFFSET_X2-TABBAR_OFFSET_X2; |
| if ( mnCurMaxWidth < 1 ) |
| mnCurMaxWidth = 1; |
| } |
| else |
| mnCurMaxWidth = 0; |
| |
| sal_Bool bChanged = sal_False; |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| long nNewWidth = GetTextWidth( pItem->maText ); |
| if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) ) |
| { |
| pItem->mbShort = sal_True; |
| nNewWidth = mnCurMaxWidth; |
| } |
| else |
| pItem->mbShort = sal_False; |
| nNewWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2; |
| if ( pItem->mnWidth != nNewWidth ) |
| { |
| pItem->mnWidth = nNewWidth; |
| if ( !pItem->maRect.IsEmpty() ) |
| bChanged = sal_True; |
| } |
| pItem = mpItemList->Next(); |
| } |
| mbSizeFormat = sal_False; |
| mbFormat = sal_True; |
| return bChanged; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplFormat() |
| { |
| ImplCalcWidth(); |
| |
| if ( !mbFormat ) |
| return; |
| |
| sal_uInt16 n = 0; |
| long x = mnOffX; |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck |
| // gesetzt |
| if ( (n+1 < mnFirstPos) || (x > mnLastOffX) ) |
| pItem->maRect.SetEmpty(); |
| else |
| { |
| // Etwas von der Tab vor der ersten sichtbaren Page |
| // muss auch zu sehen sein |
| if ( n+1 == mnFirstPos ) |
| pItem->maRect.Left() = x-pItem->mnWidth; |
| else |
| { |
| pItem->maRect.Left() = x; |
| x += pItem->mnWidth; |
| } |
| pItem->maRect.Right() = x+TABBAR_OFFSET_X+TABBAR_OFFSET_X2; |
| pItem->maRect.Bottom() = maWinSize.Height()-1; |
| |
| if( mbMirrored ) |
| { |
| long nTmp = mnOffX + mnLastOffX - pItem->maRect.Right(); |
| pItem->maRect.Right() = mnOffX + mnLastOffX - pItem->maRect.Left(); |
| pItem->maRect.Left() = nTmp; |
| } |
| } |
| |
| n++; |
| pItem = mpItemList->Next(); |
| } |
| |
| mbFormat = sal_False; |
| |
| // Button enablen/disablen |
| ImplEnableControls(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::ImplGetLastFirstPos() |
| { |
| sal_uInt16 nCount = (sal_uInt16)(mpItemList->Count()); |
| if ( !nCount || mbSizeFormat || mbFormat ) |
| return 0; |
| |
| sal_uInt16 nLastFirstPos = nCount-1; |
| long nWinWidth = mnLastOffX-mnOffX-TABBAR_OFFSET_X-ADDNEWPAGE_AREAWIDTH; |
| long nWidth = mpItemList->GetObject( nLastFirstPos )->mnWidth; |
| while ( nLastFirstPos && (nWidth < nWinWidth) ) |
| { |
| nLastFirstPos--; |
| nWidth += mpItemList->GetObject( nLastFirstPos )->mnWidth; |
| } |
| if ( (nLastFirstPos != (sal_uInt16)(mpItemList->Count()-1)) && |
| (nWidth > nWinWidth) ) |
| nLastFirstPos++; |
| return nLastFirstPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplInitControls() |
| { |
| if ( mnWinStyle & WB_SIZEABLE ) |
| { |
| if ( !mpImpl->mpSizer ) |
| mpImpl->mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) ); |
| mpImpl->mpSizer->Show(); |
| } |
| else |
| { |
| DELETEZ( mpImpl->mpSizer ); |
| } |
| |
| Link aLink = LINK( this, TabBar, ImplClickHdl ); |
| |
| if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) ) |
| { |
| if ( !mpPrevBtn ) |
| { |
| mpPrevBtn = new ImplTabButton( this, WB_REPEAT ); |
| mpPrevBtn->SetClickHdl( aLink ); |
| } |
| mpPrevBtn->SetSymbol( mbMirrored ? SYMBOL_NEXT : SYMBOL_PREV ); |
| mpPrevBtn->Show(); |
| |
| if ( !mpNextBtn ) |
| { |
| mpNextBtn = new ImplTabButton( this, WB_REPEAT ); |
| mpNextBtn->SetClickHdl( aLink ); |
| } |
| mpNextBtn->SetSymbol( mbMirrored ? SYMBOL_PREV : SYMBOL_NEXT ); |
| mpNextBtn->Show(); |
| } |
| else |
| { |
| DELETEZ( mpPrevBtn ); |
| DELETEZ( mpNextBtn ); |
| } |
| |
| if ( mnWinStyle & WB_SCROLL ) |
| { |
| if ( !mpFirstBtn ) |
| { |
| mpFirstBtn = new ImplTabButton( this ); |
| mpFirstBtn->SetClickHdl( aLink ); |
| } |
| mpFirstBtn->SetSymbol( mbMirrored ? SYMBOL_LAST : SYMBOL_FIRST ); |
| mpFirstBtn->Show(); |
| |
| if ( !mpLastBtn ) |
| { |
| mpLastBtn = new ImplTabButton( this ); |
| mpLastBtn->SetClickHdl( aLink ); |
| } |
| mpLastBtn->SetSymbol( mbMirrored ? SYMBOL_FIRST : SYMBOL_LAST ); |
| mpLastBtn->Show(); |
| } |
| else |
| { |
| DELETEZ( mpFirstBtn ); |
| DELETEZ( mpLastBtn ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplEnableControls() |
| { |
| if ( mbSizeFormat || mbFormat ) |
| return; |
| |
| // Buttons enablen/disblen |
| sal_Bool bEnableBtn = mnFirstPos > 0; |
| if ( mpFirstBtn ) |
| mpFirstBtn->Enable( bEnableBtn ); |
| if ( mpPrevBtn ) |
| mpPrevBtn->Enable( bEnableBtn ); |
| |
| bEnableBtn = mnFirstPos < ImplGetLastFirstPos(); |
| if ( mpNextBtn ) |
| mpNextBtn->Enable( bEnableBtn ); |
| if ( mpLastBtn ) |
| mpLastBtn->Enable( bEnableBtn ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplShowPage( sal_uInt16 nPos ) |
| { |
| // Breite berechnen |
| long nWidth = GetOutputSizePixel().Width(); |
| if ( nWidth >= TABBAR_OFFSET_X ) |
| nWidth -= TABBAR_OFFSET_X; |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| if ( nPos < mnFirstPos ) |
| SetFirstPageId( pItem->mnId ); |
| else if ( pItem->maRect.Right() > nWidth ) |
| { |
| while ( pItem->maRect.Right() > nWidth ) |
| { |
| sal_uInt16 nNewPos = mnFirstPos+1; |
| SetFirstPageId( GetPageId( nNewPos ) ); |
| ImplFormat(); |
| if ( nNewPos != mnFirstPos ) |
| break; |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn ) |
| { |
| EndEditMode(); |
| |
| sal_uInt16 nNewPos = mnFirstPos; |
| |
| if ( pBtn == mpFirstBtn ) |
| nNewPos = 0; |
| else if ( pBtn == mpPrevBtn ) |
| { |
| if ( mnFirstPos ) |
| nNewPos = mnFirstPos-1; |
| } |
| else if ( pBtn == mpNextBtn ) |
| { |
| sal_uInt16 nCount = GetPageCount(); |
| if ( mnFirstPos < nCount ) |
| nNewPos = mnFirstPos+1; |
| } |
| else |
| { |
| sal_uInt16 nCount = GetPageCount(); |
| if ( nCount ) |
| nNewPos = nCount-1; |
| } |
| |
| if ( nNewPos != mnFirstPos ) |
| SetFirstPageId( GetPageId( nNewPos ) ); |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::MouseMove( const MouseEvent& rMEvt ) |
| { |
| if ( rMEvt.IsLeaveWindow() ) |
| mbInSelect = sal_False; |
| |
| Window::MouseMove( rMEvt ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::MouseButtonDown( const MouseEvent& rMEvt ) |
| { |
| // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht |
| // ausfuehren |
| if ( IsInEditMode() ) |
| { |
| EndEditMode(); |
| return; |
| } |
| |
| ImplTabBarItem* pItem; |
| sal_uInt16 nSelId = GetPageId( rMEvt.GetPosPixel() ); |
| |
| if ( !rMEvt.IsLeft() ) |
| { |
| Window::MouseButtonDown( rMEvt ); |
| if ( (nSelId > 0) && (nSelId != mnCurPageId) ) |
| { |
| sal_uInt16 nPos = GetPagePos( nSelId ); |
| pItem = mpItemList->GetObject( nPos ); |
| |
| if ( pItem->mbEnable ) |
| { |
| if ( ImplDeactivatePage() ) |
| { |
| SetCurPageId( nSelId ); |
| Update(); |
| ImplActivatePage(); |
| ImplSelect(); |
| } |
| mbInSelect = sal_True; |
| } |
| } |
| return; |
| } |
| |
| if ( rMEvt.IsMod2() && mbAutoEditMode && nSelId ) |
| { |
| if ( StartEditMode( nSelId ) ) |
| return; |
| } |
| |
| if ( (rMEvt.GetMode() & (MOUSE_MULTISELECT | MOUSE_RANGESELECT)) && (rMEvt.GetClicks() == 1) ) |
| { |
| if ( nSelId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nSelId ); |
| sal_Bool bSelectTab = sal_False; |
| pItem = mpItemList->GetObject( nPos ); |
| |
| if ( pItem->mbEnable ) |
| { |
| if ( (rMEvt.GetMode() & MOUSE_MULTISELECT) && (mnWinStyle & WB_MULTISELECT) ) |
| { |
| if ( nSelId != mnCurPageId ) |
| { |
| SelectPage( nSelId, !IsPageSelected( nSelId ) ); |
| bSelectTab = sal_True; |
| } |
| } |
| else if ( mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT) ) |
| { |
| bSelectTab = sal_True; |
| sal_uInt16 n; |
| sal_Bool bSelect; |
| sal_uInt16 nCurPos = GetPagePos( mnCurPageId ); |
| if ( nPos <= nCurPos ) |
| { |
| // Alle Tabs bis zur angeklickten Tab deselektieren |
| // und alle Tabs von der angeklickten Tab bis |
| // zur aktuellen Position selektieren |
| n = 0; |
| while ( n < nCurPos ) |
| { |
| pItem = mpItemList->GetObject( n ); |
| if ( n < nPos ) |
| bSelect = sal_False; |
| else |
| bSelect = sal_True; |
| |
| if ( pItem->mbSelect != bSelect ) |
| { |
| pItem->mbSelect = bSelect; |
| if ( !pItem->maRect.IsEmpty() ) |
| Invalidate( pItem->maRect ); |
| } |
| |
| n++; |
| } |
| } |
| |
| if ( nPos >= nCurPos ) |
| { |
| // Alle Tabs von der aktuellen bis zur angeklickten |
| // Tab selektieren und alle Tabs von der angeklickten |
| // Tab bis zur letzten Tab deselektieren |
| sal_uInt16 nCount = (sal_uInt16)mpItemList->Count(); |
| n = nCurPos; |
| while ( n < nCount ) |
| { |
| pItem = mpItemList->GetObject( n ); |
| |
| if ( n <= nPos ) |
| bSelect = sal_True; |
| else |
| bSelect = sal_False; |
| |
| if ( pItem->mbSelect != bSelect ) |
| { |
| pItem->mbSelect = bSelect; |
| if ( !pItem->maRect.IsEmpty() ) |
| Invalidate( pItem->maRect ); |
| } |
| |
| n++; |
| } |
| } |
| } |
| |
| // Gegebenenfalls muss die selektierte Tab gescrollt werden |
| if ( bSelectTab ) |
| { |
| ImplShowPage( nPos ); |
| Update(); |
| ImplSelect(); |
| } |
| } |
| else |
| ImplShowPage( nPos ); |
| mbInSelect = sal_True; |
| |
| return; |
| } |
| } |
| else if ( rMEvt.GetClicks() == 2 ) |
| { |
| // Gegebenenfalls den Double-Click-Handler rufen |
| if ( !rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)) ) |
| { |
| sal_uInt16 nOldCurId = mnCurPageId; |
| mnCurPageId = nSelId; |
| DoubleClick(); |
| // Abfrage, da im DoubleClick-Handler die aktuelle Seite |
| // umgeschaltet werden konnte |
| if ( mnCurPageId == nSelId ) |
| mnCurPageId = nOldCurId; |
| } |
| |
| return; |
| } |
| else |
| { |
| if ( nSelId ) |
| { |
| // Nur Select ausfuehren, wenn noch nicht aktuelle Page |
| if ( nSelId != mnCurPageId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nSelId ); |
| pItem = mpItemList->GetObject( nPos ); |
| |
| if ( pItem->mbEnable ) |
| { |
| if ( !pItem->mbSelect ) |
| { |
| // Muss invalidiert werden |
| sal_Bool bUpdate = sal_False; |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| bUpdate = sal_True; |
| |
| // Alle selektierten Items deselektieren |
| pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) |
| { |
| pItem->mbSelect = sal_False; |
| if ( bUpdate ) |
| Invalidate( pItem->maRect ); |
| } |
| |
| pItem = mpItemList->Next(); |
| } |
| } |
| |
| if ( ImplDeactivatePage() ) |
| { |
| SetCurPageId( nSelId ); |
| Update(); |
| ImplActivatePage(); |
| ImplSelect(); |
| } |
| } |
| else |
| ImplShowPage( nPos ); |
| mbInSelect = sal_True; |
| } |
| |
| return; |
| } |
| } |
| |
| Window::MouseButtonDown( rMEvt ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::MouseButtonUp( const MouseEvent& rMEvt ) |
| { |
| mbInSelect = sal_False; |
| Window::MouseButtonUp( rMEvt ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::Paint( const Rectangle& ) |
| { |
| // Items berechnen und ausgeben |
| sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count(); |
| ImplTabBarItem* pItem; |
| |
| // kein Item, dann auch nichts zu tun |
| if ( nItemCount ) |
| { |
| // TabBar muss formatiert sein |
| ImplFormat(); |
| |
| // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage |
| // sichtbar wird |
| if ( mbFirstFormat ) |
| { |
| mbFirstFormat = sal_False; |
| |
| if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos ) |
| { |
| pItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) ); |
| if ( pItem->maRect.IsEmpty() ) |
| { |
| // mbDropPos setzen (bzw. misbrauchen) um Invalidate() |
| // zu unterbinden |
| mbDropPos = sal_True; |
| SetFirstPageId( mnCurPageId ); |
| mbDropPos = sal_False; |
| if ( mnFirstPos != 0 ) |
| ImplFormat(); |
| } |
| } |
| } |
| } |
| |
| // Farben ermitteln |
| const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); |
| Color aFaceColor; |
| Color aSelectColor; |
| Color aFaceTextColor; |
| Color aSelectTextColor; |
| ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor ); |
| |
| // Font selektieren |
| Font aFont = GetFont(); |
| Font aLightFont = aFont; |
| //aLightFont.SetWeight( WEIGHT_LIGHT ); //TODO Make font weight light on custom color only? |
| aLightFont.SetWeight( WEIGHT_NORMAL ); |
| |
| // #i36013# exclude push buttons from painting area |
| Rectangle aClipRect( Point( mnOffX, 0 ), Point( mnLastOffX, GetOutputHeightPixel() - 1 ) ); |
| SetClipRegion( Region( aClipRect ) ); |
| |
| // Bei Border oben und unten einen Strich extra malen |
| if ( (mnWinStyle & WB_BORDER) || (mnWinStyle & WB_TOPBORDER) ) |
| { |
| Size aOutputSize = GetOutputSizePixel(); |
| |
| // Bei 3D-Tabs wird auch der Border in 3D gemalt |
| if ( mnWinStyle & WB_3DTAB ) |
| { |
| SetLineColor( rStyleSettings.GetShadowColor() ); |
| DrawLine( Point( mnOffX, 0 ), Point( aOutputSize.Width(), 0 ) ); |
| } |
| |
| // Border malen (Strich oben und Strich unten) |
| SetLineColor( rStyleSettings.GetDarkShadowColor() ); |
| DrawLine( Point( mnOffX, mnOffY ), Point( aOutputSize.Width()-1, mnOffY ) ); |
| } |
| else |
| SetLineColor( rStyleSettings.GetDarkShadowColor() ); |
| |
| // Items ausgeben |
| if ( nItemCount ) |
| { |
| // letzten sichtbaren Eintrag suchen |
| sal_uInt16 n = mnFirstPos+1; |
| if ( n >= nItemCount ) |
| n = nItemCount-1; |
| pItem = mpItemList->Seek( n ); |
| while ( pItem ) |
| { |
| if ( !pItem->maRect.IsEmpty() ) |
| { |
| n++; |
| pItem = mpItemList->Next(); |
| } |
| else |
| break; |
| } |
| |
| // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt) |
| if ( pItem ) |
| n--; |
| else if ( n >= nItemCount ) |
| n = nItemCount-1; |
| pItem = mpItemList->Seek( n ); |
| ImplTabBarItem* pCurItem = NULL; |
| while ( pItem ) |
| { |
| // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt |
| if ( !pCurItem && (pItem->mnId == mnCurPageId) ) |
| { |
| pCurItem = pItem; |
| pItem = mpItemList->Prev(); |
| if ( !pItem ) |
| pItem = pCurItem; |
| continue; |
| } |
| |
| if ( !pItem->maRect.IsEmpty() ) |
| { |
| Rectangle aRect = pItem->maRect; |
| |
| // Aktuelle Page wird mit einem fetten Font ausgegeben |
| if ( pItem->mnId == mnCurPageId ) |
| SetFont( aFont ); |
| else |
| SetFont( aLightFont ); |
| |
| // Je nach Status die richtige FillInBrush setzen |
| // Set the correct FillInBrush depending upon status |
| if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) |
| { |
| // Currently selected Tab |
| SetFillColor( aSelectColor ); |
| SetTextColor( aSelectTextColor ); |
| } |
| else |
| { |
| if ( !pItem->IsDefaultTabBgColor() && !rStyleSettings.GetHighContrastMode() ) |
| { |
| SetFillColor( pItem->maTabBgColor ); |
| SetTextColor( pItem->maTabTextColor ); |
| } else { |
| SetFillColor( aFaceColor ); |
| SetTextColor( aFaceTextColor ); |
| } |
| } |
| |
| // Muss Font Kursiv geschaltet werden |
| if ( pItem->mnBits & TPB_SPECIAL ) |
| { |
| SetTextColor( Color( COL_LIGHTBLUE ) ); |
| } |
| |
| // Position der Page berechnen |
| Point aPos0 = Point( aRect.Left(), mnOffY ); |
| Point aPos1 = Point( aRect.Left()+TABBAR_OFFSET_X, aRect.Bottom() ); |
| Point aPos2 = Point( aRect.Right()-TABBAR_OFFSET_X, aRect.Bottom() ); |
| Point aPos3 = Point( aRect.Right(), mnOffY ); |
| |
| // Zuerst geben wir das Polygon gefuellt aus |
| Polygon aPoly( 4 ); |
| aPoly[0] = aPos0; |
| aPoly[1] = aPos1; |
| aPoly[2] = aPos2; |
| aPoly[3] = aPos3; |
| DrawPolygon( aPoly ); |
| |
| // Danach den Text zentiert ausgeben |
| XubString aText = pItem->maText; |
| if ( pItem->mbShort ) |
| aText = GetEllipsisString( aText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS ); |
| Size aRectSize = aRect.GetSize(); |
| long nTextWidth = GetTextWidth( aText ); |
| long nTextHeight = GetTextHeight(); |
| Point aTxtPos( aRect.Left()+(aRectSize.Width()-nTextWidth)/2, |
| (aRectSize.Height()-nTextHeight)/2 ); |
| if ( pItem->IsDefaultTabBgColor() || (!pItem->mbSelect) ) |
| { |
| if ( !pItem->mbEnable ) |
| DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) ); |
| else |
| DrawText( aTxtPos, aText ); |
| } |
| // Jetzt im Inhalt den 3D-Effekt ausgeben |
| aPos0.X()++; |
| aPos1.X()++; |
| aPos2.X()--; |
| aPos3.X()--; |
| |
| // If this is the current tab, draw the left inner shadow the default color, |
| // otherwise make it the same as the custom background color |
| if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) { |
| SetLineColor( rStyleSettings.GetLightColor() ); |
| } else { |
| if ( !pItem->IsDefaultTabBgColor() && ! rStyleSettings.GetHighContrastMode() ) |
| { |
| SetLineColor( pItem->maTabBgColor ); |
| } else { |
| SetLineColor( rStyleSettings.GetLightColor() ); |
| } |
| } |
| // Draw the left side of the tab |
| DrawLine( aPos0, aPos1 ); |
| |
| if ( !pItem->mbSelect && (pItem->mnId != mnCurPageId) ) |
| { |
| // Draw the top inner shadow |
| // ToDo: Change from this static color to tab custom bg color |
| DrawLine( Point( aPos0.X(), aPos0.Y()+1 ), |
| Point( aPos3.X(), aPos3.Y()+1 ) ); |
| } |
| |
| SetLineColor( rStyleSettings.GetShadowColor() ); |
| DrawLine( aPos2, aPos3 ); |
| aPos1.X()--; |
| aPos1.Y()--; |
| aPos2.Y()--; |
| if ( !pItem->IsDefaultTabBgColor() && ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) ) |
| { |
| SetLineColor( pItem->maTabBgColor ); |
| DrawLine( Point(aPos1.X()-1, aPos1.Y()-1), Point(aPos2.X(), aPos2.Y()-1) ); |
| } |
| DrawLine( aPos1, aPos2 ); |
| |
| // draw a small 2px sliver of the original background color at the bottom of the selected tab |
| |
| if ( !pItem->IsDefaultTabBgColor() ) |
| { |
| if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) || rStyleSettings.GetHighContrastMode() ) { |
| SetLineColor( pItem->maTabBgColor ); |
| DrawLine( Point(aPos1.X()-1, aPos1.Y()-1), Point(aPos2.X(), aPos2.Y()-1) ); |
| if ( !pItem->mbEnable ) |
| DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) ); |
| else |
| DrawText( aTxtPos, aText ); |
| } |
| } |
| |
| // Da etwas uebermalt werden konnte, muessen wir die Polygon- |
| // umrandung nocheinmal ausgeben |
| SetLineColor( rStyleSettings.GetDarkShadowColor() ); |
| SetFillColor(); |
| DrawPolygon( aPoly ); |
| |
| // Beim dem aktuellen Tab die restlichten Ausgaben vornehmen und |
| // die Schleife abbrechen, da die aktuelle Tab als letztes |
| // ausgegeben wird |
| if ( pItem == pCurItem ) |
| { |
| // Beim aktuellen Item muss der oberstes Strich geloescht |
| // werden |
| SetLineColor(); |
| SetFillColor( aSelectColor ); |
| Rectangle aDelRect( aPos0, aPos3 ); |
| DrawRect( aDelRect ); |
| if ( mnWinStyle & WB_3DTAB ) |
| { |
| aDelRect.Top()--; |
| DrawRect( aDelRect ); |
| } |
| |
| break; |
| } |
| |
| pItem = mpItemList->Prev(); |
| } |
| else |
| { |
| if ( pItem == pCurItem ) |
| break; |
| |
| pItem = NULL; |
| } |
| |
| if ( !pItem ) |
| pItem = pCurItem; |
| } |
| } |
| |
| // Font wieder herstellen |
| SetFont( aFont ); |
| // remove clip region |
| SetClipRegion(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::Resize() |
| { |
| Size aNewSize = GetOutputSizePixel(); |
| |
| long nSizerWidth = 0; |
| long nButtonWidth = 0; |
| |
| // Sizer anordnen |
| if ( mpImpl->mpSizer ) |
| { |
| Size aSizerSize = mpImpl->mpSizer->GetSizePixel(); |
| Point aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 ); |
| Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() ); |
| mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize ); |
| nSizerWidth = aSizerSize.Width(); |
| } |
| |
| // Scroll-Buttons anordnen |
| long nHeight = aNewSize.Height(); |
| // Font in der groesse Anpassen? |
| ImplInitSettings( sal_True, sal_False ); |
| |
| long nX = mbMirrored ? (aNewSize.Width()-nHeight) : 0; |
| long nXDiff = mbMirrored ? -nHeight : nHeight; |
| |
| Size aBtnSize( nHeight, nHeight ); |
| if ( mpFirstBtn ) |
| { |
| mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize ); |
| nX += nXDiff; |
| nButtonWidth += nHeight; |
| } |
| if ( mpPrevBtn ) |
| { |
| mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize ); |
| nX += nXDiff; |
| nButtonWidth += nHeight; |
| } |
| if ( mpNextBtn ) |
| { |
| mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize ); |
| nX += nXDiff; |
| nButtonWidth += nHeight; |
| } |
| if ( mpLastBtn ) |
| { |
| mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize ); |
| nX += nXDiff; |
| nButtonWidth += nHeight; |
| } |
| |
| // Groesse merken |
| maWinSize = aNewSize; |
| |
| if( mbMirrored ) |
| { |
| mnOffX = nSizerWidth; |
| mnLastOffX = maWinSize.Width() - nButtonWidth - 1; |
| } |
| else |
| { |
| mnOffX = nButtonWidth; |
| mnLastOffX = maWinSize.Width() - nSizerWidth - 1; |
| } |
| |
| // Neu formatieren |
| mbSizeFormat = sal_True; |
| if ( IsReallyVisible() ) |
| { |
| if ( ImplCalcWidth() ) |
| Invalidate(); |
| ImplFormat(); |
| } |
| |
| // Button enablen/disablen |
| ImplEnableControls(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::RequestHelp( const HelpEvent& rHEvt ) |
| { |
| sal_uInt16 nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) ); |
| if ( nItemId ) |
| { |
| if ( rHEvt.GetMode() & HELPMODE_BALLOON ) |
| { |
| XubString aStr = GetHelpText( nItemId ); |
| if ( aStr.Len() ) |
| { |
| Rectangle aItemRect = GetPageRect( nItemId ); |
| Point aPt = OutputToScreenPixel( aItemRect.TopLeft() ); |
| aItemRect.Left() = aPt.X(); |
| aItemRect.Top() = aPt.Y(); |
| aPt = OutputToScreenPixel( aItemRect.BottomRight() ); |
| aItemRect.Right() = aPt.X(); |
| aItemRect.Bottom() = aPt.Y(); |
| Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr ); |
| return; |
| } |
| } |
| else if ( rHEvt.GetMode() & HELPMODE_EXTENDED ) |
| { |
| rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) ); |
| if ( aHelpId.getLength() ) |
| { |
| // Wenn eine Hilfe existiert, dann ausloesen |
| Help* pHelp = Application::GetHelp(); |
| if ( pHelp ) |
| pHelp->Start( aHelpId, this ); |
| return; |
| } |
| } |
| |
| // Bei Quick- oder Ballloon-Help zeigen wir den Text an, |
| // wenn dieser abgeschnitten oder nicht voll sichtbar ist |
| if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) ) |
| { |
| sal_uInt16 nPos = GetPagePos( nItemId ); |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| if ( pItem->mbShort || |
| (pItem->maRect.Right()-TABBAR_OFFSET_X-5 > mnLastOffX) ) |
| { |
| Rectangle aItemRect = GetPageRect( nItemId ); |
| Point aPt = OutputToScreenPixel( aItemRect.TopLeft() ); |
| aItemRect.Left() = aPt.X(); |
| aItemRect.Top() = aPt.Y(); |
| aPt = OutputToScreenPixel( aItemRect.BottomRight() ); |
| aItemRect.Right() = aPt.X(); |
| aItemRect.Bottom() = aPt.Y(); |
| XubString aStr = mpItemList->GetObject( nPos )->maText; |
| if ( aStr.Len() ) |
| { |
| if ( rHEvt.GetMode() & HELPMODE_BALLOON ) |
| Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr ); |
| else |
| Help::ShowQuickHelp( this, aItemRect, aStr ); |
| return; |
| } |
| } |
| } |
| } |
| |
| Window::RequestHelp( rHEvt ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::StateChanged( StateChangedType nType ) |
| { |
| Window::StateChanged( nType ); |
| |
| if ( nType == STATE_CHANGE_INITSHOW ) |
| { |
| if ( (mbSizeFormat || mbFormat) && mpItemList->Count() ) |
| ImplFormat(); |
| } |
| else if ( (nType == STATE_CHANGE_ZOOM) || |
| (nType == STATE_CHANGE_CONTROLFONT) ) |
| { |
| ImplInitSettings( sal_True, sal_False ); |
| Invalidate(); |
| } |
| else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) |
| Invalidate(); |
| else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) |
| { |
| ImplInitSettings( sal_False, sal_True ); |
| Invalidate(); |
| } |
| else if ( nType == STATE_CHANGE_MIRRORING ) |
| { |
| // reacts on calls of EnableRTL, have to mirror all child controls |
| if( mpFirstBtn ) mpFirstBtn->EnableRTL( IsRTLEnabled() ); |
| if( mpPrevBtn ) mpPrevBtn->EnableRTL( IsRTLEnabled() ); |
| if( mpNextBtn ) mpNextBtn->EnableRTL( IsRTLEnabled() ); |
| if( mpLastBtn ) mpLastBtn->EnableRTL( IsRTLEnabled() ); |
| if( mpImpl->mpSizer ) mpImpl->mpSizer->EnableRTL( IsRTLEnabled() ); |
| if( mpEdit ) mpEdit->EnableRTL( IsRTLEnabled() ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::DataChanged( const DataChangedEvent& rDCEvt ) |
| { |
| Window::DataChanged( rDCEvt ); |
| |
| if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || |
| (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || |
| ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && |
| (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) |
| { |
| ImplInitSettings( sal_True, sal_True ); |
| Invalidate(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplSelect() |
| { |
| Select(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::Select() |
| { |
| maSelectHdl.Call( this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::DoubleClick() |
| { |
| maDoubleClickHdl.Call( this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::Split() |
| { |
| maSplitHdl.Call( this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ImplActivatePage() |
| { |
| ActivatePage(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::ActivatePage() |
| { |
| maActivatePageHdl.Call( this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long TabBar::ImplDeactivatePage() |
| { |
| long nRet = DeactivatePage(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) ); |
| |
| return nRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long TabBar::DeactivatePage() |
| { |
| if ( maDeactivatePageHdl.IsSet() ) |
| return maDeactivatePageHdl.Call( this ); |
| else |
| return sal_True; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long TabBar::StartRenaming() |
| { |
| if ( maStartRenamingHdl.IsSet() ) |
| return maStartRenamingHdl.Call( this ); |
| else |
| return sal_True; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long TabBar::AllowRenaming() |
| { |
| if ( maAllowRenamingHdl.IsSet() ) |
| return maAllowRenamingHdl.Call( this ); |
| else |
| return sal_True; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::EndRenaming() |
| { |
| maEndRenamingHdl.Call( this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::Mirror() |
| { |
| |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::InsertPage( sal_uInt16 nPageId, const XubString& rText, |
| TabBarPageBits nBits, sal_uInt16 nPos ) |
| { |
| DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" ); |
| DBG_ASSERT( GetPagePos( nPageId ) == PAGE_NOT_FOUND, |
| "TabBar::InsertPage(): PageId already exists" ); |
| DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" ); |
| |
| // PageItem anlegen und in die Item-Liste eintragen |
| ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits ); |
| mpItemList->Insert( pItem, nPos ); |
| mbSizeFormat = sal_True; |
| |
| // CurPageId gegebenenfalls setzen |
| if ( !mnCurPageId ) |
| mnCurPageId = nPageId; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Color TabBar::GetTabBgColor( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| return mpItemList->GetObject( nPos )->maTabBgColor; |
| else |
| return Color( COL_AUTO ); |
| } |
| |
| void TabBar::SetTabBgColor( sal_uInt16 nPageId, const Color& aTabBgColor ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| ImplTabBarItem* pItem; |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| pItem = mpItemList->GetObject( nPos ); |
| if ( aTabBgColor != Color( COL_AUTO ) ) |
| { |
| pItem->maTabBgColor = aTabBgColor; |
| if ( aTabBgColor.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low... |
| pItem->maTabTextColor = Color( COL_WHITE ); |
| else |
| pItem->maTabTextColor = Color( COL_BLACK ); |
| } |
| else |
| { |
| pItem->maTabBgColor = Color( COL_AUTO ); |
| pItem->maTabTextColor = Color( COL_AUTO ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::RemovePage( sal_uInt16 nPageId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| // Existiert Item |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| if ( mnCurPageId == nPageId ) |
| mnCurPageId = 0; |
| |
| // Testen, ob erste sichtbare Seite verschoben werden muss |
| if ( mnFirstPos > nPos ) |
| mnFirstPos--; |
| |
| // Item-Daten loeschen |
| delete mpItemList->Remove( nPos ); |
| mbFormat = sal_True; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::MovePage( sal_uInt16 nPageId, sal_uInt16 nNewPos ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| Pair aPair( nPos, nNewPos ); |
| |
| if ( nPos < nNewPos ) |
| nNewPos--; |
| |
| if ( nPos == nNewPos ) |
| return; |
| |
| // Existiert Item |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| // TabBar-Item in der Liste verschieben |
| ImplTabBarItem* pItem = mpItemList->Remove( nPos ); |
| mpItemList->Insert( pItem, nNewPos ); |
| mbFormat = sal_True; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::Clear() |
| { |
| // Alle Items loeschen |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| // Item-Daten loeschen |
| delete pItem; |
| pItem = mpItemList->Next(); |
| } |
| |
| // Items aus der Liste loeschen |
| mpItemList->Clear(); |
| mbSizeFormat = sal_True; |
| mnCurPageId = 0; |
| mnFirstPos = 0; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, (void*) PAGE_NOT_FOUND ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::EnablePage( sal_uInt16 nPageId, sal_Bool bEnable ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| |
| if ( pItem->mbEnable != bEnable ) |
| { |
| pItem->mbEnable = bEnable; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate( pItem->maRect ); |
| |
| CallEventListeners( bEnable ? VCLEVENT_TABBAR_PAGEENABLED : VCLEVENT_TABBAR_PAGEDISABLED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool TabBar::IsPageEnabled( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| return mpItemList->GetObject( nPos )->mbEnable; |
| else |
| return sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetPageBits( sal_uInt16 nPageId, TabBarPageBits nBits ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| |
| if ( pItem->mnBits != nBits ) |
| { |
| pItem->mnBits = nBits; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate( pItem->maRect ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| TabBarPageBits TabBar::GetPageBits( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| return mpItemList->GetObject( nPos )->mnBits; |
| else |
| return sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::GetPageCount() const |
| { |
| return (sal_uInt16)mpItemList->Count(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::GetPageId( sal_uInt16 nPos ) const |
| { |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| if ( pItem ) |
| return pItem->mnId; |
| else |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::GetPagePos( sal_uInt16 nPageId ) const |
| { |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| if ( pItem->mnId == nPageId ) |
| return (sal_uInt16)mpItemList->GetCurPos(); |
| |
| pItem = mpItemList->Next(); |
| } |
| |
| return PAGE_NOT_FOUND; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::GetPageId( const Point& rPos ) const |
| { |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| if ( pItem->maRect.IsInside( rPos ) ) |
| return pItem->mnId; |
| |
| pItem = mpItemList->Next(); |
| } |
| |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Rectangle TabBar::GetPageRect( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| return mpItemList->GetObject( nPos )->maRect; |
| else |
| return Rectangle(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetCurPageId( sal_uInt16 nPageId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| // Wenn Item nicht existiert, dann nichts machen |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir |
| // jetzt nichts mehr machen |
| if ( nPageId == mnCurPageId ) |
| return; |
| |
| // Muss invalidiert werden |
| sal_Bool bUpdate = sal_False; |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| bUpdate = sal_True; |
| |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| ImplTabBarItem* pOldItem; |
| |
| if ( mnCurPageId ) |
| pOldItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) ); |
| else |
| pOldItem = NULL; |
| |
| // Wenn Page nicht selektiert, dann vorher selektierte Seite |
| // deselktieren, wenn dies die einzige selektierte Seite ist |
| if ( !pItem->mbSelect && pOldItem ) |
| { |
| sal_uInt16 nSelPageCount = GetSelectPageCount(); |
| if ( nSelPageCount == 1 ) |
| pOldItem->mbSelect = sal_False; |
| pItem->mbSelect = sal_True; |
| } |
| |
| mnCurPageId = nPageId; |
| mbFormat = sal_True; |
| |
| // Dafuer sorgen, das aktuelle Page sichtbar wird |
| if ( IsReallyVisible() ) |
| { |
| if ( nPos < mnFirstPos ) |
| SetFirstPageId( nPageId ); |
| else |
| { |
| // sichtbare Breite berechnen |
| long nWidth = mnLastOffX; |
| if ( nWidth > TABBAR_OFFSET_X ) |
| nWidth -= TABBAR_OFFSET_X; |
| if ( nWidth > ADDNEWPAGE_AREAWIDTH ) |
| nWidth -= ADDNEWPAGE_AREAWIDTH; |
| |
| if ( pItem->maRect.IsEmpty() ) |
| ImplFormat(); |
| |
| while ( (mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) || |
| pItem->maRect.IsEmpty() ) |
| { |
| sal_uInt16 nNewPos = mnFirstPos+1; |
| // Dafuer sorgen, das min. die aktuelle TabPages als |
| // erste TabPage sichtbar ist |
| if ( nNewPos >= nPos ) |
| { |
| SetFirstPageId( nPageId ); |
| break; |
| } |
| else |
| SetFirstPageId( GetPageId( nNewPos ) ); |
| ImplFormat(); |
| // Falls erste Seite nicht weitergeschaltet wird, dann |
| // koennen wir abbrechen |
| if ( nNewPos != mnFirstPos ) |
| break; |
| } |
| } |
| } |
| |
| // Leiste neu ausgeben |
| if ( bUpdate ) |
| { |
| Invalidate( pItem->maRect ); |
| if ( pOldItem ) |
| Invalidate( pOldItem->maRect ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::MakeVisible( sal_uInt16 nPageId ) |
| { |
| if ( !IsReallyVisible() ) |
| return; |
| |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| // Wenn Item nicht existiert, dann nichts machen |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| if ( nPos < mnFirstPos ) |
| SetFirstPageId( nPageId ); |
| else |
| { |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| |
| // sichtbare Breite berechnen |
| long nWidth = mnLastOffX; |
| if ( nWidth > TABBAR_OFFSET_X ) |
| nWidth -= TABBAR_OFFSET_X; |
| |
| if ( mbFormat || pItem->maRect.IsEmpty() ) |
| { |
| mbFormat = sal_True; |
| ImplFormat(); |
| } |
| |
| while ( (pItem->maRect.Right() > nWidth) || |
| pItem->maRect.IsEmpty() ) |
| { |
| sal_uInt16 nNewPos = mnFirstPos+1; |
| // Dafuer sorgen, das min. die aktuelle TabPages als |
| // erste TabPage sichtbar ist |
| if ( nNewPos >= nPos ) |
| { |
| SetFirstPageId( nPageId ); |
| break; |
| } |
| else |
| SetFirstPageId( GetPageId( nNewPos ) ); |
| ImplFormat(); |
| // Falls erste Seite nicht weitergeschaltet wird, dann |
| // koennen wir abbrechen |
| if ( nNewPos != mnFirstPos ) |
| break; |
| } |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetFirstPageId( sal_uInt16 nPageId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| // Wenn Item nicht existiert, dann sal_False zurueckgeben |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| if ( nPos != mnFirstPos ) |
| { |
| // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie |
| // moeglich sichtbar sind |
| ImplFormat(); |
| sal_uInt16 nLastFirstPos = ImplGetLastFirstPos(); |
| sal_uInt16 nNewPos; |
| if ( nPos > nLastFirstPos ) |
| nNewPos = nLastFirstPos; |
| else |
| nNewPos = nPos; |
| |
| if ( nNewPos != mnFirstPos ) |
| { |
| mnFirstPos = nNewPos; |
| mbFormat = sal_True; |
| |
| // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn |
| // dieses Flag gesetzt ist, wird direkt gepaintet) |
| if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos ) |
| Invalidate(); |
| } |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SelectPage( sal_uInt16 nPageId, sal_Bool bSelect ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| |
| if ( pItem->mbSelect != bSelect ) |
| { |
| pItem->mbSelect = bSelect; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate( pItem->maRect ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SelectPageRange( sal_Bool bSelect, sal_uInt16 nStartPos, sal_uInt16 nEndPos ) |
| { |
| Rectangle aPaintRect; |
| sal_uInt16 nPos = nStartPos; |
| ImplTabBarItem* pItem = mpItemList->Seek( nPos ); |
| while ( pItem && (nPos <= nEndPos) ) |
| { |
| if ( (pItem->mbSelect != bSelect) && (pItem->mnId != mnCurPageId) ) |
| { |
| pItem->mbSelect = bSelect; |
| aPaintRect.Union( pItem->maRect ); |
| } |
| |
| nPos++; |
| pItem = mpItemList->Next(); |
| } |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() && !aPaintRect.IsEmpty() ) |
| Invalidate( aPaintRect ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::GetSelectPage( sal_uInt16 nSelIndex ) const |
| { |
| sal_uInt16 nSelected = 0; |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| if ( pItem->mbSelect ) |
| nSelected++; |
| |
| if ( nSelected == nSelIndex ) |
| return pItem->mnId; |
| |
| pItem = mpItemList->Next(); |
| } |
| |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::GetSelectPageCount() const |
| { |
| sal_uInt16 nSelected = 0; |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| if ( pItem->mbSelect ) |
| nSelected++; |
| |
| pItem = mpItemList->Next(); |
| } |
| |
| return nSelected; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool TabBar::IsPageSelected( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( nPos != PAGE_NOT_FOUND ) |
| return mpItemList->GetObject( nPos )->mbSelect; |
| else |
| return sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool TabBar::StartEditMode( sal_uInt16 nPageId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( mpEdit || (nPos == PAGE_NOT_FOUND) || (mnLastOffX < 8) ) |
| return sal_False; |
| |
| mnEditId = nPageId; |
| if ( StartRenaming() ) |
| { |
| ImplShowPage( nPos ); |
| ImplFormat(); |
| Update(); |
| |
| mpEdit = new TabBarEdit( this, WB_CENTER ); |
| Rectangle aRect = GetPageRect( mnEditId ); |
| long nX = aRect.Left()+TABBAR_OFFSET_X+(TABBAR_OFFSET_X2/2); |
| long nWidth = aRect.GetWidth()-(TABBAR_OFFSET_X*2)-TABBAR_OFFSET_X2; |
| if ( mnEditId != GetCurPageId() ) |
| nX += 1; |
| if ( nX+nWidth > mnLastOffX ) |
| nWidth = mnLastOffX-nX; |
| if ( nWidth < 3 ) |
| { |
| nX = aRect.Left(); |
| nWidth = aRect.GetWidth(); |
| } |
| mpEdit->SetText( GetPageText( mnEditId ) ); |
| mpEdit->SetPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 ); |
| Font aFont = GetPointFont(); |
| Color aForegroundColor; |
| Color aBackgroundColor; |
| Color aFaceColor; |
| Color aSelectColor; |
| Color aFaceTextColor; |
| Color aSelectTextColor; |
| ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor ); |
| if ( mnEditId != GetCurPageId() ) |
| aFont.SetWeight( WEIGHT_LIGHT ); |
| if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) ) |
| { |
| aForegroundColor = aSelectTextColor; |
| aBackgroundColor = aSelectColor; |
| } |
| else |
| { |
| aForegroundColor = aFaceTextColor; |
| aBackgroundColor = aFaceColor; |
| } |
| if ( GetPageBits( mnEditId ) & TPB_SPECIAL ) |
| aForegroundColor = Color( COL_LIGHTBLUE ); |
| mpEdit->SetControlFont( aFont ); |
| mpEdit->SetControlForeground( aForegroundColor ); |
| mpEdit->SetControlBackground( aBackgroundColor ); |
| mpEdit->GrabFocus(); |
| mpEdit->SetSelection( Selection( 0, mpEdit->GetText().Len() ) ); |
| mpEdit->Show(); |
| return sal_True; |
| } |
| else |
| { |
| mnEditId = 0; |
| return sal_False; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::EndEditMode( sal_Bool bCancel ) |
| { |
| if ( mpEdit ) |
| { |
| // call hdl |
| sal_Bool bEnd = sal_True; |
| mbEditCanceled = bCancel; |
| maEditText = mpEdit->GetText(); |
| mpEdit->SetPostEvent(); |
| if ( !bCancel ) |
| { |
| long nAllowRenaming = AllowRenaming(); |
| if ( nAllowRenaming == TABBAR_RENAMING_YES ) |
| SetPageText( mnEditId, maEditText ); |
| else if ( nAllowRenaming == TABBAR_RENAMING_NO ) |
| bEnd = sal_False; |
| else // nAllowRenaming == TABBAR_RENAMING_CANCEL |
| mbEditCanceled = sal_True; |
| } |
| |
| // renaming not allowed, than reset edit data |
| if ( !bEnd ) |
| { |
| mpEdit->ResetPostEvent(); |
| mpEdit->GrabFocus(); |
| } |
| else |
| { |
| // close edit and call end hdl |
| delete mpEdit; |
| mpEdit = NULL; |
| EndRenaming(); |
| mnEditId = 0; |
| } |
| |
| // reset |
| maEditText.Erase(); |
| mbEditCanceled = sal_False; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetMirrored( sal_Bool bMirrored ) |
| { |
| if( mbMirrored != bMirrored ) |
| { |
| mbMirrored = bMirrored; |
| mbSizeFormat = sal_True; |
| ImplInitControls(); // for button images |
| Resize(); // recalculates control positions |
| Mirror(); |
| } |
| } |
| |
| void TabBar::SetEffectiveRTL( sal_Bool bRTL ) |
| { |
| SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() ); |
| } |
| |
| sal_Bool TabBar::IsEffectiveRTL() const |
| { |
| return IsMirrored() != Application::GetSettings().GetLayoutRTL(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetMaxPageWidth( long nMaxWidth ) |
| { |
| if ( mnMaxPageWidth != nMaxWidth ) |
| { |
| mnMaxPageWidth = nMaxWidth; |
| mbSizeFormat = sal_True; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetSelectColor() |
| { |
| if ( mbSelColor ) |
| { |
| maSelColor = Color( COL_TRANSPARENT ); |
| mbSelColor = sal_False; |
| Invalidate(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetSelectColor( const Color& rColor ) |
| { |
| if ( rColor.GetTransparency() ) |
| { |
| if ( mbSelColor ) |
| { |
| maSelColor = Color( COL_TRANSPARENT ); |
| mbSelColor = sal_False; |
| Invalidate(); |
| } |
| } |
| else |
| { |
| if ( maSelColor != rColor ) |
| { |
| maSelColor = rColor; |
| mbSelColor = sal_True; |
| Invalidate(); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetSelectTextColor() |
| { |
| if ( mbSelTextColor ) |
| { |
| maSelTextColor = Color( COL_TRANSPARENT ); |
| mbSelTextColor = sal_False; |
| Invalidate(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetSelectTextColor( const Color& rColor ) |
| { |
| if ( rColor.GetTransparency() ) |
| { |
| if ( mbSelTextColor ) |
| { |
| maSelTextColor = Color( COL_TRANSPARENT ); |
| mbSelTextColor = sal_False; |
| Invalidate(); |
| } |
| } |
| else |
| { |
| if ( maSelTextColor != rColor ) |
| { |
| maSelTextColor = rColor; |
| mbSelTextColor = sal_True; |
| Invalidate(); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetPageText( sal_uInt16 nPageId, const XubString& rText ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| mpItemList->GetObject( nPos )->maText = rText; |
| mbSizeFormat = sal_True; |
| |
| // Leiste neu ausgeben |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Invalidate(); |
| |
| CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| XubString TabBar::GetPageText( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( nPos != PAGE_NOT_FOUND ) |
| return mpItemList->GetObject( nPos )->maText; |
| else |
| return XubString(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetHelpText( sal_uInt16 nPageId, const XubString& rText ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( nPos != PAGE_NOT_FOUND ) |
| mpItemList->GetObject( nPos )->maHelpText = rText; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| XubString TabBar::GetHelpText( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( nPos != PAGE_NOT_FOUND ) |
| { |
| ImplTabBarItem* pItem = mpItemList->GetObject( nPos ); |
| if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() ) |
| { |
| Help* pHelp = Application::GetHelp(); |
| if ( pHelp ) |
| pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this ); |
| } |
| |
| return pItem->maHelpText; |
| } |
| else |
| return XubString(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetHelpId( sal_uInt16 nPageId, const rtl::OString& rHelpId ) |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| if ( nPos != PAGE_NOT_FOUND ) |
| mpItemList->GetObject( nPos )->maHelpId = rHelpId; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| rtl::OString TabBar::GetHelpId( sal_uInt16 nPageId ) const |
| { |
| sal_uInt16 nPos = GetPagePos( nPageId ); |
| rtl::OString aRet; |
| if ( nPos != PAGE_NOT_FOUND ) |
| aRet = mpItemList->GetObject( nPos )->maHelpId; |
| return aRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long TabBar::GetMinSize() const |
| { |
| long nMinSize = TABBAR_MINSIZE + TABBAR_OFFSET_X; |
| if ( mnWinStyle & WB_MINSCROLL ) |
| nMinSize += mpPrevBtn->GetSizePixel().Width()*2; |
| else if ( mnWinStyle & WB_SCROLL ) |
| nMinSize += mpFirstBtn->GetSizePixel().Width()*4; |
| return nMinSize; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool TabBar::StartDrag( const CommandEvent& rCEvt, Region& rRegion ) |
| { |
| if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) ) |
| return sal_False; |
| |
| // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht |
| // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and |
| // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir |
| // dies nur bei einer Mausaktion. |
| // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde, |
| // da der Select schon den Bereich gescrollt haben kann |
| if ( rCEvt.IsMouseEvent() && !mbInSelect ) |
| { |
| sal_uInt16 nSelId = GetPageId( rCEvt.GetMousePosPixel() ); |
| |
| // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging |
| if ( !nSelId ) |
| return sal_False; |
| |
| // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle |
| // Seite setzen und Select rufen. |
| if ( !IsPageSelected( nSelId ) ) |
| { |
| if ( ImplDeactivatePage() ) |
| { |
| SetCurPageId( nSelId ); |
| Update(); |
| ImplActivatePage(); |
| ImplSelect(); |
| } |
| else |
| return sal_False; |
| } |
| } |
| mbInSelect = sal_False; |
| |
| Region aRegion; |
| |
| // Region zuweisen |
| rRegion = aRegion; |
| |
| return sal_True; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 TabBar::ShowDropPos( const Point& rPos ) |
| { |
| ImplTabBarItem* pItem; |
| sal_uInt16 nDropId; |
| sal_uInt16 nNewDropPos; |
| sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count(); |
| short nScroll = 0; |
| |
| if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF ) |
| { |
| pItem = mpItemList->GetObject( mpItemList->Count()-1 ); |
| if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) ) |
| nNewDropPos = (sal_uInt16)mpItemList->Count(); |
| else |
| { |
| nNewDropPos = mnFirstPos+1; |
| nScroll = 1; |
| } |
| } |
| else if ( (rPos.X() <= mnOffX) || |
| (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) ) |
| { |
| if ( mnFirstPos ) |
| { |
| nNewDropPos = mnFirstPos; |
| nScroll = -1; |
| } |
| else |
| nNewDropPos = 0; |
| } |
| else |
| { |
| nDropId = GetPageId( rPos ); |
| if ( nDropId ) |
| { |
| nNewDropPos = GetPagePos( nDropId ); |
| if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) ) |
| nScroll = -1; |
| } |
| else |
| nNewDropPos = nItemCount; |
| } |
| |
| if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll ) |
| return mnDropPos; |
| |
| if ( mbDropPos ) |
| HideDropPos(); |
| mbDropPos = sal_True; |
| mnDropPos = nNewDropPos; |
| |
| if ( nScroll ) |
| { |
| sal_uInt16 nOldFirstPos = mnFirstPos; |
| SetFirstPageId( GetPageId( mnFirstPos+nScroll ) ); |
| |
| // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich |
| if ( nOldFirstPos != mnFirstPos ) |
| { |
| Rectangle aRect( mnOffX, 0, mnLastOffX, maWinSize.Height() ); |
| SetFillColor( GetBackground().GetColor() ); |
| DrawRect( aRect ); |
| Paint( aRect ); |
| } |
| } |
| |
| // Drop-Position-Pfeile ausgeben |
| Color aBlackColor( COL_BLACK ); |
| long nX; |
| long nY = (maWinSize.Height()/2)-1; |
| sal_uInt16 nCurPos = GetPagePos( mnCurPageId ); |
| |
| SetLineColor( aBlackColor ); |
| if ( mnDropPos < nItemCount ) |
| { |
| pItem = mpItemList->GetObject( mnDropPos ); |
| nX = pItem->maRect.Left()+TABBAR_OFFSET_X; |
| if ( mnDropPos == nCurPos ) |
| nX--; |
| else |
| nX++; |
| if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect) |
| SetLineColor( pItem->maTabTextColor ); |
| DrawLine( Point( nX, nY ), Point( nX, nY ) ); |
| DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) ); |
| DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) ); |
| SetLineColor( aBlackColor ); |
| } |
| if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) ) |
| { |
| pItem = mpItemList->GetObject( mnDropPos-1 ); |
| nX = pItem->maRect.Right()-TABBAR_OFFSET_X; |
| if ( mnDropPos == nCurPos ) |
| nX++; |
| if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect) |
| SetLineColor( pItem->maTabTextColor ); |
| DrawLine( Point( nX, nY ), Point( nX, nY ) ); |
| DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) ); |
| DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) ); |
| } |
| |
| return mnDropPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::HideDropPos() |
| { |
| if ( mbDropPos ) |
| { |
| ImplTabBarItem* pItem; |
| long nX; |
| long nY1 = (maWinSize.Height()/2)-3; |
| long nY2 = nY1 + 5; |
| sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count(); |
| |
| if ( mnDropPos < nItemCount ) |
| { |
| pItem = mpItemList->GetObject( mnDropPos ); |
| nX = pItem->maRect.Left()+TABBAR_OFFSET_X; |
| // Paint direkt aufrufen, da bei Drag and Drop kein Paint |
| // moeglich |
| Rectangle aRect( nX-1, nY1, nX+3, nY2 ); |
| Region aRegion( aRect ); |
| SetClipRegion( aRegion ); |
| Paint( aRect ); |
| SetClipRegion(); |
| } |
| if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) ) |
| { |
| pItem = mpItemList->GetObject( mnDropPos-1 ); |
| nX = pItem->maRect.Right()-TABBAR_OFFSET_X; |
| // Paint direkt aufrufen, da bei Drag and Drop kein Paint |
| // moeglich |
| Rectangle aRect( nX-2, nY1, nX+1, nY2 ); |
| Region aRegion( aRect ); |
| SetClipRegion( aRegion ); |
| Paint( aRect ); |
| SetClipRegion(); |
| } |
| |
| mbDropPos = sal_False; |
| mnDropPos = 0; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool TabBar::SwitchPage( const Point& rPos ) |
| { |
| sal_Bool bSwitch = sal_False; |
| sal_uInt16 nSwitchId = GetPageId( rPos ); |
| if ( !nSwitchId ) |
| EndSwitchPage(); |
| else |
| { |
| if ( nSwitchId != mnSwitchId ) |
| { |
| mnSwitchId = nSwitchId; |
| mnSwitchTime = Time::GetSystemTicks(); |
| } |
| else |
| { |
| // Erst nach 500 ms umschalten |
| if ( mnSwitchId != GetCurPageId() ) |
| { |
| if ( Time::GetSystemTicks() > mnSwitchTime+500 ) |
| { |
| mbInSwitching = sal_True; |
| if ( ImplDeactivatePage() ) |
| { |
| SetCurPageId( mnSwitchId ); |
| Update(); |
| ImplActivatePage(); |
| ImplSelect(); |
| bSwitch = sal_True; |
| } |
| mbInSwitching = sal_False; |
| } |
| } |
| } |
| } |
| |
| return bSwitch; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::EndSwitchPage() |
| { |
| mnSwitchTime = 0; |
| mnSwitchId = 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void TabBar::SetStyle( WinBits nStyle ) |
| { |
| mnWinStyle = nStyle; |
| ImplInitControls(); |
| // Evt. Controls neu anordnen |
| if ( IsReallyVisible() && IsUpdateMode() ) |
| Resize(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Size TabBar::CalcWindowSizePixel() const |
| { |
| long nWidth = 0; |
| |
| if ( mpItemList->Count() ) |
| { |
| ((TabBar*)this)->ImplCalcWidth(); |
| ImplTabBarItem* pItem = mpItemList->First(); |
| while ( pItem ) |
| { |
| nWidth += pItem->mnWidth; |
| pItem = mpItemList->Next(); |
| } |
| nWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2; |
| } |
| |
| return Size( nWidth, GetSettings().GetStyleSettings().GetScrollBarSize() ); |
| } |
| // ----------------------------------------------------------------------- |
| |
| Rectangle TabBar::GetPageArea() const |
| { |
| return Rectangle( Point( mnOffX, mnOffY ), Size( mnLastOffX-mnOffX+1, GetSizePixel().Height()-mnOffY ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabBar::CreateAccessible() |
| { |
| return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar( *this ); |
| } |
| |
| // ----------------------------------------------------------------------- |