diff options
author | Chris Adams <christopher.adams@nokia.com> | 2012-01-27 11:33:37 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-15 00:22:45 +0100 |
commit | b06108350b1390b51886474628e03e2e84640548 (patch) | |
tree | bbf00677d9edc64e2549f2cc3ee42f1edd5a50f4 /src/qml/qml/qqmlvmemetaobject.cpp | |
parent | a27fd584df0ec3d1d072501d8fefe576a97a2e53 (diff) |
Ensure that dynamic property storing QObject ptr notifies on delete
Previously, when a QObject ptr was stored in a dynamic variant
property, the value of the property could change (to a zero ptr)
if the QObject was deleted without a notify signal being emitted
by the QDeclarativeVMEMetaObject which stores the property.
This commit ensures that such a notify signal is emitted correctly.
Task-number: QTBUG-23451
Change-Id: I5689abd984b177737f8d5f18950838b73ebde328
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlvmemetaobject.cpp')
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 7ea89a4a2d..ecfde203c6 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -56,6 +56,28 @@ Q_DECLARE_METATYPE(QJSValue); QT_BEGIN_NAMESPACE +QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr() + : QQmlGuard<QObject>(0), m_target(0), m_index(-1) +{ +} + +QQmlVMEVariantQObjectPtr::~QQmlVMEVariantQObjectPtr() +{ +} + +void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *) +{ + if (m_target && m_index >= 0) + m_target->activate(m_target->object, m_target->methodOffset + m_index, 0); +} + +void QQmlVMEVariantQObjectPtr::setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index) +{ + m_target = target; + m_index = index; + setObject(obj); +} + class QQmlVMEVariant { public: @@ -79,7 +101,7 @@ public: inline const QDateTime &asQDateTime(); inline const QJSValue &asQJSValue(); - inline void setValue(QObject *); + inline void setValue(QObject *v, QQmlVMEMetaObject *target, int index); inline void setValue(const QVariant &); inline void setValue(int); inline void setValue(bool); @@ -93,7 +115,7 @@ public: inline void setValue(const QJSValue &); private: int type; - void *data[4]; // Large enough to hold all types + void *data[6]; // Large enough to hold all types inline void cleanup(); }; @@ -127,7 +149,7 @@ void QQmlVMEVariant::cleanup() type == QMetaType::Double) { type = QVariant::Invalid; } else if (type == QMetaType::QObjectStar) { - ((QQmlGuard<QObject>*)dataPtr())->~QQmlGuard<QObject>(); + ((QQmlVMEVariantQObjectPtr*)dataPtr())->~QQmlVMEVariantQObjectPtr(); type = QVariant::Invalid; } else if (type == QMetaType::QString) { ((QString *)dataPtr())->~QString(); @@ -174,8 +196,8 @@ void *QQmlVMEVariant::dataPtr() QObject *QQmlVMEVariant::asQObject() { - if (type != QMetaType::QObjectStar) - setValue((QObject *)0); + if (type != QMetaType::QObjectStar) + setValue((QObject *)0, 0, -1); return *(QQmlGuard<QObject> *)(dataPtr()); } @@ -268,14 +290,14 @@ const QJSValue &QQmlVMEVariant::asQJSValue() return *(QJSValue *)(dataPtr()); } -void QQmlVMEVariant::setValue(QObject *v) +void QQmlVMEVariant::setValue(QObject *v, QQmlVMEMetaObject *target, int index) { if (type != QMetaType::QObjectStar) { cleanup(); type = QMetaType::QObjectStar; - new (dataPtr()) QQmlGuard<QObject>(); + new (dataPtr()) QQmlVMEVariantQObjectPtr; } - *(QQmlGuard<QObject>*)(dataPtr()) = v; + reinterpret_cast<QQmlVMEVariantQObjectPtr*>(dataPtr())->setGuardedValue(v, target, index); } void QQmlVMEVariant::setValue(const QVariant &v) @@ -629,7 +651,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) break; case QMetaType::QObjectStar: needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject(); - data[id].setValue(*reinterpret_cast<QObject **>(a[0])); + data[id].setValue(*reinterpret_cast<QObject **>(a[0]), this, id); break; case QMetaType::QVariant: writeProperty(id, *reinterpret_cast<QVariant *>(a[0])); @@ -892,7 +914,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) if (value.userType() == QMetaType::QObjectStar) { QObject *o = qvariant_cast<QObject *>(value); needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o); - data[id].setValue(qvariant_cast<QObject *>(value)); + data[id].setValue(qvariant_cast<QObject *>(value), this, id); } else { needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() || data[id].asQVariant().userType() != value.userType() || |