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 <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 //For the future 00056 //delete d; 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 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 if( t && t->iconSet() && t->isEnabled() ) { 00165 QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ); 00166 QRect rect( 0, 0, pixmap.width() + 4, pixmap.height() +4); 00167 00168 int xoff = 0, yoff = 0; 00169 // The additional offsets were found by try and error, TODO: find the rational behind them 00170 if ( t == tab( currentTab() ) ) { 00171 xoff = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal, this ) + 3; 00172 yoff = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical, this ) - 4; 00173 } 00174 else { 00175 xoff = 7; 00176 yoff = 0; 00177 } 00178 rect.moveLeft( t->rect().left() + 2 + xoff ); 00179 rect.moveTop( t->rect().center().y()-pixmap.height()/2 + yoff ); 00180 if ( rect.contains( e->pos() ) ) { 00181 if ( mHoverCloseButton ) { 00182 if ( mHoverCloseButtonTab == t ) 00183 return; 00184 mEnableCloseButtonTimer->stop(); 00185 delete mHoverCloseButton; 00186 } 00187 00188 mHoverCloseButton = new QPushButton( this ); 00189 mHoverCloseButton->setIconSet( KGlobal::iconLoader()->loadIcon("fileclose", KIcon::Toolbar, KIcon::SizeSmall, KIcon::ActiveState) ); 00190 mHoverCloseButton->setGeometry( rect ); 00191 QToolTip::add(mHoverCloseButton,i18n("Close this tab")); 00192 mHoverCloseButton->setFlat(true); 00193 mHoverCloseButton->show(); 00194 if ( mHoverCloseButtonDelayed ) { 00195 mHoverCloseButton->setEnabled(false); 00196 mEnableCloseButtonTimer->start( QApplication::doubleClickInterval(), true ); 00197 } 00198 mHoverCloseButtonTab = t; 00199 connect( mHoverCloseButton, SIGNAL( clicked() ), SLOT( closeButtonClicked() ) ); 00200 return; 00201 } 00202 } 00203 if ( mHoverCloseButton ) { 00204 mEnableCloseButtonTimer->stop(); 00205 delete mHoverCloseButton; 00206 mHoverCloseButton = 0; 00207 } 00208 } 00209 00210 QTabBar::mouseMoveEvent( e ); 00211 } 00212 00213 void KTabBar::enableCloseButton() 00214 { 00215 mHoverCloseButton->setEnabled(true); 00216 } 00217 00218 void KTabBar::activateDragSwitchTab() 00219 { 00220 setCurrentTab( mDragSwitchTab ); 00221 mDragSwitchTab = 0; 00222 } 00223 00224 void KTabBar::mouseReleaseEvent( QMouseEvent *e ) 00225 { 00226 if( e->button() == MidButton ) { 00227 if ( mReorderStartTab==-1 ) { 00228 QTab *tab = selectTab( e->pos() ); 00229 if( tab!= 0L ) { 00230 emit( mouseMiddleClick( indexOf( tab->identifier() ) ) ); 00231 return; 00232 } 00233 } 00234 else { 00235 releaseMouse(); 00236 setCursor( arrowCursor ); 00237 mReorderStartTab=-1; 00238 mReorderPreviousTab=-1; 00239 } 00240 } 00241 QTabBar::mouseReleaseEvent( e ); 00242 } 00243 00244 void KTabBar::dragMoveEvent( QDragMoveEvent *e ) 00245 { 00246 QTab *tab = selectTab( e->pos() ); 00247 if( tab!= 0L ) { 00248 bool accept = false; 00249 // The receivers of the testCanDecode() signal has to adjust 00250 // 'accept' accordingly. 00251 emit testCanDecode( e, accept); 00252 if ( accept && tab != QTabBar::tab( currentTab() ) ) { 00253 mDragSwitchTab = tab; 00254 mActivateDragSwitchTabTimer->start( QApplication::doubleClickInterval()*2, true ); 00255 } 00256 e->accept( accept ); 00257 return; 00258 } 00259 e->accept( false ); 00260 QTabBar::dragMoveEvent( e ); 00261 } 00262 00263 void KTabBar::dropEvent( QDropEvent *e ) 00264 { 00265 QTab *tab = selectTab( e->pos() ); 00266 if( tab!= 0L ) { 00267 mActivateDragSwitchTabTimer->stop(); 00268 mDragSwitchTab = 0; 00269 emit( receivedDropEvent( indexOf( tab->identifier() ) , e ) ); 00270 return; 00271 } 00272 QTabBar::dropEvent( e ); 00273 } 00274 00275 #ifndef QT_NO_WHEELEVENT 00276 void KTabBar::wheelEvent( QWheelEvent *e ) 00277 { 00278 if ( e->orientation() == Horizontal ) 00279 return; 00280 00281 emit( wheelDelta( e->delta() ) ); 00282 } 00283 #endif 00284 00285 void KTabBar::setTabColor( int id, const QColor& color ) 00286 { 00287 QTab *t = tab( id ); 00288 if ( t ) { 00289 mTabColors.insert( id, color ); 00290 repaint( t->rect(), false ); 00291 } 00292 } 00293 00294 const QColor &KTabBar::tabColor( int id ) const 00295 { 00296 if ( mTabColors.contains( id ) ) 00297 return mTabColors[id]; 00298 00299 return colorGroup().foreground(); 00300 } 00301 00302 int KTabBar::insertTab( QTab *t, int index ) 00303 { 00304 int res = QTabBar::insertTab( t, index ); 00305 00306 if ( mTabCloseActivatePrevious && count() > 2 ) { 00307 QPtrList<QTab> *tablist = tabList(); 00308 tablist->insert( count()-2, tablist->take( tablist->findRef( t ) ) ); 00309 } 00310 00311 return res; 00312 } 00313 00314 void KTabBar::removeTab( QTab *t ) 00315 { 00316 mTabColors.remove( t->identifier() ); 00317 QTabBar::removeTab( t ); 00318 } 00319 00320 void KTabBar::paintLabel( QPainter *p, const QRect& br, 00321 QTab *t, bool has_focus ) const 00322 { 00323 QRect r = br; 00324 bool selected = currentTab() == t->identifier(); 00325 if ( t->iconSet() ) { 00326 // the tab has an iconset, draw it in the right mode 00327 QIconSet::Mode mode = ( t->isEnabled() && isEnabled() ) 00328 ? QIconSet::Normal : QIconSet::Disabled; 00329 if ( mode == QIconSet::Normal && has_focus ) 00330 mode = QIconSet::Active; 00331 QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode ); 00332 int pixw = pixmap.width(); 00333 int pixh = pixmap.height(); 00334 r.setLeft( r.left() + pixw + 4 ); 00335 r.setRight( r.right() + 2 ); 00336 00337 int inactiveXShift = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal, this ); 00338 int inactiveYShift = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical, this ); 00339 00340 int right = t->text().isEmpty() ? br.right() - pixw : br.left() + 2; 00341 00342 p->drawPixmap( right + ((selected == true) ? 0 : inactiveXShift), 00343 br.center().y() - pixh / 2 + ((selected == true) ? 0 : inactiveYShift), 00344 pixmap ); 00345 } 00346 00347 QStyle::SFlags flags = QStyle::Style_Default; 00348 00349 if ( isEnabled() && t->isEnabled() ) 00350 flags |= QStyle::Style_Enabled; 00351 if ( has_focus ) 00352 flags |= QStyle::Style_HasFocus; 00353 00354 QColorGroup cg( colorGroup() ); 00355 if ( mTabColors.contains( t->identifier() ) ) 00356 cg.setColor( QColorGroup::Foreground, mTabColors[t->identifier()] ); 00357 00358 style().drawControl( QStyle::CE_TabBarLabel, p, this, r, 00359 t->isEnabled() ? cg : palette().disabled(), 00360 flags, QStyleOption(t) ); 00361 } 00362 00363 bool KTabBar::isTabReorderingEnabled() const 00364 { 00365 return mTabReorderingEnabled; 00366 } 00367 00368 void KTabBar::setTabReorderingEnabled( bool on ) 00369 { 00370 mTabReorderingEnabled = on; 00371 } 00372 00373 bool KTabBar::tabCloseActivatePrevious() const 00374 { 00375 return mTabCloseActivatePrevious; 00376 } 00377 00378 void KTabBar::setTabCloseActivatePrevious( bool on ) 00379 { 00380 mTabCloseActivatePrevious = on; 00381 } 00382 00383 void KTabBar::closeButtonClicked() 00384 { 00385 emit closeRequest( indexOf( mHoverCloseButtonTab->identifier() ) ); 00386 } 00387 00388 void KTabBar::setHoverCloseButton( bool button ) 00389 { 00390 mHoverCloseButtonEnabled = button; 00391 if ( !button ) 00392 onLayoutChange(); 00393 } 00394 00395 bool KTabBar::hoverCloseButton() const 00396 { 00397 return mHoverCloseButtonEnabled; 00398 } 00399 00400 void KTabBar::setHoverCloseButtonDelayed( bool delayed ) 00401 { 00402 mHoverCloseButtonDelayed = delayed; 00403 } 00404 00405 bool KTabBar::hoverCloseButtonDelayed() const 00406 { 00407 return mHoverCloseButtonDelayed; 00408 } 00409 00410 void KTabBar::onLayoutChange() 00411 { 00412 mEnableCloseButtonTimer->stop(); 00413 delete mHoverCloseButton; 00414 mHoverCloseButton = 0; 00415 mHoverCloseButtonTab = 0; 00416 mActivateDragSwitchTabTimer->stop(); 00417 mDragSwitchTab = 0; 00418 } 00419 00420 #include "ktabbar.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:40:35 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003