Skip to content
Permalink
Browse files
Fix searching in expression builder function list, make filtering
more robust

Fixes #44711
  • Loading branch information
nyalldawson committed Aug 17, 2021
1 parent a346ec1 commit 2f7efed0b1a78d076ef9b2a88e6a9257606c4bb2
Showing with 37 additions and 29 deletions.
  1. +26 −29 src/gui/qgsexpressiontreeview.cpp
  2. +11 −0 src/gui/qgsexpressiontreeview.h
@@ -195,12 +195,7 @@ void QgsExpressionTreeView::setProject( QgsProject *project )

void QgsExpressionTreeView::setSearchText( const QString &text )
{
const QRegularExpression regularExpression( QRegularExpression::wildcardToRegularExpression( text ) );
if ( regularExpression.isValid() )
{
mProxyModel->setFilterRegularExpression( regularExpression );
mProxyModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
}
mProxyModel->setFilterString( text );
if ( text.isEmpty() )
{
collapseAll();
@@ -816,40 +811,42 @@ QgsExpressionItemSearchProxy::QgsExpressionItemSearchProxy()
bool QgsExpressionItemSearchProxy::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
{
QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
QgsExpressionItem::ItemType itemType = QgsExpressionItem::ItemType( sourceModel()->data( index, QgsExpressionItem::ITEM_TYPE_ROLE ).toInt() );
const QgsExpressionItem::ItemType itemType = QgsExpressionItem::ItemType( sourceModel()->data( index, QgsExpressionItem::ITEM_TYPE_ROLE ).toInt() );

int count = sourceModel()->rowCount( index );
bool matchchild = false;
for ( int i = 0; i < count; ++i )
if ( itemType == QgsExpressionItem::Header )
{
if ( filterAcceptsRow( i, index ) )
// show header if any child item matches
int count = sourceModel()->rowCount( index );
bool matchchild = false;
for ( int i = 0; i < count; ++i )
{
matchchild = true;
break;
if ( filterAcceptsRow( i, index ) )
{
matchchild = true;
break;
}
}
return matchchild;
}

if ( itemType == QgsExpressionItem::Header && matchchild )
return true;

if ( itemType == QgsExpressionItem::Header )
return false;

// check match of item label or tags
if ( QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent ) )
const QString name = sourceModel()->data( index, Qt::DisplayRole ).toString();
if ( name.contains( mFilterString, Qt::CaseInsensitive ) )
{
return true;
}
else

const QStringList tags = sourceModel()->data( index, QgsExpressionItem::SEARCH_TAGS_ROLE ).toStringList();
return std::any_of( tags.begin(), tags.end(), [this]( const QString & tag )
{
const QStringList tags = sourceModel()->data( index, QgsExpressionItem::SEARCH_TAGS_ROLE ).toStringList();
for ( const QString &tag : tags )
{
if ( tag.contains( filterRegularExpression() ) )
return true;
}
}
return false;
return tag.contains( mFilterString, Qt::CaseInsensitive );
} );
}

void QgsExpressionItemSearchProxy::setFilterString( const QString &string )
{
mFilterString = string;
invalidateFilter();
}

bool QgsExpressionItemSearchProxy::lessThan( const QModelIndex &left, const QModelIndex &right ) const
@@ -121,9 +121,20 @@ class GUI_EXPORT QgsExpressionItemSearchProxy : public QSortFilterProxyModel

bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const override;

/**
* Sets the search filter \a string.
*
* \since QGIS 3.22
*/
void setFilterString( const QString &string );

protected:

bool lessThan( const QModelIndex &left, const QModelIndex &right ) const override;

private:

QString mFilterString;
};

/**

0 comments on commit 2f7efed

Please sign in to comment.