aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlproperty.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-12-22 10:15:47 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-01-04 08:55:55 +0100
commit32a9015c8f511608d98a9fdf16795b32c52052c3 (patch)
tree8608a6ed31eb45ac8f24ed83082418786f89e341 /src/qml/qml/qqmlproperty.cpp
parentbb06d1382174b3a1ce560790df6432c9bf67a1cc (diff)
QML: Re-allow assigning QVariantList to arbitrary other lists
Since we can assign a QVariant to any other singular value, we should be able to do the same with lists of QVariant. This ability was lost when we stopped converting QVariantList to JS array but rather started to express it as QV4::Sequence. As a drive-by, generalize the messy code that allows assigning singular values to lists. This should also just work for any singular value and any kind of list. Fixes: QTBUG-109584 Pick-to: 6.4 6.5 Change-Id: Icab1dceff332c5fc4fae9e7e8a8b5fde9f0b0ea9 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlproperty.cpp')
-rw-r--r--src/qml/qml/qqmlproperty.cpp73
1 files changed, 40 insertions, 33 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 8f1e32b573..2eff37f54c 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -29,6 +29,7 @@
#include <cmath>
#include <QtQml/QQmlPropertyMap>
#include <QtCore/private/qproperty_p.h>
+#include <QtCore/qsequentialiterable.h>
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<qreal>)
@@ -1599,40 +1600,46 @@ bool QQmlPropertyPrivate::write(
}
if (!ok) {
// the only other options are that they are assigning a single value
- // to a sequence type property (eg, an int to a QList<int> property).
- // or that we encountered an interface type
+ // or a QVariantList to a sequence type property (eg, an int to a
+ // QList<int> property) or that we encountered an interface type.
// Note that we've already handled single-value assignment to QList<QUrl> properties.
- if (variantMetaType == QMetaType::fromType<int>()
- && propertyMetaType == QMetaType::fromType<QList<int>>()) {
- QList<int> list;
- list << value.toInt();
- v = QVariant::fromValue<QList<int> >(list);
- ok = true;
- } else if ((variantMetaType == QMetaType::fromType<double>()
- || variantMetaType == QMetaType::fromType<int>())
- && (propertyMetaType == QMetaType::fromType<QList<qreal>>())) {
- QList<qreal> list;
- list << value.toReal();
- v = QVariant::fromValue<QList<qreal> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<bool>()
- && propertyMetaType == QMetaType::fromType<QList<bool>>()) {
- QList<bool> list;
- list << value.toBool();
- v = QVariant::fromValue<QList<bool> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<QString>()
- && propertyMetaType == QMetaType::fromType<QList<QString>>()) {
- QList<QString> list;
- list << value.toString();
- v = QVariant::fromValue<QList<QString> >(list);
- ok = true;
- } else if (variantMetaType == QMetaType::fromType<QString>()
- && propertyMetaType == QMetaType::fromType<QStringList>()) {
- QStringList list;
- list << value.toString();
- v = QVariant::fromValue<QStringList>(list);
- ok = true;
+ QSequentialIterable iterable;
+ v = QVariant(propertyMetaType);
+ if (QMetaType::view(
+ propertyMetaType, v.data(),
+ QMetaType::fromType<QSequentialIterable>(),
+ &iterable)) {
+ const QMetaSequence metaContainer = iterable.metaContainer();
+ if (metaContainer.canAddValueAtEnd()) {
+ const QMetaType elementMetaType = iterable.valueMetaType();
+ void *container = iterable.mutableIterable();
+ if (variantMetaType == elementMetaType) {
+ metaContainer.addValueAtEnd(container, value.constData());
+ ok = true;
+ } else if (variantMetaType == QMetaType::fromType<QVariantList>()) {
+ const QVariantList list = value.value<QVariantList>();
+ for (const QVariant &valueElement : list) {
+ if (valueElement.metaType() == elementMetaType) {
+ metaContainer.addValueAtEnd(
+ container, valueElement.constData());
+ } else {
+ QVariant converted(elementMetaType);
+ QMetaType::convert(
+ valueElement.metaType(), valueElement.constData(),
+ elementMetaType, converted.data());
+ metaContainer.addValueAtEnd(
+ container, converted.constData());
+ }
+ }
+ ok = true;
+ } else {
+ QVariant converted = value;
+ if (converted.convert(elementMetaType)) {
+ metaContainer.addValueAtEnd(container, converted.constData());
+ ok = true;
+ }
+ }
+ }
}
}