diff --git a/python/core/auto_generated/qgsdbfilterproxymodel.sip.in b/python/core/auto_generated/qgsdbfilterproxymodel.sip.in index 702adc345936..a5bfe8185fb6 100644 --- a/python/core/auto_generated/qgsdbfilterproxymodel.sip.in +++ b/python/core/auto_generated/qgsdbfilterproxymodel.sip.in @@ -42,6 +42,7 @@ Calls QSortFilterProxyModel.setFilterRegExp and triggers update protected: virtual bool filterAcceptsRow( int row, const QModelIndex &source_parent ) const; + }; /************************************************************************ diff --git a/src/core/qgsdbfilterproxymodel.cpp b/src/core/qgsdbfilterproxymodel.cpp index 78f39d3dd5ca..d4970677b422 100644 --- a/src/core/qgsdbfilterproxymodel.cpp +++ b/src/core/qgsdbfilterproxymodel.cpp @@ -17,24 +17,68 @@ #include "qgsdbfilterproxymodel.h" +#include + QgsDatabaseFilterProxyModel::QgsDatabaseFilterProxyModel( QObject *parent ): QSortFilterProxyModel( parent ) { } -bool QgsDatabaseFilterProxyModel::filterAcceptsRow( int row, const QModelIndex &source_parent ) const +bool QgsDatabaseFilterProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const { - //if parent is valid, we have a toplevel item that should be always shown - if ( !source_parent.isValid() ) + if ( filterAcceptsRowItself( source_row, source_parent ) ) + return true; + +//accept if any of the parents is accepted on it's own merits + QModelIndex parent = source_parent; + while ( parent.isValid() ) + { + if ( filterAcceptsRowItself( parent.row(), parent.parent() ) ) + return true; + parent = parent.parent(); + } + + //accept if any of the children is accepted on it's own merits + if ( hasAcceptedChildren( source_row, source_parent ) ) { return true; } - //else we have a row that describes a table and that - //should be tested using the given wildcard/regexp - return QSortFilterProxyModel::filterAcceptsRow( row, source_parent ); + return false; +} + +bool QgsDatabaseFilterProxyModel::filterAcceptsRowItself( int source_row, const QModelIndex &source_parent ) const +{ + return QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent ); +} + +bool QgsDatabaseFilterProxyModel::hasAcceptedChildren( int source_row, const QModelIndex &source_parent ) const +{ + QModelIndex item = sourceModel()->index( source_row, 0, source_parent ); + if ( !item.isValid() ) + { + return false; + } + +//check if there are children + int childCount = item.model()->rowCount( item ); + if ( childCount == 0 ) + return false; + + for ( int i = 0; i < childCount; ++i ) + { + if ( filterAcceptsRowItself( i, item ) ) + return true; + if ( hasAcceptedChildren( i, item ) ) + return true; + } + + return false; } + + + void QgsDatabaseFilterProxyModel::_setFilterWildcard( const QString &pattern ) { QSortFilterProxyModel::setFilterWildcard( pattern ); diff --git a/src/core/qgsdbfilterproxymodel.h b/src/core/qgsdbfilterproxymodel.h index a403036a0c68..a9295b01cac6 100644 --- a/src/core/qgsdbfilterproxymodel.h +++ b/src/core/qgsdbfilterproxymodel.h @@ -49,6 +49,10 @@ class CORE_EXPORT QgsDatabaseFilterProxyModel: public QSortFilterProxyModel protected: bool filterAcceptsRow( int row, const QModelIndex &source_parent ) const override; + + private: + bool filterAcceptsRowItself( int source_row, const QModelIndex &source_parent ) const; + bool hasAcceptedChildren( int source_row, const QModelIndex &source_parent ) const; }; #endif