From 884bc89e9fe765a7be245b3009339f999936a761 Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Tue, 17 Jul 2012 11:14:43 +1000 Subject: Allow QQmlPropertyMap property updates to be controlled Allow clients to control updates made from QML to types derived from QQmlPropertyMap, by overriding the updateValue() function. Task-number: QTBUG-23183 Change-Id: I0169093779ebfe50dc9349f5aaac08ed85c80a8f Reviewed-by: Michael Brasser Reviewed-by: abcd --- src/qml/qml/qqmlopenmetaobject.cpp | 29 ++++++++++++++++------------ src/qml/qml/qqmlopenmetaobject_p.h | 1 + src/qml/util/qqmlpropertymap.cpp | 39 +++++++++++++++++++++++++++++++++++++- src/qml/util/qqmlpropertymap.h | 3 +++ 4 files changed, 59 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp index 221cb3a314..4774f7e126 100644 --- a/src/qml/qml/qqmlopenmetaobject.cpp +++ b/src/qml/qml/qqmlopenmetaobject.cpp @@ -145,10 +145,14 @@ public: QQmlOpenMetaObjectPrivate(QQmlOpenMetaObject *_q) : q(_q), parent(0), type(0), cacheProperties(false) {} - inline QVariant &getData(int idx) { + inline QPair &getDataRef(int idx) { while (data.count() <= idx) data << QPair(QVariant(), false); - QPair &prop = data[idx]; + return data[idx]; + } + + inline QVariant &getData(int idx) { + QPair &prop = getDataRef(idx); if (!prop.second) { prop.first = q->initialValue(idx); prop.second = true; @@ -156,14 +160,6 @@ public: return prop.first; } - inline void writeData(int idx, const QVariant &value) { - while (data.count() <= idx) - data << QPair(QVariant(), false); - QPair &prop = data[idx]; - prop.first = value; - prop.second = true; - } - inline bool hasData(int idx) const { if (idx >= data.count()) return false; @@ -235,7 +231,9 @@ int QQmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a) } else if (c == QMetaObject::WriteProperty) { if (propId <= d->data.count() || d->data[propId].first != *reinterpret_cast(a[0])) { propertyWrite(propId); - d->writeData(propId, *reinterpret_cast(a[0])); + QPair &prop = d->getDataRef(propId); + prop.first = propertyWriteValue(propId, *reinterpret_cast(a[0])); + prop.second = true; propertyWritten(propId); activate(d->object, d->type->d->signalOffset + propId, 0); } @@ -261,7 +259,9 @@ QVariant QQmlOpenMetaObject::value(int id) const void QQmlOpenMetaObject::setValue(int id, const QVariant &value) { - d->writeData(id, value); + QPair &prop = d->getDataRef(id); + prop.first = propertyWriteValue(id, value); + prop.second = true; activate(d->object, id + d->type->d->signalOffset, 0); } @@ -354,6 +354,11 @@ void QQmlOpenMetaObject::propertyWrite(int) { } +QVariant QQmlOpenMetaObject::propertyWriteValue(int, const QVariant &value) +{ + return value; +} + void QQmlOpenMetaObject::propertyWritten(int) { } diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h index 188192edc1..a45d7d8259 100644 --- a/src/qml/qml/qqmlopenmetaobject_p.h +++ b/src/qml/qml/qqmlopenmetaobject_p.h @@ -113,6 +113,7 @@ protected: virtual void propertyRead(int); virtual void propertyWrite(int); + virtual QVariant propertyWriteValue(int, const QVariant &); virtual void propertyWritten(int); virtual void propertyCreated(int, QMetaPropertyBuilder &); diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp index 1571d2dfc9..cdc82fe86e 100644 --- a/src/qml/util/qqmlpropertymap.cpp +++ b/src/qml/util/qqmlpropertymap.cpp @@ -56,9 +56,13 @@ public: QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv); protected: + virtual QVariant propertyWriteValue(int, const QVariant &); virtual void propertyWritten(int index); virtual void propertyCreated(int, QMetaPropertyBuilder &); virtual int createProperty(const char *, const char *); + + const QString &propertyName(int index); + private: QQmlPropertyMap *map; QQmlPropertyMapPrivate *priv; @@ -70,8 +74,12 @@ class QQmlPropertyMapPrivate : public QObjectPrivate public: QQmlPropertyMapMetaObject *mo; QStringList keys; + + QVariant updateValue(const QString &key, const QVariant &input); void emitChanged(const QString &key, const QVariant &value); bool validKeyName(const QString& name); + + const QString &propertyName(int index) const; }; bool QQmlPropertyMapPrivate::validKeyName(const QString& name) @@ -84,21 +92,38 @@ bool QQmlPropertyMapPrivate::validKeyName(const QString& name) && name != QLatin1String("deleteLater"); } +QVariant QQmlPropertyMapPrivate::updateValue(const QString &key, const QVariant &input) +{ + Q_Q(QQmlPropertyMap); + return q->updateValue(key, input); +} + void QQmlPropertyMapPrivate::emitChanged(const QString &key, const QVariant &value) { Q_Q(QQmlPropertyMap); emit q->valueChanged(key, value); } +const QString &QQmlPropertyMapPrivate::propertyName(int index) const +{ + Q_ASSERT(index < keys.size()); + return keys[index]; +} + QQmlPropertyMapMetaObject::QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv) : QQmlOpenMetaObject(obj) { map = obj; priv = objPriv; } +QVariant QQmlPropertyMapMetaObject::propertyWriteValue(int index, const QVariant &input) +{ + return priv->updateValue(priv->propertyName(index), input); +} + void QQmlPropertyMapMetaObject::propertyWritten(int index) { - priv->emitChanged(QString::fromUtf8(name(index)), operator[](index)); + priv->emitChanged(priv->propertyName(index), operator[](index)); } void QQmlPropertyMapMetaObject::propertyCreated(int, QMetaPropertyBuilder &b) @@ -297,6 +322,18 @@ QVariant QQmlPropertyMap::operator[](const QString &key) const return value(key); } +/*! + Returns the new value to be stored for the key \a key. This function is provided + to intercept updates to a property from QML, where the value provided from QML is \a input. + + Override this function to manipulate the property value as it is updated. Note that + this function is only invoked when the value is updated from QML. +*/ +QVariant QQmlPropertyMap::updateValue(const QString &key, const QVariant &input) +{ + return input; +} + /*! \fn void QQmlPropertyMap::valueChanged(const QString &key, const QVariant &value) This signal is emitted whenever one of the values in the map is changed. \a key diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h index 53254ab672..bfd11e5c80 100644 --- a/src/qml/util/qqmlpropertymap.h +++ b/src/qml/util/qqmlpropertymap.h @@ -79,6 +79,9 @@ public: Q_SIGNALS: void valueChanged(const QString &key, const QVariant &value); +protected: + virtual QVariant updateValue(const QString &key, const QVariant &input); + private: Q_DECLARE_PRIVATE(QQmlPropertyMap) Q_DISABLE_COPY(QQmlPropertyMap) -- cgit v1.2.3