# kdeui Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

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

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:23 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003