void QgsAttributeAction::runAction( const QgsAction &action, void ( *executePython )( const QString & ) )
{
  if ( action.type() == QgsAction::OpenUrl )
  {
    QFileInfo finfo( action.action() );
    if ( finfo.exists() && finfo.isFile() )
      QDesktopServices::openUrl( QUrl::fromLocalFile( action.action() ) );
    else
      QDesktopServices::openUrl( QUrl( action.action(), QUrl::TolerantMode ) );
  }
  else if ( action.type() == QgsAction::GenericPython )
  {
    if ( executePython )
    {
      // deprecated
      executePython( action.action() );
    }
    else if ( smPythonExecute )
    {
      // deprecated
      smPythonExecute( action.action() );
    }
    else
    {
      // TODO: capture output from QgsPythonRunner (like QgsRunProcess does)
      QgsPythonRunner::run( action.action() );
    }
  }
  else
  {
    // The QgsRunProcess instance created by this static function
    // deletes itself when no longer needed.
    QgsRunProcess::create( action.action(), action.capture() );
  }
}
Exemple #2
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 );
  }
}
void QgsAttributeActionDialog::init()
{
  // Start from a fresh slate.
  attributeActionTable->setRowCount( 0 );

  // Populate with our actions.
  for ( int i = 0; i < mActions->size(); i++ )
  {
    const QgsAction action = ( *mActions )[i];
    insertRow( i, action.type(), action.name(), action.action(), action.capture() );
  }

  updateButtons();
}
void QgsAttributeActionDialog::insertRow( int row, const QgsAction& action )
{
  QTableWidgetItem* item;
  mAttributeActionTable->insertRow( row );

  // Type
  item = new QTableWidgetItem( textForType( action.type() ) );
  item->setData( Qt::UserRole, action.type() );
  item->setFlags( item->flags() & ~Qt::ItemIsEditable );
  mAttributeActionTable->setItem( row, Type, item );

  // Description
  mAttributeActionTable->setItem( row, Description, new QTableWidgetItem( action.name() ) );

  // Short Title
  mAttributeActionTable->setItem( row, ShortTitle, new QTableWidgetItem( action.shortTitle() ) );

  // Action text
  mAttributeActionTable->setItem( row, ActionText, new QTableWidgetItem( action.action() ) );

  // Capture output
  item = new QTableWidgetItem();
  item->setFlags( item->flags() & ~( Qt::ItemIsEditable ) );
  item->setCheckState( action.capture() ? Qt::Checked : Qt::Unchecked );
  mAttributeActionTable->setItem( row, Capture, item );

  // Capture output
  item = new QTableWidgetItem();
  item->setFlags( item->flags() & ~( Qt::ItemIsEditable ) );
  item->setCheckState( action.showInAttributeTable() ? Qt::Checked : Qt::Unchecked );
  mAttributeActionTable->setItem( row, ShowInAttributeTable, item );

  // Icon
  QIcon icon = action.icon();
  QTableWidgetItem* headerItem = new QTableWidgetItem( icon, "" );
  headerItem->setData( Qt::UserRole, action.iconPath() );
  mAttributeActionTable->setVerticalHeaderItem( row, headerItem );

  updateButtons();
}
Exemple #5
0
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;
}