fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kio / kio / kurifilter.cpp
blob8b5e1323568e3694cda9e0f6cfab2b63e2a6c48e
1 /* This file is part of the KDE libraries
2 * Copyright (C) 2000 Yves Arrouye <yves@realnames.com>
3 * Copyright (C) 2000 Dawit Alemayehu <adawit at kde.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 **/
21 #include "kurifilter.h"
23 #include <config.h>
24 #include <QPixmap>
26 #include <kdebug.h>
27 #include <kiconloader.h>
28 #include <kservicetypetrader.h>
29 #include <kmimetype.h>
31 typedef QList<KUriFilterPlugin *> KUriFilterPluginList;
33 class KUriFilterDataPrivate
35 public:
36 explicit KUriFilterDataPrivate( const KUrl& url, const QString& typedUrl ) :
37 bCheckForExecutables(true),
38 bChanged(true),
39 pURI(url),
40 iType(KUriFilterData::Unknown),
41 typedString(typedUrl)
44 void setData( const KUrl& url, const QString& typedUrl )
46 bCheckForExecutables = true;
47 bChanged = true;
48 strErrMsg.clear();
49 strIconName.clear();
50 pURI = url;
51 iType = KUriFilterData::Unknown;
52 typedString = typedUrl;
54 KUriFilterDataPrivate( KUriFilterDataPrivate * data )
56 iType = data->iType;
57 pURI = data->pURI;
58 strErrMsg = data->strErrMsg;
59 strIconName = data->strIconName;
60 bChanged = data->bChanged;
61 bCheckForExecutables = data->bCheckForExecutables;
62 abs_path = data->abs_path;
63 typedString = data->typedString;
64 args = data->args;
66 bool bCheckForExecutables;
67 bool bChanged;
69 QString strErrMsg;
70 QString strIconName;
72 KUrl pURI;
73 KUriFilterData::UriTypes iType;
75 QString abs_path;
76 QString args;
77 QString typedString;
80 KUriFilterData::KUriFilterData()
81 : d( new KUriFilterDataPrivate( KUrl(), QString() ) )
85 KUriFilterData::KUriFilterData( const KUrl& url )
86 : d( new KUriFilterDataPrivate( url, url.url() ) )
90 KUriFilterData::KUriFilterData( const QString& url )
91 : d( new KUriFilterDataPrivate( KUrl(url), url ) )
93 d->typedString = url;
97 KUriFilterData::KUriFilterData( const KUriFilterData& data )
98 : d( new KUriFilterDataPrivate( data.d ) )
102 KUriFilterData::~KUriFilterData()
104 delete d;
107 KUrl KUriFilterData::uri() const
109 return d->pURI;
112 QString KUriFilterData::errorMsg() const
114 return d->strErrMsg;
117 KUriFilterData::UriTypes KUriFilterData::uriType() const
119 return d->iType;
122 void KUriFilterData::setData( const KUrl& url )
124 d->setData(url, url.url());
127 void KUriFilterData::setData( const QString& url )
129 d->setData(KUrl(url), url);
132 bool KUriFilterData::setAbsolutePath( const QString& absPath )
134 // Since a malformed URL could possibly be a relative
135 // URL we tag it as a possible local resource...
136 if( (d->pURI.protocol().isEmpty() || d->pURI.isLocalFile()) )
138 d->abs_path = absPath;
139 return true;
141 return false;
144 QString KUriFilterData::absolutePath() const
146 return d->abs_path;
149 bool KUriFilterData::hasAbsolutePath() const
151 return !d->abs_path.isEmpty();
154 QString KUriFilterData::argsAndOptions() const
156 return d->args;
159 bool KUriFilterData::hasArgsAndOptions() const
161 return !d->args.isEmpty();
164 QString KUriFilterData::iconName()
166 if( d->bChanged )
168 switch ( d->iType )
170 case KUriFilterData::LocalFile:
171 case KUriFilterData::LocalDir:
172 case KUriFilterData::NetProtocol:
174 d->strIconName = KMimeType::iconNameForUrl( d->pURI );
175 break;
177 case KUriFilterData::Executable:
179 QString exeName = d->pURI.url();
180 exeName = exeName.mid( exeName.lastIndexOf( '/' ) + 1 ); // strip path if given
181 KService::Ptr service = KService::serviceByDesktopName( exeName );
182 if (service && service->icon() != QLatin1String( "unknown" ))
183 d->strIconName = service->icon();
184 // Try to find an icon with the same name as the binary (useful for non-kde apps)
185 else if ( !KIconLoader::global()->loadIcon( exeName, KIconLoader::NoGroup, 16, KIconLoader::DefaultState, QStringList(), 0, true ).isNull() )
186 d->strIconName = exeName;
187 else
188 // not found, use default
189 d->strIconName = QLatin1String("system-run");
190 break;
192 case KUriFilterData::Help:
194 d->strIconName = QLatin1String("khelpcenter");
195 break;
197 case KUriFilterData::Shell:
199 d->strIconName = QLatin1String("konsole");
200 break;
202 case KUriFilterData::Error:
203 case KUriFilterData::Blocked:
205 d->strIconName = QLatin1String("error");
206 break;
208 default:
209 d->strIconName.clear();
210 break;
212 d->bChanged = false;
214 return d->strIconName;
217 void KUriFilterData::setCheckForExecutables( bool check )
219 d->bCheckForExecutables = check;
222 bool KUriFilterData::checkForExecutables() const
224 return d->bCheckForExecutables;
227 QString KUriFilterData::typedString() const
229 return d->typedString;
232 KUriFilterData& KUriFilterData::operator=( const KUrl& url )
234 d->setData(url, url.url());
235 return *this;
238 KUriFilterData& KUriFilterData::operator=( const QString& url )
240 d->setData(KUrl(url), url);
241 return *this;
244 /************************* KUriFilterPlugin ******************************/
246 KUriFilterPlugin::KUriFilterPlugin( const QString & name, QObject *parent )
247 : QObject( parent ), d( 0 )
249 setObjectName( name );
252 KCModule *KUriFilterPlugin::configModule( QWidget*, const char* ) const
254 return 0;
257 QString KUriFilterPlugin::configName() const
259 return objectName();
262 void KUriFilterPlugin::setFilteredUri( KUriFilterData& data, const KUrl& uri ) const
264 if ( data.uri() != uri )
266 data.d->pURI = uri;
267 data.d->bChanged = true;
271 void KUriFilterPlugin::setErrorMsg ( KUriFilterData& data,
272 const QString& errmsg ) const
274 data.d->strErrMsg = errmsg;
277 void KUriFilterPlugin::setUriType ( KUriFilterData& data,
278 KUriFilterData::UriTypes type) const
280 data.d->iType = type;
281 data.d->bChanged = true;
284 void KUriFilterPlugin::setArguments( KUriFilterData& data,
285 const QString& args ) const
287 data.d->args = args;
290 /******************************* KUriFilter ******************************/
292 class KUriFilterPrivate
294 public:
295 KUriFilterPrivate() {}
296 ~KUriFilterPrivate()
298 qDeleteAll(lstPlugins);
300 QList<KUriFilterPlugin *> lstPlugins;
303 KUriFilter *KUriFilter::self()
305 K_GLOBAL_STATIC(KUriFilter, m_self)
306 return m_self;
309 KUriFilter::KUriFilter()
310 : d(new KUriFilterPrivate())
312 loadPlugins();
315 KUriFilter::~KUriFilter()
317 delete d;
320 static KUriFilterPlugin* findPluginByName( const KUriFilterPluginList& lst, const QString& name )
322 for ( KUriFilterPluginList::const_iterator it = lst.begin(), end = lst.end();
323 it != end ; ++it ) {
324 if ( (*it)->objectName() == name )
325 return *it;
327 return 0;
330 bool KUriFilter::filterUri( KUriFilterData& data, const QStringList& filters )
332 KUriFilterPluginList use_plugins;
334 // If we have a filter list, only include the once
335 // explicitly specified by it. Otherwise, use all available filters...
336 if( filters.isEmpty() )
337 use_plugins = d->lstPlugins; // Use everything that is loaded...
338 else {
339 //kDebug() << "Named plugins requested...";
340 for( QStringList::ConstIterator lst = filters.begin(); lst != filters.end(); ++lst ) {
341 KUriFilterPlugin* plugin = findPluginByName( d->lstPlugins, *lst );
342 if (plugin) {
343 //kDebug() << "Will use filter plugin named: " << plugin->objectName();
344 use_plugins.append(plugin);
349 //kDebug() << "Using" << use_plugins.count() << "out of the"
350 // << d->lstPlugins.count() << "available plugins";
351 bool filtered = false;
352 for ( KUriFilterPluginList::const_iterator it = use_plugins.constBegin(), end = use_plugins.constEnd();
353 it != end; ++it ) {
354 //kDebug() << "Using a filter plugin named: " << (*it)->objectName();
355 if( (*it)->filterUri( data ))
356 filtered = true;
358 return filtered;
361 bool KUriFilter::filterUri( KUrl& uri, const QStringList& filters )
363 KUriFilterData data(uri);
364 bool filtered = filterUri( data, filters );
365 if( filtered ) uri = data.uri();
366 return filtered;
369 bool KUriFilter::filterUri( QString& uri, const QStringList& filters )
371 KUriFilterData data(uri);
372 bool filtered = filterUri( data, filters );
373 if( filtered ) uri = data.uri().url();
374 return filtered;
377 KUrl KUriFilter::filteredUri( const KUrl &uri, const QStringList& filters )
379 KUriFilterData data(uri);
380 filterUri( data, filters );
381 return data.uri();
384 QString KUriFilter::filteredUri( const QString &uri, const QStringList& filters )
386 KUriFilterData data(uri);
387 filterUri( data, filters );
388 return data.uri().url();
391 QStringList KUriFilter::pluginNames() const
393 QStringList list;
394 Q_FOREACH( KUriFilterPlugin* plugin, d->lstPlugins )
395 list.append(plugin->objectName());
396 return list;
399 void KUriFilter::loadPlugins()
401 const KService::List offers = KServiceTypeTrader::self()->query( "KUriFilter/Plugin" );
403 foreach (const KService::Ptr &ptr, offers) {
404 KUriFilterPlugin *plugin = ptr->createInstance<KUriFilterPlugin>();
405 if (!plugin)
406 continue;
407 Q_ASSERT( !plugin->objectName().isEmpty() );
408 d->lstPlugins.append( plugin );
411 // NOTE: Plugin priority is determined by
412 // the InitialPreference entry in the .desktop files,
413 // so the trader result is already sorted.
415 // TODO: Config dialog to differentiate "system"
416 // plugins from "user-defined" ones...
417 // d->lstPlugins.sort();
420 #include "kurifilter.moc"