2 * Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License version 2 as
6 * published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
13 * You should have received a copy of the GNU Library General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "servicerunner.h"
28 #include <KServiceTypeTrader>
30 ServiceRunner::ServiceRunner(QObject
*parent
, const QVariantList
&args
)
31 : Plasma::AbstractRunner( parent
)
35 setObjectName("Application");
36 setPriority(AbstractRunner::HighestPriority
);
39 ServiceRunner::~ServiceRunner()
43 void ServiceRunner::match(Plasma::RunnerContext
&context
)
45 const QString term
= context
.query();
46 if (term
.length() < 3) {
50 QMutexLocker
lock(bigLock());
51 // Search for applications which are executable and case-insensitively match the search term
52 // See http://techbase.kde.org/Development/Tutorials/Services/Traders#The_KTrader_Query_Language
53 // if the following is unclear to you.
54 QString query
= QString("exist Exec and ('%1' =~ Name)").arg(term
);
55 KService::List services
= KServiceTypeTrader::self()->query("Application", query
);
57 QList
<Plasma::QueryMatch
> matches
;
59 QHash
<QString
, bool> seen
;
60 if (!services
.isEmpty()) {
61 //kDebug() << service->name() << "is an exact match!" << service->storageId() << service->exec();
62 KService::Ptr service
= services
.at(0);
63 if (!service
->noDisplay()) {
64 Plasma::QueryMatch
match(this);
65 match
.setType(Plasma::QueryMatch::ExactMatch
);
66 setupAction(service
, match
);
67 match
.setRelevance(1);
69 seen
[service
->storageId()] = true;
70 seen
[service
->exec()] = true;
74 // Search for applications which are executable and the term case-insensitive matches any of
75 // * a substring of one of the keywords
76 // * a substring of the GenericName field
77 // * a substring of the Name field
78 // Note that before asking for the content of e.g. Keywords and GenericName we need to ask if
79 // they exist to prevent a tree evaluation error if they are not defined.
80 query
= QString("exist Exec and ( (exist Keywords and '%1' ~subin Keywords) or (exist GenericName and '%1' ~~ GenericName) or (exist Name and '%1' ~~ Name) )").arg(term
);
81 services
= KServiceTypeTrader::self()->query("Application", query
);
82 services
+= KServiceTypeTrader::self()->query("KCModule", query
);
84 //kDebug() << "got " << services.count() << " services from " << query;
85 foreach (const KService::Ptr
&service
, services
) {
86 if (service
->noDisplay()) {
90 QString id
= service
->storageId();
91 QString exec
= service
->exec();
92 if (seen
.contains(id
) || seen
.contains(exec
)) {
93 //kDebug() << "already seen" << id << exec;
97 //kDebug() << "haven't seen" << id << "so processing now";
101 Plasma::QueryMatch
match(this);
102 match
.setType(Plasma::QueryMatch::PossibleMatch
);
103 setupAction(service
, match
);
104 qreal
relevance(0.6);
106 if (service
->name().contains(term
, Qt::CaseInsensitive
)) {
109 if (service
->name().startsWith(term
, Qt::CaseInsensitive
)) {
112 } else if (service
->genericName().contains(term
, Qt::CaseInsensitive
)) {
115 if (service
->genericName().startsWith(term
, Qt::CaseInsensitive
)) {
120 if (service
->categories().contains("KDE") || service
->serviceTypes().contains("KCModule")) {
121 //kDebug() << "found a kde thing" << id << match.subtext() << relevance;
122 if (id
.startsWith("kde-")) {
123 // This is an older version, let's disambiguate it
124 QString
subtext("KDE3");
126 //kDebug() << "old" << service->type();
127 if (service
->type() == "KCModule") {
128 // avoid showing old kcms
132 if (!match
.subtext().isEmpty()) {
133 subtext
.append(", " + match
.subtext());
136 match
.setSubtext(subtext
);
142 //kDebug() << service->name() << "is this relevant:" << relevance;
143 match
.setRelevance(relevance
);
147 context
.addMatches(term
, matches
);
150 void ServiceRunner::run(const Plasma::RunnerContext
&context
, const Plasma::QueryMatch
&match
)
153 QMutexLocker
lock(bigLock());
154 KService::Ptr service
= KService::serviceByStorageId(match
.data().toString());
156 KRun::run(*service
, KUrl::List(), 0);
160 void ServiceRunner::setupAction(const KService::Ptr
&service
, Plasma::QueryMatch
&match
)
162 const QString name
= service
->name();
165 match
.setData(service
->storageId());
167 if (!service
->genericName().isEmpty() && service
->genericName() != name
) {
168 match
.setSubtext(service
->genericName());
169 } else if (!service
->comment().isEmpty()) {
170 match
.setSubtext(service
->comment());
173 if (!service
->icon().isEmpty()) {
174 match
.setIcon(KIcon(service
->icon()));
178 #include "servicerunner.moc"