Skip to content

Commit

Permalink
Allow literal enum to int property assignments
Browse files Browse the repository at this point in the history
Previously, enum to int property assignments were considered bindings.
This commit adds support for assigning enum values to int properties
as enums.

Note that to use an enum in QML, it must have been declared with
Q_ENUMS or otherwise registered as a metatype.  Enum values from the
global Qt object are also usable.

Task-number: QTBUG-23403
Change-Id: I50db6cae54a24400ea472bde43619d547e4ceb78
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
  • Loading branch information
Chris Adams authored and Qt by Nokia committed Mar 21, 2012
1 parent b2722ab commit 4c9d326
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/qml/qml/qqmlcompiler.cpp
Expand Up @@ -2227,7 +2227,7 @@ bool QQmlCompiler::buildValueTypeProperty(QObject *type,
//optimization for <Type>.<EnumValue> enum assignments
bool isEnumAssignment = false;

if (prop->core.isEnum())
if (prop->core.isEnum() || prop->core.propType == QMetaType::Int)
COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, value, &isEnumAssignment));

if (isEnumAssignment) {
Expand Down Expand Up @@ -2495,7 +2495,7 @@ bool QQmlCompiler::buildPropertyLiteralAssignment(QQmlScript::Property *prop,
if (v->value.isScript()) {

//optimization for <Type>.<EnumValue> enum assignments
if (prop->core.isEnum()) {
if (prop->core.isEnum() || prop->core.propType == QMetaType::Int) {
bool isEnumAssignment = false;
COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, v, &isEnumAssignment));
if (isEnumAssignment) {
Expand Down Expand Up @@ -2525,8 +2525,9 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
QQmlScript::Value *v,
bool *isAssignment)
{
bool isIntProp = (prop->core.propType == QMetaType::Int) && !prop->core.isEnum();
*isAssignment = false;
if (!prop->core.isEnum())
if (!prop->core.isEnum() && !isIntProp)
return true;

QMetaProperty mprop = obj->metaObject()->property(prop->index);
Expand All @@ -2538,6 +2539,17 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
if (!string.at(0).isUpper())
return true;

if (isIntProp) {
// Allow enum assignment to ints.
int enumval = evaluateEnum(string.toUtf8());
if (enumval != -1) {
v->type = Value::Literal;
v->value = QQmlScript::Variant((double)enumval);
*isAssignment = true;
}
return true;
}

QStringList parts = string.split(QLatin1Char('.'));
if (parts.count() != 2)
return true;
Expand Down
41 changes: 41 additions & 0 deletions tests/auto/qml/qqmlecmascript/data/enums.3.qml
@@ -0,0 +1,41 @@
import QtQuick 2.0
import Qt.test 1.0
import Qt.test 1.0 as Namespace

Item {
// Enums from type
property int a: Item.Center
property int b: Item.Right

// Enums from Qt
property int c: Qt.blue
property int d: Qt.darkRed

// Enums from other type
property int e: MyQmlObject.EnumValue3
property int f: MyQmlObject.EnumValue4

// Enums from namespaced other type
property int h: Namespace.MyQmlObject.EnumValue3
property int i: Namespace.MyQmlObject.EnumValue4

// Count the onChanged signals to see whether
// they're assigned as literals or via bindings
property int ac: 0
property int bc: 0
property int cc: 0
property int dc: 0
property int ec: 0
property int fc: 0
property int hc: 0
property int ic: 0

onAChanged: ac++
onBChanged: bc++
onCChanged: cc++
onDChanged: dc++
onEChanged: ec++
onFChanged: fc++
onHChanged: hc++
onIChanged: ic++
}
28 changes: 28 additions & 0 deletions tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
Expand Up @@ -846,6 +846,34 @@ void tst_qqmlecmascript::enums()
QCOMPARE(object->property("a").toInt(), 0);
QCOMPARE(object->property("b").toInt(), 0);

delete object;
}
// Enums as literals
{
QQmlComponent component(&engine, testFileUrl("enums.3.qml"));
QObject *object = component.create();
QVERIFY(object != 0);

// check the values are what we expect
QCOMPARE(object->property("a").toInt(), 4);
QCOMPARE(object->property("b").toInt(), 5);
QCOMPARE(object->property("c").toInt(), 9);
QCOMPARE(object->property("d").toInt(), 13);
QCOMPARE(object->property("e").toInt(), 2);
QCOMPARE(object->property("f").toInt(), 3);
QCOMPARE(object->property("h").toInt(), 2);
QCOMPARE(object->property("i").toInt(), 3);

// count of change signals
QCOMPARE(object->property("ac").toInt(), 0);
QCOMPARE(object->property("bc").toInt(), 0);
QCOMPARE(object->property("cc").toInt(), 0);
QCOMPARE(object->property("dc").toInt(), 0);
QCOMPARE(object->property("ec").toInt(), 0);
QCOMPARE(object->property("fc").toInt(), 0);
QCOMPARE(object->property("hc").toInt(), 1); // namespace -> binding
QCOMPARE(object->property("ic").toInt(), 1); // namespace -> binding

delete object;
}
}
Expand Down

0 comments on commit 4c9d326

Please sign in to comment.