summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-03-05 08:04:37 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-03-05 08:04:37 (GMT)
commitdcd17fa7b77cb6adfb8b21ea90c113915cab9bd5 (patch)
tree37dca0549529fe43b6e98af3adab133a9f5991d1
parent4a6154ec912d5b84a556aa731c5b7de8f758ba3d (diff)
downloadQt-dcd17fa7b77cb6adfb8b21ea90c113915cab9bd5.zip
Qt-dcd17fa7b77cb6adfb8b21ea90c113915cab9bd5.tar.gz
Qt-dcd17fa7b77cb6adfb8b21ea90c113915cab9bd5.tar.bz2
Add support for QtScript connect/disconnect syntax in QML
This support was accidentally removed as a consequence of 4a665ff5da05860f5eb46e3982ef3d8163a6cf59. QTBUG-8001
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp81
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass_p.h12
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml16
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml15
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml12
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml11
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml20
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml20
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp162
13 files changed, 427 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 2e4ffa7..e6f6e5f 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -442,6 +442,13 @@ QDeclarativeObjectMethodScriptClass::QDeclarativeObjectMethodScriptClass(QDeclar
engine(bindEngine)
{
setSupportsCall(true);
+
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+
+ m_connect = scriptEngine->newFunction(connect);
+ m_connectId = createPersistentIdentifier(QLatin1String("connect"));
+ m_disconnect = scriptEngine->newFunction(disconnect);
+ m_disconnectId = createPersistentIdentifier(QLatin1String("disconnect"));
}
QDeclarativeObjectMethodScriptClass::~QDeclarativeObjectMethodScriptClass()
@@ -455,6 +462,80 @@ QScriptValue QDeclarativeObjectMethodScriptClass::newMethod(QObject *object, con
return newObject(scriptEngine, this, new MethodData(object, *method));
}
+QScriptValue QDeclarativeObjectMethodScriptClass::connect(QScriptContext *context, QScriptEngine *engine)
+{
+ QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
+
+ QScriptValue that = context->thisObject();
+ if (&p->objectClass->methods != scriptClass(that))
+ return engine->undefinedValue();
+
+ MethodData *data = (MethodData *)object(that);
+
+ if (!data->object || context->argumentCount() == 0)
+ return engine->undefinedValue();
+
+ QByteArray signal("2");
+ signal.append(data->object->metaObject()->method(data->data.coreIndex).signature());
+
+ if (context->argumentCount() == 1) {
+ qScriptConnect(data->object, signal.constData(), QScriptValue(), context->argument(0));
+ } else {
+ qScriptConnect(data->object, signal.constData(), context->argument(0), context->argument(1));
+ }
+
+ return engine->undefinedValue();
+}
+
+QScriptValue QDeclarativeObjectMethodScriptClass::disconnect(QScriptContext *context, QScriptEngine *engine)
+{
+ QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
+
+ QScriptValue that = context->thisObject();
+ if (&p->objectClass->methods != scriptClass(that))
+ return engine->undefinedValue();
+
+ MethodData *data = (MethodData *)object(that);
+
+ if (!data->object || context->argumentCount() == 0)
+ return engine->undefinedValue();
+
+ QByteArray signal("2");
+ signal.append(data->object->metaObject()->method(data->data.coreIndex).signature());
+
+ if (context->argumentCount() == 1) {
+ qScriptDisconnect(data->object, signal.constData(), QScriptValue(), context->argument(0));
+ } else {
+ qScriptDisconnect(data->object, signal.constData(), context->argument(0), context->argument(1));
+ }
+
+ return engine->undefinedValue();
+}
+
+QScriptClass::QueryFlags
+QDeclarativeObjectMethodScriptClass::queryProperty(Object *, const Identifier &name,
+ QScriptClass::QueryFlags flags)
+{
+ if (name == m_connectId.identifier || name == m_disconnectId.identifier)
+ return QScriptClass::HandlesReadAccess;
+ else
+ return 0;
+
+}
+
+QDeclarativeObjectScriptClass::ScriptValue
+QDeclarativeObjectMethodScriptClass::property(Object *, const Identifier &name)
+{
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+
+ if (name == m_connectId.identifier)
+ return Value(scriptEngine, m_connect);
+ else if (name == m_disconnectId.identifier)
+ return Value(scriptEngine, m_disconnect);
+ else
+ return Value();
+}
+
namespace {
struct MetaCallArgument {
inline MetaCallArgument();
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
index 8023756..04e760f 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
@@ -73,10 +73,21 @@ public:
~QDeclarativeObjectMethodScriptClass();
QScriptValue newMethod(QObject *, const QDeclarativePropertyCache::Data *);
+
protected:
virtual Value call(Object *, QScriptContext *);
+ virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags);
+ virtual Value property(Object *, const Identifier &);
private:
+ PersistentIdentifier m_connectId;
+ PersistentIdentifier m_disconnectId;
+ QScriptValue m_connect;
+ QScriptValue m_disconnect;
+
+ static QScriptValue connect(QScriptContext *context, QScriptEngine *engine);
+ static QScriptValue disconnect(QScriptContext *context, QScriptEngine *engine);
+
QDeclarativeEngine *engine;
};
#endif
@@ -119,6 +130,7 @@ protected:
private:
#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
+ friend class QDeclarativeObjectMethodScriptClass;
QDeclarativeObjectMethodScriptClass methods;
#endif
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml
new file mode 100644
index 0000000..2bdd706
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml
@@ -0,0 +1,16 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property bool test: false
+
+ id: root
+
+ Script {
+ function testFunction() {
+ test = true;
+ }
+ }
+
+ Component.onCompleted: root.argumentSignal.connect(testFunction);
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml
new file mode 100644
index 0000000..fa90918
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml
@@ -0,0 +1,22 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property bool test: false
+
+ id: root
+
+ Script {
+ function testFunction() {
+ if (this.b == 12)
+ test = true;
+ }
+ }
+
+ Component.onCompleted: {
+ var a = new Object;
+ a.b = 12;
+ root.argumentSignal.connect(a, testFunction);
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml
new file mode 100644
index 0000000..0d8e6ef
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml
@@ -0,0 +1,15 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property bool test: false
+
+ id: root
+
+ function testFunction() {
+ test = true;
+ }
+
+ Component.onCompleted: root.argumentSignal.connect(testFunction);
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml
new file mode 100644
index 0000000..3e1ff1b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml
@@ -0,0 +1,12 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property bool test: false
+
+ id: root
+
+ Component.onCompleted: root.argumentSignal.connect(methodNoArgs);
+}
+
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml
new file mode 100644
index 0000000..3ad5cbc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property bool test: false
+
+ id: root
+
+ Component.onCompleted: root.argumentSignal.connect(root, methodNoArgs);
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml
new file mode 100644
index 0000000..8c35db1
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml
@@ -0,0 +1,20 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property int test: 0
+
+ id: root
+
+ Script {
+ function testFunction() {
+ test++;
+ }
+ }
+
+ Component.onCompleted: {
+ root.argumentSignal.connect(testFunction);
+ root.argumentSignal.connect(testFunction);
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml
new file mode 100644
index 0000000..45c4f73
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml
@@ -0,0 +1,18 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property int test: 0
+
+ id: root
+
+ Script {
+ function testFunction() {
+ test++;
+ }
+ }
+
+ Component.onCompleted: root.argumentSignal.connect(testFunction);
+
+ onBasicSignal: root.argumentSignal.disconnect(testFunction);
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml
new file mode 100644
index 0000000..a47fe74
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml
@@ -0,0 +1,19 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property int test: 0
+
+ id: root
+
+ Script {
+ function testFunction() {
+ test++;
+ }
+ }
+
+ Component.onCompleted: root.argumentSignal.connect(root, testFunction);
+
+ onBasicSignal: root.argumentSignal.disconnect(root, testFunction);
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml
new file mode 100644
index 0000000..c95ffbf
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml
@@ -0,0 +1,19 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property int test: 0
+
+ id: root
+
+ Script {
+ function testFunction() {
+ test++;
+ }
+ }
+
+ Component.onCompleted: root.argumentSignal.connect(root, testFunction);
+
+ onBasicSignal: root.argumentSignal.disconnect(testFunction);
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml
new file mode 100644
index 0000000..342f24a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml
@@ -0,0 +1,20 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyQmlObject {
+ property int test: 0
+
+ id: root
+
+ Script {
+ function testFunction() {
+ test++;
+ }
+ function otherFunction() {
+ }
+ }
+
+ Component.onCompleted: root.argumentSignal.connect(testFunction);
+
+ onBasicSignal: root.argumentSignal.disconnect(otherFunction);
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index b5649cb..4838288 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -124,6 +124,8 @@ private slots:
void deletedObject();
void scriptScope();
void attachedPropertyScope();
+ void scriptConnect();
+ void scriptDisconnect();
void bug1();
@@ -1731,6 +1733,166 @@ void tst_qdeclarativeecmascript::attachedPropertyScope()
delete object;
}
+void tst_qdeclarativeecmascript::scriptConnect()
+{
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.1.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), false);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toBool(), true);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.2.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), false);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toBool(), true);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.3.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), false);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toBool(), true);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.4.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->methodCalled(), false);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->methodCalled(), true);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.5.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->methodCalled(), false);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->methodCalled(), true);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.6.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 0);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+
+ delete object;
+ }
+}
+
+void tst_qdeclarativeecmascript::scriptDisconnect()
+{
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.1.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 0);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 1);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->basicSignal();
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.2.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 0);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 1);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->basicSignal();
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+
+ delete object;
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.3.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 0);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 1);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->basicSignal();
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 3);
+
+ delete object;
+ }
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.4.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 0);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 1);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->basicSignal();
+ QCOMPARE(object->property("test").toInt(), 2);
+ emit object->argumentSignal(19, "Hello world!", 10.3);
+ QCOMPARE(object->property("test").toInt(), 3);
+
+ delete object;
+ }
+
+}
+
QTEST_MAIN(tst_qdeclarativeecmascript)
#include "tst_qdeclarativeecmascript.moc"