~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to plasma/generic/runners/services/servicerunner.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
 
3
 *
 
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
 
7
 *
 
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
 
12
 *
 
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.
 
17
 */
 
18
 
 
19
#include "servicerunner.h"
 
20
 
 
21
#include <QMimeData>
 
22
 
 
23
#include <KIcon>
 
24
#include <KDebug>
 
25
#include <KLocale>
 
26
#include <KRun>
 
27
#include <KService>
 
28
#include <KServiceTypeTrader>
 
29
#include <KUrl>
 
30
 
 
31
ServiceRunner::ServiceRunner(QObject *parent, const QVariantList &args)
 
32
    : Plasma::AbstractRunner(parent, args)
 
33
{
 
34
    Q_UNUSED(args)
 
35
 
 
36
    setObjectName( QLatin1String("Application" ));
 
37
    setPriority(AbstractRunner::HighestPriority);
 
38
 
 
39
    addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds applications whose name or description match :q:")));
 
40
}
 
41
 
 
42
ServiceRunner::~ServiceRunner()
 
43
{
 
44
}
 
45
 
 
46
void ServiceRunner::match(Plasma::RunnerContext &context)
 
47
{
 
48
    const QString term = context.query();
 
49
    if (term.length() <  3) {
 
50
        return;
 
51
    }
 
52
 
 
53
    // Search for applications which are executable and case-insensitively match the search term
 
54
    // See http://techbase.kde.org/Development/Tutorials/Services/Traders#The_KTrader_Query_Language
 
55
    // if the following is unclear to you.
 
56
    QString query = QString("exist Exec and ('%1' =~ Name)").arg(term);
 
57
    KService::List services = KServiceTypeTrader::self()->query("Application", query);
 
58
 
 
59
    QList<Plasma::QueryMatch> matches;
 
60
 
 
61
    QSet<QString> seen;
 
62
    if (!services.isEmpty()) {
 
63
        //kDebug() << service->name() << "is an exact match!" << service->storageId() << service->exec();
 
64
        foreach (const KService::Ptr &service, services) {
 
65
            if (!service->noDisplay() && service->property("NotShowIn", QVariant::String) != "KDE") {
 
66
                Plasma::QueryMatch match(this);
 
67
                match.setType(Plasma::QueryMatch::ExactMatch);
 
68
                setupMatch(service, match);
 
69
                match.setRelevance(1);
 
70
                matches << match;
 
71
                seen.insert(service->storageId());
 
72
                seen.insert(service->exec());
 
73
            }
 
74
        }
 
75
    }
 
76
 
 
77
    if (!context.isValid()) {
 
78
        return;
 
79
    }
 
80
 
 
81
    // Search for applications which are executable and the term case-insensitive matches any of
 
82
    // * a substring of one of the keywords
 
83
    // * a substring of the GenericName field
 
84
    // * a substring of the Name field
 
85
    // Note that before asking for the content of e.g. Keywords and GenericName we need to ask if
 
86
    // they exist to prevent a tree evaluation error if they are not defined.
 
87
    query = QString("exist Exec and ( (exist Keywords and '%1' ~subin Keywords) or (exist GenericName and '%1' ~~ GenericName) or (exist Name and '%1' ~~ Name) or ('%1' ~~ Exec) )").arg(term);
 
88
    services = KServiceTypeTrader::self()->query("Application", query);
 
89
    services += KServiceTypeTrader::self()->query("KCModule", query);
 
90
 
 
91
    //kDebug() << "got " << services.count() << " services from " << query;
 
92
    foreach (const KService::Ptr &service, services) {
 
93
        if (!context.isValid()) {
 
94
            return;
 
95
        }
 
96
 
 
97
        if (service->noDisplay()) {
 
98
            continue;
 
99
        }
 
100
 
 
101
        const QString id = service->storageId();
 
102
        const QString exec = service->exec();
 
103
        if (seen.contains(id) || seen.contains(exec)) {
 
104
            //kDebug() << "already seen" << id << exec;
 
105
            continue;
 
106
        }
 
107
 
 
108
        //kDebug() << "haven't seen" << id << "so processing now";
 
109
        seen.insert(id);
 
110
        seen.insert(exec);
 
111
 
 
112
        Plasma::QueryMatch match(this);
 
113
        match.setType(Plasma::QueryMatch::PossibleMatch);
 
114
        setupMatch(service, match);
 
115
        qreal relevance(0.6);
 
116
 
 
117
        if (service->name().contains(term, Qt::CaseInsensitive)) {
 
118
            relevance = 0.8;
 
119
 
 
120
            if (service->name().startsWith(term, Qt::CaseInsensitive)) {
 
121
                relevance += 0.1;
 
122
            }
 
123
        } else if (service->genericName().contains(term, Qt::CaseInsensitive)) {
 
124
            relevance = 0.7;
 
125
 
 
126
            if (service->genericName().startsWith(term, Qt::CaseInsensitive)) {
 
127
                relevance += 0.1;
 
128
            }
 
129
        }
 
130
 
 
131
        if (service->categories().contains("KDE") || service->serviceTypes().contains("KCModule")) {
 
132
            //kDebug() << "found a kde thing" << id << match.subtext() << relevance;
 
133
            if (id.startsWith("kde-")) {
 
134
                //kDebug() << "old" << service->type();
 
135
                if (!service->isApplication()) {
 
136
                    // avoid showing old kcms and what not
 
137
                    continue;
 
138
                }
 
139
 
 
140
                // This is an older version, let's disambiguate it
 
141
                QString subtext("KDE3");
 
142
 
 
143
                if (!match.subtext().isEmpty()) {
 
144
                    subtext.append(", " + match.subtext());
 
145
                }
 
146
 
 
147
                match.setSubtext(subtext);
 
148
            } else {
 
149
                relevance += .1;
 
150
            }
 
151
        }
 
152
 
 
153
        //kDebug() << service->name() << "is this relevant:" << relevance;
 
154
        match.setRelevance(relevance);
 
155
        matches << match;
 
156
    }
 
157
 
 
158
    //search for applications whose categories contains the query
 
159
    query = QString("exist Exec and (exist Categories and '%1' ~subin Categories)").arg(term);
 
160
    services = KServiceTypeTrader::self()->query("Application", query);
 
161
 
 
162
    //kDebug() << service->name() << "is an exact match!" << service->storageId() << service->exec();
 
163
    foreach (const KService::Ptr &service, services) {
 
164
        if (!context.isValid()) {
 
165
            return;
 
166
        }
 
167
 
 
168
        if (!service->noDisplay()) {
 
169
            QString id = service->storageId();
 
170
            QString exec = service->exec();
 
171
            if (seen.contains(id) || seen.contains(exec)) {
 
172
                //kDebug() << "already seen" << id << exec;
 
173
                continue;
 
174
            }
 
175
            Plasma::QueryMatch match(this);
 
176
            match.setType(Plasma::QueryMatch::PossibleMatch);
 
177
            setupMatch(service, match);
 
178
 
 
179
            qreal relevance = 0.6;
 
180
            if (service->categories().contains("X-KDE-More") ||
 
181
                    !service->showInKDE()) {
 
182
                relevance = 0.5;
 
183
            }
 
184
 
 
185
            if (service->isApplication()) {
 
186
                relevance += .4;
 
187
            }
 
188
 
 
189
            match.setRelevance(relevance);
 
190
            matches << match;
 
191
        }
 
192
    }
 
193
 
 
194
    context.addMatches(term, matches);
 
195
}
 
196
 
 
197
void ServiceRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
 
198
{
 
199
    Q_UNUSED(context);
 
200
    KService::Ptr service = KService::serviceByStorageId(match.data().toString());
 
201
    if (service) {
 
202
        KRun::run(*service, KUrl::List(), 0);
 
203
    }
 
204
}
 
205
 
 
206
void ServiceRunner::setupMatch(const KService::Ptr &service, Plasma::QueryMatch &match)
 
207
{
 
208
    const QString name = service->name();
 
209
 
 
210
    match.setText(name);
 
211
    match.setData(service->storageId());
 
212
 
 
213
    if (!service->genericName().isEmpty() && service->genericName() != name) {
 
214
        match.setSubtext(service->genericName());
 
215
    } else if (!service->comment().isEmpty()) {
 
216
        match.setSubtext(service->comment());
 
217
    }
 
218
 
 
219
    if (!service->icon().isEmpty()) {
 
220
        match.setIcon(KIcon(service->icon()));
 
221
    }
 
222
}
 
223
 
 
224
QMimeData * ServiceRunner::mimeDataForMatch(const Plasma::QueryMatch *match)
 
225
{
 
226
    KService::Ptr service = KService::serviceByStorageId(match->data().toString());
 
227
    if (service) {
 
228
        QMimeData * result = new QMimeData();
 
229
        QList<QUrl> urls;
 
230
        urls << KUrl(service->entryPath());
 
231
        kDebug() << urls;
 
232
        result->setUrls(urls);
 
233
        return result;
 
234
    }
 
235
 
 
236
    return 0;
 
237
}
 
238
 
 
239
#include "servicerunner.moc"
 
240