diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(QT_MIN_VERSION "5.9.0") set(KF5_MIN_VERSION "5.45.0") set(INSTALL_SDDM_THEME TRUE) -find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Widgets Quick QuickWidgets Concurrent Test Script Network) +find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Widgets Quick QuickWidgets Concurrent Test Network) find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt --- a/shell/CMakeLists.txt +++ b/shell/CMakeLists.txt @@ -9,9 +9,7 @@ scripting/applet.cpp scripting/containment.cpp scripting/configgroup.cpp - scripting/i18n.cpp scripting/panel.cpp - scripting/rect.cpp scripting/scriptengine.cpp scripting/scriptengine_v1.cpp scripting/widget.cpp @@ -60,7 +58,6 @@ KF5::Crash KF5::Plasma KF5::PlasmaQuick - Qt5::Script KF5::Solid KF5::Declarative KF5::I18n diff --git a/shell/scripting/appinterface.h b/shell/scripting/appinterface.h --- a/shell/scripting/appinterface.h +++ b/shell/scripting/appinterface.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace Plasma { @@ -87,7 +88,7 @@ bool coronaLocked() const; public Q_SLOTS: - QRectF screenGeometry(int screen) const; + QJSValue screenGeometry(int screen) const; void lockCorona(bool locked); void sleep(int ms); diff --git a/shell/scripting/appinterface.cpp b/shell/scripting/appinterface.cpp --- a/shell/scripting/appinterface.cpp +++ b/shell/scripting/appinterface.cpp @@ -59,9 +59,11 @@ return m_env->corona()->numScreens(); } -QRectF AppInterface::screenGeometry(int screen) const +QJSValue AppInterface::screenGeometry(int screen) const { - return m_env->corona()->screenGeometry(screen); + QRectF rect = m_env->corona()->screenGeometry(screen); + QJSValueList args({QJSValue(rect.x()), QJSValue(rect.y()), QJSValue(rect.width()), QJSValue(rect.height())}); + return m_env->globalObject().property("QRectF").callAsConstructor(args); } QList AppInterface::activityIds() const diff --git a/shell/scripting/backportglobal.h b/shell/scripting/backportglobal.h deleted file mode 100644 --- a/shell/scripting/backportglobal.h +++ /dev/null @@ -1,349 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the plugins of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** Trolltech ASA (c) 2007 -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ -#ifndef QTSCRIPTEXTENSIONS_GLOBAL_H -#define QTSCRIPTEXTENSIONS_GLOBAL_H - -#include - - -#define DECLARE_SELF(Class, __fn__) \ - Class* self = qscriptvalue_cast(ctx->thisObject()); \ - if (!self) { \ - return ctx->throwError(QScriptContext::TypeError, \ - QStringLiteral("%0.prototype.%1: this object is not a %0") \ - .arg(#Class, #__fn__)); \ - } - -#define DECLARE_SELF2(Class, __fn__, __ret__) \ - Class* self = qscriptvalue_cast(thisObject()); \ - if (!self) { \ - context()->throwError(QScriptContext::TypeError, \ - QStringLiteral("%0.prototype.%1: this object is not a %0") \ - .arg(#Class, #__fn__)); \ - return __ret__; \ - } - - - -#define ADD_METHOD(__p__, __f__) \ - __p__.setProperty(#__f__, __p__.engine()->newFunction(__f__)) - -#define ADD_GET_METHOD(__p__, __get__) \ - ADD_METHOD(__p__, __get__) - -#define ADD_GET_SET_METHODS(__p__, __get__, __set__) \ -do { \ - ADD_METHOD(__p__, __get__); \ - ADD_METHOD(__p__, __set__); \ -} while (0); - -#define ADD_CTOR_FUNCTION(__c__, __f__) ADD_METHOD(__c__, __f__) - -#define ADD_ENUM_VALUE(__c__, __ns__, __v__) \ - __c__.setProperty(#__v__, QScriptValue(__c__.engine(), __ns__::__v__)) - - -#define BEGIN_DECLARE_METHOD(Class, __mtd__) \ -static QScriptValue __mtd__(QScriptContext *ctx, QScriptEngine *eng) \ -{ \ - DECLARE_SELF(Class, __mtd__); - -#define END_DECLARE_METHOD \ -} - - -#define DECLARE_GET_METHOD(Class, __get__) \ -BEGIN_DECLARE_METHOD(Class, __get__) { \ - return qScriptValueFromValue(eng, self->__get__()); \ -} END_DECLARE_METHOD - -#define DECLARE_SET_METHOD(Class, T, __set__) \ -BEGIN_DECLARE_METHOD(Class, __set__) { \ - self->__set__(qscriptvalue_cast(ctx->argument(0))); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_GET_SET_METHODS(Class, T, __get__, __set__) \ -DECLARE_GET_METHOD(Class, /*T,*/ __get__) \ -DECLARE_SET_METHOD(Class, T, __set__) - - - -#define DECLARE_SIMPLE_GET_METHOD(Class, __get__) \ -BEGIN_DECLARE_METHOD(Class, __get__) { \ - return QScriptValue(eng, self->__get__()); \ -} END_DECLARE_METHOD - -#define DECLARE_SIMPLE_SET_METHOD(Class, ToType, __set__) \ -BEGIN_DECLARE_METHOD(Class, __set__) { \ - self->__set__(ctx->argument(0).ToType()); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_BOOLEAN_GET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_GET_METHOD(Class, __set__) -#define DECLARE_BOOLEAN_SET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_SET_METHOD(Class, toBoolean, __set__) - -#define DECLARE_INT_GET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_GET_METHOD(Class, __set__) -#define DECLARE_INT_SET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_SET_METHOD(Class, toInt32, __set__) - -#define DECLARE_NUMBER_GET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_GET_METHOD(Class, __set__) -#define DECLARE_NUMBER_SET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_SET_METHOD(Class, toNumber, __set__) - -#define DECLARE_STRING_GET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_GET_METHOD(Class, __set__) -#define DECLARE_STRING_SET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_SET_METHOD(Class, toString, __set__) - -#define DECLARE_QOBJECT_GET_METHOD(Class, __get__) \ -BEGIN_DECLARE_METHOD(Class, __get__) { \ - return eng->newQObject(self->__get__()); \ -} END_DECLARE_METHOD -#define DECLARE_QOBJECT_SET_METHOD(Class, __set__) \ - DECLARE_SIMPLE_SET_METHOD(Class, toQObject, __set__) - -#define DECLARE_BOOLEAN_GET_SET_METHODS(Class, __get__, __set__) \ - DECLARE_BOOLEAN_GET_METHOD(Class, __get__) \ - DECLARE_BOOLEAN_SET_METHOD(Class, __set__) - -#define DECLARE_NUMBER_GET_SET_METHODS(Class, __get__, __set__) \ - DECLARE_NUMBER_GET_METHOD(Class, __get__) \ - DECLARE_NUMBER_SET_METHOD(Class, __set__) - -#define DECLARE_INT_GET_SET_METHODS(Class, __get__, __set__) \ - DECLARE_INT_GET_METHOD(Class, __get__) \ - DECLARE_INT_SET_METHOD(Class, __set__) - -#define DECLARE_STRING_GET_SET_METHODS(Class, __get__, __set__) \ - DECLARE_STRING_GET_METHOD(Class, __get__) \ - DECLARE_STRING_SET_METHOD(Class, __set__) - -#define DECLARE_QOBJECT_GET_SET_METHODS(Class, __get__, __set__) \ - DECLARE_QOBJECT_GET_METHOD(Class, __get__) \ - DECLARE_QOBJECT_SET_METHOD(Class, __set__) - - -#define DECLARE_VOID_METHOD(Class, __fun__) \ -BEGIN_DECLARE_METHOD(Class, __fun__) { \ - self->__fun__(); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_VOID_NUMBER_METHOD(Class, __fun__) \ -BEGIN_DECLARE_METHOD(Class, __fun__) { \ - self->__fun__(ctx->argument(0).toNumber()); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_VOID_NUMBER_NUMBER_METHOD(Class, __fun__) \ -BEGIN_DECLARE_METHOD(Class, __fun__) { \ - self->__fun__(ctx->argument(0).toNumber(), ctx->argument(1).toNumber()); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_VOID_QUAD_NUMBER_METHOD(Class, __fun__) \ -BEGIN_DECLARE_METHOD(Class, __fun__) { \ - self->__fun__(ctx->argument(0).toNumber(), ctx->argument(1).toNumber(), ctx->argument(2).toNumber(), ctx->argument(3).toNumber()); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_VOID_1ARG_METHOD(Class, ArgType, __fun__) \ -BEGIN_DECLARE_METHOD(Class, __fun__) { \ - self->__fun__(qscriptvalue_cast(ctx->argument(0))); \ - return eng->undefinedValue(); \ -} END_DECLARE_METHOD - -#define DECLARE_BOOLEAN_1ARG_METHOD(Class, ArgType, __fun__) \ -BEGIN_DECLARE_METHOD(Class, __fun__) { \ - return QScriptValue(eng, self->__fun__(qscriptvalue_cast(ctx->argument(0)))); \ -} END_DECLARE_METHOD - - -#define DECLARE_POINTER_METATYPE(T) \ - Q_DECLARE_METATYPE(T*) \ - Q_DECLARE_METATYPE(QScript::Pointer::wrapped_pointer_type) - -namespace QScript -{ - -enum { - UserOwnership = 1 -}; - -template -class Pointer : public QSharedData -{ -public: - typedef T* pointer_type; - typedef QExplicitlySharedDataPointer > wrapped_pointer_type; - - ~Pointer() - { - if (!(m_flags & UserOwnership)) - delete m_value; - } - - operator T*() - { - return m_value; - } - - operator const T*() const - { - return m_value; - } - - static wrapped_pointer_type create(T *value, uint flags = 0) - { - return wrapped_pointer_type(new Pointer(value, flags)); - } - - static QScriptValue toScriptValue(QScriptEngine *engine, T* const &source) - { - if (!source) - return engine->nullValue(); - return engine->newVariant(qVariantFromValue(source)); - } - - static void fromScriptValue(const QScriptValue &value, T* &target) - { - if (value.isVariant()) { - QVariant var = value.toVariant(); - if (var.canConvert()) { - target = qvariant_cast(var); - } else if (var.canConvert()) { - target = qvariant_cast(var)->operator T*(); - } else { - // look in prototype chain - target = 0; - int type = qMetaTypeId(); - int pointerType = qMetaTypeId(); - QScriptValue proto = value.prototype(); - while (proto.isObject() && proto.isVariant()) { - int protoType = proto.toVariant().userType(); - if ((type == protoType) || (pointerType == protoType)) { - QByteArray name = QMetaType::typeName(var.userType()); - if (name.startsWith("QScript::Pointer<")) { - target = (*reinterpret_cast(var.data()))->operator T*(); - break; - } else { - target = static_cast(var.data()); - break; - } - } - proto = proto.prototype(); - } - } - } else if (value.isQObject()) { - QObject *qobj = value.toQObject(); - QByteArray typeName = QMetaType::typeName(qMetaTypeId()); - target = reinterpret_cast(qobj->qt_metacast(typeName.left(typeName.size()-1))); - } else { - target = 0; - } - } - - uint flags() const - { return m_flags; } - void setFlags(uint flags) - { m_flags = flags; } - void unsetFlags(uint flags) - { m_flags &= ~flags; } - -protected: - Pointer(T* value, uint flags) - : m_flags(flags), m_value(value) - {} - -private: - uint m_flags; - T* m_value; -}; - -template -int registerPointerMetaType( - QScriptEngine *eng, - const QScriptValue &prototype = QScriptValue(), - T * /* dummy */ = 0 -) -{ - QScriptValue (*mf)(QScriptEngine *, T* const &) = Pointer::toScriptValue; - void (*df)(const QScriptValue &, T* &) = Pointer::fromScriptValue; - const int id = qMetaTypeId(); - qScriptRegisterMetaType_helper( - eng, id, reinterpret_cast(mf), - reinterpret_cast(df), - prototype); - eng->setDefaultPrototype(qMetaTypeId::wrapped_pointer_type>(), prototype); - return id; -} - -inline void maybeReleaseOwnership(const QScriptValue &value) -{ - if (value.isVariant()) { - QVariant var = value.toVariant(); - QByteArray name = QMetaType::typeName(var.userType()); - if (name.startsWith("QScript::Pointer<")) - (*reinterpret_cast::wrapped_pointer_type *>(var.data()))->setFlags(UserOwnership); - } -} - -inline void maybeTakeOwnership(const QScriptValue &value) -{ - if (value.isVariant()) { - QVariant var = value.toVariant(); - QByteArray name = QMetaType::typeName(var.userType()); - if (name.startsWith("QScript::Pointer<")) - (*reinterpret_cast::wrapped_pointer_type *>(var.data()))->unsetFlags(UserOwnership); - } -} - -template -inline QScriptValue wrapPointer(QScriptEngine *eng, T *ptr, uint flags = 0) -{ - return eng->newVariant(qVariantFromValue(Pointer::create(ptr, flags))); -} - -} // namespace QScript - -#endif // QTSCRIPTEXTENSIONS_GLOBAL_H diff --git a/shell/scripting/configgroup.cpp b/shell/scripting/configgroup.cpp --- a/shell/scripting/configgroup.cpp +++ b/shell/scripting/configgroup.cpp @@ -212,4 +212,3 @@ } } - diff --git a/shell/scripting/containment.h b/shell/scripting/containment.h --- a/shell/scripting/containment.h +++ b/shell/scripting/containment.h @@ -20,8 +20,7 @@ #ifndef CONTAINMENT #define CONTAINMENT -#include -#include +#include #include #include "applet.h" @@ -31,9 +30,13 @@ class Containment; } // namespace Plasma +class ShellCorona; + namespace WorkspaceScripting { +class ScriptEngine; + class Containment : public Applet { Q_OBJECT @@ -54,7 +57,7 @@ Q_PROPERTY(int id READ id) public: - explicit Containment(Plasma::Containment *containment, QObject *parent = nullptr); + explicit Containment(Plasma::Containment *containment, ScriptEngine *parent); ~Containment() override; uint id() const; @@ -72,22 +75,16 @@ QString wallpaperMode() const; void setWallpaperMode(const QString &wallpaperMode); - static QScriptValue widgetById(QScriptContext *context, QScriptEngine *engine); - static QScriptValue addWidget(QScriptContext *context, QScriptEngine *engine); - static QScriptValue widgets(QScriptContext *context, QScriptEngine *engine); + Q_INVOKABLE QJSValue widgetById(const QJSValue ¶mId = QJSValue()) const; + Q_INVOKABLE QJSValue addWidget(const QJSValue &v = QJSValue(), qreal x = -1, qreal y = -1, qreal w = -1, qreal h = -1); + Q_INVOKABLE QJSValue widgets(const QString &widgetType = QString()) const; public Q_SLOTS: void remove(); void showConfigurationInterface(); - // from the applet interface - QVariant readConfig(const QString &key, const QVariant &def = QString()) const override { return Applet::readConfig(key, def); } - void writeConfig(const QString &key, const QVariant &value) override { Applet::writeConfig(key, value); } - - QVariant readGlobalConfig(const QString &key, const QVariant &def = QString()) const override { return Applet::readGlobalConfig(key, def); } - void writeGlobalConfig(const QString &key, const QVariant &value) override { Applet::writeGlobalConfig(key, value); } - - void reloadConfig() override { Applet::reloadConfig(); } +protected: + ShellCorona *corona() const; private: class Private; diff --git a/shell/scripting/containment.cpp b/shell/scripting/containment.cpp --- a/shell/scripting/containment.cpp +++ b/shell/scripting/containment.cpp @@ -30,6 +30,7 @@ #include #include +#include "shellcorona.h" #include "scriptengine.h" #include "widget.h" @@ -39,18 +40,26 @@ class Containment::Private { public: + QPointer engine; QPointer containment; + ShellCorona *corona; QString oldWallpaperPlugin; QString wallpaperPlugin; QString oldWallpaperMode; QString wallpaperMode; + + QString type; + QString plugin; }; -Containment::Containment(Plasma::Containment *containment, QObject *parent) - : Applet(parent), +Containment::Containment(Plasma::Containment *containment, ScriptEngine *engine) + : Applet(engine), d(new Containment::Private) { + d->engine = engine; d->containment = containment; + d->corona = qobject_cast(containment->corona()); + setCurrentConfigGroup(QStringList()); setCurrentGlobalConfigGroup(QStringList()); if (containment) { @@ -73,6 +82,11 @@ delete d; } +ShellCorona *Containment::corona() const +{ + return d->corona; +} + int Containment::screen() const { if (!d->containment) { @@ -140,115 +154,85 @@ return w; } -QScriptValue Containment::widgetById(QScriptContext *context, QScriptEngine *engine) +QJSValue Containment::widgetById(const QJSValue ¶mId) const { - if (context->argumentCount() == 0) { - return context->throwError(i18n("widgetById requires an id")); + if (!paramId.isNumber()) { + return d->engine->newError(i18n("widgetById requires an id")); } - const uint id = context->argument(0).toInt32(); - Containment *c = qobject_cast(context->thisObject().toQObject()); - - if (!c) { - return engine->undefinedValue(); - } + const uint id = paramId.toInt(); - if (c->d->containment) { - foreach (Plasma::Applet *w, c->d->containment.data()->applets()) { + if (d->containment) { + foreach (Plasma::Applet *w, d->containment.data()->applets()) { if (w->id() == id) { - ScriptEngine *env = ScriptEngine::envFor(engine); - return env->wrap(w); + return d->engine->wrap(w); } } } - return engine->undefinedValue(); + return QJSValue(); } -QScriptValue Containment::addWidget(QScriptContext *context, QScriptEngine *engine) +QJSValue Containment::addWidget(const QJSValue &v, qreal x, qreal y, qreal w, qreal h) { - if (context->argumentCount() == 0) { - return context->throwError(i18n("addWidget requires a name of a widget or a widget object")); + if (!v.isString() && !v.isQObject()) { + return d->engine->newError(i18n("addWidget requires a name of a widget or a widget object")); } - Containment *c = qobject_cast(context->thisObject().toQObject()); - - if (!c || !c->d->containment) { - return engine->undefinedValue(); + if (!d->containment) { + return QJSValue(); } - QScriptValue v = context->argument(0); - QRectF geometry(-1, -1, -1, -1); - if (context->argumentCount() > 4) { - //The user provided a geometry as parameter - if (context->argument(1).isNumber() && - context->argument(2).isNumber() && - context->argument(3).isNumber() && - context->argument(4).isNumber()) { - //Try to reconstruct a rectangle from the object hat has been passed - //It's expected a js object such as - //addWidget("org.kde.plasma.analogclock", 0, 100, 300, 400); - geometry = QRectF(context->argument(1).toNumber(), - context->argument(2).toNumber(), - context->argument(3).toNumber(), - context->argument(4).toNumber()); - } - } + QRectF geometry(x, y, w, h); Plasma::Applet *applet = nullptr; if (v.isString()) { //A position has been supplied: search for the containment's graphics object QQuickItem *containmentItem = nullptr; if (geometry.x() >= 0 && geometry.y() >= 0) { - containmentItem = c->d->containment.data()->property("_plasma_graphicObject").value(); + containmentItem = d->containment.data()->property("_plasma_graphicObject").value(); if (containmentItem) { QMetaObject::invokeMethod(containmentItem , "createApplet", Qt::DirectConnection, Q_RETURN_ARG(Plasma::Applet *, applet), Q_ARG(QString, v.toString()), Q_ARG(QVariantList, QVariantList()), Q_ARG(QRectF, geometry)); } if (applet) { - ScriptEngine *env = ScriptEngine::envFor(engine); - return env->wrap(applet); + return d->engine->wrap(applet); } - return context->throwError(i18n("Could not create the %1 widget!", v.toString())); + return d->engine->newError(i18n("Could not create the %1 widget!", v.toString())); } //Case in which either: // * a geometry wasn't provided // * containmentItem wasn't found - applet = c->d->containment.data()->createApplet(v.toString()); + applet = d->containment.data()->createApplet(v.toString()); if (applet) { - ScriptEngine *env = ScriptEngine::envFor(engine); - return env->wrap(applet); + return d->engine->wrap(applet); } - return context->throwError(i18n("Could not create the %1 widget!", v.toString())); + return d->engine->newError(i18n("Could not create the %1 widget!", v.toString())); } else if (Widget *widget = qobject_cast(v.toQObject())) { applet = widget->applet(); - c->d->containment.data()->addApplet(applet); + d->containment.data()->addApplet(applet); return v; } - return engine->undefinedValue(); + return QJSValue(); } -QScriptValue Containment::widgets(QScriptContext *context, QScriptEngine *engine) +QJSValue Containment::widgets(const QString &widgetType) const { - Containment *c = qobject_cast(context->thisObject().toQObject()); - - if (!c || !c->d->containment) { - return engine->undefinedValue(); + if (!d->containment) { + return QJSValue(); } - const QString widgetType = context->argumentCount() > 0 ? context->argument(0).toString() : QString(); - QScriptValue widgets = engine->newArray(); - ScriptEngine *env = ScriptEngine::envFor(engine); + QJSValue widgets = d->engine->newArray(); int count = 0; - foreach (Plasma::Applet *widget, c->d->containment.data()->applets()) { + foreach (Plasma::Applet *widget, d->containment.data()->applets()) { if (widgetType.isEmpty() || widget->pluginMetaData().pluginId() == widgetType) { - widgets.setProperty(count, env->wrap(widget)); + widgets.setProperty(count, d->engine->wrap(widget)); ++count; } } diff --git a/shell/scripting/i18n.h b/shell/scripting/i18n.h deleted file mode 100644 --- a/shell/scripting/i18n.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2009 Aaron Seigo - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef JAVASCRIPTBINDI18N_H -#define JAVASCRIPTBINDI18N_H - -#include - -class QScriptContext; -class QScriptEngine; - -QScriptValue jsi18n(QScriptContext *context, QScriptEngine *engine); -QScriptValue jsi18nc(QScriptContext *context, QScriptEngine *engine); -QScriptValue jsi18np(QScriptContext *context, QScriptEngine *engine); -QScriptValue jsi18ncp(QScriptContext *context, QScriptEngine *engine); -void bindI18N(QScriptEngine *engine); - -#endif - diff --git a/shell/scripting/i18n.cpp b/shell/scripting/i18n.cpp deleted file mode 100644 --- a/shell/scripting/i18n.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2009 Aaron Seigo - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "i18n.h" - -#include -#include - -#include -#include - -QScriptValue jsi18n(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine) - - if (context->argumentCount() < 1) { - // qDebug() << i18n("i18n() takes at least one argument"); - return engine->undefinedValue(); - } - - KLocalizedString message = ki18n(context->argument(0).toString().toUtf8()); - - const int numArgs = context->argumentCount(); - for (int i = 1; i < numArgs; ++i) { - message = message.subs(context->argument(i).toString()); - } - - return message.toString(); -} - -QScriptValue jsi18nc(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine) - - if (context->argumentCount() < 2) { - // qDebug() << i18n("i18nc() takes at least two arguments"); - return engine->undefinedValue(); - } - - KLocalizedString message = ki18nc(context->argument(0).toString().toUtf8(), - context->argument(1).toString().toUtf8()); - - const int numArgs = context->argumentCount(); - for (int i = 2; i < numArgs; ++i) { - message = message.subs(context->argument(i).toString()); - } - - return message.toString(); -} - -QScriptValue jsi18np(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine) - - if (context->argumentCount() < 2) { - // qDebug() << i18n("i18np() takes at least two arguments"); - return engine->undefinedValue(); - } - - KLocalizedString message = ki18np(context->argument(0).toString().toUtf8(), - context->argument(1).toString().toUtf8()); - - const int numArgs = context->argumentCount(); - for (int i = 2; i < numArgs; ++i) { - QScriptValue v = context->argument(i); - if (v.isNumber()) { - message = message.subs(v.toInt32()); - } else { - message = message.subs(v.toString()); - } - } - - return message.toString(); -} - -QScriptValue jsi18ncp(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine) - - if (context->argumentCount() < 3) { - // qDebug() << i18n("i18ncp() takes at least three arguments"); - return engine->undefinedValue(); - } - - KLocalizedString message = ki18ncp(context->argument(0).toString().toUtf8(), - context->argument(1).toString().toUtf8(), - context->argument(2).toString().toUtf8()); - - const int numArgs = context->argumentCount(); - for (int i = 3; i < numArgs; ++i) { - message = message.subs(context->argument(i).toString()); - } - - return message.toString(); -} - -void bindI18N(QScriptEngine *engine) -{ - QScriptValue global = engine->globalObject(); - global.setProperty(QStringLiteral("i18n"), engine->newFunction(jsi18n)); - global.setProperty(QStringLiteral("i18nc"), engine->newFunction(jsi18nc)); - global.setProperty(QStringLiteral("i18np"), engine->newFunction(jsi18np)); - global.setProperty(QStringLiteral("i18ncp"), engine->newFunction(jsi18ncp)); -} - diff --git a/shell/scripting/panel.h b/shell/scripting/panel.h --- a/shell/scripting/panel.h +++ b/shell/scripting/panel.h @@ -20,8 +20,7 @@ #ifndef PANEL #define PANEL -#include -#include +#include #include #include "containment.h" @@ -61,7 +60,7 @@ Q_PROPERTY(QString hiding READ hiding WRITE setHiding) public: - explicit Panel(Plasma::Containment *containment, QObject *parent = nullptr); + explicit Panel(Plasma::Containment *containment, ScriptEngine *parent); ~Panel() override; QString location() const; @@ -92,11 +91,6 @@ void remove() { Containment::remove(); } void showConfigurationInterface() { Containment::showConfigurationInterface(); } - // from the applet interface - QVariant readConfig(const QString &key, const QVariant &def = QString()) const override { return Applet::readConfig(key, def); } - void writeConfig(const QString &key, const QVariant &value) override { Applet::writeConfig(key, value); } - void reloadConfig() override { Applet::reloadConfig(); } - private: PanelView *panel() const; KConfigGroup panelConfig() const; diff --git a/shell/scripting/panel.cpp b/shell/scripting/panel.cpp --- a/shell/scripting/panel.cpp +++ b/shell/scripting/panel.cpp @@ -34,10 +34,9 @@ namespace WorkspaceScripting { -Panel::Panel(Plasma::Containment *containment, QObject *parent) - : Containment(containment, parent) +Panel::Panel(Plasma::Containment *containment, ScriptEngine *engine) + : Containment(containment, engine) { - m_corona = qobject_cast(containment->corona()); } Panel::~Panel() @@ -106,11 +105,11 @@ PanelView *Panel::panel() const { Plasma::Containment *c = containment(); - if (!c || !m_corona) { + if (!c || !corona()) { return nullptr; } - return m_corona->panelView(c); + return corona()->panelView(c); } @@ -122,7 +121,7 @@ return KConfigGroup(); } QScreen *s = QGuiApplication::screens().at(screenNum); - return PanelView::panelConfig(m_corona, containment(), s); + return PanelView::panelConfig(corona(), containment(), s); } QString Panel::alignment() const diff --git a/shell/scripting/rect.cpp b/shell/scripting/rect.cpp deleted file mode 100644 --- a/shell/scripting/rect.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2007 Richard J. Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License version 2 as - * published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include "backportglobal.h" - -Q_DECLARE_METATYPE(QRectF*) -Q_DECLARE_METATYPE(QRectF) - -static QScriptValue ctor(QScriptContext *ctx, QScriptEngine *eng) -{ - if (ctx->argumentCount() == 4) - { - qreal x = ctx->argument(0).toNumber(); - qreal y = ctx->argument(1).toNumber(); - qreal width = ctx->argument(2).toNumber(); - qreal height = ctx->argument(3).toNumber(); - return qScriptValueFromValue(eng, QRectF(x, y, width, height)); - } - - return qScriptValueFromValue(eng, QRectF()); -} - -static QScriptValue adjust(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, adjust); - qreal dx1 = ctx->argument(0).toNumber(); - qreal dy1 = ctx->argument(1).toNumber(); - qreal dx2 = ctx->argument(2).toNumber(); - qreal dy2 = ctx->argument(3).toNumber(); - - self->adjust(dx1, dy1, dx2, dy2); - return QScriptValue(); -} - -static QScriptValue adjusted(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, adjusted); - qreal dx1 = ctx->argument(0).toNumber(); - qreal dy1 = ctx->argument(1).toNumber(); - qreal dx2 = ctx->argument(2).toNumber(); - qreal dy2 = ctx->argument(3).toNumber(); - - QRectF tmp = self->adjusted(dx1, dy1, dx2, dy2); - return qScriptValueFromValue(eng, tmp); -} - -static QScriptValue bottom(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, bottom); - - if (ctx->argumentCount() > 0) { - int bottom = ctx->argument(0).toInt32(); - self->setBottom(bottom); - } - - return QScriptValue(eng, self->bottom()); -} - -static QScriptValue top(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, top); - - if (ctx->argumentCount() > 0) { - int top = ctx->argument(0).toInt32(); - self->setTop(top); - } - - return QScriptValue(eng, self->top()); -} - -static QScriptValue contains(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, contains); - qreal x = ctx->argument(0).toNumber(); - qreal y = ctx->argument(1).toNumber(); - return QScriptValue(eng, self->contains(x, y)); -} - -static QScriptValue height(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, height); - - if (ctx->argumentCount() > 0) { - int height = ctx->argument(0).toInt32(); - self->setHeight(height); - } - - return QScriptValue(eng, self->height()); -} - -static QScriptValue empty(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, empty); - return QScriptValue(eng, self->isEmpty()); -} - -static QScriptValue null(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, null); - return QScriptValue(eng, self->isNull()); -} - -static QScriptValue valid(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, valid); - return QScriptValue(eng, self->isValid()); -} - -static QScriptValue left(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, left); - - if (ctx->argumentCount() > 0) { - int left = ctx->argument(0).toInt32(); - self->setLeft(left); - } - - return QScriptValue(eng, self->left()); -} - -static QScriptValue moveBottom(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, moveBottom); - qreal bottom = ctx->argument(0).toNumber(); - self->moveBottom(bottom); - return QScriptValue(); -} - -static QScriptValue moveLeft(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, moveLeft); - qreal left = ctx->argument(0).toNumber(); - self->moveBottom(left); - return QScriptValue(); -} - -static QScriptValue moveRight(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, moveRight); - qreal right = ctx->argument(0).toNumber(); - self->moveBottom(right); - return QScriptValue(); -} - - -static QScriptValue moveTo(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, moveTo); - qreal x = ctx->argument(0).toNumber(); - qreal y = ctx->argument(1).toNumber(); - self->moveTo(x, y); - return QScriptValue(); -} - -static QScriptValue moveTop(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, moveTop); - qreal top = ctx->argument(0).toNumber(); - self->moveTop(top); - return QScriptValue(); -} - -static QScriptValue right(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, right); - - if (ctx->argumentCount() > 0) { - int right = ctx->argument(0).toInt32(); - self->setRight(right); - } - - return QScriptValue(eng, self->right()); -} - -static QScriptValue setCoords(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, setCoords); - qreal x1 = ctx->argument(0).toNumber(); - qreal y1 = ctx->argument(1).toNumber(); - qreal x2 = ctx->argument(2).toNumber(); - qreal y2 = ctx->argument(3).toNumber(); - self->setCoords(x1, y1, x2, y2); - return QScriptValue(); -} - -static QScriptValue setRect(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, setRect); - qreal x = ctx->argument(0).toNumber(); - qreal y = ctx->argument(1).toNumber(); - qreal width = ctx->argument(2).toNumber(); - qreal height = ctx->argument(3).toNumber(); - self->setRect(x, y, width, height); - return QScriptValue(); -} - -static QScriptValue translate(QScriptContext *ctx, QScriptEngine *) -{ - DECLARE_SELF(QRectF, translate); - qreal dx = ctx->argument(0).toNumber(); - qreal dy = ctx->argument(1).toNumber(); - self->translate(dx, dy); - return QScriptValue(); -} - -static QScriptValue width(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, width); - - if (ctx->argumentCount() > 0) { - int width = ctx->argument(0).toInt32(); - self->setWidth(width); - } - - return QScriptValue(eng, self->width()); -} - -static QScriptValue x(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, x); - - if (ctx->argumentCount() > 0) { - int x = ctx->argument(0).toInt32(); - self->setX(x); - } - - return QScriptValue(eng, self->x()); -} - -static QScriptValue y(QScriptContext *ctx, QScriptEngine *eng) -{ - DECLARE_SELF(QRectF, y); - - if (ctx->argumentCount() > 0) { - int y = ctx->argument(0).toInt32(); - self->setY(y); - } - - return QScriptValue(eng, self->y()); -} - -/* Not Implemented Yet */ -// QPointF bottomLeft () const -// QPointF bottomRight () const -// QPointF center () const -// bool contains ( const QPointF & point ) const -// bool contains ( const QRectF & rectangle ) const -// void getCoords ( qreal * x1, qreal * y1, qreal * x2, qreal * y2 ) const -// void getRect ( qreal * x, qreal * y, qreal * width, qreal * height ) const -// QRectF intersected ( const QRectF & rectangle ) const -// bool intersects ( const QRectF & rectangle ) const -// void moveBottomLeft ( const QPointF & position ) -// void moveBottomRight ( const QPointF & position ) -// void moveCenter ( const QPointF & position ) -// void moveTo ( const QPointF & position ) -// void moveTopLeft ( const QPointF & position ) -// void moveTopRight ( const QPointF & position ) -// QRectF normalized () const -// void setBottomLeft ( const QPointF & position ) -// void setBottomRight ( const QPointF & position ) -// void setSize ( const QSizeF & size ) -// void setTopLeft ( const QPointF & position ) -// void setTopRight ( const QPointF & position ) -// QSizeF size () const -// QRect toAlignedRect () const -// QRect toRect () const -// QPointF topLeft () const -// QPointF topRight () const -// void translate ( const QPointF & offset ) -// QRectF translated ( qreal dx, qreal dy ) const -// QRectF translated ( const QPointF & offset ) const -// QRectF united ( const QRectF & rectangle ) const - -QScriptValue constructQRectFClass(QScriptEngine *eng) -{ - QScriptValue proto = qScriptValueFromValue(eng, QRectF()); - QScriptValue::PropertyFlags getter = QScriptValue::PropertyGetter; - QScriptValue::PropertyFlags setter = QScriptValue::PropertySetter; - - proto.setProperty(QStringLiteral("adjust"), eng->newFunction(adjust)); - proto.setProperty(QStringLiteral("adjusted"), eng->newFunction(adjusted), getter); - proto.setProperty(QStringLiteral("translate"), eng->newFunction(translate)); - proto.setProperty(QStringLiteral("setCoords"), eng->newFunction(setCoords)); - proto.setProperty(QStringLiteral("setRect"), eng->newFunction(setRect)); - - proto.setProperty(QStringLiteral("contains"), eng->newFunction(contains)); - - proto.setProperty(QStringLiteral("moveBottom"), eng->newFunction(moveBottom)); - proto.setProperty(QStringLiteral("moveLeft"), eng->newFunction(moveLeft)); - proto.setProperty(QStringLiteral("moveRight"), eng->newFunction(moveRight)); - proto.setProperty(QStringLiteral("moveTo"), eng->newFunction(moveTo)); - proto.setProperty(QStringLiteral("moveTop"), eng->newFunction(moveTop)); - - proto.setProperty(QStringLiteral("empty"), eng->newFunction(empty), getter); - proto.setProperty(QStringLiteral("null"), eng->newFunction(null), getter); - proto.setProperty(QStringLiteral("valid"), eng->newFunction(valid), getter); - - proto.setProperty(QStringLiteral("left"), eng->newFunction(left), getter | setter); - proto.setProperty(QStringLiteral("top"), eng->newFunction(top), getter | setter); - proto.setProperty(QStringLiteral("bottom"), eng->newFunction(bottom), getter | setter); - proto.setProperty(QStringLiteral("right"), eng->newFunction(right), getter | setter); - proto.setProperty(QStringLiteral("height"), eng->newFunction(height), getter | setter); - proto.setProperty(QStringLiteral("width"), eng->newFunction(width), getter | setter); - proto.setProperty(QStringLiteral("x"), eng->newFunction(x), getter | setter); - proto.setProperty(QStringLiteral("y"), eng->newFunction(y), getter | setter); - - eng->setDefaultPrototype(qMetaTypeId(), proto); - eng->setDefaultPrototype(qMetaTypeId(), proto); - - return eng->newFunction(ctor, proto); -} diff --git a/shell/scripting/scriptengine.h b/shell/scripting/scriptengine.h --- a/shell/scripting/scriptengine.h +++ b/shell/scripting/scriptengine.h @@ -20,8 +20,8 @@ #ifndef SCRIPTENGINE #define SCRIPTENGINE -#include -#include +#include +#include #include @@ -35,30 +35,36 @@ class Containment; } // namespace Plasma +class KLocalizedContext; namespace WorkspaceScripting { - +class AppInterface; class Containment; +class V1; + -class ScriptEngine : public QScriptEngine +class ScriptEngine : public QJSEngine { Q_OBJECT public: explicit ScriptEngine(Plasma::Corona *corona, QObject *parent = nullptr); ~ScriptEngine() override; + QString errorString() const; + static QStringList pendingUpdateScripts(Plasma::Corona *corona); Plasma::Corona *corona() const; - QScriptValue wrap(Plasma::Applet *w); - virtual QScriptValue wrap(Plasma::Containment *c); - QScriptValue wrap(Containment *c); + QJSValue wrap(Plasma::Applet *w); + QJSValue wrap(Plasma::Containment *c); virtual int defaultPanelScreen() const; + QJSValue newError(const QString &message); static bool isPanel(const Plasma::Containment *c); - static ScriptEngine *envFor(QScriptEngine *engine); + + Plasma::Containment *createContainment(const QString &type, const QString &plugin); public Q_SLOTS: bool evaluateScript(const QString &script, const QString &path = QString()); @@ -71,24 +77,24 @@ void setupEngine(); static QString onlyExec(const QString &commandLine); - static QScriptValue createAPIForVersion(QScriptContext *context, QScriptEngine *engine); - // Script API versions class V1; // helpers QStringList availableActivities() const; QList desktopsForActivity(const QString &id); - Containment *createContainment(const QString &type, const QString &plugin); - - static int gridUnit(); + Containment *createContainmentWrapper(const QString &type, const QString &plugin); private Q_SLOTS: - void exception(const QScriptValue &value); + void exception(const QJSValue &value); private: Plasma::Corona *m_corona; - QScriptValue m_scriptSelf; + ScriptEngine::V1 *m_globalScriptEngineObject; + KLocalizedContext *m_localizedContext; + AppInterface *m_appInterface; + QJSValue m_scriptSelf; + QString m_errorString; }; static const int PLASMA_DESKTOP_SCRIPTING_VERSION = 20; diff --git a/shell/scripting/scriptengine.cpp b/shell/scripting/scriptengine.cpp --- a/shell/scripting/scriptengine.cpp +++ b/shell/scripting/scriptengine.cpp @@ -24,15 +24,16 @@ #include #include #include -#include +#include #include #include #include #include #include #include #include +#include // KIO //#include // no camelcase include @@ -47,81 +48,57 @@ #include "appinterface.h" #include "containment.h" #include "configgroup.h" -#include "i18n.h" #include "panel.h" #include "widget.h" #include "../shellcorona.h" #include "../standaloneappcorona.h" #include "../screenpool.h" -QScriptValue constructQRectFClass(QScriptEngine *engine); - namespace WorkspaceScripting { ScriptEngine::ScriptEngine(Plasma::Corona *corona, QObject *parent) - : QScriptEngine(parent), + : QJSEngine(parent), m_corona(corona) { Q_ASSERT(m_corona); - AppInterface *interface = new AppInterface(this); - connect(interface, &AppInterface::print, this, &ScriptEngine::print); - m_scriptSelf = newQObject(interface, QScriptEngine::QtOwnership, - QScriptEngine::ExcludeSuperClassProperties | - QScriptEngine::ExcludeSuperClassMethods); + m_appInterface = new AppInterface(this); + connect(m_appInterface, &AppInterface::print, this, &ScriptEngine::print); + m_scriptSelf = globalObject(); + m_globalScriptEngineObject = new ScriptEngine::V1(this); + m_localizedContext = new KLocalizedContext(this); setupEngine(); - connect(this, &ScriptEngine::signalHandlerException, this, &ScriptEngine::exception); - bindI18N(this); } ScriptEngine::~ScriptEngine() { } -QScriptValue ScriptEngine::wrap(Plasma::Applet *w) +QString ScriptEngine::errorString() const { - Widget *wrapper = new Widget(w); - QScriptValue v = newQObject(wrapper, QScriptEngine::ScriptOwnership, - QScriptEngine::ExcludeSuperClassProperties | - QScriptEngine::ExcludeSuperClassMethods); - return v; + return m_errorString; } -QScriptValue ScriptEngine::wrap(Plasma::Containment *c) +QJSValue ScriptEngine::wrap(Plasma::Applet *w) { - Containment *wrapper = isPanel(c) ? new Panel(c) : new Containment(c); - return wrap(wrapper); + Widget *wrapper = new Widget(w); + return newQObject(wrapper); } -QScriptValue ScriptEngine::wrap(Containment *c) +QJSValue ScriptEngine::wrap(Plasma::Containment *c) { - QScriptValue v = newQObject(c, QScriptEngine::ScriptOwnership, - QScriptEngine::ExcludeSuperClassProperties | - QScriptEngine::ExcludeSuperClassMethods); - v.setProperty(QStringLiteral("widgetById"), newFunction(Containment::widgetById)); - v.setProperty(QStringLiteral("addWidget"), newFunction(Containment::addWidget)); - v.setProperty(QStringLiteral("widgets"), newFunction(Containment::widgets)); - - return v; + Containment *wrapper = isPanel(c) ? new Panel(c, this) : new Containment(c, this); + return newQObject(wrapper); } int ScriptEngine::defaultPanelScreen() const { - return 0; + return 1; } -ScriptEngine *ScriptEngine::envFor(QScriptEngine *engine) +QJSValue ScriptEngine::newError(const QString &message) { - QObject *object = engine->globalObject().toQObject(); - Q_ASSERT(object); - - AppInterface *interface = qobject_cast(object); - Q_ASSERT(interface); - - ScriptEngine *env = qobject_cast(interface->parent()); - Q_ASSERT(env); - - return env; + return evaluate(QString("new Error('%1');").arg(message)); } QString ScriptEngine::onlyExec(const QString &commandLine) @@ -135,61 +112,134 @@ void ScriptEngine::setupEngine() { - QScriptValue v = globalObject(); - QScriptValueIterator it(v); - while (it.hasNext()) { - it.next(); - // we provide our own print implementation, but we want the rest - if (it.name() != QLatin1String("print")) { - m_scriptSelf.setProperty(it.name(), it.value()); - } - } - - m_scriptSelf.setProperty(QStringLiteral("getApiVersion"), newFunction(ScriptEngine::createAPIForVersion)); - - m_scriptSelf.setProperty(QStringLiteral("QRectF"), constructQRectFClass(this)); - m_scriptSelf.setProperty(QStringLiteral("createActivity"), newFunction(ScriptEngine::V1::createActivity)); - m_scriptSelf.setProperty(QStringLiteral("setCurrentActivity"), newFunction(ScriptEngine::V1::setCurrentActivity)); - m_scriptSelf.setProperty(QStringLiteral("currentActivity"), newFunction(ScriptEngine::V1::currentActivity)); - m_scriptSelf.setProperty(QStringLiteral("activities"), newFunction(ScriptEngine::V1::activities)); - m_scriptSelf.setProperty(QStringLiteral("activityName"), newFunction(ScriptEngine::V1::activityName)); - m_scriptSelf.setProperty(QStringLiteral("setActivityName"), newFunction(ScriptEngine::V1::setActivityName)); - m_scriptSelf.setProperty(QStringLiteral("loadSerializedLayout"), newFunction(ScriptEngine::V1::loadSerializedLayout)); - m_scriptSelf.setProperty(QStringLiteral("Panel"), newFunction(ScriptEngine::V1::newPanel, newObject())); - m_scriptSelf.setProperty(QStringLiteral("desktopsForActivity"), newFunction(ScriptEngine::V1::desktopsForActivity)); - m_scriptSelf.setProperty(QStringLiteral("desktops"), newFunction(ScriptEngine::V1::desktops)); - m_scriptSelf.setProperty(QStringLiteral("desktopById"), newFunction(ScriptEngine::V1::desktopById)); - m_scriptSelf.setProperty(QStringLiteral("desktopForScreen"), newFunction(ScriptEngine::V1::desktopForScreen)); - m_scriptSelf.setProperty(QStringLiteral("panelById"), newFunction(ScriptEngine::V1::panelById)); - m_scriptSelf.setProperty(QStringLiteral("panels"), newFunction(ScriptEngine::V1::panels)); - m_scriptSelf.setProperty(QStringLiteral("fileExists"), newFunction(ScriptEngine::V1::fileExists)); - m_scriptSelf.setProperty(QStringLiteral("loadTemplate"), newFunction(ScriptEngine::V1::loadTemplate)); - m_scriptSelf.setProperty(QStringLiteral("applicationExists"), newFunction(ScriptEngine::V1::applicationExists)); - m_scriptSelf.setProperty(QStringLiteral("defaultApplication"), newFunction(ScriptEngine::V1::defaultApplication)); - m_scriptSelf.setProperty(QStringLiteral("userDataPath"), newFunction(ScriptEngine::V1::userDataPath)); - m_scriptSelf.setProperty(QStringLiteral("applicationPath"), newFunction(ScriptEngine::V1::applicationPath)); - m_scriptSelf.setProperty(QStringLiteral("knownWallpaperPlugins"), newFunction(ScriptEngine::V1::knownWallpaperPlugins)); - m_scriptSelf.setProperty(QStringLiteral("ConfigFile"), newFunction(ScriptEngine::V1::configFile)); - m_scriptSelf.setProperty(QStringLiteral("gridUnit"), newFunction(ScriptEngine::V1::gridUnit), QScriptValue::PropertyGetter); - m_scriptSelf.setProperty(QStringLiteral("setImmutability"), newFunction(ScriptEngine::V1::setImmutability)); - m_scriptSelf.setProperty(QStringLiteral("immutability"), newFunction(ScriptEngine::V1::immutability)); - - setGlobalObject(m_scriptSelf); -} - -QScriptValue ScriptEngine::createAPIForVersion(QScriptContext *context, QScriptEngine *engine) -{ - if (context->argumentCount() < 1) { - return context->throwError(i18n("getApiVersion() needs you to specify the version")); - } - - const uint version = context->argument(0).toInt32(); - - if (version != 1) { - return context->throwError(i18n("getApiVersion() invalid version number")); - } - - return envFor(engine)->m_scriptSelf; + QJSValue globalScriptEngineObject = newQObject(m_globalScriptEngineObject); + QJSValue localizedContext = newQObject(m_localizedContext); + QJSValue appInterface = newQObject(m_appInterface); + + + + + //AppInterface stuff + //FIXME: this line doesn't have much effect for now, if QTBUG-68397 gets fixed, + //all the connects to rewrite the properties won't be necessary anymore + //globalObject().setPrototype(appInterface); + //FIXME: remove __AppInterface if QTBUG-68397 gets solved + //as workaround we build manually a js object with getters and setters + m_scriptSelf.setProperty(QStringLiteral("__AppInterface"), appInterface); + QJSValue res = evaluate("__proto__ = {\ + get locked() {return __AppInterface.locked;},\ + get hasBattery() {return __AppInterface.hasBattery;},\ + get screenCount() {return __AppInterface.screenCount;},\ + get activityIds() {return __AppInterface.activityIds;},\ + get panelIds() {return __AppInterface.panelIds;},\ + get knownPanelTypes() {return __AppInterface.knownPanelTypes;},\ + get knownActivityTypes() {return __AppInterface.knownActivityTypes;},\ + get knownWidgetTypes() {return __AppInterface.knownWidgetTypes;},\ + get theme() {return __AppInterface.theme;},\ + set theme(name) {__AppInterface.theme = name;},\ + get applicationVersion() {return __AppInterface.applicationVersion;},\ + get platformVersion() {return __AppInterface.platformVersion;},\ + get scriptingVersion() {return __AppInterface.scriptingVersion;},\ + get multihead() {return __AppInterface.multihead;},\ + get multiheadScreen() {return __AppInterface.multihead;},\ + get locale() {return __AppInterface.locale;},\ + get language() {return __AppInterface.language;},\ + get languageId() {return __AppInterface.languageId;},\ + }"); + Q_ASSERT(!res.isError()); + //methods from AppInterface + m_scriptSelf.setProperty(QStringLiteral("screenGeometry"), appInterface.property("screenGeometry")); + m_scriptSelf.setProperty(QStringLiteral("lockCorona"), appInterface.property("lockCorona")); + m_scriptSelf.setProperty(QStringLiteral("sleep"), appInterface.property("sleep")); + m_scriptSelf.setProperty(QStringLiteral("print"), appInterface.property("print")); + + + m_scriptSelf.setProperty(QStringLiteral("getApiVersion"), globalScriptEngineObject.property("getApiVersion")); + + //Constructors: prefer them js based as they make the c++ code of panel et al way simpler without hacks to get the engine + m_scriptSelf.setProperty(QStringLiteral("__newPanel"), globalScriptEngineObject.property("newPanel")); + m_scriptSelf.setProperty(QStringLiteral("__newConfigFile"), globalScriptEngineObject.property("configFile")); + //definitions of qrectf properties from documentation + //only properties/functions which were already binded are. + //TODO KF6: just a plain QRectF binding + res = evaluate("function QRectF(x,y,w,h) {\ + return {x: x, y: y, width: w, height: h,\ + get left() {return this.x},\ + get top() {return this.y},\ + get right() {return this.x + this.width},\ + get bottom() {return this.y + this.height},\ + get empty() {return this.width <= 0 || this.height <= 0},\ + get null() {return this.width == 0 || this.height == 0},\ + get valid() {return !this.empty},\ + adjust: function(dx1, dy1, dx2, dy2) {\ + this.x += dx1; this.y += dy1;\ + this.width = this.width - dx1 + dx2;\ + this.height = this.height - dy1 + dy2;},\ + adjusted: function(dx1, dy1, dx2, dy2) {\ + return new QRectF(this.x + dx1, this.y + dy1,\ + this.width - dx1 + dx2,\ + this.height - dy1 + dy2)},\ + translate: function(dx, dy) {this.x += dx; this.y += dy;},\ + setCoords: function(x1, y1, x2, y2) {\ + this.x = x1; this.y = y1;\ + this.width = x2 - x1;\ + this.height = y2 - y1;},\ + setRect: function(x1, y1, w1, h1) {\ + this.x = x1; this.y = y1;\ + this.width = w1; this.height = h1;},\ + contains: function(x1, y1) { return x1 >= this.x && x1 <= this.x + this.width && y1 >= this.y && y1 <= this.y + this.height},\ + moveBottom: function(bottom1) {this.y = bottom1 - this.height;},\ + moveLeft: function(left1) {this.x = left1;},\ + moveRight: function(right1) {this.x = right1 - this.width;},\ + moveTop: function(top1) {this.y = top1;},\ + moveTo: function(x1, y1) {this.x = x1; this.y = y1;}\ + }};\ + function ConfigFile(config, group){return __newConfigFile(config, group)};\ + function Panel(plugin){return __newPanel(plugin)};"); + Q_ASSERT(!res.isError()); + + m_scriptSelf.setProperty(QStringLiteral("createActivity"), globalScriptEngineObject.property("createActivity")); + m_scriptSelf.setProperty(QStringLiteral("setCurrentActivity"), globalScriptEngineObject.property("setCurrentActivity")); + m_scriptSelf.setProperty(QStringLiteral("currentActivity"), globalScriptEngineObject.property("currentActivity")); + m_scriptSelf.setProperty(QStringLiteral("activities"), globalScriptEngineObject.property("activities")); + m_scriptSelf.setProperty(QStringLiteral("activityName"), globalScriptEngineObject.property("activityName")); + m_scriptSelf.setProperty(QStringLiteral("setActivityName"), globalScriptEngineObject.property("setActivityName")); + m_scriptSelf.setProperty(QStringLiteral("loadSerializedLayout"), globalScriptEngineObject.property("loadSerializedLayout")); + m_scriptSelf.setProperty(QStringLiteral("desktopsForActivity"), globalScriptEngineObject.property("desktopsForActivity")); + m_scriptSelf.setProperty(QStringLiteral("desktops"), globalScriptEngineObject.property("desktops")); + m_scriptSelf.setProperty(QStringLiteral("desktopById"), globalScriptEngineObject.property("desktopById")); + m_scriptSelf.setProperty(QStringLiteral("desktopForScreen"), globalScriptEngineObject.property("desktopForScreen")); + m_scriptSelf.setProperty(QStringLiteral("panelById"), globalScriptEngineObject.property("panelById")); + m_scriptSelf.setProperty(QStringLiteral("panels"), globalScriptEngineObject.property("panels")); + m_scriptSelf.setProperty(QStringLiteral("fileExists"), globalScriptEngineObject.property("fileExists")); + m_scriptSelf.setProperty(QStringLiteral("loadTemplate"), globalScriptEngineObject.property("loadTemplate")); + m_scriptSelf.setProperty(QStringLiteral("applicationExists"), globalScriptEngineObject.property("applicationExists")); + m_scriptSelf.setProperty(QStringLiteral("defaultApplication"), globalScriptEngineObject.property("defaultApplication")); + m_scriptSelf.setProperty(QStringLiteral("userDataPath"), globalScriptEngineObject.property("userDataPath")); + m_scriptSelf.setProperty(QStringLiteral("applicationPath"), globalScriptEngineObject.property("applicationPath")); + m_scriptSelf.setProperty(QStringLiteral("knownWallpaperPlugins"), globalScriptEngineObject.property("knownWallpaperPlugins")); + m_scriptSelf.setProperty(QStringLiteral("gridUnit"), globalScriptEngineObject.property("gridUnit")); + m_scriptSelf.setProperty(QStringLiteral("setImmutability"), globalScriptEngineObject.property("setImmutability")); + m_scriptSelf.setProperty(QStringLiteral("immutability"), globalScriptEngineObject.property("immutability")); + + //i18n + m_scriptSelf.setProperty(QStringLiteral("i18n"), localizedContext.property("i18n")); + m_scriptSelf.setProperty(QStringLiteral("i18nc"), localizedContext.property("i18nc")); + m_scriptSelf.setProperty(QStringLiteral("i18np"), localizedContext.property("i18np")); + m_scriptSelf.setProperty(QStringLiteral("i18ncp"), localizedContext.property("i18ncp")); + m_scriptSelf.setProperty(QStringLiteral("i18nd"), localizedContext.property("i18nd")); + m_scriptSelf.setProperty(QStringLiteral("i18ndc"), localizedContext.property("i18ndc")); + m_scriptSelf.setProperty(QStringLiteral("i18ndp"), localizedContext.property("i18ndp")); + m_scriptSelf.setProperty(QStringLiteral("i18ndcp"), localizedContext.property("i18ndcp")); + + m_scriptSelf.setProperty(QStringLiteral("xi18n"), localizedContext.property("xi18n")); + m_scriptSelf.setProperty(QStringLiteral("xi18nc"), localizedContext.property("xi18nc")); + m_scriptSelf.setProperty(QStringLiteral("xi18np"), localizedContext.property("xi18np")); + m_scriptSelf.setProperty(QStringLiteral("xi18ncp"), localizedContext.property("xi18ncp")); + m_scriptSelf.setProperty(QStringLiteral("xi18nd"), localizedContext.property("xi18nd")); + m_scriptSelf.setProperty(QStringLiteral("xi18ndc"), localizedContext.property("xi18ndc")); + m_scriptSelf.setProperty(QStringLiteral("xi18ndp"), localizedContext.property("xi18ndp")); + m_scriptSelf.setProperty(QStringLiteral("xi18ndcp"), localizedContext.property("xi18ndcp")); } bool ScriptEngine::isPanel(const Plasma::Containment *c) @@ -209,22 +259,25 @@ bool ScriptEngine::evaluateScript(const QString &script, const QString &path) { - //qDebug() << "evaluating" << m_editor->toPlainText(); - evaluate(script, path); - if (hasUncaughtException()) { + m_errorString = QString(); + + QJSValue result = evaluate(script, path); + if (result.isError()) { //qDebug() << "catch the exception!"; QString error = i18n("Error: %1 at line %2\n\nBacktrace:\n%3", - uncaughtException().toString(), - QString::number(uncaughtExceptionLineNumber()), - uncaughtExceptionBacktrace().join(QStringLiteral("\n "))); + result.toString(), + result.property("lineNumber").toInt(), + result.property("stack").toVariant().value().join(QStringLiteral("\n "))); emit printError(error); + emit exception(result); + m_errorString = error; return false; } return true; } -void ScriptEngine::exception(const QScriptValue &value) +void ScriptEngine::exception(const QJSValue &value) { //qDebug() << "exception caught!" << value.toVariant(); emit printError(value.toVariant().toString()); @@ -309,7 +362,7 @@ foreach (Plasma::Containment *c, m_corona->containments()) { if (c->activity() == id && !isPanel(c)) { - result << new Containment(c); + result << new Containment(c, this); } } @@ -322,30 +375,20 @@ StandaloneAppCorona *ac = qobject_cast(m_corona); if (sc) { foreach (int i, sc->screenIds()) { - result << new Containment(sc->createContainmentForActivity(id, i)); + result << new Containment(sc->createContainmentForActivity(id, i), this); } } else if (ac) { const int numScreens = m_corona->numScreens(); for (int i = 0; i < numScreens; ++i) { - result << new Containment(ac->createContainmentForActivity(id, i)); + result << new Containment(ac->createContainmentForActivity(id, i), this); } } } return result; } -int ScriptEngine::gridUnit() -{ - int gridUnit = QFontMetrics(QGuiApplication::font()).boundingRect(QStringLiteral("M")).height(); - if (gridUnit % 2 != 0) { - gridUnit++; - } - - return gridUnit; -} - -Containment *ScriptEngine::createContainment(const QString &type, const QString &plugin) +Plasma::Containment *ScriptEngine::createContainment(const QString &type, const QString &plugin) { bool exists = false; const KPluginInfo::List list = Plasma::PluginLoader::listContainmentsOfType(type); @@ -390,7 +433,13 @@ c->flushPendingConstraintsEvents(); } - return isPanel(c) ? new Panel(c) : new Containment(c); + return c; +} + +Containment *ScriptEngine::createContainmentWrapper(const QString &type, const QString &plugin) +{ + Plasma::Containment *c = createContainment(type, plugin); + return isPanel(c) ? new Panel(c, this) : new Containment(c, this); } } // namespace WorkspaceScripting diff --git a/shell/scripting/scriptengine_v1.h b/shell/scripting/scriptengine_v1.h --- a/shell/scripting/scriptengine_v1.h +++ b/shell/scripting/scriptengine_v1.h @@ -1,5 +1,6 @@ /* * Copyright 2009 Aaron Seigo + * Copyright 2018 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -20,8 +21,8 @@ #ifndef SCRIPTENGINE_V1 #define SCRIPTENGINE_V1 -#include -#include +#include +#include #include @@ -33,35 +34,49 @@ namespace WorkspaceScripting { -class ScriptEngine::V1 { +class ScriptEngine::V1 : public QObject { + Q_OBJECT + Q_PROPERTY(int gridUnit READ gridUnit CONSTANT) + public: - static QScriptValue createActivity(QScriptContext *context, QScriptEngine *engine); - static QScriptValue setCurrentActivity(QScriptContext *context, QScriptEngine *engine); - static QScriptValue currentActivity(QScriptContext *controller, QScriptEngine *engine); - static QScriptValue activities(QScriptContext *context, QScriptEngine *engine); - static QScriptValue setActivityName(QScriptContext *context, QScriptEngine *engine); - static QScriptValue activityName(QScriptContext *context, QScriptEngine *engine); - static QScriptValue loadSerializedLayout(QScriptContext *context, QScriptEngine *engine); - static QScriptValue newPanel(QScriptContext *context, QScriptEngine *engine); - static QScriptValue desktopsForActivity(QScriptContext *context, QScriptEngine *engine); - static QScriptValue desktops(QScriptContext *context, QScriptEngine *engine); - static QScriptValue desktopById(QScriptContext *context, QScriptEngine *engine); - static QScriptValue desktopForScreen(QScriptContext *context, QScriptEngine *engine); - static QScriptValue panelById(QScriptContext *context, QScriptEngine *engine); - static QScriptValue panels(QScriptContext *context, QScriptEngine *engine); - static QScriptValue fileExists(QScriptContext *context, QScriptEngine *engine); - static QScriptValue loadTemplate(QScriptContext *context, QScriptEngine *engine); - static QScriptValue applicationExists(QScriptContext *context, QScriptEngine *engine); - static QScriptValue defaultApplication(QScriptContext *context, QScriptEngine *engine); - static QScriptValue applicationPath(QScriptContext *context, QScriptEngine *engine); - static QScriptValue userDataPath(QScriptContext *context, QScriptEngine *engine); - static QScriptValue knownWallpaperPlugins(QScriptContext *context, QScriptEngine *engine); - static QScriptValue configFile(QScriptContext *context, QScriptEngine *engine); - static QScriptValue gridUnit(QScriptContext *context, QScriptEngine *engine); - static QScriptValue createContainment(const QString &type, const QString &defautPlugin, - QScriptContext *context, QScriptEngine *engine); - static QScriptValue setImmutability(QScriptContext *context, QScriptEngine *engine); - static QScriptValue immutability(QScriptContext *context, QScriptEngine *engine); + V1(ScriptEngine *parent); + ~V1(); + int gridUnit() const; + + Q_INVOKABLE QJSValue getApiVersion(const QJSValue ¶m); + Q_INVOKABLE QJSValue desktopById(const QJSValue &id = QJSValue()) const; + Q_INVOKABLE QJSValue desktopsForActivity(const QJSValue &id = QJSValue()) const; + Q_INVOKABLE QJSValue desktopForScreen(const QJSValue &screen = QJSValue()) const; + Q_INVOKABLE QJSValue createActivity(const QJSValue &nameParam = QJSValue(), const QString &plugin = QString()); + Q_INVOKABLE QJSValue setCurrentActivity(const QJSValue &id = QJSValue()); + Q_INVOKABLE QJSValue setActivityName(const QJSValue &idParam = QJSValue(), const QJSValue &nameParam = QJSValue()); + Q_INVOKABLE QJSValue activityName(const QJSValue &idParam = QJSValue()) const; + Q_INVOKABLE QString currentActivity() const; + Q_INVOKABLE QJSValue activities() const; + Q_INVOKABLE QJSValue loadSerializedLayout(const QJSValue &data = QJSValue()); + Q_INVOKABLE QJSValue panelById(const QJSValue &idParam = QJSValue()) const; + Q_INVOKABLE QJSValue desktops() const; + Q_INVOKABLE QJSValue panels() const; + Q_INVOKABLE bool fileExists(const QString &path = QString()) const; + Q_INVOKABLE bool loadTemplate(const QString &layout = QString()); + Q_INVOKABLE bool applicationExists(const QString &application = QString()) const; + Q_INVOKABLE QJSValue defaultApplication(const QString &application = QString(), bool storageId = false) const; + Q_INVOKABLE QJSValue applicationPath(const QString &application = QString()) const; + Q_INVOKABLE QJSValue userDataPath(const QString &type = QString(), const QString &path = QString()) const; + Q_INVOKABLE QJSValue knownWallpaperPlugins(const QString &formFactor = QString()) const; + + Q_INVOKABLE void setImmutability(const QString &immutability = QString()); + Q_INVOKABLE QString immutability() const; + Q_INVOKABLE QJSValue createContainment(const QString &type, const QString &defautPlugin, const QString &plugin = QString()); + + //for ctors + Q_INVOKABLE QJSValue newPanel(const QString &plugin = QStringLiteral("org.kde.panel")); + Q_INVOKABLE QJSValue configFile(const QJSValue &config = QJSValue(), const QString &group = QString()); + +Q_SIGNALS: + void print(const QJSValue ¶m); +private: + ScriptEngine *m_engine; }; } diff --git a/shell/scripting/scriptengine_v1.cpp b/shell/scripting/scriptengine_v1.cpp --- a/shell/scripting/scriptengine_v1.cpp +++ b/shell/scripting/scriptengine_v1.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -46,7 +46,6 @@ #include "appinterface.h" #include "containment.h" #include "configgroup.h" -#include "i18n.h" #include "panel.h" #include "widget.h" #include "../shellcorona.h" @@ -64,7 +63,7 @@ class ScriptArray_forEach_Helper { public: - ScriptArray_forEach_Helper(const QScriptValue &array) + ScriptArray_forEach_Helper(const QJSValue &array) : array(array) { } @@ -76,22 +75,22 @@ { if (!array.isArray()) return; - int length = array.property("length").toInteger(); + int length = array.property("length").toInt(); for (int i = 0; i < length; ++i) { function(array.property(i)); } } private: - const QScriptValue &array; + const QJSValue &array; }; #define SCRIPT_ARRAY_FOREACH(Variable, Array) \ - ScriptArray_forEach_Helper(Array) + [&] (const QScriptValue &Variable) + ScriptArray_forEach_Helper(Array) + [&] (const QJSValue &Variable) class ScriptObject_forEach_Helper { public: - ScriptObject_forEach_Helper(const QScriptValue &object) + ScriptObject_forEach_Helper(const QJSValue &object) : object(object) { } @@ -101,19 +100,19 @@ template void operator+ (Function function) const { - QScriptValueIterator it(object); + QJSValueIterator it(object); while (it.hasNext()) { it.next(); function(it.name(), it.value()); } } private: - const QScriptValue &object; + const QJSValue &object; }; #define SCRIPT_OBJECT_FOREACH(Key, Value, Array) \ - ScriptObject_forEach_Helper(Array) + [&] (const QString &Key, const QScriptValue &Value) + ScriptObject_forEach_Helper(Array) + [&] (const QString &Key, const QJSValue &Value) // Case insensitive comparison of two strings template @@ -126,68 +125,91 @@ namespace WorkspaceScripting { -QScriptValue ScriptEngine::V1::desktopById(QScriptContext *context, QScriptEngine *engine) +ScriptEngine::V1::V1(ScriptEngine *parent) + : QObject(parent), + m_engine(parent) +{} + +ScriptEngine::V1::~V1() +{} + +QJSValue ScriptEngine::V1::getApiVersion(const QJSValue ¶m) +{ + if (param.toInt() != 1) { + return m_engine->newError(i18n("maximum api version supported is 1")); + } + return m_engine->newQObject(this); +} + +int ScriptEngine::V1::gridUnit() const { - if (context->argumentCount() == 0) { - return context->throwError(i18n("desktopById requires an id")); + int gridUnit = QFontMetrics(QGuiApplication::font()).boundingRect(QStringLiteral("M")).height(); + if (gridUnit % 2 != 0) { + gridUnit++; } - const uint id = context->argument(0).toInt32(); - ScriptEngine *env = envFor(engine); - foreach (Plasma::Containment *c, env->m_corona->containments()) { + return gridUnit; +} + +QJSValue ScriptEngine::V1::desktopById(const QJSValue ¶m) const +{ + //this needs to work also for string of numberls, like "20" + if (param.isUndefined()) { + return m_engine->newError(i18n("desktopById required an id")); + } + + const quint32 id = param.toInt(); + + foreach (Plasma::Containment *c, m_engine->m_corona->containments()) { if (c->id() == id && !isPanel(c)) { - return env->wrap(c); + return m_engine->wrap(c); } } - return engine->undefinedValue(); + return QJSValue(); } -QScriptValue ScriptEngine::V1::desktopsForActivity(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::desktopsForActivity(const QJSValue &actId) const { - if (context->argumentCount() == 0) { - return context->throwError(i18n("desktopsForActivity requires an id")); + if (!actId.isString()) { + return m_engine->newError(i18n("desktopsForActivity requires an id")); } - QScriptValue containments = engine->newArray(); + QJSValue containments = m_engine->newArray(); int count = 0; - const QString id = context->argument(0).toString(); + const QString id = actId.toString(); - ScriptEngine *env = envFor(engine); - - const auto result = env->desktopsForActivity(id); + const auto result = m_engine->desktopsForActivity(id); for (Containment* c: result) { - containments.setProperty(count, env->wrap(c)); + containments.setProperty(count, m_engine->newQObject(c)); ++count; } containments.setProperty(QStringLiteral("length"), count); return containments; } -QScriptValue ScriptEngine::V1::desktopForScreen(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::desktopForScreen(const QJSValue ¶m) const { - if (context->argumentCount() == 0) { - return context->throwError(i18n("activityForScreen requires a screen id")); + //this needs to work also for string of numberls, like "20" + if (param.isUndefined()) { + return m_engine->newError(i18n("activityForScreen requires a screen id")); } - const uint screen = context->argument(0).toInt32(); - ScriptEngine *env = envFor(engine); - return env->wrap(env->m_corona->containmentForScreen(screen)); + const uint screen = param.toInt(); + return m_engine->wrap(m_engine->m_corona->containmentForScreen(screen)); } -QScriptValue ScriptEngine::V1::createActivity(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::createActivity(const QJSValue &nameParam, const QString &pluginParam) { - if (context->argumentCount() < 0) { - return context->throwError(i18n("createActivity required the activity name")); + if (!nameParam.isString()) { + return m_engine->newError(i18n("createActivity required the activity name")); } - const QString name = context->argument(0).toString(); - QString plugin = context->argument(1).toString(); - - ScriptEngine *env = envFor(engine); + QString plugin = pluginParam; + const QString name = nameParam.toString(); KActivities::Controller controller; @@ -200,95 +222,95 @@ qDebug() << "Setting default Containment plugin:" << plugin; - ShellCorona *sc = qobject_cast(env->m_corona); - StandaloneAppCorona *ac = qobject_cast(env->m_corona); + ShellCorona *sc = qobject_cast(m_engine->m_corona); + StandaloneAppCorona *ac = qobject_cast(m_engine->m_corona); if (sc) { if (plugin.isEmpty() || plugin == QLatin1String("undefined")) { plugin = sc->defaultContainmentPlugin(); } sc->insertActivity(id, plugin); } else if (ac) { if (plugin.isEmpty() || plugin == QLatin1String("undefined")) { - KConfigGroup shellCfg = KConfigGroup(KSharedConfig::openConfig(env->m_corona->package().filePath("defaults")), "Desktop"); + KConfigGroup shellCfg = KConfigGroup(KSharedConfig::openConfig(m_engine->m_corona->package().filePath("defaults")), "Desktop"); plugin = shellCfg.readEntry("Containment", "org.kde.desktopcontainment"); } ac->insertActivity(id, plugin); } - return QScriptValue(id); + return m_engine->toScriptValue(id); } -QScriptValue ScriptEngine::V1::setCurrentActivity(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::setCurrentActivity(const QJSValue ¶m) { - Q_UNUSED(engine) - - if (context->argumentCount() < 0) { - return context->throwError(i18n("setCurrentActivity required the activity id")); + if (!param.isString()) { + return m_engine->newError(i18n("setCurrentActivity required the activity id")); } - const QString id = context->argument(0).toString(); + const QString id = param.toString(); KActivities::Controller controller; QFuture task = controller.setCurrentActivity(id); awaitFuture(task); - return QScriptValue(task.result()); + return task.result(); } -QScriptValue ScriptEngine::V1::setActivityName(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::setActivityName(const QJSValue &idParam, const QJSValue &nameParam) { - Q_UNUSED(engine) - - if (context->argumentCount() < 2) { - return context->throwError(i18n("setActivityName required the activity id and name")); + if (!idParam.isString() || !nameParam.isString()) { + return m_engine->newError(i18n("setActivityName required the activity id and name")); } - const QString id = context->argument(0).toString(); - const QString name = context->argument(1).toString(); + + const QString id = idParam.toString(); + const QString name = nameParam.toString(); KActivities::Controller controller; QFuture task = controller.setActivityName(id, name); awaitFuture(task); - - return QScriptValue(); + return QJSValue(); } -QScriptValue ScriptEngine::V1::activityName(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::activityName(const QJSValue &idParam) const { - Q_UNUSED(engine) - - if (context->argumentCount() < 1) { - return context->throwError(i18n("setActivityName required the activity id and name")); + if (!idParam.isString()) { + return m_engine->newError(i18n("activityName required the activity id")); } - const QString id = context->argument(0).toString(); + const QString id = idParam.toString(); KActivities::Info info(id); - return QScriptValue(info.name()); + return QJSValue(info.name()); } -QScriptValue ScriptEngine::V1::currentActivity(QScriptContext *context, QScriptEngine *engine) +QString ScriptEngine::V1::currentActivity() const { - Q_UNUSED(engine) - Q_UNUSED(context) - KActivities::Consumer consumer; return consumer.currentActivity(); } -QScriptValue ScriptEngine::V1::activities(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::activities() const { - Q_UNUSED(context) + QJSValue acts = m_engine->newArray(); + int count = 0; + + const auto result = m_engine->availableActivities(); + + for (const auto a : result) { + acts.setProperty(count, a); + ++count; + } + acts.setProperty(QStringLiteral("length"), count); - return qScriptValueFromSequence(engine, envFor(engine)->availableActivities()); + return acts; } // Utility function to process configs and config groups template -void loadSerializedConfigs(Object *object, const QScriptValue &configs) +void loadSerializedConfigs(Object *object, const QJSValue &configs) { SCRIPT_OBJECT_FOREACH(escapedGroup, config, configs) { // If the config group is set, pass it on to the containment @@ -306,23 +328,17 @@ }; } -QScriptValue ScriptEngine::V1::loadSerializedLayout(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::loadSerializedLayout(const QJSValue &data) { - Q_UNUSED(engine) - - if (context->argumentCount() < 1) { - return context->throwError(i18n("loadSerializedLayout requires the JSON object to deserialize from")); + if (!data.isObject()) { + return m_engine->newError(i18n("loadSerializedLayout requires the JSON object to deserialize from")); } - ScriptEngine *env = envFor(engine); - - const auto data = context->argument(0); - - if (data.property("serializationFormatVersion").toInteger() != 1) { - return context->throwError(i18n("loadSerializedLayout: invalid version of the serialized object")); + if (data.property("serializationFormatVersion").toInt() != 1) { + return m_engine->newError(i18n("loadSerializedLayout: invalid version of the serialized object")); } - const auto desktops = env->desktopsForActivity(KActivities::Consumer().currentActivity()); + const auto desktops = m_engine->desktopsForActivity(KActivities::Consumer().currentActivity()); Q_ASSERT_X(desktops.size() != 0, "V1::loadSerializedLayout", "We need desktops"); // qDebug() << "DESKTOP DESERIALIZATION: Loading desktops..."; @@ -346,18 +362,11 @@ SCRIPT_ARRAY_FOREACH(appletData, desktopData.property("applets")) { // qDebug() << "DESKTOP DESERIALIZATION: Applet: " << appletData.toString(); - // TODO: It would be nicer to be able to call addWidget directly - auto desktopObject = env->wrap(desktop); - auto addAppletFunction = desktopObject.property("addWidget"); - QScriptValueList args { - appletData.property("plugin"), - appletData.property("geometry.x").toInteger() * ScriptEngine::gridUnit(), - appletData.property("geometry.y").toInteger() * ScriptEngine::gridUnit(), - appletData.property("geometry.width").toInteger() * ScriptEngine::gridUnit(), - appletData.property("geometry.height").toInteger() * ScriptEngine::gridUnit() - }; - - auto appletObject = addAppletFunction.call(desktopObject, args); + auto appletObject = desktop->addWidget( appletData.property("plugin"), + appletData.property("geometry.x").toInt() * gridUnit(), + appletData.property("geometry.y").toInt() * gridUnit(), + appletData.property("geometry.width").toInt() * gridUnit(), + appletData.property("geometry.height").toInt() * gridUnit()); if (auto applet = qobject_cast(appletObject.toQObject())) { // Now, lets go through the configs for the applet @@ -371,17 +380,17 @@ // qDebug() << "PANEL DESERIALIZATION: Loading panels..."; SCRIPT_ARRAY_FOREACH(panelData, data.property("panels")) { - const auto panel = qobject_cast(env->createContainment( + const auto panel = qobject_cast(m_engine->createContainmentWrapper( QStringLiteral("Panel"), QStringLiteral("org.kde.panel"))); Q_ASSERT(panel); // Basic panel setup panel->setLocation(panelData.property("location").toString()); - panel->setHeight(panelData.property("height").toNumber() * ScriptEngine::gridUnit()); - panel->setMaximumLength(panelData.property("maximumLength").toNumber() * ScriptEngine::gridUnit()); - panel->setMinimumLength(panelData.property("minimumLength").toNumber() * ScriptEngine::gridUnit()); - panel->setOffset(panelData.property("offset").toNumber() * ScriptEngine::gridUnit()); + panel->setHeight(panelData.property("height").toNumber() * gridUnit()); + panel->setMaximumLength(panelData.property("maximumLength").toNumber() * gridUnit()); + panel->setMinimumLength(panelData.property("minimumLength").toNumber() * gridUnit()); + panel->setOffset(panelData.property("offset").toNumber() * gridUnit()); panel->setAlignment(panelData.property("alignment").toString()); panel->setHiding(panelData.property("hiding").toString()); @@ -392,12 +401,7 @@ SCRIPT_ARRAY_FOREACH(appletData, panelData.property("applets")) { // qDebug() << "PANEL DESERIALIZATION: Applet: " << appletData.toString(); - // TODO: It would be nicer to be able to call addWidget directly - auto panelObject = env->wrap(panel); - auto addAppletFunction = panelObject.property("addWidget"); - QScriptValueList args { appletData.property("plugin") }; - - auto appletObject = addAppletFunction.call(panelObject, args); + auto appletObject = panel->addWidget(appletData.property("plugin")); // qDebug() << "PANEL DESERIALIZATION: addWidget" // << appletData.property("plugin").toString() // ; @@ -409,82 +413,80 @@ }; }; - return QScriptValue(); + return QJSValue(); } -QScriptValue ScriptEngine::V1::newPanel(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::newPanel(const QString &plugin) { - QString plugin(QStringLiteral("org.kde.panel")); - - if (context->argumentCount() > 0) { - plugin = context->argument(0).toString(); - } - - return createContainment(QStringLiteral("Panel"), plugin, context, engine); + return createContainment(QStringLiteral("Panel"), QStringLiteral("org.kde.panel"), plugin); } -QScriptValue ScriptEngine::V1::panelById(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::panelById(const QJSValue &idParam) const { - if (context->argumentCount() == 0) { - return context->throwError(i18n("panelById requires an id")); + //this needs to work also for string of numberls, like "20" + if (idParam.isUndefined()) { + return m_engine->newError(i18n("panelById requires an id")); } - const uint id = context->argument(0).toInt32(); - ScriptEngine *env = envFor(engine); - foreach (Plasma::Containment *c, env->m_corona->containments()) { + const quint32 id = idParam.toInt(); + + foreach (Plasma::Containment *c, m_engine->m_corona->containments()) { if (c->id() == id && isPanel(c)) { - return env->wrap(c); + return m_engine->wrap(c); } } - return engine->undefinedValue(); + return QJSValue(); } -QScriptValue ScriptEngine::V1::panels(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::desktops() const { - Q_UNUSED(context) - - QScriptValue panels = engine->newArray(); - ScriptEngine *env = envFor(engine); + QJSValue containments = m_engine->newArray(); int count = 0; - foreach (Plasma::Containment *c, env->m_corona->containments()) { - if (isPanel(c)) { - panels.setProperty(count, env->wrap(c)); + const auto result = m_engine->m_corona->containments(); + + for (const auto c : result) { + // make really sure we get actual desktops, so check for a non empty + // activty id + if (!isPanel(c) && !c->activity().isEmpty()) { + containments.setProperty(count, m_engine->wrap(c)); ++count; } } - panels.setProperty(QStringLiteral("length"), count); - return panels; + containments.setProperty(QStringLiteral("length"), count); + return containments; } -QScriptValue ScriptEngine::V1::fileExists(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::panels() const { - Q_UNUSED(engine) - if (context->argumentCount() == 0) { - return false; + QJSValue panels = m_engine->newArray(); + int count = 0; + + const auto result = m_engine->m_corona->containments(); + + for (const auto c : result) { + panels.setProperty(count, m_engine->wrap(c)); + ++count; } + panels.setProperty(QStringLiteral("length"), count); + + return panels; +} - const QString path = context->argument(0).toString(); +bool ScriptEngine::V1::fileExists(const QString &path) const +{ if (path.isEmpty()) { return false; } QFile f(KShell::tildeExpand(path)); return f.exists(); } -QScriptValue ScriptEngine::V1::loadTemplate(QScriptContext *context, QScriptEngine *engine) +bool ScriptEngine::V1::loadTemplate(const QString &layout) { - Q_UNUSED(engine) - - if (context->argumentCount() == 0) { - // qDebug() << "no arguments"; - return false; - } - - const QString layout = context->argument(0).toString(); if (layout.isEmpty() || layout.contains(QStringLiteral("'"))) { // qDebug() << "layout is empty"; return false; @@ -506,8 +508,7 @@ QString path; { - ScriptEngine *env = envFor(engine); - ShellCorona *sc = qobject_cast(env->m_corona); + ShellCorona *sc = qobject_cast(m_engine->m_corona); if (sc) { const QString overridePackagePath = sc->lookAndFeelPackage().path() + QStringLiteral("contents/layouts/") + pluginData.pluginId(); @@ -554,28 +555,18 @@ return false; } - ScriptEngine *env = envFor(engine); - env->globalObject().setProperty(QStringLiteral("templateName"), env->newVariant(pluginData.name()), QScriptValue::ReadOnly | QScriptValue::Undeletable); - env->globalObject().setProperty(QStringLiteral("templateComment"), env->newVariant(pluginData.description()), QScriptValue::ReadOnly | QScriptValue::Undeletable); + ScriptEngine *engine = new ScriptEngine(m_engine->corona(), this); + engine->globalObject().setProperty(QStringLiteral("templateName"), pluginData.name()); + engine->globalObject().setProperty(QStringLiteral("templateComment"), pluginData.description()); - QScriptValue rv = env->newObject(); - QScriptContext *ctx = env->pushContext(); - ctx->setThisObject(rv); + engine->evaluateScript(script, path); - env->evaluateScript(script, path); - - env->popContext(); - return rv; + engine->deleteLater(); + return true; } -QScriptValue ScriptEngine::V1::applicationExists(QScriptContext *context, QScriptEngine *engine) +bool ScriptEngine::V1::applicationExists(const QString &application) const { - Q_UNUSED(engine) - if (context->argumentCount() == 0) { - return false; - } - - const QString application = context->argument(0).toString(); if (application.isEmpty()) { return false; } @@ -607,22 +598,12 @@ return false; } -QScriptValue ScriptEngine::V1::defaultApplication(QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::defaultApplication(const QString &application, bool storageId) const { - Q_UNUSED(engine) - - if (context->argumentCount() == 0) { - return false; - } - - const QString application = context->argument(0).toString(); if (application.isEmpty()) { return false; } - const bool storageId - = context->argumentCount() < 2 ? false : context->argument(1).toBool(); - // FIXME: there are some pretty horrible hacks below, in the sense that they // assume a very // specific implementation system. there is much room for improvement here. @@ -727,15 +708,8 @@ return false; } -QScriptValue ScriptEngine::V1::applicationPath(QScriptContext *context, - QScriptEngine *engine) +QJSValue ScriptEngine::V1::applicationPath(const QString &application) const { - Q_UNUSED(engine) - if (context->argumentCount() == 0) { - return false; - } - - const QString application = context->argument(0).toString(); if (application.isEmpty()) { return false; } @@ -776,15 +750,8 @@ return QString(); } -QScriptValue ScriptEngine::V1::userDataPath(QScriptContext *context, - QScriptEngine *engine) +QJSValue ScriptEngine::V1::userDataPath(const QString &type, const QString &path) const { - Q_UNUSED(engine) - if (context->argumentCount() == 0) { - return QDir::homePath(); - } - - const QString type = context->argument(0).toString(); if (type.isEmpty()) { return QDir::homePath(); } @@ -813,27 +780,19 @@ location = QStandardPaths::GenericConfigLocation; } - if (context->argumentCount() > 1) { + if (!path.isEmpty()) { QString loc = QStandardPaths::writableLocation(location); loc.append(QDir::separator()); - loc.append(context->argument(1).toString()); + loc.append(path); return loc; } const QStringList &locations = QStandardPaths::standardLocations(location); return locations.count() ? locations.first() : QString(); } -QScriptValue ScriptEngine::V1::knownWallpaperPlugins(QScriptContext *context, - QScriptEngine *engine) +QJSValue ScriptEngine::V1::knownWallpaperPlugins(const QString &formFactor) const { - Q_UNUSED(engine) - - QString formFactor; - if (context->argumentCount() > 0) { - formFactor = context->argument(0).toString(); - } - QString constraint; if (!formFactor.isEmpty()) { constraint.append("[X-Plasma-FormFactors] ~~ '") @@ -844,111 +803,72 @@ const QList wallpapers = KPackage::PackageLoader::self()->listPackages( QStringLiteral("Plasma/Wallpaper"), QString()); - QScriptValue rv = engine->newArray(wallpapers.size()); + QJSValue rv = m_engine->newArray(wallpapers.size()); for (auto wp : wallpapers) { - rv.setProperty(wp.name(), engine->newArray(0)); + rv.setProperty(wp.name(), m_engine->newArray(0)); } return rv; } -QScriptValue ScriptEngine::V1::configFile(QScriptContext *context, - QScriptEngine *engine) +QJSValue ScriptEngine::V1::configFile(const QJSValue &config, const QString &group) { ConfigGroup *file = nullptr; - if (context->argumentCount() > 0) { - if (context->argument(0).isString()) { + if (!config.isUndefined()) { + if (config.isString()) { file = new ConfigGroup; - const QString &fileName = context->argument(0).toString(); - const ScriptEngine *env = envFor(engine); - const Plasma::Corona *corona = env->corona(); + const Plasma::Corona *corona = m_engine->corona(); + const QString &fileName = config.toString(); if (fileName == corona->config()->name()) { file->setConfig(corona->config()); } else { file->setFile(fileName); } - if (context->argumentCount() > 1) { - file->setGroup(context->argument(1).toString()); + if (!group.isEmpty()) { + file->setGroup(group); } } else if (ConfigGroup *parent = qobject_cast( - context->argument(0).toQObject())) { + config.toQObject())) { file = new ConfigGroup(parent); - if (context->argumentCount() > 1) { - file->setGroup(context->argument(1).toString()); + if (!group.isEmpty()) { + file->setGroup(group); } } } else { file = new ConfigGroup; } - QScriptValue v - = engine->newQObject(file, QScriptEngine::ScriptOwnership, - QScriptEngine::ExcludeSuperClassProperties - | QScriptEngine::ExcludeSuperClassMethods); + QJSValue v = m_engine->newQObject(file); return v; } -QScriptValue ScriptEngine::V1::desktops(QScriptContext *context, - QScriptEngine *engine) -{ - Q_UNUSED(context) - - QScriptValue containments = engine->newArray(); - ScriptEngine *env = envFor(engine); - int count = 0; - - foreach (Plasma::Containment *c, env->corona()->containments()) { - // make really sure we get actual desktops, so check for a non empty - // activty id - if (!isPanel(c) && !c->activity().isEmpty()) { - containments.setProperty(count, env->wrap(c)); - ++count; - } - } - - containments.setProperty(QStringLiteral("length"), count); - return containments; -} - -QScriptValue ScriptEngine::V1::gridUnit(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(context); - Q_UNUSED(engine); - return ScriptEngine::gridUnit(); -} - -QScriptValue ScriptEngine::V1::setImmutability(QScriptContext *context, - QScriptEngine *engine) +void ScriptEngine::V1::setImmutability(const QString &immutability) { - if (context->argumentCount() == 0) { - return QScriptValue(); + if (immutability.isEmpty()) { + return; } - ScriptEngine *env = envFor(engine); - const QString immutability = context->argument(0).toString(); if (immutability == QLatin1String("systemImmutable")) { - env->corona()->setImmutability(Plasma::Types::SystemImmutable); + m_engine->corona()->setImmutability(Plasma::Types::SystemImmutable); } else if (immutability == QLatin1String("userImmutable")) { - env->corona()->setImmutability(Plasma::Types::UserImmutable); + m_engine->corona()->setImmutability(Plasma::Types::UserImmutable); } else { - env->corona()->setImmutability(Plasma::Types::Mutable); + m_engine->corona()->setImmutability(Plasma::Types::Mutable); } - return QScriptValue(); + return; } -QScriptValue ScriptEngine::V1::immutability(QScriptContext *context, - QScriptEngine *engine) +QString ScriptEngine::V1::immutability() const { - ScriptEngine *env = envFor(engine); - switch (env->corona()->immutability()) { + switch (m_engine->corona()->immutability()) { case Plasma::Types::SystemImmutable: return QLatin1String("systemImmutable"); case Plasma::Types::UserImmutable: @@ -958,21 +878,19 @@ } } -QScriptValue ScriptEngine::V1::createContainment(const QString &type, const QString &defaultPlugin, - QScriptContext *context, QScriptEngine *engine) +QJSValue ScriptEngine::V1::createContainment(const QString &type, const QString &defaultPlugin, const QString &plugin) { - const QString plugin = context->argumentCount() > 0 - ? context->argument(0).toString() - : defaultPlugin; + const QString actualPlugin = plugin.isEmpty() + ? defaultPlugin + : plugin; - ScriptEngine *env = envFor(engine); - auto result = env->createContainment(type, plugin); + auto result = m_engine->createContainmentWrapper(type, actualPlugin); if (!result) { - return context->throwError(i18n("Could not find a plugin for %1 named %2.", type, plugin)); + return m_engine->newError(i18n("Could not find a plugin for %1 named %2.", type, actualPlugin)); } - return env->wrap(result); + return m_engine->newQObject(result); } } // namespace WorkspaceScripting diff --git a/shell/scripting/widget.h b/shell/scripting/widget.h --- a/shell/scripting/widget.h +++ b/shell/scripting/widget.h @@ -21,6 +21,7 @@ #define WIDGET #include +#include #include "applet.h" @@ -43,7 +44,8 @@ Q_PROPERTY(QStringList globalConfigKeys READ globalConfigKeys) Q_PROPERTY(QStringList globalConfigGroups READ globalConfigGroups) Q_PROPERTY(int index WRITE setIndex READ index) - Q_PROPERTY(QRectF geometry WRITE setGeometry READ geometry) + //We pass our js based QRect wrapper instead of a simple QRectF + Q_PROPERTY(QJSValue geometry WRITE setGeometry READ geometry) Q_PROPERTY(QStringList currentConfigGroup WRITE setCurrentConfigGroup READ currentConfigGroup) Q_PROPERTY(QString globalShortcut WRITE setGlobalShortcut READ globalShorcut) Q_PROPERTY(bool locked READ locked WRITE setLocked) @@ -58,8 +60,8 @@ int index() const; void setIndex(int index); - QRectF geometry() const; - void setGeometry(const QRectF &geometry); + QJSValue geometry() const; + void setGeometry(const QJSValue &geometry); void setGlobalShortcut(const QString &shortcut); QString globalShorcut() const; @@ -70,15 +72,6 @@ void remove(); void showConfigurationInterface(); - // from the applet interface - QVariant readConfig(const QString &key, const QVariant &def = QString()) const override { return Applet::readConfig(key, def); } - void writeConfig(const QString &key, const QVariant &value) override { Applet::writeConfig(key, value); } - - QVariant readGlobalConfig(const QString &key, const QVariant &def = QString()) const override { return Applet::readGlobalConfig(key, def); } - void writeGlobalConfig(const QString &key, const QVariant &value) override { Applet::writeGlobalConfig(key, value); } - - void reloadConfig() override { Applet::reloadConfig(); } - private: class Private; Private * const d; diff --git a/shell/scripting/widget.cpp b/shell/scripting/widget.cpp --- a/shell/scripting/widget.cpp +++ b/shell/scripting/widget.cpp @@ -148,16 +148,16 @@ layout->insertItem(index, applet);*/ } -QRectF Widget::geometry() const +QJSValue Widget::geometry() const { /*if (d->applet) { return d->applet.data()->geometry(); } */ - return QRectF(); + return QJSValue(); } -void Widget::setGeometry(const QRectF &geometry) +void Widget::setGeometry(const QJSValue &geometry) { Q_UNUSED(geometry) /*if (d->applet) { diff --git a/shell/shellcorona.cpp b/shell/shellcorona.cpp --- a/shell/shellcorona.cpp +++ b/shell/shellcorona.cpp @@ -1485,8 +1485,8 @@ }); scriptEngine.evaluateScript(script); - if (scriptEngine.hasUncaughtException() && calledFromDBus()) { - sendErrorReply(QDBusError::Failed, scriptEngine.uncaughtException().toString()); + if (!scriptEngine.errorString().isEmpty() && calledFromDBus()) { + sendErrorReply(QDBusError::Failed, scriptEngine.errorString()); } }