23 #include <nlohmann/json.hpp> 
   26 QgsProcessingBatchAlgorithmDialogBase::QgsProcessingBatchAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags )
 
   27   : QgsProcessingAlgorithmDialogBase( parent, flags, QgsProcessingAlgorithmDialogBase::DialogMode::Batch )
 
   29   mButtonRunSingle = 
new QPushButton( tr( 
"Run as Single Process…" ) );
 
   30   connect( mButtonRunSingle, &QPushButton::clicked, 
this, &QgsProcessingBatchAlgorithmDialogBase::runAsSingle );
 
   31   buttonBox()->addButton( mButtonRunSingle, QDialogButtonBox::ResetRole ); 
 
   35   updateRunButtonVisibility();
 
   38 QgsProcessingBatchAlgorithmDialogBase::~QgsProcessingBatchAlgorithmDialogBase() = 
default;
 
   40 void QgsProcessingBatchAlgorithmDialogBase::resetAdditionalGui()
 
   42   mButtonRunSingle->setEnabled( 
true );
 
   45 void QgsProcessingBatchAlgorithmDialogBase::blockAdditionalControlsWhileRunning()
 
   47   mButtonRunSingle->setEnabled( 
false );
 
   50 void QgsProcessingBatchAlgorithmDialogBase::execute( 
const QList<QVariantMap> ¶meters )
 
   52   mQueuedParameters = parameters;
 
   54   mTotalSteps = mQueuedParameters.size();
 
   58   mFeedback.reset( createFeedback() );
 
   60   mBatchFeedback = std::make_unique< QgsProcessingBatchFeedback >( mTotalSteps, mFeedback.get() );
 
   67   blockControlsWhileRunning();
 
   68   setExecutedAnyResult( 
true );
 
   69   cancelButton()->setEnabled( 
true );
 
   75   mTotalTimer.restart();
 
   76   if ( mTotalSteps > 0 )
 
   80 bool QgsProcessingBatchAlgorithmDialogBase::isFinalized()
 
   82   return mQueuedParameters.empty();
 
   85 void QgsProcessingBatchAlgorithmDialogBase::executeNext()
 
   87   if ( mQueuedParameters.empty() || mFeedback->isCanceled() )
 
   89     allTasksComplete( 
false );
 
   93   mBatchFeedback->setCurrentStep( mCurrentStep++ );
 
   94   setProgressText( QStringLiteral( 
"\n" ) + tr( 
"Processing algorithm %1/%2…" ).arg( mCurrentStep ).arg( mTotalSteps ) );
 
   95   setInfo( tr( 
"<b>Algorithm %1 starting…</b>" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
   97   pushInfo( tr( 
"Input parameters:" ) );
 
  103   mTaskContext.reset( createContext( mBatchFeedback.get() ) );
 
  105   const QVariantMap paramsJson = 
algorithm()->
asMap( mQueuedParameters.constFirst(), *mTaskContext ).value( QStringLiteral( 
"inputs" ) ).toMap();
 
  107   pushInfo( QString() );
 
  110   mQueuedParameters.pop_front();
 
  112   mCurrentStepTimer.restart();
 
  117       onTaskComplete( 
false, {} );
 
  120       setCurrentTask( task );
 
  127     const QVariantMap results = 
algorithm()->
run( mCurrentParameters, *mTaskContext, mBatchFeedback.get(), &ok );
 
  128     onTaskComplete( ok, results );
 
  132 void QgsProcessingBatchAlgorithmDialogBase::algExecuted( 
bool successful, 
const QVariantMap &results )
 
  135   QgsProcessingAlgorithmDialogBase::algExecuted( successful, results );
 
  136   onTaskComplete( successful, results );
 
  139 void QgsProcessingBatchAlgorithmDialogBase::onTaskComplete( 
bool ok, 
const QVariantMap &results )
 
  143     setInfo( tr( 
"Algorithm %1 correctly executed…" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
  144     pushInfo( tr( 
"Execution completed in %1 seconds" ).arg( mCurrentStepTimer.elapsed() / 1000.0, 2 ) );
 
  145     pushInfo( tr( 
"Results:" ) );
 
  148     pushInfo( QString() );
 
  150     mResults.append( QVariantMap(
 
  152       { QStringLiteral( 
"parameters" ), mCurrentParameters },
 
  153       { QStringLiteral( 
"results" ), results }
 
  156     handleAlgorithmResults( 
algorithm(), *mTaskContext, mBatchFeedback.get(), mCurrentParameters );
 
  159   else if ( mBatchFeedback->isCanceled() )
 
  161     setInfo( tr( 
"Algorithm %1 canceled…" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
  162     pushInfo( tr( 
"Execution canceled after %1 seconds" ).arg( mCurrentStepTimer.elapsed() / 1000.0, 2 ) );
 
  163     allTasksComplete( 
true );
 
  167     const QStringList taskErrors = mBatchFeedback->popErrors();
 
  168     setInfo( tr( 
"Algorithm %1 failed…" ).arg( 
algorithm()->displayName() ), 
false, 
false );
 
  169     reportError( tr( 
"Execution failed after %1 seconds" ).arg( mCurrentStepTimer.elapsed() / 1000.0, 2 ), 
false );
 
  171     mErrors.append( QVariantMap(
 
  173       { QStringLiteral( 
"parameters" ), mCurrentParameters },
 
  174       { QStringLiteral( 
"errors" ), taskErrors }
 
  180 void QgsProcessingBatchAlgorithmDialogBase::taskTriggered( 
QgsTask *task )
 
  182   if ( task == mProxyTask )
 
  186     setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
 
  192 void QgsProcessingBatchAlgorithmDialogBase::allTasksComplete( 
bool canceled )
 
  194   mBatchFeedback.reset();
 
  196   mTaskContext.reset();
 
  197   mQueuedParameters.clear();
 
  200     mProxyTask->finalize( 
true );
 
  201     mProxyTask = 
nullptr;
 
  206     pushInfo( tr( 
"Batch execution completed in %1 seconds" ).arg( mTotalTimer.elapsed() / 1000.0, 2 ) );
 
  207     if ( !mErrors.empty() )
 
  209       reportError( tr( 
"%1 executions failed. See log for further details." ).arg( mErrors.size() ), 
true );
 
  212     for ( 
int i = 0; i < mResults.size(); ++i )
 
  214       loadHtmlResults( mResults.at( i ).value( QStringLiteral( 
"results" ) ).toMap(), i );
 
  217     createSummaryTable( mResults, mErrors );
 
  221   cancelButton()->setEnabled( 
false );