00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qapplication.h>
00022 #include <qstyle.h>
00023
00024 #include <kconfig.h>
00025 #include <kiconloader.h>
00026 #include <kstringhandler.h>
00027
00028 #include "ktabwidget.h"
00029 #include "ktabbar.h"
00030
00031 class KTabWidgetPrivate {
00032 public:
00033 bool m_automaticResizeTabs;
00034 int m_maxLength;
00035 int m_minLength;
00036 unsigned int m_CurrentMaxLength;
00037
00038
00039
00040 QStringList m_tabNames;
00041
00042 KTabWidgetPrivate() {
00043 m_automaticResizeTabs = false;
00044 KConfigGroupSaver groupsaver(KGlobal::config(), "General");
00045 m_maxLength = KGlobal::config()->readNumEntry("MaximumTabLength", 30);
00046 m_minLength = KGlobal::config()->readNumEntry("MinimumTabLength", 3);
00047 m_CurrentMaxLength = m_minLength;
00048 }
00049 };
00050
00051 KTabWidget::KTabWidget( QWidget *parent, const char *name, WFlags f )
00052 : QTabWidget( parent, name, f )
00053 {
00054 d = new KTabWidgetPrivate;
00055 setTabBar( new KTabBar(this, "tabbar") );
00056 setAcceptDrops( true );
00057
00058 connect(tabBar(), SIGNAL(contextMenu( int, const QPoint & )), SLOT(contextMenu( int, const QPoint & )));
00059 connect(tabBar(), SIGNAL(mouseDoubleClick( int )), SLOT(mouseDoubleClick( int )));
00060 connect(tabBar(), SIGNAL(mouseMiddleClick( int )), SLOT(mouseMiddleClick( int )));
00061 connect(tabBar(), SIGNAL(initiateDrag( int )), SLOT(initiateDrag( int )));
00062 connect(tabBar(), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )));
00063 connect(tabBar(), SIGNAL(receivedDropEvent( int, QDropEvent * )), SLOT(receivedDropEvent( int, QDropEvent * )));
00064 connect(tabBar(), SIGNAL(moveTab( int, int )), SLOT(moveTab( int, int )));
00065 connect(tabBar(), SIGNAL(closeRequest( int )), SLOT(closeRequest( int )));
00066 #ifndef QT_NO_WHEELEVENT
00067 connect(tabBar(), SIGNAL(wheelDelta( int )), SLOT(wheelDelta( int )));
00068 #endif
00069 }
00070
00071 KTabWidget::~KTabWidget()
00072 {
00073 delete d;
00074 }
00075
00076 void KTabWidget::insertTab( QWidget *child, const QString &label, int index )
00077 {
00078 QTabWidget::insertTab( child, label, index );
00079 }
00080
00081 void KTabWidget::insertTab( QWidget *child, const QIconSet& iconset, const QString &label, int index )
00082 {
00083 QTabWidget::insertTab( child, iconset, label, index );
00084 }
00085
00086 void KTabWidget::insertTab( QWidget *child, QTab *tab, int index )
00087 {
00088 QTabWidget::insertTab( child, tab, index);
00089 if ( d->m_automaticResizeTabs ) {
00090 if ( index < 0 || index >= count() ) {
00091 d->m_tabNames.append( tab->text() );
00092 resizeTabs( d->m_tabNames.count()-1 );
00093 }
00094 else {
00095 d->m_tabNames.insert( d->m_tabNames.at( index ), tab->text() );
00096 resizeTabs( index );
00097 }
00098 }
00099 }
00100
00101 void KTabWidget::setTabBarHidden( bool hide )
00102 {
00103 QWidget *rightcorner = this->cornerWidget( TopRight );
00104 QWidget *leftcorner = this->cornerWidget( TopLeft );
00105
00106 if ( hide ) {
00107 if ( leftcorner ) leftcorner->hide();
00108 if ( rightcorner ) rightcorner->hide();
00109 tabBar()->hide();
00110 } else {
00111 tabBar()->show();
00112 if ( leftcorner ) leftcorner->show();
00113 if ( rightcorner ) rightcorner->show();
00114 }
00115 }
00116
00117 bool KTabWidget::isTabBarHidden() const
00118 {
00119 return !( tabBar()->isVisible() );
00120 }
00121
00122 void KTabWidget::setTabColor( QWidget *w, const QColor& color )
00123 {
00124 QTab *t = tabBar()->tabAt( indexOf( w ) );
00125 if (t) {
00126 static_cast<KTabBar*>(tabBar())->setTabColor( t->identifier(), color );
00127 }
00128 }
00129
00130 QColor KTabWidget::tabColor( QWidget *w ) const
00131 {
00132 QTab *t = tabBar()->tabAt( indexOf( w ) );
00133 if (t) {
00134 return static_cast<KTabBar*>(tabBar())->tabColor( t->identifier() );
00135 } else {
00136 return QColor();
00137 }
00138 }
00139
00140 void KTabWidget::setTabReorderingEnabled( bool on)
00141 {
00142 static_cast<KTabBar*>(tabBar())->setTabReorderingEnabled( on );
00143 }
00144
00145 bool KTabWidget::isTabReorderingEnabled() const
00146 {
00147 return static_cast<KTabBar*>(tabBar())->isTabReorderingEnabled();
00148 }
00149
00150 void KTabWidget::setTabCloseActivatePrevious( bool previous)
00151 {
00152 static_cast<KTabBar*>(tabBar())->setTabCloseActivatePrevious( previous );
00153 }
00154
00155 bool KTabWidget::tabCloseActivatePrevious() const
00156 {
00157 return static_cast<KTabBar*>(tabBar())->tabCloseActivatePrevious();
00158 }
00159
00160 unsigned int KTabWidget::tabBarWidthForMaxChars( uint maxLength )
00161 {
00162 int hframe, overlap;
00163 hframe = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, tabBar() );
00164 overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, tabBar() );
00165
00166 QFontMetrics fm = tabBar()->fontMetrics();
00167 int x = 0;
00168 for( int i=0; i < count(); ++i ) {
00169 QString newTitle = d->m_tabNames[ i ];
00170 newTitle = KStringHandler::rsqueeze( newTitle, maxLength ).leftJustify( d->m_minLength, ' ' );
00171
00172 QTab* tab = tabBar()->tabAt( i );
00173 int lw = fm.width( newTitle );
00174 int iw = 0;
00175 if ( tab->iconSet() )
00176 iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;
00177 x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this,
00178 QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ),
00179 QStyleOption( tab ) ) ).width();
00180 }
00181 return x;
00182 }
00183
00184 void KTabWidget::changeTab( QWidget *w, const QString &label )
00185 {
00186 QTabWidget::changeTab( w, label );
00187 if ( d->m_automaticResizeTabs ) {
00188 int index = indexOf( w );
00189 if ( index != -1 ) {
00190 d->m_tabNames[ index ] = label;
00191 resizeTabs( index );
00192 }
00193 }
00194 }
00195
00196 void KTabWidget::changeTab( QWidget *w, const QIconSet &iconset, const QString &label )
00197 {
00198 QTabWidget::changeTab( w, iconset, label );
00199 if ( d->m_automaticResizeTabs ) {
00200 int index = indexOf( w );
00201 if ( index != -1 ) {
00202 d->m_tabNames[ index ] = label;
00203 resizeTabs( index );
00204 }
00205 }
00206 }
00207
00208 QString KTabWidget::label( int index ) const
00209 {
00210 if ( d->m_automaticResizeTabs ) {
00211 if ( index >= 0 && index < count() )
00212 return d->m_tabNames[ index ];
00213 else
00214 return QString::null;
00215 }
00216 else
00217 return QTabWidget::label( index );
00218 }
00219
00220 QString KTabWidget::tabLabel( QWidget * w ) const
00221 {
00222 if ( d->m_automaticResizeTabs ) {
00223 int index = indexOf( w );
00224 if ( index == -1 )
00225 return QString::null;
00226 else
00227 return d->m_tabNames[ index ];
00228 }
00229 else
00230 return QTabWidget::tabLabel( w );
00231 }
00232
00233 void KTabWidget::setTabLabel( QWidget *w, const QString &l )
00234 {
00235 QTabWidget::setTabLabel( w, l );
00236 if ( d->m_automaticResizeTabs ) {
00237 int index = indexOf( w );
00238 if ( index != -1 ) {
00239 d->m_tabNames[ index ] = l;
00240 resizeTabs( index );
00241 }
00242 }
00243 }
00244
00245 void KTabWidget::resizeTabs( int changeTabIndex )
00246 {
00247 uint newMaxLength;
00248 if ( d->m_automaticResizeTabs ) {
00249
00250 newMaxLength=d->m_maxLength;
00251 uint lcw=0, rcw=0;
00252
00253 int tabBarHeight = tabBar()->sizeHint().height();
00254 if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
00255 lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
00256 if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
00257 rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight );
00258
00259 uint maxTabBarWidth = width() - lcw - rcw;
00260
00261 for ( ; newMaxLength > (uint)d->m_minLength; newMaxLength-- ) {
00262 if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
00263 break;
00264 }
00265 }
00266 else
00267 newMaxLength = 4711;
00268
00269
00270 if ( d->m_CurrentMaxLength != newMaxLength ) {
00271 d->m_CurrentMaxLength = newMaxLength;
00272 for( int i = 0; i < count(); ++i )
00273 updateTab( i );
00274 }
00275 else if ( changeTabIndex != -1 )
00276 updateTab( changeTabIndex );
00277 }
00278
00279 void KTabWidget::updateTab( int index )
00280 {
00281 QString title = d->m_automaticResizeTabs ? d->m_tabNames[ index ] : QTabWidget::label( index );
00282 removeTabToolTip( page( index ) );
00283 if ( title.length() > d->m_CurrentMaxLength )
00284 setTabToolTip( page( index ), title );
00285
00286 title = KStringHandler::rsqueeze( title, d->m_CurrentMaxLength ).leftJustify( d->m_minLength, ' ' );
00287 title.replace( '&', "&&" );
00288
00289 if ( QTabWidget::label( index ) != title )
00290 QTabWidget::setTabLabel( page( index ), title );
00291 }
00292
00293 void KTabWidget::dragMoveEvent( QDragMoveEvent *e )
00294 {
00295 if ( isEmptyTabbarSpace( e->pos() ) ) {
00296 bool accept = false;
00297
00298
00299 emit testCanDecode( e, accept);
00300 e->accept( accept );
00301 return;
00302 }
00303 e->accept( false );
00304 QTabWidget::dragMoveEvent( e );
00305 }
00306
00307 void KTabWidget::dropEvent( QDropEvent *e )
00308 {
00309 if ( isEmptyTabbarSpace( e->pos() ) ) {
00310 emit ( receivedDropEvent( e ) );
00311 return;
00312 }
00313 QTabWidget::dropEvent( e );
00314 }
00315
00316 #ifndef QT_NO_WHEELEVENT
00317 void KTabWidget::wheelEvent( QWheelEvent *e )
00318 {
00319 if ( e->orientation() == Horizontal )
00320 return;
00321
00322 if ( isEmptyTabbarSpace( e->pos() ) )
00323 wheelDelta( e->delta() );
00324 else
00325 e->ignore();
00326 }
00327
00328 void KTabWidget::wheelDelta( int delta )
00329 {
00330 if ( count() < 2 )
00331 return;
00332
00333 int page = currentPageIndex();
00334 if ( delta < 0 )
00335 page = (page + 1) % count();
00336 else {
00337 page--;
00338 if ( page < 0 )
00339 page = count() - 1;
00340 }
00341 setCurrentPage( page );
00342 }
00343 #endif
00344
00345 void KTabWidget::mouseDoubleClickEvent( QMouseEvent *e )
00346 {
00347 if( e->button() != LeftButton )
00348 return;
00349
00350 if ( isEmptyTabbarSpace( e->pos() ) ) {
00351 emit( mouseDoubleClick() );
00352 return;
00353 }
00354 QTabWidget::mouseDoubleClickEvent( e );
00355 }
00356
00357 void KTabWidget::mousePressEvent( QMouseEvent *e )
00358 {
00359 if ( e->button() == RightButton ) {
00360 if ( isEmptyTabbarSpace( e->pos() ) ) {
00361 emit( contextMenu( mapToGlobal( e->pos() ) ) );
00362 return;
00363 }
00364 } else if ( e->button() == MidButton ) {
00365 if ( isEmptyTabbarSpace( e->pos() ) ) {
00366 emit( mouseMiddleClick() );
00367 return;
00368 }
00369 }
00370 QTabWidget::mousePressEvent( e );
00371 }
00372
00373 void KTabWidget::receivedDropEvent( int index, QDropEvent *e )
00374 {
00375 emit( receivedDropEvent( page( index ), e ) );
00376 }
00377
00378 void KTabWidget::initiateDrag( int index )
00379 {
00380 emit( initiateDrag( page( index ) ) );
00381 }
00382
00383 void KTabWidget::contextMenu( int index, const QPoint &p )
00384 {
00385 emit( contextMenu( page( index ), p ) );
00386 }
00387
00388 void KTabWidget::mouseDoubleClick( int index )
00389 {
00390 emit( mouseDoubleClick( page( index ) ) );
00391 }
00392
00393 void KTabWidget::mouseMiddleClick( int index )
00394 {
00395 emit( mouseMiddleClick( page( index ) ) );
00396 }
00397
00398 void KTabWidget::moveTab( int from, int to )
00399 {
00400 QString tablabel = label( from );
00401 QWidget *w = page( from );
00402 QColor color = tabColor( w );
00403 QIconSet tabiconset = tabIconSet( w );
00404 QString tabtooltip = tabToolTip( w );
00405 bool current = ( w == currentPage() );
00406 bool enabled = isTabEnabled( w );
00407 blockSignals(true);
00408 removePage( w );
00409
00410
00411 QTab * t = new QTab();
00412 t->setText(tablabel);
00413 QTabWidget::insertTab( w, t, to );
00414 if ( d->m_automaticResizeTabs ) {
00415 if ( to < 0 || to >= count() )
00416 d->m_tabNames.append( QString::null );
00417 else
00418 d->m_tabNames.insert( d->m_tabNames.at( to ), QString::null );
00419 }
00420
00421 w = page( to );
00422 changeTab( w, tabiconset, tablabel );
00423 setTabToolTip( w, tabtooltip );
00424 setTabColor( w, color );
00425 if ( current )
00426 showPage( w );
00427 setTabEnabled( w, enabled );
00428 blockSignals(false);
00429
00430 emit ( movedTab( from, to ) );
00431 }
00432
00433 void KTabWidget::removePage( QWidget * w ) {
00434 if ( d->m_automaticResizeTabs ) {
00435 int index = indexOf( w );
00436 if ( index != -1 )
00437 d->m_tabNames.remove( d->m_tabNames.at( index ) );
00438 }
00439 QTabWidget::removePage( w );
00440 if ( d->m_automaticResizeTabs )
00441 resizeTabs();
00442 }
00443
00444
00445 bool KTabWidget::isEmptyTabbarSpace( const QPoint &p ) const
00446 {
00447 QPoint point( p );
00448 QSize size( tabBar()->sizeHint() );
00449 if ( ( tabPosition()==Top && point.y()< size.height() ) || ( tabPosition()==Bottom && point.y()>(height()-size.height() ) ) ) {
00450 QWidget *rightcorner = cornerWidget( TopRight );
00451 if ( rightcorner ) {
00452 if ( point.x()>=width()-rightcorner->width() )
00453 return false;
00454 }
00455 QWidget *leftcorner = cornerWidget( TopLeft );
00456 if ( leftcorner ) {
00457 if ( point.x()<=leftcorner->width() )
00458 return false;
00459 point.setX( point.x()-size.height() );
00460 }
00461 if ( tabPosition()==Bottom )
00462 point.setY( point.y()-( height()-size.height() ) );
00463 QTab *tab = tabBar()->selectTab( point);
00464 if( !tab )
00465 return true;
00466 }
00467 return false;
00468 }
00469
00470 void KTabWidget::setHoverCloseButton( bool button )
00471 {
00472 static_cast<KTabBar*>(tabBar())->setHoverCloseButton( button );
00473 }
00474
00475 bool KTabWidget::hoverCloseButton() const
00476 {
00477 return static_cast<KTabBar*>(tabBar())->hoverCloseButton();
00478 }
00479
00480 void KTabWidget::setHoverCloseButtonDelayed( bool delayed )
00481 {
00482 static_cast<KTabBar*>(tabBar())->setHoverCloseButtonDelayed( delayed );
00483 }
00484
00485 bool KTabWidget::hoverCloseButtonDelayed() const
00486 {
00487 return static_cast<KTabBar*>(tabBar())->hoverCloseButtonDelayed();
00488 }
00489
00490 void KTabWidget::setAutomaticResizeTabs( bool enabled )
00491 {
00492 if ( d->m_automaticResizeTabs==enabled )
00493 return;
00494
00495 d->m_automaticResizeTabs = enabled;
00496 if ( enabled ) {
00497 d->m_tabNames.clear();
00498 for( int i = 0; i < count(); ++i )
00499 d->m_tabNames.append( tabBar()->tabAt( i )->text() );
00500 }
00501 else
00502 for( int i = 0; i < count(); ++i )
00503 tabBar()->tabAt( i )->setText( d->m_tabNames[ i ] );
00504 resizeTabs();
00505 }
00506
00507 bool KTabWidget::automaticResizeTabs() const
00508 {
00509 return d->m_automaticResizeTabs;
00510 }
00511
00512 void KTabWidget::closeRequest( int index )
00513 {
00514 emit( closeRequest( page( index ) ) );
00515 }
00516
00517 void KTabWidget::resizeEvent( QResizeEvent *e )
00518 {
00519 QTabWidget::resizeEvent( e );
00520 resizeTabs();
00521 }
00522
00523 #include "ktabwidget.moc"