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