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