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

KDEUI

kactioncollection.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
00003               (C) 1999 Simon Hausmann <hausmann@kde.org>
00004               (C) 2000 Nicolas Hadacek <haadcek@kde.org>
00005               (C) 2000 Kurt Granroth <granroth@kde.org>
00006               (C) 2000 Michael Koch <koch@kde.org>
00007               (C) 2001 Holger Freyther <freyther@kde.org>
00008               (C) 2002 Ellis Whitehead <ellis@kde.org>
00009               (C) 2002 Joseph Wenninger <jowenn@kde.org>
00010               (C) 2005-2007 Hamish Rodda <rodda@kde.org>
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Library General Public
00014     License version 2 as published by the Free Software Foundation.
00015 
00016     This library is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019     Library General Public License for more details.
00020 
00021     You should have received a copy of the GNU Library General Public License
00022     along with this library; see the file COPYING.LIB.  If not, write to
00023     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00024     Boston, MA 02110-1301, USA.
00025 */
00026 
00027 #include "kactioncollection.h"
00028 #include <kauthorized.h>
00029 #include "ktoolbar.h"
00030 #include "kxmlguiclient.h"
00031 #include "kxmlguifactory.h"
00032 
00033 #include "kdebug.h"
00034 #include "kglobal.h"
00035 #include "kaction.h"
00036 #include "kaction_p.h"
00037 
00038 #include <QtXml/QDomDocument>
00039 #include <QSet>
00040 #include <QtCore/QVariant>
00041 #include <QHash>
00042 #include <QChildEvent>
00043 #include <QTimer>
00044 #include <QAction>
00045 
00046 #include <stdio.h>
00047 #include "kcomponentdata.h"
00048 #include "kconfiggroup.h"
00049 #include "klocale.h"
00050 
00051 class KActionCollectionPrivate
00052 {
00053 public:
00054   KActionCollectionPrivate()
00055   {
00056     q = 0;
00057     m_parentGUIClient = 0L;
00058 
00059     configIsGlobal = false;
00060 
00061     connectHovered = connectTriggered = false;
00062 
00063     configGroup = "Shortcuts";
00064   }
00065 
00066   void setComponentForAction(KAction *kaction)
00067     { kaction->d->maybeSetComponentData(m_componentData); }
00068 
00069   static QList<KActionCollection*> s_allCollections;
00070 
00071   void _k_associatedWidgetDestroyed(QObject *obj);
00072   void _k_actionDestroyed(QObject *obj);
00073 
00074   bool writeKXMLGUIConfigFile();
00075 
00076   KComponentData m_componentData;
00077 
00078   QMap<QString, QAction*> actionByName;
00079   QHash<QAction *, QString> nameByAction;
00080 
00081   const KXMLGUIClient *m_parentGUIClient;
00082 
00083   QString configGroup;
00084   bool configIsGlobal : 1;
00085 
00086   bool connectTriggered : 1;
00087   bool connectHovered : 1;
00088 
00089   KActionCollection *q;
00090 
00091   QList<QWidget*> associatedWidgets;
00092 };
00093 
00094 QList<KActionCollection*> KActionCollectionPrivate::s_allCollections;
00095 
00096 KActionCollection::KActionCollection(QObject *parent, const KComponentData &cData)
00097   : QObject( parent )
00098   , d(new KActionCollectionPrivate)
00099 {
00100   d->q = this;
00101   KActionCollectionPrivate::s_allCollections.append(this);
00102 
00103   setComponentData(cData);
00104 }
00105 
00106 KActionCollection::KActionCollection( const KXMLGUIClient *parent )
00107   : QObject( 0 )
00108   , d(new KActionCollectionPrivate)
00109 {
00110   d->q = this;
00111   KActionCollectionPrivate::s_allCollections.append(this);
00112 
00113   d->m_parentGUIClient=parent;
00114   d->m_componentData = parent->componentData();
00115 }
00116 
00117 KActionCollection::~KActionCollection()
00118 {
00119   KActionCollectionPrivate::s_allCollections.removeAll(this);
00120 
00121   delete d;
00122 }
00123 
00124 void KActionCollection::clear()
00125 {
00126   QList<QAction *> actions = d->nameByAction.keys();
00127   d->actionByName.clear();
00128   d->nameByAction.clear();
00129   qDeleteAll(actions);
00130 }
00131 
00132 QAction* KActionCollection::action( const QString& name ) const
00133 {
00134   QAction* action = 0L;
00135 
00136   if ( !name.isEmpty() )
00137     action = d->actionByName.value (name);
00138 
00139   return action;
00140 }
00141 
00142 QAction* KActionCollection::action( int index ) const
00143 {
00144   // ### investigate if any apps use this at all
00145   return actions().value(index);
00146 }
00147 
00148 int KActionCollection::count() const
00149 {
00150   return d->nameByAction.count();
00151 }
00152 
00153 bool KActionCollection::isEmpty() const
00154 {
00155   return count() == 0;
00156 }
00157 
00158 void KActionCollection::setComponentData(const KComponentData &cData)
00159 {
00160   if (count() > 0) {
00161     // Its component name is part of an action's signature in the context of
00162     // global shortcuts and the semantics of changing an existing action's
00163     // signature are, as it seems, impossible to get right.
00164     // As of now this only matters for global shortcuts. We could
00165     // thus relax the requirement and only refuse to change the component data
00166     // if we have actions with global shortcuts in this collection.
00167     kWarning(129) << "this does not work on a KActionCollection containing actions!";
00168   }
00169 
00170   if (cData.isValid()) {
00171     d->m_componentData = cData;
00172   } else {
00173     d->m_componentData = KGlobal::mainComponent();
00174   }
00175 }
00176 
00177 KComponentData KActionCollection::componentData() const
00178 {
00179   return d->m_componentData;
00180 }
00181 
00182 const KXMLGUIClient *KActionCollection::parentGUIClient() const
00183 {
00184     return d->m_parentGUIClient;
00185 }
00186 
00187 QList<QAction*> KActionCollection::actions() const
00188 {
00189   return d->actionByName.values();
00190 }
00191 
00192 const QList< QAction* > KActionCollection::actionsWithoutGroup( ) const
00193 {
00194   QList<QAction*> ret;
00195   foreach (QAction* action, d->actionByName)
00196     if (!action->actionGroup())
00197       ret.append(action);
00198   return ret;
00199 }
00200 
00201 const QList< QActionGroup * > KActionCollection::actionGroups( ) const
00202 {
00203   QSet<QActionGroup*> set;
00204   foreach (QAction* action, d->actionByName)
00205     if (action->actionGroup())
00206       set.insert(action->actionGroup());
00207   return set.toList();
00208 }
00209 
00210 KAction *KActionCollection::addAction(const QString &name, KAction *action)
00211 {
00212     QAction* ret = addAction(name, static_cast<QAction*>(action));
00213     Q_ASSERT(ret == action);
00214     return action;
00215 }
00216 
00217 QAction *KActionCollection::addAction(const QString &name, QAction *action)
00218 {
00219     if (!action)
00220         return action;
00221 
00222     QString index_name = name;
00223 
00224     if (index_name.isEmpty())
00225         index_name = action->objectName();
00226     else
00227         action->setObjectName(index_name);
00228 
00229     if( index_name.isEmpty() )
00230         index_name = index_name.sprintf("unnamed-%p", (void*)action);
00231 
00232     // look if we already have THIS action under THIS name ;)
00233     if (d->actionByName.value(index_name, 0) == action ) {
00234         // This is not a multi map!
00235         Q_ASSERT( d->actionByName.count(index_name)==1);
00236         return action;
00237     }
00238 
00239     if (!KAuthorized::authorizeKAction(index_name)) {
00240       // Disable this action
00241       action->setEnabled(false);
00242       action->setVisible(false);
00243       action->blockSignals(true);
00244     }
00245 
00246     if (QAction *oldAction = d->actionByName.value(index_name)) {
00247       takeAction(oldAction);
00248     }
00249     takeAction(action);
00250     // really insert action
00251     d->actionByName.insert(index_name, action);
00252     d->nameByAction.insert(action, index_name);
00253 
00254     foreach (QWidget* widget, d->associatedWidgets)
00255       widget->addAction(action);
00256 
00257     connect(action, SIGNAL(destroyed(QObject*)), SLOT(_k_actionDestroyed(QObject*)));
00258 
00259     // only our private class is a friend of KAction
00260     if (KAction *kaction = dynamic_cast<KAction *>(action)) {
00261       d->setComponentForAction(kaction);
00262     }
00263 
00264     if (d->connectHovered)
00265         connect(action, SIGNAL(hovered()), SLOT(slotActionHovered()));
00266 
00267     if (d->connectTriggered)
00268         connect(action, SIGNAL(triggered(bool)), SLOT(slotActionTriggered()));
00269 
00270     emit inserted( action );
00271     return action;
00272 }
00273 
00274 void KActionCollection::removeAction( QAction* action )
00275 {
00276     delete takeAction( action );
00277 }
00278 
00279 QAction* KActionCollection::takeAction(QAction *action)
00280 {
00281   QHash<QAction *, QString>::Iterator it = d->nameByAction.find(action);
00282   if (it == d->nameByAction.end())
00283     return 0;
00284   const QString name = *it;
00285   d->nameByAction.erase(it);
00286   d->actionByName.remove(name);
00287 
00288   foreach (QWidget* widget, d->associatedWidgets)
00289     widget->removeAction(action);
00290 
00291   action->disconnect(this);
00292 
00293   emit removed( action ); //deprecated
00294   return action;
00295 }
00296 
00297 KAction *KActionCollection::addAction(KStandardAction::StandardAction actionType, const QObject *receiver, const char *member)
00298 {
00299   KAction *action = KStandardAction::create(actionType, receiver, member, this);
00300   return addAction(action->objectName(), action);
00301 }
00302 
00303 KAction *KActionCollection::addAction(KStandardAction::StandardAction actionType, const QString &name,
00304                                       const QObject *receiver, const char *member)
00305 {
00306   KAction *action = KStandardAction::create(actionType, receiver, member, this);
00307   return addAction(name, action);
00308 }
00309 
00310 KAction *KActionCollection::addAction(const QString &name, const QObject *receiver, const char *member)
00311 {
00312   KAction *a = new KAction(this);
00313   if (receiver && member)
00314     connect(a, SIGNAL(triggered()), receiver, member);
00315   return addAction(name, a);
00316 }
00317 
00318 QString KActionCollection::configGroup( ) const
00319 {
00320   return d->configGroup;
00321 }
00322 
00323 void KActionCollection::setConfigGroup( const QString & group )
00324 {
00325   d->configGroup = group;
00326 }
00327 
00328 bool KActionCollection::configIsGlobal() const
00329 {
00330   return d->configIsGlobal;
00331 }
00332 
00333 void KActionCollection::setConfigGlobal( bool global )
00334 {
00335   d->configIsGlobal = global;
00336 }
00337 
00338 void KActionCollection::importGlobalShortcuts( KConfigGroup* config )
00339 {
00340   Q_ASSERT(config);
00341   if( !config || !config->exists()) {
00342     return;
00343   }
00344 
00345   for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin();
00346        it != d->actionByName.constEnd(); ++it) {
00347       KAction *kaction = qobject_cast<KAction*>(it.value());
00348       if (!kaction)
00349           continue;
00350 
00351       QString actionName = it.key();
00352 
00353       if( kaction->isShortcutConfigurable() ) {
00354           QString entry = config->readEntry(actionName, QString());
00355           if( !entry.isEmpty() ) {
00356               kaction->setGlobalShortcut( KShortcut(entry), KAction::ActiveShortcut, KAction::NoAutoloading );
00357           } else {
00358               kaction->setGlobalShortcut( kaction->shortcut(KAction::DefaultShortcut), KAction::ActiveShortcut, KAction::NoAutoloading );
00359           }
00360       }
00361   }
00362 }
00363 
00364 
00365 void KActionCollection::readSettings( KConfigGroup* config )
00366 {
00367   KConfigGroup cg( KGlobal::config(), configGroup() );
00368   if( !config )
00369       config = &cg;
00370 
00371   if( !config->exists()) {
00372     return;
00373   }
00374 
00375   for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin();
00376        it != d->actionByName.constEnd(); ++it) {
00377       KAction *kaction = qobject_cast<KAction*>(it.value());
00378       if (!kaction)
00379           continue;
00380 
00381 
00382       if( kaction->isShortcutConfigurable() ) {
00383           QString actionName = it.key();
00384           QString entry = config->readEntry(actionName, QString());
00385           if( !entry.isEmpty() ) {
00386               kaction->setShortcut( KShortcut(entry), KAction::ActiveShortcut );
00387           } else {
00388               kaction->setShortcut( kaction->shortcut(KAction::DefaultShortcut) );
00389           }
00390       }
00391   }
00392 
00393   //kDebug(125) << " done";
00394 }
00395 
00396 void KActionCollection::exportGlobalShortcuts( KConfigGroup* config, bool writeAll ) const
00397 {
00398   Q_ASSERT(config);
00399   if (!config) {
00400     return;
00401   }
00402 
00403   QList<QAction*> writeActions = actions();
00404 
00405   for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin();
00406        it != d->actionByName.constEnd(); ++it) {
00407 
00408       KAction *kaction = qobject_cast<KAction*>(it.value());
00409       if (!kaction)
00410           continue;
00411       QString actionName = it.key();
00412 
00413       if( kaction->isShortcutConfigurable() && kaction->isGlobalShortcutEnabled() ) {
00414           bool bConfigHasAction = !config->readEntry( actionName, QString() ).isEmpty();
00415           bool bSameAsDefault = (kaction->globalShortcut() == kaction->globalShortcut(KAction::DefaultShortcut));
00416           // If we're using a global config or this setting
00417           //  differs from the default, then we want to write.
00418           KConfigGroup::WriteConfigFlags flags = KConfigGroup::Persistent;
00419           if (configIsGlobal())
00420               flags |= KConfigGroup::Global;
00421           if( writeAll || !bSameAsDefault ) {
00422               QString s = kaction->globalShortcut().toString();
00423               if( s.isEmpty() )
00424                   s = "none";
00425               kDebug(125) << "\twriting " << actionName << " = " << s;
00426               config->writeEntry( actionName, s, flags );
00427           }
00428           // Otherwise, this key is the same as default
00429           //  but exists in config file.  Remove it.
00430           else if( bConfigHasAction ) {
00431               kDebug(125) << "\tremoving " << actionName << " because == default";
00432               config->deleteEntry( actionName, flags );
00433           }
00434       }
00435   }
00436 
00437   config->sync();
00438 }
00439 
00440 
00441 bool KActionCollectionPrivate::writeKXMLGUIConfigFile()
00442 {
00443     const KXMLGUIClient *kxmlguiClient = q->parentGUIClient();
00444     // return false if there is no KXMLGUIClient
00445     if (!kxmlguiClient || kxmlguiClient->xmlFile().isEmpty()) {
00446         return false;
00447     }
00448 
00449     kDebug(129) << "xmlFile=" << kxmlguiClient->xmlFile();
00450 
00451     QString attrShortcut = QLatin1String("shortcut");
00452 
00453     // Read XML file
00454     QString sXml(KXMLGUIFactory::readConfigFile(kxmlguiClient->xmlFile(), q->componentData()));
00455     QDomDocument doc;
00456     doc.setContent( sXml );
00457 
00458     // Process XML data
00459 
00460     // Get hold of ActionProperties tag
00461     QDomElement elem = KXMLGUIFactory::actionPropertiesElement( doc );
00462 
00463     // now, iterate through our actions
00464     for (QMap<QString, QAction *>::ConstIterator it = actionByName.constBegin();
00465          it != actionByName.constEnd(); ++it) {
00466       KAction *kaction = qobject_cast<KAction*>(it.value());
00467       if (!kaction) {
00468         continue;
00469       }
00470 
00471       QString actionName = it.key();
00472 
00473       bool bSameAsDefault = (kaction->shortcut() == kaction->shortcut(KAction::DefaultShortcut));
00474       kDebug(129) << "name = " << actionName 
00475                   << " shortcut = " << kaction->shortcut(KAction::ActiveShortcut).toString()
00476                   << " globalshortcut = " << kaction->globalShortcut(KAction::ActiveShortcut).toString()
00477                   << " def = " << kaction->shortcut(KAction::DefaultShortcut).toString();
00478 
00479       // now see if this element already exists
00480       // and create it if necessary (unless bSameAsDefault)
00481       QDomElement act_elem = KXMLGUIFactory::findActionByName( elem, actionName, !bSameAsDefault );
00482       if ( act_elem.isNull() )
00483         continue;
00484 
00485       if( bSameAsDefault ) {
00486         act_elem.removeAttribute( attrShortcut );
00487         //kDebug(129) << "act_elem.attributes().count() = " << act_elem.attributes().count();
00488         if( act_elem.attributes().count() == 1 )
00489           elem.removeChild( act_elem );
00490       } else {
00491         act_elem.setAttribute( attrShortcut, kaction->shortcut().toString() );
00492       }
00493     }
00494 
00495     // Write back to XML file
00496     KXMLGUIFactory::saveConfigFile(doc, kxmlguiClient->xmlFile(), q->componentData());
00497     return true;
00498 }
00499 
00500 
00501 void KActionCollection::writeSettings( KConfigGroup* config, bool writeAll, QAction* oneAction ) const
00502 {
00503     // If the caller didn't provide a config group we try to save the KXMLGUI
00504     // Configuration file. If that succeeds we are finished.
00505     if (config==0 && d->writeKXMLGUIConfigFile() ) {
00506         return;
00507     }
00508 
00509     KConfigGroup cg(KGlobal::config() , configGroup() );
00510     if (!config) {
00511         config = &cg;
00512     }
00513 
00514     QList<QAction*> writeActions;
00515     if (oneAction) {
00516         writeActions.append(oneAction);
00517     } else {
00518         writeActions = actions();
00519     }
00520 
00521 
00522     for (QMap<QString, QAction *>::ConstIterator it = d->actionByName.constBegin();
00523          it != d->actionByName.constEnd(); ++it) {
00524 
00525         // Get the action. We only handle KActions so skip QActions
00526         KAction *kaction = qobject_cast<KAction*>(it.value());
00527         if (!kaction) {
00528             continue;
00529         }
00530 
00531         // Write the shortcut
00532         if( kaction->isShortcutConfigurable() ) {
00533             QString actionName = it.key();
00534             bool bConfigHasAction = !config->readEntry( actionName, QString() ).isEmpty();
00535             bool bSameAsDefault = (kaction->shortcut() == kaction->shortcut(KAction::DefaultShortcut));
00536             // If we're using a global config or this setting
00537             //  differs from the default, then we want to write.
00538             KConfigGroup::WriteConfigFlags flags = KConfigGroup::Persistent;
00539 
00540             // Honor the configIsGlobal() setting
00541             if (configIsGlobal()) {
00542                 flags |= KConfigGroup::Global;
00543             }
00544 
00545             if( writeAll || !bSameAsDefault ) {
00546                 // We are instructed to write all shortcuts or the shortcut is
00547                 // not set to its default value. Write it
00548                 QString s = kaction->shortcut().toString();
00549                 if( s.isEmpty() )
00550                     s = "none";
00551                 kDebug(125) << "\twriting " << actionName << " = " << s;
00552                 config->writeEntry( actionName, s, flags );
00553 
00554             } else if( bConfigHasAction ) {
00555                 // Otherwise, this key is the same as default but exists in
00556                 // config file. Remove it.
00557                 kDebug(125) << "\tremoving " << actionName << " because == default";
00558                 config->deleteEntry( actionName, flags );
00559             }
00560         }
00561     }
00562 
00563     config->sync();
00564 }
00565 
00566 void KActionCollection::slotActionTriggered( )
00567 {
00568   QAction* action = qobject_cast<QAction*>(sender());
00569   if (action)
00570     emit actionTriggered(action);
00571 }
00572 
00573 void KActionCollection::slotActionHighlighted( )
00574 {
00575     slotActionHovered();
00576 }
00577 
00578 void KActionCollection::slotActionHovered( )
00579 {
00580   QAction* action = qobject_cast<QAction*>(sender());
00581   if (action) {
00582     emit actionHighlighted(action);
00583     emit actionHovered(action);
00584   }
00585 }
00586 
00587 void KActionCollectionPrivate::_k_actionDestroyed( QObject *obj )
00588 {
00589   QAction *action = static_cast<QAction*>(obj);
00590   QHash<QAction *, QString>::Iterator it = nameByAction.find(action);
00591   if (it == nameByAction.end())
00592     return;
00593   const QString name = *it;
00594   nameByAction.erase(it);
00595   actionByName.remove(name);
00596 
00597   //HACK the object we emit is partly destroyed
00598   emit q->removed(action); //deprecated. remove in KDE5
00599 }
00600 
00601 void KActionCollection::connectNotify ( const char * signal )
00602 {
00603   if (d->connectHovered && d->connectTriggered)
00604     return;
00605 
00606   if (QMetaObject::normalizedSignature(SIGNAL(actionHighlighted(QAction*))) == signal || 
00607       QMetaObject::normalizedSignature(SIGNAL(actionHovered(QAction*))) == signal) {
00608     if (!d->connectHovered) {
00609       d->connectHovered = true;
00610       foreach (QAction* action, actions())
00611         connect(action, SIGNAL(hovered()), SLOT(slotActionHovered()));
00612     }
00613 
00614   } else if (QMetaObject::normalizedSignature(SIGNAL(actionTriggered(QAction*))) == signal) {
00615     if (!d->connectTriggered) {
00616       d->connectTriggered = true;
00617       foreach (QAction* action, actions())
00618         connect(action, SIGNAL(triggered(bool)), SLOT(slotActionTriggered()));
00619     }
00620   }
00621 
00622   QObject::connectNotify(signal);
00623 }
00624 
00625 const QList< KActionCollection * >& KActionCollection::allCollections( )
00626 {
00627     return KActionCollectionPrivate::s_allCollections;
00628 }
00629 
00630 void KActionCollection::associateWidget(QWidget* widget) const
00631 {
00632     foreach (QAction* action, actions()) {
00633         if (!widget->actions().contains(action))
00634             widget->addAction(action);
00635     }
00636 }
00637 
00638 void KActionCollection::addAssociatedWidget(QWidget * widget)
00639 {
00640   if (!d->associatedWidgets.contains(widget)) {
00641     widget->addActions(actions());
00642 
00643     d->associatedWidgets.append(widget);
00644     connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(_k_associatedWidgetDestroyed(QObject*)));
00645   }
00646 }
00647 
00648 void KActionCollection::removeAssociatedWidget(QWidget * widget)
00649 {
00650   foreach (QAction* action, actions())
00651     widget->removeAction(action);
00652 
00653   d->associatedWidgets.removeAll(widget);
00654   disconnect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(_k_associatedWidgetDestroyed(QObject*)));
00655 }
00656 
00657 QList< QWidget * > KActionCollection::associatedWidgets() const
00658 {
00659   return d->associatedWidgets;
00660 }
00661 
00662 void KActionCollection::clearAssociatedWidgets()
00663 {
00664   foreach (QWidget* widget, d->associatedWidgets)
00665     foreach (QAction* action, actions())
00666       widget->removeAction(action);
00667 
00668   d->associatedWidgets.clear();
00669 }
00670 
00671 void KActionCollectionPrivate::_k_associatedWidgetDestroyed(QObject *obj)
00672 {
00673   associatedWidgets.removeAll(static_cast<QWidget*>(obj));
00674 }
00675 
00676 /* vim: et sw=2 ts=2
00677  */
00678 
00679 #include "kactioncollection.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
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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