Skip to content
Permalink
Browse files

Merge pull request #8229 from signedav/duplication-context-fix

Select feature menu on action with multiple features
  • Loading branch information
m-kuhn committed Oct 26, 2018
2 parents bbdbfa1 + fa625ff commit e797f7efe94d85f4f1857b1cf578e5f99253e618
Showing with 55 additions and 22 deletions.
  1. +53 −22 src/app/qgsmaptoolfeatureaction.cpp
  2. +2 −0 src/app/qgsmaptoolfeatureaction.h
@@ -15,7 +15,6 @@

#include "qgsmaptoolfeatureaction.h"

#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
@@ -96,6 +95,7 @@ bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y )
return false;

QgsPointXY point = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y );
QPoint position = mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );

QgsRectangle r;

@@ -121,36 +121,67 @@ bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y )
QgsDebugMsg( QStringLiteral( "Caught CRS exception %1" ).arg( cse.what() ) );
}

QgsAction defaultAction = layer->actions()->defaultAction( QStringLiteral( "Canvas" ) );

QgsFeature f;
QgsFeatureList features;
QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) );
QgsFeature feat;
while ( fit.nextFeature( feat ) )
while ( fit.nextFeature( f ) )
{
features.append( f );
}

if ( !features.isEmpty() )
{
if ( defaultAction.isValid() )
if ( features.count() == 1 )
{
// define custom substitutions: layer id and clicked coords
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::mapSettingsScope( mCanvas->mapSettings() );
QgsExpressionContextScope *actionScope = new QgsExpressionContextScope();
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "click_x" ), point.x(), true ) );
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "click_y" ), point.y(), true ) );
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "action_scope" ), QStringLiteral( "Canvas" ), true ) );
context << actionScope;

defaultAction.run( layer, feat, context );
doActionForFeature( layer, features.first(), point );
}
else
{
QgsMapLayerAction *mapLayerAction = QgsGui::mapLayerActionRegistry()->defaultActionForLayer( layer );
if ( mapLayerAction )
QMenu *featureMenu = new QMenu();
for ( const QgsFeature &feature : qgis::as_const( features ) )
{
mapLayerAction->triggerForFeature( layer, &feat );
QAction *featureAction = featureMenu->addAction( FID_TO_STRING( feature.id() ) );
connect( featureAction, &QAction::triggered, this, [ = ] { doActionForFeature( layer, feature, point );} );
}
QAction *allFeatureAction = featureMenu->addAction( tr( "All Features" ) );
connect( allFeatureAction, &QAction::triggered, this, [ = ]
{
for ( const QgsFeature &feature : qgis::as_const( features ) )
{
doActionForFeature( layer, feature, point );
}
} );
featureMenu->exec( position );
}
return true;
}
return false;
}

return true;
void QgsMapToolFeatureAction::doActionForFeature( QgsVectorLayer *layer, const QgsFeature &feature, const QgsPointXY &point )
{
QgsAction defaultAction = layer->actions()->defaultAction( QStringLiteral( "Canvas" ) );
if ( defaultAction.isValid() )
{
// define custom substitutions: layer id and clicked coords
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::mapSettingsScope( mCanvas->mapSettings() );
QgsExpressionContextScope *actionScope = new QgsExpressionContextScope();
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "click_x" ), point.x(), true ) );
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "click_y" ), point.y(), true ) );
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "action_scope" ), QStringLiteral( "Canvas" ), true ) );
context << actionScope;

defaultAction.run( layer, feature, context );
}
else
{
QgsMapLayerAction *mapLayerAction = QgsGui::mapLayerActionRegistry()->defaultActionForLayer( layer );
if ( mapLayerAction )
{
mapLayerAction->triggerForFeature( layer, &feature );
}
}
}
@@ -24,6 +24,7 @@
#include "qgis_app.h"

class QgsVectorLayer;
class QgsFeature;

/**
\brief Map tool for running feature actions on the current layer
@@ -52,6 +53,7 @@ class APP_EXPORT QgsMapToolFeatureAction : public QgsMapTool

private:
bool doAction( QgsVectorLayer *layer, int x, int y );
void doActionForFeature( QgsVectorLayer *layer, const QgsFeature &feature, const QgsPointXY &point );
};

#endif

0 comments on commit e797f7e

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