mirror of https://github.com/qt/qtbase.git
QSortFilterProxyModel: Keep invalid index updated on source model sort
If we have a filter applied that removes all entries, the source model is sorted, and then we remove the filter, QSortFilterProxyModel never emits rowsInserted. This is because it doesn't have the correct source mapping and doesn't update when the filter is removed. Change-Id: I447b2d150e509b128d27f4dabc4e081ca4ef037f Task-number: QTBUG-46282 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
862b1b3ceb
commit
db377a4202
|
@ -272,6 +272,7 @@ public:
|
|||
QModelIndexPairList store_persistent_indexes();
|
||||
void update_persistent_indexes(const QModelIndexPairList &source_indexes);
|
||||
|
||||
void filter_about_to_be_changed(const QModelIndex &source_parent = QModelIndex());
|
||||
void filter_changed(const QModelIndex &source_parent = QModelIndex());
|
||||
QSet<int> handle_filter_changed(
|
||||
QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
|
||||
|
@ -1045,6 +1046,19 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
|
|||
q->changePersistentIndexList(from, to);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Updates the source_index mapping in case it's invalid and we
|
||||
need it because we have a valid filter
|
||||
*/
|
||||
void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent)
|
||||
{
|
||||
if (!filter_regexp.pattern().isEmpty() &&
|
||||
source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd())
|
||||
create_mapping(source_parent);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
@ -2304,6 +2318,7 @@ QRegExp QSortFilterProxyModel::filterRegExp() const
|
|||
void QSortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp = regExp;
|
||||
d->filter_changed();
|
||||
}
|
||||
|
@ -2325,6 +2340,7 @@ int QSortFilterProxyModel::filterKeyColumn() const
|
|||
void QSortFilterProxyModel::setFilterKeyColumn(int column)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_column = column;
|
||||
d->filter_changed();
|
||||
}
|
||||
|
@ -2350,6 +2366,7 @@ void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
|
|||
Q_D(QSortFilterProxyModel);
|
||||
if (cs == d->filter_regexp.caseSensitivity())
|
||||
return;
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setCaseSensitivity(cs);
|
||||
d->filter_changed();
|
||||
}
|
||||
|
@ -2415,6 +2432,7 @@ void QSortFilterProxyModel::setSortLocaleAware(bool on)
|
|||
void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setPatternSyntax(QRegExp::RegExp);
|
||||
d->filter_regexp.setPattern(pattern);
|
||||
d->filter_changed();
|
||||
|
@ -2429,6 +2447,7 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
|
|||
void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setPatternSyntax(QRegExp::Wildcard);
|
||||
d->filter_regexp.setPattern(pattern);
|
||||
d->filter_changed();
|
||||
|
@ -2443,6 +2462,7 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
|
|||
void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
|
||||
{
|
||||
Q_D(QSortFilterProxyModel);
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_regexp.setPatternSyntax(QRegExp::FixedString);
|
||||
d->filter_regexp.setPattern(pattern);
|
||||
d->filter_changed();
|
||||
|
@ -2522,6 +2542,7 @@ void QSortFilterProxyModel::setFilterRole(int role)
|
|||
Q_D(QSortFilterProxyModel);
|
||||
if (d->filter_role == role)
|
||||
return;
|
||||
d->filter_about_to_be_changed();
|
||||
d->filter_role = role;
|
||||
d->filter_changed();
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ private slots:
|
|||
void filter_qtbug30662();
|
||||
|
||||
void changeSourceLayout();
|
||||
void changeSourceLayoutFilteredOut();
|
||||
void removeSourceRows_data();
|
||||
void removeSourceRows();
|
||||
void insertSourceRows_data();
|
||||
|
@ -1533,6 +1534,32 @@ void tst_QSortFilterProxyModel::changeSourceLayout()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
|
||||
{
|
||||
QStandardItemModel model(2, 1);
|
||||
model.setData(model.index(0, 0), QString("b"));
|
||||
model.setData(model.index(1, 0), QString("a"));
|
||||
QSortFilterProxyModel proxy;
|
||||
proxy.setSourceModel(&model);
|
||||
|
||||
int beforeSortFilter = proxy.rowCount();
|
||||
|
||||
QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
|
||||
// Filter everything out
|
||||
proxy.setFilterRegExp(QRegExp("c"));
|
||||
QCOMPARE(removeSpy.count(), 1);
|
||||
QCOMPARE(0, proxy.rowCount());
|
||||
|
||||
// change layout of source model
|
||||
model.sort(0, Qt::AscendingOrder);
|
||||
|
||||
QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
|
||||
// Remove filter; we expect an insert
|
||||
proxy.setFilterRegExp(QRegExp(""));
|
||||
QCOMPARE(insertSpy.count(), 1);
|
||||
QCOMPARE(beforeSortFilter, proxy.rowCount());
|
||||
}
|
||||
|
||||
void tst_QSortFilterProxyModel::removeSourceRows_data()
|
||||
{
|
||||
QTest::addColumn<QStringList>("sourceItems");
|
||||
|
|
Loading…
Reference in New Issue