lib Library API Documentation

kotabbar.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Ariya Hidayat <ariya@kde.org>
00003    Copyright (C) 2003 Norbert Andres <nandres@web.de>
00004    Copyright (C) 2002 Laurent Montel <montel@kde.org>
00005    Copyright (C) 1999 David Faure <faure@kde.org>
00006    Copyright (C) 1999 Boris Wedl <boris.wedl@kfunigraz.ac.at>
00007    Copyright (C) 1998-2000 Torben Weis <weis@kde.org>
00008 
00009    This library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Library General Public
00011    License as published by the Free Software Foundation; either
00012    version 2 of the License, or (at your option) any later version.
00013 
00014    This library is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017    Library General Public License for more details.
00018 
00019    You should have received a copy of the GNU Library General Public License
00020    along with this library; see the file COPYING.LIB.  If not, write to
00021    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00022    Boston, MA 02111-1307, USA.
00023 */
00024 
00025 #include "kotabbar.h"
00026 
00027 #include <qdrawutil.h>
00028 #include <qpainter.h>
00029 #include <qstring.h>
00030 #include <qstringlist.h>
00031 #include <qstyle.h>
00032 #include <qtimer.h>
00033 #include <qtoolbutton.h>
00034 #include <qvaluevector.h>
00035 #include <qwidget.h>
00036 
00037 // TODO
00038 // improvement possibilities
00039 // - use offscreen buffer to reduce flicker even more
00040 // - keep track of tabs, only (re)layout when necessary
00041 // - paint all tabs to buffer, show only by shifting
00042 // - customizable button pixmaps
00043 // - use QStyle to paint the tabs & buttons (is it good/possible?)
00044 
00045 
00046 class KoTabBarPrivate
00047 {
00048 public:
00049     KoTabBar* tabbar;
00050 
00051     // scroll buttons
00052     QToolButton* scrollFirstButton;
00053     QToolButton* scrollLastButton;
00054     QToolButton* scrollBackButton;
00055     QToolButton* scrollForwardButton;
00056 
00057     // read-only: no mouse drag, double-click, right-click
00058     bool readOnly;
00059     
00060     // if true, layout is from right to left
00061     bool reverseLayout;
00062 
00063     // list of all tabs, in order of appearance
00064     QStringList tabs;
00065 
00066     // array of QRect for each visible tabs
00067     QValueVector<QRect> tabRects;
00068 
00069     // leftmost tab (or rightmost if reverseLayout)
00070     int firstTab;
00071     
00072     // rightmost tab (or leftmost if reverseLayout)
00073     int lastTab;
00074 
00075     // the active tab in the range form 1..n.
00076     // if this value is 0, that means that no tab is active.
00077     int activeTab;
00078 
00079     // unusable space on the left, taken by the scroll buttons
00080     int offset;
00081 
00082     // when the user drag the tab (in order to move it)
00083     // this is the target position, it's 0 if no tab is dragged
00084     int targetTab;
00085 
00086     // true if autoscroll is active
00087     bool autoScroll;
00088 
00089     // calculate the bounding rectangle for each visible tab
00090     void layoutTabs();
00091     
00092     // reposition scroll buttons
00093     void layoutButtons();
00094 
00095     // find a tab whose bounding rectangle contains the pos
00096     // return -1 if no such tab is found
00097     int tabAt( const QPoint& pos );
00098 
00099     // draw a single tab
00100     void drawTab( QPainter& painter, QRect& rect, const QString& text, bool active );
00101 
00102     // draw a marker to indicate tab moving
00103     void drawMoveMarker( QPainter& painter, int x, int y );
00104 
00105     // update the enable/disable status of scroll buttons
00106     void updateButtons();
00107 };
00108 
00109 // built-in pixmap for scroll-first button
00110 static const char * arrow_leftmost_xpm[] = {
00111 "10 10 2 1",
00112 "   c None",
00113 ".  c #000000",
00114 "          ",
00115 "  .    .  ",
00116 "  .   ..  ",
00117 "  .  ...  ",
00118 "  . ....  ",
00119 "  .  ...  ",
00120 "  .   ..  ",
00121 "  .    .  ",
00122 "          ",
00123 "          "};
00124 
00125 // built-in pixmap for scroll-last button
00126 static const char * arrow_rightmost_xpm[] = {
00127 "10 10 2 1",
00128 "   c None",
00129 ".  c #000000",
00130 "          ",
00131 "  .    .  ",
00132 "  ..   .  ",
00133 "  ...  .  ",
00134 "  .... .  ",
00135 "  ...  .  ",
00136 "  ..   .  ",
00137 "  .    .  ",
00138 "          ",
00139 "          "};
00140 
00141 // built-in pixmap for scroll-left button
00142 static const char * arrow_left_xpm[] = {
00143 "10 10 2 1",
00144 "   c None",
00145 ".  c #000000",
00146 "          ",
00147 "      .   ",
00148 "     ..   ",
00149 "    ...   ",
00150 "   ....   ",
00151 "    ...   ",
00152 "     ..   ",
00153 "      .   ",
00154 "          ",
00155 "          "};
00156 
00157 // built-in pixmap for scroll-right button
00158 static const char * arrow_right_xpm[] = {
00159 "10 10 2 1",
00160 "   c None",
00161 ".  c #000000",
00162 "          ",
00163 "   .      ",
00164 "   ..     ",
00165 "   ...    ",
00166 "   ....   ",
00167 "   ...    ",
00168 "   ..     ",
00169 "   .      ",
00170 "          ",
00171 "          "};
00172 
00173 
00174 void KoTabBarPrivate::layoutTabs()
00175 {
00176     tabRects.clear();
00177 
00178     QPainter painter( tabbar );
00179 
00180     QFont f = painter.font();
00181     f.setBold( true );
00182     painter.setFont( f );
00183     QFontMetrics fm = painter.fontMetrics();
00184     
00185     if( !reverseLayout )
00186     {
00187         // left to right
00188         int x = 0;
00189         for( unsigned c = 0; c < tabs.count(); c++ )
00190         {
00191             QRect rect;
00192             if( (int)c >= firstTab-1 )
00193             {
00194                 QString text = tabs[ c ];
00195                 int tw = fm.width( text ) + 4;
00196                 rect = QRect( x, 0, tw + 20, tabbar->height() );
00197                 x = x + tw + 10;
00198             }
00199             tabRects.append( rect );
00200         }
00201 
00202         lastTab = tabRects.count();
00203         for( unsigned i = 0; i < tabRects.count(); i++ )
00204             if( tabRects[i].right()-10+offset > tabbar->width() )
00205             {
00206                 lastTab = i;
00207                 break;
00208             }
00209     }
00210     else
00211     {
00212         // right to left
00213         int x = tabbar->width() - offset;
00214         for( unsigned c = 0; c < tabs.count(); c++ )
00215         {
00216             QRect rect;
00217             if( (int)c >= firstTab-1 )
00218             {
00219                 QString text = tabs[ c ];
00220                 int tw = fm.width( text ) + 4;
00221                 rect = QRect( x - tw - 20, 0, tw + 20, tabbar->height() );
00222                 x = x - tw - 10;
00223             }
00224             tabRects.append( rect );
00225         }
00226 
00227         lastTab = tabRects.count();
00228         for( unsigned i = 0; i < tabRects.count(); i++ )
00229             if( tabRects[i].right() < 0 )
00230             {
00231                 lastTab = i;
00232                 break;
00233             }
00234     }    
00235 }
00236 
00237 int KoTabBarPrivate::tabAt( const QPoint& pos )
00238 {
00239     for( unsigned i = 0; i < tabRects.count(); i++ )
00240     {
00241       QRect rect = tabRects[ i ];
00242       if( rect.isNull() ) continue;
00243       if( rect.contains( pos ) ) return i;
00244     }
00245 
00246     return -1; // not found
00247 }
00248 
00249 void KoTabBarPrivate::drawTab( QPainter& painter, QRect& rect, const QString& text, bool active )
00250 {
00251     QPointArray pa;
00252     pa.setPoints( 4, rect.x(), rect.y(), rect.x()+10, rect.bottom()-1,
00253       rect.right()-10, rect.bottom()-1, rect.right(), rect.top() );
00254 
00255     QColor bgcolor = tabbar->colorGroup().background();
00256     if( active ) bgcolor = tabbar->colorGroup().base();
00257 
00258     painter.setClipping( true );
00259     painter.setClipRegion( QRegion( pa ) );
00260     painter.setBackgroundColor( bgcolor );
00261     painter.eraseRect( rect );
00262     painter.setClipping( false );
00263 
00264     painter.drawLine( rect.x(), rect.y(), rect.x()+10, rect.bottom()-1 );
00265     painter.drawLine( rect.x()+10, rect.bottom()-1, rect.right()-10, rect.bottom()-1 );
00266     painter.drawLine( rect.right()-10, rect.bottom()-1, rect.right(), rect.top() );
00267     if( !active )
00268       painter.drawLine( rect.x(), rect.y(), rect.right(), rect.y() );
00269 
00270     painter.save();
00271     QFont f = painter.font();
00272     if( active ) f.setBold( true );
00273     painter.setFont( f );
00274     QFontMetrics fm = painter.fontMetrics();
00275     int tx =  rect.x() + ( rect.width() - fm.width( text ) ) / 2;
00276     int ty =  rect.y() + ( rect.height() - fm.height() ) / 2 + fm.ascent();
00277     painter.drawText( tx, ty, text );
00278     painter.restore();
00279 }
00280 
00281 void KoTabBarPrivate::drawMoveMarker( QPainter& painter, int x, int y )
00282 {
00283     QPointArray movmark;
00284     movmark.setPoints( 3, x, y, x + 7, y, x + 4, y + 6);
00285     QBrush oldBrush = painter.brush();
00286     painter.setBrush( Qt::black );
00287     painter.drawPolygon(movmark);
00288     painter.setBrush( oldBrush );
00289 }
00290 
00291 void KoTabBarPrivate::layoutButtons()
00292 {
00293     int bw = tabbar->height();
00294     int w = tabbar->width();
00295     offset = bw * 4;
00296     
00297     if( !reverseLayout )
00298     {
00299         scrollFirstButton->setGeometry( 0, 0, bw, bw );
00300         scrollFirstButton->setPixmap( arrow_leftmost_xpm );
00301         scrollBackButton->setGeometry( bw, 0, bw, bw );
00302         scrollBackButton->setPixmap( arrow_left_xpm );
00303         scrollForwardButton->setGeometry( bw*2, 0, bw, bw );
00304         scrollForwardButton->setPixmap( arrow_right_xpm );
00305         scrollLastButton->setGeometry( bw*3, 0, bw, bw );
00306         scrollLastButton->setPixmap( arrow_rightmost_xpm );
00307     }
00308     else
00309     {
00310         scrollFirstButton->setGeometry( w-bw, 0, bw, bw );
00311         scrollFirstButton->setPixmap( arrow_rightmost_xpm );
00312         scrollBackButton->setGeometry( w-2*bw, 0, bw, bw );
00313         scrollBackButton->setPixmap( arrow_right_xpm );
00314         scrollForwardButton->setGeometry( w-3*bw, 0, bw, bw );
00315         scrollForwardButton->setPixmap( arrow_left_xpm );
00316         scrollLastButton->setGeometry( w-4*bw, 0, bw, bw );
00317         scrollLastButton->setPixmap( arrow_leftmost_xpm );
00318     }
00319  }
00320 
00321 void KoTabBarPrivate::updateButtons()
00322 {
00323     scrollFirstButton->setEnabled( tabbar->canScrollBack() );
00324     scrollBackButton->setEnabled( tabbar->canScrollBack() );
00325     scrollForwardButton->setEnabled( tabbar->canScrollForward() );
00326     scrollLastButton->setEnabled( tabbar->canScrollForward() );
00327 }
00328 
00329 // creates a new tabbar
00330 KoTabBar::KoTabBar( QWidget* parent, const char* name )
00331     : QWidget( parent, name, Qt::WResizeNoErase | Qt::WRepaintNoErase )
00332 {
00333     d = new KoTabBarPrivate;
00334     d->tabbar = this;
00335     d->readOnly = false;
00336     d->reverseLayout = false;
00337     d->firstTab = 1;
00338     d->lastTab = 0;
00339     d->activeTab = 0;
00340     d->targetTab = 0;
00341     d->autoScroll = false;
00342     d->offset = 64;
00343 
00344     // initialize the scroll buttons
00345     d->scrollFirstButton = new QToolButton( this );
00346     connect( d->scrollFirstButton, SIGNAL( clicked() ),
00347       this, SLOT( scrollFirst() ) );
00348     d->scrollLastButton = new QToolButton( this );
00349     connect( d->scrollLastButton, SIGNAL( clicked() ),
00350       this, SLOT( scrollLast() ) );
00351     d->scrollBackButton = new QToolButton( this );
00352     connect( d->scrollBackButton, SIGNAL( clicked() ),
00353       this, SLOT( scrollBack() ) );
00354     d->scrollForwardButton = new QToolButton( this );
00355     connect( d->scrollForwardButton, SIGNAL( clicked() ),
00356       this, SLOT( scrollForward() ) );
00357     d->layoutButtons();
00358     d->updateButtons();
00359 }
00360 
00361 // destroys the tabbar
00362 KoTabBar::~KoTabBar()
00363 {
00364     delete d;
00365 }
00366 
00367 // adds a new visible tab
00368 void KoTabBar::addTab( const QString& text )
00369 {
00370     d->tabs.append( text );
00371 
00372     update();
00373 }
00374 
00375 // removes a tab
00376 void KoTabBar::removeTab( const QString& text )
00377 {
00378     int i = d->tabs.findIndex( text );
00379     if ( i == -1 ) return;
00380 
00381     if ( d->activeTab == i + 1 )
00382         d->activeTab = 0;
00383 
00384     d->tabs.remove( text );
00385 
00386     update();
00387 }
00388 
00389 // removes all tabs
00390 void KoTabBar::clear()
00391 {
00392     d->tabs.clear();
00393     d->activeTab = 0;
00394     d->firstTab = 1;
00395 
00396     update();
00397 }
00398 
00399 bool KoTabBar::readOnly() const
00400 {
00401     return d->readOnly;
00402 }
00403 
00404 void KoTabBar::setReadOnly( bool ro )
00405 {
00406     d->readOnly = ro;
00407 }
00408 
00409 bool KoTabBar::reverseLayout() const
00410 {
00411     return d->reverseLayout;
00412 }
00413 
00414 void KoTabBar::setReverseLayout( bool reverse )
00415 {
00416     if( reverse != d->reverseLayout )
00417     {
00418         d->reverseLayout = reverse;
00419         d->layoutTabs();
00420         d->layoutButtons();
00421         d->updateButtons();
00422         update();
00423     }
00424 }
00425 
00426 void KoTabBar::setTabs( const QStringList& list )
00427 {
00428     QString left, active;
00429 
00430     if( d->activeTab > 0 )
00431         active = d->tabs[ d->activeTab-1 ];
00432     if( d->firstTab > 0 )
00433         left = d->tabs[ d->firstTab-1 ];
00434 
00435     d->tabs = list;
00436 
00437     if( !left.isNull() )
00438     {
00439         d->firstTab = d->tabs.findIndex( left ) + 1;
00440         if( d->firstTab > (int)d->tabs.count() )
00441             d->firstTab = 1;
00442         if( d->firstTab <= 0 )
00443             d->firstTab = 1;
00444     }
00445 
00446     d->activeTab = 0;
00447     if( !active.isNull() )
00448         setActiveTab( active );
00449 
00450     update();
00451 }
00452 
00453 QStringList KoTabBar::tabs() const
00454 {
00455     return d->tabs;
00456 }
00457 
00458 unsigned KoTabBar::count() const
00459 {
00460     return d->tabs.count();
00461 }
00462 
00463 bool KoTabBar::canScrollBack() const
00464 {
00465     if ( d->tabs.count() == 0 )
00466         return false;
00467 
00468     return d->firstTab > 1;
00469 }
00470 
00471 bool KoTabBar::canScrollForward() const
00472 {
00473     if ( d->tabs.count() == 0 )
00474         return false;
00475         
00476     return d->lastTab < (int)d->tabs.count();
00477 }
00478 
00479 void KoTabBar::scrollBack()
00480 {
00481     if ( !canScrollBack() )
00482         return;
00483 
00484     d->firstTab--;
00485     if( d->firstTab < 1 ) d->firstTab = 1;
00486 
00487     d->layoutTabs();
00488     d->updateButtons();
00489     update();
00490 }
00491 
00492 void KoTabBar::scrollForward()
00493 {
00494     if ( !canScrollForward() )
00495         return;
00496 
00497     d->firstTab ++;
00498     if( d->firstTab > (int)d->tabs.count() )
00499         d->firstTab = d->tabs.count();
00500 
00501     d->layoutTabs();
00502     d->updateButtons();
00503     update();
00504 }
00505 
00506 void KoTabBar::scrollFirst()
00507 {
00508     if ( !canScrollBack() )
00509         return;
00510 
00511     d->firstTab = 1;
00512     d->layoutTabs();
00513     d->updateButtons();
00514     update();
00515 }
00516 
00517 void KoTabBar::scrollLast()
00518 {
00519     if ( !canScrollForward() )
00520         return;
00521 
00522     d->layoutTabs();
00523 
00524     if( !d->reverseLayout )
00525     {
00526         int fullWidth = d->tabRects[ d->tabRects.count()-1 ].right();
00527         int delta = fullWidth - width() + d->offset;
00528         for( unsigned i = 0; i < d->tabRects.count(); i++ )
00529             if( d->tabRects[i].x() > delta )
00530             {
00531                 d->firstTab = i+1;
00532                 break;
00533             }
00534     }
00535     else
00536     {
00537         // FIXME optimize this, perhaps without loop
00538         for( ; d->firstTab <= (int)d->tabRects.count();)
00539         {
00540             int x = d->tabRects[ d->tabRects.count()-1 ].x();
00541             if( x > 0 ) break;
00542             d->firstTab++;
00543             d->layoutTabs();
00544         }
00545     }
00546 
00547     d->layoutTabs();
00548     d->updateButtons();
00549     update();
00550 }
00551 
00552 void KoTabBar::moveTab( unsigned tab, unsigned target )
00553 {
00554     QString tabName = d->tabs[ tab ];
00555     QStringList::Iterator it;
00556 
00557     it = d->tabs.at( tab );
00558     d->tabs.remove( it );
00559 
00560     if( target > tab ) target--;
00561     it = d->tabs.at( target );
00562     if( target >= d->tabs.count() )
00563       it = d->tabs.end();
00564     d->tabs.insert( it, tabName );
00565 
00566     if( d->activeTab == (int)tab+1 )
00567         d->activeTab = target+1;
00568 
00569     update();
00570 }
00571 
00572 void KoTabBar::setActiveTab( const QString& text )
00573 {
00574     int i = d->tabs.findIndex( text );
00575     if ( i == -1 )
00576         return;
00577 
00578     if ( i + 1 == d->activeTab )
00579         return;
00580 
00581     d->activeTab = i + 1;
00582     d->updateButtons();
00583     update();
00584 
00585     emit tabChanged( text );
00586 }
00587 
00588 void KoTabBar::autoScrollBack()
00589 {
00590     if( !d->autoScroll ) return;
00591 
00592     scrollBack();
00593 
00594     if( !canScrollBack() )
00595         d->autoScroll = false;
00596     else
00597         QTimer::singleShot( 400, this, SLOT( autoScrollBack() ) );
00598 }
00599 
00600 void KoTabBar::autoScrollForward()
00601 {
00602     if( !d->autoScroll ) return;
00603 
00604     scrollForward();
00605 
00606     if( !canScrollForward() )
00607         d->autoScroll = false;
00608     else
00609         QTimer::singleShot( 400, this, SLOT( autoScrollForward() ) );
00610 }
00611 
00612 void KoTabBar::paintEvent( QPaintEvent* )
00613 {
00614     if ( d->tabs.count() == 0 )
00615     {
00616         erase();
00617         return;
00618     }
00619 
00620     QPainter painter;
00621     QPixmap pm( size() );
00622     pm.fill( colorGroup().background() );
00623     painter.begin( &pm, this );
00624 
00625     QBrush fill( colorGroup().brush( QColorGroup::Background ) );
00626     qDrawShadePanel( &painter, 0, 0, width(),
00627                      height(), colorGroup(), FALSE, 1, &fill );
00628 
00629     d->layoutTabs();
00630     d->updateButtons();
00631     
00632     // draw first all non-active, visible tabs
00633     for( unsigned c = 0; c < d->tabRects.count(); c++ )
00634     {
00635         QRect rect = d->tabRects[ c ];
00636         if( rect.isNull() ) continue;
00637         QString text = d->tabs[ c ];
00638         d->drawTab( painter, rect, text, false );
00639     }
00640 
00641     // draw the active tab
00642     if( d->activeTab > 0 )
00643     {
00644         QRect rect = d->tabRects[ d->activeTab-1 ];
00645         if( !rect.isNull() )
00646         {
00647             QString text = d->tabs[ d->activeTab-1 ];
00648             d->drawTab( painter, rect, text, true );
00649         }
00650     }
00651 
00652     // draw the move marker
00653     if( d->targetTab > 0 )
00654     {
00655         int p = QMIN( d->targetTab, (int)d->tabRects.count() );
00656         QRect rect = d->tabRects[ p-1 ];
00657         if( !rect.isNull() )
00658         {
00659             int x = !d->reverseLayout ? rect.x() : rect.right()-7;
00660             if( d->targetTab > (int)d->tabRects.count() )
00661               x = !d->reverseLayout ? rect.right()-7 : rect.x()-3;
00662             d->drawMoveMarker( painter, x, rect.y() );
00663         }
00664     }
00665 
00666     painter.end();
00667     
00668     if( !d->reverseLayout )
00669          bitBlt( this, d->offset, 0, &pm );
00670     else
00671          bitBlt( this, 0, 0, &pm );
00672 
00673 }
00674 
00675 void KoTabBar::resizeEvent( QResizeEvent* )
00676 {
00677     d->layoutButtons();
00678     d->updateButtons();
00679     update();
00680 }
00681 
00682 QSize KoTabBar::sizeHint() const
00683 {
00684     return QSize( 40, style().pixelMetric( QStyle::PM_ScrollBarExtent, this ) );
00685 }
00686 
00687 void KoTabBar::renameTab( const QString& old_name, const QString& new_name )
00688 {
00689     QStringList::Iterator it = d->tabs.find( old_name );
00690     (*it) = new_name;
00691 
00692     update();
00693 }
00694 
00695 QString KoTabBar::activeTab() const
00696 {
00697     if( d->activeTab == 0 )
00698         return QString::null;
00699     else
00700         return d->tabs[ d->activeTab ];
00701 }
00702 
00703 void KoTabBar::mousePressEvent( QMouseEvent* ev )
00704 {
00705     if ( d->tabs.count() == 0 )
00706     {
00707         erase();
00708         return;
00709     }
00710 
00711     d->layoutTabs();
00712 
00713     QPoint pos = ev->pos();
00714     if( !d->reverseLayout ) pos = pos - QPoint( d->offset,0 );
00715     
00716     int tab = d->tabAt( pos ) + 1;
00717     if( ( tab > 0 ) && ( tab != d->activeTab ) )
00718     {
00719         d->activeTab = tab;
00720         update();
00721 
00722         emit tabChanged( d->tabs[ d->activeTab-1] );
00723 
00724         // scroll if partially visible
00725         if( d->tabRects[ tab-1 ].right() > width() - d->offset )
00726             scrollForward();
00727     }
00728 
00729     if( ev->button() == RightButton )
00730     if( !d->readOnly )
00731         emit contextMenu( ev->globalPos() );
00732 }
00733 
00734 void KoTabBar::mouseReleaseEvent( QMouseEvent* ev )
00735 {
00736     if ( d->readOnly ) return;
00737 
00738     d->autoScroll = false;
00739 
00740     if ( ev->button() == LeftButton && d->targetTab != 0 )
00741     {
00742         emit tabMoved( d->activeTab-1, d->targetTab-1 );
00743         d->targetTab = 0;
00744     }
00745 }
00746 
00747 void KoTabBar::mouseMoveEvent( QMouseEvent* ev )
00748 {
00749     if ( d->readOnly ) return;
00750 
00751     QPoint pos = ev->pos();
00752     if( !d->reverseLayout) pos = pos - QPoint( d->offset,0 );
00753     
00754     // check if user drags a tab to move it
00755     int i = d->tabAt( pos ) + 1;
00756     if( ( i > 0 ) && ( i != d->targetTab ) )
00757     {
00758         if( i == d->activeTab ) i = 0;
00759         if( i == d->activeTab+1 ) i = 0;
00760 
00761         if( i != d->targetTab )
00762         {
00763            d->targetTab = i;
00764            d->autoScroll = false;
00765            update();
00766         }
00767     }
00768 
00769     // drag past the very latest visible tab
00770     // e.g move a tab to the last ordering position
00771     QRect r = d->tabRects[ d->tabRects.count()-1 ];
00772     bool moveToLast = false;
00773     if( r.isValid() )
00774     {
00775         if( !d->reverseLayout )
00776         if( pos.x() > r.right() )
00777         if( pos.x() < width() )
00778             moveToLast = true;
00779         if( d->reverseLayout )
00780         if( pos.x() < r.x() )
00781         if( pos.x() > 0 )
00782             moveToLast = true;
00783     }
00784     if( moveToLast )
00785     if( d->targetTab != (int)d->tabRects.count()+1 )
00786     {
00787         d->targetTab = d->tabRects.count()+1;
00788         d->autoScroll = false;
00789         update();
00790     }
00791 
00792     // outside far too left ? activate autoscroll...
00793     if ( pos.x() < 0 && !d->autoScroll  )
00794     {
00795         d->autoScroll = true;
00796         autoScrollBack();
00797     }
00798 
00799     // outside far too right ? activate autoscroll...
00800     int w = width() - d->offset;
00801     if ( pos.x() > w && !d->autoScroll )
00802     {
00803         d->autoScroll = true;
00804         autoScrollForward();
00805     }
00806 }
00807 
00808 void KoTabBar::mouseDoubleClickEvent( QMouseEvent* ev )
00809 {
00810     int offset = d->reverseLayout ? 0 : d->offset;
00811     if( ev->pos().x() > offset )
00812     if( !d->readOnly )
00813         emit doubleClicked();
00814 }
00815 
00816 
00817 #include "kotabbar.moc"
KDE Logo
This file is part of the documentation for lib Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:40:08 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003