From f7accb884e45ddf241991ef29ee8d34731e0211a Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 26 Oct 2009 14:50:29 +1000 Subject: Add support for value interceptors to the DOM. --- src/declarative/qml/qmldom.cpp | 96 ++++++++++++++++++++++++++++ src/declarative/qml/qmldom.h | 20 ++++++ tests/auto/declarative/qmldom/tst_qmldom.cpp | 30 ++++++++- 3 files changed, 143 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index a0601d7..21eeb7c 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -1181,6 +1181,75 @@ QmlDomObject QmlDomValueValueSource::object() const return rv; } +/*! + \class QmlDomValueValueInterceptor + \internal + \brief The QmlDomValueValueInterceptor class represents a value interceptor assignment value. + + In QML, value interceptor are special write-intercepting types that may be + assigned to properties. Value interceptor inherit the QmlPropertyValueInterceptor + class. In the example below, the "x" property is being assigned the + Behavior value interceptor. + + \qml +Rectangle { + x: Behavior { NumberAnimation { duration: 500 } } +} + \endqml +*/ + +/*! + Construct an empty QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor::QmlDomValueValueInterceptor(): + d(new QmlDomBasicValuePrivate) +{ +} + +/*! + Create a copy of \a other QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor::QmlDomValueValueInterceptor(const QmlDomValueValueInterceptor &other) +: d(other.d) +{ +} + +/*! + Destroy the QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor::~QmlDomValueValueInterceptor() +{ +} + +/*! + Assign \a other to this QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor &QmlDomValueValueInterceptor::operator=(const QmlDomValueValueInterceptor &other) +{ + d = other.d; + return *this; +} + +/*! + Return the value interceptor object. + + In the example below, an object representing the Behavior will be + returned. + \qml +Rectangle { + x: Behavior { NumberAnimation { duration: 500 } } +} + \endqml +*/ +QmlDomObject QmlDomValueValueInterceptor::object() const +{ + QmlDomObject rv; + if (d->value) { + rv.d->object = d->value->object; + rv.d->object->addref(); + } + return rv; +} QmlDomValuePrivate::QmlDomValuePrivate() : property(0), value(0) @@ -1286,6 +1355,7 @@ QmlDomValue &QmlDomValue::operator=(const QmlDomValue &other) \value Literal The QmlDomValue is a literal value assignment. Use QmlDomValue::toLiteral() to access the type instance. \value PropertyBinding The QmlDomValue is a property binding. Use QmlDomValue::toBinding() to access the type instance. \value ValueSource The QmlDomValue is a property value source. Use QmlDomValue::toValueSource() to access the type instance. + \value ValueInterceptor The QmlDomValue is a property value interceptor. Use QmlDomValue::toValueInterceptor() to access the type instance. \value Object The QmlDomValue is an object assignment. Use QmlDomValue::toObject() to access the type instnace. \value List The QmlDomValue is a list of other values. Use QmlDomValue::toList() to access the type instance. */ @@ -1314,6 +1384,8 @@ QmlDomValue::Type QmlDomValue::type() const return PropertyBinding; case QmlParser::Value::ValueSource: return ValueSource; + case QmlParser::Value::ValueInterceptor: + return ValueInterceptor; case QmlParser::Value::CreatedObject: return Object; case QmlParser::Value::SignalObject: @@ -1359,6 +1431,14 @@ bool QmlDomValue::isValueSource() const } /*! + Returns true if this is a value interceptor value, otherwise false. +*/ +bool QmlDomValue::isValueInterceptor() const +{ + return type() == ValueInterceptor; +} + +/*! Returns true if this is an object value, otherwise false. */ bool QmlDomValue::isObject() const @@ -1423,6 +1503,22 @@ QmlDomValueValueSource QmlDomValue::toValueSource() const } /*! + Returns a QmlDomValueValueInterceptor if this value is a property value interceptor + type, otherwise returns an invalid QmlDomValueValueInterceptor. + + \sa QmlDomValue::type() +*/ +QmlDomValueValueInterceptor QmlDomValue::toValueInterceptor() const +{ + QmlDomValueValueInterceptor rv; + if (type() == ValueInterceptor) { + rv.d->value = d->value; + rv.d->value->addref(); + } + return rv; +} + +/*! Returns a QmlDomObject if this value is an object assignment type, otherwise returns an invalid QmlDomObject. diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index f344bb2..5816780 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -175,6 +175,7 @@ private: friend class QmlDomComponent; friend class QmlDomValue; friend class QmlDomValueValueSource; + friend class QmlDomValueValueInterceptor; QSharedDataPointer d; }; @@ -225,6 +226,22 @@ private: QSharedDataPointer d; }; +class Q_DECLARATIVE_EXPORT QmlDomValueValueInterceptor +{ +public: + QmlDomValueValueInterceptor(); + QmlDomValueValueInterceptor(const QmlDomValueValueInterceptor &); + ~QmlDomValueValueInterceptor(); + QmlDomValueValueInterceptor &operator=(const QmlDomValueValueInterceptor &); + + QmlDomObject object() const; + +private: + friend class QmlDomValue; + QSharedDataPointer d; +}; + + class Q_DECLARATIVE_EXPORT QmlDomComponent : public QmlDomObject { public: @@ -244,6 +261,7 @@ public: Literal, PropertyBinding, ValueSource, + ValueInterceptor, Object, List }; @@ -259,12 +277,14 @@ public: bool isLiteral() const; bool isBinding() const; bool isValueSource() const; + bool isValueInterceptor() const; bool isObject() const; bool isList() const; QmlDomValueLiteral toLiteral() const; QmlDomValueBinding toBinding() const; QmlDomValueValueSource toValueSource() const; + QmlDomValueValueInterceptor toValueInterceptor() const; QmlDomObject toObject() const; QmlDomList toList() const; diff --git a/tests/auto/declarative/qmldom/tst_qmldom.cpp b/tests/auto/declarative/qmldom/tst_qmldom.cpp index 77c13c3..8079a23 100644 --- a/tests/auto/declarative/qmldom/tst_qmldom.cpp +++ b/tests/auto/declarative/qmldom/tst_qmldom.cpp @@ -20,6 +20,7 @@ private slots: void loadImports(); void testValueSource(); + void testValueInterceptor(); private: QmlEngine engine; @@ -30,7 +31,6 @@ void tst_qmldom::loadSimple() { QByteArray qml = "import Qt 4.6\n" "Item {}"; - //QByteArray qml = ""; QmlDomDocument document; QVERIFY(document.load(&engine, qml)); @@ -49,7 +49,6 @@ void tst_qmldom::loadProperties() { QByteArray qml = "import Qt 4.6\n" "Item { id : item; x : 300; visible : true }"; - //QByteArray qml = ""; QmlDomDocument document; QVERIFY(document.load(&engine, qml)); @@ -74,7 +73,6 @@ void tst_qmldom::loadChildObject() { QByteArray qml = "import Qt 4.6\n" "Item { Item {} }"; - //QByteArray qml = " "; QmlDomDocument document; QVERIFY(document.load(&engine, qml)); @@ -148,6 +146,32 @@ void tst_qmldom::testValueSource() QVERIFY(sourceValue.toBinding().binding() == "Math.min(Math.max(-130, value*2.2 - 130), 133)"); } +void tst_qmldom::testValueInterceptor() +{ + QByteArray qml = "import Qt 4.6\n" + "Rectangle { height: Behavior { NumberAnimation { duration: 100 } } }"; + + QmlEngine freshEngine; + QmlDomDocument document; + QVERIFY(document.load(&freshEngine, qml)); + + QmlDomObject rootItem = document.rootObject(); + QVERIFY(rootItem.isValid()); + QmlDomProperty heightProperty = rootItem.properties().at(0); + QVERIFY(heightProperty.propertyName() == "height"); + QVERIFY(heightProperty.value().isValueInterceptor()); + + const QmlDomValueValueInterceptor valueInterceptor = heightProperty.value().toValueInterceptor(); + QmlDomObject valueInterceptorObject = valueInterceptor.object(); + QVERIFY(valueInterceptorObject.isValid()); + + QVERIFY(valueInterceptorObject.objectType() == "Qt/Behavior"); + + const QmlDomValue animationValue = valueInterceptorObject.property("animation").value(); + QVERIFY(!animationValue.isInvalid()); + QVERIFY(animationValue.isObject()); +} + void tst_qmldom::loadImports() { QByteArray qml = "import Qt 4.6\n" -- cgit v0.12