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