• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

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 
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., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, 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                     mHoverCloseButton->deleteLater();
00190                     mHoverCloseButton = 0;
00191                 }
00192 
00193                 mHoverCloseButton = new QPushButton( this );
00194                 mHoverCloseButton->setIconSet( KGlobal::iconLoader()->loadIconSet("fileclose", KIcon::Toolbar, KIcon::SizeSmall) );
00195                 mHoverCloseButton->setGeometry( rect );
00196                 QToolTip::add(mHoverCloseButton,i18n("Close this tab"));
00197                 mHoverCloseButton->setFlat(true);
00198                 mHoverCloseButton->show();
00199                 if ( mHoverCloseButtonDelayed ) {
00200                   mHoverCloseButton->setEnabled(false);
00201                   mEnableCloseButtonTimer->start( QApplication::doubleClickInterval(), true );
00202                 }
00203                 mHoverCloseButtonTab = t;
00204                 connect( mHoverCloseButton, SIGNAL( clicked() ), SLOT( closeButtonClicked() ) );
00205                 return;
00206             }
00207         }
00208         if ( mHoverCloseButton ) {
00209             mEnableCloseButtonTimer->stop();
00210             mHoverCloseButton->deleteLater();
00211             mHoverCloseButton = 0;
00212         }
00213     }
00214 
00215     QTabBar::mouseMoveEvent( e );
00216 }
00217 
00218 void KTabBar::enableCloseButton()
00219 {
00220     mHoverCloseButton->setEnabled(true);
00221 }
00222 
00223 void KTabBar::activateDragSwitchTab()
00224 {
00225     QTab *tab = selectTab( mapFromGlobal( QCursor::pos() ) );
00226     if ( tab && mDragSwitchTab == tab )
00227     setCurrentTab( mDragSwitchTab );
00228     mDragSwitchTab = 0;
00229 }
00230 
00231 void KTabBar::mouseReleaseEvent( QMouseEvent *e )
00232 {
00233     if( e->button() == MidButton ) {
00234         if ( mReorderStartTab==-1 ) {
00235             QTab *tab = selectTab( e->pos() );
00236             if( tab ) {
00237                 emit( mouseMiddleClick( indexOf( tab->identifier() ) ) );
00238                 return;
00239             }
00240         }
00241         else {
00242             releaseMouse();
00243             setCursor( arrowCursor );
00244             mReorderStartTab=-1;
00245             mReorderPreviousTab=-1;
00246         }
00247     }
00248     QTabBar::mouseReleaseEvent( e );
00249 }
00250 
00251 void KTabBar::dragMoveEvent( QDragMoveEvent *e )
00252 {
00253     QTab *tab = selectTab( e->pos() );
00254     if( tab ) {
00255         bool accept = false;
00256         // The receivers of the testCanDecode() signal has to adjust
00257         // 'accept' accordingly.
00258         emit testCanDecode( e, accept);
00259         if ( accept && tab != QTabBar::tab( currentTab() ) ) {
00260           mDragSwitchTab = tab;
00261           mActivateDragSwitchTabTimer->start( QApplication::doubleClickInterval()*2, true );
00262         }
00263         e->accept( accept );
00264         return;
00265     }
00266     e->accept( false );
00267     QTabBar::dragMoveEvent( e );
00268 }
00269 
00270 void KTabBar::dropEvent( QDropEvent *e )
00271 {
00272     QTab *tab = selectTab( e->pos() );
00273     if( tab ) {
00274         mActivateDragSwitchTabTimer->stop();
00275         mDragSwitchTab = 0;
00276         emit( receivedDropEvent( indexOf( tab->identifier() ) , e ) );
00277         return;
00278     }
00279     QTabBar::dropEvent( e );
00280 }
00281 
00282 #ifndef QT_NO_WHEELEVENT
00283 void KTabBar::wheelEvent( QWheelEvent *e )
00284 {
00285     if ( e->orientation() == Horizontal )
00286         return;
00287 
00288     emit( wheelDelta( e->delta() ) );
00289 }
00290 #endif
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 int KTabBar::insertTab( QTab *t, int index )
00310 {
00311     int res = QTabBar::insertTab( t, index );
00312 
00313     if ( mTabCloseActivatePrevious && count() > 2 ) {
00314         QPtrList<QTab> *tablist = tabList();
00315         tablist->insert( count()-2, tablist->take( tablist->findRef( t ) ) );
00316     }
00317 
00318     return res;
00319 }
00320 
00321 void KTabBar::removeTab( QTab *t )
00322 {
00323     mTabColors.remove( t->identifier() );
00324     QTabBar::removeTab( t );
00325 }
00326 
00327 void KTabBar::paintLabel( QPainter *p, const QRect& br,
00328                           QTab *t, bool has_focus ) const
00329 {
00330     QRect r = br;
00331     bool selected = currentTab() == t->identifier();
00332     if ( t->iconSet() ) {
00333         // the tab has an iconset, draw it in the right mode
00334         QIconSet::Mode mode = ( t->isEnabled() && isEnabled() )
00335                                  ? QIconSet::Normal : QIconSet::Disabled;
00336         if ( mode == QIconSet::Normal && has_focus )
00337             mode = QIconSet::Active;
00338         QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode );
00339         int pixw = pixmap.width();
00340         int pixh = pixmap.height();
00341         r.setLeft( r.left() + pixw + 4 );
00342         r.setRight( r.right() + 2 );
00343 
00344         int inactiveXShift = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal, this );
00345         int inactiveYShift = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical, this );
00346 
00347         int right = t->text().isEmpty() ? br.right() - pixw : br.left() + 2;
00348 
00349         p->drawPixmap( right + (selected ? 0 : inactiveXShift),
00350                        br.center().y() - pixh / 2 + (selected ? 0 : inactiveYShift),
00351                        pixmap );
00352     }
00353 
00354     QStyle::SFlags flags = QStyle::Style_Default;
00355 
00356     if ( isEnabled() && t->isEnabled() )
00357         flags |= QStyle::Style_Enabled;
00358     if ( has_focus )
00359         flags |= QStyle::Style_HasFocus;
00360 
00361     QColorGroup cg( colorGroup() );
00362     if ( mTabColors.contains( t->identifier() ) )
00363         cg.setColor( QColorGroup::Foreground, mTabColors[t->identifier()] );
00364 
00365     style().drawControl( QStyle::CE_TabBarLabel, p, this, r,
00366                              t->isEnabled() ? cg : palette().disabled(),
00367                              flags, QStyleOption(t) );
00368 }
00369 
00370 bool KTabBar::isTabReorderingEnabled() const
00371 {
00372     return mTabReorderingEnabled;
00373 }
00374 
00375 void KTabBar::setTabReorderingEnabled( bool on )
00376 {
00377     mTabReorderingEnabled = on;
00378 }
00379 
00380 bool KTabBar::tabCloseActivatePrevious() const
00381 {
00382     return mTabCloseActivatePrevious;
00383 }
00384 
00385 void KTabBar::setTabCloseActivatePrevious( bool on )
00386 {
00387     mTabCloseActivatePrevious = on;
00388 }
00389 
00390 void KTabBar::closeButtonClicked()
00391 {
00392     emit closeRequest( indexOf( mHoverCloseButtonTab->identifier() ) );
00393 }
00394 
00395 void KTabBar::setHoverCloseButton( bool button )
00396 {
00397     mHoverCloseButtonEnabled = button;
00398     if ( !button )
00399         onLayoutChange();
00400 }
00401 
00402 bool KTabBar::hoverCloseButton() const
00403 {
00404     return mHoverCloseButtonEnabled;
00405 }
00406 
00407 void KTabBar::setHoverCloseButtonDelayed( bool delayed )
00408 {
00409     mHoverCloseButtonDelayed = delayed;
00410 }
00411 
00412 bool KTabBar::hoverCloseButtonDelayed() const
00413 {
00414     return mHoverCloseButtonDelayed;
00415 }
00416 
00417 void KTabBar::onLayoutChange()
00418 {
00419     mEnableCloseButtonTimer->stop();
00420     delete mHoverCloseButton;
00421     mHoverCloseButton = 0;
00422     mHoverCloseButtonTab = 0;
00423     mActivateDragSwitchTabTimer->stop();
00424     mDragSwitchTab = 0;
00425 }
00426 
00427 #include "ktabbar.moc"

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal