allow connecting engine sources to pretty much anything in the script
svn path=/trunk/KDE/kdebase/runtime/; revision=1101799
This commit is contained in:
parent
7b3c875217
commit
8df3489f24
@ -7,6 +7,7 @@ set(simple_javascript_engine_SRCS
|
|||||||
simplebindings/animationgroup.cpp
|
simplebindings/animationgroup.cpp
|
||||||
simplebindings/appletinterface.cpp
|
simplebindings/appletinterface.cpp
|
||||||
simplebindings/anchorlayout.cpp
|
simplebindings/anchorlayout.cpp
|
||||||
|
simplebindings/dataenginereceiver.cpp
|
||||||
simplebindings/bytearrayclass.cpp
|
simplebindings/bytearrayclass.cpp
|
||||||
simplebindings/bytearrayprototype.cpp
|
simplebindings/bytearrayprototype.cpp
|
||||||
simplebindings/color.cpp
|
simplebindings/color.cpp
|
||||||
|
190
scriptengines/javascript/simplebindings/dataenginereceiver.cpp
Normal file
190
scriptengines/javascript/simplebindings/dataenginereceiver.cpp
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Aaron J. Seigo <aseigo@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 "dataenginereceiver.h"
|
||||||
|
|
||||||
|
#include <QScriptEngine>
|
||||||
|
|
||||||
|
#include "dataengine.h"
|
||||||
|
#include "scriptenv.h"
|
||||||
|
|
||||||
|
QSet<DataEngineReceiver*> DataEngineReceiver::s_receivers;
|
||||||
|
|
||||||
|
DataEngineReceiver::DataEngineReceiver(const Plasma::DataEngine *engine, const QString &source, const QScriptValue &func, QObject *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
m_engine(engine),
|
||||||
|
m_source(source),
|
||||||
|
m_func(func),
|
||||||
|
m_obj(m_func)
|
||||||
|
{
|
||||||
|
s_receivers.insert(this);
|
||||||
|
if (!m_func.isFunction()) {
|
||||||
|
QScriptValue func = m_func.property("dataUpdated");
|
||||||
|
if (func.isFunction()) {
|
||||||
|
m_func = func;
|
||||||
|
} else {
|
||||||
|
m_obj = QScriptValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEngineReceiver::~DataEngineReceiver()
|
||||||
|
{
|
||||||
|
s_receivers.remove(this);
|
||||||
|
//kDebug() << s_receivers.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataEngineReceiver::isValid() const
|
||||||
|
{
|
||||||
|
return m_obj.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataEngineReceiver::matches(const Plasma::DataEngine *engine, const QString &source, const QScriptValue &v)
|
||||||
|
{
|
||||||
|
return engine == m_engine && m_source == source && v.equals(m_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataEngineReceiver::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
|
||||||
|
{
|
||||||
|
QScriptEngine *engine = m_func.engine();
|
||||||
|
// QScriptValue appletValue = engine->globalObject().property("plasmoid");
|
||||||
|
QScriptValueList args;
|
||||||
|
args << source;
|
||||||
|
args << qScriptValueFromMap<Plasma::DataEngine::Data>(engine, data);
|
||||||
|
|
||||||
|
m_func.call(m_obj, args);
|
||||||
|
|
||||||
|
if (engine->hasUncaughtException()) {
|
||||||
|
ScriptEnv *env = ScriptEnv::findScriptEnv(engine);
|
||||||
|
env->checkForErrors(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEngineReceiver *DataEngineReceiver::getReceiver(Plasma::DataEngine *dataEngine, const QString &source, const QScriptValue &v)
|
||||||
|
{
|
||||||
|
foreach (DataEngineReceiver *receiver, DataEngineReceiver::s_receivers) {
|
||||||
|
if (receiver->matches(dataEngine, source, v)) {
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue DataEngineReceiver::connectSource(QScriptContext *context, QScriptEngine *engine)
|
||||||
|
{
|
||||||
|
if (context->argumentCount() < 2) {
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEngine *dataEngine = qobject_cast<DataEngine *>(context->thisObject().toQObject());
|
||||||
|
if (!dataEngine) {
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString source = context->argument(0).toString();
|
||||||
|
if (source.isEmpty()) {
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *obj = 0;
|
||||||
|
QScriptValue v = context->argument(1);
|
||||||
|
// if it's a function we get, then use that directly
|
||||||
|
// next see if it is a qobject with a good slot; if it is then use that directly
|
||||||
|
// otherwise, try to use the object with a dataUpdated method call
|
||||||
|
if (v.isFunction()) {
|
||||||
|
obj = getReceiver(dataEngine, source, v);
|
||||||
|
if (!obj) {
|
||||||
|
obj = new DataEngineReceiver(dataEngine, source, v, ScriptEnv::findScriptEnv(engine));
|
||||||
|
}
|
||||||
|
} else if (v.isObject()) {
|
||||||
|
obj = v.toQObject();
|
||||||
|
if (!obj || obj->metaObject()->indexOfSlot("dataUpdated(QString,Plasma::DataEngine::Data)") == -1) {
|
||||||
|
obj = getReceiver(dataEngine, source, v);
|
||||||
|
if (!obj) {
|
||||||
|
DataEngineReceiver *receiver = new DataEngineReceiver(dataEngine, source, v, ScriptEnv::findScriptEnv(engine));
|
||||||
|
if (receiver->isValid()) {
|
||||||
|
obj = receiver;
|
||||||
|
} else {
|
||||||
|
delete receiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj) {
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
int pollingInterval = 0;
|
||||||
|
Plasma::IntervalAlignment intervalAlignment = Plasma::NoAlignment;
|
||||||
|
if (context->argumentCount() > 2) {
|
||||||
|
pollingInterval = context->argument(2).toInt32();
|
||||||
|
|
||||||
|
if (context->argumentCount() > 3) {
|
||||||
|
intervalAlignment = static_cast<Plasma::IntervalAlignment>(context->argument(4).toInt32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataEngine->connectSource(source, obj, pollingInterval, intervalAlignment);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue DataEngineReceiver::disconnectSource(QScriptContext *context, QScriptEngine *engine)
|
||||||
|
{
|
||||||
|
if (context->argumentCount() < 2) {
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEngine *dataEngine = qobject_cast<DataEngine *>(context->thisObject().toQObject());
|
||||||
|
if (!dataEngine) {
|
||||||
|
//kDebug() << "no engine!";
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString source = context->argument(0).toString();
|
||||||
|
if (source.isEmpty()) {
|
||||||
|
//kDebug() << "no source!";
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *obj = 0;
|
||||||
|
QScriptValue v = context->argument(1);
|
||||||
|
if (v.isQObject()) {
|
||||||
|
obj = v.toQObject();
|
||||||
|
} else if (v.isObject() || v.isFunction()) {
|
||||||
|
foreach (DataEngineReceiver *receiver, DataEngineReceiver::s_receivers) {
|
||||||
|
if (receiver->matches(dataEngine, source, v)) {
|
||||||
|
obj = receiver;
|
||||||
|
receiver->deleteLater();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj) {
|
||||||
|
//kDebug() << "no object!";
|
||||||
|
return engine->undefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
dataEngine->disconnectSource(source, obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "dataenginereceiver.moc"
|
||||||
|
|
57
scriptengines/javascript/simplebindings/dataenginereceiver.h
Normal file
57
scriptengines/javascript/simplebindings/dataenginereceiver.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Aaron Seigo <aseigo@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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DATAENGINERECEIVER_H
|
||||||
|
#define DATAENGINERECEIVER_H
|
||||||
|
|
||||||
|
#include <QScriptValue>
|
||||||
|
|
||||||
|
#include <Plasma/DataEngine>
|
||||||
|
|
||||||
|
class QScriptContext;
|
||||||
|
class QScriptEngine;
|
||||||
|
|
||||||
|
class DataEngineReceiver : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
DataEngineReceiver(const Plasma::DataEngine *engine, const QString &source, const QScriptValue &func, QObject *parent);
|
||||||
|
~DataEngineReceiver();
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
static QScriptValue connectSource(QScriptContext *context, QScriptEngine *engine);
|
||||||
|
static QScriptValue disconnectSource(QScriptContext *context, QScriptEngine *engine);
|
||||||
|
static QSet<DataEngineReceiver*> s_receivers;
|
||||||
|
|
||||||
|
bool matches(const Plasma::DataEngine *engine, const QString &source, const QScriptValue &v);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void dataUpdated(const QString &source, const Plasma::DataEngine::Data &data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static DataEngineReceiver *getReceiver(Plasma::DataEngine *dataEngine, const QString &source, const QScriptValue &v);
|
||||||
|
|
||||||
|
const Plasma::DataEngine *m_engine;
|
||||||
|
const QString m_source;
|
||||||
|
QScriptValue m_func;
|
||||||
|
QScriptValue m_obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DATAENGINERECEIVER_H
|
||||||
|
|
@ -55,6 +55,7 @@
|
|||||||
#include "scriptenv.h"
|
#include "scriptenv.h"
|
||||||
#include "simplebindings/animationgroup.h"
|
#include "simplebindings/animationgroup.h"
|
||||||
#include "simplebindings/dataengine.h"
|
#include "simplebindings/dataengine.h"
|
||||||
|
#include "simplebindings/dataenginereceiver.h"
|
||||||
#include "simplebindings/i18n.h"
|
#include "simplebindings/i18n.h"
|
||||||
#include "simplebindings/appletinterface.h"
|
#include "simplebindings/appletinterface.h"
|
||||||
#include "simplebindings/bytearrayclass.h"
|
#include "simplebindings/bytearrayclass.h"
|
||||||
@ -157,23 +158,9 @@ void SimpleJavaScriptApplet::configChanged()
|
|||||||
|
|
||||||
void SimpleJavaScriptApplet::dataUpdated(const QString &name, const DataEngine::Data &data)
|
void SimpleJavaScriptApplet::dataUpdated(const QString &name, const DataEngine::Data &data)
|
||||||
{
|
{
|
||||||
QScriptValue fun = m_self.property("dataUpdated");
|
|
||||||
if (!fun.isFunction()) {
|
|
||||||
kDebug() << "Script: dataUpdated is not a function, " << fun.toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValueList args;
|
QScriptValueList args;
|
||||||
args << m_engine->toScriptValue(name) << m_engine->toScriptValue(data);
|
args << m_engine->toScriptValue(name) << m_engine->toScriptValue(data);
|
||||||
|
callFunction("dataUpdated", args);
|
||||||
QScriptContext *ctx = m_engine->pushContext();
|
|
||||||
ctx->setActivationObject(m_self);
|
|
||||||
fun.call(m_self, args);
|
|
||||||
m_engine->popContext();
|
|
||||||
|
|
||||||
if (m_engine->hasUncaughtException()) {
|
|
||||||
reportError(m_env);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleJavaScriptApplet::extenderItemRestored(Plasma::ExtenderItem* item)
|
void SimpleJavaScriptApplet::extenderItemRestored(Plasma::ExtenderItem* item)
|
||||||
@ -413,9 +400,12 @@ QScriptValue SimpleJavaScriptApplet::dataEngine(QScriptContext *context, QScript
|
|||||||
return context->throwError(i18n("Could not extract the Applet"));
|
return context->throwError(i18n("Could not extract the Applet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString dataEngine = context->argument(0).toString();
|
const QString dataEngineName = context->argument(0).toString();
|
||||||
DataEngine *data = interface->dataEngine(dataEngine);
|
DataEngine *dataEngine = interface->dataEngine(dataEngineName);
|
||||||
return engine->newQObject(data, QScriptEngine::QtOwnership, QScriptEngine::PreferExistingWrapperObject);
|
QScriptValue v = engine->newQObject(dataEngine, QScriptEngine::QtOwnership, QScriptEngine::PreferExistingWrapperObject);
|
||||||
|
v.setProperty("connectSource", engine->newFunction(DataEngineReceiver::connectSource));
|
||||||
|
v.setProperty("disconnectSource", engine->newFunction(DataEngineReceiver::disconnectSource));
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue SimpleJavaScriptApplet::service(QScriptContext *context, QScriptEngine *engine)
|
QScriptValue SimpleJavaScriptApplet::service(QScriptContext *context, QScriptEngine *engine)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user