Directly resolve property aliases in QQmlBinding::setTarget
authorLars Knoll <lars.knoll@theqtcompany.com>
Wed, 15 Apr 2015 10:43:24 +0000 (12:43 +0200)
committerSimon Hausmann <simon.hausmann@theqtcompany.com>
Sun, 26 Apr 2015 18:42:16 +0000 (18:42 +0000)
Like this the target properties of the binding will always point
to the correct resolved object and property.

Change-Id: I400a265a17bc55de041c3df17f357e4b40f31c4d
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
src/qml/qml/qqmlbinding.cpp
src/qml/qml/qqmlproperty.cpp

index 33fea6b..8baebec 100644 (file)
@@ -43,6 +43,7 @@
 #include <private/qqmlscriptstring_p.h>
 #include <private/qqmlcontextwrapper_p.h>
 #include <private/qqmlbuiltinfunctions_p.h>
+#include <private/qqmlvmemetaobject_p.h>
 
 #include <QVariant>
 #include <QtCore/qdebug.h>
@@ -296,6 +297,42 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core)
 {
     m_coreObject = object;
     m_core = core;
+
+    while (m_core.isAlias()) {
+        int coreIndex = core.coreIndex;
+        int valueTypeIndex = core.getValueTypeCoreIndex();
+        QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
+
+        int aValueTypeIndex;
+        if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
+            m_core.coreIndex = -1;
+            m_coreObject = 0;
+            return;
+        }
+        if (valueTypeIndex == -1)
+            valueTypeIndex = aValueTypeIndex;
+
+        QQmlData *data = QQmlData::get(object, false);
+        if (!data || !data->propertyCache) {
+            m_core.coreIndex = -1;
+            m_coreObject = 0;
+            return;
+        }
+        QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
+        Q_ASSERT(propertyData);
+
+        m_coreObject = object;
+        m_core = *propertyData;
+        if (valueTypeIndex != -1) {
+            const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(m_core.propType);
+            Q_ASSERT(valueTypeMetaObject);
+            QMetaProperty vtProp = valueTypeMetaObject->property(valueTypeIndex);
+            m_core.setFlags(m_core.getFlags() | QQmlPropertyData::IsValueTypeVirtual);
+            m_core.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp);
+            m_core.valueTypePropType = vtProp.userType();
+            m_core.valueTypeCoreIndex = valueTypeIndex;
+        }
+    }
 }
 
 QQmlProperty QQmlBinding::property() const
index 8ee4a2d..f003bf8 100644 (file)
@@ -869,23 +869,6 @@ QQmlPropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeInd
     }
 
     if (newBinding) {
-        if (newBinding->targetPropertyIndex() != index || newBinding->targetObject() != object) {
-            QQmlData *data = QQmlData::get(object, true);
-            if (data && data->propertyCache) {
-                QQmlPropertyData propertyData = *data->propertyCache->property(coreIndex);
-                if (valueTypeIndex != -1) {
-                    const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(propertyData.propType);
-                    Q_ASSERT(valueTypeMetaObject);
-                    QMetaProperty vtProp = valueTypeMetaObject->property(valueTypeIndex);
-                    propertyData.setFlags(propertyData.getFlags() | QQmlPropertyData::IsValueTypeVirtual);
-                    propertyData.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp);
-                    propertyData.valueTypePropType = vtProp.userType();
-                    propertyData.valueTypeCoreIndex = valueTypeIndex;
-                }
-                static_cast<QQmlBinding *>(newBinding)->setTarget(object, propertyData);
-            }
-        }
-
         Q_ASSERT(newBinding->targetPropertyIndex() == index);
         Q_ASSERT(newBinding->targetObject() == object);
 
@@ -945,23 +928,6 @@ QQmlPropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valu
         binding->removeFromObject();
 
     if (newBinding) {
-        if (newBinding->targetPropertyIndex() != index || newBinding->targetObject() != object) {
-            QQmlData *data = QQmlData::get(object, true);
-            if (data && data->propertyCache) {
-                QQmlPropertyData propertyData = *data->propertyCache->property(coreIndex);
-                if (valueTypeIndex != -1) {
-                    const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(propertyData.propType);
-                    Q_ASSERT(valueTypeMetaObject);
-                    QMetaProperty vtProp = valueTypeMetaObject->property(valueTypeIndex);
-                    propertyData.setFlags(propertyData.getFlags() | QQmlPropertyData::IsValueTypeVirtual);
-                    propertyData.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp);
-                    propertyData.valueTypePropType = vtProp.userType();
-                    propertyData.valueTypeCoreIndex = valueTypeIndex;
-                }
-                static_cast<QQmlBinding *>(newBinding)->setTarget(object, propertyData);
-            }
-        }
-
         Q_ASSERT(newBinding->targetPropertyIndex() == index);
         Q_ASSERT(newBinding->targetObject() == object);