aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlbinding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlbinding.cpp')
-rw-r--r--src/qml/qml/qqmlbinding.cpp56
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();