diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-12-15 16:47:27 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-12-17 02:45:33 +0100 |
commit | e9b7eaaf6e627c84cf77dc0ea76c9cb40d705711 (patch) | |
tree | b0fc412c1311efdf6539c21ce251bbb810956dc5 /src/qml/qml/qqmlabstractbinding.cpp | |
parent | 9ea0b225372f6b9104ff330364a81aee2855e3f2 (diff) |
QML: Consider deep aliases when finding binding targets
If we have a deep alias we need to bind to the inner object rather than
the outer one.
Fixes: QTBUG-109417
Pick-to: 6.5 6.2
Change-Id: Iefe8641026cfbbf9199b2bb8d9fa2f5fba591f17
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlabstractbinding.cpp')
-rw-r--r-- | src/qml/qml/qqmlabstractbinding.cpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp index 0904d1af46..78d1d68f55 100644 --- a/src/qml/qml/qqmlabstractbinding.cpp +++ b/src/qml/qml/qqmlabstractbinding.cpp @@ -207,15 +207,36 @@ bool QQmlAbstractBinding::setTarget( valueType ? valueType->coreIndex() : -1); } +static const QQmlPropertyData *getObjectPropertyData(QObject *object, int coreIndex) +{ + QQmlData *data = QQmlData::get(object, true); + if (!data) + return nullptr; + + if (!data->propertyCache) { + data->propertyCache = QQmlMetaType::propertyCache(object); + if (!data->propertyCache) + return nullptr; + } + + const QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); + Q_ASSERT(propertyData); + return propertyData; +} + bool QQmlAbstractBinding::setTarget( QObject *object, int coreIndex, bool coreIsAlias, int valueTypeIndex) { - m_target = object; - - if (!object) { + auto invalidate = [this]() { + m_target = nullptr; m_targetIndex = QQmlPropertyIndex(); return false; - } + }; + + if (!object) + return invalidate(); + + m_target = object; for (bool isAlias = coreIsAlias; isAlias;) { QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex); @@ -223,21 +244,26 @@ bool QQmlAbstractBinding::setTarget( int aValueTypeIndex; if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) { // can't resolve id (yet) - m_target = nullptr; - m_targetIndex = QQmlPropertyIndex(); - return false; + return invalidate(); } - if (valueTypeIndex == -1) - valueTypeIndex = aValueTypeIndex; - - QQmlData *data = QQmlData::get(object, false); - if (!data || !data->propertyCache) { - m_target = nullptr; - m_targetIndex = QQmlPropertyIndex(); - return false; + + const QQmlPropertyData *propertyData = getObjectPropertyData(object, coreIndex); + if (!propertyData) + return invalidate(); + + if (aValueTypeIndex != -1) { + if (propertyData->propType().flags().testFlag(QMetaType::PointerToQObject)) { + // deep alias + propertyData->readProperty(object, &object); + coreIndex = aValueTypeIndex; + valueTypeIndex = -1; + propertyData = getObjectPropertyData(object, coreIndex); + if (!propertyData) + return invalidate(); + } else { + valueTypeIndex = aValueTypeIndex; + } } - const QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); - Q_ASSERT(propertyData); m_target = object; isAlias = propertyData->isAlias(); |