diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-12-22 10:15:47 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-04 08:55:55 +0100 |
commit | 32a9015c8f511608d98a9fdf16795b32c52052c3 (patch) | |
tree | 8608a6ed31eb45ac8f24ed83082418786f89e341 /src/qml/qml/qqmlproperty.cpp | |
parent | bb06d1382174b3a1ce560790df6432c9bf67a1cc (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.cpp | 73 |
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; + } + } + } } } |