diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /lib/kofficeui/KoTabBar.cpp | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/kofficeui/KoTabBar.cpp')
-rw-r--r-- | lib/kofficeui/KoTabBar.cpp | 913 |
1 files changed, 913 insertions, 0 deletions
diff --git a/lib/kofficeui/KoTabBar.cpp b/lib/kofficeui/KoTabBar.cpp new file mode 100644 index 00000000..d73025b4 --- /dev/null +++ b/lib/kofficeui/KoTabBar.cpp @@ -0,0 +1,913 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Ariya Hidayat <ariya@kde.org> + Copyright (C) 2003 Norbert Andres <nandres@web.de> + Copyright (C) 2002 Laurent Montel <montel@kde.org> + Copyright (C) 1999 David Faure <faure@kde.org> + Copyright (C) 1999 Boris Wedl <boris.wedl@kfunigraz.ac.at> + Copyright (C) 1998-2000 Torben Weis <weis@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "KoTabBar.h" + +#include <qdrawutil.h> +#include <qpainter.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qstyle.h> +#include <qtimer.h> +#include <qtoolbutton.h> +#include <qvaluevector.h> +#include <qwidget.h> + +// TODO +// improvement possibilities +// - use offscreen buffer to reduce flicker even more +// - keep track of tabs, only (re)layout when necessary +// - paint all tabs to buffer, show only by shifting +// - customizable button pixmaps +// - use QStyle to paint the tabs & buttons (is it good/possible?) + + +class KoTabBarPrivate +{ +public: + KoTabBar* tabbar; + + // scroll buttons + QToolButton* scrollFirstButton; + QToolButton* scrollLastButton; + QToolButton* scrollBackButton; + QToolButton* scrollForwardButton; + + // read-only: no mouse drag, double-click, right-click + bool readOnly; + + // if true, layout is from right to left + bool reverseLayout; + + // list of all tabs, in order of appearance + QStringList tabs; + + // array of QRect for each visible tabs + QValueVector<QRect> tabRects; + + // leftmost tab (or rightmost if reverseLayout) + int firstTab; + + // rightmost tab (or leftmost if reverseLayout) + int lastTab; + + // the active tab in the range form 1..n. + // if this value is 0, that means that no tab is active. + int activeTab; + + // unusable space on the left, taken by the scroll buttons + int offset; + + // when the user drag the tab (in order to move it) + // this is the target position, it's 0 if no tab is dragged + int targetTab; + + // wheel movement since selected tab was last changed by the + // mouse wheel + int wheelDelta; + + // true if autoscroll is active + bool autoScroll; + + // calculate the bounding rectangle for each visible tab + void layoutTabs(); + + // reposition scroll buttons + void layoutButtons(); + + // find a tab whose bounding rectangle contains the pos + // return -1 if no such tab is found + int tabAt( const QPoint& pos ); + + // draw a single tab + void drawTab( QPainter& painter, QRect& rect, const QString& text, bool active ); + + // draw a marker to indicate tab moving + void drawMoveMarker( QPainter& painter, int x, int y ); + + // update the enable/disable status of scroll buttons + void updateButtons(); + +}; + +// built-in pixmap for scroll-first button +static const char * arrow_leftmost_xpm[] = { +"10 10 2 1", +" c None", +". c #000000", +" ", +" . . ", +" . .. ", +" . ... ", +" . .... ", +" . ... ", +" . .. ", +" . . ", +" ", +" "}; + +// built-in pixmap for scroll-last button +static const char * arrow_rightmost_xpm[] = { +"10 10 2 1", +" c None", +". c #000000", +" ", +" . . ", +" .. . ", +" ... . ", +" .... . ", +" ... . ", +" .. . ", +" . . ", +" ", +" "}; + +// built-in pixmap for scroll-left button +static const char * arrow_left_xpm[] = { +"10 10 2 1", +" c None", +". c #000000", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ... ", +" .. ", +" . ", +" ", +" "}; + +// built-in pixmap for scroll-right button +static const char * arrow_right_xpm[] = { +"10 10 2 1", +" c None", +". c #000000", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ... ", +" .. ", +" . ", +" ", +" "}; + + +void KoTabBarPrivate::layoutTabs() +{ + tabRects.clear(); + + QPainter painter( tabbar ); + + QFont f = painter.font(); + f.setBold( true ); + painter.setFont( f ); + QFontMetrics fm = painter.fontMetrics(); + + if( !reverseLayout ) + { + // left to right + int x = 0; + for( unsigned c = 0; c < tabs.count(); c++ ) + { + QRect rect; + if( (int)c >= firstTab-1 ) + { + QString text = tabs[ c ]; + int tw = fm.width( text ) + 4; + rect = QRect( x, 0, tw + 20, tabbar->height() ); + x = x + tw + 20; + } + tabRects.append( rect ); + } + + lastTab = tabRects.count(); + for( unsigned i = 0; i < tabRects.count(); i++ ) + if( tabRects[i].right()-10+offset > tabbar->width() ) + { + lastTab = i; + break; + } + } + else + { + // right to left + int x = tabbar->width() - offset; + for( unsigned c = 0; c < tabs.count(); c++ ) + { + QRect rect; + if( (int)c >= firstTab-1 ) + { + QString text = tabs[ c ]; + int tw = fm.width( text ) + 4; + rect = QRect( x - tw - 20, 0, tw + 20, tabbar->height() ); + x = x - tw - 20; + } + tabRects.append( rect ); + } + + lastTab = tabRects.count(); + for( unsigned i = tabRects.count()-1; i>0; i-- ) + if( tabRects[i].left() > 0 ) + { + lastTab = i+1; + break; + } + } +} + +int KoTabBarPrivate::tabAt( const QPoint& pos ) +{ + for( unsigned i = 0; i < tabRects.count(); i++ ) + { + QRect rect = tabRects[ i ]; + if( rect.isNull() ) continue; + if( rect.contains( pos ) ) return i; + } + + return -1; // not found +} + +void KoTabBarPrivate::drawTab( QPainter& painter, QRect& rect, const QString& text, bool active ) +{ + QPointArray polygon; + + if( !reverseLayout ) + polygon.setPoints( 6, rect.x(), rect.y(), + rect.x(), rect.bottom()-3, + rect.x()+2, rect.bottom(), + rect.right()-4, rect.bottom(), + rect.right()-2, rect.bottom()-2, + rect.right()+5, rect.top() ); + else + polygon.setPoints( 6, rect.right(), rect.top(), + rect.right(), rect.bottom()-3, + rect.right()-2, rect.bottom(), + rect.x()+4, rect.bottom(), + rect.x()+2, rect.bottom()-2, + rect.x()-5, rect.top() ); + + painter.save(); + + // fill it first + QBrush bg = tabbar->colorGroup().background(); + if( active ) bg = tabbar->colorGroup().base(); + painter.setBrush( bg ); + painter.setPen( QPen( Qt::NoPen ) ); + painter.drawPolygon( polygon ); + + // draw the lines + painter.setPen( tabbar->colorGroup().dark() ); + if( !active ) + painter.drawLine( rect.x()-25, rect.y(), rect.right()+25, rect.top() ); + // Qt4: painter.setRenderHint( QPainter::Antialiasing ); + painter.drawPolyline( polygon ); + + painter.setPen( tabbar->colorGroup().buttonText() ); + QFont f = painter.font(); + if( active ) f.setBold( true ); + painter.setFont( f ); + QFontMetrics fm = painter.fontMetrics(); + int tx = rect.x() + ( rect.width() - fm.width( text ) ) / 2; + int ty = rect.y() + ( rect.height() - fm.height() ) / 2 + fm.ascent(); + painter.drawText( tx, ty, text ); + + painter.restore(); +} + +void KoTabBarPrivate::drawMoveMarker( QPainter& painter, int x, int y ) +{ + QPointArray movmark; + movmark.setPoints( 3, x, y, x + 7, y, x + 4, y + 6); + QBrush oldBrush = painter.brush(); + painter.setBrush( Qt::black ); + painter.drawPolygon(movmark); + painter.setBrush( oldBrush ); +} + +void KoTabBarPrivate::layoutButtons() +{ + int bw = tabbar->height(); + int w = tabbar->width(); + offset = bw * 4; + + if( !reverseLayout ) + { + scrollFirstButton->setGeometry( 0, 0, bw, bw ); + scrollFirstButton->setPixmap( arrow_leftmost_xpm ); + scrollBackButton->setGeometry( bw, 0, bw, bw ); + scrollBackButton->setPixmap( arrow_left_xpm ); + scrollForwardButton->setGeometry( bw*2, 0, bw, bw ); + scrollForwardButton->setPixmap( arrow_right_xpm ); + scrollLastButton->setGeometry( bw*3, 0, bw, bw ); + scrollLastButton->setPixmap( arrow_rightmost_xpm ); + } + else + { + scrollFirstButton->setGeometry( w-bw, 0, bw, bw ); + scrollFirstButton->setPixmap( arrow_rightmost_xpm ); + scrollBackButton->setGeometry( w-2*bw, 0, bw, bw ); + scrollBackButton->setPixmap( arrow_right_xpm ); + scrollForwardButton->setGeometry( w-3*bw, 0, bw, bw ); + scrollForwardButton->setPixmap( arrow_left_xpm ); + scrollLastButton->setGeometry( w-4*bw, 0, bw, bw ); + scrollLastButton->setPixmap( arrow_leftmost_xpm ); + } + } + +void KoTabBarPrivate::updateButtons() +{ + scrollFirstButton->setEnabled( tabbar->canScrollBack() ); + scrollBackButton->setEnabled( tabbar->canScrollBack() ); + scrollForwardButton->setEnabled( tabbar->canScrollForward() ); + scrollLastButton->setEnabled( tabbar->canScrollForward() ); +} + +// creates a new tabbar +KoTabBar::KoTabBar( QWidget* parent, const char* name ) + : QWidget( parent, name, Qt::WResizeNoErase | Qt::WRepaintNoErase ) +{ + d = new KoTabBarPrivate; + d->tabbar = this; + d->readOnly = false; + d->reverseLayout = false; + d->firstTab = 1; + d->lastTab = 0; + d->activeTab = 0; + d->targetTab = 0; + d->wheelDelta = 0; + d->autoScroll = false; + d->offset = 64; + + // initialize the scroll buttons + d->scrollFirstButton = new QToolButton( this ); + connect( d->scrollFirstButton, SIGNAL( clicked() ), + this, SLOT( scrollFirst() ) ); + d->scrollLastButton = new QToolButton( this ); + connect( d->scrollLastButton, SIGNAL( clicked() ), + this, SLOT( scrollLast() ) ); + d->scrollBackButton = new QToolButton( this ); + connect( d->scrollBackButton, SIGNAL( clicked() ), + this, SLOT( scrollBack() ) ); + d->scrollForwardButton = new QToolButton( this ); + connect( d->scrollForwardButton, SIGNAL( clicked() ), + this, SLOT( scrollForward() ) ); + d->layoutButtons(); + d->updateButtons(); +} + +// destroys the tabbar +KoTabBar::~KoTabBar() +{ + delete d; +} + +// adds a new visible tab +void KoTabBar::addTab( const QString& text ) +{ + d->tabs.append( text ); + + update(); +} + +// removes a tab +void KoTabBar::removeTab( const QString& text ) +{ + int i = d->tabs.findIndex( text ); + if ( i == -1 ) return; + + if ( d->activeTab == i + 1 ) + d->activeTab = 0; + + d->tabs.remove( text ); + + update(); +} + +// removes all tabs +void KoTabBar::clear() +{ + d->tabs.clear(); + d->activeTab = 0; + d->firstTab = 1; + + update(); +} + +bool KoTabBar::readOnly() const +{ + return d->readOnly; +} + +void KoTabBar::setReadOnly( bool ro ) +{ + d->readOnly = ro; +} + +bool KoTabBar::reverseLayout() const +{ + return d->reverseLayout; +} + +void KoTabBar::setReverseLayout( bool reverse ) +{ + if( reverse != d->reverseLayout ) + { + d->reverseLayout = reverse; + d->layoutTabs(); + d->layoutButtons(); + d->updateButtons(); + update(); + } +} + +void KoTabBar::setTabs( const QStringList& list ) +{ + QString left, active; + + if( d->activeTab > 0 ) + active = d->tabs[ d->activeTab-1 ]; + if( d->firstTab > 0 ) + left = d->tabs[ d->firstTab-1 ]; + + d->tabs = list; + + if( !left.isNull() ) + { + d->firstTab = d->tabs.findIndex( left ) + 1; + if( d->firstTab > (int)d->tabs.count() ) + d->firstTab = 1; + if( d->firstTab <= 0 ) + d->firstTab = 1; + } + + d->activeTab = 0; + if( !active.isNull() ) + setActiveTab( active ); + + update(); +} + +QStringList KoTabBar::tabs() const +{ + return d->tabs; +} + +unsigned KoTabBar::count() const +{ + return d->tabs.count(); +} + +bool KoTabBar::canScrollBack() const +{ + if ( d->tabs.count() == 0 ) + return false; + + return d->firstTab > 1; +} + +bool KoTabBar::canScrollForward() const +{ + if ( d->tabs.count() == 0 ) + return false; + + return d->lastTab < (int)d->tabs.count(); +} + +void KoTabBar::scrollBack() +{ + if ( !canScrollBack() ) + return; + + d->firstTab--; + if( d->firstTab < 1 ) d->firstTab = 1; + + d->layoutTabs(); + d->updateButtons(); + update(); +} + +void KoTabBar::scrollForward() +{ + if ( !canScrollForward() ) + return; + + d->firstTab ++; + if( d->firstTab > (int)d->tabs.count() ) + d->firstTab = d->tabs.count(); + + d->layoutTabs(); + d->updateButtons(); + update(); +} + +void KoTabBar::scrollFirst() +{ + if ( !canScrollBack() ) + return; + + d->firstTab = 1; + d->layoutTabs(); + d->updateButtons(); + update(); +} + +void KoTabBar::scrollLast() +{ + if ( !canScrollForward() ) + return; + + d->layoutTabs(); + + if( !d->reverseLayout ) + { + int fullWidth = d->tabRects[ d->tabRects.count()-1 ].right(); + int delta = fullWidth - width() + d->offset; + for( unsigned i = 0; i < d->tabRects.count(); i++ ) + if( d->tabRects[i].x() > delta ) + { + d->firstTab = i+1; + break; + } + } + else + { + // FIXME optimize this, perhaps without loop + for( ; d->firstTab <= (int)d->tabRects.count();) + { + int x = d->tabRects[ d->tabRects.count()-1 ].x(); + if( x > 0 ) break; + d->firstTab++; + d->layoutTabs(); + } + } + + d->layoutTabs(); + d->updateButtons(); + update(); +} + +void KoTabBar::ensureVisible( const QString& tab ) +{ + int i = d->tabs.findIndex( tab ); + if ( i == -1 ) + return; + i++; + + // already visible, then do nothing + if( ( i >= d->firstTab ) && ( i <= d->lastTab ) ) + return; + + if( i < d->firstTab ) + while( i < d->firstTab ) + scrollBack(); + + if( i > d->lastTab ) + while( i > d->lastTab ) + scrollForward(); +} + +void KoTabBar::moveTab( unsigned tab, unsigned target ) +{ + QString tabName = d->tabs[ tab ]; + QStringList::Iterator it; + + it = d->tabs.at( tab ); + d->tabs.remove( it ); + + if( target > tab ) target--; + it = d->tabs.at( target ); + if( target >= d->tabs.count() ) + it = d->tabs.end(); + d->tabs.insert( it, tabName ); + + if( d->activeTab == (int)tab+1 ) + d->activeTab = target+1; + + update(); +} + +void KoTabBar::setActiveTab( const QString& text ) +{ + int i = d->tabs.findIndex( text ); + if ( i == -1 ) + return; + + if ( i + 1 == d->activeTab ) + return; + + d->activeTab = i + 1; + d->updateButtons(); + update(); + + emit tabChanged( text ); +} + +void KoTabBar::autoScrollBack() +{ + if( !d->autoScroll ) return; + + scrollBack(); + + if( !canScrollBack() ) + d->autoScroll = false; + else + QTimer::singleShot( 400, this, SLOT( autoScrollBack() ) ); +} + +void KoTabBar::autoScrollForward() +{ + if( !d->autoScroll ) return; + + scrollForward(); + + if( !canScrollForward() ) + d->autoScroll = false; + else + QTimer::singleShot( 400, this, SLOT( autoScrollForward() ) ); +} + +void KoTabBar::paintEvent( QPaintEvent* ) +{ + if ( d->tabs.count() == 0 ) + { + erase(); + return; + } + + QPainter painter; + QPixmap pm( size() ); + pm.fill( colorGroup().background() ); + painter.begin( &pm, this ); + + painter.setPen( colorGroup().dark() ); + painter.drawLine( 0, 0, width(), 0 ); + + if( !d->reverseLayout ) + painter.translate( 5, 0 ); + + d->layoutTabs(); + d->updateButtons(); + + // draw first all non-active, visible tabs + for( int c = d->tabRects.count()-1; c>=0; c-- ) + { + QRect rect = d->tabRects[ c ]; + if( rect.isNull() ) continue; + QString text = d->tabs[ c ]; + d->drawTab( painter, rect, text, false ); + } + + // draw the active tab + if( d->activeTab > 0 ) + { + QRect rect = d->tabRects[ d->activeTab-1 ]; + if( !rect.isNull() ) + { + QString text = d->tabs[ d->activeTab-1 ]; + d->drawTab( painter, rect, text, true ); + } + } + + // draw the move marker + if( d->targetTab > 0 ) + { + int p = QMIN( d->targetTab, (int)d->tabRects.count() ); + QRect rect = d->tabRects[ p-1 ]; + if( !rect.isNull() ) + { + int x = !d->reverseLayout ? rect.x() : rect.right()-7; + if( d->targetTab > (int)d->tabRects.count() ) + x = !d->reverseLayout ? rect.right()-7 : rect.x()-3; + d->drawMoveMarker( painter, x, rect.y() ); + } + } + + painter.end(); + + if( !d->reverseLayout ) + bitBlt( this, d->offset, 0, &pm ); + else + bitBlt( this, 0, 0, &pm ); + +} + +void KoTabBar::resizeEvent( QResizeEvent* ) +{ + d->layoutButtons(); + d->updateButtons(); + update(); +} + +QSize KoTabBar::sizeHint() const +{ + return QSize( 40, style().pixelMetric( QStyle::PM_ScrollBarExtent, this ) ); +} + +void KoTabBar::renameTab( const QString& old_name, const QString& new_name ) +{ + QStringList::Iterator it = d->tabs.find( old_name ); + (*it) = new_name; + + update(); +} + +QString KoTabBar::activeTab() const +{ + if( d->activeTab == 0 ) + return QString::null; + else + return d->tabs[ d->activeTab ]; +} + +void KoTabBar::mousePressEvent( QMouseEvent* ev ) +{ + if ( d->tabs.count() == 0 ) + { + erase(); + return; + } + + d->layoutTabs(); + + QPoint pos = ev->pos(); + if( !d->reverseLayout ) pos = pos - QPoint( d->offset,0 ); + + int tab = d->tabAt( pos ) + 1; + if( ( tab > 0 ) && ( tab != d->activeTab ) ) + { + d->activeTab = tab; + update(); + + emit tabChanged( d->tabs[ d->activeTab-1] ); + + // scroll if partially visible + if( d->tabRects[ tab-1 ].right() > width() - d->offset ) + scrollForward(); + } + + if( ev->button() == RightButton ) + if( !d->readOnly ) + emit contextMenu( ev->globalPos() ); +} + +void KoTabBar::mouseReleaseEvent( QMouseEvent* ev ) +{ + if ( d->readOnly ) return; + + d->autoScroll = false; + + if ( ev->button() == LeftButton && d->targetTab != 0 ) + { + emit tabMoved( d->activeTab-1, d->targetTab-1 ); + d->targetTab = 0; + } +} + +void KoTabBar::mouseMoveEvent( QMouseEvent* ev ) +{ + if ( d->readOnly ) return; + + QPoint pos = ev->pos(); + if( !d->reverseLayout) pos = pos - QPoint( d->offset,0 ); + + // check if user drags a tab to move it + int i = d->tabAt( pos ) + 1; + if( ( i > 0 ) && ( i != d->targetTab ) ) + { + if( i == d->activeTab ) i = 0; + if( i == d->activeTab+1 ) i = 0; + + if( i != d->targetTab ) + { + d->targetTab = i; + d->autoScroll = false; + update(); + } + } + + // drag past the very latest visible tab + // e.g move a tab to the last ordering position + QRect r = d->tabRects[ d->tabRects.count()-1 ]; + bool moveToLast = false; + if( r.isValid() ) + { + if( !d->reverseLayout ) + if( pos.x() > r.right() ) + if( pos.x() < width() ) + moveToLast = true; + if( d->reverseLayout ) + if( pos.x() < r.x() ) + if( pos.x() > 0 ) + moveToLast = true; + } + if( moveToLast ) + if( d->targetTab != (int)d->tabRects.count()+1 ) + { + d->targetTab = d->tabRects.count()+1; + d->autoScroll = false; + update(); + } + + // outside far too left ? activate autoscroll... + if ( pos.x() < 0 && !d->autoScroll ) + { + d->autoScroll = true; + autoScrollBack(); + } + + // outside far too right ? activate autoscroll... + int w = width() - d->offset; + if ( pos.x() > w && !d->autoScroll ) + { + d->autoScroll = true; + autoScrollForward(); + } +} + +void KoTabBar::mouseDoubleClickEvent( QMouseEvent* ev ) +{ + int offset = d->reverseLayout ? 0 : d->offset; + if( ev->pos().x() > offset ) + if( !d->readOnly ) + emit doubleClicked(); +} + +void KoTabBar::wheelEvent( QWheelEvent * e ) +{ + if ( d->tabs.count() == 0 ) + { + erase(); + return; + } + + // Currently one wheel movement is a delta of 120. + // The 'unused' delta is stored for devices that allow + // a higher scrolling resolution. + // The delta required to move one tab is one wheel movement: + const int deltaRequired = 120; + + d->wheelDelta += e->delta(); + int tabDelta = - (d->wheelDelta / deltaRequired); + d->wheelDelta = d->wheelDelta % deltaRequired; + int numTabs = d->tabs.size(); + + if(d->activeTab + tabDelta > numTabs) + { + // Would take us past the last tab + d->activeTab = numTabs; + } + else if (d->activeTab + tabDelta < 1) + { + // Would take us before the first tab + d->activeTab = 1; + } + else + { + d->activeTab = d->activeTab + tabDelta; + } + + // Find the left and right edge of the new tab. If we're + // going forward, and the right of the new tab isn't visible + // then scroll forward. Likewise, if going back, and the + // left of the new tab isn't visible, then scroll back. + int activeTabRight = d->tabRects[ d->activeTab-1 ].right(); + int activeTabLeft = d->tabRects[ d->activeTab-1 ].left(); + if(tabDelta > 0 && activeTabRight > width() - d->offset ) + { + scrollForward(); + } + else if(tabDelta < 0 && activeTabLeft < width() - d->offset ) + { + scrollBack(); + } + + update(); + emit tabChanged( d->tabs[ d->activeTab-1] ); +} + + +#include "KoTabBar.moc" |