Add (and install) svg for the new krunner interface.
[kdebase/uwolfer.git] / workspace / libs / plasma / abstractrunner.cpp
blobce2515925e1c6c3e384ef782db9e94248fe069ad
1 /*
2 * Copyright 2006-2007 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 as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "abstractrunner.h"
22 #include <QMutex>
23 #include <QMutexLocker>
25 #include <KDebug>
26 #include <KPluginInfo>
27 #include <KServiceTypeTrader>
28 #include <QTimer>
30 #include "scripting/runnerscript.h"
31 #include "searchcontext.h"
33 namespace Plasma
36 class AbstractRunner::Private
38 public:
39 bool hasMatchOptions;
40 bool hasConfig;
41 Priority priority;
42 Speed speed;
43 RunnerScript* script;
44 KPluginInfo runnerDescription;
45 AbstractRunner* runner;
46 QTime runtime;
47 int fastRuns;
49 Private(AbstractRunner* r, KService::Ptr service)
50 : priority(NormalPriority),
51 speed(NormalSpeed),
52 script(0),
53 runnerDescription(service),
54 runner(r),
55 fastRuns(0)
57 if (runnerDescription.isValid()) {
58 QString language = runnerDescription.property("X-Plasma-Language").toString();
60 if (!language.isEmpty()) {
61 script = Plasma::loadScriptEngine(language, runner);
62 if (!script) {
63 kDebug() << "Could not create a" << language << "ScriptEngine for the"
64 << runnerDescription.name() << "Runner.";
65 } else {
66 QTimer::singleShot(0, runner, SLOT(init()));
72 static QMutex bigLock;
75 QMutex AbstractRunner::Private::bigLock;
77 AbstractRunner::AbstractRunner(QObject* parent, const QString& serviceId)
78 : QObject(parent),
79 d(new Private(this, KService::serviceByStorageId(serviceId)))
83 AbstractRunner::AbstractRunner(QObject* parent, const QVariantList& args)
84 : QObject(parent),
85 d(new Private(this, KService::serviceByStorageId(args.count() > 0 ? args[0].toString() : QString())))
89 AbstractRunner::~AbstractRunner()
91 delete d;
94 KConfigGroup AbstractRunner::config() const
96 QString group = objectName();
97 if (group.isEmpty()) {
98 group = "UnnamedRunner";
101 KConfigGroup runners(KGlobal::config(), "Runners");
102 return KConfigGroup(&runners, group);
105 void AbstractRunner::performMatch( Plasma::SearchContext &globalContext )
107 static const int reasonableRunTime = 1500;
108 static const int fastEnoughTime = 250;
110 d->runtime.restart();
111 SearchContext localContext(0, globalContext);
113 match(&localContext);
115 // automatically rate limit runners that become slooow
116 const int runtime = d->runtime.elapsed();
117 bool slowed = speed() == SlowSpeed;
119 if (!slowed && runtime > reasonableRunTime) {
120 // we punish runners that return too slowly, even if they don't bring
121 // back matches
122 kDebug() << runnerName() << "runner is too slow, putting it on the back burner.";
123 d->fastRuns = 0;
124 setSpeed(SlowSpeed);
127 //If matches were not added, delete items on the heap
128 if (localContext.addMatchesTo(globalContext) &&
129 slowed && runtime < fastEnoughTime) {
130 ++d->fastRuns;
132 if (d->fastRuns > 2) {
133 // we reward slowed runners who bring back matches fast enough
134 // 3 times in a row
135 kDebug() << runnerName() << "runner is faster than we thought, kicking it up a notch";
136 setSpeed(NormalSpeed);
141 bool AbstractRunner::hasMatchOptions()
143 return d->hasMatchOptions;
146 void AbstractRunner::setHasMatchOptions(bool hasMatchOptions)
148 d->hasMatchOptions = hasMatchOptions;
151 void AbstractRunner::createMatchOptions(QWidget *parent)
153 Q_UNUSED(parent)
156 bool AbstractRunner::isConfigurable()
158 return d->hasConfig;
161 void AbstractRunner::setIsConfigurable(bool hasConfig)
163 d->hasConfig = hasConfig;
166 void AbstractRunner::createConfigurationInterface(QWidget *widget)
168 Q_UNUSED(widget)
171 AbstractRunner::Speed AbstractRunner::speed() const
173 return d->speed;
176 void AbstractRunner::setSpeed(Speed speed)
178 d->speed = speed;
181 AbstractRunner::Priority AbstractRunner::priority() const
183 return d->priority;
186 void AbstractRunner::setPriority(Priority priority)
188 d->priority = priority;
191 KService::List AbstractRunner::serviceQuery(const QString &serviceType, const QString &constraint) const
193 QMutexLocker lock(&Private::bigLock);
194 return KServiceTypeTrader::self()->query(serviceType, constraint);
197 QMutex* AbstractRunner::bigLock() const
199 return &Private::bigLock;
202 void AbstractRunner::exec(const Plasma::SearchContext *search, const Plasma::SearchMatch *action)
204 if (d->script) {
205 return d->script->exec(search, action);
209 void AbstractRunner::match(Plasma::SearchContext *search)
211 if (d->script) {
212 return d->script->match(search);
216 QString AbstractRunner::runnerName() const
218 if (!d->runnerDescription.isValid()) {
219 return objectName();
221 return d->runnerDescription.property("X-Plasma-RunnerName").toString();
224 void AbstractRunner::init()
226 if (d->script) {
227 d->script->init();
231 AbstractRunner::List AbstractRunner::load(QObject* parent, const QStringList& whitelist)
233 List firstRunners;
234 List runners;
235 List lastRunners;
237 KService::List offers = KServiceTypeTrader::self()->query("Plasma/Runner");
238 QString error;
239 foreach (KService::Ptr service, offers) {
240 if (whitelist.empty() || whitelist.contains(service->name())) {
241 QString language = service->property("X-Plasma-Language").toString();
242 AbstractRunner* runner = 0;
244 if (language.isEmpty()) {
245 QVariantList args;
246 args << service->storageId();
247 runner = service->createInstance<AbstractRunner>(parent, args, &error);
248 } else {
249 runner = new AbstractRunner(parent, service->storageId());
252 if (runner) {
253 //kDebug() << "loaded runner : " << service->name();
254 QString phase = service->property("X-Plasma-RunnerPhase").toString();
255 if (phase == "last") {
256 lastRunners.append(runner);
257 } else if (phase == "first") {
258 firstRunners.append(runner);
259 } else {
260 runners.append(runner);
262 } else {
263 kDebug() << "failed to load runner : " << service->name() << ". error reported: " << error;
268 firstRunners << runners << lastRunners;
269 return firstRunners;
272 } // Plasma namespace
274 #include "abstractrunner.moc"