blob: d892ef1574e4f22144032d49e3225723570911f5 [file] [log] [blame]
/**************************************************************
*
* 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 );
}
// -----------------------------------------------------------------------