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

KIO

kurifilter.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002  *  Copyright (C) 2000 Yves Arrouye <yves@realnames.com>
00003  *  Copyright (C) 2000,2010 Dawit Alemayehu <adawit at 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 "kurifilter.h"
00022 
00023 #include "hostinfo_p.h"
00024 
00025 #include <kdebug.h>
00026 #include <kiconloader.h>
00027 #include <kservicetypetrader.h>
00028 #include <kmimetype.h>
00029 #include <kstandarddirs.h>
00030 
00031 #include <QtCore/QHashIterator>
00032 #include <QtCore/QStringBuilder>
00033 #include <QtNetwork/QHostInfo>
00034 #include <QtNetwork/QHostAddress>
00035 
00036 typedef QList<KUriFilterPlugin *> KUriFilterPluginList;
00037 typedef QMap<QString, KUriFilterSearchProvider*> SearchProviderMap;
00038 
00039 
00040 static QString lookupIconNameFor(const KUrl &url, KUriFilterData::UriTypes type)
00041 {
00042     QString iconName;
00043 
00044     switch ( type )
00045     {
00046         case KUriFilterData::NetProtocol:
00047             iconName = KMimeType::favIconForUrl(url);
00048             if (iconName.isEmpty())
00049                 iconName = KMimeType::iconNameForUrl( url );
00050             else
00051                 iconName = KStandardDirs::locate("cache", iconName + QLatin1String(".png"));
00052             break;
00053         case KUriFilterData::LocalFile:
00054         case KUriFilterData::LocalDir:
00055         {
00056             iconName = KMimeType::iconNameForUrl( url );
00057             break;
00058         }
00059         case KUriFilterData::Executable:
00060         {
00061             QString exeName = url.path();
00062             exeName = exeName.mid( exeName.lastIndexOf( '/' ) + 1 ); // strip path if given
00063             KService::Ptr service = KService::serviceByDesktopName( exeName );
00064             if (service && service->icon() != QLatin1String( "unknown" ))
00065                 iconName = service->icon();
00066             // Try to find an icon with the same name as the binary (useful for non-kde apps)
00067             // Use iconPath rather than loadIcon() as the latter uses QPixmap (not threadsafe)
00068             else if ( !KIconLoader::global()->iconPath( exeName, KIconLoader::NoGroup, true ).isNull() )
00069                 iconName = exeName;
00070             else
00071                 // not found, use default
00072                 iconName = QLatin1String("system-run");
00073             break;
00074         }
00075         case KUriFilterData::Help:
00076         {
00077             iconName = QLatin1String("khelpcenter");
00078             break;
00079         }
00080         case KUriFilterData::Shell:
00081         {
00082             iconName = QLatin1String("konsole");
00083             break;
00084         }
00085         case KUriFilterData::Error:
00086         case KUriFilterData::Blocked:
00087         {
00088             iconName = QLatin1String("error");
00089             break;
00090         }
00091         default:
00092             break;
00093     }
00094 
00095     return iconName;
00096 }
00097 
00098 
00099 class KUriFilterSearchProvider::KUriFilterSearchProviderPrivate
00100 {
00101 public:
00102     KUriFilterSearchProviderPrivate() {}
00103     KUriFilterSearchProviderPrivate(const KUriFilterSearchProviderPrivate& other)
00104       : desktopEntryName(other.desktopEntryName),
00105         iconName(other.iconName),
00106         name(other.name),
00107         keys(other.keys) {}
00108 
00109 
00110     QString desktopEntryName;
00111     QString iconName;
00112     QString name;
00113     QStringList keys;
00114 };
00115 
00116 KUriFilterSearchProvider::KUriFilterSearchProvider()
00117                          :d(new KUriFilterSearchProvider::KUriFilterSearchProviderPrivate)
00118 {
00119 }
00120 
00121 KUriFilterSearchProvider::KUriFilterSearchProvider(const KUriFilterSearchProvider& other)
00122                          :d(new KUriFilterSearchProvider::KUriFilterSearchProviderPrivate(*(other.d)))
00123 {
00124 }
00125 
00126 KUriFilterSearchProvider::~KUriFilterSearchProvider()
00127 {
00128     delete d;
00129 }
00130 
00131 QString KUriFilterSearchProvider::desktopEntryName() const
00132 {
00133     return d->desktopEntryName;
00134 }
00135 
00136 QString KUriFilterSearchProvider::iconName() const
00137 {
00138     return d->iconName;
00139 }
00140 
00141 QString KUriFilterSearchProvider::name() const
00142 {
00143     return d->name;
00144 }
00145 
00146 QStringList KUriFilterSearchProvider::keys() const
00147 {
00148     return d->keys;
00149 }
00150 
00151 QString KUriFilterSearchProvider::defaultKey() const
00152 {
00153     if (d->keys.isEmpty())
00154         return QString();
00155 
00156     return d->keys.first();
00157 }
00158 
00159 KUriFilterSearchProvider& KUriFilterSearchProvider::operator=(const KUriFilterSearchProvider& other)
00160 {
00161     d->desktopEntryName = other.d->desktopEntryName;
00162     d->iconName = other.d->iconName;
00163     d->keys = other.d->keys;
00164     d->name = other.d->name;
00165     return *this;
00166 }
00167 
00168 void KUriFilterSearchProvider::setDesktopEntryName(const QString& desktopEntryName)
00169 {
00170     d->desktopEntryName = desktopEntryName;
00171 }
00172 
00173 void KUriFilterSearchProvider::setIconName(const QString& iconName)
00174 {
00175     d->iconName = iconName;
00176 }
00177 
00178 void KUriFilterSearchProvider::setName(const QString& name)
00179 {
00180     d->name = name;
00181 }
00182 
00183 void KUriFilterSearchProvider::setKeys(const QStringList& keys)
00184 {
00185     d->keys = keys;
00186 }
00187 
00188 class KUriFilterDataPrivate
00189 {
00190 public:
00191     explicit KUriFilterDataPrivate( const KUrl& u, const QString& typedUrl )
00192       : checkForExecs(true),
00193         wasModified(true),
00194         uriType(KUriFilterData::Unknown),
00195         searchFilterOptions(KUriFilterData::SearchFilterOptionNone),
00196         url(u),
00197         typedString(typedUrl)
00198     {
00199     }
00200 
00201     ~KUriFilterDataPrivate()
00202     {
00203         qDeleteAll(searchProviderMap.begin(), searchProviderMap.end());
00204     }
00205 
00206     void setData( const KUrl& u, const QString& typedUrl )
00207     {
00208         checkForExecs = true;
00209         wasModified = true;
00210         uriType = KUriFilterData::Unknown;
00211         searchFilterOptions = KUriFilterData::SearchFilterOptionNone;
00212 
00213         url = u;
00214         typedString = typedUrl;
00215 
00216         errMsg.clear();
00217         iconName.clear();
00218         absPath.clear();
00219         args.clear();
00220         searchTerm.clear();
00221         searchProvider.clear();
00222         searchTermSeparator = QChar();
00223         alternateDefaultSearchProvider.clear();
00224         alternateSearchProviders.clear();
00225         searchProviderMap.clear();
00226         defaultUrlScheme.clear();
00227     }
00228 
00229     KUriFilterDataPrivate( KUriFilterDataPrivate * data )
00230     {
00231         wasModified = data->wasModified;
00232         checkForExecs = data->checkForExecs;
00233         uriType = data->uriType;
00234         searchFilterOptions = data->searchFilterOptions;
00235 
00236         url = data->url;
00237         typedString = data->typedString;
00238 
00239         errMsg = data->errMsg;
00240         iconName = data->iconName;
00241         absPath = data->absPath;
00242         args = data->args;
00243         searchTerm = data->searchTerm;
00244         searchTermSeparator = data->searchTermSeparator;
00245         searchProvider = data->searchProvider;
00246         alternateDefaultSearchProvider = data->alternateDefaultSearchProvider;
00247         alternateSearchProviders = data->alternateSearchProviders;
00248         searchProviderMap = data->searchProviderMap;
00249         defaultUrlScheme = data->defaultUrlScheme;
00250     }
00251 
00252     bool checkForExecs;
00253     bool wasModified;
00254     KUriFilterData::UriTypes uriType;
00255     KUriFilterData::SearchFilterOptions searchFilterOptions;
00256 
00257     KUrl url;
00258     QString typedString;
00259     QString errMsg;
00260     QString iconName;
00261     QString absPath;
00262     QString args;
00263     QString searchTerm;
00264     QString searchProvider;
00265     QString alternateDefaultSearchProvider;
00266     QString defaultUrlScheme;
00267     QChar searchTermSeparator;
00268 
00269     QStringList alternateSearchProviders;
00270     QStringList searchProviderList;
00271     SearchProviderMap searchProviderMap;
00272 };
00273 
00274 KUriFilterData::KUriFilterData()
00275                :d( new KUriFilterDataPrivate( KUrl(), QString() ) )
00276 {
00277 }
00278 
00279 KUriFilterData::KUriFilterData( const KUrl& url )
00280                :d( new KUriFilterDataPrivate( url, url.url() ) )
00281 {
00282 }
00283 
00284 KUriFilterData::KUriFilterData( const QString& url )
00285                :d( new KUriFilterDataPrivate( KUrl(url), url ) )
00286 {
00287 }
00288 
00289 
00290 KUriFilterData::KUriFilterData( const KUriFilterData& other )
00291                :d( new KUriFilterDataPrivate( other.d ) )
00292 {
00293 }
00294 
00295 KUriFilterData::~KUriFilterData()
00296 {
00297     delete d;
00298 }
00299 
00300 KUrl KUriFilterData::uri() const
00301 {
00302     return d->url;
00303 }
00304 
00305 QString KUriFilterData::errorMsg() const
00306 {
00307     return d->errMsg;
00308 }
00309 
00310 KUriFilterData::UriTypes KUriFilterData::uriType() const
00311 {
00312     return d->uriType;
00313 }
00314 
00315 QString KUriFilterData::absolutePath() const
00316 {
00317     return d->absPath;
00318 }
00319 
00320 bool KUriFilterData::hasAbsolutePath() const
00321 {
00322     return !d->absPath.isEmpty();
00323 }
00324 
00325 QString KUriFilterData::argsAndOptions() const
00326 {
00327     return d->args;
00328 }
00329 
00330 bool KUriFilterData::hasArgsAndOptions() const
00331 {
00332     return !d->args.isEmpty();
00333 }
00334 
00335 bool KUriFilterData::checkForExecutables() const
00336 {
00337     return d->checkForExecs;
00338 }
00339 
00340 QString KUriFilterData::typedString() const
00341 {
00342     return d->typedString;
00343 }
00344 
00345 QString KUriFilterData::searchTerm() const
00346 {
00347     return d->searchTerm;
00348 }
00349 
00350 QChar KUriFilterData::searchTermSeparator() const
00351 {
00352     return d->searchTermSeparator;
00353 }
00354 
00355 QString KUriFilterData::searchProvider() const
00356 {
00357     return d->searchProvider;
00358 }
00359 
00360 QStringList KUriFilterData::preferredSearchProviders() const
00361 {
00362     return d->searchProviderList;
00363 }
00364 
00365 KUriFilterSearchProvider KUriFilterData::queryForSearchProvider(const QString& provider) const
00366 {
00367     const KUriFilterSearchProvider* searchProvider = d->searchProviderMap.value(provider);
00368 
00369     if (searchProvider)
00370         return *(searchProvider);
00371 
00372     return KUriFilterSearchProvider();
00373 }
00374 
00375 QString KUriFilterData::queryForPreferredSearchProvider(const QString& provider) const
00376 {
00377     const KUriFilterSearchProvider* searchProvider = d->searchProviderMap.value(provider);
00378     if (searchProvider)
00379         return (searchProvider->defaultKey() % searchTermSeparator() % searchTerm());
00380     return QString();
00381 }
00382 
00383 QStringList KUriFilterData::allQueriesForSearchProvider(const QString& provider) const
00384 {
00385     const KUriFilterSearchProvider* searchProvider = d->searchProviderMap.value(provider);
00386     if (searchProvider)
00387         return searchProvider->keys();
00388     return QStringList();
00389 }
00390 
00391 QString KUriFilterData::iconNameForPreferredSearchProvider(const QString &provider) const
00392 {
00393     const KUriFilterSearchProvider* searchProvider = d->searchProviderMap.value(provider);
00394     if (searchProvider)
00395         return searchProvider->iconName();
00396     return QString();
00397 }
00398 
00399 QStringList KUriFilterData::alternateSearchProviders() const
00400 {
00401     return d->alternateSearchProviders;
00402 }
00403 
00404 QString KUriFilterData::alternateDefaultSearchProvider() const
00405 {
00406     return d->alternateDefaultSearchProvider;
00407 }
00408 
00409 QString KUriFilterData::defaultUrlScheme() const
00410 {
00411     return d->defaultUrlScheme;
00412 }
00413 
00414 KUriFilterData::SearchFilterOptions KUriFilterData::searchFilteringOptions() const
00415 {
00416     return d->searchFilterOptions;
00417 }
00418 
00419 QString KUriFilterData::iconName()
00420 {
00421     if (d->wasModified) {
00422         d->iconName = lookupIconNameFor(d->url, d->uriType);
00423         d->wasModified = false;
00424     }
00425 
00426     return d->iconName;
00427 }
00428 
00429 void KUriFilterData::setData( const KUrl& url )
00430 {
00431     d->setData(url, url.url());
00432 }
00433 
00434 void KUriFilterData::setData( const QString& url )
00435 {
00436     d->setData(KUrl(url), url);
00437 }
00438 
00439 bool KUriFilterData::setAbsolutePath( const QString& absPath )
00440 {
00441     // Since a malformed URL could possibly be a relative
00442     // URL we tag it as a possible local resource...
00443     if( (d->url.protocol().isEmpty() || d->url.isLocalFile()) )
00444     {
00445         d->absPath = absPath;
00446         return true;
00447     }
00448     return false;
00449 }
00450 
00451 void KUriFilterData::setCheckForExecutables( bool check )
00452 {
00453     d->checkForExecs = check;
00454 }
00455 
00456 void KUriFilterData::setAlternateSearchProviders(const QStringList &providers)
00457 {
00458     d->alternateSearchProviders = providers;
00459 }
00460 
00461 void KUriFilterData::setAlternateDefaultSearchProvider(const QString &provider)
00462 {
00463     d->alternateDefaultSearchProvider = provider;
00464 }
00465 
00466 void KUriFilterData::setDefaultUrlScheme(const QString& scheme)
00467 {
00468     d->defaultUrlScheme = scheme;
00469 }
00470 
00471 void KUriFilterData::setSearchFilteringOptions(SearchFilterOptions options)
00472 {
00473     d->searchFilterOptions = options;
00474 }
00475 
00476 KUriFilterData& KUriFilterData::operator=( const KUrl& url )
00477 {
00478     d->setData(url, url.url());
00479     return *this;
00480 }
00481 
00482 KUriFilterData& KUriFilterData::operator=( const QString& url )
00483 {
00484     d->setData(KUrl(url), url);
00485     return *this;
00486 }
00487 
00488 /*************************  KUriFilterPlugin ******************************/
00489 
00490 KUriFilterPlugin::KUriFilterPlugin( const QString & name, QObject *parent )
00491                  :QObject( parent ), d( 0 )
00492 {
00493     setObjectName( name );
00494 }
00495 
00496 KCModule *KUriFilterPlugin::configModule( QWidget*, const char* ) const
00497 {
00498     return 0;
00499 }
00500 
00501 QString KUriFilterPlugin::configName() const
00502 {
00503     return objectName();
00504 }
00505 
00506 void KUriFilterPlugin::setFilteredUri( KUriFilterData& data, const KUrl& uri ) const
00507 {
00508     data.d->url = uri;
00509     data.d->wasModified = true;
00510     kDebug(7022) << "Got filtered to:" << uri;
00511 }
00512 
00513 void KUriFilterPlugin::setErrorMsg ( KUriFilterData& data,
00514                                      const QString& errmsg ) const
00515 {
00516     data.d->errMsg = errmsg;
00517 }
00518 
00519 void KUriFilterPlugin::setUriType ( KUriFilterData& data,
00520                                     KUriFilterData::UriTypes type) const
00521 {
00522     data.d->uriType = type;
00523     data.d->wasModified = true;
00524 }
00525 
00526 void KUriFilterPlugin::setArguments( KUriFilterData& data,
00527                                      const QString& args ) const
00528 {
00529     data.d->args = args;
00530 }
00531 
00532 void KUriFilterPlugin::setSearchProvider( KUriFilterData &data, const QString& provider,
00533                                           const QString &term, const QChar &separator) const
00534 {
00535     data.d->searchProvider = provider;
00536     data.d->searchTerm = term;
00537     data.d->searchTermSeparator = separator;
00538 }
00539 
00540 #ifndef KDE_NO_DEPRECATED
00541 void KUriFilterPlugin::setPreferredSearchProviders(KUriFilterData &data, const ProviderInfoList &providers) const
00542 {
00543     QHashIterator<QString, QPair<QString, QString> > it (providers);
00544     while (it.hasNext())
00545     {
00546         it.next();
00547         KUriFilterSearchProvider* searchProvider = data.d->searchProviderMap[it.key()];
00548         searchProvider->setName(it.key());
00549         searchProvider->setIconName(it.value().second);
00550         QStringList keys;
00551         const QStringList queries = it.value().first.split(QLatin1Char(','));
00552         Q_FOREACH(const QString& query,  queries)
00553             keys << query.left(query.indexOf(data.d->searchTermSeparator));
00554         searchProvider->setKeys(keys);
00555     }
00556 }
00557 #endif
00558 
00559 void KUriFilterPlugin::setSearchProviders(KUriFilterData &data, const QList<KUriFilterSearchProvider*>& providers) const
00560 {
00561     Q_FOREACH(KUriFilterSearchProvider* searchProvider, providers) {
00562         data.d->searchProviderList << searchProvider->name();
00563         data.d->searchProviderMap.insert(searchProvider->name(), searchProvider);
00564     }
00565 }
00566 
00567 QString KUriFilterPlugin::iconNameFor(const KUrl& url, KUriFilterData::UriTypes type) const
00568 {
00569     return lookupIconNameFor(url, type);
00570 }
00571 
00572 QHostInfo KUriFilterPlugin::resolveName(const QString& hostname, unsigned long timeout) const
00573 {
00574     return KIO::HostInfo::lookupHost(hostname, timeout);
00575 }
00576 
00577 
00578 /*******************************  KUriFilter ******************************/
00579 
00580 class KUriFilterPrivate
00581 {
00582 public:
00583     KUriFilterPrivate() {}
00584     ~KUriFilterPrivate()
00585     {
00586         qDeleteAll(plugins);
00587         plugins.clear();
00588     }
00589     QHash<QString, KUriFilterPlugin *> plugins;
00590     // NOTE: DO NOT REMOVE this variable! Read the
00591     // comments in KUriFilter::loadPlugins to understand why...
00592     QStringList pluginNames; 
00593 };
00594 
00595 KUriFilter *KUriFilter::self()
00596 {
00597     K_GLOBAL_STATIC(KUriFilter, m_self)
00598     return m_self;
00599 }
00600 
00601 KUriFilter::KUriFilter()
00602     : d(new KUriFilterPrivate())
00603 {
00604     loadPlugins();
00605 }
00606 
00607 KUriFilter::~KUriFilter()
00608 {
00609     delete d;
00610 }
00611 
00612 bool KUriFilter::filterUri( KUriFilterData& data, const QStringList& filters )
00613 {
00614     bool filtered = false;
00615 
00616     // If no specific filters were requested, iterate through all the plugins.
00617     // Otherwise, only use available filters.
00618     if( filters.isEmpty() ) {        
00619         QStringListIterator it (d->pluginNames);
00620         while (it.hasNext()) {
00621             KUriFilterPlugin* plugin = d->plugins.value(it.next());
00622             if (plugin &&  plugin->filterUri( data ))
00623                 filtered = true;
00624         }
00625     } else {
00626         QStringListIterator it (filters);
00627         while (it.hasNext()) {
00628             KUriFilterPlugin* plugin = d->plugins.value(it.next());
00629             if (plugin &&  plugin->filterUri( data ))
00630                 filtered = true;
00631         }
00632     }
00633 
00634     return filtered;
00635 }
00636 
00637 bool KUriFilter::filterUri( KUrl& uri, const QStringList& filters )
00638 {
00639     KUriFilterData data(uri);
00640     bool filtered = filterUri( data, filters );
00641     if( filtered ) uri = data.uri();
00642     return filtered;
00643 }
00644 
00645 bool KUriFilter::filterUri( QString& uri, const QStringList& filters )
00646 {
00647     KUriFilterData data(uri);
00648     bool filtered = filterUri( data, filters );
00649     if( filtered )  uri = data.uri().url();
00650     return filtered;
00651 }
00652 
00653 KUrl KUriFilter::filteredUri( const KUrl &uri, const QStringList& filters )
00654 {
00655     KUriFilterData data(uri);
00656     filterUri( data, filters );
00657     return data.uri();
00658 }
00659 
00660 QString KUriFilter::filteredUri( const QString &uri, const QStringList& filters )
00661 {
00662     KUriFilterData data(uri);
00663     filterUri( data, filters );
00664     return data.uri().url();
00665 }
00666 
00667 #ifndef KDE_NO_DEPRECATED
00668 bool KUriFilter::filterSearchUri(KUriFilterData &data)
00669 {
00670     return filterSearchUri(data, (NormalTextFilter | WebShortcutFilter));
00671 }
00672 #endif
00673 
00674 bool KUriFilter::filterSearchUri(KUriFilterData &data, SearchFilterTypes types)
00675 {
00676     QStringList filters;
00677 
00678     if (types & WebShortcutFilter)
00679         filters << "kurisearchfilter";
00680 
00681     if (types & NormalTextFilter)
00682         filters << "kuriikwsfilter";
00683 
00684     return filterUri(data, filters);
00685 }
00686 
00687 
00688 QStringList KUriFilter::pluginNames() const
00689 {
00690     return d->pluginNames;
00691 }
00692 
00693 void KUriFilter::loadPlugins()
00694 {
00695     const KService::List offers = KServiceTypeTrader::self()->query( "KUriFilter/Plugin" );
00696 
00697     // NOTE: Plugin priority is determined by the InitialPreference entry in
00698     // the .desktop files, so the trader result is already sorted and should
00699     // not be manually sorted.    
00700     Q_FOREACH (const KService::Ptr &ptr, offers) {
00701         KUriFilterPlugin *plugin = ptr->createInstance<KUriFilterPlugin>();
00702         if (plugin) {
00703             const QString& pluginName = plugin->objectName();
00704             Q_ASSERT( !pluginName.isEmpty() );
00705             d->plugins.insert(pluginName, plugin );
00706             // Needed to ensure the order of filtering is honored since
00707             // items are ordered arbitarily in a QHash and QMap always
00708             // sorts by keys. Both undesired behavior.
00709             d->pluginNames << pluginName;
00710         }
00711     }
00712 }
00713 
00714 #include "kurifilter.moc"

KIO

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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.5
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