KDEUI
ktabbar.cpp
Go to the documentation of this file.
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 Copyright (C) 2009 Urs Wolfer <uwolfer @ kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "ktabbar.h" 00023 00024 #include <QtCore/QTimer> 00025 #include <QtGui/QApplication> 00026 #include <QtGui/QCursor> 00027 #include <QtGui/QMouseEvent> 00028 00029 #include <kglobalsettings.h> 00030 00031 class KTabBar::Private 00032 { 00033 public: 00034 Private() 00035 : mReorderStartTab( -1 ), 00036 mReorderPreviousTab( -1 ), 00037 mDragSwitchTab( -1 ), 00038 mActivateDragSwitchTabTimer( 0 ), 00039 mTabReorderingEnabled( false ), 00040 mMiddleMouseTabMoveInProgress( false) 00041 { 00042 } 00043 00044 QPoint mDragStart; 00045 int mReorderStartTab; 00046 int mReorderPreviousTab; 00047 int mDragSwitchTab; 00048 QTimer *mActivateDragSwitchTabTimer; 00049 00050 bool mTabReorderingEnabled : 1; 00051 bool mMiddleMouseTabMoveInProgress : 1; 00052 00053 }; 00054 00055 KTabBar::KTabBar( QWidget *parent ) 00056 : QTabBar( parent ), 00057 d( new Private ) 00058 { 00059 setAcceptDrops( true ); 00060 setMouseTracking( true ); 00061 00062 d->mActivateDragSwitchTabTimer = new QTimer( this ); 00063 d->mActivateDragSwitchTabTimer->setSingleShot( true ); 00064 connect( d->mActivateDragSwitchTabTimer, SIGNAL( timeout() ), SLOT( activateDragSwitchTab() ) ); 00065 #ifndef KDE_NO_DEPRECATED 00066 connect( this, SIGNAL(tabCloseRequested(int)), this, SIGNAL(closeRequest(int))); // just for backward compatibility, KDE5 remove 00067 #endif 00068 00069 //connect( this, SIGNAL( layoutChanged() ), SLOT( onLayoutChange() ) ); 00070 } 00071 00072 KTabBar::~KTabBar() 00073 { 00074 delete d; 00075 } 00076 00077 void KTabBar::mouseDoubleClickEvent( QMouseEvent *event ) 00078 { 00079 if ( event->button() != Qt::LeftButton ) 00080 return; 00081 00082 int tab = selectTab( event->pos() ); 00083 00084 if(tab == -1) { 00085 emit newTabRequest(); 00086 } else { 00087 #ifndef KDE_NO_DEPRECATED 00088 emit mouseDoubleClick( tab ); //deprecated 00089 #endif 00090 emit tabDoubleClicked( tab ); 00091 } 00092 00093 QTabBar::mouseDoubleClickEvent( event ); 00094 } 00095 00096 void KTabBar::mousePressEvent( QMouseEvent *event ) 00097 { 00098 if ( event->button() == Qt::LeftButton ) { 00099 d->mDragStart = event->pos(); 00100 } else if( event->button() == Qt::RightButton ) { 00101 int tab = selectTab( event->pos() ); 00102 if ( tab != -1 ) { 00103 emit contextMenu( tab, mapToGlobal( event->pos() ) ); 00104 } else { 00105 emit emptyAreaContextMenu( mapToGlobal( event->pos() ) ); 00106 } 00107 return; 00108 } else if (QTabBar::isMovable() && event->button() == Qt::MidButton) { 00109 // compatibility feature for old middle mouse tab moving 00110 event->accept(); 00111 QMouseEvent fakedMouseEvent(event->type(), event->pos(), Qt::LeftButton, Qt::LeftButton, event->modifiers()); 00112 QCoreApplication::sendEvent(this, &fakedMouseEvent); 00113 } 00114 00115 QTabBar::mousePressEvent( event ); 00116 } 00117 00118 void KTabBar::mouseMoveEvent( QMouseEvent *event ) 00119 { 00120 if ( event->buttons() == Qt::LeftButton && !isMovable() ) { 00121 int tab = selectTab( event->pos() ); 00122 if ( d->mDragSwitchTab && tab != d->mDragSwitchTab ) { 00123 d->mActivateDragSwitchTabTimer->stop(); 00124 d->mDragSwitchTab = 0; 00125 } 00126 00127 int delay = KGlobalSettings::dndEventDelay(); 00128 QPoint newPos = event->pos(); 00129 if ( newPos.x() > d->mDragStart.x() + delay || newPos.x() < d->mDragStart.x() - delay || 00130 newPos.y() > d->mDragStart.y() + delay || newPos.y() < d->mDragStart.y() - delay ) { 00131 if ( tab != -1 ) { 00132 emit initiateDrag( tab ); 00133 return; 00134 } 00135 } 00136 } else if ( event->buttons() == Qt::MidButton && !isMovable() ) { 00137 if ( d->mReorderStartTab == -1 ) { 00138 int delay = KGlobalSettings::dndEventDelay(); 00139 QPoint newPos = event->pos(); 00140 00141 if ( newPos.x() > d->mDragStart.x() + delay || newPos.x() < d->mDragStart.x() - delay || 00142 newPos.y() > d->mDragStart.y() + delay || newPos.y() < d->mDragStart.y() - delay ) { 00143 int tab = selectTab( event->pos() ); 00144 if ( tab != -1 && d->mTabReorderingEnabled ) { 00145 d->mReorderStartTab = tab; 00146 grabMouse( Qt::SizeAllCursor ); 00147 return; 00148 } 00149 } 00150 } else { 00151 int tab = selectTab( event->pos() ); 00152 if ( tab != -1 ) { 00153 int reorderStopTab = tab; 00154 if ( d->mReorderStartTab != reorderStopTab && d->mReorderPreviousTab != reorderStopTab ) { 00155 emit moveTab( d->mReorderStartTab, reorderStopTab ); 00156 00157 d->mReorderPreviousTab = d->mReorderStartTab; 00158 d->mReorderStartTab = reorderStopTab; 00159 00160 return; 00161 } 00162 } 00163 } 00164 } else if ( event->button() == Qt::NoButton && event->buttons() == Qt::MidButton && isMovable() ) { 00165 // compatibility feature for old middle mouse tab moving 00166 d->mMiddleMouseTabMoveInProgress = true; 00167 event->accept(); 00168 QMouseEvent fakedMouseEvent(event->type(), event->pos(), event->button(), Qt::LeftButton, event->modifiers()); 00169 QCoreApplication::sendEvent(this, &fakedMouseEvent); 00170 return; 00171 } 00172 00173 QTabBar::mouseMoveEvent( event ); 00174 } 00175 00176 00177 #ifndef KDE_NO_DEPRECATED 00178 void KTabBar::closeButtonClicked() 00179 { 00180 // deprecated 00181 } 00182 #endif 00183 00184 00185 #ifndef KDE_NO_DEPRECATED 00186 void KTabBar::enableCloseButton() 00187 { 00188 // deprecated 00189 } 00190 #endif 00191 00192 00193 void KTabBar::activateDragSwitchTab() 00194 { 00195 int tab = selectTab( mapFromGlobal( QCursor::pos() ) ); 00196 if ( tab != -1 && d->mDragSwitchTab == tab ) 00197 setCurrentIndex( d->mDragSwitchTab ); 00198 00199 d->mDragSwitchTab = 0; 00200 } 00201 00202 void KTabBar::mouseReleaseEvent( QMouseEvent *event ) 00203 { 00204 switch ( event->button() ) { 00205 case Qt::LeftButton: 00206 break; 00207 00208 case Qt::MidButton: 00209 if (d->mMiddleMouseTabMoveInProgress && QTabBar::isMovable()) { 00210 // compatibility feature for old middle mouse tab moving 00211 d->mMiddleMouseTabMoveInProgress = false; 00212 event->accept(); 00213 QMouseEvent fakedMouseEvent(event->type(), event->pos(), Qt::LeftButton, Qt::LeftButton, event->modifiers()); 00214 QCoreApplication::sendEvent(this, &fakedMouseEvent); 00215 return; 00216 } 00217 if ( d->mReorderStartTab == -1 ) { 00218 int tab = selectTab( event->pos() ); 00219 if ( tab != -1 ) { 00220 event->accept(); 00221 if (QTabBar::isMovable()) { 00222 QMouseEvent fakedMouseEvent(event->type(), event->pos(), Qt::LeftButton, Qt::LeftButton, event->modifiers()); 00223 QCoreApplication::sendEvent(this, &fakedMouseEvent); 00224 } 00225 emit mouseMiddleClick( tab ); 00226 return; 00227 } 00228 } else { 00229 releaseMouse(); 00230 setCursor( Qt::ArrowCursor ); 00231 d->mReorderStartTab = -1; 00232 d->mReorderPreviousTab = -1; 00233 } 00234 break; 00235 00236 default: 00237 break; 00238 } 00239 00240 QTabBar::mouseReleaseEvent( event ); 00241 } 00242 00243 void KTabBar::dragEnterEvent( QDragEnterEvent *event ) 00244 { 00245 int tab = selectTab( event->pos() ); 00246 if ( tab != -1 ) { 00247 bool accept = false; 00248 // The receivers of the testCanDecode() signal has to adjust 00249 // 'accept' accordingly. 00250 emit testCanDecode( event, accept ); 00251 if ( accept && tab != currentIndex() ) { 00252 d->mDragSwitchTab = tab; 00253 d->mActivateDragSwitchTabTimer->start( QApplication::doubleClickInterval() * 2 ); 00254 } 00255 00256 event->setAccepted( accept ); 00257 return; 00258 } 00259 00260 QTabBar::dragEnterEvent( event ); 00261 } 00262 00263 void KTabBar::dragMoveEvent( QDragMoveEvent *event ) 00264 { 00265 int tab = selectTab( event->pos() ); 00266 if ( tab != -1 ) { 00267 bool accept = false; 00268 // The receivers of the testCanDecode() signal has to adjust 00269 // 'accept' accordingly. 00270 emit testCanDecode( event, accept ); 00271 if ( accept && tab != currentIndex() ) { 00272 d->mDragSwitchTab = tab; 00273 d->mActivateDragSwitchTabTimer->start( QApplication::doubleClickInterval() * 2 ); 00274 } 00275 00276 event->setAccepted( accept ); 00277 return; 00278 } 00279 00280 QTabBar::dragMoveEvent( event ); 00281 } 00282 00283 void KTabBar::dropEvent( QDropEvent *event ) 00284 { 00285 int tab = selectTab( event->pos() ); 00286 if ( tab != -1 ) { 00287 d->mActivateDragSwitchTabTimer->stop(); 00288 d->mDragSwitchTab = 0; 00289 emit receivedDropEvent( tab , event ); 00290 return; 00291 } 00292 00293 QTabBar::dropEvent( event ); 00294 } 00295 00296 void KTabBar::paintEvent( QPaintEvent *event ) 00297 { 00298 QTabBar::paintEvent( event ); 00299 } 00300 00301 void KTabBar::leaveEvent( QEvent *event ) 00302 { 00303 QTabBar::leaveEvent( event ); 00304 } 00305 00306 QSize KTabBar::tabSizeHint( int index ) const 00307 { 00308 QSize size = QTabBar::tabSizeHint( index ); 00309 00310 return size; 00311 } 00312 00313 #ifndef QT_NO_WHEELEVENT 00314 void KTabBar::wheelEvent( QWheelEvent *event ) 00315 { 00316 if ( !( event->orientation() == Qt::Horizontal ) ) { 00317 if ( receivers( SIGNAL(wheelDelta(int)) ) ) { 00318 emit( wheelDelta( event->delta() ) ); 00319 return; 00320 } 00321 int lastIndex = count() - 1; 00322 //Set an invalid index as base case 00323 int targetIndex = -1; 00324 bool forward = event->delta() < 0; 00325 if ( forward && lastIndex == currentIndex() ) { 00326 targetIndex = 0; 00327 } 00328 else if ( !forward && 0 == currentIndex() ) { 00329 targetIndex = lastIndex; 00330 } 00331 //Will not move when targetIndex is invalid 00332 setCurrentIndex( targetIndex ); 00333 //If it has not moved yet (targetIndex == -1), or if it moved but current tab is disabled 00334 if ( targetIndex != currentIndex() || !isTabEnabled( targetIndex ) ) { 00335 QTabBar::wheelEvent( event ); 00336 } 00337 event->accept(); 00338 } else { 00339 event->ignore(); 00340 } 00341 } 00342 #endif 00343 00344 #ifndef KDE_NO_DEPRECATED 00345 bool KTabBar::isTabReorderingEnabled() const 00346 { 00347 return d->mTabReorderingEnabled; 00348 } 00349 #endif 00350 00351 #ifndef KDE_NO_DEPRECATED 00352 void KTabBar::setTabReorderingEnabled( bool on ) 00353 { 00354 d->mTabReorderingEnabled = on; 00355 } 00356 #endif 00357 00358 #ifndef KDE_NO_DEPRECATED 00359 bool KTabBar::tabCloseActivatePrevious() const 00360 { 00361 return selectionBehaviorOnRemove() == QTabBar::SelectPreviousTab; 00362 } 00363 #endif 00364 00365 #ifndef KDE_NO_DEPRECATED 00366 void KTabBar::setTabCloseActivatePrevious( bool on ) 00367 { 00368 setSelectionBehaviorOnRemove(on ? QTabBar::SelectPreviousTab : QTabBar::SelectRightTab); 00369 } 00370 #endif 00371 00372 00373 #ifndef KDE_NO_DEPRECATED 00374 void KTabBar::setHoverCloseButton( bool button ) 00375 { 00376 // deprecated 00377 setTabsClosable(button); 00378 } 00379 #endif 00380 00381 #ifndef KDE_NO_DEPRECATED 00382 bool KTabBar::hoverCloseButton() const 00383 { 00384 // deprecated 00385 return tabsClosable(); 00386 } 00387 #endif 00388 00389 #ifndef KDE_NO_DEPRECATED 00390 void KTabBar::setHoverCloseButtonDelayed( bool delayed ) 00391 { 00392 // deprecated 00393 Q_UNUSED( delayed ); 00394 } 00395 #endif 00396 00397 #ifndef KDE_NO_DEPRECATED 00398 bool KTabBar::hoverCloseButtonDelayed() const 00399 { 00400 // deprecated 00401 return false; 00402 } 00403 #endif 00404 00405 #ifndef KDE_NO_DEPRECATED 00406 void KTabBar::setCloseButtonEnabled( bool enable ) 00407 { 00408 QTabBar::setTabsClosable(enable); 00409 } 00410 #endif 00411 00412 #ifndef KDE_NO_DEPRECATED 00413 bool KTabBar::isCloseButtonEnabled() const 00414 { 00415 return QTabBar::tabsClosable(); 00416 } 00417 #endif 00418 00419 void KTabBar::tabLayoutChange() 00420 { 00421 d->mActivateDragSwitchTabTimer->stop(); 00422 d->mDragSwitchTab = 0; 00423 } 00424 00425 int KTabBar::selectTab( const QPoint &pos ) const 00426 { 00427 const int tabCount = count(); 00428 for ( int i = 0; i < tabCount; ++i ) 00429 if ( tabRect( i ).contains( pos ) ) 00430 return i; 00431 00432 return -1; 00433 } 00434 00435 QPoint KTabBar::closeButtonPos( int tabIndex ) const 00436 { 00437 Q_UNUSED(tabIndex); 00438 return QPoint(); 00439 } 00440 00441 QRect KTabBar::closeButtonRect( int tabIndex ) const 00442 { 00443 Q_UNUSED(tabIndex); 00444 return QRect(); 00445 } 00446 00447 #include "ktabbar.moc"
KDE 4.7 API Reference