29 #include <QToolButton> 
   30 #include <QDesktopServices> 
   32 #include <QApplication> 
   34 #include <QFileDialog> 
   37 #include <nlohmann/json.hpp> 
   42 QgsProcessingAlgorithmDialogFeedback::QgsProcessingAlgorithmDialogFeedback()
 
   46 void QgsProcessingAlgorithmDialogFeedback::setProgressText( 
const QString &text )
 
   49   emit progressTextChanged( text );
 
   52 void QgsProcessingAlgorithmDialogFeedback::reportError( 
const QString &error, 
bool fatalError )
 
   55   emit errorReported( error, fatalError );
 
   58 void QgsProcessingAlgorithmDialogFeedback::pushWarning( 
const QString &warning )
 
   61   emit warningPushed( warning );
 
   64 void QgsProcessingAlgorithmDialogFeedback::pushInfo( 
const QString &info )
 
   67   emit infoPushed( info );
 
   70 void QgsProcessingAlgorithmDialogFeedback::pushCommandInfo( 
const QString &info )
 
   73   emit commandInfoPushed( info );
 
   76 void QgsProcessingAlgorithmDialogFeedback::pushDebugInfo( 
const QString &info )
 
   79   emit debugInfoPushed( info );
 
   82 void QgsProcessingAlgorithmDialogFeedback::pushConsoleInfo( 
const QString &info )
 
   85   emit consoleInfoPushed( info );
 
   92 QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags, DialogMode mode )
 
   93   : QDialog( parent, flags )
 
   99   splitter->setCollapsible( 0, 
false );
 
  102   QSplitterHandle *splitterHandle = splitter->handle( 1 );
 
  103   QVBoxLayout *handleLayout = 
new QVBoxLayout();
 
  104   handleLayout->setContentsMargins( 0, 0, 0, 0 );
 
  105   mButtonCollapse = 
new QToolButton( splitterHandle );
 
  106   mButtonCollapse->setAutoRaise( 
true );
 
  107   mButtonCollapse->setFixedSize( 12, 12 );
 
  108   mButtonCollapse->setCursor( Qt::ArrowCursor );
 
  109   handleLayout->addWidget( mButtonCollapse );
 
  110   handleLayout->addStretch();
 
  111   splitterHandle->setLayout( handleLayout );
 
  116   splitter->restoreState( settings.
value( QStringLiteral( 
"/Processing/dialogBaseSplitter" ), QByteArray() ).toByteArray() );
 
  117   mSplitterState = splitter->saveState();
 
  118   splitterChanged( 0, 0 );
 
  121   mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
 
  122   mButtonRun->setText( tr( 
"Run" ) );
 
  125   mButtonChangeParameters = mButtonBox->button( QDialogButtonBox::Yes );
 
  126   mButtonChangeParameters->setText( tr( 
"Change Parameters" ) );
 
  128   buttonCancel->setEnabled( 
false );
 
  129   mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
 
  133     case DialogMode::Single:
 
  135       mAdvancedButton = 
new QPushButton( tr( 
"Advanced" ) );
 
  136       mAdvancedMenu = 
new QMenu( 
this );
 
  137       mAdvancedButton->setMenu( mAdvancedMenu );
 
  139       QAction *copyAsPythonCommand = 
new QAction( tr( 
"Copy as Python Command" ), mAdvancedMenu );
 
  142       mAdvancedMenu->addAction( copyAsPythonCommand );
 
  143       connect( copyAsPythonCommand, &QAction::triggered, 
this, [
this]
 
  151           const QString command = alg->asPythonCommand( createProcessingParameters(), *context );
 
  152           QMimeData *m = 
new QMimeData();
 
  153           m->setText( command );
 
  154           QClipboard *cb = QApplication::clipboard();
 
  157           cb->setMimeData( m, QClipboard::Selection );
 
  159           cb->setMimeData( m, QClipboard::Clipboard );
 
  163       mCopyAsQgisProcessCommand = 
new QAction( tr( 
"Copy as qgis_process Command" ), mAdvancedMenu );
 
  165       mAdvancedMenu->addAction( mCopyAsQgisProcessCommand );
 
  167       connect( mCopyAsQgisProcessCommand, &QAction::triggered, 
this, [
this]
 
  176           const QString command = alg->asQgisProcessCommand( createProcessingParameters(), *context, ok );
 
  179             mMessageBar->pushMessage( tr( 
"Current settings cannot be specified as arguments to qgis_process (Pipe parameters as JSON to qgis_process instead)" ), Qgis::MessageLevel::Warning );
 
  183             QMimeData *m = 
new QMimeData();
 
  184             m->setText( command );
 
  185             QClipboard *cb = QApplication::clipboard();
 
  188             cb->setMimeData( m, QClipboard::Selection );
 
  190             cb->setMimeData( m, QClipboard::Clipboard );
 
  195       mAdvancedMenu->addSeparator();
 
  197       QAction *copyAsJson = 
new QAction( tr( 
"Copy as JSON" ), mAdvancedMenu );
 
  200       mAdvancedMenu->addAction( copyAsJson );
 
  201       connect( copyAsJson, &QAction::triggered, 
this, [
this]
 
  209           const QVariantMap properties = alg->asMap( createProcessingParameters(), *context );
 
  212           QMimeData *m = 
new QMimeData();
 
  214           QClipboard *cb = QApplication::clipboard();
 
  217           cb->setMimeData( m, QClipboard::Selection );
 
  219           cb->setMimeData( m, QClipboard::Clipboard );
 
  223       mPasteJsonAction = 
new QAction( tr( 
"Paste Settings" ), mAdvancedMenu );
 
  226       mAdvancedMenu->addAction( mPasteJsonAction );
 
  227       connect( mPasteJsonAction, &QAction::triggered, 
this, [
this]
 
  229         const QString text = QApplication::clipboard()->text();
 
  230         if ( text.isEmpty() )
 
  233         const QVariantMap parameterValues = 
QgsJsonUtils::parseJson( text ).toMap().value( QStringLiteral( 
"inputs" ) ).toMap();
 
  234         if ( parameterValues.isEmpty() )
 
  237         setParameters( parameterValues );
 
  240       mButtonBox->addButton( mAdvancedButton, QDialogButtonBox::ResetRole );
 
  244     case DialogMode::Batch:
 
  250     connect( mAdvancedMenu, &QMenu::aboutToShow, 
this, [ = ]
 
  252       mCopyAsQgisProcessCommand->setEnabled( 
algorithm()
 
  254       mPasteJsonAction->setEnabled( !QApplication::clipboard()->text().isEmpty() );
 
  258   connect( mButtonRun, &QPushButton::clicked, 
this, &QgsProcessingAlgorithmDialogBase::runAlgorithm );
 
  259   connect( mButtonChangeParameters, &QPushButton::clicked, 
this, &QgsProcessingAlgorithmDialogBase::showParameters );
 
  260   connect( mButtonBox, &QDialogButtonBox::rejected, 
this, &QgsProcessingAlgorithmDialogBase::closeClicked );
 
  261   connect( mButtonBox, &QDialogButtonBox::helpRequested, 
this, &QgsProcessingAlgorithmDialogBase::openHelp );
 
  262   connect( mButtonCollapse, &QToolButton::clicked, 
this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed );
 
  263   connect( splitter, &QSplitter::splitterMoved, 
this, &QgsProcessingAlgorithmDialogBase::splitterChanged );
 
  265   connect( mButtonSaveLog, &QToolButton::clicked, 
this, &QgsProcessingAlgorithmDialogBase::saveLog );
 
  266   connect( mButtonCopyLog, &QToolButton::clicked, 
this, &QgsProcessingAlgorithmDialogBase::copyLogToClipboard );
 
  267   connect( mButtonClearLog, &QToolButton::clicked, 
this, &QgsProcessingAlgorithmDialogBase::clearLog );
 
  269   connect( mTabWidget, &QTabWidget::currentChanged, 
this, &QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged );
 
  272   mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
 
  273   verticalLayout->insertWidget( 0,  mMessageBar );
 
  278 QgsProcessingAlgorithmDialogBase::~QgsProcessingAlgorithmDialogBase() = 
default;
 
  280 void QgsProcessingAlgorithmDialogBase::setParameters( 
const QVariantMap & )
 
  293     title = mAlgorithm->displayName();
 
  295   setWindowTitle( title );
 
  297   const QString algHelp = formatHelp( 
algorithm );
 
  298   if ( algHelp.isEmpty() )
 
  299     textShortHelp->hide();
 
  302     textShortHelp->document()->setDefaultStyleSheet( QStringLiteral( 
".summary { margin-left: 10px; margin-right: 10px; }\n" 
  303         "h2 { color: #555555; padding-bottom: 15px; }\n" 
  304         "a { text - decoration: none; color: #3498db; font-weight: bold; }\n" 
  305         "p { color: #666666; }\n" 
  306         "b { color: #333333; }\n" 
  307         "dl dd { margin - bottom: 5px; }" ) );
 
  308     textShortHelp->setHtml( algHelp );
 
  309     connect( textShortHelp, &QTextBrowser::anchorClicked, 
this, &QgsProcessingAlgorithmDialogBase::linkClicked );
 
  310     textShortHelp->show();
 
  315     mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Help ) );
 
  319   if ( !warning.isEmpty() )
 
  321     mMessageBar->pushMessage( warning, Qgis::MessageLevel::Warning );
 
  327   return mAlgorithm.get();
 
  330 void QgsProcessingAlgorithmDialogBase::setMainWidget( 
QgsPanelWidget *widget )
 
  334     mMainWidget->deleteLater();
 
  337   mPanelStack->setMainPanel( widget );
 
  340   mMainWidget = widget;
 
  349 void QgsProcessingAlgorithmDialogBase::saveLogToFile( 
const QString &path, 
const LogFormat format )
 
  351   QFile logFile( path );
 
  352   if ( !logFile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
 
  356   QTextStream fout( &logFile );
 
  360     case FormatPlainText:
 
  361       fout << txtLog->toPlainText();
 
  365       fout << txtLog->toHtml();
 
  372   auto feedback = std::make_unique< QgsProcessingAlgorithmDialogFeedback >();
 
  374   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::commandInfoPushed, 
this, &QgsProcessingAlgorithmDialogBase::pushCommandInfo );
 
  375   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::consoleInfoPushed, 
this, &QgsProcessingAlgorithmDialogBase::pushConsoleInfo );
 
  376   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::debugInfoPushed, 
this, &QgsProcessingAlgorithmDialogBase::pushDebugInfo );
 
  377   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::errorReported, 
this, &QgsProcessingAlgorithmDialogBase::reportError );
 
  378   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::warningPushed, 
this, &QgsProcessingAlgorithmDialogBase::pushWarning );
 
  379   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::infoPushed, 
this, &QgsProcessingAlgorithmDialogBase::pushInfo );
 
  380   connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::progressTextChanged, 
this, &QgsProcessingAlgorithmDialogBase::setProgressText );
 
  382   return feedback.release();
 
  385 QDialogButtonBox *QgsProcessingAlgorithmDialogBase::buttonBox()
 
  390 QTabWidget *QgsProcessingAlgorithmDialogBase::tabWidget()
 
  395 void QgsProcessingAlgorithmDialogBase::showLog()
 
  397   mTabWidget->setCurrentIndex( 1 );
 
  400 void QgsProcessingAlgorithmDialogBase::showParameters()
 
  402   mTabWidget->setCurrentIndex( 0 );
 
  405 QPushButton *QgsProcessingAlgorithmDialogBase::runButton()
 
  410 QPushButton *QgsProcessingAlgorithmDialogBase::cancelButton()
 
  415 QPushButton *QgsProcessingAlgorithmDialogBase::changeParametersButton()
 
  417   return mButtonChangeParameters;
 
  420 void QgsProcessingAlgorithmDialogBase::clearProgress()
 
  422   progressBar->setMaximum( 0 );
 
  425 void QgsProcessingAlgorithmDialogBase::setExecuted( 
bool executed )
 
  427   mExecuted = executed;
 
  430 void QgsProcessingAlgorithmDialogBase::setExecutedAnyResult( 
bool executedAnyResult )
 
  432   mExecutedAnyResult = executedAnyResult;
 
  435 void QgsProcessingAlgorithmDialogBase::setResults( 
const QVariantMap &results )
 
  445 void QgsProcessingAlgorithmDialogBase::openHelp()
 
  447   QUrl algHelp = mAlgorithm->helpUrl();
 
  448   if ( algHelp.isEmpty() )
 
  450     algHelp = 
QgsHelp::helpUrl( QStringLiteral( 
"processing_algs/%1/%2.html#%3" ).arg( mAlgorithm->provider()->helpId(), mAlgorithm->groupId(), QStringLiteral( 
"%1%2" ).arg( mAlgorithm->provider()->helpId() ).arg( mAlgorithm->name() ) ) );
 
  453   if ( !algHelp.isEmpty() )
 
  454     QDesktopServices::openUrl( algHelp );
 
  457 void QgsProcessingAlgorithmDialogBase::toggleCollapsed()
 
  459   if ( mHelpCollapsed )
 
  461     splitter->restoreState( mSplitterState );
 
  462     mButtonCollapse->setArrowType( Qt::RightArrow );
 
  466     mSplitterState = splitter->saveState();
 
  467     splitter->setSizes( QList<int>() << 1 << 0 );
 
  468     mButtonCollapse->setArrowType( Qt::LeftArrow );
 
  470   mHelpCollapsed = !mHelpCollapsed;
 
  473 void QgsProcessingAlgorithmDialogBase::splitterChanged( 
int, 
int )
 
  475   if ( splitter->sizes().at( 1 ) == 0 )
 
  477     mHelpCollapsed = 
true;
 
  478     mButtonCollapse->setArrowType( Qt::LeftArrow );
 
  482     mHelpCollapsed = 
false;
 
  483     mButtonCollapse->setArrowType( Qt::RightArrow );
 
  487 void QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged( 
int )
 
  489   updateRunButtonVisibility();
 
  492 void QgsProcessingAlgorithmDialogBase::linkClicked( 
const QUrl &url )
 
  494   QDesktopServices::openUrl( url.toString() );
 
  497 void QgsProcessingAlgorithmDialogBase::algExecuted( 
bool successful, 
const QVariantMap & )
 
  499   mAlgorithmTask = 
nullptr;
 
  506     setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
 
  513     if ( isFinalized() && !isVisible() )
 
  520 void QgsProcessingAlgorithmDialogBase::taskTriggered( 
QgsTask *task )
 
  522   if ( task == mAlgorithmTask )
 
  526     setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
 
  532 void QgsProcessingAlgorithmDialogBase::closeClicked()
 
  548 void QgsProcessingAlgorithmDialogBase::reportError( 
const QString &error, 
bool fatalError )
 
  550   setInfo( error, 
true );
 
  557 void QgsProcessingAlgorithmDialogBase::pushWarning( 
const QString &warning )
 
  559   setInfo( warning, 
false, 
true, 
true );
 
  563 void QgsProcessingAlgorithmDialogBase::pushInfo( 
const QString &info )
 
  569 void QgsProcessingAlgorithmDialogBase::pushCommandInfo( 
const QString &command )
 
  571   txtLog->append( QStringLiteral( 
"<code>%1<code>" ).arg( formatStringForLog( command.toHtmlEscaped() ) ) );
 
  572   scrollToBottomOfLog();
 
  576 void QgsProcessingAlgorithmDialogBase::pushDebugInfo( 
const QString &message )
 
  578   txtLog->append( QStringLiteral( 
"<span style=\"color:#777\">%1</span>" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
 
  579   scrollToBottomOfLog();
 
  583 void QgsProcessingAlgorithmDialogBase::pushConsoleInfo( 
const QString &info )
 
  585   txtLog->append( QStringLiteral( 
"<code style=\"color:#777\">%1</code>" ).arg( formatStringForLog( info.toHtmlEscaped() ) ) );
 
  586   scrollToBottomOfLog();
 
  590 QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
 
  592   QgsProcessingAlgorithmProgressDialog *dialog = 
new QgsProcessingAlgorithmProgressDialog( 
this );
 
  593   dialog->setWindowModality( Qt::ApplicationModal );
 
  594   dialog->setWindowTitle( windowTitle() );
 
  595   dialog->setGeometry( geometry() ); 
 
  596   connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
 
  597   connect( dialog->cancelButton(), &QPushButton::clicked, buttonCancel, &QPushButton::click );
 
  598   dialog->logTextEdit()->setHtml( txtLog->toHtml() );
 
  599   connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]()
 
  601     dialog->logTextEdit()->setHtml( txtLog->toHtml() );
 
  602     QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
 
  603     sb->setValue( sb->maximum() );
 
  608 void QgsProcessingAlgorithmDialogBase::clearLog()
 
  613 void QgsProcessingAlgorithmDialogBase::saveLog()
 
  616   const QString lastUsedDir = settings.
value( QStringLiteral( 
"/Processing/lastUsedLogDirectory" ), QDir::homePath() ).toString();
 
  619   const QString txtExt = tr( 
"Text files" ) + QStringLiteral( 
" (*.txt *.TXT)" );
 
  620   const QString htmlExt = tr( 
"HTML files" ) + QStringLiteral( 
" (*.html *.HTML)" );
 
  622   const QString path = QFileDialog::getSaveFileName( 
this, tr( 
"Save Log to File" ), lastUsedDir, txtExt + 
";;" + htmlExt, &filter );
 
  623   if ( path.isEmpty() )
 
  628   settings.
setValue( QStringLiteral( 
"/Processing/lastUsedLogDirectory" ), QFileInfo( path ).path() );
 
  630   LogFormat format = FormatPlainText;
 
  631   if ( filter == htmlExt )
 
  635   saveLogToFile( path, format );
 
  638 void QgsProcessingAlgorithmDialogBase::copyLogToClipboard()
 
  640   QMimeData *m = 
new QMimeData();
 
  641   m->setText( txtLog->toPlainText() );
 
  642   m->setHtml( txtLog->toHtml() );
 
  643   QClipboard *cb = QApplication::clipboard();
 
  646   cb->setMimeData( m, QClipboard::Selection );
 
  648   cb->setMimeData( m, QClipboard::Clipboard );
 
  651 void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
 
  653   if ( !mHelpCollapsed )
 
  656     settings.
setValue( QStringLiteral( 
"/Processing/dialogBaseSplitter" ), splitter->saveState() );
 
  659   QDialog::closeEvent( e );
 
  661   if ( !mAlgorithmTask && isFinalized() )
 
  670 void QgsProcessingAlgorithmDialogBase::runAlgorithm()
 
  675 void QgsProcessingAlgorithmDialogBase::setPercentage( 
double percent )
 
  678   if ( progressBar->maximum() == 0 )
 
  679     progressBar->setMaximum( 100 );
 
  680   progressBar->setValue( percent );
 
  684 void QgsProcessingAlgorithmDialogBase::setProgressText( 
const QString &text )
 
  686   lblProgress->setText( text );
 
  687   setInfo( text, 
false );
 
  688   scrollToBottomOfLog();
 
  695   if ( !text.isEmpty() )
 
  697     const QStringList paragraphs = text.split( 
'\n' );
 
  699     for ( 
const QString ¶graph : paragraphs )
 
  701       help += QStringLiteral( 
"<p>%1</p>" ).arg( paragraph );
 
  713 void QgsProcessingAlgorithmDialogBase::processEvents()
 
  715   if ( mAlgorithmTask )
 
  731   while ( ++nIters < 100 )
 
  734     QCoreApplication::processEvents();
 
  738 void QgsProcessingAlgorithmDialogBase::scrollToBottomOfLog()
 
  740   QScrollBar *sb = txtLog->verticalScrollBar();
 
  741   sb->setValue( sb->maximum() );
 
  744 void QgsProcessingAlgorithmDialogBase::resetGui()
 
  746   lblProgress->clear();
 
  747   progressBar->setMaximum( 100 );
 
  748   progressBar->setValue( 0 );
 
  749   mButtonRun->setEnabled( 
true );
 
  750   mButtonChangeParameters->setEnabled( 
true );
 
  751   mButtonClose->setEnabled( 
true );
 
  754     mMainWidget->setEnabled( 
true );
 
  756   updateRunButtonVisibility();
 
  757   resetAdditionalGui();
 
  760 void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility()
 
  763   const bool runButtonVisible = mTabWidget->currentIndex() == 0;
 
  764   mButtonRun->setVisible( runButtonVisible );
 
  765   mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult && mButtonChangeParameters->isEnabled() );
 
  768 void QgsProcessingAlgorithmDialogBase::resetAdditionalGui()
 
  773 void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning()
 
  775   mButtonRun->setEnabled( 
false );
 
  776   mButtonChangeParameters->setEnabled( 
false );
 
  779     mMainWidget->setEnabled( 
false );
 
  781   blockAdditionalControlsWhileRunning();
 
  784 void QgsProcessingAlgorithmDialogBase::blockAdditionalControlsWhileRunning()
 
  789 QgsMessageBar *QgsProcessingAlgorithmDialogBase::messageBar()
 
  794 void QgsProcessingAlgorithmDialogBase::hideShortHelp()
 
  796   textShortHelp->setVisible( 
false );
 
  801   mAlgorithmTask = task;
 
  806 QString QgsProcessingAlgorithmDialogBase::formatStringForLog( 
const QString &
string )
 
  809   s.replace( 
'\n', QLatin1String( 
"<br>" ) );
 
  813 bool QgsProcessingAlgorithmDialogBase::isFinalized()
 
  818 void QgsProcessingAlgorithmDialogBase::setInfo( 
const QString &message, 
bool isError, 
bool escapeHtml, 
bool isWarning )
 
  820   constexpr 
int MESSAGE_COUNT_LIMIT = 10000;
 
  822   if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
 
  824   ++mMessageLoggedCount;
 
  828   if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
 
  829     txtLog->append( QStringLiteral( 
"<span style=\"color:red\">%1</span>" ).arg( tr( 
"Message log truncated" ) ) );
 
  830   else if ( isError || isWarning )
 
  831     txtLog->append( QStringLiteral( 
"<span style=\"color:%1\">%2</span>" ).arg( isError ? QStringLiteral( 
"red" ) : QStringLiteral( 
"#b85a20" ), escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
 
  832   else if ( escapeHtml )
 
  833     txtLog->append( QStringLiteral( 
"<span>%1</span" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
 
  835     txtLog->append( QStringLiteral( 
"<span>%1</span>" ).arg( formatStringForLog( message ) ) );
 
  836   scrollToBottomOfLog();
 
  840 void QgsProcessingAlgorithmDialogBase::reject()
 
  842   if ( !mAlgorithmTask && isFinalized() )
 
  844     setAttribute( Qt::WA_DeleteOnClose );
 
  853 QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
 
  859 QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
 
  864 QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
 
  866   return mButtonBox->button( QDialogButtonBox::Cancel );
 
  869 QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
 
  874 void QgsProcessingAlgorithmProgressDialog::reject()