summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp23
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp12
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h7
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp20
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp5
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 } ] } }"