summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-10-09 10:17:04 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-10-09 10:17:04 (GMT)
commita700d7c263748d3635eb06a7091164fd75ec608c (patch)
tree17fc6e408bc49003ddb5800ca6a60f5725849626
parent65aa9ff2704fed181eee2b189fc0db81a59ff75f (diff)
downloadQt-a700d7c263748d3635eb06a7091164fd75ec608c.zip
Qt-a700d7c263748d3635eb06a7091164fd75ec608c.tar.gz
Qt-a700d7c263748d3635eb06a7091164fd75ec608c.tar.bz2
Add id aliases
-rw-r--r--doc/src/declarative/extending.qdoc6
-rw-r--r--src/declarative/qml/qmlcompiler.cpp33
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp26
-rw-r--r--tests/auto/declarative/qmllanguage/data/alias.5.qml13
-rw-r--r--tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp24
5 files changed, 82 insertions, 20 deletions
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index 649eab1..bc18108 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -645,13 +645,13 @@ value, a property alias includes a compulsary alias reference. The alias
reference is used to locate the aliased property. While similar to a property
binding, the alias reference syntax is highly restricted.
-An alias reference takes the form
+An alias reference takes one of the following forms
\code
<Id>.<property>
+ <Id>
\endcode
where <Id> must refer to an object id within the same component as the type
-declaring the alias, and <property> refers to a property on this object. The
-alias reference syntax may become more flexibly in future releases.
+declaring the alias, and, optionally, <property> refers to a property on that object.
Here is the property definition example rewritten to use property aliases.
\code
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 8856892..d36b1c9 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -2236,31 +2236,44 @@ bool QmlCompiler::compileAlias(QMetaObjectBuilder &builder,
QStringList alias = astNodeToStringList(node);
- if (alias.count() != 2)
+ if (alias.count() != 1 && alias.count() != 2)
COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
if (!compileState.ids.contains(alias.at(0)))
COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
Object *idObject = compileState.ids[alias.at(0)];
- int propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
- if (-1 == propIdx)
- COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
+ QByteArray typeName;
+
+ int propIdx = -1;
+ bool writable = false;
+ if (alias.count() == 2) {
+ propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
+
+ if (-1 == propIdx)
+ COMPILE_EXCEPTION(prop.defaultValue, "Invalid alias location");
+
+ QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
+ writable = aliasProperty.isWritable();
- QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
+ if (aliasProperty.isEnumType())
+ typeName = "int"; // Avoid introducing a dependency on the aliased metaobject
+ else
+ typeName = aliasProperty.typeName();
+ } else {
+ typeName = idObject->metaObject()->className();
+ typeName += "*";
+ }
data.append((const char *)&idObject->idIndex, sizeof(idObject->idIndex));
data.append((const char *)&propIdx, sizeof(propIdx));
- const char *typeName = aliasProperty.typeName();
- if (aliasProperty.isEnumType())
- typeName = "int"; // Avoid introducing a dependency on the aliased metaobject
-
builder.addSignal(prop.name + "Changed()");
QMetaPropertyBuilder propBuilder =
- builder.addProperty(prop.name, typeName, builder.methodCount() - 1);
+ builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
propBuilder.setScriptable(true);
+ propBuilder.setWritable(writable);
return true;
}
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index f473743..a324795 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -181,20 +181,32 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
(QmlContextPrivate *)QObjectPrivate::get(ctxt);
QObject *target = ctxtPriv->idValues[d->contextIdx].data();
- if (!target) return -1;
+ if (!target) {
+ if (d->propertyIdx == -1)
+ *reinterpret_cast<QObject **>(a[0]) = target;
+ return -1;
+ }
if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) {
int sigIdx = methodOffset + id + metaData->propertyCount;
QMetaObject::connect(ctxt, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx);
- QMetaProperty prop =
- target->metaObject()->property(d->propertyIdx);
- if (prop.hasNotifySignal())
- QMetaObject::connect(target, prop.notifySignalIndex(),
- object, sigIdx);
+ if (d->propertyIdx != -1) {
+ QMetaProperty prop =
+ target->metaObject()->property(d->propertyIdx);
+ if (prop.hasNotifySignal())
+ QMetaObject::connect(target, prop.notifySignalIndex(),
+ object, sigIdx);
+ }
aConnected.setBit(id);
}
- return QMetaObject::metacall(target, c, d->propertyIdx, a);
+
+ if (d->propertyIdx == -1) {
+ *reinterpret_cast<QObject **>(a[0]) = target;
+ return -1;
+ } else {
+ return QMetaObject::metacall(target, c, d->propertyIdx, a);
+ }
}
return -1;
diff --git a/tests/auto/declarative/qmllanguage/data/alias.5.qml b/tests/auto/declarative/qmllanguage/data/alias.5.qml
new file mode 100644
index 0000000..39bfd9b
--- /dev/null
+++ b/tests/auto/declarative/qmllanguage/data/alias.5.qml
@@ -0,0 +1,13 @@
+import Qt 4.6
+import Test 1.0
+
+Object {
+ property alias otherAlias: otherObject
+
+ property var other
+ other: MyQmlObject {
+ id: otherObject
+ value: 10
+ }
+}
+
diff --git a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp
index 135a207..ff78e6d 100644
--- a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp
+++ b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp
@@ -620,6 +620,30 @@ void tst_qmllanguage::aliasProperties()
QVERIFY(object != 0);
QCOMPARE(object->property("enumAlias").toInt(), 1);
+
+ delete object;
+ }
+
+ // Id aliases
+ {
+ QmlComponent component(&engine, TEST_FILE("alias.5.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QVariant v = object->property("otherAlias");
+ QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
+ MyQmlObject *o = qvariant_cast<MyQmlObject*>(v);
+ QCOMPARE(o->value(), 10);
+
+ delete o;
+
+ v = object->property("otherAlias");
+ QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
+ o = qvariant_cast<MyQmlObject*>(v);
+ QVERIFY(o == 0);
+
+ delete object;
}
}