diff options
Diffstat (limited to 'tdeui/ktabwidget.cpp')
-rw-r--r-- | tdeui/ktabwidget.cpp | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/tdeui/ktabwidget.cpp b/tdeui/ktabwidget.cpp new file mode 100644 index 000000000..3825d5aa5 --- /dev/null +++ b/tdeui/ktabwidget.cpp @@ -0,0 +1,526 @@ +/* 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 <tqapplication.h> +#include <tqstyle.h> +#include <tqstylesheet.h> + +#include <kconfig.h> +#include <kiconloader.h> +#include <kstringhandler.h> + +#include "ktabwidget.h" +#include "ktabbar.h" + +class KTabWidgetPrivate { +public: + bool m_automaticResizeTabs; + int m_maxLength; + int m_minLength; + unsigned int m_CurrentMaxLength; + + //holds the full names of the tab, otherwise all we + //know about is the shortened name + TQStringList m_tabNames; + + KTabWidgetPrivate() { + m_automaticResizeTabs = false; + KConfigGroupSaver groupsaver(KGlobal::config(), "General"); + m_maxLength = KGlobal::config()->readNumEntry("MaximumTabLength", 30); + m_minLength = KGlobal::config()->readNumEntry("MinimumTabLength", 3); + m_CurrentMaxLength = m_minLength; + } +}; + +KTabWidget::KTabWidget( TQWidget *parent, const char *name, WFlags f ) + : TQTabWidget( parent, name, f ) +{ + d = new KTabWidgetPrivate; + setTabBar( new KTabBar(this, "tabbar") ); + setAcceptDrops( true ); + + setHoverCloseButtonDelayed(false); + + connect(tabBar(), TQT_SIGNAL(contextMenu( int, const TQPoint & )), TQT_SLOT(contextMenu( int, const TQPoint & ))); + connect(tabBar(), TQT_SIGNAL(mouseDoubleClick( int )), TQT_SLOT(mouseDoubleClick( int ))); + connect(tabBar(), TQT_SIGNAL(mouseMiddleClick( int )), TQT_SLOT(mouseMiddleClick( int ))); + connect(tabBar(), TQT_SIGNAL(initiateDrag( int )), TQT_SLOT(initiateDrag( int ))); + connect(tabBar(), TQT_SIGNAL(testCanDecode(const TQDragMoveEvent *, bool & )), TQT_SIGNAL(testCanDecode(const TQDragMoveEvent *, bool & ))); + connect(tabBar(), TQT_SIGNAL(receivedDropEvent( int, TQDropEvent * )), TQT_SLOT(receivedDropEvent( int, TQDropEvent * ))); + connect(tabBar(), TQT_SIGNAL(moveTab( int, int )), TQT_SLOT(moveTab( int, int ))); + connect(tabBar(), TQT_SIGNAL(closeRequest( int )), TQT_SLOT(closeRequest( int ))); +#ifndef QT_NO_WHEELEVENT + connect(tabBar(), TQT_SIGNAL(wheelDelta( int )), TQT_SLOT(wheelDelta( int ))); +#endif +} + +KTabWidget::~KTabWidget() +{ + delete d; +} + +void KTabWidget::insertTab( TQWidget *child, const TQString &label, int index ) +{ + TQTabWidget::insertTab( child, label, index ); +} + +void KTabWidget::insertTab( TQWidget *child, const TQIconSet& iconset, const TQString &label, int index ) +{ + TQTabWidget::insertTab( child, iconset, label, index ); +} + +void KTabWidget::insertTab( TQWidget *child, TQTab *tab, int index ) +{ + TQTabWidget::insertTab( child, tab, index); + if ( d->m_automaticResizeTabs ) { + if ( index < 0 || index >= count() ) { + d->m_tabNames.append( tab->text() ); + resizeTabs( d->m_tabNames.count()-1 ); + } + else { + d->m_tabNames.insert( d->m_tabNames.tqat( index ), tab->text() ); + resizeTabs( index ); + } + } +} + +void KTabWidget::setTabBarHidden( bool hide ) +{ + TQWidget *rightcorner = this->cornerWidget( TopRight ); + TQWidget *leftcorner = this->cornerWidget( TopLeft ); + + if ( hide ) { + if ( leftcorner ) leftcorner->hide(); + if ( rightcorner ) rightcorner->hide(); + tabBar()->hide(); + } else { + tabBar()->show(); + if ( leftcorner ) leftcorner->show(); + if ( rightcorner ) rightcorner->show(); + } +} + +bool KTabWidget::isTabBarHidden() const +{ + return !( tabBar()->isVisible() ); +} + +void KTabWidget::setTabColor( TQWidget *w, const TQColor& color ) +{ + TQTab *t = tabBar()->tabAt( indexOf( w ) ); + if (t) { + static_cast<KTabBar*>(tabBar())->setTabColor( t->identifier(), color ); + } +} + +TQColor KTabWidget::tabColor( TQWidget *w ) const +{ + TQTab *t = tabBar()->tabAt( indexOf( w ) ); + if (t) { + return static_cast<KTabBar*>(tabBar())->tabColor( t->identifier() ); + } else { + return TQColor(); + } +} + +void KTabWidget::setTabReorderingEnabled( bool on) +{ + static_cast<KTabBar*>(tabBar())->setTabReorderingEnabled( on ); +} + +bool KTabWidget::isTabReorderingEnabled() const +{ + return static_cast<KTabBar*>(tabBar())->isTabReorderingEnabled(); +} + +void KTabWidget::setTabCloseActivatePrevious( bool previous) +{ + static_cast<KTabBar*>(tabBar())->setTabCloseActivatePrevious( previous ); +} + +bool KTabWidget::tabCloseActivatePrevious() const +{ + return static_cast<KTabBar*>(tabBar())->tabCloseActivatePrevious(); +} + +unsigned int KTabWidget::tabBarWidthForMaxChars( uint maxLength ) +{ + int hframe, overlap; + hframe = tabBar()->tqstyle().tqpixelMetric( TQStyle::PM_TabBarTabHSpace, tabBar() ); + overlap = tabBar()->tqstyle().tqpixelMetric( TQStyle::PM_TabBarTabOverlap, tabBar() ); + + TQFontMetrics fm = tabBar()->fontMetrics(); + int x = 0; + for( int i=0; i < count(); ++i ) { + TQString newTitle = d->m_tabNames[ i ]; + newTitle = KStringHandler::rsqueeze( newTitle, maxLength ).leftJustify( d->m_minLength, ' ' ); + + TQTab* tab = tabBar()->tabAt( i ); + int lw = fm.width( newTitle ); + int iw = 0; + if ( tab->iconSet() ) + iw = tab->iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4; + x += ( tabBar()->tqstyle().tqsizeFromContents( TQStyle::CT_TabBarTab, this, + TQSize( QMAX( lw + hframe + iw, TQApplication::globalStrut().width() ), 0 ), + TQStyleOption( tab ) ) ).width(); + } + return x; +} + +void KTabWidget::changeTab( TQWidget *w, const TQString &label ) +{ + TQTabWidget::changeTab( w, label ); + if ( d->m_automaticResizeTabs ) { + int index = indexOf( w ); + if ( index != -1 ) { + d->m_tabNames[ index ] = label; + resizeTabs( index ); + } + } +} + +void KTabWidget::changeTab( TQWidget *w, const TQIconSet &iconset, const TQString &label ) +{ + TQTabWidget::changeTab( w, iconset, label ); + if ( d->m_automaticResizeTabs ) { + int index = indexOf( w ); + if ( index != -1 ) { + d->m_tabNames[ index ] = label; + resizeTabs( index ); + } + } +} + +TQString KTabWidget::label( int index ) const +{ + if ( d->m_automaticResizeTabs ) { + if ( index >= 0 && index < count() ) + return d->m_tabNames[ index ]; + else + return TQString::null; + } + else + return TQTabWidget::label( index ); +} + +TQString KTabWidget::tabLabel( TQWidget * w ) const +{ + if ( d->m_automaticResizeTabs ) { + int index = indexOf( w ); + if ( index == -1 ) + return TQString::null; + else + return d->m_tabNames[ index ]; + } + else + return TQTabWidget::tabLabel( w ); +} + +void KTabWidget::setTabLabel( TQWidget *w, const TQString &l ) +{ + TQTabWidget::setTabLabel( w, l ); + if ( d->m_automaticResizeTabs ) { + int index = indexOf( w ); + if ( index != -1 ) { + d->m_tabNames[ index ] = l; + resizeTabs( index ); + } + } +} + +void KTabWidget::resizeTabs( int changeTabIndex ) +{ + uint newMaxLength; + if ( d->m_automaticResizeTabs ) { + // Calculate new max length + newMaxLength=d->m_maxLength; + uint lcw=0, rcw=0; + + int tabBarHeight = tabBar()->tqsizeHint().height(); + if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() ) + lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight ); + if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() ) + rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight ); + + uint maxTabBarWidth = width() - lcw - rcw; + + for ( ; newMaxLength > (uint)d->m_minLength; newMaxLength-- ) { + if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth ) + break; + } + } + else + newMaxLength = 4711; + + // Update hinted or all tabs + if ( d->m_CurrentMaxLength != newMaxLength ) { + d->m_CurrentMaxLength = newMaxLength; + for( int i = 0; i < count(); ++i ) + updateTab( i ); + } + else if ( changeTabIndex != -1 ) + updateTab( changeTabIndex ); +} + +void KTabWidget::updateTab( int index ) +{ + TQString title = d->m_automaticResizeTabs ? d->m_tabNames[ index ] : TQTabWidget::label( index ); + removeTabToolTip( page( index ) ); + if ( title.length() > d->m_CurrentMaxLength ) { + if ( TQStyleSheet::mightBeRichText( title ) ) + setTabToolTip( page( index ), TQStyleSheet::escape(title) ); + else + setTabToolTip( page( index ), title ); + } + + title = KStringHandler::rsqueeze( title, d->m_CurrentMaxLength ).leftJustify( d->m_minLength, ' ' ); + title.replace( '&', "&&" ); + + if ( TQTabWidget::label( index ) != title ) + TQTabWidget::setTabLabel( page( index ), title ); +} + +void KTabWidget::dragMoveEvent( TQDragMoveEvent *e ) +{ + if ( isEmptyTabbarSpace( e->pos() ) ) { + bool accept = false; + // The tqreceivers of the testCanDecode() signal has to adjust + // 'accept' accordingly. + emit testCanDecode( e, accept); + e->accept( accept ); + return; + } + e->accept( false ); + TQTabWidget::dragMoveEvent( e ); +} + +void KTabWidget::dropEvent( TQDropEvent *e ) +{ + if ( isEmptyTabbarSpace( e->pos() ) ) { + emit ( receivedDropEvent( e ) ); + return; + } + TQTabWidget::dropEvent( e ); +} + +#ifndef QT_NO_WHEELEVENT +void KTabWidget::wheelEvent( TQWheelEvent *e ) +{ + if ( e->orientation() == Qt::Horizontal ) + return; + + if ( isEmptyTabbarSpace( e->pos() ) ) + wheelDelta( e->delta() ); + else + e->ignore(); +} + +void KTabWidget::wheelDelta( int delta ) +{ + if ( count() < 2 ) + return; + + int page = currentPageIndex(); + if ( delta < 0 ) + page = (page + 1) % count(); + else { + page--; + if ( page < 0 ) + page = count() - 1; + } + setCurrentPage( page ); +} +#endif + +void KTabWidget::mouseDoubleClickEvent( TQMouseEvent *e ) +{ + if( e->button() != Qt::LeftButton ) + return; + + if ( isEmptyTabbarSpace( e->pos() ) ) { + emit( mouseDoubleClick() ); + return; + } + TQTabWidget::mouseDoubleClickEvent( e ); +} + +void KTabWidget::mousePressEvent( TQMouseEvent *e ) +{ + if ( e->button() == Qt::RightButton ) { + if ( isEmptyTabbarSpace( e->pos() ) ) { + emit( contextMenu( mapToGlobal( e->pos() ) ) ); + return; + } + } else if ( e->button() == Qt::MidButton ) { + if ( isEmptyTabbarSpace( e->pos() ) ) { + emit( mouseMiddleClick() ); + return; + } + } + TQTabWidget::mousePressEvent( e ); +} + +void KTabWidget::receivedDropEvent( int index, TQDropEvent *e ) +{ + emit( receivedDropEvent( page( index ), e ) ); +} + +void KTabWidget::initiateDrag( int index ) +{ + emit( initiateDrag( page( index ) ) ); +} + +void KTabWidget::contextMenu( int index, const TQPoint &p ) +{ + emit( contextMenu( page( index ), p ) ); +} + +void KTabWidget::mouseDoubleClick( int index ) +{ + emit( mouseDoubleClick( page( index ) ) ); +} + +void KTabWidget::mouseMiddleClick( int index ) +{ + emit( mouseMiddleClick( page( index ) ) ); +} + +void KTabWidget::moveTab( int from, int to ) +{ + TQString tablabel = label( from ); + TQWidget *w = page( from ); + TQColor color = tabColor( w ); + TQIconSet tabiconset = tabIconSet( w ); + TQString tabtooltip = tabToolTip( w ); + bool current = ( w == currentPage() ); + bool enabled = isTabEnabled( w ); + blockSignals(true); + removePage( w ); + + // Work-around kmdi brain damage which calls showPage() in insertTab() + TQTab * t = new TQTab(); + t->setText(tablabel); + TQTabWidget::insertTab( w, t, to ); + if ( d->m_automaticResizeTabs ) { + if ( to < 0 || to >= count() ) + d->m_tabNames.append( TQString::null ); + else + d->m_tabNames.insert( d->m_tabNames.tqat( to ), TQString::null ); + } + + w = page( to ); + changeTab( w, tabiconset, tablabel ); + setTabToolTip( w, tabtooltip ); + setTabColor( w, color ); + if ( current ) + showPage( w ); + setTabEnabled( w, enabled ); + blockSignals(false); + + emit ( movedTab( from, to ) ); +} + +void KTabWidget::removePage( TQWidget * w ) { + if ( d->m_automaticResizeTabs ) { + int index = indexOf( w ); + if ( index != -1 ) + d->m_tabNames.remove( d->m_tabNames.tqat( index ) ); + } + TQTabWidget::removePage( w ); + if ( d->m_automaticResizeTabs ) + resizeTabs(); +} + + +bool KTabWidget::isEmptyTabbarSpace( const TQPoint &point ) const +{ + TQSize size( tabBar()->tqsizeHint() ); + if ( ( tabPosition()==Top && point.y()< size.height() ) || ( tabPosition()==Bottom && point.y()>(height()-size.height() ) ) ) { + TQWidget *rightcorner = cornerWidget( TopRight ); + if ( rightcorner ) { + if ( point.x()>=width()-rightcorner->width() ) + return false; + } + TQWidget *leftcorner = cornerWidget( TopLeft ); + if ( leftcorner ) { + if ( point.x()<=leftcorner->width() ) + return false; + } + TQTab *tab = tabBar()->selectTab( tabBar()->mapFromParent( point ) ); + if( !tab ) + return true; + } + return false; +} + +void KTabWidget::setHoverCloseButton( bool button ) +{ + static_cast<KTabBar*>(tabBar())->setHoverCloseButton( button ); +} + +bool KTabWidget::hoverCloseButton() const +{ + return static_cast<KTabBar*>(tabBar())->hoverCloseButton(); +} + +void KTabWidget::setHoverCloseButtonDelayed( bool delayed ) +{ + static_cast<KTabBar*>(tabBar())->setHoverCloseButtonDelayed( delayed ); +} + +bool KTabWidget::hoverCloseButtonDelayed() const +{ + return static_cast<KTabBar*>(tabBar())->hoverCloseButtonDelayed(); +} + +void KTabWidget::setAutomaticResizeTabs( bool enabled ) +{ + if ( d->m_automaticResizeTabs==enabled ) + return; + + d->m_automaticResizeTabs = enabled; + if ( enabled ) { + d->m_tabNames.clear(); + for( int i = 0; i < count(); ++i ) + d->m_tabNames.append( tabBar()->tabAt( i )->text() ); + } + else + for( int i = 0; i < count(); ++i ) + tabBar()->tabAt( i )->setText( d->m_tabNames[ i ] ); + resizeTabs(); +} + +bool KTabWidget::automaticResizeTabs() const +{ + return d->m_automaticResizeTabs; +} + +void KTabWidget::closeRequest( int index ) +{ + emit( closeRequest( page( index ) ) ); +} + +void KTabWidget::resizeEvent( TQResizeEvent *e ) +{ + TQTabWidget::resizeEvent( e ); + resizeTabs(); +} + +#include "ktabwidget.moc" |