summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativebinding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qdeclarativebinding.cpp')
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp142
1 files changed, 133 insertions, 9 deletions
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 88ca5cd..bc78b5b 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -223,7 +223,7 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF
int QDeclarativeBinding::propertyIndex()
{
Q_D(QDeclarativeBinding);
- return d->bindingData()->property.index();
+ return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property);
}
bool QDeclarativeBinding::enabled() const
@@ -259,23 +259,57 @@ void QDeclarativeAbstractBinding::addToObject(QObject *object)
{
Q_ASSERT(object);
+ if (m_object == object)
+ return;
+
+ int index = propertyIndex();
+
removeFromObject();
Q_ASSERT(!m_prevBinding);
- QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true);
- m_nextBinding = data->bindings;
- if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
- m_prevBinding = &data->bindings;
- data->bindings = this;
m_object = object;
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true);
+
+ if (index & 0xFF000000) {
+ // Value type
- data->setBindingBit(m_object, propertyIndex());
+ int coreIndex = index & 0xFFFFFF;
+
+ // Find the value type proxy (if there is one)
+ QDeclarativeValueTypeProxyBinding *proxy = 0;
+ if (data->hasBindingBit(coreIndex)) {
+ QDeclarativeAbstractBinding *b = data->bindings;
+ while (b && b->propertyIndex() != coreIndex)
+ b = b->m_nextBinding;
+ Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy);
+ proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(b);
+ }
+
+ if (!proxy)
+ proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex);
+ proxy->addToObject(object);
+
+ m_nextBinding = proxy->m_bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &proxy->m_bindings;
+ proxy->m_bindings = this;
+
+ } else {
+ m_nextBinding = data->bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &data->bindings;
+ data->bindings = this;
+
+ data->setBindingBit(m_object, index);
+ }
}
void QDeclarativeAbstractBinding::removeFromObject()
{
if (m_prevBinding) {
+ int index = propertyIndex();
+
Q_ASSERT(m_object);
*m_prevBinding = m_nextBinding;
@@ -283,8 +317,14 @@ void QDeclarativeAbstractBinding::removeFromObject()
m_prevBinding = 0;
m_nextBinding = 0;
- QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false);
- if (data) data->clearBindingBit(propertyIndex());
+ if (index & 0xFF000000) {
+ // Value type - we don't remove the proxy from the object. It will sit their happily
+ // doing nothing for ever more.
+ } else {
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false);
+ if (data) data->clearBindingBit(index);
+ }
+
m_object = 0;
}
}
@@ -305,4 +345,88 @@ void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate
if (e) m_mePtr = 0;
}
+QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index)
+: m_object(o), m_index(index), m_bindings(0)
+{
+}
+
+QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding()
+{
+ while (m_bindings) {
+ QDeclarativeAbstractBinding *binding = m_bindings;
+ binding->setEnabled(false, 0);
+ binding->destroy();
+ }
+}
+
+void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (e) {
+ addToObject(m_object);
+
+ QDeclarativeAbstractBinding *bindings = m_bindings;
+ m_bindings = 0;
+ recursiveEnable(bindings, flags);
+ } else {
+ removeFromObject();
+
+ QDeclarativeAbstractBinding *bindings = m_bindings;
+ m_bindings = 0;
+ recursiveDisable(bindings);
+ }
+}
+
+void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBinding *b, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (!b)
+ return;
+
+ QDeclarativeAbstractBinding *next = b->m_nextBinding;
+ b->m_prevBinding = 0;
+ b->m_nextBinding = 0;
+ Q_ASSERT(b->m_mePtr == 0);
+ b->m_mePtr = &b;
+
+ recursiveEnable(next, flags);
+
+ if (b)
+ b->setEnabled(true, flags);
+}
+
+void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBinding *b)
+{
+ if (!b)
+ return;
+
+ recursiveDisable(b->m_nextBinding);
+
+ b->setEnabled(false, 0);
+
+ Q_ASSERT(b->m_prevBinding == 0);
+ Q_ASSERT(b->m_nextBinding == 0);
+ b->m_nextBinding = m_bindings;
+ if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding;
+ b->m_prevBinding = &m_bindings;
+ m_bindings = b;
+}
+
+int QDeclarativeValueTypeProxyBinding::propertyIndex()
+{
+ return m_index;
+}
+
+void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags)
+{
+}
+
+QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int propertyIndex)
+{
+ QDeclarativeAbstractBinding *binding = m_bindings;
+
+ while (binding && binding->propertyIndex() != propertyIndex)
+ binding = binding->m_nextBinding;
+
+ return binding;
+}
+
QT_END_NAMESPACE