diff options
Diffstat (limited to 'src/corelib/itemmodels/qsortfilterproxymodel.cpp')
-rw-r--r-- | src/corelib/itemmodels/qsortfilterproxymodel.cpp | 127 |
1 files changed, 108 insertions, 19 deletions
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 9ef75f6073..1b5dc0dec2 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -202,6 +202,20 @@ public: void setDynamicSortFilterForwarder(bool enable) { q_func()->setDynamicSortFilter(enable); } + void setFilterCaseSensitivityForwarder(Qt::CaseSensitivity cs) + { + q_func()->setFilterCaseSensitivity(cs); + } + void filterCaseSensitivityChangedForwarder(Qt::CaseSensitivity cs) + { + emit q_func()->filterCaseSensitivityChanged(cs); + } + + void setFilterRegularExpressionForwarder(const QRegularExpression &re) + { + q_func()->setFilterRegularExpression(re); + } + int source_sort_column = -1; int proxy_sort_column = -1; Qt::SortOrder sort_order = Qt::AscendingOrder; @@ -245,7 +259,15 @@ public: &QSortFilterProxyModelPrivate::setDynamicSortFilterForwarder, true) - QRegularExpression filter_regularexpression; + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS( + QSortFilterProxyModelPrivate, Qt::CaseSensitivity, filter_casesensitive, + &QSortFilterProxyModelPrivate::setFilterCaseSensitivityForwarder, + &QSortFilterProxyModelPrivate::filterCaseSensitivityChangedForwarder, Qt::CaseSensitive) + + Q_OBJECT_COMPAT_PROPERTY(QSortFilterProxyModelPrivate, QRegularExpression, + filter_regularexpression, + &QSortFilterProxyModelPrivate::setFilterRegularExpressionForwarder) + QModelIndex last_top_source; QRowsRemoval itemsBeingRemoved; @@ -266,9 +288,14 @@ public: */ void set_filter_pattern(const QString &pattern) { - filter_regularexpression.setPattern(pattern); - filter_regularexpression.setPatternOptions(filter_regularexpression.patternOptions() - & QRegularExpression::CaseInsensitiveOption); + QRegularExpression re = filter_regularexpression.value(); + const auto cs = re.patternOptions() & QRegularExpression::CaseInsensitiveOption; + re.setPattern(pattern); + re.setPatternOptions(cs); + // This is a helper function, which is supposed to be called from a + // more complicated context. Because of that, the caller is responsible + // for calling notify() and removeBindingUnlessInWrapper(), if needed. + filter_regularexpression.setValueBypassingBindings(re); } inline QHash<QModelIndex, Mapping *>::const_iterator index_to_iterator( @@ -1247,7 +1274,7 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes( */ void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent) { - if (!filter_regularexpression.pattern().isEmpty() + if (!filter_regularexpression.value().pattern().isEmpty() && source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd()) { create_mapping(source_parent); } @@ -2567,6 +2594,12 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const If no QRegularExpression or an empty string is set, everything in the source model will be accepted. + \note Setting this property propagates the case sensitivity of the new + regular expression to the \l filterCaseSensitivity property, and so breaks + its binding. Likewise explicitly setting \l filterCaseSensitivity changes + the case sensitivity of the current regular expression, thereby breaking + its binding. + \sa filterCaseSensitivity, setFilterWildcard(), setFilterFixedString() */ QRegularExpression QSortFilterProxyModel::filterRegularExpression() const @@ -2575,16 +2608,35 @@ QRegularExpression QSortFilterProxyModel::filterRegularExpression() const return d->filter_regularexpression; } +QBindable<QRegularExpression> QSortFilterProxyModel::bindableFilterRegularExpression() +{ + Q_D(QSortFilterProxyModel); + return QBindable<QRegularExpression>(&d->filter_regularexpression); +} + void QSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression ®ularExpression) { Q_D(QSortFilterProxyModel); + Qt::beginPropertyUpdateGroup(); + const bool regExpChanged = regularExpression != d->filter_regularexpression.value(); + d->filter_regularexpression.removeBindingUnlessInWrapper(); + d->filter_casesensitive.removeBindingUnlessInWrapper(); const Qt::CaseSensitivity cs = filterCaseSensitivity(); d->filter_about_to_be_changed(); - d->filter_regularexpression = regularExpression; + const Qt::CaseSensitivity updatedCs = + regularExpression.patternOptions() & QRegularExpression::CaseInsensitiveOption + ? Qt::CaseInsensitive : Qt::CaseSensitive; + d->filter_regularexpression.setValueBypassingBindings(regularExpression); + if (cs != updatedCs) + d->filter_casesensitive.setValueBypassingBindings(updatedCs); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); - const Qt::CaseSensitivity updatedCs = filterCaseSensitivity(); + // Do not change the evaluation logic, but notify only if the regular + // expression has actually changed. + if (regExpChanged) + d->filter_regularexpression.notify(); if (cs != updatedCs) - emit filterCaseSensitivityChanged(updatedCs); + d->filter_casesensitive.notify(); + Qt::endPropertyUpdateGroup(); } /*! @@ -2632,6 +2684,11 @@ QBindable<int> QSortFilterProxyModel::bindableFilterKeyColumn() By default, the filter is case sensitive. + \note Setting this property propagates the new case sensitivity to the + \l filterRegularExpression property, and so breaks its binding. Likewise + explicitly setting \l filterRegularExpression changes the current case + sensitivity, thereby breaking its binding. + \sa filterRegularExpression, sortCaseSensitivity */ @@ -2644,23 +2701,37 @@ QBindable<int> QSortFilterProxyModel::bindableFilterKeyColumn() Qt::CaseSensitivity QSortFilterProxyModel::filterCaseSensitivity() const { Q_D(const QSortFilterProxyModel); - return d->filter_regularexpression.patternOptions() & QRegularExpression::CaseInsensitiveOption - ? Qt::CaseInsensitive - : Qt::CaseSensitive; + return d->filter_casesensitive; } void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs) { Q_D(QSortFilterProxyModel); - QRegularExpression::PatternOptions options = d->filter_regularexpression.patternOptions(); - options.setFlag(QRegularExpression::CaseInsensitiveOption, cs == Qt::CaseInsensitive); - if (d->filter_regularexpression.patternOptions() == options) + d->filter_casesensitive.removeBindingUnlessInWrapper(); + d->filter_regularexpression.removeBindingUnlessInWrapper(); + if (cs == d->filter_casesensitive) return; + Qt::beginPropertyUpdateGroup(); + QRegularExpression::PatternOptions options = + d->filter_regularexpression.value().patternOptions(); + options.setFlag(QRegularExpression::CaseInsensitiveOption, cs == Qt::CaseInsensitive); + d->filter_casesensitive.setValueBypassingBindings(cs); + d->filter_about_to_be_changed(); - d->filter_regularexpression.setPatternOptions(options); + QRegularExpression re = d->filter_regularexpression; + re.setPatternOptions(options); + d->filter_regularexpression.setValueBypassingBindings(re); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); - emit filterCaseSensitivityChanged(cs); + d->filter_regularexpression.notify(); + d->filter_casesensitive.notify(); + Qt::endPropertyUpdateGroup(); +} + +QBindable<Qt::CaseSensitivity> QSortFilterProxyModel::bindableFilterCaseSensitivity() +{ + Q_D(QSortFilterProxyModel); + return QBindable<Qt::CaseSensitivity>(&d->filter_casesensitive); } /*! @@ -2755,14 +2826,20 @@ QBindable<bool> QSortFilterProxyModel::bindableIsSortLocaleAware() This method will reset the regular expression options but respect case sensitivity. + \note Calling this method updates the regular expression, thereby breaking + the binding for \l filterRegularExpression. However it has no effect on the + \l filterCaseSensitivity bindings. + \sa setFilterCaseSensitivity(), setFilterWildcard(), setFilterFixedString(), filterRegularExpression() */ void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern) { Q_D(QSortFilterProxyModel); + d->filter_regularexpression.removeBindingUnlessInWrapper(); d->filter_about_to_be_changed(); d->set_filter_pattern(pattern); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_regularexpression.notify(); } /*! @@ -2772,15 +2849,21 @@ void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern) This method will reset the regular expression options but respect case sensitivity. + \note Calling this method updates the regular expression, thereby breaking + the binding for \l filterRegularExpression. However it has no effect on the + \l filterCaseSensitivity bindings. + \sa setFilterCaseSensitivity(), setFilterRegularExpression(), setFilterFixedString(), filterRegularExpression() */ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) { Q_D(QSortFilterProxyModel); + d->filter_regularexpression.removeBindingUnlessInWrapper(); d->filter_about_to_be_changed(); d->set_filter_pattern(QRegularExpression::wildcardToRegularExpression( pattern, QRegularExpression::UnanchoredWildcardConversion)); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_regularexpression.notify(); } /*! @@ -2790,14 +2873,20 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) This method will reset the regular expression options but respect case sensitivity. + \note Calling this method updates the regular expression, thereby breaking + the binding for \l filterRegularExpression. However it has no effect on the + \l filterCaseSensitivity bindings. + \sa setFilterCaseSensitivity(), setFilterRegularExpression(), setFilterWildcard(), filterRegularExpression() */ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern) { Q_D(QSortFilterProxyModel); + d->filter_regularexpression.removeBindingUnlessInWrapper(); d->filter_about_to_be_changed(); d->set_filter_pattern(QRegularExpression::escape(pattern)); d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_regularexpression.notify(); } /*! @@ -3151,7 +3240,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & { Q_D(const QSortFilterProxyModel); - if (d->filter_regularexpression.pattern().isEmpty()) + if (d->filter_regularexpression.value().pattern().isEmpty()) return true; int column_count = d->model->columnCount(source_parent); @@ -3159,7 +3248,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 (key.contains(d->filter_regularexpression)) + if (key.contains(d->filter_regularexpression.value())) return true; } return false; @@ -3169,7 +3258,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 key.contains(d->filter_regularexpression); + return key.contains(d->filter_regularexpression.value()); } /*! |