From 0c34325841ba1aed1dedd5b6affe235b1da151d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Cie=C5=9Blak?= Date: Fri, 5 Apr 2024 12:33:48 +0200 Subject: [PATCH] feat(StatusQ/LeftJoinModel): Add possibility to explicitly define roles to be joined The new property is added to allow indicating which roles from the right model should be used. It prevents from unnecessary renamings. Closes: #14298 --- ui/StatusQ/include/StatusQ/leftjoinmodel.h | 8 +++ ui/StatusQ/src/leftjoinmodel.cpp | 44 +++++++++++++- ui/StatusQ/tests/tst_LeftJoinModel.cpp | 69 ++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/ui/StatusQ/include/StatusQ/leftjoinmodel.h b/ui/StatusQ/include/StatusQ/leftjoinmodel.h index 5b585a78c2..43b656867a 100644 --- a/ui/StatusQ/include/StatusQ/leftjoinmodel.h +++ b/ui/StatusQ/include/StatusQ/leftjoinmodel.h @@ -16,6 +16,9 @@ class LeftJoinModel : public QAbstractListModel Q_PROPERTY(QString joinRole READ joinRole WRITE setJoinRole NOTIFY joinRoleChanged) + Q_PROPERTY(QStringList rolesToJoin READ rolesToJoin + WRITE setRolesToJoin NOTIFY rolesToJoinChanged) + public: explicit LeftJoinModel(QObject* parent = nullptr); @@ -28,6 +31,9 @@ public: void setJoinRole(const QString& joinRole); const QString& joinRole() const; + void setRolesToJoin(const QStringList& roles); + const QStringList& rolesToJoin() const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash roleNames() const override; QVariant data(const QModelIndex& index, int role) const override; @@ -36,6 +42,7 @@ signals: void leftModelChanged(); void rightModelChanged(); void joinRoleChanged(); + void rolesToJoinChanged(); private: void initializeIfReady(bool reset); @@ -51,6 +58,7 @@ private: QVector m_joinedRoles; QString m_joinRole; + QStringList m_rolesToJoin; int m_leftModelJoinRole = 0; int m_rightModelJoinRole = 0; diff --git a/ui/StatusQ/src/leftjoinmodel.cpp b/ui/StatusQ/src/leftjoinmodel.cpp index 776edf90c6..62db8a6c30 100644 --- a/ui/StatusQ/src/leftjoinmodel.cpp +++ b/ui/StatusQ/src/leftjoinmodel.cpp @@ -23,7 +23,35 @@ void LeftJoinModel::initialize(bool reset) auto rightRoleNames = m_rightModel->roleNames(); auto leftNames = leftRoleNames.values(); - auto rightNames = rightRoleNames.values(); + QList rightNames; + + if (m_rolesToJoin.empty()) { + rightNames = rightRoleNames.values(); + } else { + QHash tmpRightRoleNames; + + auto rolesToJoin = m_rolesToJoin; + + if (rolesToJoin.indexOf(m_joinRole) == -1) + rolesToJoin << m_joinRole; + + for (auto& roleName : qAsConst(rolesToJoin)) { + auto name = roleName.toUtf8(); + auto roles = rightRoleNames.keys(name); + + if (roles.empty()) { + qWarning().noquote() + << QString("Role to join %1 not found in the right model!") + .arg(roleName); + return; + } + + rightNames << name; + tmpRightRoleNames.insert(roles.front(), name); + } + + rightRoleNames = tmpRightRoleNames; + } QSet leftNamesSet(leftNames.cbegin(), leftNames.cend()); QSet rightNamesSet(rightNames.cbegin(), rightNames.cend()); @@ -347,6 +375,20 @@ const QString& LeftJoinModel::joinRole() const return m_joinRole; } +void LeftJoinModel::setRolesToJoin(const QStringList& roles) +{ + if (m_rolesToJoin == roles) + return; + + m_rolesToJoin = roles; + emit rolesToJoinChanged(); +} + +const QStringList &LeftJoinModel::rolesToJoin() const +{ + return m_rolesToJoin; +} + int LeftJoinModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) diff --git a/ui/StatusQ/tests/tst_LeftJoinModel.cpp b/ui/StatusQ/tests/tst_LeftJoinModel.cpp index d43c03a150..a89900f920 100644 --- a/ui/StatusQ/tests/tst_LeftJoinModel.cpp +++ b/ui/StatusQ/tests/tst_LeftJoinModel.cpp @@ -942,6 +942,75 @@ private slots: QCOMPARE(modelResetSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); } + + void invalidRolesToJoinTest() + { + TestModel leftModel({ + { "title", { "Token 1", "Token 2", "Token 3"}}, + { "communityId", { "community_1", "community_2", "community_1" }} + }); + + TestModel rightModel({ + { "name", { "Community 1", "Community 2" }}, + { "communityId", { "community_1", "community_2" }}, + { "other", { "other_1", "other_1" }} + }); + + LeftJoinModel model; + QAbstractItemModelTester tester(&model); + + QTest::ignoreMessage( + QtWarningMsg, + "Role to join notExisting not found in the right model!"); + + model.setLeftModel(&leftModel); + model.setRightModel(&rightModel); + + model.setRolesToJoin({ "name", "notExisting" }); + model.setJoinRole("communityId"); + + QCOMPARE(model.roleNames(), {}); + QCOMPARE(model.rowCount(), 0); + } + + void rolesToJoinTest() + { + TestModel leftModel({ + { "title", { "Token 1", "Token 2", "Token 3"}}, + { "communityId", { "community_1", "community_2", "community_1" }} + }); + + TestModel rightModel({ + { "name", { "Community 1", "Community 2" }}, + { "communityId", { "community_1", "community_2" }}, + { "other", { "other_1", "other_1" }} + }); + + LeftJoinModel model; + QAbstractItemModelTester tester(&model); + + model.setLeftModel(&leftModel); + model.setRightModel(&rightModel); + + model.setRolesToJoin({ "name" }); + model.setJoinRole("communityId"); + + QHash roles{{0, "title" }, {1, "communityId"}, {2, "name"}}; + + QCOMPARE(model.roleNames(), roles); + QCOMPARE(model.rowCount(), 3); + + QCOMPARE(model.rowCount(), 3); + QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1")); + QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2")); + QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3")); + QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1")); + QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2")); + QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1")); + QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1")); + QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2")); + QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1")); + } }; QTEST_MAIN(TestLeftJoinModel)