diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-23 15:42:07 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-25 17:08:37 +0000 |
commit | 6d181fc043af65dfe97c6df4ee81249010b8f746 (patch) | |
tree | a8b52dd794fcd94bf0a32a697aa8191a06d6f98e /src | |
parent | 518509297fd545892ed4200b7b806f87d19cc57d (diff) |
QML: Allow converting any object list to QQmlListProperty
We can use QSequentialIterable for this.
Pick-to: 6.5
Fixes: QTBUG-110438
Change-Id: I7e82d0f089c9bb9eab46be46dedc2db3726e64b0
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 2eff37f54c..cfdcc9ea60 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1534,29 +1534,44 @@ bool QQmlPropertyPrivate::write( prop.clear(&prop); + const auto doAppend = [&](QObject *o) { + if (o && !QQmlMetaObject::canConvert(o, valueMetaObject)) + o = nullptr; + prop.append(&prop, o); + }; + if (variantMetaType == QMetaType::fromType<QQmlListReference>()) { QQmlListReference qdlr = value.value<QQmlListReference>(); - - for (qsizetype ii = 0; ii < qdlr.count(); ++ii) { - QObject *o = qdlr.at(ii); - if (o && !QQmlMetaObject::canConvert(o, valueMetaObject)) - o = nullptr; - prop.append(&prop, o); - } + 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) { - QObject *o = list.at(ii); - if (o && !QQmlMetaObject::canConvert(o, valueMetaObject)) - o = nullptr; - prop.append(&prop, o); + for (qsizetype ii = 0; ii < list.size(); ++ii) + doAppend(list.at(ii)); + } else if (QSequentialIterable iterable; + QMetaType::convert(variantMetaType, value.data(), + QMetaType::fromType<QSequentialIterable>(), &iterable)) { + const QMetaSequence metaContainer = iterable.metaContainer(); + if (metaContainer.hasConstIterator() + && metaContainer.canGetValueAtConstIterator() + && iterable.valueMetaType().flags().testFlag( + QMetaType::PointerToQObject)) { + const void *container = iterable.constIterable(); + void *it = metaContainer.constBegin(container); + const void *end = metaContainer.constEnd(container); + QObject *o = nullptr; + while (!metaContainer.compareConstIterator(it, end)) { + metaContainer.valueAtConstIterator(it, &o); + doAppend(o); + metaContainer.advanceConstIterator(it, 1); + } + metaContainer.destroyConstIterator(it); + metaContainer.destroyConstIterator(end); + } else { + doAppend(QQmlMetaType::toQObject(value)); } } else { - QObject *o = QQmlMetaType::toQObject(value); - if (o && !QQmlMetaObject::canConvert(o, valueMetaObject)) - o = nullptr; - prop.append(&prop, o); + doAppend(QQmlMetaType::toQObject(value)); } } else if (variantMetaType == propertyMetaType) { QVariant v = value; |