libplasma
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 <QMutex>
00023 #include <QMutexLocker>
00024
00025 #include <KDebug>
00026 #include <KPluginInfo>
00027 #include <KServiceTypeTrader>
00028 #include <KStandardDirs>
00029 #include <QTimer>
00030
00031 #include <plasma/querymatch.h>
00032 #include <plasma/package.h>
00033
00034 #include "scripting/runnerscript.h"
00035
00036 #include "runnercontext.h"
00037
00038 namespace Plasma
00039 {
00040
00041 class AbstractRunnerPrivate
00042 {
00043 public:
00044 AbstractRunnerPrivate(AbstractRunner* r, KService::Ptr service)
00045 : priority(AbstractRunner::NormalPriority),
00046 speed(AbstractRunner::NormalSpeed),
00047 blackListed(0),
00048 script(0),
00049 runnerDescription(service),
00050 runner(r),
00051 fastRuns(0),
00052 package(0)
00053 {
00054 if (runnerDescription.isValid()) {
00055 const QString api = runnerDescription.property("X-Plasma-API").toString();
00056 if (!api.isEmpty()) {
00057 const QString path = KStandardDirs::locate("data",
00058 "plasma/runners/" + runnerDescription.pluginName() + '/');
00059 PackageStructure::Ptr structure = Plasma::packageStructure(api, Plasma::RunnerComponent);
00060 structure->setPath(path);
00061 package = new Package(path, structure);
00062
00063 script = Plasma::loadScriptEngine(api, runner);
00064 if (!script) {
00065 kDebug() << "Could not create a(n)" << api << "ScriptEngine for the"
00066 << runnerDescription.name() << "Runner.";
00067 delete package;
00068 package = 0;
00069 } else {
00070 QTimer::singleShot(0, runner, SLOT(init()));
00071 }
00072 }
00073 }
00074 }
00075
00076 bool hasRunOptions;
00077 bool hasConfig;
00078 AbstractRunner::Priority priority;
00079 AbstractRunner::Speed speed;
00080 RunnerContext::Types blackListed;
00081 RunnerScript* script;
00082 KPluginInfo runnerDescription;
00083 AbstractRunner* runner;
00084 QTime runtime;
00085 int fastRuns;
00086 Package *package;
00087 };
00088
00089 K_GLOBAL_STATIC(QMutex, s_bigLock)
00090
00091 AbstractRunner::AbstractRunner(QObject* parent, const QString& serviceId)
00092 : QObject(parent),
00093 d(new AbstractRunnerPrivate(this, KService::serviceByStorageId(serviceId)))
00094 {
00095 }
00096
00097 AbstractRunner::AbstractRunner(QObject* parent, const QVariantList& args)
00098 : QObject(parent),
00099 d(new AbstractRunnerPrivate(this, KService::serviceByStorageId(args.count() > 0 ? args[0].toString() : QString())))
00100 {
00101 }
00102
00103 AbstractRunner::~AbstractRunner()
00104 {
00105 delete d;
00106 }
00107
00108 KConfigGroup AbstractRunner::config() const
00109 {
00110 QString group = objectName();
00111 if (group.isEmpty()) {
00112 group = "UnnamedRunner";
00113 }
00114
00115 KConfigGroup runners(KGlobal::config(), "Runners");
00116 return KConfigGroup(&runners, group);
00117 }
00118
00119 void AbstractRunner::reloadConfiguration()
00120 {
00121 }
00122
00123 void AbstractRunner::performMatch(Plasma::RunnerContext &globalContext)
00124 {
00125 static const int reasonableRunTime = 1500;
00126 static const int fastEnoughTime = 250;
00127
00128 d->runtime.restart();
00129
00130 RunnerContext localContext(globalContext, 0);
00131 match(localContext);
00132
00133 const int runtime = d->runtime.elapsed();
00134 bool slowed = speed() == SlowSpeed;
00135
00136 if (!slowed && runtime > reasonableRunTime) {
00137
00138
00139 kDebug() << id() << "runner is too slow, putting it on the back burner.";
00140 d->fastRuns = 0;
00141 setSpeed(SlowSpeed);
00142 }
00143
00144
00145 if (slowed && runtime < fastEnoughTime) {
00146 ++d->fastRuns;
00147
00148 if (d->fastRuns > 2) {
00149
00150
00151 kDebug() << id() << "runner is faster than we thought, kicking it up a notch";
00152 setSpeed(NormalSpeed);
00153 }
00154 }
00155 }
00156
00157 bool AbstractRunner::hasRunOptions()
00158 {
00159 return d->hasRunOptions;
00160 }
00161
00162 void AbstractRunner::setHasRunOptions(bool hasRunOptions)
00163 {
00164 d->hasRunOptions = hasRunOptions;
00165 }
00166
00167 void AbstractRunner::createRunOptions(QWidget *parent)
00168 {
00169 Q_UNUSED(parent)
00170 }
00171
00172 AbstractRunner::Speed AbstractRunner::speed() const
00173 {
00174 return d->speed;
00175 }
00176
00177 void AbstractRunner::setSpeed(Speed speed)
00178 {
00179 d->speed = speed;
00180 }
00181
00182 AbstractRunner::Priority AbstractRunner::priority() const
00183 {
00184 return d->priority;
00185 }
00186
00187 void AbstractRunner::setPriority(Priority priority)
00188 {
00189 d->priority = priority;
00190 }
00191
00192 RunnerContext::Types AbstractRunner::ignoredTypes() const
00193 {
00194 return d->blackListed;
00195 }
00196
00197 void AbstractRunner::setIgnoredTypes(RunnerContext::Types types)
00198 {
00199 d->blackListed = types;
00200 }
00201
00202 KService::List AbstractRunner::serviceQuery(const QString &serviceType, const QString &constraint) const
00203 {
00204 QMutexLocker lock(s_bigLock);
00205 return KServiceTypeTrader::self()->query(serviceType, constraint);
00206 }
00207
00208 QMutex* AbstractRunner::bigLock() const
00209 {
00210 return s_bigLock;
00211 }
00212
00213 void AbstractRunner::run(const Plasma::RunnerContext &search, const Plasma::QueryMatch &action)
00214 {
00215 if (d->script) {
00216 return d->script->run(search, action);
00217 }
00218 }
00219
00220 void AbstractRunner::match(Plasma::RunnerContext &search)
00221 {
00222 if (d->script) {
00223 return d->script->match(search);
00224 }
00225 }
00226
00227 QString AbstractRunner::name() const
00228 {
00229 if (!d->runnerDescription.isValid()) {
00230 return objectName();
00231 }
00232 return d->runnerDescription.name();
00233 }
00234
00235 QString AbstractRunner::id() const
00236 {
00237 if (!d->runnerDescription.isValid()) {
00238 return objectName();
00239 }
00240 return d->runnerDescription.pluginName();
00241 }
00242
00243 QString AbstractRunner::description() const
00244 {
00245 if (!d->runnerDescription.isValid()) {
00246 return objectName();
00247 }
00248 return d->runnerDescription.property("Comment").toString();
00249 }
00250
00251 const Package* AbstractRunner::package() const
00252 {
00253 return d->package;
00254 }
00255
00256 void AbstractRunner::init()
00257 {
00258 if (d->script) {
00259 d->script->init();
00260 }
00261 }
00262
00263 }
00264
00265 #include "abstractrunner.moc"