diff --git a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp index 841b395bf98..d5e0376c48b 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp @@ -17,7 +17,7 @@ void MySortFilterProxyModel::setFilterMinimumDate(QDate date) { beginFilterChange(); minDate = date; - invalidateRowsFilter(); + endFilterChange(QSortFilterProxyModel::Direction::Rows); } //! [1] @@ -26,7 +26,7 @@ void MySortFilterProxyModel::setFilterMaximumDate(QDate date) { beginFilterChange(); maxDate = date; - invalidateRowsFilter(); + endFilterChange(QSortFilterProxyModel::Direction::Rows); } //! [2] diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 774dcfd9794..4bc09862e96 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -111,12 +111,6 @@ class QSortFilterProxyModelPrivate : public QAbstractProxyModelPrivate public: Q_DECLARE_PUBLIC(QSortFilterProxyModel) - enum class Direction { - Rows = 1, - Columns = 2, - All = Rows | Columns - }; - struct Mapping { QList source_rows; QList source_columns; @@ -327,6 +321,8 @@ public: void _q_clearMapping(); + using Direction = QSortFilterProxyModel::Direction; + using Directions = QSortFilterProxyModel::Directions; void sort(); bool update_source_sort_column(); int find_source_sort_column() const; @@ -334,29 +330,29 @@ public: const QModelIndex &source_parent) const; QList>> proxy_intervals_for_source_items_to_add( const QList &proxy_to_source, const QList &source_items, - const QModelIndex &source_parent, Qt::Orientation orient) const; + const QModelIndex &source_parent, Direction direction) const; QList> proxy_intervals_for_source_items( const QList &source_to_proxy, const QList &source_items) const; void insert_source_items( QList &source_to_proxy, QList &proxy_to_source, const QList &source_items, const QModelIndex &source_parent, - Qt::Orientation orient, bool emit_signal = true); + Direction direction, bool emit_signal = true); void remove_source_items( QList &source_to_proxy, QList &proxy_to_source, const QList &source_items, const QModelIndex &source_parent, - Qt::Orientation orient, bool emit_signal = true); + Direction direction, bool emit_signal = true); void remove_proxy_interval( QList &source_to_proxy, QList &proxy_to_source, int proxy_start, int proxy_end, const QModelIndex &proxy_parent, - Qt::Orientation orient, bool emit_signal = true); + Direction direction, bool emit_signal = true); static inline void build_source_to_proxy_mapping( const QList &proxy_to_source, QList &source_to_proxy, int start = 0); void source_items_inserted(const QModelIndex &source_parent, - int start, int end, Qt::Orientation orient); + int start, int end, Direction direction); void source_items_about_to_be_removed(const QModelIndex &source_parent, - int start, int end, Qt::Orientation orient); + int start, int end, Direction direction); void source_items_removed(const QModelIndex &source_parent, - int start, int end, Qt::Orientation orient); + int start, int end, Direction direction); void proxy_item_range( const QList &source_to_proxy, const QList &source_items, int &proxy_low, int &proxy_high) const; @@ -365,13 +361,13 @@ public: void update_persistent_indexes(const QModelIndexPairList &source_indexes); void filter_about_to_be_changed(const QModelIndex &source_parent = QModelIndex()); - void filter_changed(Direction dir, const QModelIndex &source_parent = QModelIndex()); + void filter_changed(Directions directions, const QModelIndex &source_parent = QModelIndex()); QSet handle_filter_changed( QList &source_to_proxy, QList &proxy_to_source, - const QModelIndex &source_parent, Qt::Orientation orient); + const QModelIndex &source_parent, Direction direction); void updateChildrenMapping(const QModelIndex &source_parent, Mapping *parent_mapping, - Qt::Orientation orient, int start, int end, int delta_item_count, bool remove); + Direction direction, int start, int end, int delta_item_count, bool remove); void _q_sourceModelDestroyed() override; @@ -384,11 +380,6 @@ public: typedef QHash IndexMap; -static bool operator&(QSortFilterProxyModelPrivate::Direction a, QSortFilterProxyModelPrivate::Direction b) -{ - return int(a) & int(b); -} - void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed() { QAbstractProxyModelPrivate::_q_sourceModelDestroyed(); @@ -745,7 +736,7 @@ QList> QSortFilterProxyModelPrivate::proxy_intervals_for_sou /*! \internal - Given source-to-proxy mapping \a src_to_proxy and proxy-to-source mapping + Given source-to-proxy mapping \a source_to_proxy and proxy-to-source mapping \a proxy_to_source, removes \a source_items from this proxy model. The corresponding proxy items are removed in intervals, so that the proper rows/columnsRemoved(start, end) signals will be generated. @@ -753,7 +744,7 @@ QList> QSortFilterProxyModelPrivate::proxy_intervals_for_sou void QSortFilterProxyModelPrivate::remove_source_items( QList &source_to_proxy, QList &proxy_to_source, const QList &source_items, const QModelIndex &source_parent, - Qt::Orientation orient, bool emit_signal) + Direction direction, bool emit_signal) { Q_Q(QSortFilterProxyModel); QModelIndex proxy_parent = q->mapFromSource(source_parent); @@ -771,7 +762,7 @@ void QSortFilterProxyModelPrivate::remove_source_items( const int proxy_start = interval.first; const int proxy_end = interval.second; remove_proxy_interval(source_to_proxy, proxy_to_source, proxy_start, proxy_end, - proxy_parent, orient, emit_signal); + proxy_parent, direction, emit_signal); } } @@ -784,11 +775,11 @@ void QSortFilterProxyModelPrivate::remove_source_items( */ void QSortFilterProxyModelPrivate::remove_proxy_interval( QList &source_to_proxy, QList &proxy_to_source, int proxy_start, int proxy_end, - const QModelIndex &proxy_parent, Qt::Orientation orient, bool emit_signal) + const QModelIndex &proxy_parent, Direction direction, bool emit_signal) { Q_Q(QSortFilterProxyModel); if (emit_signal) { - if (orient == Qt::Vertical) + if (direction == Direction::Rows) q->beginRemoveRows(proxy_parent, proxy_start, proxy_end); else q->beginRemoveColumns(proxy_parent, proxy_start, proxy_end); @@ -802,7 +793,7 @@ void QSortFilterProxyModelPrivate::remove_proxy_interval( build_source_to_proxy_mapping(proxy_to_source, source_to_proxy, proxy_start); if (emit_signal) { - if (orient == Qt::Vertical) + if (direction == Direction::Rows) q->endRemoveRows(); else q->endRemoveColumns(); @@ -823,7 +814,7 @@ void QSortFilterProxyModelPrivate::remove_proxy_interval( */ QList>> QSortFilterProxyModelPrivate::proxy_intervals_for_source_items_to_add( const QList &proxy_to_source, const QList &source_items, - const QModelIndex &source_parent, Qt::Orientation orient) const + const QModelIndex &source_parent, Direction direction) const { Q_Q(const QSortFilterProxyModel); QList>> proxy_intervals; @@ -833,7 +824,7 @@ QList>> QSortFilterProxyModelPrivate::proxy_intervals_ int proxy_low = 0; int proxy_item = 0; int source_items_index = 0; - bool compare = (orient == Qt::Vertical && source_sort_column >= 0 && dynamic_sortfilter); + bool compare = (direction == Direction::Rows && source_sort_column >= 0 && dynamic_sortfilter); while (source_items_index < source_items.size()) { QList source_items_in_interval; int first_new_source_item = source_items.at(source_items_index); @@ -897,7 +888,7 @@ QList>> QSortFilterProxyModelPrivate::proxy_intervals_ void QSortFilterProxyModelPrivate::insert_source_items( QList &source_to_proxy, QList &proxy_to_source, const QList &source_items, const QModelIndex &source_parent, - Qt::Orientation orient, bool emit_signal) + Direction direction, bool emit_signal) { Q_Q(QSortFilterProxyModel); QModelIndex proxy_parent = q->mapFromSource(source_parent); @@ -905,7 +896,7 @@ void QSortFilterProxyModelPrivate::insert_source_items( return; // nothing to do (source_parent is not mapped) const auto proxy_intervals = proxy_intervals_for_source_items_to_add( - proxy_to_source, source_items, source_parent, orient); + proxy_to_source, source_items, source_parent, direction); const auto end = proxy_intervals.rend(); for (auto it = proxy_intervals.rbegin(); it != end; ++it) { @@ -915,7 +906,7 @@ void QSortFilterProxyModelPrivate::insert_source_items( const int proxy_end = proxy_start + source_items.size() - 1; if (emit_signal) { - if (orient == Qt::Vertical) + if (direction == Direction::Rows) q->beginInsertRows(proxy_parent, proxy_start, proxy_end); else q->beginInsertColumns(proxy_parent, proxy_start, proxy_end); @@ -928,7 +919,7 @@ void QSortFilterProxyModelPrivate::insert_source_items( build_source_to_proxy_mapping(proxy_to_source, source_to_proxy, proxy_start); if (emit_signal) { - if (orient == Qt::Vertical) + if (direction == Direction::Rows) q->endInsertRows(); else q->endInsertColumns(); @@ -949,7 +940,7 @@ void QSortFilterProxyModelPrivate::insert_source_items( signals will be generated. */ void QSortFilterProxyModelPrivate::source_items_inserted( - const QModelIndex &source_parent, int start, int end, Qt::Orientation orient) + const QModelIndex &source_parent, int start, int end, Direction direction) { Q_Q(QSortFilterProxyModel); if ((start < 0) || (end < 0)) @@ -973,13 +964,13 @@ void QSortFilterProxyModelPrivate::source_items_inserted( } Mapping *m = it.value(); - QList &source_to_proxy = (orient == Qt::Vertical) ? m->proxy_rows : m->proxy_columns; - QList &proxy_to_source = (orient == Qt::Vertical) ? m->source_rows : m->source_columns; + QList &source_to_proxy = (direction == Direction::Rows) ? m->proxy_rows : m->proxy_columns; + QList &proxy_to_source = (direction == Direction::Rows) ? m->source_rows : m->source_columns; int delta_item_count = end - start + 1; int old_item_count = source_to_proxy.size(); - updateChildrenMapping(source_parent, m, orient, start, end, delta_item_count, false); + updateChildrenMapping(source_parent, m, direction, start, end, delta_item_count, false); // Expand source-to-proxy mapping to account for new items if (start < 0 || start > source_to_proxy.size()) { @@ -1003,7 +994,7 @@ void QSortFilterProxyModelPrivate::source_items_inserted( // Figure out which items to add to mapping based on filter QList source_items; for (int i = start; i <= end; ++i) { - if ((orient == Qt::Vertical) + if ((direction == Direction::Rows) ? filterAcceptsRowInternal(i, source_parent) : q->filterAcceptsColumn(i, source_parent)) { source_items.append(i); @@ -1015,21 +1006,21 @@ void QSortFilterProxyModelPrivate::source_items_inserted( // If it was new rows make sure to create mappings for columns so that a // valid mapping can be retrieved later and vice-versa. - QList &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns; - QList &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns; + QList &orthogonal_proxy_to_source = (direction == Direction::Columns) ? m->source_rows : m->source_columns; + QList &orthogonal_source_to_proxy = (direction == Direction::Columns) ? m->proxy_rows : m->proxy_columns; if (orthogonal_source_to_proxy.isEmpty()) { - const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent); + const int ortho_end = (direction == Direction::Columns) ? model->rowCount(source_parent) : model->columnCount(source_parent); orthogonal_source_to_proxy.resize(ortho_end); for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) { - if ((orient == Qt::Horizontal) ? filterAcceptsRowInternal(ortho_item, source_parent) + if ((direction == Direction::Columns) ? filterAcceptsRowInternal(ortho_item, source_parent) : q->filterAcceptsColumn(ortho_item, source_parent)) { orthogonal_proxy_to_source.append(ortho_item); } } - if (orient == Qt::Horizontal) { + if (direction == Direction::Columns) { // We're reacting to columnsInserted, but we've just inserted new rows. Sort them. sort_source_rows(orthogonal_proxy_to_source, source_parent); } @@ -1038,9 +1029,9 @@ void QSortFilterProxyModelPrivate::source_items_inserted( } // Sort and insert the items - if (orient == Qt::Vertical) // Only sort rows + if (direction == Direction::Rows) // Only sort rows sort_source_rows(source_items, source_parent); - insert_source_items(source_to_proxy, proxy_to_source, source_items, source_parent, orient); + insert_source_items(source_to_proxy, proxy_to_source, source_items, source_parent, direction); } /*! @@ -1050,7 +1041,7 @@ void QSortFilterProxyModelPrivate::source_items_inserted( (columnsAboutToBeRemoved(), rowsAboutToBeRemoved()). */ void QSortFilterProxyModelPrivate::source_items_about_to_be_removed( - const QModelIndex &source_parent, int start, int end, Qt::Orientation orient) + const QModelIndex &source_parent, int start, int end, Direction direction) { if ((start < 0) || (end < 0)) return; @@ -1061,8 +1052,8 @@ void QSortFilterProxyModelPrivate::source_items_about_to_be_removed( } Mapping *m = it.value(); - QList &source_to_proxy = (orient == Qt::Vertical) ? m->proxy_rows : m->proxy_columns; - QList &proxy_to_source = (orient == Qt::Vertical) ? m->source_rows : m->source_columns; + QList &source_to_proxy = (direction == Direction::Rows) ? m->proxy_rows : m->proxy_columns; + QList &proxy_to_source = (direction == Direction::Rows) ? m->source_rows : m->source_columns; // figure out which items to remove QList source_items_to_remove; @@ -1074,7 +1065,7 @@ void QSortFilterProxyModelPrivate::source_items_about_to_be_removed( } remove_source_items(source_to_proxy, proxy_to_source, source_items_to_remove, - source_parent, orient); + source_parent, direction); } /*! @@ -1083,7 +1074,7 @@ void QSortFilterProxyModelPrivate::source_items_about_to_be_removed( Handles source model items removal (columnsRemoved(), rowsRemoved()). */ void QSortFilterProxyModelPrivate::source_items_removed( - const QModelIndex &source_parent, int start, int end, Qt::Orientation orient) + const QModelIndex &source_parent, int start, int end, Direction direction) { if ((start < 0) || (end < 0)) return; @@ -1094,8 +1085,8 @@ void QSortFilterProxyModelPrivate::source_items_removed( } Mapping *m = it.value(); - QList &source_to_proxy = (orient == Qt::Vertical) ? m->proxy_rows : m->proxy_columns; - QList &proxy_to_source = (orient == Qt::Vertical) ? m->source_rows : m->source_columns; + QList &source_to_proxy = (direction == Direction::Rows) ? m->proxy_rows : m->proxy_columns; + QList &proxy_to_source = (direction == Direction::Rows) ? m->source_rows : m->source_columns; if (end >= source_to_proxy.size()) end = source_to_proxy.size() - 1; @@ -1125,7 +1116,7 @@ void QSortFilterProxyModelPrivate::source_items_removed( } build_source_to_proxy_mapping(proxy_to_source, source_to_proxy); - updateChildrenMapping(source_parent, m, orient, start, end, delta_item_count, true); + updateChildrenMapping(source_parent, m, direction, start, end, delta_item_count, true); } @@ -1135,14 +1126,14 @@ void QSortFilterProxyModelPrivate::source_items_removed( updates the mapping of the children when inserting or removing items */ void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &source_parent, Mapping *parent_mapping, - Qt::Orientation orient, int start, int end, int delta_item_count, bool remove) + Direction direction, int start, int end, int delta_item_count, bool remove) { // see if any mapped children should be (re)moved QList> moved_source_index_mappings; auto it2 = parent_mapping->mapped_children.begin(); for ( ; it2 != parent_mapping->mapped_children.end();) { const QModelIndex source_child_index = *it2; - const int pos = (orient == Qt::Vertical) + const int pos = (direction == Direction::Rows) ? source_child_index.row() : source_child_index.column(); if (pos < start) { @@ -1156,7 +1147,7 @@ void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &sour // below the removed items -- recompute the index QModelIndex new_index; const int newpos = remove ? pos - delta_item_count : pos + delta_item_count; - if (orient == Qt::Vertical) { + if (direction == Direction::Rows) { new_index = model->index(newpos, source_child_index.column(), source_parent); @@ -1280,14 +1271,21 @@ void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex Updates the proxy model (adds/removes rows) based on the new filter. */ -void QSortFilterProxyModelPrivate::filter_changed(Direction dir, const QModelIndex &source_parent) +void QSortFilterProxyModelPrivate::filter_changed(Directions directions, + const QModelIndex &source_parent) { IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); if (it == source_index_mapping.constEnd()) return; Mapping *m = it.value(); - const QSet rows_removed = (dir & Direction::Rows) ? handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical) : QSet(); - const QSet columns_removed = (dir & Direction::Columns) ? handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal) : QSet(); + const QSet rows_removed = (directions & Direction::Rows) + ? handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, + Direction::Rows) + : QSet(); + const QSet columns_removed = (directions & Direction::Columns) + ? handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, + Direction::Columns) + : QSet(); // We need to iterate over a copy of m->mapped_children because otherwise it may be changed by other code, invalidating // the iterator it2. @@ -1301,7 +1299,7 @@ void QSortFilterProxyModelPrivate::filter_changed(Direction dir, const QModelInd indexesToRemove.push_back(i); remove_from_mapping(source_child_index); } else { - filter_changed(dir, source_child_index); + filter_changed(directions, source_child_index); } } QList::const_iterator removeIt = indexesToRemove.constEnd(); @@ -1324,14 +1322,14 @@ void QSortFilterProxyModelPrivate::filter_changed(Direction dir, const QModelInd */ QSet QSortFilterProxyModelPrivate::handle_filter_changed( QList &source_to_proxy, QList &proxy_to_source, - const QModelIndex &source_parent, Qt::Orientation orient) + const QModelIndex &source_parent, Direction direction) { Q_Q(QSortFilterProxyModel); // Figure out which mapped items to remove QList source_items_remove; for (int i = 0; i < proxy_to_source.size(); ++i) { const int source_item = proxy_to_source.at(i); - if ((orient == Qt::Vertical) + if ((direction == Direction::Rows) ? !filterAcceptsRowInternal(source_item, source_parent) : !q->filterAcceptsColumn(source_item, source_parent)) { // This source item does not satisfy the filter, so it must be removed @@ -1343,7 +1341,7 @@ QSet QSortFilterProxyModelPrivate::handle_filter_changed( int source_count = source_to_proxy.size(); for (int source_item = 0; source_item < source_count; ++source_item) { if (source_to_proxy.at(source_item) == -1) { - if ((orient == Qt::Vertical) + if ((direction == Direction::Rows) ? filterAcceptsRowInternal(source_item, source_parent) : q->filterAcceptsColumn(source_item, source_parent)) { // This source item satisfies the filter, so it must be added @@ -1354,11 +1352,11 @@ QSet QSortFilterProxyModelPrivate::handle_filter_changed( if (!source_items_remove.isEmpty() || !source_items_insert.isEmpty()) { // Do item removal and insertion remove_source_items(source_to_proxy, proxy_to_source, - source_items_remove, source_parent, orient); - if (orient == Qt::Vertical) + source_items_remove, source_parent, direction); + if (direction == Direction::Rows) sort_source_rows(source_items_insert, source_parent); insert_source_items(source_to_proxy, proxy_to_source, - source_items_insert, source_parent, orient); + source_items_insert, source_parent, direction); } return qListToSet(source_items_remove); } @@ -1465,7 +1463,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc if (!source_rows_remove.isEmpty()) { remove_source_items(m->proxy_rows, m->source_rows, - source_rows_remove, source_parent, Qt::Vertical); + source_rows_remove, source_parent, Direction::Rows); QSet source_rows_remove_set = qListToSet(source_rows_remove); QList::iterator childIt = m->mapped_children.end(); while (childIt != m->mapped_children.begin()) { @@ -1486,10 +1484,10 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc emit q->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint); QModelIndexPairList source_indexes = store_persistent_indexes(); remove_source_items(m->proxy_rows, m->source_rows, source_rows_resort, - source_parent, Qt::Vertical, false); + source_parent, Direction::Rows, false); sort_source_rows(source_rows_resort, source_parent); insert_source_items(m->proxy_rows, m->source_rows, source_rows_resort, - source_parent, Qt::Vertical, false); + source_parent, Direction::Rows, false); update_persistent_indexes(source_indexes); emit q->layoutChanged(parents, QAbstractItemModel::VerticalSortHint); } @@ -1529,7 +1527,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc if (!source_rows_insert.isEmpty()) { sort_source_rows(source_rows_insert, source_parent); insert_source_items(m->proxy_rows, m->source_rows, - source_rows_insert, source_parent, Qt::Vertical); + source_rows_insert, source_parent, Direction::Rows); } } } @@ -1682,7 +1680,7 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsInserted( if (!filter_recursive || complete_insert) { if (filter_recursive) complete_insert = false; - source_items_inserted(source_parent, start, end, Qt::Vertical); + source_items_inserted(source_parent, start, end, Direction::Rows); if (update_source_sort_column() && dynamic_sortfilter) //previous call to update_source_sort_column may fail if the model has no column. sort(); // now it should succeed so we need to make sure to sort again return; @@ -1711,14 +1709,14 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeRemoved( { itemsBeingRemoved = QRowsRemoval(source_parent, start, end); source_items_about_to_be_removed(source_parent, start, end, - Qt::Vertical); + Direction::Rows); } void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved( const QModelIndex &source_parent, int start, int end) { itemsBeingRemoved = QRowsRemoval(); - source_items_removed(source_parent, start, end, Qt::Vertical); + source_items_removed(source_parent, start, end, Direction::Rows); if (filter_recursive) { // Find out if removing this visible row means that some ascendant @@ -1783,7 +1781,7 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsInserted( const QModelIndex &source_parent, int start, int end) { Q_Q(const QSortFilterProxyModel); - source_items_inserted(source_parent, start, end, Qt::Horizontal); + source_items_inserted(source_parent, start, end, Direction::Columns); if (source_parent.isValid()) return; //we sort according to the root column only @@ -1803,14 +1801,14 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved( const QModelIndex &source_parent, int start, int end) { source_items_about_to_be_removed(source_parent, start, end, - Qt::Horizontal); + Direction::Columns); } void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( const QModelIndex &source_parent, int start, int end) { Q_Q(const QSortFilterProxyModel); - source_items_removed(source_parent, start, end, Qt::Horizontal); + source_items_removed(source_parent, start, end, Direction::Columns); if (source_parent.isValid()) return; //we sort according to the root column only @@ -1981,11 +1979,11 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved( example.) If you are working with large amounts of filtering and have to invoke - invalidateFilter() repeatedly, using beginResetModel() / endResetModel() may - be more efficient, depending on the implementation of your model. However, - beginResetModel() / endResetModel() returns the - proxy model to its original state, losing selection information, and will - cause the proxy model to be repopulated. + beginFilterChange() / endFilterChange() repeatedly, using beginResetModel() + / endResetModel() may be more efficient, depending on the implementation of + your model. However, beginResetModel() / endResetModel() returns the proxy + model to its original state, losing selection information, and will cause + the proxy model to be repopulated. \section1 Subclassing @@ -2593,7 +2591,7 @@ void QSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression d->filter_regularexpression.setValueBypassingBindings(regularExpression); if (cs != updatedCs) d->filter_casesensitive.setValueBypassingBindings(updatedCs); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); // Do not change the evaluation logic, but notify only if the regular // expression has actually changed. if (regExpChanged) @@ -2628,7 +2626,7 @@ void QSortFilterProxyModel::setFilterKeyColumn(int column) d->filter_about_to_be_changed(); const auto oldColumn = d->filter_column.valueBypassingBindings(); d->filter_column.setValueBypassingBindings(column); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); if (oldColumn != column) d->filter_column.notify(); } @@ -2685,7 +2683,7 @@ void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs) QRegularExpression re = d->filter_regularexpression; re.setPatternOptions(options); d->filter_regularexpression.setValueBypassingBindings(re); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); d->filter_regularexpression.notify(); d->filter_casesensitive.notify(); } @@ -2800,7 +2798,7 @@ void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern) d->filter_regularexpression.removeBindingUnlessInWrapper(); d->filter_about_to_be_changed(); d->set_filter_pattern(pattern); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); d->filter_regularexpression.notify(); } @@ -2824,7 +2822,7 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern) d->filter_about_to_be_changed(); d->set_filter_pattern(QRegularExpression::wildcardToRegularExpression( pattern, QRegularExpression::UnanchoredWildcardConversion)); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); d->filter_regularexpression.notify(); } @@ -2847,7 +2845,7 @@ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern) 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_changed(Direction::Rows); d->filter_regularexpression.notify(); } @@ -2967,7 +2965,7 @@ void QSortFilterProxyModel::setFilterRole(int role) return; d->filter_about_to_be_changed(); d->filter_role.setValueBypassingBindings(role); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); d->filter_role.notify(); // also emits a signal } @@ -3009,7 +3007,7 @@ void QSortFilterProxyModel::setRecursiveFilteringEnabled(bool recursive) return; d->filter_about_to_be_changed(); d->filter_recursive.setValueBypassingBindings(recursive); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); d->filter_recursive.notify(); // also emits a signal } @@ -3054,7 +3052,7 @@ void QSortFilterProxyModel::setAutoAcceptChildRows(bool accept) d->filter_about_to_be_changed(); d->accept_children.setValueBypassingBindings(accept); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); d->accept_children.notify(); // also emits a signal } @@ -3069,7 +3067,7 @@ QBindable QSortFilterProxyModel::bindableAutoAcceptChildRows() Invalidates the current sorting and filtering. - \sa invalidateFilter() + \sa beginFilterChange(), endFilterChange() */ void QSortFilterProxyModel::invalidate() { @@ -3089,7 +3087,11 @@ void QSortFilterProxyModel::invalidate() \snippet ../widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 2 - \sa invalidateFilter(), invalidateColumnsFilter(), invalidateRowsFilter() + Once the filter has been changed, call endFilterChange() with Direction::Rows + for row-filters, Direction::Columns for column-filters, or Direction::Columns|Direction::Rows + if both rows and columns are filtered. + + \sa endFilterChange() */ void QSortFilterProxyModel::beginFilterChange() @@ -3098,8 +3100,10 @@ void QSortFilterProxyModel::beginFilterChange() d->create_mapping({}); } +#if QT_DEPRECATED_SINCE(6, 13) /*! \since 4.3 + \deprecated [6.13] use beginFilterChange() and endFilterChange() instead. Invalidates the current filtering. @@ -3116,11 +3120,12 @@ void QSortFilterProxyModel::beginFilterChange() void QSortFilterProxyModel::invalidateFilter() { Q_D(QSortFilterProxyModel); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::All); + d->filter_changed(Direction::Columns|Direction::Rows); } /*! \since 6.0 + \deprecated [6.13] use beginFilterChange() and endFilterChange(Direction::Rows) instead. Invalidates the current filtering for the columns. @@ -3138,11 +3143,12 @@ void QSortFilterProxyModel::invalidateFilter() void QSortFilterProxyModel::invalidateColumnsFilter() { Q_D(QSortFilterProxyModel); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Columns); + d->filter_changed(Direction::Columns); } /*! \since 6.0 + \deprecated [6.13] use beginFilterChange() and endFilterChange(Direction::Columns) instead. Invalidates the current filtering for the rows. @@ -3160,7 +3166,44 @@ void QSortFilterProxyModel::invalidateColumnsFilter() void QSortFilterProxyModel::invalidateRowsFilter() { Q_D(QSortFilterProxyModel); - d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + d->filter_changed(Direction::Rows); +} +#endif // QT_DEPRECATED_SINCE(6, 10) + +/*! + \enum QSortFilterProxyModel::Direction + \since 6.10 + + This enum is used to specify the direction to which a custom filter applies + when the filter parameters are changed. + + \value Rows The filter applies to \l{filterAcceptsRow()}{rows} + \value Columns The filter applies to \l{filterAcceptsColumn()}{columns} + \value Both The filter applies to both rows and columns + + \sa beginFilterChange(), endFilterChange() +*/ + +/*! + \since 6.10 + + Invalidates the current filtering after the filter parameter has changed. + + This function should be called if you implement custom filtering (e.g. + filterAcceptsRow()), and your filter parameters have changed. The \a directions + parameter specifies whether the custom filter impacts rows, columns, or both. + + Call beginFilterChange() when the filter parameter is about to change, and + follow with a call to this function once the filter parameters have been + changed. Call with \a directions set to Direction::Rows for row-filters + (i.e. filterAcceptsRow() is implemented), Direction::Columns for + column-filters (i.e. filterAcceptsColumn() is implemented), + or \c{Direction::Both} if both filter functions are implemented. +*/ +void QSortFilterProxyModel::endFilterChange(QSortFilterProxyModel::Directions directions) +{ + Q_D(QSortFilterProxyModel); + d->filter_changed(directions); } /*! diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index b2d5a320fc4..e4a2d31636d 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -101,6 +101,13 @@ public: void setAutoAcceptChildRows(bool accept); QBindable bindableAutoAcceptChildRows(); + enum class Direction { + Rows = 0x01, + Columns = 0x02, + Both = Rows | Columns, + }; + Q_DECLARE_FLAGS(Directions, Direction) + public Q_SLOTS: void setFilterRegularExpression(const QString &pattern); void setFilterRegularExpression(const QRegularExpression ®ularExpression); @@ -114,9 +121,15 @@ protected: virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; void beginFilterChange(); + void endFilterChange(Directions directions = Direction::Both); +#if QT_DEPRECATED_SINCE(6, 13) + QT_DEPRECATED_VERSION_X_6_13("Use begin/endFilterChange() instead") void invalidateFilter(); + QT_DEPRECATED_VERSION_X_6_13("Use begin/endFilterChange(QSortFilterProxyModel::Direction::Rows) instead") void invalidateRowsFilter(); + QT_DEPRECATED_VERSION_X_6_13("Use begin/endFilterChange(QSortFilterProxyModel::Direction::Columns) instead") void invalidateColumnsFilter(); +#endif public: using QObject::parent; @@ -175,6 +188,8 @@ private: Q_DISABLE_COPY(QSortFilterProxyModel) }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QSortFilterProxyModel::Directions) + QT_END_NAMESPACE #endif // QSORTFILTERPROXYMODEL_H diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 4d21fcbb593..ece1bfd912c 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -3635,7 +3635,7 @@ void tst_QSortFilterProxyModel::resetInvalidate() endResetModel(); break; case 2: invalidate(); break; - case 3: invalidateFilter(); break; + case 3: endFilterChange(); break; } } }; @@ -4090,7 +4090,7 @@ public slots: void setMode(bool on) { mode = on; - invalidateFilter(); + endFilterChange(); } protected: @@ -4148,7 +4148,7 @@ public slots: void setMode(bool on) { mode = on; - invalidateFilter(); + endFilterChange(); } protected: @@ -5163,7 +5163,8 @@ class SortFilterProxyModel final : public QSortFilterProxyModel Q_OBJECT public: using QSortFilterProxyModel::QSortFilterProxyModel; - using QSortFilterProxyModel::invalidateFilter; + using QSortFilterProxyModel::beginFilterChange; + using QSortFilterProxyModel::endFilterChange; void setSourceModel(QAbstractItemModel *m) override { @@ -5209,15 +5210,17 @@ void tst_QSortFilterProxyModel::checkFilteredIndexes() s.setSourceModel(&m); s.sort(0); - s.invalidateFilter(); + s.endFilterChange(); checkIndexes(s); + s.beginFilterChange(); s.m_filteredRows = 5; // every 5th row is filtered - s.invalidateFilter(); + s.endFilterChange(); checkIndexes(s); + s.beginFilterChange(); s.m_filteredRows = 3; // every 3rd row is filtered - s.invalidateFilter(); + s.endFilterChange(); checkIndexes(s); } @@ -5252,6 +5255,8 @@ void tst_QSortFilterProxyModel::invalidateColumnsOrRowsFilter() using QSortFilterProxyModel::invalidateFilter; using QSortFilterProxyModel::invalidateRowsFilter; using QSortFilterProxyModel::invalidateColumnsFilter; + using QSortFilterProxyModel::beginFilterChange; + using QSortFilterProxyModel::endFilterChange; }; QStandardItemModel model(10, 4); for (int i = 0; i < model.rowCount(); ++i) { @@ -5271,19 +5276,19 @@ void tst_QSortFilterProxyModel::invalidateColumnsOrRowsFilter() QCOMPARE(proxy.columnFiltered, 44); // 4 parents + 4 * 10 children proxy.rowFiltered = proxy.columnFiltered = 0; - proxy.invalidateFilter(); + proxy.endFilterChange(); QCOMPARE(proxy.rowFiltered, 20); QCOMPARE(proxy.columnFiltered, 44); proxy.rowFiltered = proxy.columnFiltered = 0; - proxy.invalidateRowsFilter(); + proxy.endFilterChange(QSortFilterProxyModel::Direction::Rows); QCOMPARE(proxy.rowFiltered, 20); QCOMPARE(proxy.columnFiltered, 0); proxy.rowFiltered = proxy.columnFiltered = 0; - proxy.invalidateColumnsFilter(); + proxy.endFilterChange(QSortFilterProxyModel::Direction::Columns); QCOMPARE(proxy.rowFiltered, 0); QCOMPARE(proxy.columnFiltered, 44); @@ -5291,12 +5296,12 @@ void tst_QSortFilterProxyModel::invalidateColumnsOrRowsFilter() QCOMPARE(proxy.rowCount(), 10); proxy.rejectA1 = true; proxy.rowFiltered = proxy.columnFiltered = 0; - proxy.invalidateRowsFilter(); + proxy.endFilterChange(QSortFilterProxyModel::Direction::Rows); QCOMPARE(proxy.rowCount(), 9); QCOMPARE(proxy.rowFiltered, 19); // it will not check the child row of A1 proxy.rowFiltered = proxy.columnFiltered = 0; - proxy.setRecursiveFilteringEnabled(true); // this triggers invalidateRowsFilter() + proxy.setRecursiveFilteringEnabled(true); // this triggers endFilterChange(QSortFilterProxyModel::Direction::Rows) QCOMPARE(proxy.rowCount(), 10); QCOMPARE(proxy.rowFiltered, 20); } @@ -5512,7 +5517,7 @@ void tst_QSortFilterProxyModel::filterChangeEmitsModelChangedSignals() beginFilterChange(); m_matchString = s; - invalidateFilter(); + endFilterChange(); } bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override