Changeset View
Changeset View
Standalone View
Standalone View
runners/services/servicerunner.cpp
Show All 33 Lines | |||||
34 | #include <KLocalizedString> | 34 | #include <KLocalizedString> | ||
35 | #include <KNotificationJobUiDelegate> | 35 | #include <KNotificationJobUiDelegate> | ||
36 | #include <KService> | 36 | #include <KService> | ||
37 | #include <KServiceAction> | 37 | #include <KServiceAction> | ||
38 | #include <KServiceTypeTrader> | 38 | #include <KServiceTypeTrader> | ||
39 | #include <KStringHandler> | 39 | #include <KStringHandler> | ||
40 | 40 | | |||
41 | #include <KIO/ApplicationLauncherJob> | 41 | #include <KIO/ApplicationLauncherJob> | ||
42 | #include <KIO/DesktopExecParser> | ||||
42 | 43 | | |||
43 | #include "debug.h" | 44 | #include "debug.h" | ||
44 | 45 | | |||
45 | namespace { | 46 | namespace { | ||
46 | 47 | | |||
47 | int weightedLength(const QString &query) { | 48 | int weightedLength(const QString &query) { | ||
48 | return KStringHandler::logicalLength(query); | 49 | return KStringHandler::logicalLength(query); | ||
49 | } | 50 | } | ||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Line(s) | 144 | { | |||
155 | for (const QStringRef &str : strList) | 156 | for (const QStringRef &str : strList) | ||
156 | { | 157 | { | ||
157 | keywordTemplate += QStringLiteral(" and '%1' ~subin Keywords").arg(str.toString()); | 158 | keywordTemplate += QStringLiteral(" and '%1' ~subin Keywords").arg(str.toString()); | ||
158 | genericNameTemplate += QStringLiteral(" and '%1' ~~ GenericName").arg(str.toString()); | 159 | genericNameTemplate += QStringLiteral(" and '%1' ~~ GenericName").arg(str.toString()); | ||
159 | nameTemplate += QStringLiteral(" and '%1' ~~ Name").arg(str.toString()); | 160 | nameTemplate += QStringLiteral(" and '%1' ~~ Name").arg(str.toString()); | ||
160 | commentTemplate += QStringLiteral(" and '%1' ~~ Comment").arg(str.toString()); | 161 | commentTemplate += QStringLiteral(" and '%1' ~~ Comment").arg(str.toString()); | ||
161 | } | 162 | } | ||
162 | 163 | | |||
163 | QString finalQuery = QStringLiteral("exist Exec and ( (%1) or (%2) or (%3) or ('%4' ~~ Exec) or (%5) )") | 164 | QString finalQuery = QStringLiteral("exist Exec and ( (%1) or (%2) or (%3) or (%4) )") | ||
164 | .arg(keywordTemplate, genericNameTemplate, nameTemplate, strList[0].toString(), commentTemplate); | 165 | .arg(keywordTemplate, genericNameTemplate, nameTemplate, commentTemplate); | ||
anthonyfieroni: It should be `%4` instead of `%5` | |||||
165 | 166 | | |||
166 | qCDebug(RUNNER_SERVICES) << "Final query : " << finalQuery; | 167 | qCDebug(RUNNER_SERVICES) << "Final query : " << finalQuery; | ||
167 | return finalQuery; | 168 | return finalQuery; | ||
168 | } | 169 | } | ||
169 | 170 | | |||
170 | void setupMatch(const KService::Ptr &service, Plasma::QueryMatch &match) | 171 | void setupMatch(const KService::Ptr &service, Plasma::QueryMatch &match) | ||
171 | { | 172 | { | ||
172 | const QString name = service->name(); | 173 | const QString name = service->name(); | ||
Show All 39 Lines | 208 | for (const KService::Ptr &service : services) { | |||
212 | Plasma::QueryMatch match(m_runner); | 213 | Plasma::QueryMatch match(m_runner); | ||
213 | match.setType(Plasma::QueryMatch::ExactMatch); | 214 | match.setType(Plasma::QueryMatch::ExactMatch); | ||
214 | setupMatch(service, match); | 215 | setupMatch(service, match); | ||
215 | match.setRelevance(1); | 216 | match.setRelevance(1); | ||
216 | matches << match; | 217 | matches << match; | ||
217 | } | 218 | } | ||
218 | } | 219 | } | ||
219 | 220 | | |||
221 | KService::List execServicesFor(const QStringRef &primaryQuery, const KService::List &services) | ||||
222 | { | ||||
223 | // Potential Exec matches. | ||||
224 | // Exec lines can contain a lot of garbage so we'll want to apply additional constraints. | ||||
225 | // Notably any service that exclusively matches on its Exec content MUST have the match | ||||
226 | // on the actual exectuableName not any env var or other arguments. | ||||
227 | // All services that are also matched through the general purpose query do not count into this | ||||
228 | // as they are matches in their own right. | ||||
229 | const QString execQuery = QStringLiteral("exist Exec and ('%1' ~~ Exec)").arg(primaryQuery); | ||||
230 | KService::List execServices = KServiceTypeTrader::self()->query(QStringLiteral("Application"), execQuery); | ||||
231 | execServices += KServiceTypeTrader::self()->query(QStringLiteral("KCModule"), execQuery); | ||||
232 | | ||||
233 | QHash<QString, KService::Ptr> execMap; | ||||
234 | for (const KService::Ptr &service : qAsConst(execServices)) { | ||||
235 | execMap.insert(service->storageId(), service); | ||||
236 | } | ||||
237 | | ||||
238 | for (const KService::Ptr &service : qAsConst(services)) { | ||||
239 | execMap.remove(service->storageId()); | ||||
240 | } | ||||
241 | for (auto it = execMap.begin(); it != execMap.end(); ++it) { | ||||
242 | if (!KIO::DesktopExecParser::executableName(it.value()->exec()).contains(primaryQuery)) { | ||||
243 | it = execMap.erase(it); | ||||
244 | } | ||||
245 | if (it == execMap.end()) { | ||||
246 | break; | ||||
247 | } | ||||
248 | } | ||||
249 | | ||||
250 | return execMap.values(); | ||||
251 | } | ||||
252 | | ||||
220 | void matchNameKeywordAndGenericName() | 253 | void matchNameKeywordAndGenericName() | ||
221 | { | 254 | { | ||
222 | //Splitting the query term to match using subsequences | 255 | //Splitting the query term to match using subsequences | ||
223 | QVector<QStringRef> queryList = term.splitRef(QLatin1Char(' ')); | 256 | QVector<QStringRef> queryList = term.splitRef(QLatin1Char(' ')); | ||
224 | 257 | | |||
225 | // If the term length is < 3, no real point searching the Keywords and GenericName | 258 | // If the term length is < 3, no real point searching the Keywords and GenericName | ||
226 | if (weightedTermLength < 3) { | 259 | if (weightedTermLength < 3) { | ||
227 | query = QStringLiteral("exist Exec and ( (exist Name and '%1' ~~ Name) or ('%1' ~~ Exec) )").arg(term); | 260 | query = QStringLiteral("exist Exec and (exist Name and '%1' ~~ Name)").arg(term); | ||
228 | } else { | 261 | } else { | ||
229 | //Match using subsequences (Bug: 262837) | 262 | //Match using subsequences (Bug: 262837) | ||
230 | query = generateQuery(queryList); | 263 | query = generateQuery(queryList); | ||
231 | } | 264 | } | ||
232 | 265 | | |||
233 | KService::List services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), query); | 266 | KService::List services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), query); | ||
234 | services += KServiceTypeTrader::self()->query(QStringLiteral("KCModule"), query); | 267 | services += KServiceTypeTrader::self()->query(QStringLiteral("KCModule"), query); | ||
268 | services += execServicesFor(queryList[0], services); | ||||
235 | 269 | | |||
236 | qCDebug(RUNNER_SERVICES) << "got " << services.count() << " services from " << query; | 270 | qCDebug(RUNNER_SERVICES) << "got " << services.count() << " services from " << query; | ||
237 | for (const KService::Ptr &service : qAsConst(services)) { | 271 | for (const KService::Ptr &service : qAsConst(services)) { | ||
238 | if (disqualify(service)) { | 272 | if (disqualify(service)) { | ||
239 | continue; | 273 | continue; | ||
240 | } | 274 | } | ||
241 | 275 | | |||
242 | const QString id = service->storageId(); | 276 | const QString id = service->storageId(); | ||
243 | const QString name = service->desktopEntryName(); | 277 | const QString name = service->desktopEntryName(); | ||
244 | const QString exec = service->exec(); | 278 | const QString exec = KIO::DesktopExecParser::executableName(service->exec()); | ||
245 | 279 | | |||
246 | Plasma::QueryMatch match(m_runner); | 280 | Plasma::QueryMatch match(m_runner); | ||
247 | match.setType(Plasma::QueryMatch::PossibleMatch); | 281 | match.setType(Plasma::QueryMatch::PossibleMatch); | ||
248 | setupMatch(service, match); | 282 | setupMatch(service, match); | ||
249 | qreal relevance(0.6); | 283 | qreal relevance(0.6); | ||
250 | 284 | | |||
251 | // If the term was < 3 chars and NOT at the beginning of the App's name or Exec, then | 285 | // If the term was < 3 chars and NOT at the beginning of the App's name or Exec, then | ||
252 | // chances are the user doesn't want that app. | 286 | // chances are the user doesn't want that app. | ||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |
It should be %4 instead of %5