diff options
6 files changed, 63 insertions, 6 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 06ff47c..5dc3858 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -825,7 +825,9 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) if (isCustomParser && !customProps.isEmpty()) { QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser(); cp->clearErrors(); + cp->compiler = this; obj->custom = cp->compile(customProps); + cp->compiler = 0; foreach (QDeclarativeError err, cp->errors()) { err.setUrl(output->url); exceptions << err; @@ -2184,6 +2186,27 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop return true; } +// Similar logic to above, but not knowing target property. +int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const +{ + int dot = script.find('.'); + if (dot > 0) { + QDeclarativeType *type = 0; + QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0); + if (!type) + return -1; + const QMetaObject *mo = type->metaObject(); + const char *key = script.constData() + dot+1; + int i = mo->enumeratorCount(); + while (i--) { + int v = mo->enumerator(i).keyToValue(key); + if (v >= 0) + return v; + } + } + return -1; +} + // Ensures that the dynamic meta specification on obj is valid bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) { diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 05b556e..a81259b 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -161,6 +161,8 @@ public: static QMetaMethod findSignalByName(const QMetaObject *, const QByteArray &name); + int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum + private: static void reset(QDeclarativeCompiledData *); diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp index 67f0963..a3a511c 100644 --- a/src/declarative/qml/qdeclarativecustomparser.cpp +++ b/src/declarative/qml/qdeclarativecustomparser.cpp @@ -43,6 +43,7 @@ #include "qdeclarativecustomparser_p_p.h" #include "qdeclarativeparser_p.h" +#include "qdeclarativecompiler_p.h" #include <QtCore/qdebug.h> @@ -260,4 +261,15 @@ void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, c exceptions << error; } +/*! + If \a script is a simply enum expression (eg. Text.AlignLeft), + returns the integer equivalent (eg. 1). + + Otherwise, returns -1. +*/ +int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const +{ + return compiler->evaluateEnum(script); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 39bd43c..f9bf513 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -66,6 +66,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class QDeclarativeCompiler; + class QDeclarativeCustomParserPropertyPrivate; class Q_DECLARATIVE_EXPORT QDeclarativeCustomParserProperty { @@ -111,6 +113,7 @@ private: class Q_DECLARATIVE_EXPORT QDeclarativeCustomParser { public: + QDeclarativeCustomParser() : compiler(0) {} virtual ~QDeclarativeCustomParser() {} void clearErrors(); @@ -124,8 +127,12 @@ protected: void error(const QDeclarativeCustomParserProperty&, const QString& description); void error(const QDeclarativeCustomParserNode&, const QString& description); + int evaluateEnum(const QByteArray&) const; + private: QList<QDeclarativeError> exceptions; + QDeclarativeCompiler *compiler; + friend class QDeclarativeCompiler; }; #if 0 diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 824e1b5..32a996d 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -94,9 +94,12 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM } \endcode - Roles (properties) must begin with a lower-case letter. The above example defines a + Roles (properties) must begin with a lower-case letter.The above example defines a ListModel containing three elements, with the roles "name" and "cost". + Values must be simple constants - either strings (quoted), bools (true, false), numbers, + or enum values (like Text.AlignHCenter). + The defined model can be used in views such as ListView: \code Component { @@ -167,6 +170,8 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM } \endcode + \section2 Modifying list models + The content of a ListModel may be created and modified using the clear(), append(), and set() methods. For example: @@ -674,10 +679,17 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser d += char(variant.asBoolean()); } else if (variant.isScript()) { if (definesEmptyList(variant.asScript())) { - d[0] = 0; // QDeclarativeParser::Variant::Invalid - marks empty list + d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list } else { - error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); - return false; + QByteArray script = variant.asScript().toUtf8(); + int v = evaluateEnum(script); + if (v<0) { + error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); + return false; + } else { + d[0] = char(QDeclarativeParser::Variant::Number); + d += QByteArray::number(v); + } } } d.append('\0'); diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 78e5912..576fe21 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include <qtest.h> #include <QtDeclarative/private/qdeclarativeitem_p.h> +#include <QtDeclarative/private/qdeclarativetext_p.h> #include <QtDeclarative/private/qdeclarativelistmodel_p.h> #include <QtDeclarative/private/qdeclarativeexpression_p.h> #include <QDeclarativeComponent> @@ -459,7 +460,7 @@ void tst_QDeclarativeListModel::static_types_data() QTest::newRow("enum") << "ListElement { foo: Text.AlignHCenter }" - << QVariant("QTBUG-5974:ListElement: constant script support for property value"); + << QVariant(double(QDeclarativeText::AlignHCenter)); } void tst_QDeclarativeListModel::static_types() @@ -516,7 +517,7 @@ void tst_QDeclarativeListModel::error_data() QTest::newRow("bindings not allowed in ListElement") << "import Qt 4.6\nRectangle { id: rect; ListModel { ListElement { foo: rect.color } } }" - << "ListElement: cannot use script for property value"; // but note QTBUG-5974 + << "ListElement: cannot use script for property value"; QTest::newRow("random object list properties allowed in ListElement") << "import Qt 4.6\nListModel { ListElement { foo: [ ListElement { bar: 123 } ] } }" |