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