Skip to content
Permalink
Browse files

[locator] show field where text has been found in current layer filter (

#7904)

* [locator] show field where text has been found

also fix an issue that a field was not returning a match for big number (e/f formats)

* init layer tree model when testing QgisApp

* add test for inbuilt active layer locator filter

* use string comparison for numerical value

this is how it is done in attribute table filter and seems to have better result than comparing numerical values

* switch back to numerical precision and cleanup layers
  • Loading branch information
3nids committed Sep 18, 2018
1 parent 622fe8c commit 6b8cd4bd472fbd3ef5e3951cd65d06787ae95d34
@@ -212,7 +212,7 @@ void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const
return;

bool allowNumeric = false;
double numericValue = string.toDouble( &allowNumeric );
double numericalValue = string.toDouble( &allowNumeric );

QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgisApp::instance()->activeLayer() );
if ( !layer )
@@ -234,7 +234,7 @@ void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const
}
else if ( allowNumeric && field.isNumeric() )
{
expressionParts << QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( field.name() ) ).arg( numericValue );
expressionParts << QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( field.name() ) ).arg( QString::number( numericalValue, 'g', 17 ) );
}
}

@@ -248,6 +248,11 @@ void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const

mLayerId = layer->id();
mLayerIcon = QgsMapLayerModel::iconForLayer( layer );
mAttributeAliases.clear();
for ( int idx = 0; idx < layer->fields().size(); ++idx )
{
mAttributeAliases.append( layer->attributeDisplayName( idx ) );
}
}

void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, const QgsLocatorContext &, QgsFeedback *feedback )
@@ -265,14 +270,20 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c
mContext.setFeature( f );

// find matching field content
Q_FOREACH ( const QVariant &var, f.attributes() )
int idx = 0;
const QgsAttributes attributes = f.attributes();
for ( const QVariant &var : attributes )
{
QString attrString = var.toString();
if ( attrString.contains( string, Qt::CaseInsensitive ) )
{
result.displayString = attrString;
if ( idx < mAttributeAliases.count() )
result.displayString = QString( "%1 (%2)" ).arg( attrString, mAttributeAliases[idx] );
else
result.displayString = attrString;
break;
}
idx++;
}
if ( result.displayString.isEmpty() )
continue; //not sure how this result slipped through...
@@ -18,7 +18,7 @@
#ifndef QGSINBUILTLOCATORFILTERS_H
#define QGSINBUILTLOCATORFILTERS_H

#include "qgisapp.h"
#include "qgis_app.h"
#include "qgslocatorfilter.h"
#include "qgsexpressioncontext.h"
#include "qgsfeatureiterator.h"
@@ -63,7 +63,7 @@ class APP_EXPORT QgsLayoutLocatorFilter : public QgsLocatorFilter

};

class QgsActionLocatorFilter : public QgsLocatorFilter
class APP_EXPORT QgsActionLocatorFilter : public QgsLocatorFilter
{
Q_OBJECT

@@ -87,7 +87,7 @@ class QgsActionLocatorFilter : public QgsLocatorFilter

};

class QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter
class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter
{
Q_OBJECT

@@ -111,6 +111,7 @@ class QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter
QgsFeatureIterator mIterator;
QString mLayerId;
QIcon mLayerIcon;
QStringList mAttributeAliases;
};

class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter
@@ -167,7 +168,7 @@ class APP_EXPORT QgsExpressionCalculatorLocatorFilter : public QgsLocatorFilter
};


class QgsBookmarkLocatorFilter : public QgsLocatorFilter
class APP_EXPORT QgsBookmarkLocatorFilter : public QgsLocatorFilter
{
Q_OBJECT

@@ -185,7 +186,7 @@ class QgsBookmarkLocatorFilter : public QgsLocatorFilter
void triggerResult( const QgsLocatorResult &result ) override;
};

class QgsSettingsLocatorFilter : public QgsLocatorFilter
class APP_EXPORT QgsSettingsLocatorFilter : public QgsLocatorFilter
{
Q_OBJECT

@@ -1433,6 +1433,8 @@ QgisApp::QgisApp()
connect( mMapCanvas, &QgsMapCanvas::messageEmitted, this, &QgisApp::displayMessage );
mMapCanvas->freeze();
mLayerTreeView = new QgsLayerTreeView( this );
QgsLayerTreeModel *model = new QgsLayerTreeModel( QgsProject::instance()->layerTreeRoot(), this );
mLayerTreeView->setModel( model );
mUndoWidget = new QgsUndoWidget( nullptr, mMapCanvas );
mUserInputDockWidget = new QgsUserInputWidget( this );
mInfoBar = new QgsMessageBar( centralWidget() );
@@ -2791,13 +2791,7 @@ QString QgsVectorLayer::attributeDisplayName( int index ) const

QgsStringMap QgsVectorLayer::attributeAliases() const
{
QgsStringMap map;
Q_FOREACH ( const QgsField &field, fields() )
{
if ( !field.alias().isEmpty() )
map.insert( field.name(), field.alias() );
}
return map;
return mAttributeAliasMap;
}

bool QgsVectorLayer::deleteAttribute( int index )
@@ -36,6 +36,7 @@ class TestQgsAppLocatorFilters : public QObject
void testCalculator();
void testLayers();
void testLayouts();
void testSearchActiveLayer();
void testSearchAllLayers();

private:
@@ -148,6 +149,38 @@ void TestQgsAppLocatorFilters::testLayouts()
QCOMPARE( results.at( 2 ).userData.toString(), pl3->name() );
}

void TestQgsAppLocatorFilters::testSearchActiveLayer()
{
QString layerDef = QStringLiteral( "Point?crs=epsg:4326&field=pk:integer&field=my_text:string&field=my_integer:integer&field=my_double:double&key=pk" );
QgsVectorLayer *vl = new QgsVectorLayer( layerDef, QStringLiteral( "Layer" ), QStringLiteral( "memory" ) );
QgsProject::instance()->addMapLayer( vl );

QgsFeature f;
f.setAttributes( QVector<QVariant>() << 1001 << "A nice feature" << 1234567890 << 12345.6789 );
f.setGeometry( QgsGeometry::fromWkt( "Point (-71.123 78.23)" ) );

vl->dataProvider()->addFeature( f );

mQgisApp->setActiveLayer( vl );

QgsActiveLayerFeaturesLocatorFilter filter;
QgsLocatorContext context;

QList< QgsLocatorResult > results = gatherResults( &filter, QStringLiteral( "12345.6789" ), context );
QCOMPARE( results.count(), 1 );

results = gatherResults( &filter, QStringLiteral( "12345.67" ), context );
QCOMPARE( results.count(), 0 );

results = gatherResults( &filter, QStringLiteral( "1234567890" ), context );
QCOMPARE( results.count(), 1 );

results = gatherResults( &filter, QStringLiteral( "nice" ), context );
QCOMPARE( results.count(), 1 );

QgsProject::instance()->removeAllMapLayers();
}

void TestQgsAppLocatorFilters::testSearchAllLayers()
{
QString layerDef = QStringLiteral( "Point?crs=epsg:4326&field=pk:integer&field=my_text:string&field=my_number:integer&key=pk" );
@@ -173,7 +206,6 @@ void TestQgsAppLocatorFilters::testSearchAllLayers()
QgsLocatorContext context;

QList< QgsLocatorResult > results = gatherResults( &filter, QStringLiteral( "100" ), context );
QCOMPARE( results.count(), 2 );

l1->setDisplayExpression( QStringLiteral( "\"my_text\" || ' is ' || \"my_number\"" ) );
l2->setDisplayExpression( QStringLiteral( "\"my_text\" || ' is ' || \"my_number\"" ) );
@@ -185,6 +217,8 @@ void TestQgsAppLocatorFilters::testSearchAllLayers()

results = gatherResults( &filter, QStringLiteral( "feature is 6789" ), context );
QCOMPARE( results.count(), 1 );

QgsProject::instance()->removeAllMapLayers();
}

QList<QgsLocatorResult> TestQgsAppLocatorFilters::gatherResults( QgsLocatorFilter *filter, const QString &string, const QgsLocatorContext &context )

0 comments on commit 6b8cd4b

Please sign in to comment.
You can’t perform that action at this time.