diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-02-04 14:02:51 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-04 18:29:12 +0100 |
commit | a74af1ffba4c21e9dc459d18830fe573188dc90e (patch) | |
tree | 44467b02f742f4931bd348e8fc7afd212a9a8609 | |
parent | 50269fc37a6a50864bf08b25327a05f2ab885a1a (diff) |
[new compiler] Fix partial bindings on value types
You can have a binding like this:
property point blah: Qt.point(someX, someY);
and later you can have bindings on
blah.x: { someExpression }
In that case we need to clear the binding on blah.
Change-Id: I27bfa6ab0f104bf989803c5910e6094767429c03
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index e63d6a9f21..e2f1212e84 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -55,6 +55,7 @@ #include <private/qqmlcustomparser_p.h> #include <private/qqmlscriptstring_p.h> #include <private/qqmlpropertyvalueinterceptor_p.h> +#include <private/qqmlvaluetypeproxybinding_p.h> QT_USE_NAMESPACE @@ -509,6 +510,17 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C } } +static QQmlType *qmlTypeForObject(QObject *object) +{ + QQmlType *type = 0; + const QMetaObject *mo = object->metaObject(); + while (mo && !type) { + type = QQmlMetaType::qmlType(mo); + mo = mo->superClass(); + } + return type; +} + void QmlObjectCreator::setupBindings() { QQmlListProperty<void> savedList; @@ -531,6 +543,36 @@ void QmlObjectCreator::setupBindings() } } + // ### this is best done through type-compile-time binding skip lists. + if (_valueTypeProperty) { + QQmlAbstractBinding *binding = + QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex, -1); + + if (binding && binding->bindingType() != QQmlAbstractBinding::ValueTypeProxy) { + QQmlPropertyPrivate::setBinding(_bindingTarget, _valueTypeProperty->coreIndex, -1, 0); + binding->destroy(); + } else if (binding) { + QQmlValueTypeProxyBinding *proxy = + static_cast<QQmlValueTypeProxyBinding *>(binding); + + if (qmlTypeForObject(_bindingTarget)) { + quint32 bindingSkipList = 0; + + const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable(); + for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) { + if (binding->type != QV4::CompiledData::Binding::Type_Script) + continue; + property = binding->propertyNameIndex != 0 ? _propertyCache->property(stringAt(binding->propertyNameIndex), _qobject, context) : defaultProperty; + if (property) + bindingSkipList |= (1 << property->coreIndex); + } + property = 0; + + proxy->removeBindings(bindingSkipList); + } + } + } + const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable(); for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) { @@ -661,7 +703,8 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI } if (_ddata->hasBindingBit(property->coreIndex) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) - && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment)) + && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) + && !_valueTypeProperty) removeBindingOnProperty(_bindingTarget, property->coreIndex); if (binding->type == QV4::CompiledData::Binding::Type_Script) { @@ -712,12 +755,7 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI if (binding->type == QV4::CompiledData::Binding::Type_Object) { if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) { // ### determine value source and interceptor casts ahead of time. - QQmlType *type = 0; - const QMetaObject *mo = createdSubObject->metaObject(); - while (mo && !type) { - type = QQmlMetaType::qmlType(mo); - mo = mo->superClass(); - } + QQmlType *type = qmlTypeForObject(createdSubObject); Q_ASSERT(type); QQmlPropertyData targetCorePropertyData = *property; |