예제 #1
0
void QgsActionMenu::triggerAction()
{
  if ( !feature().isValid() )
    return;

  QAction* action = qobject_cast<QAction*>( sender() );
  if ( !action )
    return;

  if ( !action->data().isValid() || !action->data().canConvert<ActionData>() )
    return;

  ActionData data = action->data().value<ActionData>();

  if ( data.actionType == Invalid )
    return;

  if ( data.actionType == MapLayerAction )
  {
    QgsMapLayerAction* mapLayerAction = data.actionData.value<QgsMapLayerAction*>();
    mapLayerAction->triggerForFeature( data.mapLayer, &mFeature );
  }
  else if ( data.actionType == AttributeAction )
  {
    // define custom substitutions: layer id and clicked coords
    QgsExpressionContext context = mLayer->createExpressionContext();

    QgsExpressionContextScope* actionScope = new QgsExpressionContextScope();
    actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "action_scope" ), mActionScope, true ) );
    context << actionScope;
    QgsAction act = data.actionData.value<QgsAction>();
    act.run( context );
  }
}
예제 #2
0
void QgsActionMenu::triggerAction()
{
  if ( !feature() )
    return;

  QAction* action = qobject_cast<QAction*>( sender() );
  if ( !action )
    return;

  if ( !action->data().isValid() || !action->data().canConvert<ActionData>() )
    return;

  ActionData data = action->data().value<ActionData>();

  if ( data.actionType == Invalid )
    return;

  if ( data.actionType == MapLayerAction )
  {
    QgsMapLayerAction* mapLayerAction = data.actionId.action;
    mapLayerAction->triggerForFeature( data.mapLayer, feature() );
  }
  else if ( data.actionType == AttributeAction )
  {
    mActions->doAction( data.actionId.id, *feature() );
  }
}
예제 #3
0
void QgsActionMenu::reloadActions()
{
  clear();

  delete mActions;
  mActions = new QgsAttributeAction( *mLayer->actions() );

  for ( int idx = 0; idx < mActions->size(); ++idx )
  {
    const QgsAction& qaction( mActions->at( idx ) );

    QAction* action = new QAction( qaction.icon(), qaction.name(), this );
    action->setData( QVariant::fromValue<ActionData>( ActionData( idx, mFeatureId, mLayer ) ) );
    action->setIcon( qaction.icon() );

    // Only enable items on supported platforms
    if ( !qaction.runable() )
    {
      action->setEnabled( false );
      action->setToolTip( tr( "Not supported on your platform" ) );
    }
    else
    {
      action->setToolTip( qaction.action() );
    }
    connect( action, SIGNAL( triggered() ), this, SLOT( triggerAction() ) );
    addAction( action );
  }

  QList<QgsMapLayerAction*> mapLayerActions = QgsMapLayerActionRegistry::instance()->mapLayerActions( mLayer, QgsMapLayerAction::SingleFeature );

  if ( !mapLayerActions.isEmpty() )
  {
    //add a separator between user defined and standard actions
    addSeparator();

    for ( int i = 0; i < mapLayerActions.size(); ++i )
    {
      QgsMapLayerAction* qaction = mapLayerActions.at( i );
      QAction* action = new QAction( qaction->icon(), qaction->text(), this );
      action->setData( QVariant::fromValue<ActionData>( ActionData( qaction, mFeatureId, mLayer ) ) );
      addAction( action );
      connect( action, SIGNAL( triggered() ), this, SLOT( triggerAction() ) );
    }
  }

  emit reinit();
}
예제 #4
0
bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y )
{
  if ( !layer )
    return false;

  QgsPoint point = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y );

  QgsFeatureList featList;

  // 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
  {
    // create the search rectangle
    double searchRadius = searchRadiusMU( mCanvas );

    QgsRectangle r;
    r.setXMinimum( point.x() - searchRadius );
    r.setXMaximum( point.x() + searchRadius );
    r.setYMinimum( point.y() - searchRadius );
    r.setYMaximum( point.y() + searchRadius );

    r = toLayerCoordinates( layer, r );

    QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) );
    QgsFeature f;
    while ( fit.nextFeature( f ) )
      featList << QgsFeature( f );
  }
  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() ) );
  }

  if ( featList.size() == 0 )
    return false;

  Q_FOREACH ( const QgsFeature& feat, featList )
  {
    if ( layer->actions()->defaultAction() >= 0 )
    {
      // define custom substitutions: layer id and clicked coords
      QMap<QString, QVariant> substitutionMap;
      substitutionMap.insert( "$layerid", layer->id() );
      point = toLayerCoordinates( layer, point );
      substitutionMap.insert( "$clickx", point.x() );
      substitutionMap.insert( "$clicky", point.y() );

      int actionIdx = layer->actions()->defaultAction();
      layer->actions()->doAction( actionIdx, feat, &substitutionMap );
    }
    else
    {
      QgsMapLayerAction* mapLayerAction = QgsMapLayerActionRegistry::instance()->defaultActionForLayer( layer );
      if ( mapLayerAction )
      {
        mapLayerAction->triggerForFeature( layer, &feat );
      }
    }
  }

  return true;
}
예제 #5
0
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;
}