2009-01-05 09:08:38 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2007-2008 Richard J. Moore <rich@kde.org>
|
|
|
|
*
|
|
|
|
* 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 "simplejavascriptapplet.h"
|
|
|
|
|
|
|
|
#include <QScriptEngine>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QUiLoader>
|
|
|
|
#include <QGraphicsLayout>
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
|
|
#include <KDebug>
|
|
|
|
#include <KLocale>
|
|
|
|
#include <KStandardDirs>
|
2009-01-05 20:16:44 +01:00
|
|
|
#include <KConfigGroup>
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
#include <Plasma/Applet>
|
|
|
|
#include <Plasma/Svg>
|
|
|
|
#include <Plasma/FrameSvg>
|
|
|
|
#include <Plasma/Package>
|
2009-02-14 14:57:37 +01:00
|
|
|
#include <Plasma/VideoWidget>
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
#include "appletinterface.h"
|
|
|
|
|
|
|
|
using namespace Plasma;
|
|
|
|
|
|
|
|
#include "bind_dataengine.h"
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(QPainter*)
|
|
|
|
Q_DECLARE_METATYPE(QStyleOptionGraphicsItem*)
|
|
|
|
Q_DECLARE_METATYPE(SimpleJavaScriptApplet*)
|
|
|
|
Q_DECLARE_METATYPE(AppletInterface*)
|
|
|
|
Q_DECLARE_METATYPE(Applet*)
|
|
|
|
Q_DECLARE_METATYPE(QGraphicsWidget*)
|
|
|
|
Q_DECLARE_METATYPE(QGraphicsLayout*)
|
2009-01-05 20:16:44 +01:00
|
|
|
Q_DECLARE_METATYPE(KConfigGroup)
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
Q_SCRIPT_DECLARE_QMETAOBJECT(AppletInterface, SimpleJavaScriptApplet*)
|
|
|
|
|
|
|
|
QScriptValue constructPainterClass(QScriptEngine *engine);
|
|
|
|
QScriptValue constructGraphicsItemClass(QScriptEngine *engine);
|
2009-01-05 10:58:26 +01:00
|
|
|
QScriptValue constructLinearLayoutClass(QScriptEngine *engine);
|
2009-04-28 04:13:21 +02:00
|
|
|
QScriptValue constructKUrlClass(QScriptEngine *engine);
|
2009-01-05 09:08:38 +01:00
|
|
|
QScriptValue constructTimerClass(QScriptEngine *engine);
|
|
|
|
QScriptValue constructFontClass(QScriptEngine *engine);
|
|
|
|
QScriptValue constructQRectFClass(QScriptEngine *engine);
|
|
|
|
QScriptValue constructQPointClass(QScriptEngine *engine);
|
|
|
|
QScriptValue constructQSizeFClass(QScriptEngine *engine);
|
|
|
|
|
2009-02-14 14:57:37 +01:00
|
|
|
|
|
|
|
//typedef VideoWidget::Control Control;
|
|
|
|
Q_DECLARE_FLAGS(Controls, VideoWidget::Control)
|
|
|
|
Q_DECLARE_METATYPE(Controls)
|
|
|
|
|
2009-01-05 20:16:44 +01:00
|
|
|
class DummyService : public Service
|
|
|
|
{
|
2009-01-05 21:48:22 +01:00
|
|
|
public:
|
|
|
|
ServiceJob *createJob(const QString &operation, QMap<QString, QVariant> ¶meters)
|
2009-01-05 20:16:44 +01:00
|
|
|
{
|
2009-01-05 21:48:22 +01:00
|
|
|
Q_UNUSED(operation)
|
|
|
|
Q_UNUSED(parameters)
|
2009-01-05 20:16:44 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
/*
|
|
|
|
* Workaround the fact that QtScripts handling of variants seems a bit broken.
|
|
|
|
*/
|
2009-04-02 08:15:22 +02:00
|
|
|
QScriptValue variantToScriptValue(QScriptEngine *engine, QVariant var)
|
2009-01-05 09:08:38 +01:00
|
|
|
{
|
|
|
|
if (var.isNull()) {
|
|
|
|
return engine->nullValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(var.type())
|
|
|
|
{
|
|
|
|
case QVariant::Invalid:
|
|
|
|
return engine->nullValue();
|
|
|
|
case QVariant::Bool:
|
|
|
|
return QScriptValue(engine, var.toBool());
|
|
|
|
case QVariant::Date:
|
|
|
|
return engine->newDate(var.toDateTime());
|
|
|
|
case QVariant::DateTime:
|
|
|
|
return engine->newDate(var.toDateTime());
|
|
|
|
case QVariant::Double:
|
|
|
|
return QScriptValue(engine, var.toDouble());
|
|
|
|
case QVariant::Int:
|
|
|
|
case QVariant::LongLong:
|
|
|
|
return QScriptValue(engine, var.toInt());
|
|
|
|
case QVariant::String:
|
|
|
|
return QScriptValue(engine, var.toString());
|
2009-01-05 12:01:28 +01:00
|
|
|
case QVariant::Time: {
|
|
|
|
QDateTime t(QDate::currentDate(), var.toTime());
|
|
|
|
return engine->newDate(t);
|
|
|
|
}
|
2009-01-05 09:08:38 +01:00
|
|
|
case QVariant::UInt:
|
|
|
|
return QScriptValue(engine, var.toUInt());
|
|
|
|
default:
|
2009-04-02 08:15:22 +02:00
|
|
|
if (var.typeName() == QLatin1String("KUrl")) {
|
|
|
|
return QScriptValue(engine, var.value<KUrl>().prettyUrl());
|
|
|
|
} else if (var.typeName() == QLatin1String("QColor")) {
|
|
|
|
return QScriptValue(engine, var.value<QColor>().name());
|
|
|
|
} else if (var.typeName() == QLatin1String("QUrl")) {
|
|
|
|
return QScriptValue(engine, var.value<QUrl>().toString());
|
|
|
|
}
|
2009-01-05 09:08:38 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return qScriptValueFromValue(engine, var);
|
|
|
|
}
|
|
|
|
|
2009-02-14 14:57:37 +01:00
|
|
|
QScriptValue qScriptValueFromControls(QScriptEngine *engine, const Controls &controls)
|
|
|
|
{
|
|
|
|
return QScriptValue(engine, controls);
|
|
|
|
}
|
|
|
|
|
|
|
|
void controlsFromScriptValue(const QScriptValue& obj, Controls &controls)
|
|
|
|
{
|
|
|
|
int flagValue = obj.toInteger();
|
|
|
|
//FIXME: it has to be a less ugly way to do that :)
|
|
|
|
if (flagValue&VideoWidget::Play) {
|
|
|
|
controls |= VideoWidget::Play;
|
|
|
|
}
|
|
|
|
if (flagValue&VideoWidget::Pause) {
|
|
|
|
controls |= VideoWidget::Pause;
|
|
|
|
}
|
|
|
|
if (flagValue&VideoWidget::Stop) {
|
|
|
|
controls |= VideoWidget::Stop;
|
|
|
|
}
|
|
|
|
if (flagValue&VideoWidget::PlayPause) {
|
|
|
|
controls |= VideoWidget::PlayPause;
|
|
|
|
}
|
|
|
|
if (flagValue&VideoWidget::Progress) {
|
|
|
|
controls |= VideoWidget::Progress;
|
|
|
|
}
|
|
|
|
if (flagValue&VideoWidget::Volume) {
|
|
|
|
controls |= VideoWidget::Volume;
|
|
|
|
}
|
|
|
|
if (flagValue&VideoWidget::OpenFile) {
|
|
|
|
controls |= VideoWidget::OpenFile;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
QScriptValue qScriptValueFromData(QScriptEngine *engine, const DataEngine::Data &data)
|
|
|
|
{
|
|
|
|
DataEngine::Data::const_iterator begin = data.begin();
|
|
|
|
DataEngine::Data::const_iterator end = data.end();
|
|
|
|
DataEngine::Data::const_iterator it;
|
|
|
|
|
|
|
|
QScriptValue obj = engine->newObject();
|
|
|
|
|
|
|
|
for (it = begin; it != end; ++it) {
|
2009-01-05 12:01:28 +01:00
|
|
|
//kDebug() << "setting" << it.key() << "to" << it.value();
|
|
|
|
QString prop = it.key();
|
|
|
|
prop.replace(' ', '_');
|
2009-04-02 08:15:22 +02:00
|
|
|
obj.setProperty(prop, variantToScriptValue(engine, it.value()));
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2009-01-05 20:16:44 +01:00
|
|
|
QScriptValue qScriptValueFromKConfigGroup(QScriptEngine *engine, const KConfigGroup &config)
|
|
|
|
{
|
|
|
|
QScriptValue obj = engine->newObject();
|
|
|
|
|
|
|
|
if (!config.isValid()) {
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QString, QString> entryMap = config.entryMap();
|
2009-01-05 21:02:11 +01:00
|
|
|
QMap<QString, QString>::const_iterator it = entryMap.constBegin();
|
2009-01-05 20:16:44 +01:00
|
|
|
QMap<QString, QString>::const_iterator begin = it;
|
2009-01-05 21:02:11 +01:00
|
|
|
QMap<QString, QString>::const_iterator end = entryMap.constEnd();
|
2009-01-05 20:16:44 +01:00
|
|
|
|
2009-01-05 21:53:39 +01:00
|
|
|
//setting the group name
|
|
|
|
obj.setProperty("__name", QScriptValue(engine, config.name()));
|
|
|
|
|
|
|
|
//setting the key/value pairs
|
2009-01-05 20:16:44 +01:00
|
|
|
for (it = begin; it != end; ++it) {
|
2009-01-05 22:52:23 +01:00
|
|
|
//kDebug() << "setting" << it.key() << "to" << it.value();
|
2009-01-05 20:16:44 +01:00
|
|
|
QString prop = it.key();
|
|
|
|
prop.replace(' ', '_');
|
2009-04-02 08:15:22 +02:00
|
|
|
obj.setProperty(prop, variantToScriptValue(engine, it.value()));
|
2009-01-05 20:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
void kConfigGroupFromScriptValue(const QScriptValue& obj, KConfigGroup &config)
|
|
|
|
{
|
2009-01-05 21:53:39 +01:00
|
|
|
KConfigSkeleton *skel = new KConfigSkeleton();
|
|
|
|
config = KConfigGroup(skel->config(), obj.property("__name").toString());
|
|
|
|
|
2009-01-05 22:52:23 +01:00
|
|
|
QScriptValueIterator it(obj);
|
|
|
|
|
2009-01-05 20:16:44 +01:00
|
|
|
while (it.hasNext()) {
|
2009-01-05 22:52:23 +01:00
|
|
|
it.next();
|
|
|
|
//kDebug() << it.name() << "is" << it.value().toString();
|
2009-01-05 21:53:39 +01:00
|
|
|
if (it.name() != "__name") {
|
|
|
|
config.writeEntry(it.name(), it.value().toString());
|
|
|
|
}
|
2009-01-05 20:16:44 +01:00
|
|
|
}
|
|
|
|
}
|
2009-01-05 09:08:38 +01:00
|
|
|
|
2009-02-14 14:57:37 +01:00
|
|
|
void registerEnums(QScriptEngine *engine, QScriptValue &scriptValue, const QMetaObject &meta)
|
|
|
|
{
|
|
|
|
//manually create enum values. ugh
|
|
|
|
for (int i=0; i < meta.enumeratorCount(); ++i) {
|
|
|
|
QMetaEnum e = meta.enumerator(i);
|
|
|
|
//kDebug() << e.name();
|
|
|
|
for (int i=0; i < e.keyCount(); ++i) {
|
|
|
|
//kDebug() << e.key(i) << e.value(i);
|
|
|
|
scriptValue.setProperty(e.key(i), QScriptValue(engine, e.value(i)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-07 21:35:28 +01:00
|
|
|
KSharedPtr<UiLoader> SimpleJavaScriptApplet::s_widgetLoader;
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
SimpleJavaScriptApplet::SimpleJavaScriptApplet(QObject *parent, const QVariantList &args)
|
|
|
|
: Plasma::AppletScript(parent)
|
|
|
|
{
|
2009-04-02 08:15:22 +02:00
|
|
|
Q_UNUSED(args)
|
2009-02-08 16:27:53 +01:00
|
|
|
// kDebug() << "Script applet launched, args" << applet()->startupArguments();
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
m_engine = new QScriptEngine(this);
|
|
|
|
importExtensions();
|
|
|
|
}
|
|
|
|
|
|
|
|
SimpleJavaScriptApplet::~SimpleJavaScriptApplet()
|
|
|
|
{
|
2009-01-07 21:35:28 +01:00
|
|
|
if (s_widgetLoader.count() == 1) {
|
|
|
|
s_widgetLoader.clear();
|
|
|
|
}
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::reportError()
|
|
|
|
{
|
|
|
|
kDebug() << "Error: " << m_engine->uncaughtException().toString()
|
|
|
|
<< " at line " << m_engine->uncaughtExceptionLineNumber() << endl;
|
|
|
|
kDebug() << m_engine->uncaughtExceptionBacktrace();
|
|
|
|
}
|
|
|
|
|
2009-02-07 18:51:13 +01:00
|
|
|
void SimpleJavaScriptApplet::configChanged()
|
2009-01-05 09:08:38 +01:00
|
|
|
{
|
2009-02-07 18:55:08 +01:00
|
|
|
QScriptValue fun = m_self.property("configChanged");
|
2009-01-05 09:08:38 +01:00
|
|
|
if (!fun.isFunction()) {
|
2009-02-07 18:55:08 +01:00
|
|
|
kDebug() << "Script: plasmoid.configChanged is not a function, " << fun.toString();
|
2009-01-05 09:08:38 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptContext *ctx = m_engine->pushContext();
|
|
|
|
ctx->setActivationObject(m_self);
|
2009-02-07 18:51:13 +01:00
|
|
|
//kDebug() << "calling plasmoid";
|
2009-01-05 09:08:38 +01:00
|
|
|
fun.call(m_self);
|
|
|
|
m_engine->popContext();
|
|
|
|
|
|
|
|
if (m_engine->hasUncaughtException()) {
|
|
|
|
reportError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::dataUpdated(const QString &name, const DataEngine::Data &data)
|
|
|
|
{
|
2009-01-05 12:01:28 +01:00
|
|
|
QScriptValue fun = m_self.property("dataUpdate");
|
2009-01-05 09:08:38 +01:00
|
|
|
if (!fun.isFunction()) {
|
2009-01-05 12:01:28 +01:00
|
|
|
kDebug() << "Script: dataUpdate is not a function, " << fun.toString();
|
2009-01-05 09:08:38 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValueList args;
|
|
|
|
args << m_engine->toScriptValue(name) << m_engine->toScriptValue(data);
|
|
|
|
|
|
|
|
QScriptContext *ctx = m_engine->pushContext();
|
|
|
|
ctx->setActivationObject(m_self);
|
|
|
|
fun.call(m_self, args);
|
|
|
|
m_engine->popContext();
|
|
|
|
|
|
|
|
if (m_engine->hasUncaughtException()) {
|
|
|
|
reportError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::executeAction(const QString &name)
|
|
|
|
{
|
|
|
|
callFunction("action_" + name);
|
|
|
|
/*
|
|
|
|
QScriptValue fun = m_self.property("action_" + name);
|
|
|
|
if (fun.isFunction()) {
|
|
|
|
QScriptContext *ctx = m_engine->pushContext();
|
|
|
|
ctx->setActivationObject(m_self);
|
|
|
|
fun.call(m_self);
|
|
|
|
m_engine->popContext();
|
|
|
|
|
|
|
|
if (m_engine->hasUncaughtException()) {
|
|
|
|
reportError();
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
|
|
|
|
{
|
|
|
|
Q_UNUSED(option)
|
|
|
|
Q_UNUSED(contentsRect)
|
|
|
|
|
|
|
|
//kDebug() << "paintInterface() (c++)";
|
|
|
|
QScriptValue fun = m_self.property("paintInterface");
|
|
|
|
if (!fun.isFunction()) {
|
2009-01-05 10:58:26 +01:00
|
|
|
//kDebug() << "Script: paintInterface is not a function, " << fun.toString();
|
2009-01-05 09:08:38 +01:00
|
|
|
AppletScript::paintInterface(p, option, contentsRect);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValueList args;
|
|
|
|
args << m_engine->toScriptValue(p);
|
|
|
|
args << m_engine->toScriptValue(const_cast<QStyleOptionGraphicsItem*>(option));
|
|
|
|
args << m_engine->toScriptValue(contentsRect);
|
|
|
|
|
|
|
|
QScriptContext *ctx = m_engine->pushContext();
|
|
|
|
ctx->setActivationObject(m_self);
|
|
|
|
fun.call(m_self, args);
|
|
|
|
m_engine->popContext();
|
|
|
|
|
|
|
|
if (m_engine->hasUncaughtException()) {
|
|
|
|
reportError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<QAction*> SimpleJavaScriptApplet::contextualActions()
|
|
|
|
{
|
|
|
|
return m_interface->contextualActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::callFunction(const QString &functionName, const QScriptValueList &args)
|
|
|
|
{
|
|
|
|
QScriptValue fun = m_self.property(functionName);
|
|
|
|
if (fun.isFunction()) {
|
|
|
|
QScriptContext *ctx = m_engine->pushContext();
|
|
|
|
ctx->setActivationObject(m_self);
|
|
|
|
fun.call(m_self, args);
|
|
|
|
m_engine->popContext();
|
|
|
|
|
|
|
|
if (m_engine->hasUncaughtException()) {
|
|
|
|
reportError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::constraintsEvent(Plasma::Constraints constraints)
|
|
|
|
{
|
|
|
|
QString functionName;
|
|
|
|
|
|
|
|
if (constraints & Plasma::FormFactorConstraint) {
|
|
|
|
callFunction("formFactorChanged");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (constraints & Plasma::LocationConstraint) {
|
|
|
|
callFunction("locationChanged");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (constraints & Plasma::ContextConstraint) {
|
|
|
|
callFunction("contextChanged");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SimpleJavaScriptApplet::init()
|
|
|
|
{
|
|
|
|
setupObjects();
|
|
|
|
|
|
|
|
kDebug() << "ScriptName:" << applet()->name();
|
|
|
|
kDebug() << "ScriptCategory:" << applet()->category();
|
|
|
|
|
|
|
|
QFile file(mainScript());
|
|
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
|
|
kWarning() << "Unable to load script file";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString script = file.readAll();
|
2009-01-11 23:49:48 +01:00
|
|
|
//kDebug() << "Script says" << script;
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
m_engine->evaluate(script);
|
|
|
|
if (m_engine->hasUncaughtException()) {
|
|
|
|
reportError();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::importExtensions()
|
|
|
|
{
|
|
|
|
return; // no extension, so do bother wasting cycles
|
2009-01-11 23:49:48 +01:00
|
|
|
|
|
|
|
/*
|
2009-01-05 09:08:38 +01:00
|
|
|
QStringList extensions;
|
|
|
|
//extensions << "qt.core" << "qt.gui" << "qt.svg" << "qt.xml" << "qt.plasma";
|
|
|
|
//extensions << "qt.core" << "qt.gui" << "qt.xml";
|
|
|
|
foreach (const QString &ext, extensions) {
|
|
|
|
kDebug() << "importing " << ext << "...";
|
|
|
|
QScriptValue ret = m_engine->importExtension(ext);
|
|
|
|
if (ret.isError()) {
|
|
|
|
kDebug() << "failed to import extension" << ext << ":" << ret.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
kDebug() << "done importing extensions.";
|
2009-01-11 23:49:48 +01:00
|
|
|
*/
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::setupObjects()
|
|
|
|
{
|
|
|
|
QScriptValue global = m_engine->globalObject();
|
|
|
|
|
2009-01-05 12:01:28 +01:00
|
|
|
// Bindings for data engine
|
|
|
|
m_engine->setDefaultPrototype(qMetaTypeId<DataEngine*>(), m_engine->newQObject(new DataEngine()));
|
2009-01-05 22:52:23 +01:00
|
|
|
m_engine->setDefaultPrototype(qMetaTypeId<Service*>(), m_engine->newQObject(new DummyService()));
|
2009-01-05 20:16:44 +01:00
|
|
|
m_engine->setDefaultPrototype(qMetaTypeId<ServiceJob*>(), m_engine->newQObject(new ServiceJob(QString(), QString(), QMap<QString, QVariant>())));
|
2009-01-05 12:01:28 +01:00
|
|
|
|
2009-05-01 08:12:07 +02:00
|
|
|
global.setProperty("i18n", m_engine->newFunction(SimpleJavaScriptApplet::jsi18n));
|
2009-01-05 12:01:28 +01:00
|
|
|
global.setProperty("dataEngine", m_engine->newFunction(SimpleJavaScriptApplet::dataEngine));
|
2009-01-05 21:48:22 +01:00
|
|
|
global.setProperty("service", m_engine->newFunction(SimpleJavaScriptApplet::service));
|
2009-01-05 12:01:28 +01:00
|
|
|
qScriptRegisterMetaType<DataEngine::Data>(m_engine, qScriptValueFromData, 0, QScriptValue());
|
2009-01-05 20:16:44 +01:00
|
|
|
qScriptRegisterMetaType<KConfigGroup>(m_engine, qScriptValueFromKConfigGroup, kConfigGroupFromScriptValue, QScriptValue());
|
2009-01-05 12:01:28 +01:00
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
// Expose applet interface
|
|
|
|
m_interface = new AppletInterface(this);
|
|
|
|
m_self = m_engine->newQObject(m_interface);
|
|
|
|
m_self.setScope(global);
|
|
|
|
global.setProperty("plasmoid", m_self);
|
|
|
|
|
2009-02-08 16:27:53 +01:00
|
|
|
QScriptValue args = m_engine->newArray();
|
|
|
|
int i = 0;
|
2009-04-11 13:11:50 +02:00
|
|
|
foreach (const QVariant &arg, applet()->startupArguments()) {
|
2009-04-02 08:15:22 +02:00
|
|
|
args.setProperty(i, variantToScriptValue(arg));
|
2009-02-08 16:27:53 +01:00
|
|
|
++i;
|
|
|
|
}
|
|
|
|
global.setProperty("startupArguments", args);
|
|
|
|
|
2009-02-14 14:57:37 +01:00
|
|
|
registerEnums(m_engine, global, AppletInterface::staticMetaObject);
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
// Add a global loadui method for ui files
|
|
|
|
QScriptValue fun = m_engine->newFunction(SimpleJavaScriptApplet::loadui);
|
|
|
|
global.setProperty("loadui", fun);
|
|
|
|
|
|
|
|
fun = m_engine->newFunction(SimpleJavaScriptApplet::print);
|
|
|
|
global.setProperty("print", fun);
|
|
|
|
|
|
|
|
|
|
|
|
// Work around bug in 4.3.0
|
|
|
|
qMetaTypeId<QVariant>();
|
|
|
|
|
|
|
|
// Add constructors
|
|
|
|
global.setProperty("PlasmaSvg", m_engine->newFunction(SimpleJavaScriptApplet::newPlasmaSvg));
|
|
|
|
global.setProperty("PlasmaFrameSvg", m_engine->newFunction(SimpleJavaScriptApplet::newPlasmaFrameSvg));
|
|
|
|
|
|
|
|
// Add stuff from 4.4
|
|
|
|
global.setProperty("QPainter", constructPainterClass(m_engine));
|
|
|
|
global.setProperty("QGraphicsItem", constructGraphicsItemClass(m_engine));
|
|
|
|
global.setProperty("QTimer", constructTimerClass(m_engine));
|
|
|
|
global.setProperty("QFont", constructFontClass(m_engine));
|
|
|
|
global.setProperty("QRectF", constructQRectFClass(m_engine));
|
|
|
|
global.setProperty("QSizeF", constructQSizeFClass(m_engine));
|
|
|
|
global.setProperty("QPoint", constructQPointClass(m_engine));
|
2009-01-05 10:58:26 +01:00
|
|
|
global.setProperty("LinearLayout", constructLinearLayoutClass(m_engine));
|
2009-04-28 04:13:21 +02:00
|
|
|
global.setProperty("Url", constructKUrlClass(m_engine));
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
installWidgets(m_engine);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString SimpleJavaScriptApplet::findDataResource(const QString &filename)
|
|
|
|
{
|
|
|
|
QString path("plasma-script/%1");
|
|
|
|
return KGlobal::dirs()->findResource("data", path.arg(filename));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::debug(const QString &msg)
|
|
|
|
{
|
|
|
|
kDebug() << msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
QScriptValue SimpleJavaScriptApplet::dataEngine(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() != 1)
|
|
|
|
return context->throwError("dataEngine takes one argument");
|
|
|
|
|
|
|
|
QString dataEngine = context->argument(0).toString();
|
|
|
|
|
|
|
|
Script *self = engine->fromScriptValue<Script*>(context->thisObject());
|
|
|
|
|
|
|
|
DataEngine *data = self->dataEngine(dataEngine);
|
|
|
|
return engine->newQObject(data);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-05-01 08:12:07 +02:00
|
|
|
QScriptValue SimpleJavaScriptApplet::jsi18n(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() != 1) {
|
|
|
|
return context->throwError(i18n("i18n takes one argument"));
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: detect i18np pattern
|
|
|
|
QString message = context->argument(0).toString();
|
|
|
|
return engine->newVariant(i18n(message.toLocal8Bit()));
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
QScriptValue SimpleJavaScriptApplet::dataEngine(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() != 1) {
|
2009-01-07 18:54:50 +01:00
|
|
|
return context->throwError(i18n("DataEngine takes one argument"));
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QString dataEngine = context->argument(0).toString();
|
|
|
|
|
|
|
|
QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
|
|
|
//kDebug() << "appletValue is " << appletValue.toString();
|
|
|
|
|
|
|
|
QObject *appletObject = appletValue.toQObject();
|
|
|
|
if (!appletObject) {
|
|
|
|
return context->throwError(i18n("Could not extract the AppletObject"));
|
|
|
|
}
|
|
|
|
|
|
|
|
AppletInterface *interface = qobject_cast<AppletInterface*>(appletObject);
|
|
|
|
if (!interface) {
|
|
|
|
return context->throwError(i18n("Could not extract the Applet"));
|
|
|
|
}
|
|
|
|
|
|
|
|
DataEngine *data = interface->dataEngine(dataEngine);
|
|
|
|
return engine->newQObject(data);
|
|
|
|
}
|
|
|
|
|
2009-01-05 21:48:22 +01:00
|
|
|
QScriptValue SimpleJavaScriptApplet::service(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() != 2) {
|
2009-01-07 18:54:50 +01:00
|
|
|
return context->throwError(i18n("Service takes two arguments"));
|
2009-01-05 21:48:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QString dataEngine = context->argument(0).toString();
|
|
|
|
|
|
|
|
QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
|
|
|
//kDebug() << "appletValue is " << appletValue.toString();
|
|
|
|
|
|
|
|
QObject *appletObject = appletValue.toQObject();
|
|
|
|
if (!appletObject) {
|
|
|
|
return context->throwError(i18n("Could not extract the AppletObject"));
|
|
|
|
}
|
|
|
|
|
|
|
|
AppletInterface *interface = qobject_cast<AppletInterface*>(appletObject);
|
|
|
|
if (!interface) {
|
|
|
|
return context->throwError(i18n("Could not extract the Applet"));
|
|
|
|
}
|
|
|
|
|
|
|
|
DataEngine *data = interface->dataEngine(dataEngine);
|
|
|
|
QString source = context->argument(1).toString();
|
|
|
|
Service *service = data->serviceForSource(source);
|
2009-01-11 23:49:48 +01:00
|
|
|
//kDebug( )<< "lets try to get" << source << "from" << dataEngine;
|
2009-01-05 21:48:22 +01:00
|
|
|
return engine->newQObject(service);
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
QScriptValue SimpleJavaScriptApplet::loadui(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() != 1) {
|
2009-01-07 18:54:50 +01:00
|
|
|
return context->throwError(i18n("loadUI takes one argument"));
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QString filename = context->argument(0).toString();
|
|
|
|
QFile f(filename);
|
|
|
|
if (!f.open(QIODevice::ReadOnly)) {
|
|
|
|
return context->throwError(i18n("Unable to open '%1'",filename));
|
|
|
|
}
|
|
|
|
|
|
|
|
QUiLoader loader;
|
|
|
|
QWidget *w = loader.load(&f);
|
|
|
|
f.close();
|
|
|
|
|
|
|
|
return engine->newQObject(w);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString SimpleJavaScriptApplet::findSvg(QScriptEngine *engine, const QString &file)
|
|
|
|
{
|
|
|
|
QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
|
|
|
//kDebug() << "appletValue is " << appletValue.toString();
|
|
|
|
|
|
|
|
QObject *appletObject = appletValue.toQObject();
|
|
|
|
if (!appletObject) {
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
AppletInterface *interface = qobject_cast<AppletInterface*>(appletObject);
|
|
|
|
if (!interface) {
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString path = interface->package()->filePath("images", file + ".svg");
|
|
|
|
if (path.isEmpty()) {
|
|
|
|
path = interface->package()->filePath("images", file + ".svgz");
|
|
|
|
|
|
|
|
if (path.isEmpty()) {
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValue SimpleJavaScriptApplet::newPlasmaSvg(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() == 0) {
|
|
|
|
return context->throwError(i18n("Constructor takes at least 1 argument"));
|
|
|
|
}
|
|
|
|
|
|
|
|
QString filename = context->argument(0).toString();
|
|
|
|
QObject *parent = 0;
|
|
|
|
|
|
|
|
if (context->argumentCount() == 2) {
|
|
|
|
parent = qscriptvalue_cast<QObject *>(context->argument(1));
|
|
|
|
}
|
|
|
|
|
2009-01-06 04:53:04 +01:00
|
|
|
bool parentedToApplet = false;
|
|
|
|
if (!parent) {
|
|
|
|
QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
|
|
|
//kDebug() << "appletValue is " << appletValue.toString();
|
|
|
|
|
|
|
|
QObject *appletObject = appletValue.toQObject();
|
|
|
|
if (appletObject) {
|
|
|
|
AppletInterface *interface = qobject_cast<AppletInterface*>(appletObject);
|
|
|
|
if (interface) {
|
|
|
|
parentedToApplet = true;
|
|
|
|
parent = interface->applet();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
Svg *svg = new Svg(parent);
|
2009-01-06 04:53:04 +01:00
|
|
|
svg->setImagePath(parentedToApplet ? filename : findSvg(engine, filename));
|
2009-01-05 09:08:38 +01:00
|
|
|
return engine->newQObject(svg);
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValue SimpleJavaScriptApplet::newPlasmaFrameSvg(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() == 0) {
|
|
|
|
return context->throwError(i18n("Constructor takes at least 1 argument"));
|
|
|
|
}
|
|
|
|
|
|
|
|
QString filename = context->argument(0).toString();
|
|
|
|
QObject *parent = 0;
|
|
|
|
|
|
|
|
if (context->argumentCount() == 2) {
|
|
|
|
parent = qscriptvalue_cast<QObject *>(context->argument(1));
|
|
|
|
}
|
|
|
|
|
2009-01-06 04:53:04 +01:00
|
|
|
bool parentedToApplet = false;
|
|
|
|
if (!parent) {
|
|
|
|
QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
|
|
|
//kDebug() << "appletValue is " << appletValue.toString();
|
|
|
|
|
|
|
|
QObject *appletObject = appletValue.toQObject();
|
|
|
|
if (appletObject) {
|
|
|
|
AppletInterface *interface = qobject_cast<AppletInterface*>(appletObject);
|
|
|
|
if (interface) {
|
|
|
|
parentedToApplet = true;
|
|
|
|
parent = interface->applet();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
FrameSvg *frameSvg = new FrameSvg(parent);
|
2009-01-06 04:53:04 +01:00
|
|
|
frameSvg->setImagePath(parentedToApplet ? filename : findSvg(engine, filename));
|
2009-01-05 09:08:38 +01:00
|
|
|
return engine->newQObject(frameSvg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleJavaScriptApplet::installWidgets(QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
QScriptValue globalObject = engine->globalObject();
|
2009-01-07 21:35:28 +01:00
|
|
|
if (!s_widgetLoader) {
|
|
|
|
s_widgetLoader = new UiLoader;
|
|
|
|
}
|
2009-01-05 09:08:38 +01:00
|
|
|
|
2009-01-07 21:35:28 +01:00
|
|
|
foreach (const QString &widget, s_widgetLoader->availableWidgets()) {
|
2009-01-05 09:08:38 +01:00
|
|
|
QScriptValue fun = engine->newFunction(createWidget);
|
2009-01-05 10:58:26 +01:00
|
|
|
QScriptValue name = engine->toScriptValue(widget);
|
2009-01-05 09:08:38 +01:00
|
|
|
fun.setProperty(QString("functionName"), name,
|
|
|
|
QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
|
|
|
|
fun.setProperty(QString("prototype"), createPrototype(engine, name.toString()));
|
|
|
|
|
2009-01-05 10:58:26 +01:00
|
|
|
globalObject.setProperty(widget, fun);
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValue SimpleJavaScriptApplet::createWidget(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() > 1) {
|
2009-01-07 18:54:50 +01:00
|
|
|
return context->throwError(i18n("CreateWidget takes one argument"));
|
2009-01-05 09:08:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QGraphicsWidget *parent = 0;
|
|
|
|
if (context->argumentCount()) {
|
|
|
|
parent = qscriptvalue_cast<QGraphicsWidget*>(context->argument(0));
|
|
|
|
|
|
|
|
if (!parent) {
|
|
|
|
return context->throwError(i18n("The parent must be a QGraphicsWidget"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-28 04:13:21 +02:00
|
|
|
if (!parent) {
|
|
|
|
QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
|
|
|
//kDebug() << "appletValue is " << appletValue.toString();
|
|
|
|
|
|
|
|
QObject *appletObject = appletValue.toQObject();
|
|
|
|
if (!appletObject) {
|
|
|
|
return context->throwError(i18n("Could not extract the AppletObject"));
|
|
|
|
}
|
|
|
|
|
|
|
|
AppletInterface *interface = qobject_cast<AppletInterface*>(appletObject);
|
|
|
|
if (!interface) {
|
|
|
|
return context->throwError(i18n("Could not extract the Applet"));
|
|
|
|
}
|
|
|
|
|
|
|
|
parent = interface->applet();
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
QString self = context->callee().property("functionName").toString();
|
2009-01-07 21:35:28 +01:00
|
|
|
if (!s_widgetLoader) {
|
|
|
|
s_widgetLoader = new UiLoader;
|
|
|
|
}
|
|
|
|
|
|
|
|
QGraphicsWidget *w = s_widgetLoader->createWidget(self, parent);
|
2009-01-05 09:08:38 +01:00
|
|
|
|
|
|
|
if (!w) {
|
|
|
|
return QScriptValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValue fun = engine->newQObject(w);
|
|
|
|
fun.setPrototype(context->callee().property("prototype"));
|
|
|
|
|
2009-02-19 23:06:16 +01:00
|
|
|
//register enums will be accessed for instance as frame.Sunken for Frame shadow...
|
|
|
|
registerEnums(engine, fun, *w->metaObject());
|
|
|
|
|
|
|
|
//FIXME: still don't have a better approach than try to cast for every widget that could have flags..
|
|
|
|
if (qobject_cast<VideoWidget *>(w)) {
|
|
|
|
qScriptRegisterMetaType<Controls>(engine, qScriptValueFromControls, controlsFromScriptValue, QScriptValue());
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
return fun;
|
|
|
|
}
|
|
|
|
|
2009-02-09 20:10:26 +01:00
|
|
|
QScriptValue SimpleJavaScriptApplet::notSupported(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
2009-04-02 08:15:22 +02:00
|
|
|
Q_UNUSED(engine)
|
|
|
|
QString message = context->callee().property("message").toString();
|
|
|
|
return context->throwError(i18n("This operation was not supported, %1", message) );
|
2009-02-09 20:10:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
QScriptValue SimpleJavaScriptApplet::print(QScriptContext *context, QScriptEngine *engine)
|
|
|
|
{
|
|
|
|
if (context->argumentCount() != 1) {
|
|
|
|
return context->throwError(i18n("print takes one argument"));
|
|
|
|
}
|
|
|
|
|
|
|
|
kDebug() << context->argument(0).toString();
|
|
|
|
return engine->undefinedValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
QScriptValue SimpleJavaScriptApplet::createPrototype(QScriptEngine *engine, const QString &name)
|
|
|
|
{
|
|
|
|
Q_UNUSED(name)
|
|
|
|
QScriptValue proto = engine->newObject();
|
|
|
|
|
|
|
|
// Hook for adding extra properties/methods
|
|
|
|
return proto;
|
|
|
|
}
|
|
|
|
|
2009-04-02 08:15:22 +02:00
|
|
|
QScriptValue SimpleJavaScriptApplet::variantToScriptValue(QVariant var)
|
|
|
|
{
|
|
|
|
return ::variantToScriptValue(m_engine, var);
|
|
|
|
}
|
|
|
|
|
2009-01-05 09:08:38 +01:00
|
|
|
K_EXPORT_PLASMA_APPLETSCRIPTENGINE(qscriptapplet, SimpleJavaScriptApplet)
|
|
|
|
|
|
|
|
#include "simplejavascriptapplet.moc"
|
|
|
|
|
|
|
|
|