diff --git a/src/app/locator/qgsactivelayerfeatureslocatorfilter.cpp b/src/app/locator/qgsactivelayerfeatureslocatorfilter.cpp index 0dbcac0b0cfc..8c326ab764ac 100644 --- a/src/app/locator/qgsactivelayerfeatureslocatorfilter.cpp +++ b/src/app/locator/qgsactivelayerfeatureslocatorfilter.cpp @@ -15,13 +15,14 @@ * * ***************************************************************************/ -#include "qgsactivelayerfeatureslocatorfilter.h" -#include "qgssettings.h" #include "qgisapp.h" +#include "qgsactivelayerfeatureslocatorfilter.h" #include "qgsexpressioncontextutils.h" -#include "qgsmapcanvas.h" +#include "qgsfeatureaction.h" #include "qgsiconutils.h" #include "qgslocatorwidget.h" +#include "qgsmapcanvas.h" +#include "qgssettings.h" #include @@ -66,6 +67,7 @@ QStringList QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, if ( !layer ) return QStringList(); + mLayerIsSpatial = layer->isSpatial(); mDispExpression = QgsExpression( layer->displayExpression() ); mContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( layer ) ); mDispExpression.prepare( &mContext ); @@ -197,10 +199,14 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c { {QStringLiteral( "type" ), QVariant::fromValue( ResultType::Feature )}, {QStringLiteral( "feature_id" ), f.id()}, - {QStringLiteral( "layer_id" ), mLayerId} + {QStringLiteral( "layer_id" ), mLayerId}, + {QStringLiteral( "layer_is_spatial" ), mLayerIsSpatial} } ); result.icon = mLayerIcon; result.score = static_cast< double >( searchString.length() ) / result.displayString.size(); + if ( mLayerIsSpatial ) + result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form…" ) ); + emit resultFetched( result ); featuresFound << f.id(); @@ -248,10 +254,14 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c { {QStringLiteral( "type" ), QVariant::fromValue( ResultType::Feature )}, {QStringLiteral( "feature_id" ), f.id()}, - {QStringLiteral( "layer_id" ), mLayerId} + {QStringLiteral( "layer_id" ), mLayerId}, + {QStringLiteral( "layer_is_spatial" ), mLayerIsSpatial} } ); result.icon = mLayerIcon; result.score = static_cast< double >( searchString.length() ) / result.displayString.size(); + if ( mLayerIsSpatial ) + result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form…" ) ); + emit resultFetched( result ); featuresFound << f.id(); @@ -260,7 +270,13 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c } } + void QgsActiveLayerFeaturesLocatorFilter::triggerResult( const QgsLocatorResult &result ) +{ + triggerResultFromAction( result, NoEntry ); +} + +void QgsActiveLayerFeaturesLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) { QVariantMap data = result.userData.value(); switch ( data.value( QStringLiteral( "type" ) ).value() ) @@ -271,8 +287,29 @@ void QgsActiveLayerFeaturesLocatorFilter::triggerResult( const QgsLocatorResult if ( layer ) { QgsFeatureId fid = data.value( QStringLiteral( "feature_id" ) ).value(); - QgisApp::instance()->mapCanvas()->zoomToFeatureIds( layer, QgsFeatureIds() << fid ); - QgisApp::instance()->mapCanvas()->flashFeatureIds( layer, QgsFeatureIds() << fid ); + if ( actionId == OpenForm || !data.value( QStringLiteral( "layer_is_spatial" ), true ).toBool() ) + { + QgsFeature f; + QgsFeatureRequest request; + request.setFilterFid( fid ); + bool fetched = layer->getFeatures( request ).nextFeature( f ); + if ( !fetched ) + return; + QgsFeatureAction action( tr( "Attributes changed" ), f, layer, QString(), -1, QgisApp::instance() ); + if ( layer->isEditable() ) + { + action.editFeature( false ); + } + else + { + action.viewFeatureForm(); + } + } + else + { + QgisApp::instance()->mapCanvas()->zoomToFeatureIds( layer, QgsFeatureIds() << fid ); + QgisApp::instance()->mapCanvas()->flashFeatureIds( layer, QgsFeatureIds() << fid ); + } } break; } diff --git a/src/app/locator/qgsactivelayerfeatureslocatorfilter.h b/src/app/locator/qgsactivelayerfeatureslocatorfilter.h index 02bc628e3acb..75f338eb74eb 100644 --- a/src/app/locator/qgsactivelayerfeatureslocatorfilter.h +++ b/src/app/locator/qgsactivelayerfeatureslocatorfilter.h @@ -29,7 +29,6 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter Q_OBJECT public: - QgsActiveLayerFeaturesLocatorFilter( QObject *parent = nullptr ); QgsActiveLayerFeaturesLocatorFilter *clone() const override; QString name() const override { return QStringLiteral( "features" ); } @@ -40,6 +39,7 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter 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; bool hasConfigWidget() const override {return true;} void openConfigWidget( QWidget *parent ) override; @@ -51,6 +51,11 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter Q_ENUM( ResultType ) private: + enum ContextMenuEntry + { + NoEntry, + OpenForm + }; /** * Returns the field restriction if defined (starting with @) @@ -63,6 +68,7 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter QgsFeatureIterator mDisplayTitleIterator; QgsFeatureIterator mFieldIterator; QString mLayerId; + bool mLayerIsSpatial = false; QIcon mLayerIcon; QStringList mAttributeAliases; QStringList mFieldsCompletion; diff --git a/src/app/locator/qgsalllayersfeatureslocatorfilter.cpp b/src/app/locator/qgsalllayersfeatureslocatorfilter.cpp index 52b943b25937..bd62c534ddba 100644 --- a/src/app/locator/qgsalllayersfeatureslocatorfilter.cpp +++ b/src/app/locator/qgsalllayersfeatureslocatorfilter.cpp @@ -87,6 +87,7 @@ QStringList QgsAllLayersFeaturesLocatorFilter::prepare( const QString &string, c preparedLayer->request = req; preparedLayer->exactMatchRequest = exactMatchRequest; preparedLayer->layerIcon = QgsIconUtils::iconForLayer( layer ); + preparedLayer->layerIsSpatial = layer->isSpatial(); mPreparedLayers.append( preparedLayer ); } @@ -154,11 +155,12 @@ void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, con result.displayString = preparedLayer->expression.evaluate( &( preparedLayer->context ) ).toString(); - result.userData = QVariantList() << f.id() << preparedLayer->layerId; + result.userData = QVariantList() << f.id() << preparedLayer->layerId << preparedLayer->layerIsSpatial; result.icon = preparedLayer->layerIcon; result.score = static_cast< double >( string.length() ) / result.displayString.size(); - result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form…" ) ); + if ( preparedLayer->layerIsSpatial ) + result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form…" ) ); emit resultFetched( result ); foundInCurrentLayer++; @@ -181,11 +183,12 @@ void QgsAllLayersFeaturesLocatorFilter::triggerResultFromAction( const QgsLocato QVariantList dataList = result.userData.toList(); QgsFeatureId fid = dataList.at( 0 ).toLongLong(); QString layerId = dataList.at( 1 ).toString(); + bool layerIsSpatial = dataList.at( 2 ).toBool(); QgsVectorLayer *layer = QgsProject::instance()->mapLayer( layerId ); if ( !layer ) return; - if ( actionId == OpenForm ) + if ( actionId == OpenForm || !layerIsSpatial ) { QgsFeature f; QgsFeatureRequest request; diff --git a/src/app/locator/qgsalllayersfeatureslocatorfilter.h b/src/app/locator/qgsalllayersfeatureslocatorfilter.h index c13c151bfcfc..55e39bc745e5 100644 --- a/src/app/locator/qgsalllayersfeatureslocatorfilter.h +++ b/src/app/locator/qgsalllayersfeatureslocatorfilter.h @@ -30,6 +30,21 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter Q_OBJECT public: + QgsAllLayersFeaturesLocatorFilter( QObject *parent = nullptr ); + QgsAllLayersFeaturesLocatorFilter *clone() const override; + QString name() const override { return QStringLiteral( "allfeatures" ); } + QString displayName() const override { return tr( "Features in All Layers" ); } + Priority priority() const override { return Medium; } + QString prefix() const override { return QStringLiteral( "af" ); } + + 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; + bool hasConfigWidget() const override {return true;} + void openConfigWidget( QWidget *parent ) override; + + private: enum ContextMenuEntry { NoEntry, @@ -47,23 +62,9 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter QString layerName; QString layerId; QIcon layerIcon; + bool layerIsSpatial; }; - QgsAllLayersFeaturesLocatorFilter( QObject *parent = nullptr ); - QgsAllLayersFeaturesLocatorFilter *clone() const override; - QString name() const override { return QStringLiteral( "allfeatures" ); } - QString displayName() const override { return tr( "Features in All Layers" ); } - Priority priority() const override { return Medium; } - QString prefix() const override { return QStringLiteral( "af" ); } - - 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; - bool hasConfigWidget() const override {return true;} - void openConfigWidget( QWidget *parent ) override; - - private: int mMaxResultsPerLayer = 8; int mMaxTotalResults = 15; QList> mPreparedLayers;