diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-04-27 10:20:36 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-04-27 15:29:25 +0200 |
commit | 01f6ba9949a2f4ef2ac38d14f9d6f3ccff5852c9 (patch) | |
tree | 751b4b7fb1db89f8aa179d788191a03d4ce085c9 | |
parent | 95837745e4123a9ba49948daefcc0d87969d1cec (diff) |
QQmlListAccessor: Support registered sequence types
Since we can pass any registered sequence types through QML as-is now,
they are not wrapped into JS arrays anymore. We have to accept them as
models because we also accept JS arrays.
Pick-to: 6.3
Fixes: QTBUG-102857
Change-Id: Ib294fff3681dce7f754efe877b19d17e698b4911
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/qmlmodels/qqmllistaccessor.cpp | 23 | ||||
-rw-r--r-- | src/qmlmodels/qqmllistaccessor_p.h | 14 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview2/data/metaSequenceAsModel.qml | 12 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp | 14 |
4 files changed, 61 insertions, 2 deletions
diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp index 230f190834..283fe2c85e 100644 --- a/src/qmlmodels/qqmllistaccessor.cpp +++ b/src/qmlmodels/qqmllistaccessor.cpp @@ -111,7 +111,13 @@ void QQmlListAccessor::setList(const QVariant &v) d = i; } } else { - m_type = Instance; + const QQmlType type = QQmlMetaType::qmlListType(v.metaType()); + if (type.isSequentialContainer()) { + m_metaSequence = type.listMetaSequence(); + m_type = Sequence; + } else { + m_type = Instance; + } } } @@ -133,6 +139,9 @@ qsizetype QQmlListAccessor::count() const case ListProperty: Q_ASSERT(d.metaType() == QMetaType::fromType<QQmlListReference>()); return reinterpret_cast<const QQmlListReference *>(d.constData())->count(); + case Sequence: + Q_ASSERT(m_metaSequence != QMetaSequence()); + return m_metaSequence.size(d.constData()); case Instance: return 1; case Integer: @@ -163,6 +172,18 @@ QVariant QQmlListAccessor::at(qsizetype idx) const case ListProperty: Q_ASSERT(d.metaType() == QMetaType::fromType<QQmlListReference>()); return QVariant::fromValue(reinterpret_cast<const QQmlListReference *>(d.constData())->at(idx)); + case Sequence: { + Q_ASSERT(m_metaSequence != QMetaSequence()); + QVariant result; + const QMetaType valueMetaType = m_metaSequence.valueMetaType(); + if (valueMetaType == QMetaType::fromType<QVariant>()) { + m_metaSequence.valueAtIndex(d.constData(), idx, &result); + } else { + result = QVariant(valueMetaType); + m_metaSequence.valueAtIndex(d.constData(), idx, result.data()); + } + return result; + } case Instance: return d; case Integer: diff --git a/src/qmlmodels/qqmllistaccessor_p.h b/src/qmlmodels/qqmllistaccessor_p.h index b3b344cd47..a0d2d78ce3 100644 --- a/src/qmlmodels/qqmllistaccessor_p.h +++ b/src/qmlmodels/qqmllistaccessor_p.h @@ -71,11 +71,23 @@ public: qsizetype count() const; QVariant at(qsizetype) const; - enum Type { Invalid, StringList, UrlList, VariantList, ObjectList, ListProperty, Instance, Integer }; + enum Type { + Invalid, + StringList, + UrlList, + VariantList, + ObjectList, + ListProperty, + Instance, + Integer, + Sequence, + }; + Type type() const { return m_type; } private: Type m_type; + QMetaSequence m_metaSequence; QVariant d; }; diff --git a/tests/auto/quick/qquicklistview2/data/metaSequenceAsModel.qml b/tests/auto/quick/qquicklistview2/data/metaSequenceAsModel.qml new file mode 100644 index 0000000000..2b4651feaa --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/metaSequenceAsModel.qml @@ -0,0 +1,12 @@ +import QtQuick + +ListView { + id: view + property list<rect> rects: [ Qt.rect(1, 2, 3, 4), Qt.rect(5, 6, 7, 8) ] + property list<string> texts + + model: rects + delegate: Item { + Component.onCompleted: view.texts.push(modelData.x + "/" + modelData.y) + } +} diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp index 6cc7abef39..a8181f6bdb 100644 --- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp +++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp @@ -57,6 +57,7 @@ private slots: void singletonModelLifetime(); void sectionsNoOverlap(); + void metaSequenceAsModel(); }; tst_QQuickListView2::tst_QQuickListView2() @@ -275,6 +276,19 @@ void tst_QQuickListView2::sectionsNoOverlap() } } +void tst_QQuickListView2::metaSequenceAsModel() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("metaSequenceAsModel.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QStringList strings = qvariant_cast<QStringList>(o->property("texts")); + QCOMPARE(strings.length(), 2); + QCOMPARE(strings[0], QStringLiteral("1/2")); + QCOMPARE(strings[1], QStringLiteral("5/6")); +} + class SingletonModel : public QStringListModel { |