17#include "moc_qgsprocessingbatchalgorithmdialogbase.cpp" 
   24#include <nlohmann/json.hpp> 
   27QgsProcessingBatchAlgorithmDialogBase::QgsProcessingBatchAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags )
 
   28  : QgsProcessingAlgorithmDialogBase( parent, flags, QgsProcessingAlgorithmDialogBase::DialogMode::Batch )
 
   30  mButtonRunSingle = 
new QPushButton( tr( 
"Run as Single Process…" ) );
 
   31  connect( mButtonRunSingle, &QPushButton::clicked, 
this, &QgsProcessingBatchAlgorithmDialogBase::runAsSingle );
 
   32  buttonBox()->addButton( mButtonRunSingle, QDialogButtonBox::ResetRole ); 
 
   36  updateRunButtonVisibility();
 
   39QgsProcessingBatchAlgorithmDialogBase::~QgsProcessingBatchAlgorithmDialogBase() = 
default;
 
   41void QgsProcessingBatchAlgorithmDialogBase::resetAdditionalGui()
 
   43  mButtonRunSingle->setEnabled( 
true );
 
   46void QgsProcessingBatchAlgorithmDialogBase::blockAdditionalControlsWhileRunning()
 
   48  mButtonRunSingle->setEnabled( 
false );
 
   51void QgsProcessingBatchAlgorithmDialogBase::execute( 
const QList<QVariantMap> ¶meters )
 
   53  mQueuedParameters = parameters;
 
   55  mTotalSteps = mQueuedParameters.size();
 
   59  mFeedback.reset( createFeedback() );
 
   61  mBatchFeedback = std::make_unique<QgsProcessingBatchFeedback>( mTotalSteps, mFeedback.get() );
 
   68  blockControlsWhileRunning();
 
   69  setExecutedAnyResult( 
true );
 
   70  cancelButton()->setEnabled( 
true );
 
   76  mTotalTimer.restart();
 
   77  if ( mTotalSteps > 0 )
 
   81bool QgsProcessingBatchAlgorithmDialogBase::isFinalized()
 
   83  return mQueuedParameters.empty();
 
   86void QgsProcessingBatchAlgorithmDialogBase::executeNext()
 
   88  if ( mQueuedParameters.empty() || mFeedback->isCanceled() )
 
   90    allTasksComplete( 
false );
 
   94  mBatchFeedback->setCurrentStep( mCurrentStep++ );
 
   95  setProgressText( QStringLiteral( 
"\n" ) + tr( 
"Processing algorithm %1/%2…" ).arg( mCurrentStep ).arg( mTotalSteps ) );
 
   96  setInfo( tr( 
"<b>Algorithm %1 starting…</b>" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
   98  pushInfo( tr( 
"Input parameters:" ) );
 
  104  mTaskContext.reset( createContext( mBatchFeedback.get() ) );
 
  106  const QVariantMap paramsJson = 
algorithm()->
asMap( mQueuedParameters.constFirst(), *mTaskContext ).value( QStringLiteral( 
"inputs" ) ).toMap();
 
  108  pushInfo( QString() );
 
  111  mQueuedParameters.pop_front();
 
  113  mCurrentStepTimer.restart();
 
  118      onTaskComplete( 
false, {} );
 
  121      setCurrentTask( task );
 
  128    const QVariantMap results = 
algorithm()->
run( mCurrentParameters, *mTaskContext, mBatchFeedback.get(), &ok );
 
  129    onTaskComplete( ok, results );
 
  133void QgsProcessingBatchAlgorithmDialogBase::algExecuted( 
bool successful, 
const QVariantMap &results )
 
  136  QgsProcessingAlgorithmDialogBase::algExecuted( successful, results );
 
  137  onTaskComplete( successful, results );
 
  140void QgsProcessingBatchAlgorithmDialogBase::onTaskComplete( 
bool ok, 
const QVariantMap &results )
 
  144    setInfo( tr( 
"Algorithm %1 correctly executed…" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
  145    pushInfo( tr( 
"Execution completed in %1 seconds" ).arg( mCurrentStepTimer.elapsed() / 1000.0, 2 ) );
 
  146    pushInfo( tr( 
"Results:" ) );
 
  149    pushInfo( QString() );
 
  151    mResults.append( QVariantMap(
 
  152      { { QStringLiteral( 
"parameters" ), mCurrentParameters },
 
  153        { QStringLiteral( 
"results" ), results }
 
  157    handleAlgorithmResults( 
algorithm(), *mTaskContext, mBatchFeedback.get(), mCurrentParameters );
 
  160  else if ( mBatchFeedback->isCanceled() )
 
  162    setInfo( tr( 
"Algorithm %1 canceled…" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
  163    pushInfo( tr( 
"Execution canceled after %1 seconds" ).arg( mCurrentStepTimer.elapsed() / 1000.0, 2 ) );
 
  164    allTasksComplete( 
true );
 
  168    const QStringList taskErrors = mBatchFeedback->popErrors();
 
  169    setInfo( tr( 
"Algorithm %1 failed…" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
  170    reportError( tr( 
"Execution failed after %1 seconds" ).arg( mCurrentStepTimer.elapsed() / 1000.0, 2 ), 
false );
 
  172    mErrors.append( QVariantMap(
 
  173      { { QStringLiteral( 
"parameters" ), mCurrentParameters },
 
  174        { QStringLiteral( 
"errors" ), taskErrors }
 
  181void QgsProcessingBatchAlgorithmDialogBase::taskTriggered( 
QgsTask *task )
 
  183  if ( task == mProxyTask )
 
  187    setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
 
  193void QgsProcessingBatchAlgorithmDialogBase::allTasksComplete( 
bool canceled )
 
  195  mBatchFeedback.reset();
 
  197  mTaskContext.reset();
 
  198  mQueuedParameters.clear();
 
  201    mProxyTask->finalize( 
true );
 
  202    mProxyTask = 
nullptr;
 
  207    pushInfo( tr( 
"Batch execution completed in %1 seconds" ).arg( mTotalTimer.elapsed() / 1000.0, 2 ) );
 
  208    if ( !mErrors.empty() )
 
  210      reportError( tr( 
"%1 executions failed. See log for further details." ).arg( mErrors.size() ), 
true );
 
  213    for ( 
int i = 0; i < mResults.size(); ++i )
 
  215      loadHtmlResults( mResults.at( i ).value( QStringLiteral( 
"results" ) ).toMap(), i );
 
  218    createSummaryTable( mResults, mErrors );
 
  222  cancelButton()->setEnabled( 
false );
 
@ NoThreading
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
 
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
 
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
 
void cancel()
Tells the internal routines that the current operation should be canceled. This should be run by the ...
 
static json jsonFromVariant(const QVariant &v)
Converts a QVariant v to a json object.
 
QgsTask task which runs a QgsProcessingAlgorithm in a background task.
 
bool algorithmCanceled()
Returns true if the algorithm was canceled.
 
virtual QVariantMap preprocessParameters(const QVariantMap ¶meters)
Pre-processes a set of parameters, allowing the algorithm to clean their values.
 
QVariantMap run(const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok=nullptr, const QVariantMap &configuration=QVariantMap(), bool catchExceptions=true) const
Executes the algorithm using the specified parameters.
 
virtual QVariantMap asMap(const QVariantMap ¶meters, QgsProcessingContext &context) const
Returns a JSON serializable variant map containing the specified parameters and context settings.
 
A QgsTask shell which proxies progress reports.
 
void setProxyProgress(double progress)
Sets the progress (from 0 to 100) for the proxied operation.
 
void canceled()
Emitted when the task is canceled.
 
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
 
void taskTriggered(QgsTask *task)
Emitted when a task is triggered.
 
Abstract base class for long running background tasks.
 
@ Hidden
Hide task from GUI.
 
@ CanCancel
Task can be canceled.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call