Plasma
abstractrunner.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "abstractrunner.h"
00021
00022 #include <QAction>
00023 #include <QHash>
00024 #include <QMutex>
00025 #include <QMutexLocker>
00026 #include <QTimer>
00027
00028 #include <kdebug.h>
00029 #include <kicon.h>
00030 #include <kplugininfo.h>
00031 #include <kservicetypetrader.h>
00032 #include <kstandarddirs.h>
00033
00034 #include <plasma/querymatch.h>
00035 #include <plasma/package.h>
00036
00037 #include "scripting/runnerscript.h"
00038
00039 #include "runnercontext.h"
00040
00041 namespace Plasma
00042 {
00043
00044 class AbstractRunnerPrivate
00045 {
00046 public:
00047 AbstractRunnerPrivate(AbstractRunner *r, KService::Ptr service)
00048 : priority(AbstractRunner::NormalPriority),
00049 speed(AbstractRunner::NormalSpeed),
00050 blackListed(0),
00051 script(0),
00052 runnerDescription(service),
00053 runner(r),
00054 fastRuns(0),
00055 package(0),
00056 hasRunOptions(false)
00057 {
00058 if (runnerDescription.isValid()) {
00059 const QString api = runnerDescription.property("X-Plasma-API").toString();
00060 if (!api.isEmpty()) {
00061 const QString path = KStandardDirs::locate("data",
00062 "plasma/runners/" + runnerDescription.pluginName() + '/');
00063 PackageStructure::Ptr structure =
00064 Plasma::packageStructure(api, Plasma::RunnerComponent);
00065 structure->setPath(path);
00066 package = new Package(path, structure);
00067
00068 script = Plasma::loadScriptEngine(api, runner);
00069 if (!script) {
00070 kDebug() << "Could not create a(n)" << api << "ScriptEngine for the"
00071 << runnerDescription.name() << "Runner.";
00072 delete package;
00073 package = 0;
00074 }
00075 }
00076 }
00077 }
00078
00079 ~AbstractRunnerPrivate()
00080 {
00081 delete script;
00082 script = 0;
00083 delete package;
00084 package = 0;
00085 }
00086
00087 AbstractRunner::Priority priority;
00088 AbstractRunner::Speed speed;
00089 RunnerContext::Types blackListed;
00090 RunnerScript *script;
00091 KPluginInfo runnerDescription;
00092 AbstractRunner *runner;
00093 QTime runtime;
00094 int fastRuns;
00095 Package *package;
00096 QHash<QString, QAction*> actions;
00097 QList<RunnerSyntax> syntaxes;
00098 bool hasRunOptions;
00099 };
00100
00101 K_GLOBAL_STATIC(QMutex, s_bigLock)
00102
00103 AbstractRunner::AbstractRunner(QObject *parent, const QString &serviceId)
00104 : QObject(parent),
00105 d(new AbstractRunnerPrivate(this, KService::serviceByStorageId(serviceId)))
00106 {
00107 }
00108
00109 AbstractRunner::AbstractRunner(QObject *parent, const QVariantList &args)
00110 : QObject(parent),
00111 d(new AbstractRunnerPrivate(this, KService::serviceByStorageId(args.count() > 0 ? args[0].toString() : QString())))
00112 {
00113 }
00114
00115 AbstractRunner::~AbstractRunner()
00116 {
00117 delete d;
00118 }
00119
00120 KConfigGroup AbstractRunner::config() const
00121 {
00122 QString group = objectName();
00123 if (group.isEmpty()) {
00124 group = "UnnamedRunner";
00125 }
00126
00127 KConfigGroup runners(KGlobal::config(), "Runners");
00128 return KConfigGroup(&runners, group);
00129 }
00130
00131 void AbstractRunner::reloadConfiguration()
00132 {
00133 }
00134
00135 void AbstractRunner::addSyntax(const RunnerSyntax &syntax)
00136 {
00137 d->syntaxes.append(syntax);
00138 }
00139
00140 void AbstractRunner::setSyntaxes(const QList<RunnerSyntax> &syntaxes)
00141 {
00142 d->syntaxes = syntaxes;
00143 }
00144
00145 QList<RunnerSyntax> AbstractRunner::syntaxes() const
00146 {
00147 return d->syntaxes;
00148 }
00149
00150 void AbstractRunner::performMatch(Plasma::RunnerContext &localContext)
00151 {
00152 static const int reasonableRunTime = 1500;
00153 static const int fastEnoughTime = 250;
00154
00155 d->runtime.restart();
00156
00157
00158 match(localContext);
00159
00160
00161 const int runtime = d->runtime.elapsed();
00162 bool slowed = speed() == SlowSpeed;
00163
00164 if (!slowed && runtime > reasonableRunTime) {
00165
00166
00167 kDebug() << id() << "runner is too slow, putting it on the back burner.";
00168 d->fastRuns = 0;
00169 setSpeed(SlowSpeed);
00170 }
00171
00172 if (slowed && runtime < fastEnoughTime && localContext.query().size() > 2) {
00173 ++d->fastRuns;
00174
00175 if (d->fastRuns > 2) {
00176
00177
00178 kDebug() << id() << "runner is faster than we thought, kicking it up a notch";
00179 setSpeed(NormalSpeed);
00180 }
00181 }
00182 }
00183
00184 QList<QAction*> AbstractRunner::actionsForMatch(const Plasma::QueryMatch &match)
00185 {
00186 Q_UNUSED(match)
00187 QList<QAction*> ret;
00188 return ret;
00189 }
00190
00191 QAction* AbstractRunner::addAction(const QString &id, const QIcon &icon, const QString &text)
00192 {
00193 QAction *a = new QAction(icon, text, this);
00194 d->actions.insert(id, a);
00195 return a;
00196 }
00197
00198 void AbstractRunner::addAction(const QString &id, QAction *action)
00199 {
00200 d->actions.insert(id, action);
00201 }
00202
00203 void AbstractRunner::removeAction(const QString &id)
00204 {
00205 QAction *a = d->actions.take(id);
00206 delete a;
00207 }
00208
00209 QAction* AbstractRunner::action(const QString &id) const
00210 {
00211 return d->actions.value(id);
00212 }
00213
00214 QHash<QString, QAction*> AbstractRunner::actions() const
00215 {
00216 return d->actions;
00217 }
00218
00219 void AbstractRunner::clearActions()
00220 {
00221 qDeleteAll(d->actions);
00222 d->actions.clear();
00223 }
00224
00225 bool AbstractRunner::hasRunOptions()
00226 {
00227 return d->hasRunOptions;
00228 }
00229
00230 void AbstractRunner::setHasRunOptions(bool hasRunOptions)
00231 {
00232 d->hasRunOptions = hasRunOptions;
00233 }
00234
00235 void AbstractRunner::createRunOptions(QWidget *parent)
00236 {
00237 Q_UNUSED(parent)
00238 }
00239
00240 AbstractRunner::Speed AbstractRunner::speed() const
00241 {
00242 return d->speed;
00243 }
00244
00245 void AbstractRunner::setSpeed(Speed speed)
00246 {
00247 d->speed = speed;
00248 }
00249
00250 AbstractRunner::Priority AbstractRunner::priority() const
00251 {
00252 return d->priority;
00253 }
00254
00255 void AbstractRunner::setPriority(Priority priority)
00256 {
00257 d->priority = priority;
00258 }
00259
00260 RunnerContext::Types AbstractRunner::ignoredTypes() const
00261 {
00262 return d->blackListed;
00263 }
00264
00265 void AbstractRunner::setIgnoredTypes(RunnerContext::Types types)
00266 {
00267 d->blackListed = types;
00268 }
00269
00270 KService::List AbstractRunner::serviceQuery(const QString &serviceType, const QString &constraint) const
00271 {
00272 return KServiceTypeTrader::self()->query(serviceType, constraint);
00273 }
00274
00275 QMutex* AbstractRunner::bigLock()
00276 {
00277 return s_bigLock;
00278 }
00279
00280 void AbstractRunner::run(const Plasma::RunnerContext &search, const Plasma::QueryMatch &action)
00281 {
00282 if (d->script) {
00283 return d->script->run(search, action);
00284 }
00285 }
00286
00287 void AbstractRunner::match(Plasma::RunnerContext &search)
00288 {
00289 if (d->script) {
00290 return d->script->match(search);
00291 }
00292 }
00293
00294 QString AbstractRunner::name() const
00295 {
00296 if (!d->runnerDescription.isValid()) {
00297 return objectName();
00298 }
00299
00300 return d->runnerDescription.name();
00301 }
00302
00303 QIcon AbstractRunner::icon() const
00304 {
00305 if (!d->runnerDescription.isValid()) {
00306 return QIcon();
00307 }
00308
00309 return KIcon(d->runnerDescription.icon());
00310 }
00311
00312 QString AbstractRunner::id() const
00313 {
00314 if (!d->runnerDescription.isValid()) {
00315 return objectName();
00316 }
00317 return d->runnerDescription.pluginName();
00318 }
00319
00320 QString AbstractRunner::description() const
00321 {
00322 if (!d->runnerDescription.isValid()) {
00323 return objectName();
00324 }
00325
00326 return d->runnerDescription.property("Comment").toString();
00327 }
00328
00329 const Package* AbstractRunner::package() const
00330 {
00331 return d->package;
00332 }
00333
00334 void AbstractRunner::init()
00335 {
00336 if (d->script) {
00337 d->script->init();
00338 }
00339 }
00340
00341 }
00342
00343 #include "abstractrunner.moc"