• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

Kross

model.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  * model.cpp
00003  * This file is part of the KDE project
00004  * copyright (C) 2006-2007 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program 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  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "model.h"
00021 
00022 #include <kross/core/action.h>
00023 #include <kross/core/actioncollection.h>
00024 #include <kross/core/manager.h>
00025 
00026 #include <kglobal.h>
00027 #include <klocale.h>
00028 #include <kdebug.h>
00029 
00030 #include <QtCore/QEvent>
00031 #include <QtCore/QMimeData>
00032 #include <QtCore/QPointer>
00033 
00034 using namespace Kross;
00035 
00036 /******************************************************************************
00037  * ActionCollectionModel
00038  */
00039 
00040 namespace Kross {
00041 
00043     class ActionCollectionModel::Private
00044     {
00045         public:
00046             QPointer<ActionCollection> collection;
00047             Mode mode;
00048     };
00049 
00050 }
00051 
00052 ActionCollectionModel::ActionCollectionModel(QObject* parent, ActionCollection* collection, Mode mode)
00053     : QAbstractItemModel(parent)
00054     , d( new Private() )
00055 {
00056     //krossdebug( QString( "ActionCollectionModel::ActionCollectionModel:") );
00057     d->collection = collection ? collection : Kross::Manager::self().actionCollection();
00058     d->mode = mode;
00059     //setSupportedDragActions(Qt::MoveAction);
00060 
00061     //ActionCollection propagates signals to parent
00062     QObject::connect( d->collection, SIGNAL( dataChanged( Action* ) ), this, SLOT( slotDataChanged( Action* ) ) );
00063     QObject::connect( d->collection, SIGNAL( dataChanged( ActionCollection* ) ), this, SLOT( slotDataChanged( ActionCollection* ) ) );
00064 
00065     QObject::connect( d->collection, SIGNAL( collectionToBeInserted( ActionCollection*, ActionCollection* ) ), this, SLOT( slotCollectionToBeInserted( ActionCollection*, ActionCollection* ) ) );
00066     QObject::connect( d->collection, SIGNAL( collectionInserted( ActionCollection*, ActionCollection* ) ), this, SLOT( slotCollectionInserted( ActionCollection*, ActionCollection* ) ) );
00067     QObject::connect( d->collection, SIGNAL( collectionToBeRemoved( ActionCollection*, ActionCollection* ) ), this, SLOT( slotCollectionToBeRemoved( ActionCollection*, ActionCollection* ) ) );
00068     QObject::connect( d->collection, SIGNAL( collectionRemoved( ActionCollection*, ActionCollection* ) ), this, SLOT( slotCollectionRemoved( ActionCollection*, ActionCollection* ) ) );
00069 
00070     QObject::connect( d->collection, SIGNAL( actionToBeInserted( Action*, ActionCollection* ) ), this, SLOT( slotActionToBeInserted( Action*, ActionCollection* ) ) );
00071     QObject::connect( d->collection, SIGNAL( actionInserted( Action*, ActionCollection* ) ), this, SLOT( slotActionInserted( Action*, ActionCollection* ) ) );
00072     QObject::connect( d->collection, SIGNAL( actionToBeRemoved( Action*, ActionCollection* ) ), this, SLOT( slotActionToBeRemoved( Action*, ActionCollection* ) ) );
00073     QObject::connect( d->collection, SIGNAL( actionRemoved( Action*, ActionCollection* ) ), this, SLOT( slotActionRemoved( Action*, ActionCollection* ) ) );
00074 }
00075 
00076 ActionCollectionModel::~ActionCollectionModel()
00077 {
00078     delete d;
00079 }
00080 
00081 ActionCollection *ActionCollectionModel::rootCollection() const
00082 {
00083     return d->collection;
00084 }
00085 
00086 int ActionCollectionModel::rowNumber( ActionCollection *collection ) const
00087 {
00088     Q_ASSERT( collection != 0 );
00089     ActionCollection *par = collection->parentCollection();
00090     Q_ASSERT( par != 0 );
00091     int row = par->collections().indexOf( collection->objectName() ) + par->actions().count();
00092     return row;
00093 }
00094 
00095 QModelIndex ActionCollectionModel::indexForCollection( ActionCollection *collection ) const
00096 {
00097     if ( collection == d->collection ) {
00098         return QModelIndex();
00099     }
00100     return createIndex( rowNumber( collection ), 0, collection->parentCollection() );
00101 }
00102 
00103 QModelIndex ActionCollectionModel::indexForAction( Action *act ) const
00104 {
00105     ActionCollection *coll = static_cast<ActionCollection*>( act->parent() );
00106     return createIndex( coll->actions().indexOf( act ), 0, coll );
00107 }
00108 
00109 void ActionCollectionModel::slotCollectionToBeInserted( ActionCollection* child, ActionCollection* parent )
00110 {
00111     //krossdebug( QString( "ActionCollectionModel::slotCollectionToBeInserted: %1 %2" ).arg( child->name() ).arg( parent->name( ) )  );
00112     Q_ASSERT( parent );
00113     Q_UNUSED( child )
00114     int row = parent->actions().count() + parent->collections().count(); // we assume child is appended!!
00115     QModelIndex parIdx = indexForCollection( parent );
00116     beginInsertRows( parIdx, row, row );
00117 }
00118 
00119 void ActionCollectionModel::slotCollectionInserted( ActionCollection*, ActionCollection* )
00120 {
00121     //krossdebug( QString( "ActionCollectionModel::slotCollectionInserted: %1 %2" ).arg( child->name( ) ).arg( parent->name( ) )  );
00122     endInsertRows();
00123 }
00124 
00125 void ActionCollectionModel::slotCollectionToBeRemoved( ActionCollection* child, ActionCollection* parent )
00126 {
00127     //krossdebug( QString( "ActionCollectionModel::slotCollectionToBeRemoved: %1 %2" ).arg( child->name() ).arg( parent->name() ) );
00128     int row = rowNumber( child );
00129     QModelIndex parIdx = indexForCollection( parent );
00130     beginRemoveRows( parIdx, row, row );
00131 }
00132 
00133 void ActionCollectionModel::slotCollectionRemoved( ActionCollection*, ActionCollection* )
00134 {
00135     //krossdebug( QString( "ActionCollectionModel::slotCollectionRemoved: %1 %2" ).arg( child->name() ).arg( parent->name() ) );
00136     endRemoveRows();
00137 }
00138 
00139 void ActionCollectionModel::slotActionToBeInserted( Action* child, ActionCollection* parent )
00140 {
00141     //krossdebug( QString( "ActionCollectionModel::slotActionInserted: %1 %2" ).arg( child->name() ).arg( parent->name() ) );
00142     Q_ASSERT( parent );
00143     Q_UNUSED( child )
00144     int row = parent->actions().count(); // assume child is appended to actions!!
00145     QModelIndex parIdx = indexForCollection( parent );
00146     beginInsertRows( parIdx, row, row );
00147 }
00148 
00149 void ActionCollectionModel::slotActionInserted( Action*, ActionCollection* )
00150 {
00151     //krossdebug( QString( "ActionCollectionModel::slotActionInserted: %1 %2" ).arg( child->name() ).arg( parent->name() ) );
00152     endInsertRows();
00153 }
00154 
00155 void ActionCollectionModel::slotActionToBeRemoved( Action* child, ActionCollection* parent )
00156 {
00157     //krossdebug( QString( "ActionCollectionModel::slotActionToBeRemoved: %1 %2" ).arg( child->name() ).arg( parent->name() ) );
00158     Q_ASSERT( parent );
00159     int row = parent->actions().indexOf( child );
00160     QModelIndex parIdx = indexForCollection( parent );
00161     beginRemoveRows( parIdx, row, row );
00162 }
00163 
00164 void ActionCollectionModel::slotActionRemoved( Action*, ActionCollection* )
00165 {
00166     //krossdebug( QString( "ActionCollectionModel::slotActionRemoved: %1 %2" ).arg( child->name() ).arg( parent->name() ) );
00167     endRemoveRows();
00168 }
00169 
00170 //NOTE: not used anymore, remove?
00171 void ActionCollectionModel::slotUpdated()
00172 {
00173     //emit layoutAboutToBeChanged();
00174     //emit layoutChanged();
00175 }
00176 
00177 void ActionCollectionModel::slotDataChanged( ActionCollection* coll )
00178 {
00179     //krossdebug( QString( "ActionCollectionModel::slotDataChanged: %1" ).arg( coll->name() ) );
00180     QModelIndex idx = indexForCollection( coll );
00181     emit dataChanged( idx, idx ); // NOTE: change if more than one column
00182 }
00183 
00184 void ActionCollectionModel::slotDataChanged( Action* act )
00185 {
00186     //krossdebug( QString( "ActionCollectionModel::slotDataChanged: %1" ).arg( act->name() ) );
00187     QModelIndex idx = indexForAction( act );
00188     emit dataChanged( idx, idx ); // NOTE: change if more than one column
00189 }
00190 
00191 Action* ActionCollectionModel::action(const QModelIndex& index)
00192 {
00193     ActionCollection *par = static_cast<ActionCollection*>( index.internalPointer() );
00194     if ( par == 0 || index.row() >= par->actions().count() ) {
00195         return 0;
00196     }
00197     return par->actions().value( index.row() );
00198 }
00199 
00200 ActionCollection* ActionCollectionModel::collection(const QModelIndex& index)
00201 {
00202     ActionCollection *par = static_cast<ActionCollection*>( index.internalPointer() );
00203     if ( par == 0 ) {
00204         return 0;
00205     }
00206     int row = index.row() - par->actions().count();
00207     if ( row < 0 ) {
00208         return 0; // this is probably an action
00209     }
00210     return par->collection( par->collections().value( row) );
00211 }
00212 
00213 int ActionCollectionModel::columnCount(const QModelIndex&) const
00214 {
00215     return 1;
00216 }
00217 
00218 int ActionCollectionModel::rowCount(const QModelIndex& index) const
00219 {
00220     if ( action( index) ) {
00221         return 0;
00222     }
00223     ActionCollection* par = index.isValid() ? collection( index ) : d->collection.data();
00224     Q_ASSERT_X( par, "ActionCollectionModel::rowCount", "index is not an action nor a collection" );
00225     if (!par) {
00226         kWarning()<<"index is not an action nor a collection"<<index;
00227         return 0;
00228     }
00229     int rows = par->actions().count() + par->collections().count();
00230     return rows;
00231 }
00232 
00233 QModelIndex ActionCollectionModel::index(int row, int column, const QModelIndex& parent) const
00234 {
00235     if ( ! hasIndex( row, column, parent ) ) {
00236         return QModelIndex();
00237     }
00238     ActionCollection* par = parent.isValid() ? collection( parent ) : d->collection.data();
00239     if ( par == 0 ) {
00240         // safety: may happen if parent index is an action (ModelTest tests this)
00241         return QModelIndex();
00242     }
00243     return createIndex( row, column, par );
00244 }
00245 
00246 QModelIndex ActionCollectionModel::parent(const QModelIndex& index) const
00247 {
00248     if( ! index.isValid() ) {
00249         return QModelIndex();
00250     }
00251     ActionCollection *par = static_cast<ActionCollection*>( index.internalPointer() );
00252     Q_ASSERT( par != 0 );
00253     if ( par == d->collection ) {
00254         return QModelIndex();
00255     }
00256     return createIndex( rowNumber( par ), 0, par->parentCollection() );
00257 }
00258 
00259 Qt::ItemFlags ActionCollectionModel::flags(const QModelIndex &index) const
00260 {
00261     Qt::ItemFlags flags = QAbstractItemModel::flags(index);
00262     if( ! index.isValid() )
00263         return Qt::ItemIsDropEnabled | flags;
00264 
00265     flags |= Qt::ItemIsSelectable;
00266     //flags |= Qt::ItemIsEditable;
00267     flags |= Qt::ItemIsDragEnabled;
00268     flags |= Qt::ItemIsDropEnabled;
00269 
00270     if( (index.column() == 0) && (d->mode & UserCheckable) )
00271         flags |= Qt::ItemIsUserCheckable;
00272     return flags;
00273 }
00274 
00275 QVariant ActionCollectionModel::data(const QModelIndex& index, int role) const
00276 {
00277     if( index.isValid() ) {
00278         Action *act = action( index );
00279         if ( act ) {
00280             switch( role ) {
00281                 case Qt::DecorationRole: {
00282                     if( d->mode & Icons )
00283                         if( ! act->iconName().isEmpty() )
00284                             return act->icon();
00285                 } break;
00286                 case Qt::DisplayRole:
00287                     return KGlobal::locale()->removeAcceleratorMarker( act->text() );
00288                 case Qt::ToolTipRole: // fall through
00289                 case Qt::WhatsThisRole: {
00290                     if( d->mode & ToolTips ) {
00291                         const QString file = QFileInfo( act->file() ).fileName();
00292                         return QString( "<qt><b>%1</b><br>%2</qt>" )
00293                             .arg( file.isEmpty() ? act->name() : file )
00294                             .arg( act->description() );
00295                     }
00296                 } break;
00297                 case Qt::CheckStateRole: {
00298                     if( d->mode & UserCheckable )
00299                         return act->isEnabled() ? Qt::Checked : Qt::Unchecked;
00300                 } break;
00301                 default: break;
00302             }
00303             return QVariant();
00304         }
00305         ActionCollection *coll = collection( index );
00306         if ( coll ) {
00307             switch( role ) {
00308                 case Qt::DecorationRole: {
00309                     if( d->mode & Icons )
00310                         if( ! coll->iconName().isEmpty() )
00311                             return coll->icon();
00312                 } break;
00313                 case Qt::DisplayRole:
00314                     return coll->text();
00315                 case Qt::ToolTipRole: // fall through
00316                 case Qt::WhatsThisRole: {
00317                     if( d->mode & ToolTips )
00318                         return QString( "<qt><b>%1</b><br>%2</qt>" ).arg( coll->text() ).arg( coll->description() );
00319                 } break;
00320                 case Qt::CheckStateRole: {
00321                     if( d->mode & UserCheckable )
00322                         return coll->isEnabled() ? Qt::Checked : Qt::Unchecked;
00323                 } break;
00324                 default: break;
00325             }
00326             return QVariant();
00327         }
00328     }
00329     return QVariant();
00330 }
00331 
00332 bool ActionCollectionModel::setData(const QModelIndex &index, const QVariant &value, int role)
00333 {
00334     Q_UNUSED(value);
00335     if( ! index.isValid() /*|| ! (d->mode & UserCheckable)*/ )
00336         return false;
00337     
00338     Action *act = action( index );
00339     if ( act ) {
00340         switch( role ) {
00341             //case Qt::EditRole: act->setText( value.toString() ); break;
00342             case Qt::CheckStateRole: act->setEnabled( ! act->isEnabled() ); break;
00343             default: return false;
00344         }
00345         return false;
00346     }
00347     ActionCollection *coll = collection( index );
00348     if ( coll ) {
00349         switch( role ) {
00350             //case Qt::EditRole: item->coll->setText( value.toString() ); break;
00351             case Qt::CheckStateRole: coll->setEnabled( ! coll->isEnabled() ); break;
00352             default: return false;
00353         }
00354         return false;
00355     }
00356     //emit dataChanged(index, index);
00357     return true;
00358 }
00359 
00360 bool ActionCollectionModel::insertRows(int row, int count, const QModelIndex& parent)
00361 {
00362     krossdebug( QString("ActionCollectionModel::insertRows: row=%1 count=%2").arg(row).arg(count) );
00363     if( ! parent.isValid() )
00364         return false;
00365 
00366     ActionCollection* coll = collection( parent );
00367     if ( coll ) {
00368         krossdebug( QString( "ActionCollectionModel::insertRows: parentindex is ActionCollection with name=%1" ).arg( coll->name() ) );
00369     } else {
00370         Action *act = action( parent );
00371         if ( act ) {
00372             krossdebug( QString( "ActionCollectionModel::insertRows: parentindex is Action with name=%1" ).arg( act->name() ) );
00373         }
00374     }
00375     return QAbstractItemModel::insertRows(row, count, parent);
00376 }
00377 
00378 bool ActionCollectionModel::removeRows(int row, int count, const QModelIndex& parent)
00379 {
00380     krossdebug( QString("ActionCollectionModel::removeRows: row=%1 count=%2").arg(row).arg(count) );
00381     return QAbstractItemModel::removeRows(row, count, parent);
00382 }
00383 
00384 bool ActionCollectionModel::insertColumns(int column, int count, const QModelIndex& parent)
00385 {
00386     krossdebug( QString("ActionCollectionModel::insertColumns: column=%1 count=%2").arg(column).arg(count) );
00387     return QAbstractItemModel::insertColumns(column, count, parent);
00388 }
00389 
00390 bool ActionCollectionModel::removeColumns(int column, int count, const QModelIndex& parent)
00391 {
00392     krossdebug( QString("ActionCollectionModel::removeColumns: column=%1 count=%2").arg(column).arg(count) );
00393     return QAbstractItemModel::removeColumns(column, count, parent);
00394 }
00395 
00396 QStringList ActionCollectionModel::mimeTypes() const
00397 {
00398     //krossdebug( QString("ActionCollectionModel::mimeTypes") );
00399     return QStringList() << "application/vnd.text.list";
00400 }
00401 
00402 QString fullPath(const QModelIndex& index)
00403 {
00404     if( ! index.isValid() ) return QString();
00405     QString n;
00406     Action *a = ActionCollectionModel::action( index );
00407     if ( a ) {
00408         n = a->name();
00409     } else {
00410         ActionCollection *c = ActionCollectionModel::collection( index );
00411         if ( c ) {
00412             n = c->name() + '/';
00413             if ( ! n.endsWith('/' ) )
00414                 n += '/';
00415         }
00416     }
00417     ActionCollection* par = static_cast<ActionCollection*>( index.internalPointer() );
00418     for ( ActionCollection *p = par; p != 0; p = par->parentCollection() ) {
00419         QString s = p->name();
00420         if ( ! s.endsWith( '/' ) ) {
00421             s += '/';
00422         }
00423         n = s + n;
00424     }
00425     return n;
00426 }
00427 
00428 QMimeData* ActionCollectionModel::mimeData(const QModelIndexList& indexes) const
00429 {
00430     //krossdebug( QString("ActionCollectionModel::mimeData") );
00431     QMimeData* mimeData = new QMimeData();
00432     QByteArray encodedData;
00433 
00434     QDataStream stream(&encodedData, QIODevice::WriteOnly);
00435     foreach(const QModelIndex &index, indexes) {
00436         //if( ! index.isValid() ) continue;
00437         //QString text = data(index, Qt::DisplayRole).toString();
00438         QString path = fullPath(index);
00439         if( ! path.isNull() )
00440             stream << path;
00441     }
00442 
00443     mimeData->setData("application/vnd.text.list", encodedData);
00444     return mimeData;
00445 }
00446 
00447 bool ActionCollectionModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
00448 {
00449     krossdebug( QString("ActionCollectionModel::dropMimeData: row=%1 col=%2").arg(row).arg(column) );
00450     if( action == Qt::IgnoreAction ) return true;
00451     if( ! data->hasFormat("application/vnd.text.list") ) return false;
00452     if( column > 0 ) return false;
00453 
00454     krossdebug( QString("ActionCollectionModel::dropMimeData: ENCODED DATA:") );
00455     QByteArray encodedData = data->data("application/vnd.text.list");
00456     QDataStream stream(&encodedData, QIODevice::ReadOnly);
00457     QStringList newItems;
00458     int rows = 0;
00459     while( ! stream.atEnd() ) {
00460         QString text;
00461         stream >> text;
00462         newItems << text;
00463         krossdebug( QString("  %1 \"%2\"").arg(rows).arg(text) );
00464         ++rows;
00465     }
00466 
00467     //FIXME: return false for now since insertRows/removeRows need to be implemented before!
00468     //return false;
00469 
00470     /*
00471     int beginRow;
00472     if( row != -1 )
00473         beginRow = row;
00474     else if( parent.isValid() )
00475         beginRow = parent.row();
00476     else
00477         beginRow = rowCount( QModelIndex() );
00478     krossdebug( QString("ActionCollectionModel::dropMimeData: beginRow=%1").arg(beginRow) );
00479     */
00480 
00481     QModelIndex targetindex = index( row, column, parent );
00482     ActionCollection *coll = collection( targetindex );
00483     if ( coll ) {
00484         krossdebug( QString( "ActionCollectionModel::dropMimeData: parentindex is ActionCollection with name=%1" ).arg( coll->name() ) );
00485     } else {
00486         Action *act = this->action( targetindex );
00487         if ( act ) {
00488             krossdebug( QString( "ActionCollectionModel::dropMimeData: parentindex is Action with name=%1" ).arg( act->name() ) );
00489         }
00490     }
00491     return false;
00492     //return QAbstractItemModel::dropMimeData(data, action, row, column, parent);
00493 }
00494 
00495 Qt::DropActions ActionCollectionModel::supportedDropActions() const
00496 {
00497     return Qt::CopyAction | Qt::MoveAction | Qt::TargetMoveAction;
00498     //return Qt::CopyAction | Qt::MoveAction | Qt::TargetMoveAction | Qt::LinkAction;
00499 }
00500 
00501 /******************************************************************************
00502  * ActionCollectionProxyModel
00503  */
00504 
00505 ActionCollectionProxyModel::ActionCollectionProxyModel(QObject* parent, ActionCollectionModel* model)
00506     : QSortFilterProxyModel(parent)
00507 {
00508     setSourceModel( model ? model : new ActionCollectionModel(this) );
00509     setFilterCaseSensitivity(Qt::CaseInsensitive);
00510     setDynamicSortFilter(true);
00511 }
00512 
00513 ActionCollectionProxyModel::~ActionCollectionProxyModel()
00514 {
00515 }
00516 
00517 void ActionCollectionProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
00518 {
00519     Q_ASSERT( dynamic_cast< ActionCollectionModel* >(sourceModel) );
00520     QSortFilterProxyModel::setSourceModel(sourceModel);
00521 }
00522 
00523 bool ActionCollectionProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
00524 {
00525     //krossdebug( QString( "ActionCollectionProxyModel::filterAcceptsRow: row=%1 parentrow=%2" ).arg( source_row ).arg( source_parent.row() ) );
00526     QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
00527     if( ! index.isValid() )
00528         return false;
00529 
00530     Action *action = ActionCollectionModel::action( index );
00531     if ( action ) {
00532         return action->isEnabled() && QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent );
00533     }
00534     ActionCollection *collection = ActionCollectionModel::collection( index );
00535     if( collection ) {
00536         return collection->isEnabled();
00537     }
00538     return true;
00539 }
00540 
00541 #include "model.moc"

Kross

Skip menu "Kross"
  • Main Page
  • 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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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