64124314a1
Change-Id: Ia274a6438dbb1e3ae94d492df6b9ff86343dd272
2806 lines
80 KiB
C++
2806 lines
80 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
|
|
#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 <vcl/image.hxx>
|
|
#include "svtaccessiblefactory.hxx"
|
|
#include <filectrl.hrc>
|
|
#include <svtools/svtresid.hxx>
|
|
#include <svtools/svtools.hrc>
|
|
#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;
|
|
Color maTabTextColor;
|
|
|
|
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 );
|
|
}
|
|
|
|
bool IsDefaultTabBgColor() const
|
|
{
|
|
return maTabBgColor == Color(COL_AUTO);
|
|
}
|
|
|
|
bool IsDefaultTabTextColor() const
|
|
{
|
|
return maTabTextColor == Color(COL_AUTO);
|
|
}
|
|
|
|
bool IsSelected(ImplTabBarItem* pCurItem) const
|
|
{
|
|
return mbSelect || (pCurItem == this);
|
|
}
|
|
};
|
|
|
|
// =======================================================================
|
|
|
|
// -----------------
|
|
// - 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 )
|
|
, mnStartWidth(0)
|
|
{
|
|
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_NOARG(TabBarEdit, ImplEndTimerHdl)
|
|
{
|
|
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();
|
|
const sal_uInt16 TabBar::INSERT_TAB_POS = ::std::numeric_limits<sal_uInt16>::max() - 1;
|
|
|
|
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(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVET0HOME));
|
|
if(mpPrevBtn)
|
|
mpPrevBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVELEFT));
|
|
if(mpNextBtn)
|
|
mpNextBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVERIGHT));
|
|
if(mpLastBtn)
|
|
mpLastBtn->SetAccessibleName(SVT_RESSTR(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 );
|
|
maCurrentItemList = 0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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;
|
|
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
|
|
delete (*mpItemList)[ i ];
|
|
}
|
|
delete mpItemList;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
ImplTabBarItem* TabBar::seek( size_t i )
|
|
{
|
|
if ( i < mpItemList->size() )
|
|
{
|
|
maCurrentItemList = i;
|
|
return (*mpItemList)[ maCurrentItemList ];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
ImplTabBarItem* TabBar::prev()
|
|
{
|
|
if ( maCurrentItemList > 0 ) {
|
|
return (*mpItemList)[ --maCurrentItemList ];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
ImplTabBarItem* TabBar::next()
|
|
{
|
|
if ( maCurrentItemList+1 < mpItemList->size() ) {
|
|
return (*mpItemList)[ ++maCurrentItemList ];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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;
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
|
|
{
|
|
ImplTabBarItem* pItem = (*mpItemList)[ i ];
|
|
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;
|
|
}
|
|
}
|
|
mbSizeFormat = sal_False;
|
|
mbFormat = sal_True;
|
|
return bChanged;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void TabBar::ImplFormat()
|
|
{
|
|
ImplCalcWidth();
|
|
|
|
if ( !mbFormat )
|
|
return;
|
|
|
|
sal_uInt16 n = 0;
|
|
long x = mnOffX;
|
|
for ( size_t i = 0, nL = mpItemList->size(); i < nL; ++i )
|
|
{
|
|
ImplTabBarItem* pItem = (*mpItemList)[ i ];
|
|
// 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++;
|
|
}
|
|
|
|
mbFormat = sal_False;
|
|
|
|
// Button enablen/disablen
|
|
ImplEnableControls();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_uInt16 TabBar::ImplGetLastFirstPos()
|
|
{
|
|
sal_uInt16 nCount = (sal_uInt16)(mpItemList->size());
|
|
if ( !nCount || mbSizeFormat || mbFormat )
|
|
return 0;
|
|
|
|
sal_uInt16 nLastFirstPos = nCount-1;
|
|
long nWinWidth = mnLastOffX-mnOffX-TABBAR_OFFSET_X-ADDNEWPAGE_AREAWIDTH;
|
|
long nWidth = (*mpItemList)[ nLastFirstPos ]->mnWidth;
|
|
while ( nLastFirstPos && (nWidth < nWinWidth) )
|
|
{
|
|
nLastFirstPos--;
|
|
nWidth += (*mpItemList)[ nLastFirstPos ]->mnWidth;
|
|
}
|
|
if ( (nLastFirstPos != (sal_uInt16)(mpItemList->size()-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 );
|
|
}
|
|
|
|
mbHasInsertTab = (mnWinStyle & WB_INSERTTAB);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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)[ 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)[ 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)[ 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)[ 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->size();
|
|
n = nCurPos;
|
|
while ( n < nCount )
|
|
{
|
|
pItem = (*mpItemList)[ 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)[ 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
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
|
|
{
|
|
pItem = (*mpItemList)[ i ];
|
|
if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
|
|
{
|
|
pItem->mbSelect = sal_False;
|
|
if ( bUpdate )
|
|
Invalidate( pItem->maRect );
|
|
}
|
|
}
|
|
}
|
|
|
|
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 );
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
namespace {
|
|
|
|
class TabBarPaintGuard
|
|
{
|
|
public:
|
|
explicit TabBarPaintGuard(TabBar& rParent) :
|
|
mrParent(rParent),
|
|
maFont(rParent.GetFont())
|
|
{
|
|
// #i36013# exclude push buttons from painting area
|
|
mrParent.SetClipRegion( Region(mrParent.GetPageArea()) );
|
|
}
|
|
|
|
~TabBarPaintGuard()
|
|
{
|
|
// Restore original font.
|
|
mrParent.SetFont(maFont);
|
|
// remove clip region
|
|
mrParent.SetClipRegion();
|
|
}
|
|
private:
|
|
TabBar& mrParent;
|
|
Font maFont;
|
|
};
|
|
|
|
class TabDrawer
|
|
{
|
|
public:
|
|
|
|
explicit TabDrawer(TabBar& rParent) :
|
|
mrParent(rParent),
|
|
mpStyleSettings(&mrParent.GetSettings().GetStyleSettings()),
|
|
maPoly(4),
|
|
mbSelected(false),
|
|
mbCustomColored(false),
|
|
mbSpecialTab(false),
|
|
mbEnabled(false)
|
|
{
|
|
}
|
|
|
|
void drawOutputAreaBorder()
|
|
{
|
|
WinBits nWinStyle = mrParent.GetStyle();
|
|
|
|
// Bei Border oben und unten einen Strich extra malen
|
|
if ( (nWinStyle & WB_BORDER) || (nWinStyle & WB_TOPBORDER) )
|
|
{
|
|
Size aOutputSize = mrParent.GetOutputSizePixel();
|
|
Rectangle aOutRect = mrParent.GetPageArea();
|
|
|
|
// Bei 3D-Tabs wird auch der Border in 3D gemalt
|
|
if ( nWinStyle & WB_3DTAB )
|
|
{
|
|
mrParent.SetLineColor( mpStyleSettings->GetShadowColor() );
|
|
mrParent.DrawLine( Point( aOutRect.Left(), 0 ), Point( aOutputSize.Width(), 0 ) );
|
|
}
|
|
|
|
// Border malen (Strich oben und Strich unten)
|
|
mrParent.SetLineColor( mpStyleSettings->GetDarkShadowColor() );
|
|
mrParent.DrawLine( aOutRect.TopLeft(), Point( aOutputSize.Width()-1, aOutRect.Top() ) );
|
|
}
|
|
}
|
|
|
|
void drawOuterFrame()
|
|
{
|
|
mrParent.DrawPolygon(maPoly);
|
|
}
|
|
|
|
void drawLeftShadow()
|
|
{
|
|
Point p1 = maPoly[0], p2 = maPoly[1];
|
|
p1.X()++;
|
|
p2.X()++;
|
|
p2.Y()--;
|
|
mrParent.DrawLine(p1, p2);
|
|
}
|
|
|
|
void drawRightShadow()
|
|
{
|
|
Point p1 = maPoly[2];
|
|
Point p2 = maPoly[3];
|
|
p1.X()--;
|
|
p2.X()--;
|
|
mrParent.DrawLine(p1, p2);
|
|
}
|
|
|
|
void drawTopInnerShadow()
|
|
{
|
|
Point p1 = maPoly[0], p2 = maPoly[3];
|
|
p1.Y()++;
|
|
p2.Y()++;
|
|
mrParent.DrawLine(p1, p2);
|
|
}
|
|
|
|
void drawBottomShadow(bool bColored)
|
|
{
|
|
Point p1 = maPoly[1], p2 = maPoly[2];
|
|
p1.X() += 1;
|
|
p1.Y() -= 1;
|
|
p2.X() -= 1;
|
|
p2.Y() -= 1;
|
|
mrParent.DrawLine(p1, p2);
|
|
if (bColored)
|
|
{
|
|
p1 += Point(-1, -1);
|
|
p2 += Point(1, -1);
|
|
mrParent.DrawLine(p1, p2);
|
|
}
|
|
}
|
|
|
|
void drawText(const String& aText)
|
|
{
|
|
Rectangle aRect = maRect;
|
|
long nTextWidth = mrParent.GetTextWidth(aText);
|
|
long nTextHeight = mrParent.GetTextHeight();
|
|
Point aPos = aRect.TopLeft();
|
|
aPos.X() += (aRect.getWidth() - nTextWidth) / 2;
|
|
aPos.Y() += (aRect.getHeight() - nTextHeight) / 2;
|
|
|
|
if (mbEnabled)
|
|
mrParent.DrawText(aPos, aText);
|
|
else
|
|
mrParent.DrawCtrlText(
|
|
aPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC));
|
|
}
|
|
|
|
void drawOverTopBorder(bool b3DTab)
|
|
{
|
|
Point p1 = maPoly[0], p2 = maPoly[3];
|
|
p1.X() += 1;
|
|
p2.X() -= 1;
|
|
Rectangle aDelRect(p1, p2);
|
|
mrParent.DrawRect(aDelRect);
|
|
if (b3DTab)
|
|
{
|
|
aDelRect.Top()--;
|
|
mrParent.DrawRect(aDelRect);
|
|
}
|
|
}
|
|
|
|
void drawTab()
|
|
{
|
|
mrParent.SetLineColor(mpStyleSettings->GetDarkShadowColor());
|
|
|
|
// Je nach Status die richtige FillInBrush setzen
|
|
// Set the correct FillInBrush depending upon status
|
|
if ( mbSelected )
|
|
{
|
|
// Currently selected Tab
|
|
mrParent.SetFillColor( maSelectedColor );
|
|
}
|
|
else if ( mbCustomColored )
|
|
{
|
|
mrParent.SetFillColor( maCustomColor );
|
|
}
|
|
else
|
|
{
|
|
mrParent.SetFillColor( maUnselectedColor );
|
|
}
|
|
|
|
drawOuterFrame();
|
|
|
|
// If this is the current tab, draw the left inner shadow the default color,
|
|
// otherwise make it the same as the custom background color
|
|
Color aColor = mpStyleSettings->GetLightColor();
|
|
if (mbCustomColored && !mbSelected)
|
|
aColor = maCustomColor;
|
|
|
|
mrParent.SetLineColor(aColor);
|
|
drawLeftShadow();
|
|
|
|
if ( !mbSelected )
|
|
drawTopInnerShadow();
|
|
|
|
mrParent.SetLineColor( mpStyleSettings->GetShadowColor() );
|
|
drawRightShadow();
|
|
if ( mbCustomColored && mbSelected )
|
|
{
|
|
mrParent.SetLineColor(maCustomColor);
|
|
drawBottomShadow(true);
|
|
}
|
|
else
|
|
drawBottomShadow(false);
|
|
|
|
// Draw the outer frame once more. In some environments, the outer frame
|
|
// gets overpainted.
|
|
mrParent.SetLineColor( mpStyleSettings->GetDarkShadowColor() );
|
|
mrParent.SetFillColor();
|
|
drawOuterFrame();
|
|
}
|
|
|
|
void drawPlusImage()
|
|
{
|
|
SvtResId id( BMP_LIST_ADD );
|
|
Image aPlusImg( id );
|
|
// Center the image within the bounding rectangle.
|
|
Size aSize = aPlusImg.GetSizePixel();
|
|
Point pt = maRect.TopLeft();
|
|
long nXOffSet = (maRect.GetWidth() - aSize.Width()) / 2;
|
|
long nYOffset = (maRect.GetHeight() - aSize.Height()) / 2;
|
|
pt += Point(nXOffSet, nYOffset);
|
|
pt.X() += 1;
|
|
mrParent.DrawImage(pt, aPlusImg);
|
|
}
|
|
|
|
void setRect(const Rectangle& rRect)
|
|
{
|
|
maRect = rRect;
|
|
|
|
long nOffY = mrParent.GetPageArea().getY();
|
|
|
|
// Zuerst geben wir das Polygon gefuellt aus
|
|
maPoly[0] = Point( rRect.Left(), nOffY );
|
|
maPoly[1] = Point( rRect.Left()+TABBAR_OFFSET_X, rRect.Bottom() );
|
|
maPoly[2] = Point( rRect.Right()-TABBAR_OFFSET_X, rRect.Bottom() );
|
|
maPoly[3] = Point( rRect.Right(), nOffY );
|
|
}
|
|
|
|
void setSelected(bool b)
|
|
{
|
|
mbSelected = b;
|
|
}
|
|
|
|
void setCustomColored(bool b)
|
|
{
|
|
mbCustomColored = b;
|
|
}
|
|
|
|
void setSpecialTab(bool b)
|
|
{
|
|
mbSpecialTab = b;
|
|
}
|
|
|
|
void setEnabled(bool b)
|
|
{
|
|
mbEnabled = b;
|
|
}
|
|
|
|
void setSelectedFillColor(const Color& rColor)
|
|
{
|
|
maSelectedColor = rColor;
|
|
}
|
|
|
|
void setUnselectedFillColor(const Color& rColor)
|
|
{
|
|
maUnselectedColor = rColor;
|
|
}
|
|
|
|
void setCustomColor(const Color& rColor)
|
|
{
|
|
maCustomColor = rColor;
|
|
}
|
|
|
|
private:
|
|
TabBar& mrParent;
|
|
const StyleSettings* mpStyleSettings;
|
|
|
|
Rectangle maRect;
|
|
Polygon maPoly;
|
|
|
|
Color maSelectedColor;
|
|
Color maCustomColor;
|
|
Color maUnselectedColor;
|
|
|
|
bool mbSelected:1;
|
|
bool mbCustomColored:1;
|
|
bool mbSpecialTab:1;
|
|
bool mbEnabled:1;
|
|
};
|
|
|
|
}
|
|
|
|
void TabBar::Paint( const Rectangle& rect )
|
|
{
|
|
if(IsNativeControlSupported(CTRL_WINDOW_BACKGROUND,PART_ENTIRE_CONTROL))
|
|
DrawNativeControl(CTRL_WINDOW_BACKGROUND,PART_ENTIRE_CONTROL,rect,
|
|
CTRL_STATE_ENABLED,ImplControlValue(0),rtl::OUString());
|
|
|
|
// Items berechnen und ausgeben
|
|
sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
|
|
if (!nItemCount)
|
|
return;
|
|
|
|
ImplPrePaint();
|
|
|
|
Color aFaceColor, aSelectColor, aFaceTextColor, aSelectTextColor;
|
|
ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
|
|
|
|
// Font selektieren
|
|
Font aFont = GetFont();
|
|
Font aLightFont = aFont;
|
|
aLightFont.SetWeight( WEIGHT_NORMAL );
|
|
|
|
TabBarPaintGuard aGuard(*this);
|
|
TabDrawer aDrawer(*this);
|
|
aDrawer.setSelectedFillColor(aSelectColor);
|
|
aDrawer.setUnselectedFillColor(aFaceColor);
|
|
aDrawer.drawOutputAreaBorder();
|
|
|
|
// Now, start drawing the tabs.
|
|
|
|
ImplTabBarItem* pItem = ImplGetLastTabBarItem(nItemCount);
|
|
|
|
if (pItem && mbHasInsertTab)
|
|
{
|
|
// Draw the insert tab at the right end.
|
|
Rectangle aRect = ImplGetInsertTabRect(pItem);
|
|
aDrawer.setRect(aRect);
|
|
aDrawer.drawTab();
|
|
aDrawer.drawPlusImage();
|
|
}
|
|
|
|
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
|
|
ImplTabBarItem* pCurItem = NULL;
|
|
while ( pItem )
|
|
{
|
|
// CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
|
|
if ( !pCurItem && (pItem->mnId == mnCurPageId) )
|
|
{
|
|
pCurItem = pItem;
|
|
pItem = prev();
|
|
if ( !pItem )
|
|
pItem = pCurItem;
|
|
continue;
|
|
}
|
|
|
|
bool bCurrent = pItem == pCurItem;
|
|
|
|
if ( !pItem->maRect.IsEmpty() )
|
|
{
|
|
Rectangle aRect = pItem->maRect;
|
|
bool bSelected = pItem->IsSelected(pCurItem);
|
|
// We disable custom background color in high contrast mode.
|
|
bool bCustomBgColor = !pItem->IsDefaultTabBgColor() && !rStyleSettings.GetHighContrastMode();
|
|
bool bSpecialTab = (pItem->mnBits & TPB_SPECIAL);
|
|
bool bEnabled = pItem->mbEnable;
|
|
String aText = pItem->mbShort ?
|
|
GetEllipsisString(pItem->maText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS) : pItem->maText;
|
|
|
|
aDrawer.setRect(aRect);
|
|
aDrawer.setSelected(bSelected);
|
|
aDrawer.setCustomColored(bCustomBgColor);
|
|
aDrawer.setSpecialTab(bSpecialTab);
|
|
aDrawer.setEnabled(bEnabled);
|
|
aDrawer.setCustomColor(pItem->maTabBgColor);
|
|
aDrawer.drawTab();
|
|
|
|
// Aktuelle Page wird mit einem fetten Font ausgegeben
|
|
if ( bCurrent )
|
|
SetFont( aFont );
|
|
else
|
|
SetFont( aLightFont );
|
|
|
|
// Je nach Status die richtige FillInBrush setzen
|
|
// Set the correct FillInBrush depending upon status
|
|
if ( bSelected )
|
|
SetTextColor( aSelectTextColor );
|
|
else if ( bCustomBgColor )
|
|
SetTextColor( pItem->maTabTextColor );
|
|
else
|
|
SetTextColor( aFaceTextColor );
|
|
|
|
// This tab is "special", and a special tab needs a blue text.
|
|
if (bSpecialTab)
|
|
SetTextColor(Color(COL_LIGHTBLUE));
|
|
|
|
aDrawer.drawText(aText);
|
|
|
|
if ( bCurrent )
|
|
{
|
|
SetLineColor();
|
|
SetFillColor(aSelectColor);
|
|
aDrawer.drawOverTopBorder(mnWinStyle & WB_3DTAB);
|
|
return;
|
|
}
|
|
|
|
pItem = prev();
|
|
}
|
|
else
|
|
{
|
|
if ( bCurrent )
|
|
return;
|
|
|
|
pItem = NULL;
|
|
}
|
|
|
|
if ( !pItem )
|
|
pItem = pCurItem;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
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.isEmpty() )
|
|
{
|
|
// 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)[ 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)[ 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->empty() )
|
|
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;
|
|
}
|
|
|
|
void TabBar::ImplPrePaint()
|
|
{
|
|
sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
|
|
if (!nItemCount)
|
|
return;
|
|
|
|
ImplTabBarItem* pItem;
|
|
|
|
// 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)[ 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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ImplTabBarItem* TabBar::ImplGetLastTabBarItem( sal_uInt16 nItemCount )
|
|
{
|
|
// letzten sichtbaren Eintrag suchen
|
|
sal_uInt16 n = mnFirstPos+1;
|
|
if ( n >= nItemCount )
|
|
n = nItemCount-1;
|
|
ImplTabBarItem* pItem = seek( n );
|
|
while ( pItem )
|
|
{
|
|
if ( !pItem->maRect.IsEmpty() )
|
|
{
|
|
n++;
|
|
pItem = next();
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
// Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
|
|
if ( pItem )
|
|
n--;
|
|
else if ( n >= nItemCount )
|
|
n = nItemCount-1;
|
|
pItem = seek( n );
|
|
return pItem;
|
|
}
|
|
|
|
Rectangle TabBar::ImplGetInsertTabRect(ImplTabBarItem* pItem) const
|
|
{
|
|
if (mbHasInsertTab && pItem)
|
|
{
|
|
Rectangle aInsTabRect = pItem->maRect;
|
|
aInsTabRect.setX(
|
|
aInsTabRect.getX() + aInsTabRect.getWidth() - TABBAR_OFFSET_X - TABBAR_OFFSET_X2);
|
|
aInsTabRect.setWidth(32);
|
|
return aInsTabRect;
|
|
}
|
|
return Rectangle();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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 );
|
|
if ( nPos < mpItemList->size() ) {
|
|
ImplTabBarList::iterator it = mpItemList->begin();
|
|
::std::advance( it, nPos );
|
|
mpItemList->insert( it, pItem );
|
|
} else {
|
|
mpItemList->push_back( pItem );
|
|
}
|
|
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)[ 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)[ 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
|
|
ImplTabBarList::iterator it = mpItemList->begin();
|
|
::std::advance( it, nPos );
|
|
delete *it;
|
|
mpItemList->erase( it );
|
|
|
|
// 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
|
|
ImplTabBarList::iterator it = mpItemList->begin();
|
|
::std::advance( it, nPos );
|
|
ImplTabBarItem* pItem = *it;
|
|
mpItemList->erase( it );
|
|
if ( nNewPos < mpItemList->size() ) {
|
|
it = mpItemList->begin();
|
|
::std::advance( it, nNewPos );
|
|
mpItemList->insert( it, pItem );
|
|
} else {
|
|
mpItemList->push_back( pItem );
|
|
}
|
|
|
|
// Leiste neu ausgeben
|
|
if ( IsReallyVisible() && IsUpdateMode() )
|
|
Invalidate();
|
|
|
|
CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void TabBar::Clear()
|
|
{
|
|
// Alle Items loeschen
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
|
|
delete (*mpItemList)[ i ];
|
|
}
|
|
mpItemList->clear();
|
|
|
|
// Items aus der Liste loeschen
|
|
mbSizeFormat = sal_True;
|
|
mnCurPageId = 0;
|
|
mnFirstPos = 0;
|
|
maCurrentItemList = 0;
|
|
|
|
// Leiste neu ausgeben
|
|
if ( IsReallyVisible() && IsUpdateMode() )
|
|
Invalidate();
|
|
|
|
CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(PAGE_NOT_FOUND)) );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_Bool TabBar::IsPageEnabled( sal_uInt16 nPageId ) const
|
|
{
|
|
sal_uInt16 nPos = GetPagePos( nPageId );
|
|
|
|
if ( nPos != PAGE_NOT_FOUND )
|
|
return (*mpItemList)[ 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)[ 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)[ nPos ]->mnBits;
|
|
else
|
|
return sal_False;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_uInt16 TabBar::GetPageCount() const
|
|
{
|
|
return (sal_uInt16)mpItemList->size();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_uInt16 TabBar::GetPageId( sal_uInt16 nPos ) const
|
|
{
|
|
return ( nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ]->mnId : 0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_uInt16 TabBar::GetPagePos( sal_uInt16 nPageId ) const
|
|
{
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
|
|
if ( (*mpItemList)[ i ]->mnId == nPageId ) {
|
|
return sal_uInt16( i );
|
|
}
|
|
}
|
|
return PAGE_NOT_FOUND;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_uInt16 TabBar::GetPageId( const Point& rPos, bool bCheckInsTab ) const
|
|
{
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
|
|
{
|
|
ImplTabBarItem* pItem = (*mpItemList)[ i ];
|
|
if ( pItem->maRect.IsInside( rPos ) )
|
|
return pItem->mnId;
|
|
}
|
|
|
|
if (bCheckInsTab && mbHasInsertTab && !mpItemList->empty())
|
|
{
|
|
ImplTabBarItem* pItem = mpItemList->back();
|
|
if (ImplGetInsertTabRect(pItem).IsInside(rPos))
|
|
return INSERT_TAB_POS;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Rectangle TabBar::GetPageRect( sal_uInt16 nPageId ) const
|
|
{
|
|
sal_uInt16 nPos = GetPagePos( nPageId );
|
|
|
|
if ( nPos != PAGE_NOT_FOUND )
|
|
return (*mpItemList)[ 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)[ nPos ];
|
|
ImplTabBarItem* pOldItem;
|
|
|
|
if ( mnCurPageId )
|
|
pOldItem = (*mpItemList)[ 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)[ 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)[ nPos ];
|
|
|
|
if ( pItem->mbSelect != bSelect )
|
|
{
|
|
pItem->mbSelect = bSelect;
|
|
|
|
// Leiste neu ausgeben
|
|
if ( IsReallyVisible() && IsUpdateMode() )
|
|
Invalidate( pItem->maRect );
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_uInt16 TabBar::GetSelectPageCount() const
|
|
{
|
|
sal_uInt16 nSelected = 0;
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
|
|
{
|
|
ImplTabBarItem* pItem = (*mpItemList)[ i ];
|
|
if ( pItem->mbSelect )
|
|
nSelected++;
|
|
}
|
|
|
|
return nSelected;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_Bool TabBar::IsPageSelected( sal_uInt16 nPageId ) const
|
|
{
|
|
sal_uInt16 nPos = GetPagePos( nPageId );
|
|
if ( nPos != PAGE_NOT_FOUND )
|
|
return (*mpItemList)[ 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(bool bMirrored)
|
|
{
|
|
if( mbMirrored != bMirrored )
|
|
{
|
|
mbMirrored = bMirrored;
|
|
mbSizeFormat = true;
|
|
ImplInitControls(); // for button images
|
|
Resize(); // recalculates control positions
|
|
Mirror();
|
|
}
|
|
}
|
|
|
|
void TabBar::SetEffectiveRTL( bool bRTL )
|
|
{
|
|
SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() );
|
|
}
|
|
|
|
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::SetPageText( sal_uInt16 nPageId, const XubString& rText )
|
|
{
|
|
sal_uInt16 nPos = GetPagePos( nPageId );
|
|
if ( nPos != PAGE_NOT_FOUND )
|
|
{
|
|
(*mpItemList)[ 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)[ nPos ]->maText;
|
|
else
|
|
return XubString();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
XubString TabBar::GetHelpText( sal_uInt16 nPageId ) const
|
|
{
|
|
sal_uInt16 nPos = GetPagePos( nPageId );
|
|
if ( nPos != PAGE_NOT_FOUND )
|
|
{
|
|
ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
|
|
if ( !pItem->maHelpText.Len() && !pItem->maHelpId.isEmpty() )
|
|
{
|
|
Help* pHelp = Application::GetHelp();
|
|
if ( pHelp )
|
|
pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
|
|
}
|
|
|
|
return pItem->maHelpText;
|
|
}
|
|
else
|
|
return XubString();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
rtl::OString TabBar::GetHelpId( sal_uInt16 nPageId ) const
|
|
{
|
|
sal_uInt16 nPos = GetPagePos( nPageId );
|
|
rtl::OString aRet;
|
|
if ( nPos != PAGE_NOT_FOUND )
|
|
return (*mpItemList)[ nPos ]->maHelpId;
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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->size();
|
|
short nScroll = 0;
|
|
|
|
if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF )
|
|
{
|
|
pItem = (*mpItemList)[ mpItemList->size()-1 ];
|
|
if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
|
|
nNewDropPos = (sal_uInt16)mpItemList->size();
|
|
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)[ 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)[ 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->size();
|
|
|
|
if ( mnDropPos < nItemCount )
|
|
{
|
|
pItem = (*mpItemList)[ 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)[ 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->size() )
|
|
{
|
|
((TabBar*)this)->ImplCalcWidth();
|
|
for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
|
|
{
|
|
ImplTabBarItem* pItem = (*mpItemList)[ i ];
|
|
nWidth += pItem->mnWidth;
|
|
}
|
|
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 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|