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