summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qmlmetaproperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qmlmetaproperty.cpp')
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp130
1 files changed, 78 insertions, 52 deletions
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 5635016..feedf13 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -768,13 +768,14 @@ bool QmlMetaPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int id
return status;
}
-void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
+bool QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
QmlMetaProperty::WriteFlags flags)
{
// Remove any existing bindings on this property
if (!(flags & QmlMetaProperty::DontRemoveBinding))
delete q->setBinding(0);
+ bool rv = false;
uint type = q->type();
if (type & QmlMetaProperty::ValueTypeProperty) {
QmlEnginePrivate *ep =
@@ -792,20 +793,23 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
QmlPropertyCache::Data data = core;
data.coreIndex = valueTypeCoreIdx;
data.propType = valueTypePropType;
- write(writeBack, data, value, context, flags);
+ rv = write(writeBack, data, value, context, flags);
writeBack->write(object, core.coreIndex, flags);
if (!ep) delete writeBack;
} else {
- write(object, core, value, context, flags);
+ rv = write(object, core, value, context, flags);
}
+
+ return rv;
}
-void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property,
- const QVariant &value, QmlContext *context, QmlMetaProperty::WriteFlags flags)
+bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property,
+ const QVariant &value, QmlContext *context,
+ QmlMetaProperty::WriteFlags flags)
{
int coreIdx = property.coreIndex;
int status = -1; //for dbus
@@ -820,14 +824,16 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
if (qFuzzyCompare(fractional, (double)0.0))
v.convert(QVariant::Int);
}
- writeEnumProperty(prop, coreIdx, object, v, flags);
-
- return;
+ return writeEnumProperty(prop, coreIdx, object, v, flags);
}
int t = property.propType;
int vt = value.userType();
+ QmlEnginePrivate *enginePriv = 0;
+ if (context && context->engine())
+ enginePriv = QmlEnginePrivate::get(context->engine());
+
if (t == QVariant::Url) {
QUrl u;
@@ -843,13 +849,14 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
found = true;
}
- if (found) {
- if (context && u.isRelative() && !u.isEmpty())
- u = context->baseUrl().resolved(u);
- int status = -1;
- void *argv[] = { &u, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);
- }
+ if (!found)
+ return false;
+
+ if (context && u.isRelative() && !u.isEmpty())
+ u = context->baseUrl().resolved(u);
+ int status = -1;
+ void *argv[] = { &u, 0, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);
} else if (vt == t) {
@@ -863,29 +870,33 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
} else if (property.flags & QmlPropertyCache::Data::IsQObjectDerived) {
- QObject *o = QmlMetaType::toQObject(value);
-
const QMetaObject *valMo = 0;
+ if (enginePriv) valMo = enginePriv->rawMetaObjectForType(value.userType());
+ else valMo = QmlMetaType::rawMetaObjectForType(value.userType());
+
+ if (!valMo)
+ return false;
- if (o) {
+ QObject *o = *(QObject **)value.constData();
+ const QMetaObject *propMo = 0;
+ if (enginePriv) propMo = enginePriv->rawMetaObjectForType(t);
+ else propMo = QmlMetaType::rawMetaObjectForType(t);
- valMo = o->metaObject();
- const QMetaObject *propMo = QmlMetaType::rawMetaObjectForType(t);
-
- while (valMo) {
- if (equal(valMo, propMo))
- break;
- valMo = valMo->superClass();
- }
-
- }
-
- if (valMo || !o) {
+ if (o) valMo = o->metaObject();
+ if (canConvert(valMo, propMo)) {
void *args[] = { &o, 0, &status, &flags };
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
args);
-
+ } else if (!o && canConvert(propMo, valMo)) {
+ // In the case of a null QObject, we assign the null if there is
+ // any change that the null variant type could be up or down cast to
+ // the property type.
+ void *args[] = { &o, 0, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
+ args);
+ } else {
+ return false;
}
} else if (property.flags & QmlPropertyCache::Data::IsQList) {
@@ -932,10 +943,8 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
objMo = objMo->superClass();
}
- if (!found) {
- qWarning() << "Unable to assign object to list";
- return;
- }
+ if (!found)
+ return false;
// NOTE: This assumes a cast to QObject does not alter
// the object pointer
@@ -951,35 +960,36 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
} else if ((uint)t >= QVariant::UserType && vt == QVariant::String) {
QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(t);
- if (con) {
- QVariant v = con(value.toString());
- if (v.userType() == t) {
- void *a[] = { (void *)v.constData(), 0, &status, &flags};
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
- }
+ if (!con)
+ return false;
+
+ QVariant v = con(value.toString());
+ if (v.userType() == t) {
+ void *a[] = { (void *)v.constData(), 0, &status, &flags};
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
}
+ } else {
+ return false;
}
}
+
+ return true;
}
/*!
Set the property value to \a value.
*/
-void QmlMetaProperty::write(const QVariant &value) const
+bool QmlMetaProperty::write(const QVariant &value) const
{
- write(value, 0);
+ return write(value, 0);
}
-void QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const
+bool QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const
{
- if (!d->object)
- return;
-
- if (type() & Property && d->core.isValid()) {
-
- d->writeValueProperty(value, flags);
-
- }
+ if (d->object && type() & Property && d->core.isValid())
+ return d->writeValueProperty(value, flags);
+ else
+ return false;
}
/*!
@@ -1217,5 +1227,21 @@ bool QmlMetaPropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rh
return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
}
+/*!
+ Returns true if from inherits to.
+*/
+bool QmlMetaPropertyPrivate::canConvert(const QMetaObject *from, const QMetaObject *to)
+{
+ if (from && to == &QObject::staticMetaObject)
+ return true;
+
+ while (from) {
+ if (equal(from, to))
+ return true;
+ from = from->superClass();
+ }
+
+ return false;
+}
QT_END_NAMESPACE