diff options
-rw-r--r-- | examples/qtobject/main.cpp | 2 | ||||
-rw-r--r-- | examples/qtobject/qml/qtobject/index.html | 36 | ||||
-rw-r--r-- | examples/qtobject/qml/qtobject/main.qml | 53 | ||||
-rw-r--r-- | examples/qtobject/qml/qtobject/qtobject.js | 118 | ||||
-rw-r--r-- | examples/qtobject/qtmetaobjectpublisher.cpp | 32 | ||||
-rw-r--r-- | examples/qtobject/qtmetaobjectpublisher.h | 34 | ||||
-rw-r--r-- | examples/qtobject/qtobject.pro | 5 | ||||
-rw-r--r-- | examples/qtobject/testobject.cpp | 2 | ||||
-rw-r--r-- | examples/qtobject/testobject.h | 2 | ||||
-rw-r--r-- | src/MetaObjectPublisher.qml | 74 | ||||
-rw-r--r-- | src/qmldir | 3 | ||||
-rw-r--r-- | src/qobject.js | 119 | ||||
-rw-r--r-- | src/qtmetaobjectpublisher.cpp | 73 | ||||
-rw-r--r-- | src/qtmetaobjectpublisher.h | 74 | ||||
-rw-r--r-- | src/qwebchannel.cpp | 9 | ||||
-rw-r--r-- | src/qwebchannel_plugin.cpp | 3 | ||||
-rw-r--r-- | src/resources.qrc | 1 | ||||
-rw-r--r-- | src/src.pri | 4 | ||||
-rw-r--r-- | src/src.pro | 7 | ||||
-rw-r--r-- | src/webchannel-iframe.html | 1 |
20 files changed, 414 insertions, 238 deletions
diff --git a/examples/qtobject/main.cpp b/examples/qtobject/main.cpp index 6165664..fe8efff 100644 --- a/examples/qtobject/main.cpp +++ b/examples/qtobject/main.cpp @@ -3,13 +3,11 @@ #include <QtQml> #include "qtquick2applicationviewer.h" -#include "qtmetaobjectpublisher.h" #include "testobject.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); - qmlRegisterType<QtMetaObjectPublisher>("Qt.labs", 1, 0, "QtMetaObjectPublisher"); qmlRegisterType<TestObject>("Qt.labs", 1, 0, "TestObject"); QtQuick2ApplicationViewer viewer; diff --git a/examples/qtobject/qml/qtobject/index.html b/examples/qtobject/qml/qtobject/index.html index d79fd7e..a24dde3 100644 --- a/examples/qtobject/qml/qtobject/index.html +++ b/examples/qtobject/qml/qtobject/index.html @@ -1,21 +1,39 @@ <html> <head> - <script> - document.write('<script src="' + (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/]+)/.exec(location.search)[1]) + '/webchannel.js/createWebChannel"><' + '/script>'); + <script type="text/javascript"> + var base = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/]+)/.exec(location.search)[1]); + document.write('<script src="' + base + '/webchannel.js/setupWebChannel"></script>'); + document.write('<script src="' + base + '/qobject.js"><' + '/script>'); window.output = function(x) { document.querySelector("#out").innerHTML += x + "\n"; } - </script> - <script src="qtobject.js"></script> - <script> + window.onload = function() { + setupWebChannel(function(webChannel) { + setupQObjectWebChannel(webChannel); + }); + } </script> </head> <body> - <a href="#" onclick="testObject.debugMe('Debugging!', function(result) { output(result); })">invoke method</a> - <a href="#" onclick="testObject.prop1(function(value) { output(value); })">Get property</a> - <a href="#" onclick="testObject.prop1 = 'Different property'; testObject.prop1(function(value) { output(value); })">Set property</a> - <a href="#" onclick="testObject.timeout.connect(function() { output('timeout'); }); testObject.startTimer(1000);">Timer</a> + <p>TestObject 1: + <a href="#" onclick="testObject1.debugMe('Debugging!', function(result) { output(result); })">invoke method</a> + <a href="#" onclick="testObject1.prop1(function(value) { output(value); })">Get property</a> + <a href="#" onclick="testObject1.prop1 = 'Different property'; testObject1.prop1(function(value) { output(value); })">Set property</a> + <a href="#" onclick="testObject1.timeout.connect(function() { output('timeout 1'); }); testObject1.startTimer(1000);">Timer</a> + </p> + <p>TestObject 2: + <a href="#" onclick="testObject2.debugMe('Debugging!', function(result) { output(result); })">invoke method</a> + <a href="#" onclick="testObject2.prop1(function(value) { output(value); })">Get property</a> + <a href="#" onclick="testObject2.prop1 = 'Different property'; testObject2.prop1(function(value) { output(value); })">Set property</a> + <a href="#" onclick="testObject2.timeout.connect(function() { output('timeout 2'); }); testObject2.startTimer(1000);">Timer</a> + </p> + <p>TestObject 3: + <a href="#" onclick="testObject3.debugMe('Debugging!', function(result) { output(result); })">invoke method</a> + <a href="#" onclick="testObject3.prop1(function(value) { output(value); })">Get property</a> + <a href="#" onclick="testObject3.prop1 = 'Different property'; testObject3.prop1(function(value) { output(value); })">Set property</a> + <a href="#" onclick="testObject3.timeout.connect(function() { output('timeout 3'); }); testObject3.startTimer(1000);">Timer</a> + </p> <br/> <textarea id="out" style="height:80%; width: 80%"></textarea> </body> diff --git a/examples/qtobject/qml/qtobject/main.qml b/examples/qtobject/qml/qtobject/main.qml index 6ed3ad6..a4ab0c3 100644 --- a/examples/qtobject/qml/qtobject/main.qml +++ b/examples/qtobject/qml/qtobject/main.qml @@ -47,52 +47,45 @@ import QtWebKit 3.0 import QtWebKit.experimental 1.0 Rectangle { - QtMetaObjectPublisher { + MetaObjectPublisher { id: publisher } TestObject { - id: testObject + id: testObject1 + objectName: "object1" + } + + TestObject { + id: testObject2 + objectName: "object2" + } + + TestObject { + id: testObject3 + objectName: "object3" } WebChannel { id: webChannel onExecute: { var payload = JSON.parse(requestData); - var object = publisher.namedObject(payload.object); - var ret; - console.log(requestData); - if (payload.type == "Qt.invokeMethod") { - ret = (object[payload.method])(payload.args); - } else if (payload.type == "Qt.connectToSignal") { - object[payload.signal].connect( - function(a,b,c,d,e,f,g,h,i,j) { - broadcast("Qt.signal", JSON.stringify({object: payload.object, signal: payload.signal, args: [a,b,c,d,e,f,g,h,i,j]})); - }); - } else if (payload.type == "Qt.getProperty") { - ret = object[payload.property]; - } else if (payload.type == "Qt.setProperty") { - object[payload.property] = payload.value; - } else if (payload.type == "Qt.getObjects") { - var objectNames = publisher.objectNames; - for (var i = 0; i < objectNames.length; ++i) { - var name = objectNames[i]; - var o = publisher.namedObject(name); - addObject(name, o); - } + var ret = publisher.handleRequest(payload, webChannel); + if (!ret) { + console.log("unhandled request: ", requestData); + } else { + response.send(JSON.stringify(ret)); } - - response.send(JSON.stringify(ret)); } - function addObject(name, object) + function registerObjects(objects) { - publisher.addObject(name, object); - var metaData = { name: name, data: publisher.classInfoForObject(object) }; - broadcast("Qt.addToWindowObject", JSON.stringify(metaData)); + for (var name in objects) { + publisher.addObject(name, objects[name]); + } } - onBaseUrlChanged: addObject("testObject", testObject) + onBaseUrlChanged: registerObjects({"testObject1": testObject1, "testObject2": testObject2, "testObject3":testObject3}) } width: 480 diff --git a/examples/qtobject/qml/qtobject/qtobject.js b/examples/qtobject/qml/qtobject/qtobject.js deleted file mode 100644 index 0553a36..0000000 --- a/examples/qtobject/qml/qtobject/qtobject.js +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QWebChannel module on Qt labs. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -window.onload = function() { - createWebChannel(function(webChannel) { - var allSignals = {}; - webChannel.subscribe( - "Qt.signal", - function(payload) { - var signalData = JSON.parse(payload); - var object = allSignals[signalData.object]; - var conns = (object ? object[signalData.signal] : []) || []; - var a = payload.args; - conns.forEach(function(callback) { - callback.call(a); - }); - } - ); - webChannel.subscribe( - "Qt.addToWindowObject", - function(payload) { - var addObjectData = JSON.parse(payload); - var objectSignals = {}; - var methodsAndSignals = []; - var object = {}; - var objectName = addObjectData.name; - var data = addObjectData.data; - for (var i in data.methods) - methodsAndSignals.push(data.methods[i]); - for (i in data.signals) - methodsAndSignals.push(data.signals[i]); - - methodsAndSignals.forEach(function(method) { - object[method] = function() { - var args = []; - var callback; - for (var i = 0; i < arguments.length; ++i) { - if (typeof arguments[i] == "function") - callback = arguments[i]; - else - args.push(arguments[i]); - } - - webChannel.exec(JSON.stringify({type: "Qt.invokeMethod", object: objectName, method: method, args: args}), function(response) { - if (response.length) - (callback)(JSON.parse(response)); - }); - }; - }); - - for (i in data.signals) { - var signal = data.signals[i]; - object[signal].connect = function(callback) { - objectSignals[signal] = objectSignals[signal] || []; - webChannel.exec(JSON.stringify({type: "Qt.connectToSignal", object: objectName, signal: signal})); - objectSignals[signal].push(callback); - }; - } - allSignals[objectName] = objectSignals; - - for (i in data.properties) { - var prop = data.properties[i]; - object.__defineSetter__(prop, function(value) { - webChannel.exec(JSON.stringify({type: "Qt.setProperty", object: objectName, property: prop, value: value })); - }); - object.__defineGetter__(prop, function() { - return (function(callback) { - webChannel.exec(JSON.stringify({type: "Qt.getProperty", object: objectName, property: prop}), function(response) { - callback(JSON.parse(response)); - }); - }); - }); - } - - window[objectName] = object; - } - ); - webChannel.exec(JSON.stringify({type:"Qt.getObjects"})); - }); -}; diff --git a/examples/qtobject/qtmetaobjectpublisher.cpp b/examples/qtobject/qtmetaobjectpublisher.cpp deleted file mode 100644 index db86145..0000000 --- a/examples/qtobject/qtmetaobjectpublisher.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "qtmetaobjectpublisher.h" -#include <QVariantMap> -#include <QStringList> -#include <QMetaObject> -#include <QMetaProperty> - -QtMetaObjectPublisher::QtMetaObjectPublisher(QObject *parent) : - QObject(parent) -{ -} - -QVariantMap QtMetaObjectPublisher::classInfoForObject(QObject *object) -{ - QVariantMap data; - QStringList qtSignals, qtMethods, qtProperties; - const QMetaObject* metaObject = object->metaObject(); - for (int i = 0; i < metaObject->propertyCount(); ++i) - qtProperties.append(metaObject->property(i).name()); - for (int i = 0; i < metaObject->methodCount(); ++i) { - QMetaMethod method = metaObject->method(i); - QString signature = method.methodSignature(); - QString name = signature.left(signature.indexOf("(")); - if (method.access() == QMetaMethod::Public) - qtMethods << signature << name; - if (method.methodType() == QMetaMethod::Signal) - qtSignals << signature << name; - } - data["signals"] = qtSignals; - data["methods"] = qtMethods; - data["properties"] = qtProperties; - return data; -} diff --git a/examples/qtobject/qtmetaobjectpublisher.h b/examples/qtobject/qtmetaobjectpublisher.h deleted file mode 100644 index 3262525..0000000 --- a/examples/qtobject/qtmetaobjectpublisher.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef QTMETAOBJECTPUBLISHER_H -#define QTMETAOBJECTPUBLISHER_H - -#include <QObject> -#include <QVariantMap> -#include <QPointer> -#include <QStringList> - -class QtMetaObjectPublisher : public QObject -{ - Q_OBJECT - Q_PROPERTY(QStringList objectNames READ objectNames) -public: - explicit QtMetaObjectPublisher(QObject *parent = 0); - Q_INVOKABLE QVariantMap classInfoForObject(QObject*); - QStringList objectNames() { return objects.keys(); } - Q_INVOKABLE QObject* namedObject(const QString& name) { - if (!objects.contains(name)) - return 0; - return objects[name]; - } - -public slots: - void addObject(const QString& name, QObject* object) - { - objects[name] = object; - } - -private: - QMap<QString, QPointer<QObject> > objects; - -}; - -#endif // QTMETAOBJECTPUBLISHER_H diff --git a/examples/qtobject/qtobject.pro b/examples/qtobject/qtobject.pro index 0be2129..b6ff512 100644 --- a/examples/qtobject/qtobject.pro +++ b/examples/qtobject/qtobject.pro @@ -14,12 +14,9 @@ QML_IMPORT_PATH = # The .cpp file which was generated for your project. Feel free to hack it. SOURCES += main.cpp \ - qtmetaobjectpublisher.cpp \ testobject.cpp -HEADERS += \ - qtmetaobjectpublisher.h \ - testobject.h +HEADERS += testobject.h # Please do not modify the following two lines. Required for deployment. include(qtquick2applicationviewer/qtquick2applicationviewer.pri) diff --git a/examples/qtobject/testobject.cpp b/examples/qtobject/testobject.cpp index f13c5ab..75daa8d 100644 --- a/examples/qtobject/testobject.cpp +++ b/examples/qtobject/testobject.cpp @@ -10,7 +10,7 @@ TestObject::TestObject(QObject *parent) : QString TestObject::debugMe(const QString& data) { qWarning() << data; - return "OK"; + return QString("OK from %1: %2").arg(objectName()).arg(data); } void TestObject::setProp1(const QString& s) diff --git a/examples/qtobject/testobject.h b/examples/qtobject/testobject.h index 93aa227..992247d 100644 --- a/examples/qtobject/testobject.h +++ b/examples/qtobject/testobject.h @@ -10,7 +10,7 @@ class TestObject : public QObject Q_PROPERTY(QString prop1 READ prop1 WRITE setProp1) public: explicit TestObject(QObject *parent = 0); - QString prop1() const { return p1; } + QString prop1() const { return p1 + objectName(); } void setProp1(const QString& s); signals: diff --git a/src/MetaObjectPublisher.qml b/src/MetaObjectPublisher.qml new file mode 100644 index 0000000..e938a83 --- /dev/null +++ b/src/MetaObjectPublisher.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QWebChannel module on Qt labs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +import Qt.labs.WebChannel 1.0 + +MetaObjectPublisherPrivate { + function handleRequest(payload, webChannel) { + var object = publisher.namedObject(payload.object); + var ret = false; + if (payload.type == "Qt.invokeMethod") { + ret = (object[payload.method])(payload.args); + } else if (payload.type == "Qt.connectToSignal") { + object[payload.signal].connect( + function(a,b,c,d,e,f,g,h,i,j) { + webChannel.broadcast("Qt.signal", JSON.stringify({object: payload.object, signal: payload.signal, args: [a,b,c,d,e,f,g,h,i,j]})); + }); + } else if (payload.type == "Qt.getProperty") { + ret = object[payload.property]; + } else if (payload.type == "Qt.setProperty") { + object[payload.property] = payload.value; + } else if (payload.type == "Qt.getObjects") { + var objects = {}; + var objectNames = publisher.objectNames; + for (var i = 0; i < objectNames.length; ++i) { + var name = objectNames[i]; + var object = publisher.namedObject(name); + objects[name] = publisher.classInfoForObject(object); + } + ret = objects; + } + + return ret; + } +}
\ No newline at end of file @@ -1,2 +1,3 @@ +module Qt.labs.WebChannel plugin qwebchannel - +MetaObjectPublisher 1.0 MetaObjectPublisher.qml
\ No newline at end of file diff --git a/src/qobject.js b/src/qobject.js new file mode 100644 index 0000000..d5d7f42 --- /dev/null +++ b/src/qobject.js @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QWebChannel module on Qt labs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function QObject(name, data, webChannel) { + this.__id__ = name; + this.__objectSignals__ = {}; + + var methodsAndSignals = []; + for (var i in data.methods) + methodsAndSignals.push(data.methods[i]); + for (i in data.signals) + methodsAndSignals.push(data.signals[i]); + + var object = this; + + methodsAndSignals.forEach(function(method) { + object[method] = function() { + var args = []; + var callback; + for (var i = 0; i < arguments.length; ++i) { + if (typeof arguments[i] == "function") + callback = arguments[i]; + else + args.push(arguments[i]); + } + + webChannel.exec(JSON.stringify({"type": "Qt.invokeMethod", "object": object.__id__, "method": method, "args": args}), function(response) { + if (response.length) + (callback)(JSON.parse(response)); + }); + }; + }); + + for (i in data.signals) { + var signal = data.signals[i]; + object[signal].connect = function(callback) { + object.__objectSignals__[signal] = object.__objectSignals__[signal] || []; + webChannel.exec(JSON.stringify({"type": "Qt.connectToSignal", "object": object.__id__, "signal": signal})); + object.__objectSignals__[signal].push(callback); + }; + } + + for (i in data.properties) { + var prop = data.properties[i]; + object.__defineSetter__(prop, function(value) { + webChannel.exec(JSON.stringify({"type": "Qt.setProperty", "object": object.__id__, "property": prop, "value": value })); + }); + object.__defineGetter__(prop, function() { + return (function(callback) { + webChannel.exec(JSON.stringify({"type": "Qt.getProperty", "object": object.__id__, "property": prop}), function(response) { + callback(JSON.parse(response)); + }); + }); + }); + } +} + +window.setupQObjectWebChannel = function(webChannel) { + webChannel.subscribe( + "Qt.signal", + function(payload) { + var signalData = JSON.parse(payload); + var object = window[signalData.object]; + var conns = (object ? object.__objectSignals__[signalData.signal] : []) || []; + var a = payload.args; + conns.forEach(function(callback) { + callback.call(a); + }); + } + ); + webChannel.exec(JSON.stringify({type:"Qt.getObjects"}), function(response) { + if (response.length) { + var objects = JSON.parse(response); + for (var objectName in objects) { + var data = objects[objectName]; + var object = new QObject(objectName, data, webChannel); + window[objectName] = object; + } + } + }); +}; diff --git a/src/qtmetaobjectpublisher.cpp b/src/qtmetaobjectpublisher.cpp new file mode 100644 index 0000000..d136ce7 --- /dev/null +++ b/src/qtmetaobjectpublisher.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QWebChannel module on Qt labs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtmetaobjectpublisher.h" +#include <QVariantMap> +#include <QStringList> +#include <QMetaObject> +#include <QMetaProperty> + +QtMetaObjectPublisher::QtMetaObjectPublisher(QObject *parent) : + QObject(parent) +{ +} + +QVariantMap QtMetaObjectPublisher::classInfoForObject(QObject *object) +{ + QVariantMap data; + QStringList qtSignals, qtMethods, qtProperties; + const QMetaObject* metaObject = object->metaObject(); + for (int i = 0; i < metaObject->propertyCount(); ++i) + qtProperties.append(metaObject->property(i).name()); + for (int i = 0; i < metaObject->methodCount(); ++i) { + QMetaMethod method = metaObject->method(i); + QString signature = method.methodSignature(); + QString name = signature.left(signature.indexOf("(")); + if (method.access() == QMetaMethod::Public) + qtMethods << signature << name; + if (method.methodType() == QMetaMethod::Signal) + qtSignals << signature << name; + } + data["signals"] = qtSignals; + data["methods"] = qtMethods; + data["properties"] = qtProperties; + return data; +} diff --git a/src/qtmetaobjectpublisher.h b/src/qtmetaobjectpublisher.h new file mode 100644 index 0000000..816338a --- /dev/null +++ b/src/qtmetaobjectpublisher.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QWebChannel module on Qt labs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTMETAOBJECTPUBLISHER_H +#define QTMETAOBJECTPUBLISHER_H + +#include <QObject> +#include <QVariantMap> +#include <QPointer> +#include <QStringList> + +class QtMetaObjectPublisher : public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringList objectNames READ objectNames) +public: + explicit QtMetaObjectPublisher(QObject *parent = 0); + Q_INVOKABLE QVariantMap classInfoForObject(QObject*); + QStringList objectNames() { return objects.keys(); } + Q_INVOKABLE QObject* namedObject(const QString& name) { + if (!objects.contains(name)) + return 0; + return objects[name]; + } +public slots: + void addObject(const QString& name, QObject* object) + { + objects[name] = object; + } + +private: + QMap<QString, QPointer<QObject> > objects; + +}; + +#endif // QTMETAOBJECTPUBLISHER_H diff --git a/src/qwebchannel.cpp b/src/qwebchannel.cpp index 6d7d62f..ee03cf8 100644 --- a/src/qwebchannel.cpp +++ b/src/qwebchannel.cpp @@ -311,6 +311,15 @@ void QWebChannelPrivate::handleHttpRequest(QTcpSocket *socket, const HttpRequest socket->write("\n})();"); socket->close(); file.close(); + } else if (type == "qobject.js") { + QFile file(":/qobject.js"); + file.open(QIODevice::ReadOnly); + socket->write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/javascript\r\n" + "\r\n"); + socket->write(file.readAll()); + socket->close(); + file.close(); } else if (type == "iframe.html") { QFile file(":/webchannel-iframe.html"); file.open(QIODevice::ReadOnly); diff --git a/src/qwebchannel_plugin.cpp b/src/qwebchannel_plugin.cpp index a0675d6..1c71463 100644 --- a/src/qwebchannel_plugin.cpp +++ b/src/qwebchannel_plugin.cpp @@ -42,12 +42,13 @@ #include <qqml.h> #include "qwebchannel.h" +#include "qtmetaobjectpublisher.h" #include "qwebchannel_plugin.h" void QWebChannelPlugin::registerTypes(const char *uri) { - Q_ASSERT(uri == QLatin1String("Qt.labs.WebChannel")); qmlRegisterType<QWebChannel>(uri, 1, 0, "WebChannel"); + qmlRegisterType<QtMetaObjectPublisher>(uri, 1, 0, "MetaObjectPublisherPrivate"); } diff --git a/src/resources.qrc b/src/resources.qrc index 6f81393..431c12b 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -1,6 +1,7 @@ <RCC> <qresource prefix="/"> <file>webchannel.js</file> + <file>qobject.js</file> <file>webchannel-iframe.html</file> </qresource> </RCC> diff --git a/src/src.pri b/src/src.pri index c64cc76..55ed7e3 100644 --- a/src/src.pri +++ b/src/src.pri @@ -1,3 +1,3 @@ QT += network -SOURCES += $$PWD/qwebchannel.cpp -HEADERS += $$PWD/qwebchannel.h +SOURCES += $$PWD/qwebchannel.cpp $$PWD/qtmetaobjectpublisher.cpp +HEADERS += $$PWD/qwebchannel.h $$PWD/qtmetaobjectpublisher.h diff --git a/src/src.pro b/src/src.pro index 1f940c6..1f5a62e 100644 --- a/src/src.pro +++ b/src/src.pro @@ -13,7 +13,6 @@ SOURCES += qwebchannel_plugin.cpp HEADERS += qwebchannel_plugin.h OTHER_FILES = qmldir \ - qwebchannel.js \ qtc_packaging/debian_harmattan/rules \ qtc_packaging/debian_harmattan/README \ qtc_packaging/debian_harmattan/copyright \ @@ -21,7 +20,9 @@ OTHER_FILES = qmldir \ qtc_packaging/debian_harmattan/compat \ qtc_packaging/debian_harmattan/changelog \ webchannel.js \ - webchannel-iframe.html + qobject.js \ + webchannel-iframe.html \ + MetaObjectPublisher.qml !equals(_PRO_FILE_PWD_, $$OUT_PWD) { copy_qmldir.target = $$OUT_PWD/qmldir @@ -33,7 +34,7 @@ OTHER_FILES = qmldir \ target.path = $$[QT_INSTALL_QML]/$$TARGETPATH -qmldir.files += $$PWD/qmldir +qmldir.files += $$PWD/qmldir $$PWD/MetaObjectPublisher.qml qmldir.path += $$[QT_INSTALL_QML]/$$TARGETPATH INSTALLS += target qmldir diff --git a/src/webchannel-iframe.html b/src/webchannel-iframe.html index 1f93eac..bbaf7cd 100644 --- a/src/webchannel-iframe.html +++ b/src/webchannel-iframe.html @@ -24,6 +24,7 @@ window.addEventListener("message", function(event) { var data = JSON.parse(event.data); + console.log("MESSAGE:", data); function callback(r) { window.parent.postMessage(JSON.stringify({ type: "callback", id: data.id, payload: r }), "*"); } if (data.type == "EXEC") exec(data.payload, callback); |