diff options
Diffstat (limited to 'src/qml/qml/qqmlbinding.cpp')
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 3dabaca09f..0b5081d491 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -691,14 +691,34 @@ bool QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const valueType ? valueType->coreIndex() : -1); } -bool QQmlBinding::setTarget(QObject *object, int coreIndex, bool coreIsAlias, int valueTypeIndex) +static const QQmlPropertyData *getObjectPropertyData(QObject *object, int coreIndex) { - m_target = object; + QQmlData *data = QQmlData::get(object, true); + if (!data) + return nullptr; + if (!data->propertyCache) { + data->propertyCache = QQmlMetaType::propertyCache(object->metaObject()); + if (!data->propertyCache) + return nullptr; + data->propertyCache->addref(); + } + const QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); + Q_ASSERT(propertyData); + return propertyData; +} - if (!object) { +bool QQmlBinding::setTarget(QObject *object, int coreIndex, bool coreIsAlias, int valueTypeIndex) +{ + 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); @@ -706,21 +726,25 @@ bool QQmlBinding::setTarget(QObject *object, int coreIndex, bool coreIsAlias, in 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; + } } - QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); - Q_ASSERT(propertyData); m_target = object; isAlias = propertyData->isAlias(); |