• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Plasma

  • sources
  • kde-4.12
  • kdelibs
  • plasma
abstractrunner.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2006-2007 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 as
6  * published by the Free Software Foundation; either version 2, or
7  * (at your option) any later version.
8  *
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
13  *
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.
18  */
19 
20 #include "abstractrunner.h"
21 
22 #include <QAction>
23 #include <QHash>
24 #include <QMenu>
25 #include <QMimeData>
26 #include <QMutex>
27 #include <QMutexLocker>
28 #include <QTimer>
29 
30 #include <kdebug.h>
31 #include <kicon.h>
32 #include <kplugininfo.h>
33 #include <kservicetypetrader.h>
34 #include <kstandarddirs.h>
35 
36 #include <plasma/package.h>
37 #include <plasma/querymatch.h>
38 
39 #include "private/abstractrunner_p.h"
40 #include "runnercontext.h"
41 #include "scripting/runnerscript.h"
42 
43 namespace Plasma
44 {
45 
46 K_GLOBAL_STATIC(QMutex, s_bigLock)
47 
48 AbstractRunner::AbstractRunner(QObject *parent, const QString &path)
49  : QObject(parent),
50  d(new AbstractRunnerPrivate(this))
51 {
52  d->init(path);
53 }
54 
55 AbstractRunner::AbstractRunner(const KService::Ptr service, QObject *parent)
56  : QObject(parent),
57  d(new AbstractRunnerPrivate(this))
58 {
59  d->init(service);
60 }
61 
62 AbstractRunner::AbstractRunner(QObject *parent, const QVariantList &args)
63  : QObject(parent),
64  d(new AbstractRunnerPrivate(this))
65 {
66  if (args.count() > 0) {
67  KService::Ptr service = KService::serviceByStorageId(args[0].toString());
68  if (service) {
69  d->init(service);
70  }
71  }
72 }
73 
74 AbstractRunner::~AbstractRunner()
75 {
76  delete d;
77 }
78 
79 KConfigGroup AbstractRunner::config() const
80 {
81  QString group = id();
82  if (group.isEmpty()) {
83  group = "UnnamedRunner";
84  }
85 
86  KConfigGroup runners(KGlobal::config(), "Runners");
87  return KConfigGroup(&runners, group);
88 }
89 
90 void AbstractRunner::reloadConfiguration()
91 {
92  if (d->script) {
93  emit d->script->reloadConfiguration();
94  }
95 }
96 
97 void AbstractRunner::addSyntax(const RunnerSyntax &syntax)
98 {
99  d->syntaxes.append(syntax);
100 }
101 
102 void AbstractRunner::setDefaultSyntax(const RunnerSyntax &syntax)
103 {
104  d->syntaxes.append(syntax);
105  d->defaultSyntax = &(d->syntaxes.last());
106 }
107 
108 void AbstractRunner::setSyntaxes(const QList<RunnerSyntax> &syntaxes)
109 {
110  d->syntaxes = syntaxes;
111 }
112 
113 QList<RunnerSyntax> AbstractRunner::syntaxes() const
114 {
115  return d->syntaxes;
116 }
117 
118 RunnerSyntax *AbstractRunner::defaultSyntax() const
119 {
120  return d->defaultSyntax;
121 }
122 
123 void AbstractRunner::performMatch(Plasma::RunnerContext &localContext)
124 {
125  static const int reasonableRunTime = 1500;
126  static const int fastEnoughTime = 250;
127 
128  if (d->suspendMatching) {
129  return;
130  }
131 
132  QTime time;
133  time.restart();
134 
135  //The local copy is already obtained in the job
136  match(localContext);
137 
138  // automatically rate limit runners that become slooow
139  const int runtime = time.elapsed();
140  bool slowed = speed() == SlowSpeed;
141 
142  if (!slowed && runtime > reasonableRunTime) {
143  // we punish runners that return too slowly, even if they don't bring
144  // back matches
145  kDebug() << id() << "runner is too slow, putting it on the back burner.";
146  d->fastRuns = 0;
147  setSpeed(SlowSpeed);
148  }
149 
150  if (slowed && runtime < fastEnoughTime && localContext.query().size() > 2) {
151  ++d->fastRuns;
152 
153  if (d->fastRuns > 2) {
154  // we reward slowed runners who bring back matches fast enough
155  // 3 times in a row
156  kDebug() << id() << "runner is faster than we thought, kicking it up a notch";
157  setSpeed(NormalSpeed);
158  }
159  }
160 }
161 
162 QList<QAction*> AbstractRunner::actionsForMatch(const Plasma::QueryMatch &match)
163 {
164  Q_UNUSED(match)
165  QList<QAction*> ret;
166  if (d->script) {
167  emit d->script->actionsForMatch(match, &ret);
168  }
169  return ret;
170 }
171 
172 QAction* AbstractRunner::addAction(const QString &id, const QIcon &icon, const QString &text)
173 {
174  QAction *a = new QAction(icon, text, this);
175  d->actions.insert(id, a);
176  return a;
177 }
178 
179 void AbstractRunner::addAction(const QString &id, QAction *action)
180 {
181  d->actions.insert(id, action);
182 }
183 
184 void AbstractRunner::removeAction(const QString &id)
185 {
186  QAction *a = d->actions.take(id);
187  delete a;
188 }
189 
190 QAction* AbstractRunner::action(const QString &id) const
191 {
192  return d->actions.value(id);
193 }
194 
195 QHash<QString, QAction*> AbstractRunner::actions() const
196 {
197  return d->actions;
198 }
199 
200 void AbstractRunner::clearActions()
201 {
202  qDeleteAll(d->actions);
203  d->actions.clear();
204 }
205 
206 QMimeData * AbstractRunner::mimeDataForMatch(const QueryMatch *match)
207 {
208  Q_UNUSED(match)
209  return 0;
210 }
211 
212 bool AbstractRunner::hasRunOptions()
213 {
214  return d->hasRunOptions;
215 }
216 
217 void AbstractRunner::setHasRunOptions(bool hasRunOptions)
218 {
219  d->hasRunOptions = hasRunOptions;
220 }
221 
222 void AbstractRunner::createRunOptions(QWidget *parent)
223 {
224  if (d->script) {
225  emit d->script->createRunOptions(parent);
226  }
227 }
228 
229 AbstractRunner::Speed AbstractRunner::speed() const
230 {
231  // the only time the read lock will fail is if we were slow are going to speed up
232  // or if we were fast and are going to slow down; so don't wait in this case, just
233  // say we're slow. we either will be soon or were just a moment ago and it doesn't
234  // hurt to do one more run the slow way
235  if (!d->speedLock.tryLockForRead()) {
236  return SlowSpeed;
237  }
238  Speed s = d->speed;
239  d->speedLock.unlock();
240  return s;
241 }
242 
243 void AbstractRunner::setSpeed(Speed speed)
244 {
245  d->speedLock.lockForWrite();
246  d->speed = speed;
247  d->speedLock.unlock();
248 }
249 
250 AbstractRunner::Priority AbstractRunner::priority() const
251 {
252  return d->priority;
253 }
254 
255 void AbstractRunner::setPriority(Priority priority)
256 {
257  d->priority = priority;
258 }
259 
260 RunnerContext::Types AbstractRunner::ignoredTypes() const
261 {
262  return d->blackListed;
263 }
264 
265 void AbstractRunner::setIgnoredTypes(RunnerContext::Types types)
266 {
267  d->blackListed = types;
268 }
269 
270 KService::List AbstractRunner::serviceQuery(const QString &serviceType, const QString &constraint) const
271 {
272  return KServiceTypeTrader::self()->query(serviceType, constraint);
273 }
274 
275 QMutex* AbstractRunner::bigLock()
276 {
277  return s_bigLock;
278 }
279 
280 void AbstractRunner::run(const Plasma::RunnerContext &search, const Plasma::QueryMatch &action)
281 {
282  if (d->script) {
283  return d->script->run(search, action);
284  }
285 }
286 
287 void AbstractRunner::match(Plasma::RunnerContext &search)
288 {
289  if (d->script) {
290  return d->script->match(search);
291  }
292 }
293 
294 QString AbstractRunner::name() const
295 {
296  if (d->runnerDescription.isValid()) {
297  return d->runnerDescription.name();
298  }
299 
300  if (d->package) {
301  return d->package->metadata().name();
302  }
303 
304  return objectName();
305 }
306 
307 QIcon AbstractRunner::icon() const
308 {
309  if (d->runnerDescription.isValid()) {
310  return KIcon(d->runnerDescription.icon());
311  }
312 
313  if (d->package) {
314  return KIcon(d->package->metadata().icon());
315  }
316 
317  return QIcon();
318 }
319 
320 QString AbstractRunner::id() const
321 {
322  if (d->runnerDescription.isValid()) {
323  return d->runnerDescription.pluginName();
324  }
325 
326  if (d->package) {
327  return d->package->metadata().pluginName();
328  }
329 
330  return objectName();
331 }
332 
333 QString AbstractRunner::description() const
334 {
335  if (d->runnerDescription.isValid()) {
336  return d->runnerDescription.property("Comment").toString();
337  }
338 
339  if (d->package) {
340  return d->package->metadata().description();
341  }
342 
343  return objectName();
344 }
345 
346 const Package* AbstractRunner::package() const
347 {
348  return d->package;
349 }
350 
351 
352 void AbstractRunner::init()
353 {
354  if (d->script) {
355  d->setupScriptSupport();
356  d->script->init();
357  }
358 
359  reloadConfiguration();
360 }
361 
362 DataEngine *AbstractRunner::dataEngine(const QString &name) const
363 {
364  return d->dataEngine(name);
365 }
366 
367 bool AbstractRunner::isMatchingSuspended() const
368 {
369  return d->suspendMatching;
370 }
371 
372 void AbstractRunner::suspendMatching(bool suspend)
373 {
374  if (d->suspendMatching == suspend) {
375  return;
376  }
377 
378  d->suspendMatching = suspend;
379  emit matchingSuspended(suspend);
380 }
381 
382 AbstractRunnerPrivate::AbstractRunnerPrivate(AbstractRunner *r)
383  : priority(AbstractRunner::NormalPriority),
384  speed(AbstractRunner::NormalSpeed),
385  blackListed(0),
386  script(0),
387  runner(r),
388  fastRuns(0),
389  package(0),
390  defaultSyntax(0),
391  hasRunOptions(false),
392  suspendMatching(false)
393 {
394 }
395 
396 AbstractRunnerPrivate::~AbstractRunnerPrivate()
397 {
398  delete script;
399  script = 0;
400  delete package;
401  package = 0;
402 }
403 
404 void AbstractRunnerPrivate::init(const KService::Ptr service)
405 {
406  runnerDescription = KPluginInfo(service);
407  if (runnerDescription.isValid()) {
408  const QString api = runnerDescription.property("X-Plasma-API").toString();
409  if (!api.isEmpty()) {
410  const QString path = KStandardDirs::locate("data", "plasma/runners/" + runnerDescription.pluginName() + '/');
411  prepScripting(path, api);
412  if (!script) {
413  kDebug() << "Could not create a(n)" << api << "ScriptEngine for the" << runnerDescription.name() << "Runner.";
414  }
415  }
416  }
417 }
418 
419 void AbstractRunnerPrivate::init(const QString &path)
420 {
421  prepScripting(path);
422 }
423 
424 void AbstractRunnerPrivate::prepScripting(const QString &path, QString api)
425 {
426  if (script) {
427  return;
428  }
429 
430  delete package;
431 
432  PackageStructure::Ptr structure = Plasma::packageStructure(api, Plasma::RunnerComponent);
433  structure->setPath(path);
434  package = new Package(path, structure);
435 
436  if (!package->isValid()) {
437  kDebug() << "Invalid Runner package at" << path;
438  delete package;
439  package = 0;
440  return;
441  }
442 
443  if (api.isEmpty()) {
444  api = package->metadata().implementationApi();
445  }
446 
447  script = Plasma::loadScriptEngine(api, runner);
448  if (!script) {
449  delete package;
450  package = 0;
451  }
452 }
453 
454 // put all setup routines for script here. at this point we can assume that
455 // package exists and that we have a script engine
456 void AbstractRunnerPrivate::setupScriptSupport()
457 {
458  if (!package) {
459  return;
460  }
461 
462  kDebug() << "setting up script support, package is in" << package->path()
463  << "which is a" << package->structure()->type() << "package"
464  << ", main script is" << package->filePath("mainscript");
465 
466  QString translationsPath = package->filePath("translations");
467  if (!translationsPath.isEmpty()) {
468  //FIXME: we should _probably_ use a KComponentData to segregate the applets
469  // from each other; but I want to get the basics working first :)
470  KGlobal::dirs()->addResourceDir("locale", translationsPath);
471  KGlobal::locale()->insertCatalog(package->metadata().pluginName());
472  }
473 }
474 
475 } // Plasma namespace
476 
477 #include "abstractrunner.moc"
Plasma::AbstractRunner::suspendMatching
void suspendMatching(bool suspend)
Sets whether or not the runner is available for match requests.
Definition: abstractrunner.cpp:372
Plasma::AbstractRunner::addSyntax
void addSyntax(const RunnerSyntax &syntax)
Adds a registered syntax that this runner understands.
Definition: abstractrunner.cpp:97
Plasma::AbstractRunner::addAction
QAction * addAction(const QString &id, const QIcon &icon, const QString &text)
Creates and then adds an action to the action registry.
Definition: abstractrunner.cpp:172
Plasma::AbstractRunner::init
void init()
Reimplement this slot to run any initialization routines on first load.
Definition: abstractrunner.cpp:352
abstractrunner.h
Plasma::AbstractRunner::Speed
Speed
Specifies a nominal speed for the runner.
Definition: abstractrunner.h:73
Plasma::AbstractRunner::actions
QHash< QString, QAction * > actions() const
Returns all registered actions.
Definition: abstractrunner.cpp:195
QWidget
Plasma::AbstractRunner
An abstract base class for Plasma Runner plugins.
Definition: abstractrunner.h:63
Plasma::AbstractRunner::action
QAction * action(const QString &id) const
Returns the action associated with the id.
Definition: abstractrunner.cpp:190
Plasma::AbstractRunner::mimeDataForMatch
QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match)
Reimplement this slot if you want your runner to support serialization and drag and drop...
Definition: abstractrunner.cpp:206
QObject
Plasma::AbstractRunner::removeAction
void removeAction(const QString &id)
Removes the action from the action registry.
Definition: abstractrunner.cpp:184
Plasma::AbstractRunner::matchingSuspended
bool matchingSuspended
Definition: abstractrunner.h:66
Plasma::loadScriptEngine
AppletScript * loadScriptEngine(const QString &language, Applet *applet)
Loads an Applet script engine for the given language.
Definition: scriptengine.cpp:206
Plasma::AbstractRunner::run
virtual void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
Called whenever an exact or possible match associated with this runner is triggered.
Definition: abstractrunner.cpp:280
Plasma::AbstractRunner::bigLock
static QMutex * bigLock()
Access to a shared lock that all runners (and code that manages/interacts with them) can share to pro...
Definition: abstractrunner.cpp:275
Plasma::AbstractRunner::description
QString description() const
Plasma::AbstractRunner::actionsForMatch
virtual QList< QAction * > actionsForMatch(const Plasma::QueryMatch &match)
A given match can have more than action that can be performed on it.
Definition: abstractrunner.cpp:162
Plasma::AbstractRunner::id
QString id() const
Plasma::RunnerSyntax
Definition: runnersyntax.h:40
Plasma::AbstractRunner::setSpeed
void setSpeed(Speed newSpeed)
Sets the nominal speed of the runner.
Definition: abstractrunner.cpp:243
Plasma::AbstractRunner::reloadConfiguration
virtual void reloadConfiguration()
Signal runner to reload its configuration.
Definition: abstractrunner.cpp:90
Plasma::AbstractRunner::AbstractRunner
AbstractRunner(QObject *parent=0, const QString &path=QString())
Definition: abstractrunner.cpp:48
Plasma::AbstractRunner::serviceQuery
KService::List serviceQuery(const QString &serviceType, const QString &constraint=QString()) const
Definition: abstractrunner.cpp:270
Plasma::AbstractRunner::setDefaultSyntax
void setDefaultSyntax(const RunnerSyntax &syntax)
Set syntax as the default syntax for the runner; the default syntax will be substituted to the empty ...
Definition: abstractrunner.cpp:102
Plasma::PackageStructure::Ptr
KSharedPtr< PackageStructure > Ptr
Definition: packagestructure.h:77
Plasma::DataEngine
Data provider for plasmoids (Plasma plugins)
Definition: dataengine.h:58
Plasma::AbstractRunner::Priority
Priority
Specifies a priority for the runner.
Definition: abstractrunner.h:79
Plasma::AbstractRunner::isMatchingSuspended
bool isMatchingSuspended() const
Definition: abstractrunner.cpp:367
Plasma::Package
object representing an installed Plasmagik package
Definition: package.h:42
Plasma::AbstractRunner::setIgnoredTypes
void setIgnoredTypes(RunnerContext::Types types)
Sets the types this runner will ignore.
Definition: abstractrunner.cpp:265
Plasma::AbstractRunner::config
KConfigGroup config() const
Provides access to the runner's configuration object.
Definition: abstractrunner.cpp:79
Plasma::RunnerContext
The RunnerContext class provides information related to a search, including the search term...
Definition: runnercontext.h:46
Plasma::toString
static QScriptValue toString(QScriptContext *ctx, QScriptEngine *eng)
Definition: easingcurve.cpp:57
Plasma::AbstractRunner::speed
Speed speed() const
The nominal speed of the runner.
Definition: abstractrunner.cpp:229
Plasma::AbstractRunner::SlowSpeed
Definition: abstractrunner.h:74
Plasma::AbstractRunner::syntaxes
QList< RunnerSyntax > syntaxes() const
Definition: abstractrunner.cpp:113
Plasma::RunnerComponent
Plasma::AbstractRunner based plugsin.
Definition: plasma.h:228
Plasma::AbstractRunner::hasRunOptions
bool hasRunOptions()
If the runner has options that the user can interact with to modify what happens when run or one of t...
Definition: abstractrunner.cpp:212
Plasma::AbstractRunner::dataEngine
Q_INVOKABLE DataEngine * dataEngine(const QString &name) const
Loads the given DataEngine.
Definition: abstractrunner.cpp:362
Plasma::AbstractRunner::priority
Priority priority() const
The priority of the runner.
Definition: abstractrunner.cpp:250
Plasma::QueryMatch
A match returned by an AbstractRunner in response to a given RunnerContext.
Definition: querymatch.h:47
package.h
Plasma::AbstractRunner::defaultSyntax
RunnerSyntax * defaultSyntax() const
Definition: abstractrunner.cpp:118
Plasma::AbstractRunner::NormalSpeed
Definition: abstractrunner.h:75
runnerscript.h
Plasma::AbstractRunner::~AbstractRunner
virtual ~AbstractRunner()
Definition: abstractrunner.cpp:74
Plasma::AbstractRunner::clearActions
void clearActions()
Clears the action registry.
Definition: abstractrunner.cpp:200
Plasma::AbstractRunner::ignoredTypes
RunnerContext::Types ignoredTypes() const
Returns the OR'ed value of all the Information types (as defined in RunnerContext::Type) this runner ...
Definition: abstractrunner.cpp:260
Plasma::AbstractRunner::setPriority
void setPriority(Priority newPriority)
Sets the priority of the runner.
Definition: abstractrunner.cpp:255
runnercontext.h
querymatch.h
Plasma::AbstractRunner::setHasRunOptions
void setHasRunOptions(bool hasRunOptions)
Sets whether or not the runner has options for matches.
Definition: abstractrunner.cpp:217
Plasma::RunnerContext::query
QString query() const
Definition: runnercontext.cpp:344
Plasma::AbstractRunner::createRunOptions
virtual void createRunOptions(QWidget *widget)
If hasRunOptions() returns true, this method may be called to get a widget displaying the options the...
Definition: abstractrunner.cpp:222
Plasma::AbstractRunner::performMatch
void performMatch(Plasma::RunnerContext &context)
Triggers a call to match.
Definition: abstractrunner.cpp:123
Plasma::AbstractRunner::setSyntaxes
void setSyntaxes(const QList< RunnerSyntax > &syns)
Sets the list of syntaxes; passing in an empty list effectively clears the syntaxes.
Definition: abstractrunner.cpp:108
Plasma::packageStructure
PackageStructure::Ptr packageStructure(const QString &language, ComponentType type)
Loads an appropriate PackageStructure for the given language and type.
Definition: scriptengine.cpp:274
Plasma::AbstractRunner::package
const Package * package() const
Accessor for the associated Package object if any.
Definition: abstractrunner.cpp:346
Plasma::AbstractRunner::icon
QIcon icon() const
Plasma::AbstractRunner::match
virtual void match(Plasma::RunnerContext &context)
This is the main query method.
Definition: abstractrunner.cpp:287
Plasma::AbstractRunner::name
QString name() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:32 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal