diff options
Diffstat (limited to 'lib/compatibility/kmdi/qextmdi/ktabbar.cpp')
-rw-r--r-- | lib/compatibility/kmdi/qextmdi/ktabbar.cpp | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/lib/compatibility/kmdi/qextmdi/ktabbar.cpp b/lib/compatibility/kmdi/qextmdi/ktabbar.cpp new file mode 100644 index 00000000..d8ee58cd --- /dev/null +++ b/lib/compatibility/kmdi/qextmdi/ktabbar.cpp @@ -0,0 +1,426 @@ +/* This file is part of the KDE libraries + Copyright (C) 2003 Stephan Binner <binner@kde.org> + Copyright (C) 2003 Zack Rusin <zack@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 <qapplication.h> +#include <qcursor.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qtimer.h> +#include <qpushbutton.h> +#include <qtooltip.h> + +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klocale.h> + +#include "ktabbar.h" +#include "ktabwidget.h" + +KTabBar::KTabBar( QWidget *parent, const char *name ) + : QTabBar( parent, name ), mReorderStartTab( -1 ), mReorderPreviousTab( -1 ), + mHoverCloseButtonTab( 0 ), mDragSwitchTab( 0 ), mHoverCloseButton( 0 ), + mHoverCloseButtonEnabled( false ), mHoverCloseButtonDelayed( true ), + mTabReorderingEnabled( false ), mTabCloseActivatePrevious( false ) +{ + setAcceptDrops( true ); + setMouseTracking( true ); + + mEnableCloseButtonTimer = new QTimer( this ); + connect( mEnableCloseButtonTimer, SIGNAL( timeout() ), SLOT( enableCloseButton() ) ); + + mActivateDragSwitchTabTimer = new QTimer( this ); + connect( mActivateDragSwitchTabTimer, SIGNAL( timeout() ), SLOT( activateDragSwitchTab() ) ); + + connect(this, SIGNAL(layoutChanged()), SLOT(onLayoutChange())); +} + +KTabBar::~KTabBar() +{ + //For the future + //delete d; +} + +void KTabBar::setTabEnabled( int id, bool enabled ) +{ + QTab * t = tab( id ); + if ( t ) { + if ( t->isEnabled() != enabled ) { + t->setEnabled( enabled ); + QRect r( t->rect() ); + if ( !enabled && id == currentTab() && count()>1 ) { + QPtrList<QTab> *tablist = tabList(); + if ( mTabCloseActivatePrevious ) + t = tablist->at( count()-2 ); + else { + int index = indexOf( id ); + index += ( index+1 == count() ) ? -1 : 1; + t = tabAt( index ); + } + + if ( t->isEnabled() ) { + r = r.unite( t->rect() ); + tablist->append( tablist->take( tablist->findRef( t ) ) ); + emit selected( t->identifier() ); + } + } + repaint( r ); + } + } +} + +void KTabBar::mouseDoubleClickEvent( QMouseEvent *e ) +{ + if( e->button() != LeftButton ) + return; + + QTab *tab = selectTab( e->pos() ); + if( tab ) { + emit( mouseDoubleClick( indexOf( tab->identifier() ) ) ); + return; + } + QTabBar::mouseDoubleClickEvent( e ); +} + +void KTabBar::mousePressEvent( QMouseEvent *e ) +{ + if( e->button() == LeftButton ) { + mEnableCloseButtonTimer->stop(); + mDragStart = e->pos(); + } + else if( e->button() == RightButton ) { + QTab *tab = selectTab( e->pos() ); + if( tab ) { + emit( contextMenu( indexOf( tab->identifier() ), mapToGlobal( e->pos() ) ) ); + return; + } + } + QTabBar::mousePressEvent( e ); +} + +void KTabBar::mouseMoveEvent( QMouseEvent *e ) +{ + if ( e->state() == LeftButton ) { + QTab *tab = selectTab( e->pos() ); + if ( mDragSwitchTab && tab != mDragSwitchTab ) { + mActivateDragSwitchTabTimer->stop(); + mDragSwitchTab = 0; + } + + int delay = KGlobalSettings::dndEventDelay(); + QPoint newPos = e->pos(); + if( newPos.x() > mDragStart.x()+delay || newPos.x() < mDragStart.x()-delay || + newPos.y() > mDragStart.y()+delay || newPos.y() < mDragStart.y()-delay ) + { + if( tab ) { + emit( initiateDrag( indexOf( tab->identifier() ) ) ); + return; + } + } + } + else if ( e->state() == MidButton ) { + if (mReorderStartTab==-1) { + int delay = KGlobalSettings::dndEventDelay(); + QPoint newPos = e->pos(); + if( newPos.x() > mDragStart.x()+delay || newPos.x() < mDragStart.x()-delay || + newPos.y() > mDragStart.y()+delay || newPos.y() < mDragStart.y()-delay ) + { + QTab *tab = selectTab( e->pos() ); + if( tab && mTabReorderingEnabled ) { + mReorderStartTab = indexOf( tab->identifier() ); + grabMouse( sizeAllCursor ); + return; + } + } + } + else { + QTab *tab = selectTab( e->pos() ); + if( tab ) { + int reorderStopTab = indexOf( tab->identifier() ); + if ( mReorderStartTab!=reorderStopTab && mReorderPreviousTab!=reorderStopTab ) { + emit( moveTab( mReorderStartTab, reorderStopTab ) ); + mReorderPreviousTab=mReorderStartTab; + mReorderStartTab=reorderStopTab; + return; + } + } + } + } + + if ( mHoverCloseButtonEnabled && mReorderStartTab==-1) { + QTab *t = selectTab( e->pos() ); + if( t && t->iconSet() && t->isEnabled() ) { + QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ); + QRect rect( 0, 0, pixmap.width() + 4, pixmap.height() +4); + + int xoff = 0, yoff = 0; + // The additional offsets were found by try and error, TODO: find the rational behind them + if ( t == tab( currentTab() ) ) { + xoff = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal, this ) + 3; + yoff = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical, this ) - 4; + } + else { + xoff = 7; + yoff = 0; + } + rect.moveLeft( t->rect().left() + 2 + xoff ); + rect.moveTop( t->rect().center().y()-pixmap.height()/2 + yoff ); + if ( rect.contains( e->pos() ) ) { + if ( mHoverCloseButton ) { + if ( mHoverCloseButtonTab == t ) + return; + mEnableCloseButtonTimer->stop(); + delete mHoverCloseButton; + } + + mHoverCloseButton = new QPushButton( this ); + mHoverCloseButton->setIconSet( KGlobal::iconLoader()->loadIconSet("fileclose", KIcon::Toolbar, KIcon::SizeSmall) ); + mHoverCloseButton->setGeometry( rect ); + QToolTip::add(mHoverCloseButton,i18n("Close this tab")); + mHoverCloseButton->setFlat(true); + mHoverCloseButton->show(); + if ( mHoverCloseButtonDelayed ) { + mHoverCloseButton->setEnabled(false); + mEnableCloseButtonTimer->start( QApplication::doubleClickInterval(), true ); + } + mHoverCloseButtonTab = t; + connect( mHoverCloseButton, SIGNAL( clicked() ), SLOT( closeButtonClicked() ) ); + return; + } + } + if ( mHoverCloseButton ) { + mEnableCloseButtonTimer->stop(); + delete mHoverCloseButton; + mHoverCloseButton = 0; + } + } + + QTabBar::mouseMoveEvent( e ); +} + +void KTabBar::enableCloseButton() +{ + mHoverCloseButton->setEnabled(true); +} + +void KTabBar::activateDragSwitchTab() +{ + QTab *tab = selectTab( mapFromGlobal( QCursor::pos() ) ); + if ( tab && mDragSwitchTab == tab ) + setCurrentTab( mDragSwitchTab ); + mDragSwitchTab = 0; +} + +void KTabBar::mouseReleaseEvent( QMouseEvent *e ) +{ + if( e->button() == MidButton ) { + if ( mReorderStartTab==-1 ) { + QTab *tab = selectTab( e->pos() ); + if( tab ) { + emit( mouseMiddleClick( indexOf( tab->identifier() ) ) ); + return; + } + } + else { + releaseMouse(); + setCursor( arrowCursor ); + mReorderStartTab=-1; + mReorderPreviousTab=-1; + } + } + QTabBar::mouseReleaseEvent( e ); +} + +void KTabBar::dragMoveEvent( QDragMoveEvent *e ) +{ + QTab *tab = selectTab( e->pos() ); + if( tab ) { + bool accept = false; + // The receivers of the testCanDecode() signal has to adjust + // 'accept' accordingly. + emit testCanDecode( e, accept); + if ( accept && tab != QTabBar::tab( currentTab() ) ) { + mDragSwitchTab = tab; + mActivateDragSwitchTabTimer->start( QApplication::doubleClickInterval()*2, true ); + } + e->accept( accept ); + return; + } + e->accept( false ); + QTabBar::dragMoveEvent( e ); +} + +void KTabBar::dropEvent( QDropEvent *e ) +{ + QTab *tab = selectTab( e->pos() ); + if( tab ) { + mActivateDragSwitchTabTimer->stop(); + mDragSwitchTab = 0; + emit( receivedDropEvent( indexOf( tab->identifier() ) , e ) ); + return; + } + QTabBar::dropEvent( e ); +} + +#ifndef QT_NO_WHEELEVENT +void KTabBar::wheelEvent( QWheelEvent *e ) +{ + if ( e->orientation() == Horizontal ) + return; + + emit( wheelDelta( e->delta() ) ); +} +#endif + +void KTabBar::setTabColor( int id, const QColor& color ) +{ + QTab *t = tab( id ); + if ( t ) { + mTabColors.insert( id, color ); + repaint( t->rect(), false ); + } +} + +const QColor &KTabBar::tabColor( int id ) const +{ + if ( mTabColors.contains( id ) ) + return mTabColors[id]; + + return colorGroup().foreground(); +} + +int KTabBar::insertTab( QTab *t, int index ) +{ + int res = QTabBar::insertTab( t, index ); + + if ( mTabCloseActivatePrevious && count() > 2 ) { + QPtrList<QTab> *tablist = tabList(); + tablist->insert( count()-2, tablist->take( tablist->findRef( t ) ) ); + } + + return res; +} + +void KTabBar::removeTab( QTab *t ) +{ + mTabColors.remove( t->identifier() ); + QTabBar::removeTab( t ); +} + +void KTabBar::paintLabel( QPainter *p, const QRect& br, + QTab *t, bool has_focus ) const +{ + QRect r = br; + bool selected = currentTab() == t->identifier(); + if ( t->iconSet() ) { + // the tab has an iconset, draw it in the right mode + QIconSet::Mode mode = ( t->isEnabled() && isEnabled() ) + ? QIconSet::Normal : QIconSet::Disabled; + if ( mode == QIconSet::Normal && has_focus ) + mode = QIconSet::Active; + QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + r.setLeft( r.left() + pixw + 4 ); + r.setRight( r.right() + 2 ); + + int inactiveXShift = style().pixelMetric( QStyle::PM_TabBarTabShiftHorizontal, this ); + int inactiveYShift = style().pixelMetric( QStyle::PM_TabBarTabShiftVertical, this ); + + int right = t->text().isEmpty() ? br.right() - pixw : br.left() + 2; + + p->drawPixmap( right + (selected ? 0 : inactiveXShift), + br.center().y() - pixh / 2 + (selected ? 0 : inactiveYShift), + pixmap ); + } + + QStyle::SFlags flags = QStyle::Style_Default; + + if ( isEnabled() && t->isEnabled() ) + flags |= QStyle::Style_Enabled; + if ( has_focus ) + flags |= QStyle::Style_HasFocus; + + QColorGroup cg( colorGroup() ); + if ( mTabColors.contains( t->identifier() ) ) + cg.setColor( QColorGroup::Foreground, mTabColors[t->identifier()] ); + + style().drawControl( QStyle::CE_TabBarLabel, p, this, r, + t->isEnabled() ? cg : palette().disabled(), + flags, QStyleOption(t) ); +} + +bool KTabBar::isTabReorderingEnabled() const +{ + return mTabReorderingEnabled; +} + +void KTabBar::setTabReorderingEnabled( bool on ) +{ + mTabReorderingEnabled = on; +} + +bool KTabBar::tabCloseActivatePrevious() const +{ + return mTabCloseActivatePrevious; +} + +void KTabBar::setTabCloseActivatePrevious( bool on ) +{ + mTabCloseActivatePrevious = on; +} + +void KTabBar::closeButtonClicked() +{ + emit closeRequest( indexOf( mHoverCloseButtonTab->identifier() ) ); +} + +void KTabBar::setHoverCloseButton( bool button ) +{ + mHoverCloseButtonEnabled = button; + if ( !button ) + onLayoutChange(); +} + +bool KTabBar::hoverCloseButton() const +{ + return mHoverCloseButtonEnabled; +} + +void KTabBar::setHoverCloseButtonDelayed( bool delayed ) +{ + mHoverCloseButtonDelayed = delayed; +} + +bool KTabBar::hoverCloseButtonDelayed() const +{ + return mHoverCloseButtonDelayed; +} + +void KTabBar::onLayoutChange() +{ + mEnableCloseButtonTimer->stop(); + delete mHoverCloseButton; + mHoverCloseButton = 0; + mHoverCloseButtonTab = 0; + mActivateDragSwitchTabTimer->stop(); + mDragSwitchTab = 0; +} + +#include "ktabbar.moc" |