Skip to content

Commit

Permalink
Fixed bug when removing ancestors of root
Browse files Browse the repository at this point in the history
  • Loading branch information
VSRonin committed Mar 20, 2024
1 parent 3433630 commit d3ef3d9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/private/rootindexproxymodel_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class RootIndexProxyModelPrivate
QModelIndexList proxyIndexes;
bool isDescendant(QModelIndex childIdx, const QModelIndex &parentIdx) const;
bool ignoreMove(const QModelIndex &sourceParent, const QModelIndex &destParent) const;
bool isRootRemoved(const QModelIndex &parent, int first, int last, const QModelIndex &target, int (QModelIndex::*rowCol)() const) const;
void resetRootOnModelChange();
void checkRootRowRemoved(const QModelIndex &parent, int first, int last);
void checkRootColumnsRemoved(const QModelIndex &parent, int first, int last);
Expand Down
14 changes: 12 additions & 2 deletions src/rootindexproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ void RootIndexProxyModelPrivate::resetRootOnModelChange()
m_rootIndex = QModelIndex();
}

bool RootIndexProxyModelPrivate::isRootRemoved(const QModelIndex &parent, int first, int last, const QModelIndex &target,
int (QModelIndex::*rowCol)() const) const
{
if (!target.isValid())
return false;
if (target.parent() == parent)
return std::bind(rowCol, target)() >= first && std::bind(rowCol, target)() <= last;
return isRootRemoved(parent, first, last, target.parent(), rowCol);
}

void RootIndexProxyModelPrivate::checkRootRowRemoved(const QModelIndex &parent, int first, int last)
{
Q_Q(RootIndexProxyModel);
Expand All @@ -50,7 +60,7 @@ void RootIndexProxyModelPrivate::checkRootRowRemoved(const QModelIndex &parent,
return;
if (!isDescendant(m_rootIndex, parent))
return;
if (m_rootIndex.row() >= first && m_rootIndex.row() <= last) {
if (isRootRemoved(parent, first, last, m_rootIndex, &QModelIndex::row)) {
m_rootRowDeleted = true;
q->beginResetModel();
m_rootIndex = QModelIndex();
Expand All @@ -65,7 +75,7 @@ void RootIndexProxyModelPrivate::checkRootColumnsRemoved(const QModelIndex &pare
return;
if (!isDescendant(m_rootIndex, parent))
return;
if (m_rootIndex.column() >= first && m_rootIndex.column() <= last) {
if (isRootRemoved(parent, first, last, m_rootIndex, &QModelIndex::column)) {
m_rootColumnDeleted = true;
q->beginResetModel();
m_rootIndex = QModelIndex();
Expand Down
41 changes: 41 additions & 0 deletions tests/tst_RootIndexProxyModel/tst_rootindexproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,47 @@ void tst_RootIndexProxyModel::bug53MoveCols()
#endif
}

void tst_RootIndexProxyModel::resetOnAncestorRemoved()
{
#ifdef COMPLEX_MODEL_SUPPORT
QAbstractItemModel *baseModel = createTreeModel(this);
RootIndexProxyModel proxyModel1;
new ModelTest(&proxyModel1, baseModel);
proxyModel1.setSourceModel(baseModel);
proxyModel1.setRootIndex(baseModel->index(1, 0, baseModel->index(1, 0))); // Set Root to 1,1,0
QSignalSpy proxyRootChangeSpy(&proxyModel1, SIGNAL(rootIndexChanged()));
QVERIFY(proxyRootChangeSpy.isValid());
QSignalSpy proxyResetSpy(&proxyModel1, SIGNAL(modelReset()));
QVERIFY(proxyResetSpy.isValid());
QSignalSpy proxyAboutToBeResetSpy(&proxyModel1, SIGNAL(modelAboutToBeReset()));
QVERIFY(proxyAboutToBeResetSpy.isValid());

QVERIFY(baseModel->removeRow(2, baseModel->index(1, 0, baseModel->index(1, 0)))); // Remove row 2 of parent 1,1,0
QVERIFY(proxyRootChangeSpy.isEmpty());
QVERIFY(proxyAboutToBeResetSpy.isEmpty());
QVERIFY(proxyResetSpy.isEmpty());
proxyModel1.setRootIndex(baseModel->index(1, 0, baseModel->index(2, 0))); // Set Root to 2,1,0
QCOMPARE(proxyRootChangeSpy.count(), 1);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 1);
QVERIFY(baseModel->removeRow(2)); // Remove root row 2
QCOMPARE(proxyRootChangeSpy.count(), 2);
QCOMPARE(proxyAboutToBeResetSpy.count(), 2);
QCOMPARE(proxyResetSpy.count(), 2);
proxyModel1.setRootIndex(baseModel->index(1, 0, baseModel->index(1, 0))); // Set Root to 1,1,0
QCOMPARE(proxyRootChangeSpy.count(), 3);
QCOMPARE(proxyAboutToBeResetSpy.count(), 3);
QCOMPARE(proxyResetSpy.count(), 3);
QVERIFY(baseModel->removeRow(0)); // Remove root row 0
QCOMPARE(proxyRootChangeSpy.count(), 3);
QCOMPARE(proxyAboutToBeResetSpy.count(), 3);
QCOMPARE(proxyResetSpy.count(), 3);
baseModel->deleteLater();
#else
QSKIP("This test requires the Qt GUI or GenericModel modules");
#endif
}

void tst_RootIndexProxyModel::bug53MoveRows()
{
#ifdef QTMODELUTILITIES_GENERICMODEL
Expand Down
1 change: 1 addition & 0 deletions tests/tst_RootIndexProxyModel/tst_rootindexproxymodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private Q_SLOTS:
void bug53MoveRows();
void bug53Cols();
void bug53MoveCols();
void resetOnAncestorRemoved();
void bug60Row();
void bug60Col();

Expand Down

0 comments on commit d3ef3d9

Please sign in to comment.