Skip to content

Commit

Permalink
Fixed order of emission of model reset signals when root is deleted
Browse files Browse the repository at this point in the history
Fixes #60
  • Loading branch information
VSRonin committed Mar 15, 2024
1 parent 868123e commit b6c5e93
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/rootindexproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ void RootIndexProxyModelPrivate::checkRootRowRemoved(const QModelIndex &parent,
return;
if (m_rootIndex.row() >= first && m_rootIndex.row() <= last) {
m_rootRowDeleted = true;
q->setRootIndex(QModelIndex());
q->beginResetModel();
m_rootIndex=QModelIndex();
}
}

Expand All @@ -66,7 +67,8 @@ void RootIndexProxyModelPrivate::checkRootColumnsRemoved(const QModelIndex &pare
return;
if (m_rootIndex.column() >= first && m_rootIndex.column() <= last) {
m_rootColumnDeleted = true;
q->setRootIndex(QModelIndex());
q->beginResetModel();
m_rootIndex=QModelIndex();
}
}

Expand Down Expand Up @@ -123,10 +125,14 @@ void RootIndexProxyModelPrivate::onRowsRemoved(const QModelIndex &parent, int fi
if (parent != m_rootIndex && !isDescendant(parent, m_rootIndex))
return;
}
if (m_rootRowDeleted)
if (m_rootRowDeleted){
q->endResetModel();
Q_EMIT q->rootIndexChanged();
m_rootRowDeleted = false;
else
}
else{
q->endRemoveRows();
}
}

bool RootIndexProxyModelPrivate::ignoreMove(const QModelIndex &sourceParent, const QModelIndex &destParent) const
Expand Down Expand Up @@ -285,10 +291,14 @@ void RootIndexProxyModelPrivate::onColumnsRemoved(const QModelIndex &parent, int
if (parent != m_rootIndex && !isDescendant(parent, m_rootIndex))
return;
}
if (m_rootColumnDeleted)
if (m_rootColumnDeleted){
q->endResetModel();
Q_EMIT q->rootIndexChanged();
m_rootColumnDeleted = false;
else
}
else{
q->endRemoveColumns();
}
}

void RootIndexProxyModelPrivate::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
Expand Down Expand Up @@ -414,7 +424,7 @@ void RootIndexProxyModel::setRootIndex(const QModelIndex &root)
beginResetModel();
d->m_rootIndex = root;
endResetModel();
rootIndexChanged();
Q_EMIT rootIndexChanged();
}

/*!
Expand Down
115 changes: 115 additions & 0 deletions tests/tst_RootIndexProxyModel/tst_rootindexproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,119 @@ void tst_RootIndexProxyModel::removeColumn()
#endif
}

void tst_RootIndexProxyModel::bug60Row()
{
#ifdef COMPLEX_MODEL_SUPPORT
QAbstractItemModel *baseModel = createTreeModel(this);
RootIndexProxyModel proxyModel;
new ModelTest(&proxyModel, baseModel);
QSignalSpy baseRowsAboutToBeRemovedSpy(baseModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)));
QVERIFY(baseRowsAboutToBeRemovedSpy.isValid());
QSignalSpy baseRowsRemovedSpy(baseModel, SIGNAL(rowsRemoved(QModelIndex, int, int)));
QVERIFY(baseRowsRemovedSpy.isValid());
QSignalSpy proxyResetSpy(&proxyModel, SIGNAL(modelReset()));
QVERIFY(proxyResetSpy.isValid());
QSignalSpy proxyAboutToBeResetSpy(&proxyModel, SIGNAL(modelAboutToBeReset()));
QVERIFY(proxyAboutToBeResetSpy.isValid());
QSignalSpy proxyRootChangedSpy(&proxyModel, SIGNAL(rootIndexChanged()));
QVERIFY(proxyRootChangedSpy.isValid());
connect(baseModel,&QAbstractItemModel::rowsAboutToBeRemoved,[&](){
QCOMPARE(baseRowsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseRowsRemovedSpy.count(), 0);
QCOMPARE(proxyResetSpy.count(), 0);
QCOMPARE(proxyAboutToBeResetSpy.count(), 0);
});
connect(&proxyModel,&QAbstractItemModel::modelAboutToBeReset,[&](){
QCOMPARE(baseRowsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseRowsRemovedSpy.count(), 0);
QCOMPARE(proxyResetSpy.count(), 0);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
});
connect(baseModel,&QAbstractItemModel::rowsRemoved,[&](){
QCOMPARE(baseRowsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseRowsRemovedSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 0);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
});
connect(&proxyModel,&QAbstractItemModel::modelReset,[&](){
QCOMPARE(baseRowsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseRowsRemovedSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 1);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
});
proxyModel.blockSignals(true);
proxyModel.setSourceModel(baseModel);
proxyModel.setRootIndex(baseModel->index(0,0));
proxyModel.blockSignals(false);
QVERIFY(baseModel->removeRow(0));
QCOMPARE(proxyModel.rootIndex(), QModelIndex());
QCOMPARE(baseRowsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseRowsRemovedSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 1);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
QCOMPARE(proxyRootChangedSpy.count(), 1);
baseModel->deleteLater();
#else
QSKIP("This test requires the Qt GUI or GenericModel modules");
#endif
}
void tst_RootIndexProxyModel::bug60Col()
{
#ifdef COMPLEX_MODEL_SUPPORT
QAbstractItemModel *baseModel = createTreeModel(this);
RootIndexProxyModel proxyModel;
new ModelTest(&proxyModel, baseModel);
QSignalSpy baseColsAboutToBeRemovedSpy(baseModel, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)));
QVERIFY(baseColsAboutToBeRemovedSpy.isValid());
QSignalSpy baseColsRemovedSpy(baseModel, SIGNAL(columnsRemoved(QModelIndex, int, int)));
QVERIFY(baseColsRemovedSpy.isValid());
QSignalSpy proxyResetSpy(&proxyModel, SIGNAL(modelReset()));
QVERIFY(proxyResetSpy.isValid());
QSignalSpy proxyAboutToBeResetSpy(&proxyModel, SIGNAL(modelAboutToBeReset()));
QVERIFY(proxyAboutToBeResetSpy.isValid());
QSignalSpy proxyRootChangedSpy(&proxyModel, SIGNAL(rootIndexChanged()));
QVERIFY(proxyRootChangedSpy.isValid());
connect(baseModel,&QAbstractItemModel::rowsAboutToBeRemoved,[&](){
QCOMPARE(baseColsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseColsRemovedSpy.count(), 0);
QCOMPARE(proxyResetSpy.count(), 0);
QCOMPARE(proxyAboutToBeResetSpy.count(), 0);
});
connect(&proxyModel,&QAbstractItemModel::modelAboutToBeReset,[&](){
QCOMPARE(baseColsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseColsRemovedSpy.count(), 0);
QCOMPARE(proxyResetSpy.count(), 0);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
});
connect(baseModel,&QAbstractItemModel::rowsRemoved,[&](){
QCOMPARE(baseColsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseColsRemovedSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 0);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
});
connect(&proxyModel,&QAbstractItemModel::modelReset,[&](){
QCOMPARE(baseColsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseColsRemovedSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 1);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
});
proxyModel.blockSignals(true);
proxyModel.setSourceModel(baseModel);
proxyModel.setRootIndex(baseModel->index(0,0));
proxyModel.blockSignals(false);
QVERIFY(baseModel->removeColumn(0));
QCOMPARE(proxyModel.rootIndex(), QModelIndex());
QCOMPARE(baseColsAboutToBeRemovedSpy.count(), 1);
QCOMPARE(baseColsRemovedSpy.count(), 1);
QCOMPARE(proxyResetSpy.count(), 1);
QCOMPARE(proxyAboutToBeResetSpy.count(), 1);
QCOMPARE(proxyRootChangedSpy.count(), 1);
baseModel->deleteLater();
#else
QSKIP("This test requires the Qt GUI or GenericModel modules");
#endif
}

void tst_RootIndexProxyModel::bug53Rows()
{
#ifdef COMPLEX_MODEL_SUPPORT
Expand Down Expand Up @@ -634,6 +747,8 @@ void tst_RootIndexProxyModel::bug53MoveCols()
QSKIP("This test requires the GenericModel module");
#endif
}


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

protected:
void compareModels(const QAbstractItemModel *source, const QAbstractItemModel *proxy, const QModelIndex &sourcePar, const QModelIndex &proxyPar);
Expand Down

0 comments on commit b6c5e93

Please sign in to comment.