kdeui Library API Documentation

ktabwidget.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2003 Stephan Binner <binner@kde.org> 00003 Copyright (C) 2003 Zack Rusin <zack@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 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 //holds the full names of the tab, otherwise all we 00039 //know about is the shortened name 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 // Calculate new max length 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 // Update hinted or all tabs 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 // The receivers of the testCanDecode() signal has to adjust 00298 // 'accept' accordingly. 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 // Work-around kmdi brain damage which calls showPage() in insertTab() 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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 22:56:32 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003