aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-04-27 10:20:36 +0200
committerUlf Hermann <ulf.hermann@qt.io>2022-04-27 15:29:25 +0200
commit01f6ba9949a2f4ef2ac38d14f9d6f3ccff5852c9 (patch)
tree751b4b7fb1db89f8aa179d788191a03d4ce085c9
parent95837745e4123a9ba49948daefcc0d87969d1cec (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.cpp23
-rw-r--r--src/qmlmodels/qqmllistaccessor_p.h14
-rw-r--r--tests/auto/quick/qquicklistview2/data/metaSequenceAsModel.qml12
-rw-r--r--tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp14
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
{