libplasma
scriptengine.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 "scripting/scriptengine.h"
00021
00022 #include <KDebug>
00023 #include <KService>
00024 #include <KServiceTypeTrader>
00025
00026 #include "abstractrunner.h"
00027 #include "applet.h"
00028 #include "dataengine.h"
00029 #include "package.h"
00030 #include "packages_p.h"
00031 #include "scripting/appletscript.h"
00032 #include "scripting/dataenginescript.h"
00033 #include "scripting/runnerscript.h"
00034
00035 namespace Plasma
00036 {
00037
00038 ScriptEngine::ScriptEngine(QObject *parent)
00039 : QObject(parent),
00040 d(0)
00041 {
00042 }
00043
00044 ScriptEngine::~ScriptEngine()
00045 {
00046
00047 }
00048
00049 bool ScriptEngine::init()
00050 {
00051 return true;
00052 }
00053
00054 const Package* ScriptEngine::package() const
00055 {
00056 return 0;
00057 }
00058
00059 QString ScriptEngine::mainScript() const
00060 {
00061 return QString();
00062 }
00063
00064 QStringList knownLanguages(ComponentTypes types)
00065 {
00066 QString constraintTemplate = "'%1' in [X-Plasma-ComponentTypes]";
00067 QString constraint;
00068
00069 if (types & AppletComponent) {
00070
00071
00072
00073 if (!constraint.isEmpty()) {
00074 constraint.append(" or ");
00075 }
00076
00077 constraint.append(constraintTemplate.arg("Applet"));
00078 }
00079
00080 if (types & DataEngineComponent) {
00081 if (!constraint.isEmpty()) {
00082 constraint.append(" or ");
00083 }
00084
00085 constraint.append(constraintTemplate.arg("DataEngine"));
00086 }
00087
00088 if (types & RunnerComponent) {
00089 if (!constraint.isEmpty()) {
00090 constraint.append(" or ");
00091 }
00092
00093 constraint.append(constraintTemplate.arg("Runner"));
00094 }
00095
00096 KService::List offers = KServiceTypeTrader::self()->query("Plasma/ScriptEngine", constraint);
00097
00098
00099 QStringList languages;
00100 foreach (const KService::Ptr &service, offers) {
00101 QString language = service->property("X-Plasma-API").toString();
00102 if (!languages.contains(language)) {
00103 languages.append(language);
00104 }
00105 }
00106
00107 return languages;
00108 }
00109
00110 KService::List engineOffers(const QString &language, ComponentType type)
00111 {
00112 if (language.isEmpty()) {
00113 return KService::List();
00114 }
00115
00116 QRegExp re("[^a-zA-Z0-9\\-_]");
00117 if (re.indexIn(language) != -1) {
00118 kDebug() << "invalid language attempted:" << language;
00119 return KService::List();
00120 }
00121
00122 QString component;
00123 switch (type) {
00124 case AppletComponent:
00125 component = "Applet";
00126 break;
00127 case DataEngineComponent:
00128 component = "DataEngine";
00129 break;
00130 case RunnerComponent:
00131 component = "Runner";
00132 break;
00133 default:
00134 return KService::List();
00135 break;
00136 }
00137
00138 QString constraint = QString("[X-Plasma-API] == '%1' and "
00139 "'%2' in [X-Plasma-ComponentTypes]").arg(language, component);
00140 KService::List offers = KServiceTypeTrader::self()->query("Plasma/ScriptEngine", constraint);
00141
00142
00143 if (offers.isEmpty()) {
00144 kDebug() << "ScriptEngine::load: no offers for \"" << language << "\"";
00145 }
00146
00147 return offers;
00148 }
00149
00150 ScriptEngine* loadEngine(const QString &language, ComponentType type, QObject *parent)
00151 {
00152 KService::List offers = engineOffers(language, type);
00153
00154 QVariantList args;
00155 QString error;
00156
00157 ScriptEngine *engine = 0;
00158 foreach (const KService::Ptr &service, offers) {
00159 switch (type) {
00160 case AppletComponent:
00161 engine = service->createInstance<Plasma::AppletScript>(parent, args, &error);
00162 break;
00163 case DataEngineComponent:
00164 engine = service->createInstance<Plasma::DataEngineScript>(parent, args, &error);
00165 break;
00166 case RunnerComponent:
00167 engine = service->createInstance<Plasma::RunnerScript>(parent, args, &error);
00168 break;
00169 default:
00170 return 0;
00171 break;
00172 }
00173
00174 if (engine) {
00175 return engine;
00176 }
00177
00178 kDebug() << "Couldn't load script engine for language " << language << "! error reported: " << error;
00179 }
00180
00181 return 0;
00182 }
00183
00184 AppletScript* loadScriptEngine(const QString &language, Applet *applet)
00185 {
00186 AppletScript *engine = static_cast<AppletScript*>(loadEngine(language, AppletComponent, applet));
00187
00188 if (engine) {
00189 engine->setApplet(applet);
00190 }
00191
00192 return engine;
00193 }
00194
00195 DataEngineScript* loadScriptEngine(const QString &language, DataEngine *dataEngine)
00196 {
00197 DataEngineScript *engine = static_cast<DataEngineScript*>(loadEngine(language, DataEngineComponent, dataEngine));
00198
00199 if (engine) {
00200 engine->setDataEngine(dataEngine);
00201 }
00202
00203 return engine;
00204 }
00205
00206 RunnerScript* loadScriptEngine(const QString &language, AbstractRunner *runner)
00207 {
00208 RunnerScript* engine = static_cast<RunnerScript*>(loadEngine(language, RunnerComponent, runner));
00209
00210 if (engine) {
00211 engine->setRunner(runner);
00212 }
00213
00214 return engine;
00215 }
00216
00217 PackageStructure::Ptr defaultPackageStructure(ComponentType type)
00218 {
00219 switch (type) {
00220 case AppletComponent:
00221 return PackageStructure::Ptr(new PlasmoidPackage());
00222 break;
00223 case RunnerComponent:
00224 case DataEngineComponent:
00225 {
00226 PackageStructure::Ptr structure(new PackageStructure());
00227 structure->addFileDefinition("mainscript", "code/main", i18n("Main Script File"));
00228 structure->setRequired("mainscript", true);
00229 return structure;
00230 break;
00231 }
00232 default:
00233
00234 break;
00235 }
00236
00237 return PackageStructure::Ptr(new PackageStructure());
00238 }
00239
00240 PackageStructure::Ptr packageStructure(const QString &language, ComponentType type)
00241 {
00242 KService::List offers = engineOffers(language, type);
00243
00244 if (offers.isEmpty()) {
00245 return defaultPackageStructure(type);
00246 }
00247
00248 KService::Ptr offer = offers.first();
00249 QString packageFormat = offer->property("X-Plasma-PackageFormat").toString();
00250
00251 if (packageFormat.isEmpty()) {
00252 return defaultPackageStructure(type);
00253 } else {
00254 PackageStructure::Ptr structure = PackageStructure::load(packageFormat);
00255 return structure;
00256 }
00257 }
00258
00259 }
00260
00261 #include <scriptengine.moc>
00262