• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

ktabwidget.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00018   Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "ktabwidget.h"
00022 
00023 #include <QtGui/QApplication>
00024 #include <QtGui/QDragMoveEvent>
00025 #include <QtGui/QDropEvent>
00026 #include <QtGui/QMouseEvent>
00027 #include <QtGui/QStyle>
00028 #include <QtGui/QStyleOption>
00029 #include <QtGui/QTextDocument>
00030 #include <QtGui/QWheelEvent>
00031 #include <QtCore/QList>
00032 
00033 #include <ksharedconfig.h>
00034 #include <kiconloader.h>
00035 #include <kstringhandler.h>
00036 
00037 #include <ktabbar.h>
00038 
00039 #include <kconfiggroup.h>
00040 
00041 class KTabWidget::Private
00042 {
00043   public:
00044     Private( KTabWidget *parent )
00045       : m_parent( parent ),
00046         m_automaticResizeTabs( false )
00047     {
00048 
00049       KConfigGroup cg(KGlobal::config(), "General");
00050       m_maxLength = cg.readEntry("MaximumTabLength", 30);
00051       m_minLength = cg.readEntry("MinimumTabLength", 3);
00052       m_currentMaxLength = m_minLength;
00053     }
00054 
00055     KTabWidget *m_parent;
00056     bool m_automaticResizeTabs;
00057     int m_maxLength;
00058     int m_minLength;
00059     int m_currentMaxLength;
00060 
00061     //holds the full names of the tab, otherwise all we
00062     //know about is the shortened name
00063     QStringList m_tabNames;
00064     
00065     // Used when tabCloseActivatePrevious is enabled
00066     QList<QWidget*> m_previousTabList;
00067 
00068     bool isEmptyTabbarSpace( const QPoint & )  const;
00069     void resizeTabs( int changedTabIndex = -1 );
00070     void updateTab( int index );
00071     void removeTab( int index );
00072 };
00073 
00074 bool KTabWidget::Private::isEmptyTabbarSpace( const QPoint &point ) const
00075 {
00076     if (m_parent->count() == 0) {
00077         return true;
00078     }
00079     if (m_parent->tabBar()->isHidden()) {
00080         return false;
00081     }
00082   QSize size( m_parent->tabBar()->sizeHint() );
00083   if ( ( m_parent->tabPosition() == QTabWidget::North && point.y() < size.height() ) ||
00084        ( m_parent->tabPosition() == QTabWidget::South && point.y() > (m_parent->height() - size.height() ) ) ) {
00085 
00086     QWidget *rightcorner = m_parent->cornerWidget( Qt::TopRightCorner );
00087     if ( rightcorner && rightcorner->isVisible() ) {
00088       if ( point.x() >= m_parent->width()-rightcorner->width() )
00089         return false;
00090     }
00091 
00092     QWidget *leftcorner = m_parent->cornerWidget( Qt::TopLeftCorner );
00093     if ( leftcorner && leftcorner->isVisible() ) {
00094       if ( point.x() <= leftcorner->width() )
00095         return false;
00096     }
00097 
00098     for ( int i = 0; i < m_parent->count(); ++i )
00099       if ( m_parent->tabBar()->tabRect( i ).contains( m_parent->tabBar()->mapFromParent( point ) ) )
00100         return false;
00101 
00102     return true;
00103   }
00104 
00105   return false;
00106 }
00107 
00108 void KTabWidget::Private::removeTab( int index )
00109 {
00110   m_previousTabList.removeOne( m_parent->widget( index ) );
00111   
00112   // We need to get the widget for "activate previous" before calling to 
00113   // QTabWidget::removeTab() because that call changes currentIndex which calls
00114   // to currentChanged() and thus modifies m_previousTabList.first(). And we
00115   // store the widget and not the index of it because the index might be changed
00116   // by the removeTab call.
00117   QWidget *widget = 0;
00118   if( !m_previousTabList.isEmpty() && m_parent->tabCloseActivatePrevious() )
00119     widget = m_previousTabList.first();
00120   
00121   m_parent->QTabWidget::removeTab( index );
00122   
00123   if( widget )
00124     m_parent->setCurrentIndex( m_parent->indexOf( widget ) );
00125 }
00126 
00127 void KTabWidget::Private::resizeTabs( int changeTabIndex )
00128 {
00129   int newMaxLength;
00130   if ( m_automaticResizeTabs ) {
00131     // Calculate new max length
00132     newMaxLength = m_maxLength;
00133     int lcw = 0, rcw = 0;
00134 
00135     int tabBarHeight = m_parent->tabBar()->sizeHint().height();
00136     if ( m_parent->cornerWidget( Qt::TopLeftCorner ) && m_parent->cornerWidget( Qt::TopLeftCorner )->isVisible() )
00137       lcw = qMax( m_parent->cornerWidget( Qt::TopLeftCorner )->width(), tabBarHeight );
00138 
00139     if ( m_parent->cornerWidget( Qt::TopRightCorner ) && m_parent->cornerWidget( Qt::TopRightCorner )->isVisible() )
00140       rcw = qMax( m_parent->cornerWidget( Qt::TopRightCorner )->width(), tabBarHeight );
00141 
00142     int maxTabBarWidth = m_parent->width() - lcw - rcw;
00143 
00144     for ( ; newMaxLength > m_minLength; newMaxLength-- ) {
00145       if ( m_parent->tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
00146         break;
00147     }
00148   } else
00149     newMaxLength = 4711;
00150 
00151   // Update hinted or all tabs
00152   if ( m_currentMaxLength != newMaxLength ) {
00153     m_currentMaxLength = newMaxLength;
00154     for ( int i = 0; i < m_parent->count(); ++i )
00155       updateTab( i );
00156   } else if ( changeTabIndex != -1 )
00157     updateTab( changeTabIndex );
00158 }
00159 
00160 void KTabWidget::Private::updateTab( int index )
00161 {
00162   QString title = m_automaticResizeTabs ? m_tabNames[ index ] : m_parent->QTabWidget::tabText( index );
00163   m_parent->setTabToolTip( index, QString() );
00164 
00165   if ( title.length() > m_currentMaxLength ) {
00166     if ( Qt::mightBeRichText( title ) )
00167       m_parent->setTabToolTip( index, Qt::escape( title ) );
00168     else
00169       m_parent->setTabToolTip( index, title );
00170   }
00171 
00172   title = KStringHandler::rsqueeze( title, m_currentMaxLength ).leftJustified( m_minLength, ' ' );
00173   title.replace( '&', "&&" );
00174 
00175   if ( m_parent->QTabWidget::tabText( index ) != title )
00176     m_parent->QTabWidget::setTabText( index, title );
00177 }
00178 
00179 KTabWidget::KTabWidget( QWidget *parent, Qt::WFlags flags )
00180   : QTabWidget( parent ),
00181     d( new Private( this ) )
00182 {
00183   setWindowFlags( flags );
00184   setTabBar( new KTabBar( this ) );
00185   setObjectName( "tabbar" );
00186   setAcceptDrops( true );
00187 
00188   connect(tabBar(), SIGNAL(contextMenu( int, const QPoint & )), SLOT(contextMenu( int, const QPoint & )));
00189   connect(tabBar(), SIGNAL(tabDoubleClicked( int )), SLOT(mouseDoubleClick( int )));
00190   connect(tabBar(), SIGNAL(mouseMiddleClick( int )), SLOT(mouseMiddleClick( int )));
00191   connect(tabBar(), SIGNAL(initiateDrag( int )), SLOT(initiateDrag( int )));
00192   connect(tabBar(), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )));
00193   connect(tabBar(), SIGNAL(receivedDropEvent( int, QDropEvent * )), SLOT(receivedDropEvent( int, QDropEvent * )));
00194   connect(tabBar(), SIGNAL(moveTab( int, int )), SLOT(moveTab( int, int )));
00195   connect(tabBar(), SIGNAL(closeRequest( int )), SLOT(closeRequest( int )));
00196   connect(tabBar(), SIGNAL(currentChanged( int )), SLOT(currentChanged( int )));
00197 #ifndef QT_NO_WHEELEVENT
00198   connect(tabBar(), SIGNAL(wheelDelta( int )), SLOT(wheelDelta( int )));
00199 #endif
00200 }
00201 
00202 KTabWidget::~KTabWidget()
00203 {
00204   delete d;
00205 }
00206 
00207 /*void KTabWidget::insertTab( QWidget *child, const QString &label, int index )
00208 {
00209   QTabWidget::insertTab( child, label, index );
00210 }
00211 
00212 void KTabWidget::insertTab( QWidget *child, const QIcon& iconset, const QString &label, int index )
00213 {
00214   QTabWidget::insertTab( child, iconset, label, index );
00215 }
00216 
00217 void KTabWidget::insertTab( QWidget *child, QTab *tab, int index )
00218 {
00219   QTabWidget::insertTab( child, tab, index);
00220   if ( d->m_automaticResizeTabs ) {
00221     if ( index < 0 || index >= count() ) {
00222       d->m_tabNames.append( tab->text() );
00223       d->resizeTabs( d->m_tabNames.count()-1 );
00224     }
00225     else {
00226       d->m_tabNames.insert( d->m_tabNames.at( index ), tab->text() );
00227       d->resizeTabs( index );
00228     }
00229   }
00230 }*/
00231 
00232 void KTabWidget::setTabBarHidden( bool hide )
00233 {
00234   QWidget *rightcorner = cornerWidget( Qt::TopRightCorner );
00235   QWidget *leftcorner = cornerWidget( Qt::TopLeftCorner );
00236 
00237   if ( hide ) {
00238     if ( leftcorner ) leftcorner->hide();
00239     if ( rightcorner ) rightcorner->hide();
00240     tabBar()->hide();
00241   } else {
00242     tabBar()->show();
00243     if ( leftcorner ) leftcorner->show();
00244     if ( rightcorner ) rightcorner->show();
00245   }
00246 }
00247 
00248 bool KTabWidget::isTabBarHidden() const
00249 {
00250   return !( tabBar()->isVisible() );
00251 }
00252 
00253 void KTabWidget::setTabTextColor( int index, const QColor& color )
00254 {
00255   tabBar()->setTabTextColor( index, color );
00256 }
00257 
00258 QColor KTabWidget::tabTextColor( int index ) const
00259 {
00260   return tabBar()->tabTextColor( index );
00261 }
00262 
00263 void KTabWidget::setTabReorderingEnabled( bool on)
00264 {
00265   static_cast<KTabBar*>(tabBar())->setTabReorderingEnabled( on );
00266 }
00267 
00268 bool KTabWidget::isTabReorderingEnabled() const
00269 {
00270   return static_cast<KTabBar*>(tabBar())->isTabReorderingEnabled();
00271 }
00272 
00273 void KTabWidget::setTabCloseActivatePrevious( bool previous)
00274 {
00275   static_cast<KTabBar*>(tabBar())->setTabCloseActivatePrevious( previous );
00276 }
00277 
00278 bool KTabWidget::tabCloseActivatePrevious() const
00279 {
00280   return static_cast<KTabBar*>(tabBar())->tabCloseActivatePrevious();
00281 }
00282 
00283 int KTabWidget::tabBarWidthForMaxChars( int maxLength )
00284 {
00285   int hframe, overlap;
00286   hframe  = tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabHSpace, 0L, tabBar() );
00287   overlap = tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabOverlap, 0L, tabBar() );
00288 
00289   const QFontMetrics fm = tabBar()->fontMetrics();
00290   int x = 0;
00291   for ( int i = 0; i < count(); ++i ) {
00292     QString newTitle = d->m_tabNames[ i ];
00293     newTitle = KStringHandler::rsqueeze( newTitle, maxLength ).leftJustified( d->m_minLength, ' ' );
00294 
00295     int lw = fm.width( newTitle );
00296     int iw = 0;
00297     if ( !tabBar()->tabIcon( i ).isNull() ) {
00298       iw = tabBar()->tabIcon( i ).pixmap( style()->pixelMetric( QStyle::PM_SmallIconSize ), QIcon::Normal ).width() + 4;
00299     }
00300     if ( isCloseButtonEnabled() ) {
00301       // FIXME: how to get the size of the close button directly from the tabBar()?
00302       iw += KIconLoader::SizeSmall * 3 / 2;
00303     }
00304     x += ( tabBar()->style()->sizeFromContents( QStyle::CT_TabBarTab, 0L,
00305          QSize( qMax( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ),
00306          this ) ).width();
00307   }
00308 
00309   return x;
00310 }
00311 
00312 QString KTabWidget::tabText( int index ) const
00313 {
00314     if ( d->m_automaticResizeTabs ) {
00315         if (index >= 0 && index < count()) {
00316             if (index >= d->m_tabNames.count()) {
00317                 // Ooops, the tab exists, but tabInserted wasn't called yet.
00318                 // This can happen when inserting the first tab,
00319                 // and calling tabText from slotCurrentChanged,
00320                 // see KTabWidget_UnitTest.
00321                 const_cast<KTabWidget*>(this)->tabInserted(index);
00322             }
00323             return d->m_tabNames[ index ];
00324         }
00325         else
00326             return QString();
00327     }
00328     else
00329         return QTabWidget::tabText( index );
00330 }
00331 
00332 void KTabWidget::setTabText( int index, const QString &text )
00333 {
00334   if (text == tabText(index))
00335     return;
00336 
00337   if ( d->m_automaticResizeTabs ) {
00338 
00339     tabBar()->setUpdatesEnabled(false); //no flicker
00340 
00341     QTabWidget::setTabText( index, text );
00342 
00343     if ( index != -1 ) {
00344       d->m_tabNames[ index ] = text;
00345       d->resizeTabs( index );
00346     }
00347 
00348     tabBar()->setUpdatesEnabled(true);
00349 
00350   } else {
00351     QTabWidget::setTabText( index, text );
00352   }
00353 }
00354 
00355 
00356 void KTabWidget::dragEnterEvent( QDragEnterEvent *event )
00357 {
00358   if ( d->isEmptyTabbarSpace( event->pos() ) ) {
00359     bool accept = false;
00360     // The receivers of the testCanDecode() signal has to adjust
00361     // 'accept' accordingly.
00362     emit testCanDecode( event, accept);
00363 
00364     event->setAccepted( accept );
00365     return;
00366   }
00367 
00368   QTabWidget::dragEnterEvent( event );
00369 }
00370 
00371 void KTabWidget::dragMoveEvent( QDragMoveEvent *event )
00372 {
00373   if ( d->isEmptyTabbarSpace( event->pos() ) ) {
00374     bool accept = false;
00375     // The receivers of the testCanDecode() signal has to adjust
00376     // 'accept' accordingly.
00377     emit testCanDecode( event, accept);
00378 
00379     event->setAccepted( accept );
00380     return;
00381   }
00382 
00383   QTabWidget::dragMoveEvent( event );
00384 }
00385 
00386 void KTabWidget::dropEvent( QDropEvent *event )
00387 {
00388   if ( d->isEmptyTabbarSpace( event->pos() ) ) {
00389     emit ( receivedDropEvent( event ) );
00390     return;
00391   }
00392 
00393   QTabWidget::dropEvent( event );
00394 }
00395 
00396 #ifndef QT_NO_WHEELEVENT
00397 void KTabWidget::wheelEvent( QWheelEvent *event )
00398 {
00399   if ( event->orientation() == Qt::Horizontal )
00400     return;
00401 
00402   if ( d->isEmptyTabbarSpace( event->pos() ) )
00403     wheelDelta( event->delta() );
00404   else
00405     event->ignore();
00406 }
00407 
00408 void KTabWidget::wheelDelta( int delta )
00409 {
00410   if ( count() < 2 )
00411     return;
00412 
00413   int page = currentIndex();
00414   if ( delta < 0 )
00415      page = (page + 1) % count();
00416   else {
00417     page--;
00418     if ( page < 0 )
00419       page = count() - 1;
00420   }
00421   setCurrentIndex( page );
00422 }
00423 #endif
00424 
00425 void KTabWidget::mouseDoubleClickEvent( QMouseEvent *event )
00426 {
00427   if ( event->button() != Qt::LeftButton )
00428     return;
00429 
00430   if ( d->isEmptyTabbarSpace( event->pos() ) ) {
00431     emit( mouseDoubleClick() );
00432     return;
00433   }
00434 
00435   QTabWidget::mouseDoubleClickEvent( event );
00436 }
00437 
00438 void KTabWidget::mousePressEvent( QMouseEvent *event )
00439 {
00440   if ( event->button() == Qt::RightButton ) {
00441     if ( d->isEmptyTabbarSpace( event->pos() ) ) {
00442       emit( contextMenu( mapToGlobal( event->pos() ) ) );
00443       return;
00444     }
00445   } else if ( event->button() == Qt::MidButton ) {
00446     if ( d->isEmptyTabbarSpace( event->pos() ) ) {
00447       emit( mouseMiddleClick() );
00448       return;
00449     }
00450   }
00451 
00452   QTabWidget::mousePressEvent( event );
00453 }
00454 
00455 void KTabWidget::receivedDropEvent( int index, QDropEvent *event )
00456 {
00457   emit( receivedDropEvent( widget( index ), event ) );
00458 }
00459 
00460 void KTabWidget::initiateDrag( int index )
00461 {
00462   emit( initiateDrag( widget( index ) ) );
00463 }
00464 
00465 void KTabWidget::contextMenu( int index, const QPoint &point )
00466 {
00467   emit( contextMenu( widget( index ), point ) );
00468 }
00469 
00470 void KTabWidget::mouseDoubleClick( int index )
00471 {
00472   emit( mouseDoubleClick( widget( index ) ) );
00473 }
00474 
00475 void KTabWidget::mouseMiddleClick( int index )
00476 {
00477   emit( mouseMiddleClick( widget( index ) ) );
00478 }
00479 
00480 void KTabWidget::moveTab( int from, int to )
00481 {
00482   setUpdatesEnabled(false);
00483 
00484   const QString tablabel = tabText( from );
00485   QWidget *w = widget( from );
00486   const QColor color = tabTextColor( from );
00487   const QIcon tabiconset = tabIcon( from );
00488   const QString tabtooltip = tabToolTip( from );
00489   const bool current = ( from == currentIndex() );
00490   const bool enabled = isTabEnabled( from );
00491 
00492   const bool blocked = blockSignals( true );
00493   removeTab( from );
00494   insertTab( to, w, tablabel );
00495 
00496   setTabIcon( to, tabiconset );
00497   setTabText( to, tablabel );
00498   setTabToolTip( to, tabtooltip );
00499   setTabTextColor( to, color );
00500   if ( current )
00501     setCurrentIndex( to );
00502   setTabEnabled( to, enabled );
00503   if ( d->m_automaticResizeTabs ) {
00504     d->resizeTabs( to );
00505   }
00506   blockSignals( blocked );
00507 
00508   setUpdatesEnabled(true);
00509 
00510   emit ( movedTab( from, to ) );
00511 }
00512 
00513 void KTabWidget::removePage( QWidget *widget )
00514 {
00515   if ( d->m_automaticResizeTabs ) {
00516 
00517     setUpdatesEnabled(false);
00518 
00519     d->removeTab( indexOf( widget ) );
00520     d->resizeTabs();
00521 
00522     setUpdatesEnabled(true);
00523 
00524   } else {
00525     d->removeTab( indexOf( widget ) );
00526   }
00527 }
00528 
00529 void KTabWidget::removeTab( int index )
00530 {
00531   if ( d->m_automaticResizeTabs ) {
00532 
00533     setUpdatesEnabled(false);
00534 
00535     d->removeTab( index );
00536     d->resizeTabs();
00537 
00538     setUpdatesEnabled(true);
00539 
00540   } else {
00541     d->removeTab( index );
00542   }
00543 }
00544 
00545 void KTabWidget::setHoverCloseButton( bool button )
00546 {
00547   // deprecated
00548   setCloseButtonEnabled( button );
00549 }
00550 
00551 bool KTabWidget::hoverCloseButton() const
00552 {
00553   // deprecated
00554   return false;
00555 }
00556 
00557 void KTabWidget::setHoverCloseButtonDelayed( bool delayed )
00558 {
00559   // deprecated
00560   Q_UNUSED( delayed );
00561 }
00562 
00563 bool KTabWidget::hoverCloseButtonDelayed() const
00564 {
00565   // deprecated
00566   return isCloseButtonEnabled();
00567 }
00568 
00569 void KTabWidget::setCloseButtonEnabled( bool enable )
00570 {
00571   static_cast<KTabBar*>( tabBar() )->setCloseButtonEnabled( enable );
00572 }
00573 
00574 bool KTabWidget::isCloseButtonEnabled() const
00575 {
00576   return static_cast<KTabBar*>( tabBar() )->isCloseButtonEnabled();
00577 }
00578 
00579 void KTabWidget::setAutomaticResizeTabs( bool enabled )
00580 {
00581   if ( d->m_automaticResizeTabs == enabled )
00582     return;
00583 
00584   setUpdatesEnabled(false);
00585 
00586   d->m_automaticResizeTabs = enabled;
00587   if ( enabled ) {
00588     d->m_tabNames.clear();
00589     for ( int i = 0; i < count(); ++i )
00590       d->m_tabNames.append( tabBar()->tabText( i ) );
00591   } else
00592     for ( int i = 0; i < count(); ++i )
00593       tabBar()->setTabText( i, d->m_tabNames[ i ] );
00594 
00595   d->resizeTabs();
00596 
00597   setUpdatesEnabled(true);
00598 }
00599 
00600 bool KTabWidget::automaticResizeTabs() const
00601 {
00602   return d->m_automaticResizeTabs;
00603 }
00604 
00605 void KTabWidget::closeRequest( int index )
00606 {
00607   emit( closeRequest( widget( index ) ) );
00608 }
00609 
00610 void KTabWidget::resizeEvent( QResizeEvent *event )
00611 {
00612   QTabWidget::resizeEvent( event );
00613   d->resizeTabs();
00614 }
00615 
00616 void KTabWidget::tabInserted( int idx )
00617 {
00618    d->m_tabNames.insert( idx, tabBar()->tabText( idx ) );
00619 }
00620 
00621 void KTabWidget::tabRemoved( int idx )
00622 {
00623    d->m_tabNames.removeAt( idx );
00624 }
00625 
00626 void KTabWidget::currentChanged( int idx )
00627 {
00628    // The tab should appear only once
00629    d->m_previousTabList.removeOne( widget(idx) );
00630    
00631    d->m_previousTabList.push_front( widget(idx) );
00632 }
00633 
00634 #include "ktabwidget.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal