From f6f89890d032317d16cda7726b4d9f97c12d661d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 10 Jun 2009 19:12:41 +1000 Subject: Simplify QmlBindableValue by using the logic already present in QmlMetaProperty --- src/declarative/qml/qmlbindablevalue.cpp | 84 +--------- src/declarative/qml/qmlmetaproperty.cpp | 274 +++++++++++++++++-------------- 2 files changed, 151 insertions(+), 207 deletions(-) diff --git a/src/declarative/qml/qmlbindablevalue.cpp b/src/declarative/qml/qmlbindablevalue.cpp index d111bbb..293c3a8 100644 --- a/src/declarative/qml/qmlbindablevalue.cpp +++ b/src/declarative/qml/qmlbindablevalue.cpp @@ -125,59 +125,7 @@ void QmlBindableValue::update() if (!d->updating) { d->updating = true; - if (d->property.propertyCategory() == QmlMetaProperty::List) { - QVariant value = this->value(); - int listType = QmlMetaType::listType(d->property.propertyType()); - - if (value.userType() == qMetaTypeId >()) { - const QList &list = - qvariant_cast >(value); - QVariant listVar = d->property.read(); - QmlMetaType::clear(listVar); - for (int ii = 0; ii < list.count(); ++ii) { - QVariant v = QmlMetaType::fromObject(list.at(ii), listType); - QmlMetaType::append(listVar, v); - } - - } else if (value.type() == uint(listType) || - value.userType() == listType) { - QVariant listVar = d->property.read(); - QmlMetaType::clear(listVar); - QmlMetaType::append(listVar, value); - } - } else if (d->property.propertyCategory() == QmlMetaProperty::QmlList) { - // XXX - optimize! - QVariant value = this->value(); - QVariant list = d->property.read(); - QmlPrivate::ListInterface *li = - *(QmlPrivate::ListInterface **)list.constData(); - - int type = li->type(); - - if (QObject *obj = QmlMetaType::toQObject(value)) { - const QMetaObject *mo = - QmlMetaType::rawMetaObjectForType(type); - - const QMetaObject *objMo = obj->metaObject(); - bool found = false; - while(!found && objMo) { - if (objMo == mo) - found = true; - else - objMo = objMo->superClass(); - } - - if (!found) { - qWarning() << "Unable to assign object to list"; - return; - } - - // NOTE: This assumes a cast to QObject does not alter - // the object pointer - void *d = (void *)&obj; - li->append(d); - } - } else if (d->property.propertyCategory() == QmlMetaProperty::Bindable) { + if (d->property.propertyCategory() == QmlMetaProperty::Bindable) { int idx = d->property.coreIndex(); Q_ASSERT(idx != -1); @@ -189,37 +137,13 @@ void QmlBindableValue::update() QMetaObject::WriteProperty, idx, a); - } else if (d->property.propertyCategory() == QmlMetaProperty::Object) { + } else { QVariant value = this->value(); - - QObject *obj = QmlMetaType::toQObject(value); - - if (!obj) { - if (scriptWarnings()) - qWarning() << "QmlBindableValue: Unable to assign non-object to object property"; - return; - } - - // XXX This isn't type safe - - // NOTE: We assume that only core properties can have - // propertyType == Object - int idx = d->property.coreIndex(); - Q_ASSERT(idx != -1); - - void *a[1]; - a[0] = (void *)&obj; - d->property.object()->qt_metacall(QMetaObject::WriteProperty, - idx, a); - - } else if (d->property.propertyCategory() == QmlMetaProperty::Normal) { - QVariant value = this->value(); if (d->property.propertyType() == QVariant::Url && - value.canConvert(QVariant::String) && !value.isNull()) { - // Must resolve first + value.canConvert(QVariant::String) && !value.isNull()) value.setValue(context()->resolvedUrl(value.toString())); - } + d->property.write(value); } diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 5cddf3d..a152807 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -646,159 +646,179 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value) v.convert(QVariant::Int); } prop.write(object, v); - } else { - if (!value.isValid()) + return; + } + + if (!value.isValid()) + return; + + int t = propertyType(); + int vt = value.userType(); + int category = propertyCategory(); + + if (vt == t) { + + void *a[1]; + a[0] = (void *)value.constData(); + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); + + } else if (qMetaTypeId() == t) { + + prop.write(object, value); + + } else if (category == QmlMetaProperty::Object) { + + QObject *o = QmlMetaType::toQObject(value); + + if (!o) return; - int t = propertyType(); - int vt = value.type(); + const QMetaObject *valMo = o->metaObject(); + const QMetaObject *propMo = QmlMetaType::rawMetaObjectForType(t); - if (vt == t || - value.userType() == t) { + while (valMo) { + if (valMo == propMo) + break; + valMo = valMo->superClass(); + } - void *a[1]; - a[0] = (void *)value.constData(); - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); + if (valMo) { - } else if (qMetaTypeId() == t) { + void *args[] = { &o, 0 }; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, + args); - prop.write(object, value); + } - } else if (propertyCategory() == QmlMetaProperty::Object) { + } else if (category == QmlMetaProperty::List) { - QObject *o = QmlMetaType::toQObject(value); - if (o) - prop.write(object, QmlMetaType::fromObject(o, propertyType())); + int listType = QmlMetaType::listType(t); - } else if (propertyCategory() == QmlMetaProperty::List) { + if (value.userType() == qMetaTypeId >()) { + const QList &list = + qvariant_cast >(value); + QVariant listVar = prop.read(object); + QmlMetaType::clear(listVar); + for (int ii = 0; ii < list.count(); ++ii) { + QVariant v = QmlMetaType::fromObject(list.at(ii), listType); + QmlMetaType::append(listVar, v); + } - int listType = QmlMetaType::listType(t); - if (value.userType() == qMetaTypeId >()) { - const QList &list = - qvariant_cast >(value); - QVariant listVar = prop.read(object); - QmlMetaType::clear(listVar); - for (int ii = 0; ii < list.count(); ++ii) { - QVariant v = QmlMetaType::fromObject(list.at(ii), listType); - QmlMetaType::append(listVar, v); - } + } else if (vt == listType || + value.userType() == listType) { + QVariant listVar = prop.read(object); + QmlMetaType::clear(listVar); + QmlMetaType::append(listVar, value); + } + } else if (category == QmlMetaProperty::QmlList) { + + // XXX - optimize! + QVariant list = prop.read(object); + QmlPrivate::ListInterface *li = + *(QmlPrivate::ListInterface **)list.constData(); + + int type = li->type(); + + if (QObject *obj = QmlMetaType::toQObject(value)) { + const QMetaObject *mo = + QmlMetaType::rawMetaObjectForType(type); + + const QMetaObject *objMo = obj->metaObject(); + bool found = false; + while(!found && objMo) { + if (objMo == mo) + found = true; + else + objMo = objMo->superClass(); + } - } else if (vt == listType || - value.userType() == listType) { - QVariant listVar = prop.read(object); - if (!QmlMetaType::append(listVar, value)) { - qWarning() << "QmlMetaProperty: Unable to assign object to list"; - } + if (!found) { + qWarning() << "Unable to assign object to list"; + return; } - } else if (propertyCategory() == QmlMetaProperty::QmlList) { - // XXX - optimize! - QVariant list = prop.read(object); - QmlPrivate::ListInterface *li = - *(QmlPrivate::ListInterface **)list.constData(); - - int type = li->type(); - - if (QObject *obj = QmlMetaType::toQObject(value)) { - const QMetaObject *mo = - QmlMetaType::rawMetaObjectForType(type); - - const QMetaObject *objMo = obj->metaObject(); - bool found = false; - while(!found && objMo) { - if (objMo == mo) - found = true; - else - objMo = objMo->superClass(); + + // NOTE: This assumes a cast to QObject does not alter + // the object pointer + void *d = (void *)&obj; + li->append(d); + } + } else if (category == QmlMetaProperty::Normal) { + + switch(t) { + case QVariant::Double: + { + double d; + bool found = true; + if (vt == QVariant::Int) { + d = value.toInt(); + } else if (vt == QVariant::UInt) { + d = value.toUInt(); + } else { + found = false; } - if (!found) { - qWarning() << "Unable to assign object to list"; + if (found) { + void *a[1]; + a[0] = &d; + QMetaObject::metacall(object, + QMetaObject::WriteProperty, + coreIdx, a); return; } - - // NOTE: This assumes a cast to QObject does not alter - // the object pointer - void *d = (void *)&obj; - li->append(d); } - } else if (propertyCategory() == QmlMetaProperty::Normal) { - - switch(t) { - case QVariant::Double: - { - double d; - bool found = true; - if (vt == QVariant::Int) { - d = value.toInt(); - } else if (vt == QVariant::UInt) { - d = value.toUInt(); - } else { - found = false; - } - - if (found) { - void *a[1]; - a[0] = &d; - QMetaObject::metacall(object, - QMetaObject::WriteProperty, - coreIdx, a); - return; - } + break; + + case QVariant::Int: + { + int i; + bool found = true; + if (vt == QVariant::Double) { + i = (int)value.toDouble(); + } else if (vt == QVariant::UInt) { + i = (int)value.toUInt(); + } else { + found = false; } - break; - case QVariant::Int: - { - int i; - bool found = true; - if (vt == QVariant::Double) { - i = (int)value.toDouble(); - } else if (vt == QVariant::UInt) { - i = (int)value.toUInt(); - } else { - found = false; - } - - if (found) { - void *a[1]; - a[0] = &i; - QMetaObject::metacall(object, - QMetaObject::WriteProperty, - coreIdx, a); - return; - } + if (found) { + void *a[1]; + a[0] = &i; + QMetaObject::metacall(object, + QMetaObject::WriteProperty, + coreIdx, a); + return; + } + } + break; + + case QVariant::String: + { + QString s; + bool found = true; + if (vt == QVariant::ByteArray) { + s = QLatin1String(value.toByteArray()); + } else { + found = false; } - break; - case QVariant::String: - { - QString s; - bool found = true; - if (vt == QVariant::ByteArray) { - s = QLatin1String(value.toByteArray()); - } else { - found = false; - } - - if (found) { - void *a[1]; - a[0] = &s; - QMetaObject::metacall(object, - QMetaObject::WriteProperty, - coreIdx, a); - return; - } + if (found) { + void *a[1]; + a[0] = &s; + QMetaObject::metacall(object, + QMetaObject::WriteProperty, + coreIdx, a); + return; } - break; + } + break; - default: - break; - } - prop.write(object, value); + default: + break; } - + prop.write(object, value); } + } /*! -- cgit v0.12