mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
[FEATURE] active layer locator filter field name restriction
the filter can now restrict the search to a specific field by typing @+field_name auto-completion is provided for the field names
This commit is contained in:
parent
002a7033f0
commit
ccb87207ae
@ -244,35 +244,58 @@ QgsActiveLayerFeaturesLocatorFilter *QgsActiveLayerFeaturesLocatorFilter::clone(
|
||||
return new QgsActiveLayerFeaturesLocatorFilter();
|
||||
}
|
||||
|
||||
void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const QgsLocatorContext &context )
|
||||
QString QgsActiveLayerFeaturesLocatorFilter::fieldRestriction( QString &searchString ) const
|
||||
{
|
||||
QString _fieldRestriction;
|
||||
if ( searchString.startsWith( '@' ) )
|
||||
{
|
||||
_fieldRestriction = searchString.left( std::max( searchString.indexOf( ' ' ), 0 ) ).remove( 0, 1 );
|
||||
searchString = searchString.mid( _fieldRestriction.length() + 2 );
|
||||
}
|
||||
return _fieldRestriction;
|
||||
}
|
||||
|
||||
QStringList QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const QgsLocatorContext &context )
|
||||
{
|
||||
// Normally skip very short search strings, unless when specifically searching using this filter
|
||||
if ( string.length() < 3 && !context.usingPrefix )
|
||||
return;
|
||||
return QStringList();
|
||||
|
||||
QgsSettings settings;
|
||||
mMaxTotalResults = settings.value( QStringLiteral( "locator_filters/active_layer_features/limit_global" ), 30, QgsSettings::App ).toInt();
|
||||
|
||||
bool allowNumeric = false;
|
||||
double numericalValue = string.toDouble( &allowNumeric );
|
||||
|
||||
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgisApp::instance()->activeLayer() );
|
||||
if ( !layer )
|
||||
return;
|
||||
return QStringList();
|
||||
|
||||
mDispExpression = QgsExpression( layer->displayExpression() );
|
||||
mContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( layer ) );
|
||||
mDispExpression.prepare( &mContext );
|
||||
|
||||
// determine if search is restricted to a specific field
|
||||
QString searchString = string;
|
||||
QString _fieldRestriction = fieldRestriction( searchString );
|
||||
bool allowNumeric = false;
|
||||
double numericalValue = searchString.toDouble( &allowNumeric );
|
||||
|
||||
// build up request expression
|
||||
QStringList expressionParts;
|
||||
QStringList completionList;
|
||||
const QgsFields fields = layer->fields();
|
||||
QgsAttributeList subsetOfAttributes;
|
||||
for ( const QgsField &field : fields )
|
||||
{
|
||||
if ( !_fieldRestriction.isEmpty() && !field.name().startsWith( _fieldRestriction ) )
|
||||
continue;
|
||||
|
||||
if ( !_fieldRestriction.isEmpty() )
|
||||
subsetOfAttributes << layer->fields().indexFromName( field.name() );
|
||||
|
||||
completionList.append( QStringLiteral( "@%1 " ).arg( field.name() ) );
|
||||
if ( field.type() == QVariant::String )
|
||||
{
|
||||
expressionParts << QStringLiteral( "%1 ILIKE '%%2%'" ).arg( QgsExpression::quotedColumnRef( field.name() ),
|
||||
string );
|
||||
searchString );
|
||||
}
|
||||
else if ( allowNumeric && field.isNumeric() )
|
||||
{
|
||||
@ -285,6 +308,9 @@ void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const
|
||||
QgsFeatureRequest req;
|
||||
req.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
req.setFilterExpression( expression );
|
||||
if ( !_fieldRestriction.isEmpty() )
|
||||
req.setSubsetOfAttributes( subsetOfAttributes );
|
||||
|
||||
req.setLimit( 30 );
|
||||
mIterator = layer->getFeatures( req );
|
||||
|
||||
@ -295,12 +321,16 @@ void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const
|
||||
{
|
||||
mAttributeAliases.append( layer->attributeDisplayName( idx ) );
|
||||
}
|
||||
|
||||
return completionList;
|
||||
}
|
||||
|
||||
void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, const QgsLocatorContext &, QgsFeedback *feedback )
|
||||
{
|
||||
int found = 0;
|
||||
QgsFeature f;
|
||||
QString searchString = string;
|
||||
fieldRestriction( searchString );
|
||||
|
||||
while ( mIterator.nextFeature( f ) )
|
||||
{
|
||||
@ -317,7 +347,7 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c
|
||||
for ( const QVariant &var : attributes )
|
||||
{
|
||||
QString attrString = var.toString();
|
||||
if ( attrString.contains( string, Qt::CaseInsensitive ) )
|
||||
if ( attrString.contains( searchString, Qt::CaseInsensitive ) )
|
||||
{
|
||||
if ( idx < mAttributeAliases.count() )
|
||||
result.displayString = QStringLiteral( "%1 (%2)" ).arg( attrString, mAttributeAliases[idx] );
|
||||
@ -334,7 +364,7 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c
|
||||
|
||||
result.userData = QVariantList() << f.id() << mLayerId;
|
||||
result.icon = mLayerIcon;
|
||||
result.score = static_cast< double >( string.length() ) / result.displayString.size();
|
||||
result.score = static_cast< double >( searchString.length() ) / result.displayString.size();
|
||||
emit resultFetched( result );
|
||||
|
||||
found++;
|
||||
@ -395,11 +425,11 @@ QgsAllLayersFeaturesLocatorFilter *QgsAllLayersFeaturesLocatorFilter::clone() co
|
||||
return new QgsAllLayersFeaturesLocatorFilter();
|
||||
}
|
||||
|
||||
void QgsAllLayersFeaturesLocatorFilter::prepare( const QString &string, const QgsLocatorContext &context )
|
||||
QStringList QgsAllLayersFeaturesLocatorFilter::prepare( const QString &string, const QgsLocatorContext &context )
|
||||
{
|
||||
// Normally skip very short search strings, unless when specifically searching using this filter
|
||||
if ( string.length() < 3 && !context.usingPrefix )
|
||||
return;
|
||||
return QStringList();
|
||||
|
||||
QgsSettings settings;
|
||||
mMaxTotalResults = settings.value( "locator_filters/all_layers_features/limit_global", 15, QgsSettings::App ).toInt();
|
||||
@ -445,6 +475,8 @@ void QgsAllLayersFeaturesLocatorFilter::prepare( const QString &string, const Qg
|
||||
|
||||
mPreparedLayers.append( preparedLayer );
|
||||
}
|
||||
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, const QgsLocatorContext &, QgsFeedback *feedback )
|
||||
|
@ -102,7 +102,7 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter
|
||||
Priority priority() const override { return Medium; }
|
||||
QString prefix() const override { return QStringLiteral( "f" ); }
|
||||
|
||||
void prepare( const QString &string, const QgsLocatorContext &context ) override;
|
||||
QStringList prepare( const QString &string, const QgsLocatorContext &context ) override;
|
||||
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
|
||||
void triggerResult( const QgsLocatorResult &result ) override;
|
||||
bool hasConfigWidget() const override {return true;}
|
||||
@ -110,6 +110,12 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Returns the field restriction if defined (starting with @)
|
||||
* The \a searchString is modified acccordingly by removing the field restriction
|
||||
*/
|
||||
QString fieldRestriction( QString &searchString ) const;
|
||||
|
||||
QgsExpression mDispExpression;
|
||||
QgsExpressionContext mContext;
|
||||
QgsFeatureIterator mIterator;
|
||||
@ -150,7 +156,7 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter
|
||||
Priority priority() const override { return Medium; }
|
||||
QString prefix() const override { return QStringLiteral( "af" ); }
|
||||
|
||||
void prepare( const QString &string, const QgsLocatorContext &context ) override;
|
||||
QStringList prepare( const QString &string, const QgsLocatorContext &context ) override;
|
||||
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
|
||||
void triggerResult( const QgsLocatorResult &result ) override;
|
||||
void triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user