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