StatusQ(LeftJoinModel): Handling of layoutChanged from source models fixed

Closes: #13683
This commit is contained in:
Michał Cieślak 2024-02-22 14:56:20 +01:00 committed by Alex Jbanca
parent 1639f1f9e7
commit 0497ecd82e
5 changed files with 93 additions and 9 deletions

View File

@ -60,4 +60,8 @@ private:
bool m_initialized = false; bool m_initialized = false;
mutable QPersistentModelIndex m_lastUsedRightModelIndex; mutable QPersistentModelIndex m_lastUsedRightModelIndex;
// helpers for handling layoutChanged from source
QList<QPersistentModelIndex> m_layoutChangePersistentIndexes;
QModelIndexList m_proxyIndexes;
}; };

View File

@ -145,19 +145,39 @@ void LeftJoinModel::connectLeftModelSignals()
connect(m_leftModel, &QAbstractItemModel::layoutAboutToBeChanged, this, [this]() { connect(m_leftModel, &QAbstractItemModel::layoutAboutToBeChanged, this, [this]() {
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
const auto persistentIndexes = persistentIndexList();
for (const QModelIndex& persistentIndex: persistentIndexes) {
m_proxyIndexes << persistentIndex;
Q_ASSERT(persistentIndex.isValid());
const auto srcIndex = m_leftModel->index(
persistentIndex.row(),
persistentIndex.column());
Q_ASSERT(srcIndex.isValid());
m_layoutChangePersistentIndexes << srcIndex;
}
}); });
connect(m_leftModel, &QAbstractItemModel::layoutChanged, this, [this]() { connect(m_leftModel, &QAbstractItemModel::layoutChanged, this, [this]() {
for (int i = 0; i < m_proxyIndexes.size(); ++i) {
auto p = m_layoutChangePersistentIndexes.at(i);
changePersistentIndex(m_proxyIndexes.at(i), index(
p.row(), p.column(), p.parent()));
}
m_layoutChangePersistentIndexes.clear();
m_proxyIndexes.clear();
emit layoutChanged(); emit layoutChanged();
}); });
connect(m_leftModel, &QAbstractItemModel::modelAboutToBeReset, this, [this]() { connect(m_leftModel, &QAbstractItemModel::modelAboutToBeReset, this,
beginResetModel(); &LeftJoinModel::beginResetModel);
});
connect(m_leftModel, &QAbstractItemModel::modelReset, this, [this]() { connect(m_leftModel, &QAbstractItemModel::modelReset, this,
endResetModel(); &LeftJoinModel::endResetModel);
});
} }
void LeftJoinModel::connectRightModelSignals() void LeftJoinModel::connectRightModelSignals()
@ -188,8 +208,6 @@ void LeftJoinModel::connectRightModelSignals()
emitJoinedRolesChanged); emitJoinedRolesChanged);
connect(m_rightModel, &QAbstractItemModel::modelReset, this, connect(m_rightModel, &QAbstractItemModel::modelReset, this,
emitJoinedRolesChanged); emitJoinedRolesChanged);
connect(m_rightModel, &QAbstractItemModel::layoutChanged, this,
emitJoinedRolesChanged);
} }
QVariant LeftJoinModel::data(const QModelIndex& index, int role) const QVariant LeftJoinModel::data(const QModelIndex& index, int role) const

View File

@ -10,6 +10,8 @@ PersistentIndexesTester::PersistentIndexesTester(QAbstractItemModel* model)
storeIndexesAndData(); storeIndexesAndData();
} }
PersistentIndexesTester::~PersistentIndexesTester() = default;
void PersistentIndexesTester::storeIndexesAndData() void PersistentIndexesTester::storeIndexesAndData()
{ {
if (m_model == nullptr) { if (m_model == nullptr) {

View File

@ -19,6 +19,7 @@ class PersistentIndexesTester
{ {
public: public:
explicit PersistentIndexesTester(QAbstractItemModel* model); explicit PersistentIndexesTester(QAbstractItemModel* model);
~PersistentIndexesTester();
void storeIndexesAndData(); void storeIndexesAndData();
bool compare(); bool compare();

View File

@ -5,6 +5,8 @@
#include <memory> #include <memory>
#include <StatusQ/leftjoinmodel.h> #include <StatusQ/leftjoinmodel.h>
#include <TestHelpers/persistentindexestester.h>
#include <TestHelpers/testmodel.h> #include <TestHelpers/testmodel.h>
class TestLeftJoinModel: public QObject class TestLeftJoinModel: public QObject
@ -387,7 +389,7 @@ private slots:
} }
} }
// TODO: cover also move and layoutChanged // TODO: cover also move
void insertRemovePropagationTest() void insertRemovePropagationTest()
{ {
TestModel leftModel({ TestModel leftModel({
@ -445,6 +447,63 @@ private slots:
QCOMPARE(rowsRemovedSpy.first().at(2), 1); QCOMPARE(rowsRemovedSpy.first().at(2), 1);
} }
void layoutChangePropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "color", { "red", "green" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
// register types to avoid warnings regarding signal params
qRegisterMetaType<QList<QPersistentModelIndex>>();
qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
QSignalSpy layoutAboutToBeChangedSpy(
&model, &LeftJoinModel::layoutAboutToBeChanged);
QSignalSpy layoutChangedSpy(&model, &LeftJoinModel::layoutChanged);
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
PersistentIndexesTester indexesTester(&model);
leftModel.invert();
QCOMPARE(layoutAboutToBeChangedSpy.count(), 1);
QCOMPARE(layoutChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.count(), 0);
QVERIFY(indexesTester.compare());
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 2"));
rightModel.invert();
QCOMPARE(layoutAboutToBeChangedSpy.count(), 1);
QCOMPARE(layoutChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.count(), 0);
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 2"));
}
void rightModelJoinRoleChangesPropagationTest() void rightModelJoinRoleChangesPropagationTest()
{ {
TestModel leftModel({ TestModel leftModel({