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