void QgsActionManager::doAction( const QUuid& actionId, const QgsFeature& feat, const QgsExpressionContext& context ) { QgsAction act = action( actionId ); if ( !act.isValid() || !act.runable() ) return; QgsExpressionContext actionContext( context ); if ( mLayer ) actionContext << QgsExpressionContextUtils::layerScope( mLayer ); actionContext.setFeature( feat ); QString expandedAction = QgsExpression::replaceExpressionText( act.command(), &actionContext ); if ( expandedAction.isEmpty() ) return; QgsAction newAction( act.type(), act.name(), expandedAction, act.capture() ); runAction( newAction ); }
bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y ) { if ( !layer ) return false; QgsPointXY point = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y ); QgsRectangle r; // create the search rectangle double searchRadius = searchRadiusMU( mCanvas ); r.setXMinimum( point.x() - searchRadius ); r.setXMaximum( point.x() + searchRadius ); r.setYMinimum( point.y() - searchRadius ); r.setYMaximum( point.y() + searchRadius ); // toLayerCoordinates will throw an exception for an 'invalid' point. // For example, if you project a world map onto a globe using EPSG 2163 // and then click somewhere off the globe, an exception will be thrown. try { r = toLayerCoordinates( layer, r ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); // catch exception for 'invalid' point and proceed with no features found QgsDebugMsg( QString( "Caught CRS exception %1" ).arg( cse.what() ) ); } QgsAction defaultAction = layer->actions()->defaultAction( QStringLiteral( "Canvas" ) ); QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature feat; while ( fit.nextFeature( feat ) ) { 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, feat, context ); } else { QgsMapLayerAction *mapLayerAction = QgsGui::mapLayerActionRegistry()->defaultActionForLayer( layer ); if ( mapLayerAction ) { mapLayerAction->triggerForFeature( layer, &feat ); } } } return true; }