Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[locator] add open form action, automatically open form for non geometric layers #43462

Merged
merged 3 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 44 additions & 7 deletions src/app/locator/qgsactivelayerfeatureslocatorfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <QSpinBox>

Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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<QVariantMap>();
switch ( data.value( QStringLiteral( "type" ) ).value<ResultType>() )
Expand All @@ -271,8 +287,29 @@ void QgsActiveLayerFeaturesLocatorFilter::triggerResult( const QgsLocatorResult
if ( layer )
{
QgsFeatureId fid = data.value( QStringLiteral( "feature_id" ) ).value<QgsFeatureId>();
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() )
3nids marked this conversation as resolved.
Show resolved Hide resolved
{
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;
}
Expand Down
8 changes: 7 additions & 1 deletion src/app/locator/qgsactivelayerfeatureslocatorfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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" ); }
Expand All @@ -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;

Expand All @@ -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 @)
Expand All @@ -63,6 +68,7 @@ class APP_EXPORT QgsActiveLayerFeaturesLocatorFilter : public QgsLocatorFilter
QgsFeatureIterator mDisplayTitleIterator;
QgsFeatureIterator mFieldIterator;
QString mLayerId;
bool mLayerIsSpatial = false;
nyalldawson marked this conversation as resolved.
Show resolved Hide resolved
QIcon mLayerIcon;
QStringList mAttributeAliases;
QStringList mFieldsCompletion;
Expand Down
9 changes: 6 additions & 3 deletions src/app/locator/qgsalllayersfeatureslocatorfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
Expand Down Expand Up @@ -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++;
Expand All @@ -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<QgsVectorLayer *>( layerId );
if ( !layer )
return;

if ( actionId == OpenForm )
if ( actionId == OpenForm || !layerIsSpatial )
{
QgsFeature f;
QgsFeatureRequest request;
Expand Down
31 changes: 16 additions & 15 deletions src/app/locator/qgsalllayersfeatureslocatorfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<std::shared_ptr<PreparedLayer>> mPreparedLayers;
Expand Down