Storybook: Add example combining RolesRenamingModel, LeftJoinModel and SFPM

This commit is contained in:
Michał Cieślak 2023-10-25 23:44:10 +02:00 committed by Michał
parent ffadd7522c
commit 2fae6d808d
3 changed files with 157 additions and 13 deletions

View File

@ -0,0 +1,121 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import StatusQ 0.1
import SortFilterProxyModel 0.2
Control {
font.pixelSize: 15
ListModel {
id: leftBaseModel
Component.onCompleted: {
const items = []
for (let i = 0; i < 1000; i++)
items.push({ name: `base name (${i})`, foreignId: i % 15 })
append(items)
}
}
ListModel {
id: rightBaseModel
Component.onCompleted: {
const items = []
for (let i = 0; i < 20; i++)
items.push({ id: i, name: `foreign name (${i})` })
append(items)
}
}
RolesRenamingModel {
id: leftModelRenamed
sourceModel: leftBaseModel
mapping: RoleRename {
from: "name"
to: "baseName"
}
}
RolesRenamingModel {
id: rightModelRenamed
sourceModel: rightBaseModel
mapping: RoleRename {
from: "id"
to: "foreignId"
}
}
LeftJoinModel {
id: joinModel
leftModel: leftModelRenamed
rightModel: rightModelRenamed
joinRole: "foreignId"
}
SortFilterProxyModel {
id: filteringModel
sourceModel: joinModel
filters: ValueFilter {
roleName: "foreignId"
value: searchTextField.text
enabled: searchTextField.length
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
Label {
Layout.fillWidth: true
text: "Simple example showing how to compose custom model from two "
+ "source models using RolesRenamingModel, LeftJoinModel "
+ "and SortFilterProxyModel"
font.bold: true
wrapMode: Text.Wrap
}
TextField {
id: searchTextField
Layout.fillWidth: true
placeholderText: "Filter by foreign id"
}
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
ScrollBar.vertical: ScrollBar {}
model: filteringModel
clip: true
delegate: Label {
width: ListView.view.height
text: `${model.baseName}, ${model.name} (id: ${model.foreignId})`
}
}
}
}
// category: Research / Examples

View File

@ -13,7 +13,8 @@ void RoleRename::setFrom(const QString& from)
return;
if (!m_from.isEmpty()) {
qWarning() << "RoleRename: property \"from\" is inteded to be initialized once and not changed!";
qWarning() << "RoleRename: property \"from\" is intended to be "
"initialized once and not changed!";
return;
}
@ -32,7 +33,8 @@ void RoleRename::setTo(const QString& to)
return;
if (!m_to.isEmpty()) {
qWarning() << "RoleRename: property \"to\" is inteded to be initialized once and not changed!";
qWarning() << "RoleRename: property \"to\" is intended to be "
"initialized once and not changed!";
return;
}
@ -63,7 +65,8 @@ QQmlListProperty<RoleRename> RolesRenamingModel::mapping()
listProperty->object);
if (model->m_rolesFetched) {
qWarning() << "RolesRenamingModel: role names mapping cannot be modified after fetching role names!";
qWarning() << "RolesRenamingModel: role names mapping cannot be "
"modified after fetching role names!";
return;
}
@ -102,7 +105,8 @@ QHash<int, QByteArray> RolesRenamingModel::roleNames() const
}
if (roles.size() != roleNamesSet.size()) {
qWarning() << "RolesRenamingModel: model cannot contain duplicated role names!";
qWarning() << "RolesRenamingModel: model cannot contain duplicated "
"role names!";
return {};
}

View File

@ -51,8 +51,9 @@ class TestRolesRenamingModel: public QObject
Q_OBJECT
private slots:
void initializationTest()
void initializationWithBrokenMappingTest()
{
TestSourceModel sourceModel({"id", "name", "color"});
RolesRenamingModel model;
QQmlListProperty<RoleRename> mapping = model.mapping();
@ -63,9 +64,16 @@ private slots:
mapping.append(&mapping, &rename);
QTest::ignoreMessage(QtWarningMsg, "RolesRenamingModel: specified source roles not found: (\"someIdFrom\")!");
model.setSourceModel(&sourceModel);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"RolesRenamingModel: specified source roles not "
"found: (\"someIdFrom\")!");
QHash<int, QByteArray> expectedRoles = {
{0, "id"}, {1, "name"}, {2, "color"}
};
QCOMPARE(model.roleNames(), expectedRoles);
}
void remappingTest()
@ -87,7 +95,9 @@ private slots:
model.setSourceModel(&sourceModel);
QHash<int, QByteArray> expectedRoles = {{0, "tokenId"}, {1, "tokenName"}, {2, "color"}};
QHash<int, QByteArray> expectedRoles = {
{0, "tokenId"}, {1, "tokenName"}, {2, "color"}
};
QCOMPARE(model.roleNames(), expectedRoles);
}
@ -105,14 +115,18 @@ private slots:
model.setSourceModel(&sourceModel);
QHash<int, QByteArray> expectedRoles = {{0, "tokenId"}, {1, "name"}, {2, "color"}};
QHash<int, QByteArray> expectedRoles = {
{0, "tokenId"}, {1, "name"}, {2, "color"}
};
QCOMPARE(model.roleNames(), expectedRoles);
RoleRename rename_2;
rename_2.setFrom("name");
rename_2.setTo("tokenName");
QTest::ignoreMessage(QtWarningMsg, "RolesRenamingModel: role names mapping cannot be modified after fetching role names!");
QTest::ignoreMessage(QtWarningMsg,
"RolesRenamingModel: role names mapping cannot be "
"modified after fetching role names!");
mapping.append(&mapping, &rename_2);
QCOMPARE(model.roleNames(), expectedRoles);
@ -132,7 +146,9 @@ private slots:
model.setSourceModel(&sourceModel);
QTest::ignoreMessage(QtWarningMsg, "RolesRenamingModel: model cannot contain duplicated role names!");
QTest::ignoreMessage(QtWarningMsg,
"RolesRenamingModel: model cannot contain "
"duplicated role names!");
QCOMPARE(model.roleNames(), {});
}
@ -146,7 +162,8 @@ private slots:
QCOMPARE(rename.to(), "");
QTest::ignoreMessage(QtWarningMsg,
"RoleRename: property \"from\" is inteded to be initialized once and not changed!");
"RoleRename: property \"from\" is intended to be "
"initialized once and not changed!");
rename.setFrom("id2");
QCOMPARE(rename.from(), "id");
QCOMPARE(rename.to(), "");
@ -155,7 +172,9 @@ private slots:
QCOMPARE(rename.from(), "id");
QCOMPARE(rename.to(), "myId");
QTest::ignoreMessage(QtWarningMsg, "RoleRename: property \"to\" is inteded to be initialized once and not changed!");
QTest::ignoreMessage(QtWarningMsg,
"RoleRename: property \"to\" is intended to be "
"initialized once and not changed!");
rename.setTo("myId2");
QCOMPARE(rename.from(), "id");
QCOMPARE(rename.to(), "myId");