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