Index: ktabbar.h =================================================================== --- ktabbar.h (revision 740173) +++ ktabbar.h (working copy) @@ -57,7 +57,18 @@ */ bool isTabReorderingEnabled() const; - // KDE4 porting: disabled + // NoCloseButton -> nothing is shown + // StaticCloseButton -> always show a close button (no other icon allowed) + // HoverCloseButton -> show close button on mouse over, otherwise use icon + enum CloseButton { NoCloseButton=0, StaticCloseButton=1, HoverCloseButton=2}; + // Q_DECLARE_FLAGS( CloseButtons, CloseButton ) not sure what this could be + + + void setCloseButton( int ); + int closeButton() const; + + + //KDE4 porting: disabled void setHoverCloseButton( bool ); bool hoverCloseButton() const; @@ -84,11 +95,17 @@ * * @param position the coordinates of the tab */ + /** @deprecated use tabAt( const QPoint & ) instead. */ int selectTab( const QPoint &position ) const; + + + void setTabIcon(int index, const QIcon & icon); Q_SIGNALS: /** Emitted when the user right-clicks a tab. */ void contextMenu( int, const QPoint& ); + /** Emitted when close button is clicked */ + void closeButtonClicked(int index ); /** Emitted when the user right-clicks the empty area on the tab bar. */ void emptyAreaContextMenu( const QPoint& ); /** @deprecated use tabDoubleClicked(int) and newTabRequest() instead. */ @@ -120,16 +137,20 @@ virtual void dragEnterEvent( QDragEnterEvent *event ); virtual void dragMoveEvent( QDragMoveEvent *event ); virtual void dropEvent( QDropEvent *event ); + virtual void paintEvent ( QPaintEvent * event ); protected Q_SLOTS: - //virtual void closeButtonClicked(); - //virtual void enableCloseButton(); + virtual void p_closeButtonClicked(); virtual void activateDragSwitchTab(); protected: + QRect findIconGeometry(const int index); virtual void tabLayoutChange(); - + virtual void tabInserted(int index); + void drawCloseButton(); + void setCloseIcon( int index); private: + class Private; Private* const d; }; Index: ktabwidget.cpp =================================================================== --- ktabwidget.cpp (revision 740173) +++ ktabwidget.cpp (working copy) @@ -496,6 +496,13 @@ } } +void KTabWidget::setCloseButton( int setting ) +{ + static_cast( tabBar() )->setCloseButton( setting ); + connect(tabBar(), SIGNAL(closeButtonClicked ( int )), this, SLOT(closeRequest(int ) )); +} + + void KTabWidget::setHoverCloseButton( bool button ) { static_cast( tabBar() )->setHoverCloseButton( button ); Index: ktabbar.cpp =================================================================== --- ktabbar.cpp (revision 740173) +++ ktabbar.cpp (working copy) @@ -27,24 +27,32 @@ #include #include #include +#include +#include +#include #include #include #include +#include + class KTabBar::Private { public: Private() : mReorderStartTab( -1 ), mReorderPreviousTab( -1 ), - // mHoverCloseButtonTab( 0 ), + mDragSwitchTab( -1 ), - // mHoverCloseButton( 0 ), - // mHoverCloseButtonEnabled( false ), + + //mHoverCloseButtonEnabled( false ), // mHoverCloseButtonDelayed( true ), mTabReorderingEnabled( false ), - mTabCloseActivatePrevious( false ) + mTabCloseActivatePrevious( false ), + mCloseButtonSetting(KTabBar::NoCloseButton), + mCloseButtonInTab( -1 ), + mCloseButton( 0 ) { } @@ -53,7 +61,7 @@ int mReorderPreviousTab; int mDragSwitchTab; //QTab *mHoverCloseButtonTab, *mDragSwitchTab; - //QPushButton *mHoverCloseButton; + //QTimer mEnableCloseButtonTimer; QTimer *mActivateDragSwitchTabTimer; @@ -61,7 +69,19 @@ //bool mHoverCloseButtonDelayed; bool mTabReorderingEnabled : 1; bool mTabCloseActivatePrevious : 1; + + //what sort of close button (static, hover, delay) + int mCloseButtonSetting; + //in what tab is the close button shown currently? + int mCloseButtonInTab; + + //the closebutton + QPushButton *mCloseButton; + //temporary storage for the icons "real" tab. + QIcon mCloseButtonTmpIcon; + + }; KTabBar::KTabBar( QWidget *parent ) @@ -86,12 +106,20 @@ delete d; } + +void KTabBar::paintEvent ( QPaintEvent * event ) +{ + drawCloseButton(); + QTabBar::paintEvent(event); +} + + void KTabBar::mouseDoubleClickEvent( QMouseEvent *event ) { if ( event->button() != Qt::LeftButton ) return; - int tab = selectTab( event->pos() ); + int tab = tabAt( event->pos() ); if(tab == -1) { emit newTabRequest(); @@ -107,7 +135,7 @@ //d->mEnableCloseButtonTimer->stop(); d->mDragStart = event->pos(); } else if( event->button() == Qt::RightButton ) { - int tab = selectTab( event->pos() ); + int tab = tabAt( event->pos() ); if ( tab != -1 ) { emit contextMenu( tab, mapToGlobal( event->pos() ) ); } else { @@ -121,8 +149,8 @@ void KTabBar::mouseMoveEvent( QMouseEvent *event ) { + int tab = tabAt( event->pos() ); if ( event->buttons() == Qt::LeftButton ) { - int tab = selectTab( event->pos() ); if ( d->mDragSwitchTab && tab != d->mDragSwitchTab ) { d->mActivateDragSwitchTabTimer->stop(); d->mDragSwitchTab = 0; @@ -144,7 +172,6 @@ if ( newPos.x() > d->mDragStart.x() + delay || newPos.x() < d->mDragStart.x() - delay || newPos.y() > d->mDragStart.y() + delay || newPos.y() < d->mDragStart.y() - delay ) { - int tab = selectTab( event->pos() ); if ( tab != -1 && d->mTabReorderingEnabled ) { d->mReorderStartTab = tab; grabMouse( Qt::SizeAllCursor ); @@ -152,7 +179,6 @@ } } } else { - int tab = selectTab( event->pos() ); if ( tab != -1 ) { int reorderStopTab = tab; if ( d->mReorderStartTab != reorderStopTab && d->mReorderPreviousTab != reorderStopTab ) { @@ -166,71 +192,92 @@ } } } + if(d->mCloseButtonSetting != KTabBar::NoCloseButton){ + + switch(d->mCloseButtonSetting){ + case KTabBar::StaticCloseButton: + d->mCloseButtonInTab = tab; + break; + case KTabBar::HoverCloseButton: + setCloseIcon(tab); + break; + } + + } + - /*if ( d->mHoverCloseButtonEnabled && d->mReorderStartTab == -1 ) { - QTab *t = selectTab( event->pos() ); - if ( t && t->iconSet() && t->isEnabled() ) { - QPixmap pixmap = t->iconSet()->pixmap( QIcon::Small, QIcon::Normal ); - QRect rect( 0, 0, pixmap.width() + 4, pixmap.height() +4); + QTabBar::mouseMoveEvent( event ); +} - 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; - } +void KTabBar::setCloseIcon(int index) +{ - rect.moveLeft( t->rect().left() + 2 + xoff ); - rect.moveTop( t->rect().center().y() - pixmap.height() / 2 + yoff ); - if ( rect.contains( event->pos() ) ) { - if ( d->mHoverCloseButton ) { - if ( d->mHoverCloseButtonTab == t ) - return; - d->mEnableCloseButtonTimer->stop(); - d->mHoverCloseButton->deleteLater(); - d->mHoverCloseButton = 0; - } + if(d->mCloseButtonInTab != -1) + setTabIcon(d->mCloseButtonInTab, d->mCloseButtonTmpIcon); - d->mHoverCloseButton = new QPushButton( this ); - d->mHoverCloseButton->setIcon( KGlobal::iconLoader()->loadIconSet( "window-close", KIconLoader::Toolbar, KIconLoader::SizeSmall ) ); - d->mHoverCloseButton->setGeometry( rect ); - d->mHoverCloseButton->setToolTip( i18n( "Close this tab" ) ); - d->mHoverCloseButton->setFlat( true ); - d->mHoverCloseButton->show(); - if ( d->mHoverCloseButtonDelayed ) { - d->mHoverCloseButton->setEnabled( false ); - d->mEnableCloseButtonTimer->start( QApplication::doubleClickInterval(), true ); - } + d->mCloseButtonInTab = index; + if(index == -1) + return; - d->mHoverCloseButtonTab = t; - connect( d->mHoverCloseButton, SIGNAL( clicked() ), SLOT( closeButtonClicked() ) ); - return; - } - } + d->mCloseButtonTmpIcon = tabIcon(index); + setTabIcon(index, KIcon( "window-close" )); - if ( d->mHoverCloseButton ) { - d->mEnableCloseButtonTimer->stop(); - d->mHoverCloseButton->deleteLater(); - d->mHoverCloseButton = 0; - } - }*/ +} - QTabBar::mouseMoveEvent( event ); +void KTabBar::drawCloseButton() +{ + + if(d->mCloseButtonSetting == KTabBar::NoCloseButton ) + return; + + //if the close button isn't set yet, set it up + if(d->mCloseButton == 0){ + d->mCloseButton = new QPushButton( this ); + d->mCloseButton->setIcon( KIcon( "window-close" ) ); + d->mCloseButton->setToolTip( i18n( "Close this tab" ) ); + d->mCloseButton->setFlat( true ); + connect( d->mCloseButton, SIGNAL( clicked() ), SLOT( p_closeButtonClicked( ) ) ); + } + + + //mouse is about to leave the tabbar. remove the button + if(d->mCloseButtonInTab == -1){ + d->mCloseButton->hide(); + return; + } + + //move the button + d->mCloseButton->setGeometry( findIconGeometry( d->mCloseButtonInTab ) ); + + d->mCloseButton->show(); + } -/* -void KTabBar::enableCloseButton() + + +QRect KTabBar::findIconGeometry(const int index) { - d->mHoverCloseButton->setEnabled( true ); + + QRect rect; + rect = QRect(tabRect(index).topLeft(), iconSize() ); + //found via trial and error... there's gotta be a system behind it: --> insert here ;) + rect.moveLeft(rect.left() + 14); + rect.moveBottom(rect.bottom() + 8); + + return rect; } -*/ +void KTabBar::p_closeButtonClicked() +{ + emit closeButtonClicked(d->mCloseButtonInTab ); + d->mCloseButtonInTab = -1; + d->mCloseButton->hide(); +} + + void KTabBar::activateDragSwitchTab() { - int tab = selectTab( mapFromGlobal( QCursor::pos() ) ); + int tab = tabAt( mapFromGlobal( QCursor::pos() ) ); if ( tab != -1 && d->mDragSwitchTab == tab ) setCurrentIndex( d->mDragSwitchTab ); @@ -241,7 +288,7 @@ { if ( event->button() == Qt::MidButton ) { if ( d->mReorderStartTab == -1 ) { - int tab = selectTab( event->pos() ); + int tab = tabAt( event->pos() ); if ( tab != -1 ) { emit mouseMiddleClick( tab ); return; @@ -265,7 +312,7 @@ void KTabBar::dragMoveEvent( QDragMoveEvent *event ) { - int tab = selectTab( event->pos() ); + int tab = tabAt( event->pos() ); if ( tab != -1 ) { bool accept = false; // The receivers of the testCanDecode() signal has to adjust @@ -286,7 +333,7 @@ void KTabBar::dropEvent( QDropEvent *event ) { - int tab = selectTab( event->pos() ); + int tab = tabAt( event->pos() ); if ( tab != -1 ) { d->mActivateDragSwitchTabTimer->stop(); d->mDragSwitchTab = 0; @@ -327,33 +374,72 @@ d->mTabCloseActivatePrevious = on; } -/* -void KTabBar::closeButtonClicked() + +void KTabBar::setHoverCloseButton( bool button ) { - emit closeRequest( indexOf( d->mHoverCloseButtonTab->identifier() ) ); + if(button == true) + setCloseButton( KTabBar::HoverCloseButton ); + else + setCloseButton( KTabBar::NoCloseButton ); + return; } -*/ -void KTabBar::setHoverCloseButton( bool /*button*/ ) + +void KTabBar::setCloseButton( int setting ) { - // KDE4 porting: disabled - return; + d->mCloseButtonSetting = setting; -/* - d->mHoverCloseButtonEnabled = button; - if ( !button ) - tabLayoutChange(); -*/ + if(setting != KTabBar::NoCloseButton){ + int i; + for(i=0;icount();i++) + tabInserted(i); + } + } -bool KTabBar::hoverCloseButton() const +int KTabBar::closeButton() const { - // KDE4 porting: disabled - return false; + return d->mCloseButtonSetting; +} - //return d->mHoverCloseButtonEnabled; +void KTabBar::setTabIcon(int index, const QIcon & icon) +{ + //if the static close button is set, disable icons + if(d->mCloseButtonSetting == KTabBar::StaticCloseButton) + return; + + if(d->mCloseButtonSetting == KTabBar::HoverCloseButton && icon.isNull()){ + QTabBar::setTabIcon(index, KIcon( "window-close" )); + return; + } + + QTabBar::setTabIcon(index, icon); } +void KTabBar::tabInserted(int index) +{ + + switch(d->mCloseButtonSetting){ + case KTabBar::StaticCloseButton : + QTabBar::setTabIcon(index, KIcon( "window-close" )); + break; + case KTabBar::HoverCloseButton: + if(tabIcon(index).isNull()) + QTabBar::setTabIcon(index, KIcon( "window-close" )); + break; + } +} + + + +bool KTabBar::hoverCloseButton() const +{ + if(d->mCloseButtonSetting == KTabBar::HoverCloseButton) + return true; + else + return false; +} + void KTabBar::setHoverCloseButtonDelayed( bool /*delayed*/ ) { // KDE4 porting: disabled @@ -372,21 +458,11 @@ void KTabBar::tabLayoutChange() { - //d->mEnableCloseButtonTimer->stop(); - //delete d->mHoverCloseButton; - //d->mHoverCloseButton = 0; - //d->mHoverCloseButtonTab = 0; d->mActivateDragSwitchTabTimer->stop(); d->mDragSwitchTab = 0; + } -int KTabBar::selectTab( const QPoint &pos ) const -{ - for ( int i = 0; i < count(); ++i ) - if ( tabRect( i ).contains( pos ) ) - return i; - return -1; -} #include "ktabbar.moc" Index: ktabwidget.h =================================================================== --- ktabwidget.h (revision 740173) +++ ktabwidget.h (working copy) @@ -187,7 +187,11 @@ * you from which index to which index a tab has been moved. */ void setTabReorderingEnabled( bool enable ); + + void setCloseButton( int setting ); + + /** * If \a enable is true, a close button will be shown on mouse hover * over tab icons which will emit signal closeRequest( QWidget * )