kdeui Library API Documentation

ktabbar.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2003 Stephan Binner <binner@kde.org> 00003 Copyright (C) 2003 Zack Rusin <zack@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 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 //For the future 00057 //delete d; 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 // The additional offsets were found by try and error, TODO: find the rational behind them 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 // The receivers of the testCanDecode() signal has to adjust 00256 // 'accept' accordingly. 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 // the tab has an iconset, draw it in the right mode 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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 22:56:32 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003