From 603c2a0475888928462679562e9b10acefaec629 Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@nokia.com>
Date: Fri, 23 Oct 2009 16:32:05 +1000
Subject: Fix Behavior support for value type properties.

---
 src/declarative/qml/qmlcompiler.cpp      |  2 +-
 src/declarative/qml/qmlmetaproperty.cpp  |  6 ++++++
 src/declarative/qml/qmlmetaproperty.h    |  1 +
 src/declarative/qml/qmlvme.cpp           |  2 +-
 src/declarative/qml/qmlvmemetaobject.cpp | 33 +++++++++++++++++++++++++-------
 src/declarative/qml/qmlvmemetaobject_p.h |  5 +++--
 6 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 726051e..69ebf9c 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -1740,7 +1740,7 @@ bool QmlCompiler::buildValueTypeProperty(QObject *type,
             } else {
                 COMPILE_CHECK(buildObject(value->object, ctxt));
 
-                if (isPropertyInterceptor && prop->parent->synthdata.isEmpty())
+                if (isPropertyInterceptor && baseObj->synthdata.isEmpty())
                     buildDynamicMeta(baseObj, ForceCreation);
                 value->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
             }
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index feedf13..baef71f 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -1067,6 +1067,12 @@ int QmlMetaProperty::coreIndex() const
     return d->core.coreIndex;
 }
 
+/*! \internal */
+int QmlMetaProperty::valueTypeCoreIndex() const
+{
+    return d->valueTypeCoreIdx;
+}
+
 Q_GLOBAL_STATIC(QmlValueTypeFactory, qmlValueTypes);
 
 /*!
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index fcc020e..4a2b864 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -136,6 +136,7 @@ public:
     static QmlMetaProperty createProperty(QObject *, const QString &);
 
     int coreIndex() const;
+    int valueTypeCoreIndex() const;
 private:
     friend class QmlEnginePrivate;
     QmlMetaPropertyPrivate *d;
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index fc19ebd2..802a78f 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -664,7 +664,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
                 obj->setParent(target);
                 vi->setTarget(prop);
                 QmlVMEMetaObject *mo = static_cast<QmlVMEMetaObject *>((QMetaObject*)target->metaObject());
-                mo->registerInterceptor(prop.coreIndex(), vi);
+                mo->registerInterceptor(prop.coreIndex(), prop.valueTypeCoreIndex(), vi);
             }
             break;
 
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index 05a6f58..a627bf9 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -105,16 +105,35 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
         if (!(flags & QmlMetaProperty::BypassInterceptor)
             && !aInterceptors.isEmpty()
             && aInterceptors.testBit(id)) {
-            QmlPropertyValueInterceptor *vi = interceptors.value(id);
+            QPair<int, QmlPropertyValueInterceptor*> pair = interceptors.value(id);
+            int valueIndex = pair.first;
+            QmlPropertyValueInterceptor *vi = pair.second;
+            QVariant::Type type = QVariant::Invalid;
             if (id >= propOffset) {
                 id -= propOffset;
                 if (id < metaData->propertyCount) {
-                    vi->write(QVariant(data[id].type(), a[0]));
-                    return -1;
+                    type = data[id].type();
                 }
             } else {
-                vi->write(QVariant(property(id).type(), a[0]));
-                return -1;
+                type = property(id).type();
+            }
+
+            if (type != QVariant::Invalid) {
+                if (valueIndex != -1) {
+                    QmlEnginePrivate *ep = ctxt?QmlEnginePrivate::get(ctxt->engine()):0;
+                    QmlValueType *valueType = 0;
+                    if (ep) valueType = ep->valueTypes[type];
+                    else valueType = QmlValueTypeFactory::valueType(type);
+                    Q_ASSERT(valueType);
+
+                    valueType->setValue(QVariant(type, a[0]));
+                    QMetaProperty valueProp = valueType->metaObject()->property(valueIndex);
+                    vi->write(valueProp.read(valueType));
+                    return -1;
+                } else {
+                    vi->write(QVariant(type, a[0]));
+                    return -1;
+                }
             }
         }
     }
@@ -280,12 +299,12 @@ void QmlVMEMetaObject::listChanged(int id)
     activate(object, methodOffset + id, 0);
 }
 
-void QmlVMEMetaObject::registerInterceptor(int index, QmlPropertyValueInterceptor *interceptor)
+void QmlVMEMetaObject::registerInterceptor(int index, int valueIndex, QmlPropertyValueInterceptor *interceptor)
 {
     if (aInterceptors.isEmpty())
         aInterceptors.resize(propertyCount() + metaData->propertyCount);
     aInterceptors.setBit(index);
-    interceptors.insert(index, interceptor);
+    interceptors.insert(index, qMakePair(valueIndex, interceptor));
 }
 
 
diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h
index de46853..74b6d09 100644
--- a/src/declarative/qml/qmlvmemetaobject_p.h
+++ b/src/declarative/qml/qmlvmemetaobject_p.h
@@ -56,6 +56,7 @@
 #include <QtDeclarative/qml.h>
 #include <QtCore/QMetaObject>
 #include <QtCore/QBitArray>
+#include <QtCore/QPair>
 #include <private/qobject_p.h>
 
 QT_BEGIN_NAMESPACE
@@ -104,7 +105,7 @@ public:
                      QmlRefCount * = 0);
     ~QmlVMEMetaObject();
 
-    void registerInterceptor(int index, QmlPropertyValueInterceptor *interceptor);
+    void registerInterceptor(int index, int valueIndex, QmlPropertyValueInterceptor *interceptor);
 
 protected:
     virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
@@ -121,7 +122,7 @@ private:
     QVariant *data;
     QBitArray aConnected;
     QBitArray aInterceptors;
-    QHash<int, QmlPropertyValueInterceptor*> interceptors;
+    QHash<int, QPair<int, QmlPropertyValueInterceptor*> > interceptors;
 
     QAbstractDynamicMetaObject *parent;
 
-- 
cgit v0.12