00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <qapplication.h>
00022
#include <qpainter.h>
00023
#include <qstyle.h>
00024
#include <qtimer.h>
00025
#include <qpushbutton.h>
00026
#include <qtooltip.h>
00027
00028
#include <kglobalsettings.h>
00029
#include <kiconloader.h>
00030
#include <klocale.h>
00031
00032
#include "ktabbar.h"
00033
#include "ktabwidget.h"
00034
00035 KTabBar::KTabBar(
QWidget *parent,
const char *name )
00036 :
QTabBar( parent,
name ), mReorderStartTab( -1 ), mReorderPreviousTab( -1 ),
00037 mHoverCloseButtonTab( 0 ), mDragSwitchTab( 0 ), mHoverCloseButton( 0 ),
00038 mHoverCloseButtonEnabled( false ), mHoverCloseButtonDelayed( true ),
00039 mTabReorderingEnabled( false )
00040 {
00041 setAcceptDrops(
true );
00042 setMouseTracking(
true );
00043
00044 mEnableCloseButtonTimer =
new QTimer(
this );
00045 connect( mEnableCloseButtonTimer, SIGNAL( timeout() ), SLOT( enableCloseButton() ) );
00046
00047 mActivateDragSwitchTabTimer =
new QTimer(
this );
00048 connect( mActivateDragSwitchTabTimer, SIGNAL( timeout() ), SLOT( activateDragSwitchTab() ) );
00049
00050
#if QT_VERSION >= 0x030200
00051
connect(
this, SIGNAL(layoutChanged()), SLOT(onLayoutChange()));
00052
#endif
00053
}
00054
00055 KTabBar::~KTabBar()
00056 {
00057
00058
00059 }
00060
00061
void KTabBar::setTabEnabled(
int id,
bool enabled )
00062 {
00063
QTab * t =
tab(
id );
00064
if ( t ) {
00065
if ( t->
isEnabled() != enabled ) {
00066 t->
setEnabled( enabled );
00067
QRect r( t->
rect() );
00068
if ( !enabled &&
id ==
currentTab() &&
count()>1 ) {
00069
int index =
indexOf(
id );
00070 index += ( index+1 ==
count() ) ? -1 : 1;
00071 t =
tabAt( index );
00072
00073
if ( t->
isEnabled() ) {
00074 r = r.
unite( t->
rect() );
00075
QPtrList<QTab> *tablist =
tabList();
00076 tablist->
append( tablist->
take( tablist->
findRef( t ) ) );
00077 emit
selected( t->
identifier() );
00078 }
00079 }
00080 repaint( r );
00081 }
00082 }
00083 }
00084
00085
void KTabBar::mouseDoubleClickEvent(
QMouseEvent *e )
00086 {
00087
QTab *
tab =
selectTab( e->
pos() );
00088
if( tab!= 0L ) {
00089 emit( mouseDoubleClick(
indexOf( tab->
identifier() ) ) );
00090
return;
00091 }
00092 QTabBar::mouseDoubleClickEvent( e );
00093 }
00094
00095
void KTabBar::mousePressEvent(
QMouseEvent *e )
00096 {
00097
if( e->
button() == LeftButton ) {
00098 mEnableCloseButtonTimer->
stop();
00099 mDragStart = e->
pos();
00100 }
00101
else if( e->
button() == RightButton ) {
00102
QTab *tab =
selectTab( e->
pos() );
00103
if( tab!= 0L ) {
00104 emit( contextMenu(
indexOf( tab->
identifier() ), mapToGlobal( e->
pos() ) ) );
00105
return;
00106 }
00107 }
00108 QTabBar::mousePressEvent( e );
00109 }
00110
00111
void KTabBar::mouseMoveEvent(
QMouseEvent *e )
00112 {
00113
if ( e->
state() == LeftButton ) {
00114
QTab *tab =
selectTab( e->
pos() );
00115
if ( mDragSwitchTab && tab != mDragSwitchTab ) {
00116 mActivateDragSwitchTabTimer->
stop();
00117 mDragSwitchTab = 0;
00118 }
00119
00120
int delay =
KGlobalSettings::dndEventDelay();
00121
QPoint newPos = e->
pos();
00122
if( newPos.
x() > mDragStart.
x()+delay || newPos.
x() < mDragStart.
x()-delay ||
00123 newPos.
y() > mDragStart.
y()+delay || newPos.
y() < mDragStart.
y()-delay )
00124 {
00125
if( tab!= 0L ) {
00126 emit( initiateDrag(
indexOf( tab->
identifier() ) ) );
00127
return;
00128 }
00129 }
00130 }
00131
else if ( e->
state() == MidButton ) {
00132
if (mReorderStartTab==-1) {
00133
int delay =
KGlobalSettings::dndEventDelay();
00134
QPoint newPos = e->
pos();
00135
if( newPos.
x() > mDragStart.
x()+delay || newPos.
x() < mDragStart.
x()-delay ||
00136 newPos.
y() > mDragStart.
y()+delay || newPos.
y() < mDragStart.
y()-delay )
00137 {
00138
QTab *tab =
selectTab( e->
pos() );
00139
if( tab!= 0L && mTabReorderingEnabled ) {
00140 mReorderStartTab =
indexOf( tab->
identifier() );
00141 grabMouse( sizeAllCursor );
00142
return;
00143 }
00144 }
00145 }
00146
else {
00147
QTab *tab =
selectTab( e->
pos() );
00148
if( tab!= 0L ) {
00149
int reorderStopTab =
indexOf( tab->
identifier() );
00150
if ( mReorderStartTab!=reorderStopTab && mReorderPreviousTab!=reorderStopTab ) {
00151 emit( moveTab( mReorderStartTab, reorderStopTab ) );
00152 mReorderPreviousTab=mReorderStartTab;
00153 mReorderStartTab=reorderStopTab;
00154
return;
00155 }
00156 }
00157 }
00158 }
00159
00160
if ( mHoverCloseButtonEnabled && mReorderStartTab==-1) {
00161
QTab *t =
selectTab( e->
pos() );
00162
00163
00164
00165
00166
00167
#ifdef __GNUC__
00168
#warning "Workaround for Qt 3.2.0, 3.2.1 bug"
00169
#endif
00170
if ( e->
globalPos() != mapToGlobal( e->
pos() ) )
00171
return;
00172
00173
00174
if( t && t->
iconSet() && t->
isEnabled() ) {
00175
QPixmap pixmap = t->
iconSet()->pixmap( QIconSet::Small, QIconSet::Normal );
00176
QRect rect( 0, 0, pixmap.
width() + 4, pixmap.
height() +4);
00177
00178
int xoff = 0, yoff = 0;
00179
00180
if ( t == tab(
currentTab() ) ) {
00181
#if QT_VERSION >= 0x030200
00182
xoff = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal,
this ) + 3;
00183 yoff = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical,
this ) - 4;
00184
#else
00185
xoff = 3;
00186 yoff = -4;
00187
#endif
00188
}
00189
else {
00190 xoff = 7;
00191 yoff = 0;
00192 }
00193 rect.
moveLeft( t->
rect().left() + 2 + xoff );
00194 rect.
moveTop( t->
rect().center().y()-pixmap.
height()/2 + yoff );
00195
if ( rect.
contains( e->
pos() ) ) {
00196
if ( mHoverCloseButton ) {
00197
if ( mHoverCloseButtonTab == t )
00198
return;
00199 mEnableCloseButtonTimer->
stop();
00200
delete mHoverCloseButton;
00201 }
00202
00203 mHoverCloseButton =
new QPushButton(
this );
00204 mHoverCloseButton->
setIconSet( KGlobal::iconLoader()->loadIcon(
"fileclose", KIcon::Toolbar, KIcon::SizeSmall, KIcon::ActiveState) );
00205 mHoverCloseButton->setGeometry( rect );
00206
QToolTip::add(mHoverCloseButton,i18n(
"Close this tab"));
00207 mHoverCloseButton->
setFlat(
true);
00208 mHoverCloseButton->show();
00209
if ( mHoverCloseButtonDelayed ) {
00210 mHoverCloseButton->setEnabled(
false);
00211 mEnableCloseButtonTimer->
start( QApplication::doubleClickInterval(),
true );
00212 }
00213 mHoverCloseButtonTab = t;
00214 connect( mHoverCloseButton, SIGNAL( clicked() ), SLOT( closeButtonClicked() ) );
00215
return;
00216 }
00217 }
00218
if ( mHoverCloseButton ) {
00219 mEnableCloseButtonTimer->
stop();
00220
delete mHoverCloseButton;
00221 mHoverCloseButton = 0;
00222 }
00223 }
00224
00225 QTabBar::mouseMoveEvent( e );
00226 }
00227
00228
void KTabBar::enableCloseButton()
00229 {
00230 mHoverCloseButton->setEnabled(
true);
00231 }
00232
00233
void KTabBar::activateDragSwitchTab()
00234 {
00235
setCurrentTab( mDragSwitchTab );
00236 mDragSwitchTab = 0;
00237 }
00238
00239
void KTabBar::mouseReleaseEvent(
QMouseEvent *e )
00240 {
00241
if( e->
button() == MidButton ) {
00242
QTab *tab =
selectTab( e->
pos() );
00243
if ( mReorderStartTab==-1 ) {
00244
if( tab!= 0L ) {
00245 emit( mouseMiddleClick(
indexOf( tab->
identifier() ) ) );
00246
return;
00247 }
00248 }
00249
else {
00250 releaseMouse();
00251 setCursor( arrowCursor );
00252 mReorderStartTab=-1;
00253 mReorderPreviousTab=-1;
00254 }
00255 }
00256 QTabBar::mouseReleaseEvent( e );
00257 }
00258
00259
void KTabBar::dragMoveEvent(
QDragMoveEvent *e )
00260 {
00261
QTab *tab =
selectTab( e->pos() );
00262
if( tab!= 0L ) {
00263
bool accept =
false;
00264
00265
00266 emit testCanDecode( e, accept);
00267
if ( accept && tab !=
QTabBar::tab(
currentTab() ) ) {
00268 mDragSwitchTab = tab;
00269 mActivateDragSwitchTabTimer->
start( QApplication::doubleClickInterval()*2,
true );
00270 }
00271 e->
accept( accept );
00272
return;
00273 }
00274 e->
accept(
false );
00275 QTabBar::dragMoveEvent( e );
00276 }
00277
00278
void KTabBar::dropEvent(
QDropEvent *e )
00279 {
00280
QTab *tab =
selectTab( e->
pos() );
00281
if( tab!= 0L ) {
00282 mActivateDragSwitchTabTimer->
stop();
00283 mDragSwitchTab = 0;
00284 emit( receivedDropEvent(
indexOf( tab->
identifier() ) , e ) );
00285
return;
00286 }
00287 QTabBar::dropEvent( e );
00288 }
00289
00290
void KTabBar::setTabColor(
int id,
const QColor& color )
00291 {
00292
QTab *t = tab(
id );
00293
if ( t ) {
00294 mTabColors.
insert(
id, color );
00295 repaint( t->
rect(),
false );
00296 }
00297 }
00298
00299
const QColor &KTabBar::tabColor(
int id )
const
00300
{
00301
if ( mTabColors.
contains(
id ) )
00302
return mTabColors[
id];
00303
00304
return colorGroup().foreground();
00305 }
00306
00307
void KTabBar::removeTab(
QTab *t )
00308 {
00309 mTabColors.
remove( t->
identifier() );
00310
QTabBar::removeTab( t );
00311 }
00312
00313
void KTabBar::paintLabel(
QPainter *p,
const QRect& br,
00314
QTab *t,
bool has_focus )
const
00315
{
00316
QRect r = br;
00317
bool selected =
currentTab() == t->
identifier();
00318
if ( t->
iconSet() ) {
00319
00320 QIconSet::Mode mode = ( t->
isEnabled() && isEnabled() )
00321 ? QIconSet::Normal : QIconSet::Disabled;
00322
if ( mode == QIconSet::Normal && has_focus )
00323 mode = QIconSet::Active;
00324
QPixmap pixmap = t->
iconSet()->pixmap( QIconSet::Small, mode );
00325
int pixw = pixmap.
width();
00326
int pixh = pixmap.
height();
00327 r.
setLeft( r.
left() + pixw + 4 );
00328 r.
setRight( r.
right() + 2 );
00329
00330
int inactiveXShift = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal,
this );
00331
int inactiveYShift = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical,
this );
00332
00333
int right = t->
text().isEmpty() ? br.
right() - pixw : br.
left() + 2;
00334
00335 p->
drawPixmap( right + ((selected ==
true) ? 0 : inactiveXShift),
00336 br.
center().y() - pixh / 2 + ((selected ==
true) ? 0 : inactiveYShift),
00337 pixmap );
00338 }
00339
00340 QStyle::SFlags flags = QStyle::Style_Default;
00341
00342
if ( isEnabled() && t->
isEnabled() )
00343 flags |= QStyle::Style_Enabled;
00344
if ( has_focus )
00345 flags |= QStyle::Style_HasFocus;
00346
00347
QColorGroup cg( colorGroup() );
00348
if ( mTabColors.
contains( t->
identifier() ) )
00349 cg.
setColor( QColorGroup::Foreground, mTabColors[t->
identifier()] );
00350
00351 style().drawControl( QStyle::CE_TabBarLabel, p,
this, r,
00352 t->
isEnabled() ? cg : palette().disabled(),
00353 flags,
QStyleOption(t) );
00354 }
00355
00356
bool KTabBar::isTabReorderingEnabled()
const
00357
{
00358
return mTabReorderingEnabled;
00359 }
00360
00361
void KTabBar::setTabReorderingEnabled(
bool on )
00362 {
00363 mTabReorderingEnabled = on;
00364 }
00365
00366
void KTabBar::closeButtonClicked()
00367 {
00368 emit closeRequest(
indexOf( mHoverCloseButtonTab->
identifier() ) );
00369
#if QT_VERSION < 0x030200
00370
onLayoutChange();
00371
#endif
00372
}
00373
00374
void KTabBar::setHoverCloseButton(
bool button )
00375 {
00376 mHoverCloseButtonEnabled = button;
00377
if ( !button )
00378 onLayoutChange();
00379 }
00380
00381
bool KTabBar::hoverCloseButton()
const
00382
{
00383
return mHoverCloseButtonEnabled;
00384 }
00385
00386
void KTabBar::setHoverCloseButtonDelayed(
bool delayed )
00387 {
00388 mHoverCloseButtonDelayed = delayed;
00389 }
00390
00391
bool KTabBar::hoverCloseButtonDelayed()
const
00392
{
00393
return mHoverCloseButtonDelayed;
00394 }
00395
00396
void KTabBar::onLayoutChange()
00397 {
00398 mEnableCloseButtonTimer->
stop();
00399
delete mHoverCloseButton;
00400 mHoverCloseButton = 0;
00401 mHoverCloseButtonTab = 0;
00402 mActivateDragSwitchTabTimer->
stop();
00403 mDragSwitchTab = 0;
00404 }
00405
00406
#include "ktabbar.moc"