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