Fix QSFPM not emitting dataChanged when source model is set

QSortFilterProxyModel did not emit dataChanged when calling
setSourceModel() after modifying the source model.
QSortFilterProxyModel::setSourceModel and
QSortFilterProxyModelPrivate::_q_sourceReset(), _q_clearMapping
is called to delete the source_index_mapping. They also need to
call create_mapping function to re-create it.

Fixes: QTBUG-87781
Pick-to: 5.15
Change-Id: Idbe34696c9d3a2fbf354b653c870bac61378811d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Wang ChunLin 2020-10-23 11:02:30 +08:00 committed by Volker Hilsheimer
parent 8a6f52bf83
commit 8455bfee76
3 changed files with 32 additions and 0 deletions

View File

@ -1479,6 +1479,7 @@ void QSortFilterProxyModelPrivate::_q_sourceReset()
_q_clearMapping(); _q_clearMapping();
// All internal structures are deleted in clear() // All internal structures are deleted in clear()
q->endResetModel(); q->endResetModel();
create_mapping(QModelIndex());
update_source_sort_column(); update_source_sort_column();
if (dynamic_sortfilter && update_source_sort_column()) if (dynamic_sortfilter && update_source_sort_column())
sort(); sort();
@ -2042,6 +2043,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
endResetModel(); endResetModel();
d->create_mapping(QModelIndex());
if (d->update_source_sort_column() && d->dynamic_sortfilter) if (d->update_source_sort_column() && d->dynamic_sortfilter)
d->sort(); d->sort();
} }

View File

@ -2163,6 +2163,35 @@ void tst_QSortFilterProxyModel::changeSourceDataForwardsRoles_qtbug35440()
QCOMPARE(spy.at(1).at(2).value<QList<int> >(), expectedChangedRoles); QCOMPARE(spy.at(1).at(2).value<QList<int> >(), expectedChangedRoles);
} }
void tst_QSortFilterProxyModel::changeSourceDataProxySendDataChanged_qtbug87781()
{
QStandardItemModel baseModel;
QSortFilterProxyModel proxyModelBefore;
QSortFilterProxyModel proxyModelAfter;
QSignalSpy baseDataChangedSpy(&baseModel, &QStandardItemModel::dataChanged);
QSignalSpy beforeDataChangedSpy(&proxyModelBefore, &QSortFilterProxyModel::dataChanged);
QSignalSpy afterDataChangedSpy(&proxyModelAfter, &QSortFilterProxyModel::dataChanged);
QVERIFY(baseDataChangedSpy.isValid());
QVERIFY(beforeDataChangedSpy.isValid());
QVERIFY(afterDataChangedSpy.isValid());
proxyModelBefore.setSourceModel(&baseModel);
baseModel.insertRows(0, 1);
baseModel.insertColumns(0, 1);
proxyModelAfter.setSourceModel(&baseModel);
QCOMPARE(baseDataChangedSpy.size(), 0);
QCOMPARE(beforeDataChangedSpy.size(), 0);
QCOMPARE(afterDataChangedSpy.size(), 0);
baseModel.setData(baseModel.index(0, 0), QStringLiteral("new data"), Qt::DisplayRole);
QCOMPARE(baseDataChangedSpy.size(), 1);
QCOMPARE(beforeDataChangedSpy.size(), 1);
QCOMPARE(afterDataChangedSpy.size(), 1);
}
void tst_QSortFilterProxyModel::sortFilterRole() void tst_QSortFilterProxyModel::sortFilterRole()
{ {
QStandardItemModel model; QStandardItemModel model;

View File

@ -90,6 +90,7 @@ private slots:
void changeSourceData(); void changeSourceData();
void changeSourceDataKeepsStableSorting_qtbug1548(); void changeSourceDataKeepsStableSorting_qtbug1548();
void changeSourceDataForwardsRoles_qtbug35440(); void changeSourceDataForwardsRoles_qtbug35440();
void changeSourceDataProxySendDataChanged_qtbug87781();
void resortingDoesNotBreakTreeModels(); void resortingDoesNotBreakTreeModels();
void dynamicFilterWithoutSort(); void dynamicFilterWithoutSort();
void sortFilterRole(); void sortFilterRole();