diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 131 | ||||
| -rw-r--r-- | src/qml/qml/qqmlproperty_p.h | 1 |
2 files changed, 69 insertions, 63 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index f4d3465b74..ca5f85df27 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1494,6 +1494,74 @@ static bool tryAssignBinding( return true; } +static bool assignToListProperty(const QQmlPropertyData &property, QQmlPropertyData::WriteFlags flags, const QMetaType propertyMetaType, const QMetaType variantMetaType, const QVariant &value, QObject *object) +{ + if (propertyMetaType.flags() & QMetaType::IsQmlList) { + QMetaType listValueType = QQmlMetaType::listValueType(propertyMetaType); + QQmlMetaObject valueMetaObject = QQmlMetaType::rawMetaObjectForType(listValueType); + if (valueMetaObject.isNull()) + return false; + + QQmlListProperty<QObject> prop; + property.readProperty(object, &prop); + + if (!prop.clear || !prop.append) + return false; + + const bool useNonsignalingListOps = prop.clear == &QQmlVMEMetaObject::list_clear + && prop.append == &QQmlVMEMetaObject::list_append; + + auto propClear = + useNonsignalingListOps ? &QQmlVMEMetaObject::list_clear_nosignal : prop.clear; + auto propAppend = + useNonsignalingListOps ? &QQmlVMEMetaObject::list_append_nosignal : prop.append; + + propClear(&prop); + + const auto doAppend = [&](QObject *o) { + if (Q_UNLIKELY(o && !QQmlMetaObject::canConvert(o, valueMetaObject))) { + qCWarning(lcIncompatibleElement) + << "Cannot append" << o << "to a QML list of" << listValueType.name(); + o = nullptr; + } + propAppend(&prop, o); + }; + + if (variantMetaType == QMetaType::fromType<QQmlListReference>()) { + QQmlListReference qdlr = value.value<QQmlListReference>(); + for (qsizetype ii = 0; ii < qdlr.count(); ++ii) + doAppend(qdlr.at(ii)); + } else if (variantMetaType == QMetaType::fromType<QList<QObject *>>()) { + const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value); + for (qsizetype ii = 0; ii < list.size(); ++ii) + doAppend(list.at(ii)); + } else if (variantMetaType == QMetaType::fromType<QList<QVariant>>()) { + const QList<QVariant> &list + = *static_cast<const QList<QVariant> *>(value.constData()); + for (const QVariant &entry : list) + doAppend(QQmlMetaType::toQObject(entry)); + } else if (!iterateQObjectContainer(variantMetaType, value.data(), doAppend)) { + doAppend(QQmlMetaType::toQObject(value)); + } + if (useNonsignalingListOps) { + Q_ASSERT(QQmlVMEMetaObject::get(object)); + QQmlVMEResolvedList(&prop).activateSignal(); + } + + return true; + } else if (variantMetaType == propertyMetaType) { + QVariant v = value; + return property.writeProperty(object, v.data(), flags); + } else { + QVariant list(propertyMetaType); + const QQmlType type = QQmlMetaType::qmlType(propertyMetaType); + const QMetaSequence sequence = type.listMetaSequence(); + if (sequence.canAddValue()) + sequence.addValue(list.data(), value.data()); + return property.writeProperty(object, list.data(), flags); + } +} + bool QQmlPropertyPrivate::write( QObject *object, const QQmlPropertyData &property, const QVariant &value, const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData::WriteFlags flags) @@ -1584,68 +1652,7 @@ bool QQmlPropertyPrivate::write( : urlSequence(value); return property.writeProperty(object, &urlSeq, flags); } else if (property.isQList()) { - if (propertyMetaType.flags() & QMetaType::IsQmlList) { - QMetaType listValueType = QQmlMetaType::listValueType(propertyMetaType); - QQmlMetaObject valueMetaObject = QQmlMetaType::rawMetaObjectForType(listValueType); - if (valueMetaObject.isNull()) - return false; - - QQmlListProperty<QObject> prop; - property.readProperty(object, &prop); - - if (!prop.clear || !prop.append) - return false; - - const bool useNonsignalingListOps = prop.clear == &QQmlVMEMetaObject::list_clear - && prop.append == &QQmlVMEMetaObject::list_append; - - auto propClear = - useNonsignalingListOps ? &QQmlVMEMetaObject::list_clear_nosignal : prop.clear; - auto propAppend = - useNonsignalingListOps ? &QQmlVMEMetaObject::list_append_nosignal : prop.append; - - propClear(&prop); - - const auto doAppend = [&](QObject *o) { - if (Q_UNLIKELY(o && !QQmlMetaObject::canConvert(o, valueMetaObject))) { - qCWarning(lcIncompatibleElement) - << "Cannot append" << o << "to a QML list of" << listValueType.name(); - o = nullptr; - } - propAppend(&prop, o); - }; - - if (variantMetaType == QMetaType::fromType<QQmlListReference>()) { - QQmlListReference qdlr = value.value<QQmlListReference>(); - for (qsizetype ii = 0; ii < qdlr.count(); ++ii) - doAppend(qdlr.at(ii)); - } else if (variantMetaType == QMetaType::fromType<QList<QObject *>>()) { - const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value); - for (qsizetype ii = 0; ii < list.size(); ++ii) - doAppend(list.at(ii)); - } else if (variantMetaType == QMetaType::fromType<QList<QVariant>>()) { - const QList<QVariant> &list - = *static_cast<const QList<QVariant> *>(value.constData()); - for (const QVariant &entry : list) - doAppend(QQmlMetaType::toQObject(entry)); - } else if (!iterateQObjectContainer(variantMetaType, value.data(), doAppend)) { - doAppend(QQmlMetaType::toQObject(value)); - } - if (useNonsignalingListOps) { - Q_ASSERT(QQmlVMEMetaObject::get(object)); - QQmlVMEResolvedList(&prop).activateSignal(); - } - } else if (variantMetaType == propertyMetaType) { - QVariant v = value; - property.writeProperty(object, v.data(), flags); - } else { - QVariant list(propertyMetaType); - const QQmlType type = QQmlMetaType::qmlType(propertyMetaType); - const QMetaSequence sequence = type.listMetaSequence(); - if (sequence.canAddValue()) - sequence.addValue(list.data(), value.data()); - property.writeProperty(object, list.data(), flags); - } + return assignToListProperty(property, flags, propertyMetaType, variantMetaType, value, object); } else if (enginePriv && propertyMetaType == QMetaType::fromType<QJSValue>()) { // We can convert everything into a QJSValue if we have an engine. QJSValue jsValue = QJSValuePrivate::fromReturnedValue( diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index 129339a207..db3cb62166 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -153,7 +153,6 @@ public: QObject *target, const QString &propertyName, const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyPrivate::InitFlags flags); - }; Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::BindingFlags) |
