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"
KDE 4.7 API Reference