From 7db527dbdd911c79f31425d099d1fc9c63e42453 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Tue, 19 May 2020 15:02:22 +0200 Subject: Add a property to QSFPM to show children of accepted items [ChangeLog][QtCore][QSortFilterProxyModel] Add a 'autoAcceptChildRows' property to always show children rows of accepted rows. Change-Id: I2402469ece438179d0f19888b9775cc27cf5c749 Reviewed-by: David Faure --- src/corelib/itemmodels/qsortfilterproxymodel.cpp | 83 +++++++++++++++++++++--- src/corelib/itemmodels/qsortfilterproxymodel.h | 5 ++ 2 files changed, 80 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 79a9875073..2c494aeec8 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -177,6 +177,7 @@ public: QModelIndex last_top_source; bool filter_recursive; + bool accept_children; bool complete_insert; bool dynamic_sortfilter; QRowsRemoval itemsBeingRemoved; @@ -305,7 +306,8 @@ public: bool needsReorder(const QVector &source_rows, const QModelIndex &source_parent) const; bool filterAcceptsRowInternal(int source_row, const QModelIndex &source_parent) const; - bool filterRecursiveAcceptsRow(int source_row, const QModelIndex &source_parent) const; + bool recursiveChildAcceptsRow(int source_row, const QModelIndex &source_parent) const; + bool recursiveParentAcceptsRow(const QModelIndex &source_parent) const; }; typedef QHash IndexMap; @@ -325,23 +327,49 @@ void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed() bool QSortFilterProxyModelPrivate::filterAcceptsRowInternal(int source_row, const QModelIndex &source_parent) const { Q_Q(const QSortFilterProxyModel); - return filter_recursive - ? filterRecursiveAcceptsRow(source_row, source_parent) - : q->filterAcceptsRow(source_row, source_parent); + + if (q->filterAcceptsRow(source_row, source_parent)) + return true; + + // Go up the tree and accept this row if a parent is accepted + if (accept_children && recursiveParentAcceptsRow(source_parent)) + return true; + + // Go down the tree and accept this row if a child is accepted + if (filter_recursive && recursiveChildAcceptsRow(source_row, source_parent)) + return true; + + return false; } -bool QSortFilterProxyModelPrivate::filterRecursiveAcceptsRow(int source_row, const QModelIndex &source_parent) const +bool QSortFilterProxyModelPrivate::recursiveParentAcceptsRow(const QModelIndex &source_parent) const { Q_Q(const QSortFilterProxyModel); - if (q->filterAcceptsRow(source_row, source_parent)) - return true; + if (source_parent.isValid()) { + const QModelIndex index = source_parent.parent(); + + if (q->filterAcceptsRow(source_parent.row(), index)) + return true; + + return recursiveParentAcceptsRow(index); + } + + return false; +} + +bool QSortFilterProxyModelPrivate::recursiveChildAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + Q_Q(const QSortFilterProxyModel); const QModelIndex index = model->index(source_row, 0, source_parent); const int count = model->rowCount(index); for (int i = 0; i < count; ++i) { - if (filterRecursiveAcceptsRow(i, index)) + if (q->filterAcceptsRow(i, index)) + return true; + + if (recursiveChildAcceptsRow(i, index)) return true; } @@ -1878,6 +1906,7 @@ QSortFilterProxyModel::QSortFilterProxyModel(QObject *parent) d->filter_column = 0; d->filter_role = Qt::DisplayRole; d->filter_recursive = false; + d->accept_children = false; d->dynamic_sortfilter = true; d->complete_insert = false; connect(this, SIGNAL(modelReset()), this, SLOT(_q_clearMapping())); @@ -2763,6 +2792,7 @@ void QSortFilterProxyModel::setFilterRole(int role) The default value is false. + \sa autoAcceptChildRows \sa filterAcceptsRow() */ @@ -2789,6 +2819,43 @@ void QSortFilterProxyModel::setRecursiveFilteringEnabled(bool recursive) emit recursiveFilteringEnabledChanged(recursive); } +/*! + \since 6.0 + \property QSortFilterProxyModel::autoAcceptChildRows + \brief if true the proxy model will not filter out children of accepted + rows, even if they themselves would be filtered out otherwise. + + The default value is false. + + \sa recursiveFilteringEnabled + \sa filterAcceptsRow() +*/ + +/*! + \since 6.0 + \fn void QSortFilterProxyModel::showMatchesChildrenChanged(bool autoAcceptChildRows) + \brief This signals is emitted when the value of the \a autoAcceptChildRows property is changed. + + \sa autoAcceptChildRows +*/ +bool QSortFilterProxyModel::autoAcceptChildRows() const +{ + Q_D(const QSortFilterProxyModel); + return d->accept_children; +} + +void QSortFilterProxyModel::setAutoAcceptChildRows(bool accept) +{ + Q_D(QSortFilterProxyModel); + if (d->accept_children == accept) + return; + + d->filter_about_to_be_changed(); + d->accept_children = accept; + d->filter_changed(QSortFilterProxyModelPrivate::Direction::Rows); + emit autoAcceptChildRowsChanged(accept); +} + #if QT_DEPRECATED_SINCE(5, 11) /*! \obsolete diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index b7d4e69cb9..647b1616ce 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -72,6 +72,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole NOTIFY sortRoleChanged) Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole NOTIFY filterRoleChanged) Q_PROPERTY(bool recursiveFilteringEnabled READ isRecursiveFilteringEnabled WRITE setRecursiveFilteringEnabled NOTIFY recursiveFilteringEnabledChanged) + Q_PROPERTY(bool autoAcceptChildRows READ autoAcceptChildRows WRITE setAutoAcceptChildRows NOTIFY autoAcceptChildRowsChanged) public: explicit QSortFilterProxyModel(QObject *parent = nullptr); @@ -116,6 +117,9 @@ public: bool isRecursiveFilteringEnabled() const; void setRecursiveFilteringEnabled(bool recursive); + bool autoAcceptChildRows() const; + void setAutoAcceptChildRows(bool accept); + public Q_SLOTS: #if QT_CONFIG(regularexpression) void setFilterRegularExpression(const QString &pattern); @@ -190,6 +194,7 @@ Q_SIGNALS: void sortRoleChanged(int sortRole); void filterRoleChanged(int filterRole); void recursiveFilteringEnabledChanged(bool recursiveFilteringEnabled); + void autoAcceptChildRowsChanged(bool autoAcceptChildRows); private: Q_DECLARE_PRIVATE(QSortFilterProxyModel) -- cgit v1.2.3