void QDeclarativeListAccessor::setList(const QVariant &v, QDeclarativeEngine *engine) { d = v; QDeclarativeEnginePrivate *enginePrivate = engine?QDeclarativeEnginePrivate::get(engine):0; if (!d.isValid()) { m_type = Invalid; } else if (d.userType() == QVariant::StringList) { m_type = StringList; } else if (d.userType() == QMetaType::QVariantList) { m_type = VariantList; } else if (d.canConvert(QVariant::Int)) { m_type = Integer; } else if ((!enginePrivate && QDeclarativeMetaType::isQObject(d.userType())) || (enginePrivate && enginePrivate->isQObject(d.userType()))) { QObject *data = enginePrivate?enginePrivate->toQObject(v):QDeclarativeMetaType::toQObject(v); d = QVariant::fromValue(data); m_type = Instance; } else if (d.userType() == qMetaTypeId<QDeclarativeListReference>()) { m_type = ListProperty; } else { m_type = Instance; } }
bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property, const QVariant &value, QDeclarativeContextData *context, WriteFlags flags) { int coreIdx = property.coreIndex; int status = -1; //for dbus if (property.flags & QDeclarativePropertyCache::Data::IsEnumType) { QMetaProperty prop = object->metaObject()->property(property.coreIndex); QVariant v = value; // Enum values come through the script engine as doubles if (value.userType() == QVariant::Double) { double integral; double fractional = modf(value.toDouble(), &integral); if (qFuzzyIsNull(fractional)) v.convert(QVariant::Int); } return writeEnumProperty(prop, coreIdx, object, v, flags); } int propertyType = property.propType; int variantType = value.userType(); QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context); if (propertyType == QVariant::Url) { QUrl u; bool found = false; if (variantType == QVariant::Url) { u = value.toUrl(); found = true; } else if (variantType == QVariant::ByteArray) { u = QUrl(QString::fromUtf8(value.toByteArray())); found = true; } else if (variantType == QVariant::String) { u = QUrl(value.toString()); found = true; } if (!found) return false; if (context && u.isRelative() && !u.isEmpty()) u = context->resolvedUrl(u); int status = -1; void *argv[] = { &u, 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv); } else if (variantType == propertyType) { void *a[] = { (void *)value.constData(), 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else if (qMetaTypeId<QVariant>() == propertyType) { void *a[] = { (void *)&value, 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else if (property.flags & QDeclarativePropertyCache::Data::IsQObjectDerived) { const QMetaObject *valMo = rawMetaObjectForType(enginePriv, value.userType()); if (!valMo) return false; QObject *o = *(QObject **)value.constData(); const QMetaObject *propMo = rawMetaObjectForType(enginePriv, propertyType); 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 & QDeclarativePropertyCache::Data::IsQList) { const QMetaObject *listType = 0; if (enginePriv) { listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType)); } else { QDeclarativeType *type = QDeclarativeMetaType::qmlType(QDeclarativeMetaType::listType(property.propType)); if (!type) return false; listType = type->baseMetaObject(); } if (!listType) return false; QDeclarativeListProperty<void> prop; void *args[] = { &prop, 0 }; QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args); if (!prop.clear) return false; prop.clear(&prop); if (value.userType() == qMetaTypeId<QList<QObject *> >()) { const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value); for (int ii = 0; ii < list.count(); ++ii) { QObject *o = list.at(ii); if (o && !canConvert(o->metaObject(), listType)) o = 0; prop.append(&prop, (void *)o); } } else { QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value); if (o && !canConvert(o->metaObject(), listType)) o = 0; prop.append(&prop, (void *)o); } } else { Q_ASSERT(variantType != propertyType); QVariant v = value; if (v.convert((QVariant::Type)propertyType)) { void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) { QDeclarativeMetaType::StringConverter con = QDeclarativeMetaType::customStringConverter(propertyType); if (!con) return false; QVariant v = con(value.toString()); if (v.userType() == propertyType) { void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } } else if (variantType == QVariant::String) { bool ok = false; QVariant v = QDeclarativeStringConverters::variantFromString(value.toString(), propertyType, &ok); if (!ok) return false; void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else { return false; } } return true; }
void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, const QScriptValue &value) { if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId<QScriptValue>()) { qscriptValuePtr = new (&allocData) QScriptValue(value); type = qMetaTypeId<QScriptValue>(); } else if (callType == QMetaType::Int) { intValue = quint32(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { intValue = quint32(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { boolValue = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { doubleValue = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { floatValue = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) qstringPtr = new (&allocData) QString(); else qstringPtr = new (&allocData) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { qobjectPtr = value.toQObject(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { QVariant other = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value); qvariantPtr = new (&allocData) QVariant(other); type = callType; } else if (callType == qMetaTypeId<QList<QObject*> >()) { qlistPtr = new (&allocData) QList<QObject *>(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { QScriptValue arrayItem = value.property(ii); QObject *d = arrayItem.toQObject(); qlistPtr->append(d); } } else if (QObject *d = value.toQObject()) { qlistPtr->append(d); } type = callType; } else { qvariantPtr = new (&allocData) QVariant(); type = -1; QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { *qvariantPtr = v; } else if (v.canConvert((QVariant::Type)callType)) { *qvariantPtr = v; qvariantPtr->convert((QVariant::Type)callType); } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { QObject *obj = priv->toQObject(v); if (obj) { const QMetaObject *objMo = obj->metaObject(); while (objMo && objMo != mo) objMo = objMo->superClass(); if (!objMo) obj = 0; } *qvariantPtr = QVariant(callType, &obj); } else { *qvariantPtr = QVariant(callType, (void *)0); } } }