diff options
-rw-r--r-- | src/corelib/itemmodels/qsortfilterproxymodel.cpp | 68 | ||||
-rw-r--r-- | tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp | 66 |
2 files changed, 110 insertions, 24 deletions
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 11992f7e2e..2d52fa9734 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -173,7 +173,7 @@ public: int filter_column; int filter_role; - QRegularExpression filter_data; + QRegularExpression filter_regularexpression; QModelIndex last_top_source; bool filter_recursive; @@ -193,6 +193,17 @@ public: void remove_from_mapping(const QModelIndex &source_parent); + /*! + * Legacy: changing the pattern through a string does not change the + * case sensitivity. + */ + void set_filter_pattern(const QString &pattern) + { + filter_regularexpression.setPattern(pattern); + filter_regularexpression.setPatternOptions(filter_regularexpression.patternOptions() + & QRegularExpression::CaseInsensitiveOption); + } + inline QHash<QModelIndex, Mapping *>::const_iterator index_to_iterator( const QModelIndex &proxy_index) const { @@ -1171,9 +1182,10 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes( */ void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent) { - if (!filter_data.pattern().isEmpty() && - source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd()) - create_mapping(source_parent); + if (!filter_regularexpression.pattern().isEmpty() + && source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd()) { + create_mapping(source_parent); + } } @@ -2492,8 +2504,8 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const \property QSortFilterProxyModel::filterRegularExpression \brief the QRegularExpression used to filter the contents of the source model - Setting this property overwrites the current - \l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}. + Setting this property through the QRegularExpression overload overwrites the + current \l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}. By default, the QRegularExpression is an empty string matching all contents. If no QRegularExpression or an empty string is set, everything in the source @@ -2504,14 +2516,14 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const QRegularExpression QSortFilterProxyModel::filterRegularExpression() const { Q_D(const QSortFilterProxyModel); - return d->filter_data; + return d->filter_regularexpression; } void QSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression ®ularExpression) { Q_D(QSortFilterProxyModel); d->filter_about_to_be_changed(); - d->filter_data = regularExpression; + d->filter_regularexpression = regularExpression; d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); } #endif @@ -2558,20 +2570,21 @@ void QSortFilterProxyModel::setFilterKeyColumn(int column) Qt::CaseSensitivity QSortFilterProxyModel::filterCaseSensitivity() const { Q_D(const QSortFilterProxyModel); - return d->filter_data.patternOptions() & QRegularExpression::CaseInsensitiveOption ? - Qt::CaseInsensitive : Qt::CaseSensitive; + return d->filter_regularexpression.patternOptions() & QRegularExpression::CaseInsensitiveOption + ? Qt::CaseInsensitive + : Qt::CaseSensitive; } void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs) { Q_D(QSortFilterProxyModel); - QRegularExpression::PatternOptions o = QRegularExpression::NoPatternOption; - if (cs == Qt::CaseInsensitive) - o = QRegularExpression::CaseInsensitiveOption; - if (o == d->filter_data.patternOptions()) + QRegularExpression::PatternOptions options = d->filter_regularexpression.patternOptions(); + options.setFlag(QRegularExpression::CaseInsensitiveOption, cs == Qt::CaseInsensitive); + if (d->filter_regularexpression.patternOptions() == options) return; + d->filter_about_to_be_changed(); - d->filter_data.setPatternOptions(o); + d->filter_regularexpression.setPatternOptions(options); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); emit filterCaseSensitivityChanged(cs); } @@ -2652,15 +2665,16 @@ void QSortFilterProxyModel::setSortLocaleAware(bool on) This method should be preferred for new code as it will use QRegularExpression internally. + This method will reset the regular expression options + but respect case sensitivity. + \sa setFilterCaseSensitivity(), setFilterWildcard(), setFilterFixedString(), filterRegularExpression() */ void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern) { Q_D(QSortFilterProxyModel); d->filter_about_to_be_changed(); - QRegularExpression rx(pattern, - d->filter_data.patternOptions() & QRegularExpression::CaseInsensitiveOption); - d->filter_data.setPattern(pattern); + d->set_filter_pattern(pattern); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); } #endif @@ -2669,14 +2683,17 @@ void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern) Sets the wildcard expression used to filter the contents of the source model to the given \a pattern. + This method will reset the regular expression options + but respect case sensitivity. + \sa setFilterCaseSensitivity(), setFilterRegularExpression(), setFilterFixedString(), filterRegularExpression() */ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) { Q_D(QSortFilterProxyModel); d->filter_about_to_be_changed(); - QString p = QRegularExpression::wildcardToRegularExpression(pattern, QRegularExpression::UnanchoredWildcardConversion); - d->filter_data.setPattern(p); + d->set_filter_pattern(QRegularExpression::wildcardToRegularExpression( + pattern, QRegularExpression::UnanchoredWildcardConversion)); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); } @@ -2684,13 +2701,16 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) Sets the fixed string used to filter the contents of the source model to the given \a pattern. + This method will reset the regular expression options + but respect case sensitivity. + \sa setFilterCaseSensitivity(), setFilterRegularExpression(), setFilterWildcard(), filterRegularExpression() */ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern) { Q_D(QSortFilterProxyModel); d->filter_about_to_be_changed(); - d->filter_data.setPattern(QRegularExpression::escape(pattern)); + d->set_filter_pattern(QRegularExpression::escape(pattern)); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); } @@ -3002,7 +3022,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & { Q_D(const QSortFilterProxyModel); - if (d->filter_data.pattern().isEmpty()) + if (d->filter_regularexpression.pattern().isEmpty()) return true; int column_count = d->model->columnCount(source_parent); @@ -3010,7 +3030,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & for (int column = 0; column < column_count; ++column) { QModelIndex source_index = d->model->index(source_row, column, source_parent); QString key = d->model->data(source_index, d->filter_role).toString(); - if (d->filter_data.match(key).hasMatch()) + if (key.contains(d->filter_regularexpression)) return true; } return false; @@ -3020,7 +3040,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & return true; QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent); QString key = d->model->data(source_index, d->filter_role).toString(); - return d->filter_data.match(key).hasMatch(); + return key.contains(d->filter_regularexpression); } /*! diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp index 7f2a4b64ae..aead57d9fc 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp @@ -38,6 +38,8 @@ public: private slots: void tst_invalid(); void tst_caseSensitivity(); + void tst_keepCaseSensitivity_QTBUG_92260(); + void tst_keepPatternOptions_QTBUG_92260(); }; tst_QSortFilterProxyModelRegularExpression::tst_QSortFilterProxyModelRegularExpression() : @@ -73,5 +75,69 @@ void tst_QSortFilterProxyModelRegularExpression::tst_caseSensitivity() QCOMPARE(proxyModel.rowCount(), 2); } +/*! + This test ensures that when a string pattern is passed to setRegularEpxression, + the options are properly reseted but that the case sensitivity is kept as is. + + */ +void tst_QSortFilterProxyModelRegularExpression::tst_keepCaseSensitivity_QTBUG_92260() +{ + const QLatin1String pattern("test"); + QStringListModel model({ "test", "TesT" }); + QSortFilterProxyModel proxyModel; + proxyModel.setSourceModel(&model); + + QRegularExpression patternWithOptions("Dummy", + QRegularExpression::MultilineOption + | QRegularExpression::CaseInsensitiveOption); + + proxyModel.setFilterRegularExpression(patternWithOptions); + QCOMPARE(proxyModel.filterRegularExpression(), patternWithOptions); + QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive); + + proxyModel.setFilterRegularExpression(pattern); + QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive); + QCOMPARE(proxyModel.filterRegularExpression().patternOptions(), + QRegularExpression::CaseInsensitiveOption); + + patternWithOptions.setPatternOptions(QRegularExpression::MultilineOption); + proxyModel.setFilterRegularExpression(patternWithOptions); + QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive); + QCOMPARE(proxyModel.filterRegularExpression(), patternWithOptions); + + proxyModel.setFilterRegularExpression(pattern); + QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive); + QCOMPARE(proxyModel.filterRegularExpression().patternOptions(), + QRegularExpression::NoPatternOption); +} + +/*! + This test ensures that when the case sensitivity is changed, it does not nuke + the pattern options that were set before. + */ +void tst_QSortFilterProxyModelRegularExpression::tst_keepPatternOptions_QTBUG_92260() +{ + QStringListModel model({ "test", "TesT" }); + QSortFilterProxyModel proxyModel; + proxyModel.setSourceModel(&model); + + QRegularExpression patternWithOptions("Dummy", + QRegularExpression::MultilineOption + | QRegularExpression::CaseInsensitiveOption); + + proxyModel.setFilterRegularExpression(patternWithOptions); + QCOMPARE(proxyModel.filterRegularExpression(), patternWithOptions); + + proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); + QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive); + QCOMPARE(proxyModel.filterRegularExpression().patternOptions(), + patternWithOptions.patternOptions()); + + proxyModel.setFilterCaseSensitivity(Qt::CaseSensitive); + QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive); + QCOMPARE(proxyModel.filterRegularExpression().patternOptions(), + QRegularExpression::MultilineOption); +} + QTEST_MAIN(tst_QSortFilterProxyModelRegularExpression) #include "tst_qsortfilterproxymodel_regularexpression.moc" |