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
This commit is contained in:
Michał Cieślak 2024-04-05 12:33:48 +02:00 committed by Michał
parent 53db09412a
commit 0c34325841
3 changed files with 120 additions and 1 deletions

View File

@ -16,6 +16,9 @@ class LeftJoinModel : public QAbstractListModel
Q_PROPERTY(QString joinRole READ joinRole Q_PROPERTY(QString joinRole READ joinRole
WRITE setJoinRole NOTIFY joinRoleChanged) WRITE setJoinRole NOTIFY joinRoleChanged)
Q_PROPERTY(QStringList rolesToJoin READ rolesToJoin
WRITE setRolesToJoin NOTIFY rolesToJoinChanged)
public: public:
explicit LeftJoinModel(QObject* parent = nullptr); explicit LeftJoinModel(QObject* parent = nullptr);
@ -28,6 +31,9 @@ public:
void setJoinRole(const QString& joinRole); void setJoinRole(const QString& joinRole);
const QString& joinRole() const; const QString& joinRole() const;
void setRolesToJoin(const QStringList& roles);
const QStringList& rolesToJoin() const;
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
QVariant data(const QModelIndex& index, int role) const override; QVariant data(const QModelIndex& index, int role) const override;
@ -36,6 +42,7 @@ signals:
void leftModelChanged(); void leftModelChanged();
void rightModelChanged(); void rightModelChanged();
void joinRoleChanged(); void joinRoleChanged();
void rolesToJoinChanged();
private: private:
void initializeIfReady(bool reset); void initializeIfReady(bool reset);
@ -51,6 +58,7 @@ private:
QVector<int> m_joinedRoles; QVector<int> m_joinedRoles;
QString m_joinRole; QString m_joinRole;
QStringList m_rolesToJoin;
int m_leftModelJoinRole = 0; int m_leftModelJoinRole = 0;
int m_rightModelJoinRole = 0; int m_rightModelJoinRole = 0;

View File

@ -23,7 +23,35 @@ void LeftJoinModel::initialize(bool reset)
auto rightRoleNames = m_rightModel->roleNames(); auto rightRoleNames = m_rightModel->roleNames();
auto leftNames = leftRoleNames.values(); auto leftNames = leftRoleNames.values();
auto rightNames = rightRoleNames.values(); QList<QByteArray> rightNames;
if (m_rolesToJoin.empty()) {
rightNames = rightRoleNames.values();
} else {
QHash<int, QByteArray> 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<QByteArray> leftNamesSet(leftNames.cbegin(), leftNames.cend()); QSet<QByteArray> leftNamesSet(leftNames.cbegin(), leftNames.cend());
QSet<QByteArray> rightNamesSet(rightNames.cbegin(), rightNames.cend()); QSet<QByteArray> rightNamesSet(rightNames.cbegin(), rightNames.cend());
@ -347,6 +375,20 @@ const QString& LeftJoinModel::joinRole() const
return m_joinRole; 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 int LeftJoinModel::rowCount(const QModelIndex &parent) const
{ {
if (parent.isValid()) if (parent.isValid())

View File

@ -942,6 +942,75 @@ private slots:
QCOMPARE(modelResetSpy.count(), 1); QCOMPARE(modelResetSpy.count(), 1);
QCOMPARE(dataChangedSpy.count(), 0); 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<int, QByteArray> 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) QTEST_MAIN(TestLeftJoinModel)