Changeset View
Changeset View
Standalone View
Standalone View
shell/scripting/scriptengine_v1.cpp
Show All 17 Lines | |||||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include "scriptengine_v1.h" | 20 | #include "scriptengine_v1.h" | ||
21 | 21 | | |||
22 | #include <QDir> | 22 | #include <QDir> | ||
23 | #include <QDirIterator> | 23 | #include <QDirIterator> | ||
24 | #include <QFile> | 24 | #include <QFile> | ||
25 | #include <QFileInfo> | 25 | #include <QFileInfo> | ||
26 | #include <QScriptValueIterator> | 26 | #include <QJSValueIterator> | ||
27 | #include <QStandardPaths> | 27 | #include <QStandardPaths> | ||
28 | #include <QFutureWatcher> | 28 | #include <QFutureWatcher> | ||
29 | 29 | | |||
30 | #include <QDebug> | 30 | #include <QDebug> | ||
31 | #include <klocalizedstring.h> | 31 | #include <klocalizedstring.h> | ||
32 | #include <kmimetypetrader.h> | 32 | #include <kmimetypetrader.h> | ||
33 | #include <kservicetypetrader.h> | 33 | #include <kservicetypetrader.h> | ||
34 | #include <kshell.h> | 34 | #include <kshell.h> | ||
35 | 35 | | |||
36 | // KIO | 36 | // KIO | ||
37 | //#include <kemailsettings.h> // no camelcase include | 37 | //#include <kemailsettings.h> // no camelcase include | ||
38 | 38 | | |||
39 | #include <Plasma/Applet> | 39 | #include <Plasma/Applet> | ||
40 | #include <Plasma/PluginLoader> | 40 | #include <Plasma/PluginLoader> | ||
41 | #include <Plasma/Containment> | 41 | #include <Plasma/Containment> | ||
42 | #include <qstandardpaths.h> | 42 | #include <qstandardpaths.h> | ||
43 | #include <KPackage/Package> | 43 | #include <KPackage/Package> | ||
44 | #include <KPackage/PackageLoader> | 44 | #include <KPackage/PackageLoader> | ||
45 | 45 | | |||
46 | #include "appinterface.h" | 46 | #include "appinterface.h" | ||
47 | #include "containment.h" | 47 | #include "containment.h" | ||
48 | #include "configgroup.h" | 48 | #include "configgroup.h" | ||
49 | #include "i18n.h" | | |||
50 | #include "panel.h" | 49 | #include "panel.h" | ||
51 | #include "widget.h" | 50 | #include "widget.h" | ||
52 | #include "../shellcorona.h" | 51 | #include "../shellcorona.h" | ||
53 | #include "../standaloneappcorona.h" | 52 | #include "../standaloneappcorona.h" | ||
54 | #include "../screenpool.h" | 53 | #include "../screenpool.h" | ||
55 | 54 | | |||
56 | namespace { | 55 | namespace { | ||
57 | template <typename T> | 56 | template <typename T> | ||
58 | inline void awaitFuture(const QFuture<T> &future) | 57 | inline void awaitFuture(const QFuture<T> &future) | ||
59 | { | 58 | { | ||
60 | while (!future.isFinished()) { | 59 | while (!future.isFinished()) { | ||
61 | QCoreApplication::processEvents(); | 60 | QCoreApplication::processEvents(); | ||
62 | } | 61 | } | ||
63 | } | 62 | } | ||
64 | 63 | | |||
65 | class ScriptArray_forEach_Helper { | 64 | class ScriptArray_forEach_Helper { | ||
66 | public: | 65 | public: | ||
67 | ScriptArray_forEach_Helper(const QScriptValue &array) | 66 | ScriptArray_forEach_Helper(const QJSValue &array) | ||
68 | : array(array) | 67 | : array(array) | ||
69 | { | 68 | { | ||
70 | } | 69 | } | ||
71 | 70 | | |||
72 | // operator + is commonly used for these things | 71 | // operator + is commonly used for these things | ||
73 | // to avoid having the lambda inside the parenthesis | 72 | // to avoid having the lambda inside the parenthesis | ||
74 | template <typename Function> | 73 | template <typename Function> | ||
75 | void operator+ (Function function) const | 74 | void operator+ (Function function) const | ||
76 | { | 75 | { | ||
77 | if (!array.isArray()) return; | 76 | if (!array.isArray()) return; | ||
78 | 77 | | |||
79 | int length = array.property("length").toInteger(); | 78 | int length = array.property("length").toInt(); | ||
80 | for (int i = 0; i < length; ++i) { | 79 | for (int i = 0; i < length; ++i) { | ||
81 | function(array.property(i)); | 80 | function(array.property(i)); | ||
82 | } | 81 | } | ||
83 | } | 82 | } | ||
84 | 83 | | |||
85 | private: | 84 | private: | ||
86 | const QScriptValue &array; | 85 | const QJSValue &array; | ||
87 | }; | 86 | }; | ||
88 | 87 | | |||
89 | #define SCRIPT_ARRAY_FOREACH(Variable, Array) \ | 88 | #define SCRIPT_ARRAY_FOREACH(Variable, Array) \ | ||
90 | ScriptArray_forEach_Helper(Array) + [&] (const QScriptValue &Variable) | 89 | ScriptArray_forEach_Helper(Array) + [&] (const QJSValue &Variable) | ||
91 | 90 | | |||
92 | class ScriptObject_forEach_Helper { | 91 | class ScriptObject_forEach_Helper { | ||
93 | public: | 92 | public: | ||
94 | ScriptObject_forEach_Helper(const QScriptValue &object) | 93 | ScriptObject_forEach_Helper(const QJSValue &object) | ||
95 | : object(object) | 94 | : object(object) | ||
96 | { | 95 | { | ||
97 | } | 96 | } | ||
98 | 97 | | |||
99 | // operator + is commonly used for these things | 98 | // operator + is commonly used for these things | ||
100 | // to avoid having the lambda inside the parenthesis | 99 | // to avoid having the lambda inside the parenthesis | ||
101 | template <typename Function> | 100 | template <typename Function> | ||
102 | void operator+ (Function function) const | 101 | void operator+ (Function function) const | ||
103 | { | 102 | { | ||
104 | QScriptValueIterator it(object); | 103 | QJSValueIterator it(object); | ||
105 | while (it.hasNext()) { | 104 | while (it.hasNext()) { | ||
106 | it.next(); | 105 | it.next(); | ||
107 | function(it.name(), it.value()); | 106 | function(it.name(), it.value()); | ||
108 | } | 107 | } | ||
109 | } | 108 | } | ||
110 | 109 | | |||
111 | private: | 110 | private: | ||
112 | const QScriptValue &object; | 111 | const QJSValue &object; | ||
113 | }; | 112 | }; | ||
114 | 113 | | |||
115 | #define SCRIPT_OBJECT_FOREACH(Key, Value, Array) \ | 114 | #define SCRIPT_OBJECT_FOREACH(Key, Value, Array) \ | ||
116 | ScriptObject_forEach_Helper(Array) + [&] (const QString &Key, const QScriptValue &Value) | 115 | ScriptObject_forEach_Helper(Array) + [&] (const QString &Key, const QJSValue &Value) | ||
117 | 116 | | |||
118 | // Case insensitive comparison of two strings | 117 | // Case insensitive comparison of two strings | ||
119 | template <typename StringType> | 118 | template <typename StringType> | ||
120 | inline bool matches(const QString &object, const StringType &string) | 119 | inline bool matches(const QString &object, const StringType &string) | ||
121 | { | 120 | { | ||
122 | return object.compare(string, Qt::CaseInsensitive) == 0; | 121 | return object.compare(string, Qt::CaseInsensitive) == 0; | ||
123 | } | 122 | } | ||
124 | } | 123 | } | ||
125 | 124 | | |||
126 | namespace WorkspaceScripting | 125 | namespace WorkspaceScripting | ||
127 | { | 126 | { | ||
128 | 127 | | |||
129 | QScriptValue ScriptEngine::V1::desktopById(QScriptContext *context, QScriptEngine *engine) | 128 | ScriptEngine::V1::V1(ScriptEngine *parent) | ||
129 | : QObject(parent), | ||||
130 | m_engine(parent) | ||||
131 | {} | ||||
132 | | ||||
133 | ScriptEngine::V1::~V1() | ||||
134 | {} | ||||
135 | | ||||
136 | QJSValue ScriptEngine::V1::getApiVersion(const QJSValue ¶m) | ||||
130 | { | 137 | { | ||
131 | if (context->argumentCount() == 0) { | 138 | if (param.toInt() != 1) { | ||
132 | return context->throwError(i18n("desktopById requires an id")); | 139 | return m_engine->newError(i18n("maximum api version supported is 1")); | ||
140 | } | ||||
141 | return m_engine->newQObject(this); | ||||
133 | } | 142 | } | ||
134 | 143 | | |||
135 | const uint id = context->argument(0).toInt32(); | 144 | int ScriptEngine::V1::gridUnit() const | ||
136 | ScriptEngine *env = envFor(engine); | 145 | { | ||
137 | foreach (Plasma::Containment *c, env->m_corona->containments()) { | 146 | int gridUnit = QFontMetrics(QGuiApplication::font()).boundingRect(QStringLiteral("M")).height(); | ||
147 | if (gridUnit % 2 != 0) { | ||||
148 | gridUnit++; | ||||
149 | } | ||||
150 | | ||||
151 | return gridUnit; | ||||
152 | } | ||||
153 | | ||||
154 | QJSValue ScriptEngine::V1::desktopById(const QJSValue ¶m) const | ||||
155 | { | ||||
156 | //this needs to work also for string of numberls, like "20" | ||||
157 | if (param.isUndefined()) { | ||||
158 | return m_engine->newError(i18n("desktopById required an id")); | ||||
159 | } | ||||
160 | | ||||
161 | const quint32 id = param.toInt(); | ||||
162 | | ||||
163 | foreach (Plasma::Containment *c, m_engine->m_corona->containments()) { | ||||
138 | if (c->id() == id && !isPanel(c)) { | 164 | if (c->id() == id && !isPanel(c)) { | ||
139 | return env->wrap(c); | 165 | return m_engine->wrap(c); | ||
140 | } | 166 | } | ||
141 | } | 167 | } | ||
142 | 168 | | |||
143 | return engine->undefinedValue(); | 169 | return QJSValue(); | ||
144 | } | 170 | } | ||
145 | 171 | | |||
146 | QScriptValue ScriptEngine::V1::desktopsForActivity(QScriptContext *context, QScriptEngine *engine) | 172 | QJSValue ScriptEngine::V1::desktopsForActivity(const QJSValue &actId) const | ||
147 | { | 173 | { | ||
148 | if (context->argumentCount() == 0) { | 174 | if (!actId.isString()) { | ||
149 | return context->throwError(i18n("desktopsForActivity requires an id")); | 175 | return m_engine->newError(i18n("desktopsForActivity requires an id")); | ||
150 | } | 176 | } | ||
151 | 177 | | |||
152 | QScriptValue containments = engine->newArray(); | 178 | QJSValue containments = m_engine->newArray(); | ||
153 | int count = 0; | 179 | int count = 0; | ||
154 | 180 | | |||
155 | const QString id = context->argument(0).toString(); | 181 | const QString id = actId.toString(); | ||
156 | | ||||
157 | ScriptEngine *env = envFor(engine); | | |||
158 | 182 | | |||
159 | const auto result = env->desktopsForActivity(id); | 183 | const auto result = m_engine->desktopsForActivity(id); | ||
160 | 184 | | |||
161 | for (Containment* c: result) { | 185 | for (Containment* c: result) { | ||
162 | containments.setProperty(count, env->wrap(c)); | 186 | containments.setProperty(count, m_engine->newQObject(c)); | ||
163 | ++count; | 187 | ++count; | ||
164 | } | 188 | } | ||
165 | 189 | | |||
166 | containments.setProperty(QStringLiteral("length"), count); | 190 | containments.setProperty(QStringLiteral("length"), count); | ||
167 | return containments; | 191 | return containments; | ||
168 | } | 192 | } | ||
169 | 193 | | |||
170 | QScriptValue ScriptEngine::V1::desktopForScreen(QScriptContext *context, QScriptEngine *engine) | 194 | QJSValue ScriptEngine::V1::desktopForScreen(const QJSValue ¶m) const | ||
171 | { | 195 | { | ||
172 | if (context->argumentCount() == 0) { | 196 | //this needs to work also for string of numberls, like "20" | ||
173 | return context->throwError(i18n("activityForScreen requires a screen id")); | 197 | if (param.isUndefined()) { | ||
198 | return m_engine->newError(i18n("activityForScreen requires a screen id")); | ||||
davidedmundson: I think we should add a wrapper for this error creation in ScriptEngine, it's duplicated a lot. | |||||
174 | } | 199 | } | ||
175 | 200 | | |||
176 | const uint screen = context->argument(0).toInt32(); | 201 | const uint screen = param.toInt(); | ||
177 | ScriptEngine *env = envFor(engine); | 202 | return m_engine->wrap(m_engine->m_corona->containmentForScreen(screen)); | ||
178 | return env->wrap(env->m_corona->containmentForScreen(screen)); | | |||
179 | } | 203 | } | ||
180 | 204 | | |||
181 | QScriptValue ScriptEngine::V1::createActivity(QScriptContext *context, QScriptEngine *engine) | 205 | QJSValue ScriptEngine::V1::createActivity(const QJSValue &nameParam, const QString &pluginParam) | ||
182 | { | 206 | { | ||
183 | if (context->argumentCount() < 0) { | 207 | if (!nameParam.isString()) { | ||
184 | return context->throwError(i18n("createActivity required the activity name")); | 208 | return m_engine->newError(i18n("createActivity required the activity name")); | ||
185 | } | 209 | } | ||
186 | 210 | | |||
187 | const QString name = context->argument(0).toString(); | 211 | QString plugin = pluginParam; | ||
188 | QString plugin = context->argument(1).toString(); | 212 | const QString name = nameParam.toString(); | ||
189 | | ||||
190 | ScriptEngine *env = envFor(engine); | | |||
191 | 213 | | |||
192 | KActivities::Controller controller; | 214 | KActivities::Controller controller; | ||
193 | 215 | | |||
194 | // This is not the nicest way to do this, but createActivity | 216 | // This is not the nicest way to do this, but createActivity | ||
195 | // is a synchronous API :/ | 217 | // is a synchronous API :/ | ||
196 | QFuture<QString> futureId = controller.addActivity(name); | 218 | QFuture<QString> futureId = controller.addActivity(name); | ||
197 | awaitFuture(futureId); | 219 | awaitFuture(futureId); | ||
198 | 220 | | |||
199 | QString id = futureId.result(); | 221 | QString id = futureId.result(); | ||
200 | 222 | | |||
201 | qDebug() << "Setting default Containment plugin:" << plugin; | 223 | qDebug() << "Setting default Containment plugin:" << plugin; | ||
202 | 224 | | |||
203 | ShellCorona *sc = qobject_cast<ShellCorona *>(env->m_corona); | 225 | ShellCorona *sc = qobject_cast<ShellCorona *>(m_engine->m_corona); | ||
204 | StandaloneAppCorona *ac = qobject_cast<StandaloneAppCorona *>(env->m_corona); | 226 | StandaloneAppCorona *ac = qobject_cast<StandaloneAppCorona *>(m_engine->m_corona); | ||
205 | if (sc) { | 227 | if (sc) { | ||
206 | if (plugin.isEmpty() || plugin == QLatin1String("undefined")) { | 228 | if (plugin.isEmpty() || plugin == QLatin1String("undefined")) { | ||
207 | plugin = sc->defaultContainmentPlugin(); | 229 | plugin = sc->defaultContainmentPlugin(); | ||
208 | } | 230 | } | ||
209 | sc->insertActivity(id, plugin); | 231 | sc->insertActivity(id, plugin); | ||
210 | } else if (ac) { | 232 | } else if (ac) { | ||
211 | if (plugin.isEmpty() || plugin == QLatin1String("undefined")) { | 233 | if (plugin.isEmpty() || plugin == QLatin1String("undefined")) { | ||
212 | KConfigGroup shellCfg = KConfigGroup(KSharedConfig::openConfig(env->m_corona->package().filePath("defaults")), "Desktop"); | 234 | KConfigGroup shellCfg = KConfigGroup(KSharedConfig::openConfig(m_engine->m_corona->package().filePath("defaults")), "Desktop"); | ||
213 | plugin = shellCfg.readEntry("Containment", "org.kde.desktopcontainment"); | 235 | plugin = shellCfg.readEntry("Containment", "org.kde.desktopcontainment"); | ||
214 | } | 236 | } | ||
215 | ac->insertActivity(id, plugin); | 237 | ac->insertActivity(id, plugin); | ||
216 | } | 238 | } | ||
217 | 239 | | |||
218 | return QScriptValue(id); | 240 | return m_engine->toScriptValue<QString>(id); | ||
219 | } | 241 | } | ||
220 | 242 | | |||
221 | QScriptValue ScriptEngine::V1::setCurrentActivity(QScriptContext *context, QScriptEngine *engine) | 243 | QJSValue ScriptEngine::V1::setCurrentActivity(const QJSValue ¶m) | ||
222 | { | 244 | { | ||
223 | Q_UNUSED(engine) | 245 | if (!param.isString()) { | ||
224 | 246 | return m_engine->newError(i18n("setCurrentActivity required the activity id")); | |||
225 | if (context->argumentCount() < 0) { | | |||
226 | return context->throwError(i18n("setCurrentActivity required the activity id")); | | |||
227 | } | 247 | } | ||
228 | 248 | | |||
229 | const QString id = context->argument(0).toString(); | 249 | const QString id = param.toString(); | ||
230 | 250 | | |||
231 | KActivities::Controller controller; | 251 | KActivities::Controller controller; | ||
232 | 252 | | |||
233 | QFuture<bool> task = controller.setCurrentActivity(id); | 253 | QFuture<bool> task = controller.setCurrentActivity(id); | ||
234 | awaitFuture(task); | 254 | awaitFuture(task); | ||
235 | 255 | | |||
236 | return QScriptValue(task.result()); | 256 | return task.result(); | ||
237 | } | 257 | } | ||
238 | 258 | | |||
239 | QScriptValue ScriptEngine::V1::setActivityName(QScriptContext *context, QScriptEngine *engine) | 259 | QJSValue ScriptEngine::V1::setActivityName(const QJSValue &idParam, const QJSValue &nameParam) | ||
240 | { | 260 | { | ||
241 | Q_UNUSED(engine) | 261 | if (!idParam.isString() || !nameParam.isString()) { | ||
242 | 262 | return m_engine->newError(i18n("setActivityName required the activity id and name")); | |||
243 | if (context->argumentCount() < 2) { | | |||
244 | return context->throwError(i18n("setActivityName required the activity id and name")); | | |||
245 | } | 263 | } | ||
246 | 264 | | |||
247 | const QString id = context->argument(0).toString(); | 265 | | ||
248 | const QString name = context->argument(1).toString(); | 266 | const QString id = idParam.toString(); | ||
267 | const QString name = nameParam.toString(); | ||||
249 | 268 | | |||
250 | KActivities::Controller controller; | 269 | KActivities::Controller controller; | ||
251 | 270 | | |||
252 | QFuture<void> task = controller.setActivityName(id, name); | 271 | QFuture<void> task = controller.setActivityName(id, name); | ||
253 | awaitFuture(task); | 272 | awaitFuture(task); | ||
254 | 273 | return QJSValue(); | |||
255 | return QScriptValue(); | | |||
256 | } | 274 | } | ||
257 | 275 | | |||
258 | QScriptValue ScriptEngine::V1::activityName(QScriptContext *context, QScriptEngine *engine) | 276 | QJSValue ScriptEngine::V1::activityName(const QJSValue &idParam) const | ||
259 | { | 277 | { | ||
260 | Q_UNUSED(engine) | 278 | if (!idParam.isString()) { | ||
261 | 279 | return m_engine->newError(i18n("activityName required the activity id")); | |||
262 | if (context->argumentCount() < 1) { | | |||
263 | return context->throwError(i18n("setActivityName required the activity id and name")); | | |||
264 | } | 280 | } | ||
265 | 281 | | |||
266 | const QString id = context->argument(0).toString(); | 282 | const QString id = idParam.toString(); | ||
267 | 283 | | |||
268 | KActivities::Info info(id); | 284 | KActivities::Info info(id); | ||
269 | 285 | | |||
270 | return QScriptValue(info.name()); | 286 | return QJSValue(info.name()); | ||
271 | } | 287 | } | ||
272 | 288 | | |||
273 | QScriptValue ScriptEngine::V1::currentActivity(QScriptContext *context, QScriptEngine *engine) | 289 | QString ScriptEngine::V1::currentActivity() const | ||
274 | { | 290 | { | ||
275 | Q_UNUSED(engine) | | |||
276 | Q_UNUSED(context) | | |||
277 | | ||||
278 | KActivities::Consumer consumer; | 291 | KActivities::Consumer consumer; | ||
279 | return consumer.currentActivity(); | 292 | return consumer.currentActivity(); | ||
280 | } | 293 | } | ||
281 | 294 | | |||
282 | QScriptValue ScriptEngine::V1::activities(QScriptContext *context, QScriptEngine *engine) | 295 | QJSValue ScriptEngine::V1::activities() const | ||
283 | { | 296 | { | ||
284 | Q_UNUSED(context) | 297 | QJSValue acts = m_engine->newArray(); | ||
298 | int count = 0; | ||||
299 | | ||||
300 | const auto result = m_engine->availableActivities(); | ||||
301 | | ||||
302 | for (const auto a : result) { | ||||
303 | acts.setProperty(count, a); | ||||
304 | ++count; | ||||
305 | } | ||||
306 | acts.setProperty(QStringLiteral("length"), count); | ||||
285 | 307 | | |||
286 | return qScriptValueFromSequence(engine, envFor(engine)->availableActivities()); | 308 | return acts; | ||
287 | } | 309 | } | ||
288 | 310 | | |||
289 | // Utility function to process configs and config groups | 311 | // Utility function to process configs and config groups | ||
290 | template <typename Object> | 312 | template <typename Object> | ||
291 | void loadSerializedConfigs(Object *object, const QScriptValue &configs) | 313 | void loadSerializedConfigs(Object *object, const QJSValue &configs) | ||
292 | { | 314 | { | ||
293 | SCRIPT_OBJECT_FOREACH(escapedGroup, config, configs) { | 315 | SCRIPT_OBJECT_FOREACH(escapedGroup, config, configs) { | ||
294 | // If the config group is set, pass it on to the containment | 316 | // If the config group is set, pass it on to the containment | ||
295 | QStringList groups = escapedGroup.split('/', QString::SkipEmptyParts); | 317 | QStringList groups = escapedGroup.split('/', QString::SkipEmptyParts); | ||
296 | for (QString &group: groups) { | 318 | for (QString &group: groups) { | ||
297 | group = QUrl::fromPercentEncoding(group.toUtf8()); | 319 | group = QUrl::fromPercentEncoding(group.toUtf8()); | ||
298 | } | 320 | } | ||
299 | qDebug() << "Config group" << groups; | 321 | qDebug() << "Config group" << groups; | ||
300 | object->setCurrentConfigGroup(groups); | 322 | object->setCurrentConfigGroup(groups); | ||
301 | 323 | | |||
302 | // Read other properties and set the configuration | 324 | // Read other properties and set the configuration | ||
303 | SCRIPT_OBJECT_FOREACH(key, value, config) { | 325 | SCRIPT_OBJECT_FOREACH(key, value, config) { | ||
304 | object->writeConfig(key, value.toVariant()); | 326 | object->writeConfig(key, value.toVariant()); | ||
305 | }; | 327 | }; | ||
306 | }; | 328 | }; | ||
307 | } | 329 | } | ||
308 | 330 | | |||
309 | QScriptValue ScriptEngine::V1::loadSerializedLayout(QScriptContext *context, QScriptEngine *engine) | 331 | QJSValue ScriptEngine::V1::loadSerializedLayout(const QJSValue &data) | ||
310 | { | 332 | { | ||
311 | Q_UNUSED(engine) | 333 | if (!data.isObject()) { | ||
312 | 334 | return m_engine->newError(i18n("loadSerializedLayout requires the JSON object to deserialize from")); | |||
313 | if (context->argumentCount() < 1) { | | |||
314 | return context->throwError(i18n("loadSerializedLayout requires the JSON object to deserialize from")); | | |||
315 | } | 335 | } | ||
316 | 336 | | |||
317 | ScriptEngine *env = envFor(engine); | 337 | if (data.property("serializationFormatVersion").toInt() != 1) { | ||
318 | 338 | return m_engine->newError(i18n("loadSerializedLayout: invalid version of the serialized object")); | |||
319 | const auto data = context->argument(0); | | |||
320 | | ||||
321 | if (data.property("serializationFormatVersion").toInteger() != 1) { | | |||
322 | return context->throwError(i18n("loadSerializedLayout: invalid version of the serialized object")); | | |||
323 | } | 339 | } | ||
324 | 340 | | |||
325 | const auto desktops = env->desktopsForActivity(KActivities::Consumer().currentActivity()); | 341 | const auto desktops = m_engine->desktopsForActivity(KActivities::Consumer().currentActivity()); | ||
326 | Q_ASSERT_X(desktops.size() != 0, "V1::loadSerializedLayout", "We need desktops"); | 342 | Q_ASSERT_X(desktops.size() != 0, "V1::loadSerializedLayout", "We need desktops"); | ||
327 | 343 | | |||
328 | // qDebug() << "DESKTOP DESERIALIZATION: Loading desktops..."; | 344 | // qDebug() << "DESKTOP DESERIALIZATION: Loading desktops..."; | ||
329 | 345 | | |||
330 | int count = 0; | 346 | int count = 0; | ||
331 | SCRIPT_ARRAY_FOREACH(desktopData, data.property("desktops")) { | 347 | SCRIPT_ARRAY_FOREACH(desktopData, data.property("desktops")) { | ||
332 | // If the template has more desktops than we do, ignore them | 348 | // If the template has more desktops than we do, ignore them | ||
333 | if (count >= desktops.size()) return; | 349 | if (count >= desktops.size()) return; | ||
334 | 350 | | |||
335 | auto desktop = desktops[count]; | 351 | auto desktop = desktops[count]; | ||
336 | // qDebug() << "DESKTOP DESERIALIZATION: var cont = desktopsArray[...]; " << count << " -> " << desktop; | 352 | // qDebug() << "DESKTOP DESERIALIZATION: var cont = desktopsArray[...]; " << count << " -> " << desktop; | ||
337 | 353 | | |||
338 | // Setting the wallpaper plugin because it is special | 354 | // Setting the wallpaper plugin because it is special | ||
339 | desktop->setWallpaperPlugin(desktopData.property("wallpaperPlugin").toString()); | 355 | desktop->setWallpaperPlugin(desktopData.property("wallpaperPlugin").toString()); | ||
340 | // qDebug() << "DESKTOP DESERIALIZATION: cont->setWallpaperPlugin(...) " << desktop->wallpaperPlugin(); | 356 | // qDebug() << "DESKTOP DESERIALIZATION: cont->setWallpaperPlugin(...) " << desktop->wallpaperPlugin(); | ||
341 | 357 | | |||
342 | // Now, lets go through the configs | 358 | // Now, lets go through the configs | ||
343 | loadSerializedConfigs(desktop, desktopData.property("config")); | 359 | loadSerializedConfigs(desktop, desktopData.property("config")); | ||
344 | 360 | | |||
345 | // After the config, we want to load the applets | 361 | // After the config, we want to load the applets | ||
346 | SCRIPT_ARRAY_FOREACH(appletData, desktopData.property("applets")) { | 362 | SCRIPT_ARRAY_FOREACH(appletData, desktopData.property("applets")) { | ||
347 | // qDebug() << "DESKTOP DESERIALIZATION: Applet: " << appletData.toString(); | 363 | // qDebug() << "DESKTOP DESERIALIZATION: Applet: " << appletData.toString(); | ||
348 | 364 | | |||
349 | // TODO: It would be nicer to be able to call addWidget directly | 365 | auto appletObject = desktop->addWidget( appletData.property("plugin"), | ||
350 | auto desktopObject = env->wrap(desktop); | 366 | appletData.property("geometry.x").toInt() * gridUnit(), | ||
351 | auto addAppletFunction = desktopObject.property("addWidget"); | 367 | appletData.property("geometry.y").toInt() * gridUnit(), | ||
352 | QScriptValueList args { | 368 | appletData.property("geometry.width").toInt() * gridUnit(), | ||
353 | appletData.property("plugin"), | 369 | appletData.property("geometry.height").toInt() * gridUnit()); | ||
354 | appletData.property("geometry.x").toInteger() * ScriptEngine::gridUnit(), | | |||
355 | appletData.property("geometry.y").toInteger() * ScriptEngine::gridUnit(), | | |||
356 | appletData.property("geometry.width").toInteger() * ScriptEngine::gridUnit(), | | |||
357 | appletData.property("geometry.height").toInteger() * ScriptEngine::gridUnit() | | |||
358 | }; | | |||
359 | | ||||
360 | auto appletObject = addAppletFunction.call(desktopObject, args); | | |||
361 | 370 | | |||
362 | if (auto applet = qobject_cast<Widget*>(appletObject.toQObject())) { | 371 | if (auto applet = qobject_cast<Widget*>(appletObject.toQObject())) { | ||
363 | // Now, lets go through the configs for the applet | 372 | // Now, lets go through the configs for the applet | ||
364 | loadSerializedConfigs(applet, appletData.property("config")); | 373 | loadSerializedConfigs(applet, appletData.property("config")); | ||
365 | } | 374 | } | ||
366 | }; | 375 | }; | ||
367 | 376 | | |||
368 | count++; | 377 | count++; | ||
369 | }; | 378 | }; | ||
370 | 379 | | |||
371 | // qDebug() << "PANEL DESERIALIZATION: Loading panels..."; | 380 | // qDebug() << "PANEL DESERIALIZATION: Loading panels..."; | ||
372 | 381 | | |||
373 | SCRIPT_ARRAY_FOREACH(panelData, data.property("panels")) { | 382 | SCRIPT_ARRAY_FOREACH(panelData, data.property("panels")) { | ||
374 | const auto panel = qobject_cast<Panel *>(env->createContainment( | 383 | const auto panel = qobject_cast<Panel *>(m_engine->createContainmentWrapper( | ||
375 | QStringLiteral("Panel"), QStringLiteral("org.kde.panel"))); | 384 | QStringLiteral("Panel"), QStringLiteral("org.kde.panel"))); | ||
376 | 385 | | |||
377 | Q_ASSERT(panel); | 386 | Q_ASSERT(panel); | ||
378 | 387 | | |||
379 | // Basic panel setup | 388 | // Basic panel setup | ||
380 | panel->setLocation(panelData.property("location").toString()); | 389 | panel->setLocation(panelData.property("location").toString()); | ||
381 | panel->setHeight(panelData.property("height").toNumber() * ScriptEngine::gridUnit()); | 390 | panel->setHeight(panelData.property("height").toNumber() * gridUnit()); | ||
382 | panel->setMaximumLength(panelData.property("maximumLength").toNumber() * ScriptEngine::gridUnit()); | 391 | panel->setMaximumLength(panelData.property("maximumLength").toNumber() * gridUnit()); | ||
383 | panel->setMinimumLength(panelData.property("minimumLength").toNumber() * ScriptEngine::gridUnit()); | 392 | panel->setMinimumLength(panelData.property("minimumLength").toNumber() * gridUnit()); | ||
384 | panel->setOffset(panelData.property("offset").toNumber() * ScriptEngine::gridUnit()); | 393 | panel->setOffset(panelData.property("offset").toNumber() * gridUnit()); | ||
385 | panel->setAlignment(panelData.property("alignment").toString()); | 394 | panel->setAlignment(panelData.property("alignment").toString()); | ||
386 | panel->setHiding(panelData.property("hiding").toString()); | 395 | panel->setHiding(panelData.property("hiding").toString()); | ||
387 | 396 | | |||
388 | // Loading the config for the panel | 397 | // Loading the config for the panel | ||
389 | loadSerializedConfigs(panel, panelData.property("config")); | 398 | loadSerializedConfigs(panel, panelData.property("config")); | ||
390 | 399 | | |||
391 | // Now dealing with the applets | 400 | // Now dealing with the applets | ||
392 | SCRIPT_ARRAY_FOREACH(appletData, panelData.property("applets")) { | 401 | SCRIPT_ARRAY_FOREACH(appletData, panelData.property("applets")) { | ||
393 | // qDebug() << "PANEL DESERIALIZATION: Applet: " << appletData.toString(); | 402 | // qDebug() << "PANEL DESERIALIZATION: Applet: " << appletData.toString(); | ||
394 | 403 | | |||
395 | // TODO: It would be nicer to be able to call addWidget directly | 404 | auto appletObject = panel->addWidget(appletData.property("plugin")); | ||
396 | auto panelObject = env->wrap(panel); | | |||
397 | auto addAppletFunction = panelObject.property("addWidget"); | | |||
398 | QScriptValueList args { appletData.property("plugin") }; | | |||
399 | | ||||
400 | auto appletObject = addAppletFunction.call(panelObject, args); | | |||
401 | // qDebug() << "PANEL DESERIALIZATION: addWidget" | 405 | // qDebug() << "PANEL DESERIALIZATION: addWidget" | ||
402 | // << appletData.property("plugin").toString() | 406 | // << appletData.property("plugin").toString() | ||
403 | // ; | 407 | // ; | ||
404 | 408 | | |||
405 | if (auto applet = qobject_cast<Widget*>(appletObject.toQObject())) { | 409 | if (auto applet = qobject_cast<Widget*>(appletObject.toQObject())) { | ||
406 | // Now, lets go through the configs for the applet | 410 | // Now, lets go through the configs for the applet | ||
407 | loadSerializedConfigs(applet, appletData.property("config")); | 411 | loadSerializedConfigs(applet, appletData.property("config")); | ||
408 | } | 412 | } | ||
409 | }; | 413 | }; | ||
410 | }; | 414 | }; | ||
411 | 415 | | |||
412 | return QScriptValue(); | 416 | return QJSValue(); | ||
413 | } | 417 | } | ||
414 | 418 | | |||
415 | QScriptValue ScriptEngine::V1::newPanel(QScriptContext *context, QScriptEngine *engine) | 419 | QJSValue ScriptEngine::V1::newPanel(const QString &plugin) | ||
416 | { | 420 | { | ||
417 | QString plugin(QStringLiteral("org.kde.panel")); | 421 | return createContainment(QStringLiteral("Panel"), QStringLiteral("org.kde.panel"), plugin); | ||
418 | | ||||
419 | if (context->argumentCount() > 0) { | | |||
420 | plugin = context->argument(0).toString(); | | |||
421 | } | | |||
422 | | ||||
423 | return createContainment(QStringLiteral("Panel"), plugin, context, engine); | | |||
424 | } | 422 | } | ||
425 | 423 | | |||
426 | QScriptValue ScriptEngine::V1::panelById(QScriptContext *context, QScriptEngine *engine) | 424 | QJSValue ScriptEngine::V1::panelById(const QJSValue &idParam) const | ||
427 | { | 425 | { | ||
428 | if (context->argumentCount() == 0) { | 426 | //this needs to work also for string of numberls, like "20" | ||
429 | return context->throwError(i18n("panelById requires an id")); | 427 | if (idParam.isUndefined()) { | ||
428 | return m_engine->newError(i18n("panelById requires an id")); | ||||
430 | } | 429 | } | ||
431 | 430 | | |||
432 | const uint id = context->argument(0).toInt32(); | 431 | const quint32 id = idParam.toInt(); | ||
433 | ScriptEngine *env = envFor(engine); | 432 | | ||
434 | foreach (Plasma::Containment *c, env->m_corona->containments()) { | 433 | foreach (Plasma::Containment *c, m_engine->m_corona->containments()) { | ||
435 | if (c->id() == id && isPanel(c)) { | 434 | if (c->id() == id && isPanel(c)) { | ||
436 | return env->wrap(c); | 435 | return m_engine->wrap(c); | ||
437 | } | 436 | } | ||
438 | } | 437 | } | ||
439 | 438 | | |||
440 | return engine->undefinedValue(); | 439 | return QJSValue(); | ||
441 | } | 440 | } | ||
442 | 441 | | |||
443 | QScriptValue ScriptEngine::V1::panels(QScriptContext *context, QScriptEngine *engine) | 442 | QJSValue ScriptEngine::V1::desktops() const | ||
444 | { | 443 | { | ||
445 | Q_UNUSED(context) | 444 | QJSValue containments = m_engine->newArray(); | ||
446 | | ||||
447 | QScriptValue panels = engine->newArray(); | | |||
448 | ScriptEngine *env = envFor(engine); | | |||
449 | int count = 0; | 445 | int count = 0; | ||
450 | 446 | | |||
451 | foreach (Plasma::Containment *c, env->m_corona->containments()) { | 447 | const auto result = m_engine->m_corona->containments(); | ||
452 | if (isPanel(c)) { | 448 | | ||
453 | panels.setProperty(count, env->wrap(c)); | 449 | for (const auto c : result) { | ||
450 | // make really sure we get actual desktops, so check for a non empty | ||||
451 | // activty id | ||||
452 | if (!isPanel(c) && !c->activity().isEmpty()) { | ||||
453 | containments.setProperty(count, m_engine->wrap(c)); | ||||
454 | ++count; | 454 | ++count; | ||
455 | } | 455 | } | ||
456 | } | 456 | } | ||
457 | 457 | | |||
458 | panels.setProperty(QStringLiteral("length"), count); | 458 | containments.setProperty(QStringLiteral("length"), count); | ||
459 | return panels; | 459 | return containments; | ||
460 | } | 460 | } | ||
461 | 461 | | |||
462 | QScriptValue ScriptEngine::V1::fileExists(QScriptContext *context, QScriptEngine *engine) | 462 | QJSValue ScriptEngine::V1::panels() const | ||
463 | { | 463 | { | ||
464 | Q_UNUSED(engine) | 464 | QJSValue panels = m_engine->newArray(); | ||
465 | if (context->argumentCount() == 0) { | 465 | int count = 0; | ||
466 | return false; | 466 | | ||
467 | const auto result = m_engine->m_corona->containments(); | ||||
468 | | ||||
469 | for (const auto c : result) { | ||||
470 | panels.setProperty(count, m_engine->wrap(c)); | ||||
471 | ++count; | ||||
472 | } | ||||
473 | panels.setProperty(QStringLiteral("length"), count); | ||||
474 | | ||||
475 | return panels; | ||||
467 | } | 476 | } | ||
468 | 477 | | |||
469 | const QString path = context->argument(0).toString(); | 478 | bool ScriptEngine::V1::fileExists(const QString &path) const | ||
479 | { | ||||
470 | if (path.isEmpty()) { | 480 | if (path.isEmpty()) { | ||
471 | return false; | 481 | return false; | ||
472 | } | 482 | } | ||
473 | 483 | | |||
474 | QFile f(KShell::tildeExpand(path)); | 484 | QFile f(KShell::tildeExpand(path)); | ||
475 | return f.exists(); | 485 | return f.exists(); | ||
476 | } | 486 | } | ||
477 | 487 | | |||
478 | QScriptValue ScriptEngine::V1::loadTemplate(QScriptContext *context, QScriptEngine *engine) | 488 | bool ScriptEngine::V1::loadTemplate(const QString &layout) | ||
479 | { | 489 | { | ||
480 | Q_UNUSED(engine) | | |||
481 | | ||||
482 | if (context->argumentCount() == 0) { | | |||
483 | // qDebug() << "no arguments"; | | |||
484 | return false; | | |||
485 | } | | |||
486 | | ||||
487 | const QString layout = context->argument(0).toString(); | | |||
488 | if (layout.isEmpty() || layout.contains(QStringLiteral("'"))) { | 490 | if (layout.isEmpty() || layout.contains(QStringLiteral("'"))) { | ||
489 | // qDebug() << "layout is empty"; | 491 | // qDebug() << "layout is empty"; | ||
490 | return false; | 492 | return false; | ||
491 | } | 493 | } | ||
492 | 494 | | |||
493 | auto filter = [&layout](const KPluginMetaData &md) -> bool | 495 | auto filter = [&layout](const KPluginMetaData &md) -> bool | ||
494 | { | 496 | { | ||
495 | return md.pluginId() == layout && KPluginMetaData::readStringList(md.rawData(), QStringLiteral("X-Plasma-ContainmentCategories")).contains(QStringLiteral("panel")); | 497 | return md.pluginId() == layout && KPluginMetaData::readStringList(md.rawData(), QStringLiteral("X-Plasma-ContainmentCategories")).contains(QStringLiteral("panel")); | ||
496 | }; | 498 | }; | ||
497 | QList<KPluginMetaData> offers = KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/LayoutTemplate"), QString(), filter); | 499 | QList<KPluginMetaData> offers = KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/LayoutTemplate"), QString(), filter); | ||
498 | 500 | | |||
499 | if (offers.isEmpty()) { | 501 | if (offers.isEmpty()) { | ||
500 | // qDebug() << "offers fail" << constraint; | 502 | // qDebug() << "offers fail" << constraint; | ||
501 | return false; | 503 | return false; | ||
502 | } | 504 | } | ||
503 | 505 | | |||
504 | KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LayoutTemplate")); | 506 | KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LayoutTemplate")); | ||
505 | KPluginMetaData pluginData(offers.first()); | 507 | KPluginMetaData pluginData(offers.first()); | ||
506 | 508 | | |||
507 | QString path; | 509 | QString path; | ||
508 | { | 510 | { | ||
509 | ScriptEngine *env = envFor(engine); | 511 | ShellCorona *sc = qobject_cast<ShellCorona *>(m_engine->m_corona); | ||
510 | ShellCorona *sc = qobject_cast<ShellCorona *>(env->m_corona); | | |||
511 | if (sc) { | 512 | if (sc) { | ||
512 | const QString overridePackagePath = sc->lookAndFeelPackage().path() + QStringLiteral("contents/layouts/") + pluginData.pluginId(); | 513 | const QString overridePackagePath = sc->lookAndFeelPackage().path() + QStringLiteral("contents/layouts/") + pluginData.pluginId(); | ||
513 | 514 | | |||
514 | path = overridePackagePath + QStringLiteral("/metadata.json"); | 515 | path = overridePackagePath + QStringLiteral("/metadata.json"); | ||
515 | if (QFile::exists(path)) { | 516 | if (QFile::exists(path)) { | ||
516 | package.setPath(overridePackagePath); | 517 | package.setPath(overridePackagePath); | ||
517 | } | 518 | } | ||
518 | 519 | | |||
Show All 30 Lines | |||||
549 | } | 550 | } | ||
550 | 551 | | |||
551 | QString script = file.readAll(); | 552 | QString script = file.readAll(); | ||
552 | if (script.isEmpty()) { | 553 | if (script.isEmpty()) { | ||
553 | // qDebug() << "script is empty"; | 554 | // qDebug() << "script is empty"; | ||
554 | return false; | 555 | return false; | ||
555 | } | 556 | } | ||
556 | 557 | | |||
557 | ScriptEngine *env = envFor(engine); | 558 | ScriptEngine *engine = new ScriptEngine(m_engine->corona(), this); | ||
558 | env->globalObject().setProperty(QStringLiteral("templateName"), env->newVariant(pluginData.name()), QScriptValue::ReadOnly | QScriptValue::Undeletable); | 559 | engine->globalObject().setProperty(QStringLiteral("templateName"), pluginData.name()); | ||
559 | env->globalObject().setProperty(QStringLiteral("templateComment"), env->newVariant(pluginData.description()), QScriptValue::ReadOnly | QScriptValue::Undeletable); | 560 | engine->globalObject().setProperty(QStringLiteral("templateComment"), pluginData.description()); | ||
560 | 561 | | |||
561 | QScriptValue rv = env->newObject(); | 562 | engine->evaluateScript(script, path); | ||
562 | QScriptContext *ctx = env->pushContext(); | | |||
563 | ctx->setThisObject(rv); | | |||
564 | 563 | | |||
565 | env->evaluateScript(script, path); | 564 | engine->deleteLater(); | ||
566 | 565 | return true; | |||
567 | env->popContext(); | | |||
568 | return rv; | | |||
569 | } | 566 | } | ||
570 | 567 | | |||
571 | QScriptValue ScriptEngine::V1::applicationExists(QScriptContext *context, QScriptEngine *engine) | 568 | bool ScriptEngine::V1::applicationExists(const QString &application) const | ||
572 | { | 569 | { | ||
573 | Q_UNUSED(engine) | | |||
574 | if (context->argumentCount() == 0) { | | |||
575 | return false; | | |||
576 | } | | |||
577 | | ||||
578 | const QString application = context->argument(0).toString(); | | |||
579 | if (application.isEmpty()) { | 570 | if (application.isEmpty()) { | ||
580 | return false; | 571 | return false; | ||
581 | } | 572 | } | ||
582 | 573 | | |||
583 | // first, check for it in $PATH | 574 | // first, check for it in $PATH | ||
584 | if (!QStandardPaths::findExecutable(application).isEmpty()) { | 575 | if (!QStandardPaths::findExecutable(application).isEmpty()) { | ||
585 | return true; | 576 | return true; | ||
586 | } | 577 | } | ||
Show All 15 Lines | |||||
602 | // next, consult ksycoca for an app by that generic name | 593 | // next, consult ksycoca for an app by that generic name | ||
603 | if (!KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("GenericName =~ '%1'").arg(application)).isEmpty()) { | 594 | if (!KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("GenericName =~ '%1'").arg(application)).isEmpty()) { | ||
604 | return true; | 595 | return true; | ||
605 | } | 596 | } | ||
606 | 597 | | |||
607 | return false; | 598 | return false; | ||
608 | } | 599 | } | ||
609 | 600 | | |||
610 | QScriptValue ScriptEngine::V1::defaultApplication(QScriptContext *context, QScriptEngine *engine) | 601 | QJSValue ScriptEngine::V1::defaultApplication(const QString &application, bool storageId) const | ||
611 | { | 602 | { | ||
612 | Q_UNUSED(engine) | | |||
613 | | ||||
614 | if (context->argumentCount() == 0) { | | |||
615 | return false; | | |||
616 | } | | |||
617 | | ||||
618 | const QString application = context->argument(0).toString(); | | |||
619 | if (application.isEmpty()) { | 603 | if (application.isEmpty()) { | ||
620 | return false; | 604 | return false; | ||
621 | } | 605 | } | ||
622 | 606 | | |||
623 | const bool storageId | | |||
624 | = context->argumentCount() < 2 ? false : context->argument(1).toBool(); | | |||
625 | | ||||
626 | // FIXME: there are some pretty horrible hacks below, in the sense that they | 607 | // FIXME: there are some pretty horrible hacks below, in the sense that they | ||
627 | // assume a very | 608 | // assume a very | ||
628 | // specific implementation system. there is much room for improvement here. | 609 | // specific implementation system. there is much room for improvement here. | ||
629 | // see | 610 | // see | ||
630 | // kdebase-runtime/kcontrol/componentchooser/ for all the gory details ;) | 611 | // kdebase-runtime/kcontrol/componentchooser/ for all the gory details ;) | ||
631 | if (matches(application, QLatin1String("mailer"))) { | 612 | if (matches(application, QLatin1String("mailer"))) { | ||
632 | // KEMailSettings settings; | 613 | // KEMailSettings settings; | ||
633 | 614 | | |||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Line(s) | 691 | if (matches(type, application)) { | |||
722 | break; | 703 | break; | ||
723 | } | 704 | } | ||
724 | } | 705 | } | ||
725 | } | 706 | } | ||
726 | 707 | | |||
727 | return false; | 708 | return false; | ||
728 | } | 709 | } | ||
729 | 710 | | |||
730 | QScriptValue ScriptEngine::V1::applicationPath(QScriptContext *context, | 711 | QJSValue ScriptEngine::V1::applicationPath(const QString &application) const | ||
731 | QScriptEngine *engine) | | |||
732 | { | 712 | { | ||
733 | Q_UNUSED(engine) | | |||
734 | if (context->argumentCount() == 0) { | | |||
735 | return false; | | |||
736 | } | | |||
737 | | ||||
738 | const QString application = context->argument(0).toString(); | | |||
739 | if (application.isEmpty()) { | 713 | if (application.isEmpty()) { | ||
740 | return false; | 714 | return false; | ||
741 | } | 715 | } | ||
742 | 716 | | |||
743 | // first, check for it in $PATH | 717 | // first, check for it in $PATH | ||
744 | const QString path = QStandardPaths::findExecutable(application); | 718 | const QString path = QStandardPaths::findExecutable(application); | ||
745 | if (!path.isEmpty()) { | 719 | if (!path.isEmpty()) { | ||
746 | return path; | 720 | return path; | ||
Show All 24 Lines | 744 | if (!offers.isEmpty()) { | |||
771 | KService::Ptr offer = offers.first(); | 745 | KService::Ptr offer = offers.first(); | ||
772 | return QStandardPaths::locate(QStandardPaths::ApplicationsLocation, | 746 | return QStandardPaths::locate(QStandardPaths::ApplicationsLocation, | ||
773 | offer->entryPath()); | 747 | offer->entryPath()); | ||
774 | } | 748 | } | ||
775 | 749 | | |||
776 | return QString(); | 750 | return QString(); | ||
777 | } | 751 | } | ||
778 | 752 | | |||
779 | QScriptValue ScriptEngine::V1::userDataPath(QScriptContext *context, | 753 | QJSValue ScriptEngine::V1::userDataPath(const QString &type, const QString &path) const | ||
780 | QScriptEngine *engine) | | |||
781 | { | 754 | { | ||
782 | Q_UNUSED(engine) | | |||
783 | if (context->argumentCount() == 0) { | | |||
784 | return QDir::homePath(); | | |||
785 | } | | |||
786 | | ||||
787 | const QString type = context->argument(0).toString(); | | |||
788 | if (type.isEmpty()) { | 755 | if (type.isEmpty()) { | ||
789 | return QDir::homePath(); | 756 | return QDir::homePath(); | ||
790 | } | 757 | } | ||
791 | 758 | | |||
792 | QStandardPaths::StandardLocation location | 759 | QStandardPaths::StandardLocation location | ||
793 | = QStandardPaths::GenericDataLocation; | 760 | = QStandardPaths::GenericDataLocation; | ||
794 | if (matches(type, QLatin1String("desktop"))) { | 761 | if (matches(type, QLatin1String("desktop"))) { | ||
795 | location = QStandardPaths::DesktopLocation; | 762 | location = QStandardPaths::DesktopLocation; | ||
Show All 12 Lines | |||||
808 | 775 | | |||
809 | } else if (matches(type, QLatin1String("pictures"))) { | 776 | } else if (matches(type, QLatin1String("pictures"))) { | ||
810 | location = QStandardPaths::PicturesLocation; | 777 | location = QStandardPaths::PicturesLocation; | ||
811 | 778 | | |||
812 | } else if (matches(type, QLatin1String("config"))) { | 779 | } else if (matches(type, QLatin1String("config"))) { | ||
813 | location = QStandardPaths::GenericConfigLocation; | 780 | location = QStandardPaths::GenericConfigLocation; | ||
814 | } | 781 | } | ||
815 | 782 | | |||
816 | if (context->argumentCount() > 1) { | 783 | if (!path.isEmpty()) { | ||
817 | QString loc = QStandardPaths::writableLocation(location); | 784 | QString loc = QStandardPaths::writableLocation(location); | ||
818 | loc.append(QDir::separator()); | 785 | loc.append(QDir::separator()); | ||
819 | loc.append(context->argument(1).toString()); | 786 | loc.append(path); | ||
820 | return loc; | 787 | return loc; | ||
821 | } | 788 | } | ||
822 | 789 | | |||
823 | const QStringList &locations = QStandardPaths::standardLocations(location); | 790 | const QStringList &locations = QStandardPaths::standardLocations(location); | ||
824 | return locations.count() ? locations.first() : QString(); | 791 | return locations.count() ? locations.first() : QString(); | ||
825 | } | 792 | } | ||
826 | 793 | | |||
827 | QScriptValue ScriptEngine::V1::knownWallpaperPlugins(QScriptContext *context, | 794 | QJSValue ScriptEngine::V1::knownWallpaperPlugins(const QString &formFactor) const | ||
828 | QScriptEngine *engine) | | |||
829 | { | 795 | { | ||
830 | Q_UNUSED(engine) | | |||
831 | | ||||
832 | QString formFactor; | | |||
833 | if (context->argumentCount() > 0) { | | |||
834 | formFactor = context->argument(0).toString(); | | |||
835 | } | | |||
836 | | ||||
837 | QString constraint; | 796 | QString constraint; | ||
838 | if (!formFactor.isEmpty()) { | 797 | if (!formFactor.isEmpty()) { | ||
839 | constraint.append("[X-Plasma-FormFactors] ~~ '") | 798 | constraint.append("[X-Plasma-FormFactors] ~~ '") | ||
840 | .append(formFactor) | 799 | .append(formFactor) | ||
841 | .append("'"); | 800 | .append("'"); | ||
842 | } | 801 | } | ||
843 | 802 | | |||
844 | const QList<KPluginMetaData> wallpapers | 803 | const QList<KPluginMetaData> wallpapers | ||
845 | = KPackage::PackageLoader::self()->listPackages( | 804 | = KPackage::PackageLoader::self()->listPackages( | ||
846 | QStringLiteral("Plasma/Wallpaper"), QString()); | 805 | QStringLiteral("Plasma/Wallpaper"), QString()); | ||
847 | QScriptValue rv = engine->newArray(wallpapers.size()); | 806 | QJSValue rv = m_engine->newArray(wallpapers.size()); | ||
848 | for (auto wp : wallpapers) { | 807 | for (auto wp : wallpapers) { | ||
849 | rv.setProperty(wp.name(), engine->newArray(0)); | 808 | rv.setProperty(wp.name(), m_engine->newArray(0)); | ||
850 | } | 809 | } | ||
851 | 810 | | |||
852 | return rv; | 811 | return rv; | ||
853 | } | 812 | } | ||
854 | 813 | | |||
855 | QScriptValue ScriptEngine::V1::configFile(QScriptContext *context, | 814 | QJSValue ScriptEngine::V1::configFile(const QJSValue &config, const QString &group) | ||
856 | QScriptEngine *engine) | | |||
857 | { | 815 | { | ||
858 | ConfigGroup *file = nullptr; | 816 | ConfigGroup *file = nullptr; | ||
859 | 817 | | |||
860 | if (context->argumentCount() > 0) { | 818 | if (!config.isUndefined()) { | ||
861 | if (context->argument(0).isString()) { | 819 | if (config.isString()) { | ||
862 | file = new ConfigGroup; | 820 | file = new ConfigGroup; | ||
863 | 821 | | |||
864 | const QString &fileName = context->argument(0).toString(); | 822 | const Plasma::Corona *corona = m_engine->corona(); | ||
865 | const ScriptEngine *env = envFor(engine); | 823 | const QString &fileName = config.toString(); | ||
866 | const Plasma::Corona *corona = env->corona(); | | |||
867 | 824 | | |||
868 | if (fileName == corona->config()->name()) { | 825 | if (fileName == corona->config()->name()) { | ||
869 | file->setConfig(corona->config()); | 826 | file->setConfig(corona->config()); | ||
870 | } else { | 827 | } else { | ||
871 | file->setFile(fileName); | 828 | file->setFile(fileName); | ||
872 | } | 829 | } | ||
873 | 830 | | |||
874 | if (context->argumentCount() > 1) { | 831 | if (!group.isEmpty()) { | ||
875 | file->setGroup(context->argument(1).toString()); | 832 | file->setGroup(group); | ||
876 | } | 833 | } | ||
877 | 834 | | |||
878 | } else if (ConfigGroup *parent = qobject_cast<ConfigGroup *>( | 835 | } else if (ConfigGroup *parent = qobject_cast<ConfigGroup *>( | ||
879 | context->argument(0).toQObject())) { | 836 | config.toQObject())) { | ||
880 | file = new ConfigGroup(parent); | 837 | file = new ConfigGroup(parent); | ||
881 | 838 | | |||
882 | if (context->argumentCount() > 1) { | 839 | if (!group.isEmpty()) { | ||
883 | file->setGroup(context->argument(1).toString()); | 840 | file->setGroup(group); | ||
884 | } | 841 | } | ||
885 | } | 842 | } | ||
886 | 843 | | |||
887 | } else { | 844 | } else { | ||
888 | file = new ConfigGroup; | 845 | file = new ConfigGroup; | ||
889 | } | 846 | } | ||
890 | 847 | | |||
891 | QScriptValue v | 848 | QJSValue v = m_engine->newQObject(file); | ||
892 | = engine->newQObject(file, QScriptEngine::ScriptOwnership, | | |||
893 | QScriptEngine::ExcludeSuperClassProperties | | |||
894 | | QScriptEngine::ExcludeSuperClassMethods); | | |||
895 | return v; | 849 | return v; | ||
896 | } | 850 | } | ||
897 | 851 | | |||
898 | QScriptValue ScriptEngine::V1::desktops(QScriptContext *context, | 852 | void ScriptEngine::V1::setImmutability(const QString &immutability) | ||
899 | QScriptEngine *engine) | | |||
900 | { | | |||
901 | Q_UNUSED(context) | | |||
902 | | ||||
903 | QScriptValue containments = engine->newArray(); | | |||
904 | ScriptEngine *env = envFor(engine); | | |||
905 | int count = 0; | | |||
906 | | ||||
907 | foreach (Plasma::Containment *c, env->corona()->containments()) { | | |||
908 | // make really sure we get actual desktops, so check for a non empty | | |||
909 | // activty id | | |||
910 | if (!isPanel(c) && !c->activity().isEmpty()) { | | |||
911 | containments.setProperty(count, env->wrap(c)); | | |||
912 | ++count; | | |||
913 | } | | |||
914 | } | | |||
915 | | ||||
916 | containments.setProperty(QStringLiteral("length"), count); | | |||
917 | return containments; | | |||
918 | } | | |||
919 | | ||||
920 | QScriptValue ScriptEngine::V1::gridUnit(QScriptContext *context, QScriptEngine *engine) | | |||
921 | { | | |||
922 | Q_UNUSED(context); | | |||
923 | Q_UNUSED(engine); | | |||
924 | return ScriptEngine::gridUnit(); | | |||
925 | } | | |||
926 | | ||||
927 | QScriptValue ScriptEngine::V1::setImmutability(QScriptContext *context, | | |||
928 | QScriptEngine *engine) | | |||
929 | { | 853 | { | ||
930 | if (context->argumentCount() == 0) { | 854 | if (immutability.isEmpty()) { | ||
931 | return QScriptValue(); | 855 | return; | ||
932 | } | 856 | } | ||
933 | ScriptEngine *env = envFor(engine); | | |||
934 | const QString immutability = context->argument(0).toString(); | | |||
935 | 857 | | |||
936 | if (immutability == QLatin1String("systemImmutable")) { | 858 | if (immutability == QLatin1String("systemImmutable")) { | ||
937 | env->corona()->setImmutability(Plasma::Types::SystemImmutable); | 859 | m_engine->corona()->setImmutability(Plasma::Types::SystemImmutable); | ||
938 | } else if (immutability == QLatin1String("userImmutable")) { | 860 | } else if (immutability == QLatin1String("userImmutable")) { | ||
939 | env->corona()->setImmutability(Plasma::Types::UserImmutable); | 861 | m_engine->corona()->setImmutability(Plasma::Types::UserImmutable); | ||
940 | } else { | 862 | } else { | ||
941 | env->corona()->setImmutability(Plasma::Types::Mutable); | 863 | m_engine->corona()->setImmutability(Plasma::Types::Mutable); | ||
942 | } | 864 | } | ||
943 | 865 | | |||
944 | return QScriptValue(); | 866 | return; | ||
945 | } | 867 | } | ||
946 | 868 | | |||
947 | QScriptValue ScriptEngine::V1::immutability(QScriptContext *context, | 869 | QString ScriptEngine::V1::immutability() const | ||
948 | QScriptEngine *engine) | | |||
949 | { | 870 | { | ||
950 | ScriptEngine *env = envFor(engine); | 871 | switch (m_engine->corona()->immutability()) { | ||
951 | switch (env->corona()->immutability()) { | | |||
952 | case Plasma::Types::SystemImmutable: | 872 | case Plasma::Types::SystemImmutable: | ||
953 | return QLatin1String("systemImmutable"); | 873 | return QLatin1String("systemImmutable"); | ||
954 | case Plasma::Types::UserImmutable: | 874 | case Plasma::Types::UserImmutable: | ||
955 | return QLatin1String("userImmutable"); | 875 | return QLatin1String("userImmutable"); | ||
956 | default: | 876 | default: | ||
957 | return QLatin1String("mutable"); | 877 | return QLatin1String("mutable"); | ||
958 | } | 878 | } | ||
959 | } | 879 | } | ||
960 | 880 | | |||
961 | QScriptValue ScriptEngine::V1::createContainment(const QString &type, const QString &defaultPlugin, | 881 | QJSValue ScriptEngine::V1::createContainment(const QString &type, const QString &defaultPlugin, const QString &plugin) | ||
962 | QScriptContext *context, QScriptEngine *engine) | | |||
963 | { | 882 | { | ||
964 | const QString plugin = context->argumentCount() > 0 | 883 | const QString actualPlugin = plugin.isEmpty() | ||
965 | ? context->argument(0).toString() | 884 | ? defaultPlugin | ||
966 | : defaultPlugin; | 885 | : plugin; | ||
967 | 886 | | |||
968 | ScriptEngine *env = envFor(engine); | 887 | auto result = m_engine->createContainmentWrapper(type, actualPlugin); | ||
969 | auto result = env->createContainment(type, plugin); | | |||
970 | 888 | | |||
971 | if (!result) { | 889 | if (!result) { | ||
972 | return context->throwError(i18n("Could not find a plugin for %1 named %2.", type, plugin)); | 890 | return m_engine->newError(i18n("Could not find a plugin for %1 named %2.", type, actualPlugin)); | ||
973 | } | 891 | } | ||
974 | 892 | | |||
975 | return env->wrap(result); | 893 | return m_engine->newQObject(result); | ||
976 | } | 894 | } | ||
977 | 895 | | |||
978 | } // namespace WorkspaceScripting | 896 | } // namespace WorkspaceScripting | ||
979 | 897 | | |||
980 | 898 | |
I think we should add a wrapper for this error creation in ScriptEngine, it's duplicated a lot.