18#include <nlohmann/json.hpp>
35#include <QApplication>
37#include <QDesktopServices>
45#include "moc_qgsprocessingalgorithmdialogbase.cpp"
47using namespace Qt::StringLiterals;
51QgsProcessingAlgorithmDialogFeedback::QgsProcessingAlgorithmDialogFeedback()
55void QgsProcessingAlgorithmDialogFeedback::setProgressText(
const QString &text )
58 emit progressTextChanged( text );
61void QgsProcessingAlgorithmDialogFeedback::reportError(
const QString &error,
bool fatalError )
64 emit errorReported( error, fatalError );
67void QgsProcessingAlgorithmDialogFeedback::pushWarning(
const QString &warning )
70 emit warningPushed( warning );
73void QgsProcessingAlgorithmDialogFeedback::pushInfo(
const QString &info )
76 emit infoPushed( info );
79void QgsProcessingAlgorithmDialogFeedback::pushCommandInfo(
const QString &info )
82 emit commandInfoPushed( info );
85void QgsProcessingAlgorithmDialogFeedback::pushDebugInfo(
const QString &info )
88 emit debugInfoPushed( info );
91void QgsProcessingAlgorithmDialogFeedback::pushConsoleInfo(
const QString &info )
94 emit consoleInfoPushed( info );
97void QgsProcessingAlgorithmDialogFeedback::pushFormattedMessage(
const QString &html,
const QString &text )
100 emit formattedMessagePushed( html );
107QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags, DialogMode mode )
108 : QDialog( parent, flags )
114 splitter->setCollapsible( 0,
false );
117 QSplitterHandle *splitterHandle = splitter->handle( 1 );
118 QVBoxLayout *handleLayout =
new QVBoxLayout();
119 handleLayout->setContentsMargins( 0, 0, 0, 0 );
120 mButtonCollapse =
new QToolButton( splitterHandle );
121 mButtonCollapse->setAutoRaise(
true );
122 mButtonCollapse->setFixedSize( 12, 12 );
123 mButtonCollapse->setCursor( Qt::ArrowCursor );
124 handleLayout->addWidget( mButtonCollapse );
125 handleLayout->addStretch();
126 splitterHandle->setLayout( handleLayout );
130 txtLog->setOpenLinks(
false );
131 connect( txtLog, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmDialogBase::urlClicked );
134 splitter->restoreState( settings.
value( u
"/Processing/dialogBaseSplitter"_s, QByteArray() ).toByteArray() );
135 mSplitterState = splitter->saveState();
136 splitterChanged( 0, 0 );
139 mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
140 mButtonRun->setText( tr(
"Run" ) );
143 mButtonChangeParameters = mButtonBox->button( QDialogButtonBox::Yes );
144 mButtonChangeParameters->setText( tr(
"Change Parameters" ) );
146 buttonCancel->setEnabled(
false );
147 mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
151 case DialogMode::Single:
153 mAdvancedButton =
new QPushButton( tr(
"Advanced" ) );
154 mAdvancedMenu =
new QMenu(
this );
155 mAdvancedButton->setMenu( mAdvancedMenu );
157 mContextSettingsAction =
new QAction( tr(
"Algorithm Settingsā¦" ), mAdvancedMenu );
159 mAdvancedMenu->addAction( mContextSettingsAction );
161 connect( mContextSettingsAction, &QAction::triggered,
this, [
this] {
164 mTabWidget->setCurrentIndex( 0 );
166 if ( !mContextOptionsWidget )
168 mContextOptionsWidget =
new QgsProcessingContextOptionsWidget();
169 mContextOptionsWidget->setFromContext( processingContext() );
170 mContextOptionsWidget->setLogLevel( mLogLevel );
171 panel->openPanel( mContextOptionsWidget );
174 mOverrideDefaultContextSettings =
true;
175 mGeometryCheck = mContextOptionsWidget->invalidGeometryCheck();
176 mDistanceUnits = mContextOptionsWidget->distanceUnit();
177 mAreaUnits = mContextOptionsWidget->areaUnit();
178 mTemporaryFolderOverride = mContextOptionsWidget->temporaryFolder();
179 mMaximumThreads = mContextOptionsWidget->maximumThreads();
180 mLogLevel = mContextOptionsWidget->logLevel();
185 mAdvancedMenu->addSeparator();
187 QAction *copyAsPythonCommand =
new QAction( tr(
"Copy as Python Command" ), mAdvancedMenu );
190 mAdvancedMenu->addAction( copyAsPythonCommand );
191 connect( copyAsPythonCommand, &QAction::triggered,
this, [
this] {
198 const QString command = alg->asPythonCommand( createProcessingParameters(), *context );
199 QMimeData *m =
new QMimeData();
200 m->setText( command );
201 QClipboard *cb = QApplication::clipboard();
204 cb->setMimeData( m, QClipboard::Selection );
206 cb->setMimeData( m, QClipboard::Clipboard );
210 mCopyAsQgisProcessCommand =
new QAction( tr(
"Copy as qgis_process Command" ), mAdvancedMenu );
212 mAdvancedMenu->addAction( mCopyAsQgisProcessCommand );
214 connect( mCopyAsQgisProcessCommand, &QAction::triggered,
this, [
this] {
222 const QString command = alg->asQgisProcessCommand( createProcessingParameters(), *context, ok );
225 mMessageBar->pushMessage( tr(
"Current settings cannot be specified as arguments to qgis_process (Pipe parameters as JSON to qgis_process instead)" ),
Qgis::MessageLevel::Warning );
229 QMimeData *m =
new QMimeData();
230 m->setText( command );
231 QClipboard *cb = QApplication::clipboard();
234 cb->setMimeData( m, QClipboard::Selection );
236 cb->setMimeData( m, QClipboard::Clipboard );
241 mAdvancedMenu->addSeparator();
243 QAction *copyAsJson =
new QAction( tr(
"Copy as JSON" ), mAdvancedMenu );
246 mAdvancedMenu->addAction( copyAsJson );
247 connect( copyAsJson, &QAction::triggered,
this, [
this] {
254 const QVariantMap properties = alg->asMap( createProcessingParameters(), *context );
257 QMimeData *m =
new QMimeData();
259 QClipboard *cb = QApplication::clipboard();
262 cb->setMimeData( m, QClipboard::Selection );
264 cb->setMimeData( m, QClipboard::Clipboard );
268 mPasteJsonAction =
new QAction( tr(
"Paste Settings" ), mAdvancedMenu );
271 mAdvancedMenu->addAction( mPasteJsonAction );
272 connect( mPasteJsonAction, &QAction::triggered,
this, [
this] {
273 const QString text = QApplication::clipboard()->text();
274 if ( text.isEmpty() )
278 if ( parameterValues.isEmpty() )
285 setParameters( preparedValues );
288 mButtonBox->addButton( mAdvancedButton, QDialogButtonBox::ResetRole );
292 case DialogMode::Batch:
298 connect( mAdvancedMenu, &QMenu::aboutToShow,
this, [
this] {
300 mPasteJsonAction->setEnabled( !QApplication::clipboard()->text().isEmpty() );
304 connect( mButtonRun, &QPushButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::runAlgorithm );
305 connect( mButtonChangeParameters, &QPushButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::showParameters );
306 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsProcessingAlgorithmDialogBase::closeClicked );
307 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsProcessingAlgorithmDialogBase::openHelp );
308 connect( mButtonCollapse, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed );
309 connect( splitter, &QSplitter::splitterMoved,
this, &QgsProcessingAlgorithmDialogBase::splitterChanged );
311 connect( mButtonSaveLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::saveLog );
312 connect( mButtonCopyLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::copyLogToClipboard );
313 connect( mButtonClearLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::clearLog );
315 connect( mTabWidget, &QTabWidget::currentChanged,
this, &QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged );
318 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
319 verticalLayout->insertWidget( 0, mMessageBar );
324QgsProcessingAlgorithmDialogBase::~QgsProcessingAlgorithmDialogBase() =
default;
326void QgsProcessingAlgorithmDialogBase::setParameters(
const QVariantMap & )
335 title = mAlgorithm->group().isEmpty()
337 : u
"%1 - %2"_s.arg(
QgsStringUtils::capitalize( mAlgorithm->group(),
Qgis::Capitalization::TitleCase ),
QgsStringUtils::capitalize( mAlgorithm->displayName(),
Qgis::Capitalization::TitleCase ) );
341 title = mAlgorithm->group().isEmpty()
342 ? mAlgorithm->displayName()
343 : u
"%1 - %2"_s.arg( mAlgorithm->group(), mAlgorithm->displayName() );
346 setWindowTitle( title );
348 const QString algHelp = formatHelp(
algorithm );
349 if ( algHelp.isEmpty() )
350 textShortHelp->hide();
353 textShortHelp->document()->setDefaultStyleSheet( QStringLiteral(
".summary { margin-left: 10px; margin-right: 10px; }\n"
354 "h2 { color: #555555; padding-bottom: 15px; }\n"
355 "a { text - decoration: none; color: #3498db; font-weight: bold; }\n"
356 "p, ul, li { color: #666666; }\n"
357 "b { color: #333333; }\n"
358 "dl dd { margin - bottom: 5px; }" ) );
359 textShortHelp->setHtml( algHelp );
360 connect( textShortHelp, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmDialogBase::linkClicked );
361 textShortHelp->show();
366 mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Help ) );
369 const QString warning =
algorithm->provider() ?
algorithm->provider()->warningMessage() : QString();
370 if ( !warning.isEmpty() )
378 return mAlgorithm.get();
381void QgsProcessingAlgorithmDialogBase::setMainWidget(
QgsPanelWidget *widget )
385 mMainWidget->deleteLater();
388 mPanelStack->setMainPanel( widget );
391 mMainWidget = widget;
400void QgsProcessingAlgorithmDialogBase::saveLogToFile(
const QString &path,
const LogFormat format )
402 QFile logFile( path );
403 if ( !logFile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
407 QTextStream fout( &logFile );
411 case FormatPlainText:
412 fout << txtLog->toPlainText();
416 fout << txtLog->toHtml();
423 auto feedback = std::make_unique<QgsProcessingAlgorithmDialogFeedback>();
425 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::commandInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushCommandInfo );
426 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::consoleInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushConsoleInfo );
427 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::debugInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushDebugInfo );
428 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::errorReported,
this, &QgsProcessingAlgorithmDialogBase::reportError );
429 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::warningPushed,
this, &QgsProcessingAlgorithmDialogBase::pushWarning );
430 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::infoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushInfo );
431 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::formattedMessagePushed,
this, &QgsProcessingAlgorithmDialogBase::pushFormattedMessage );
432 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::progressTextChanged,
this, &QgsProcessingAlgorithmDialogBase::setProgressText );
434 return feedback.release();
437QDialogButtonBox *QgsProcessingAlgorithmDialogBase::buttonBox()
442QTabWidget *QgsProcessingAlgorithmDialogBase::tabWidget()
447void QgsProcessingAlgorithmDialogBase::showLog()
449 mTabWidget->setCurrentIndex( 1 );
452void QgsProcessingAlgorithmDialogBase::showParameters()
454 mTabWidget->setCurrentIndex( 0 );
457QPushButton *QgsProcessingAlgorithmDialogBase::runButton()
462QPushButton *QgsProcessingAlgorithmDialogBase::cancelButton()
467QPushButton *QgsProcessingAlgorithmDialogBase::changeParametersButton()
469 return mButtonChangeParameters;
472void QgsProcessingAlgorithmDialogBase::clearProgress()
474 progressBar->setMaximum( 0 );
477void QgsProcessingAlgorithmDialogBase::setExecuted(
bool executed )
479 mExecuted = executed;
482void QgsProcessingAlgorithmDialogBase::setExecutedAnyResult(
bool executedAnyResult )
484 mExecutedAnyResult = executedAnyResult;
487void QgsProcessingAlgorithmDialogBase::setResults(
const QVariantMap &results )
496void QgsProcessingAlgorithmDialogBase::openHelp()
498 QUrl algHelp = mAlgorithm->helpUrl();
499 if ( algHelp.isEmpty() && mAlgorithm->provider() )
501 algHelp =
QgsHelp::helpUrl( u
"processing_algs/%1/%2.html#%3"_s.arg( mAlgorithm->provider()->helpId(), mAlgorithm->groupId(), u
"%1%2"_s.arg( mAlgorithm->provider()->helpId() ).arg( mAlgorithm->name().replace(
"_",
"-" ) ) ) );
504 if ( !algHelp.isEmpty() )
505 QDesktopServices::openUrl( algHelp );
508void QgsProcessingAlgorithmDialogBase::toggleCollapsed()
510 if ( mHelpCollapsed )
512 splitter->restoreState( mSplitterState );
513 mButtonCollapse->setArrowType( Qt::RightArrow );
517 mSplitterState = splitter->saveState();
518 splitter->setSizes( QList<int>() << 1 << 0 );
519 mButtonCollapse->setArrowType( Qt::LeftArrow );
521 mHelpCollapsed = !mHelpCollapsed;
524void QgsProcessingAlgorithmDialogBase::splitterChanged(
int,
int )
526 if ( splitter->sizes().at( 1 ) == 0 )
528 mHelpCollapsed =
true;
529 mButtonCollapse->setArrowType( Qt::LeftArrow );
533 mHelpCollapsed =
false;
534 mButtonCollapse->setArrowType( Qt::RightArrow );
538void QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged(
int )
540 updateRunButtonVisibility();
543void QgsProcessingAlgorithmDialogBase::linkClicked(
const QUrl &url )
545 QDesktopServices::openUrl( url.toString() );
548void QgsProcessingAlgorithmDialogBase::algExecuted(
bool successful,
const QVariantMap & )
550 mAlgorithmTask =
nullptr;
557 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
563 if ( isFinalized() && successful )
565 progressBar->setFormat( tr(
"Complete" ) );
569 if ( isFinalized() && !isVisible() )
576void QgsProcessingAlgorithmDialogBase::taskTriggered(
QgsTask *task )
578 if ( task == mAlgorithmTask )
582 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
588void QgsProcessingAlgorithmDialogBase::closeClicked()
594void QgsProcessingAlgorithmDialogBase::urlClicked(
const QUrl &url )
596 const QFileInfo file( url.toLocalFile() );
597 if ( file.exists() && !file.isDir() )
600 QDesktopServices::openUrl( url );
613void QgsProcessingAlgorithmDialogBase::reportError(
const QString &error,
bool fatalError )
615 setInfo( error,
true );
622void QgsProcessingAlgorithmDialogBase::pushWarning(
const QString &warning )
624 setInfo( warning,
false,
true,
true );
628void QgsProcessingAlgorithmDialogBase::pushInfo(
const QString &info )
634void QgsProcessingAlgorithmDialogBase::pushFormattedMessage(
const QString &html )
636 setInfo( html,
false,
false );
640void QgsProcessingAlgorithmDialogBase::pushCommandInfo(
const QString &command )
642 txtLog->append( u
"<code>%1<code>"_s.arg( formatStringForLog( command.toHtmlEscaped() ) ) );
643 scrollToBottomOfLog();
647void QgsProcessingAlgorithmDialogBase::pushDebugInfo(
const QString &message )
649 txtLog->append( u
"<span style=\"color:#777\">%1</span>"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
650 scrollToBottomOfLog();
654void QgsProcessingAlgorithmDialogBase::pushConsoleInfo(
const QString &info )
656 txtLog->append( u
"<code style=\"color:#777\">%1</code>"_s.arg( formatStringForLog( info.toHtmlEscaped() ) ) );
657 scrollToBottomOfLog();
661QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
663 QgsProcessingAlgorithmProgressDialog *dialog =
new QgsProcessingAlgorithmProgressDialog(
this );
664 dialog->setWindowModality( Qt::ApplicationModal );
665 dialog->setWindowTitle( windowTitle() );
666 dialog->setGeometry( geometry() );
667 connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
668 connect( dialog->cancelButton(), &QPushButton::clicked, buttonCancel, &QPushButton::click );
669 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
670 connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]() {
671 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
672 QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
673 sb->setValue( sb->maximum() );
678void QgsProcessingAlgorithmDialogBase::clearLog()
683void QgsProcessingAlgorithmDialogBase::saveLog()
686 const QString lastUsedDir = settings.
value( u
"/Processing/lastUsedLogDirectory"_s, QDir::homePath() ).toString();
689 const QString txtExt = tr(
"Text files" ) + u
" (*.txt *.TXT)"_s;
690 const QString htmlExt = tr(
"HTML files" ) + u
" (*.html *.HTML)"_s;
692 const QString path = QFileDialog::getSaveFileName(
this, tr(
"Save Log to File" ), lastUsedDir, txtExt +
";;" + htmlExt, &filter );
696 if ( path.isEmpty() )
701 settings.
setValue( u
"/Processing/lastUsedLogDirectory"_s, QFileInfo( path ).path() );
703 LogFormat format = FormatPlainText;
704 if ( filter == htmlExt )
708 saveLogToFile( path, format );
711void QgsProcessingAlgorithmDialogBase::copyLogToClipboard()
713 QMimeData *m =
new QMimeData();
714 m->setText( txtLog->toPlainText() );
715 m->setHtml( txtLog->toHtml() );
716 QClipboard *cb = QApplication::clipboard();
719 cb->setMimeData( m, QClipboard::Selection );
721 cb->setMimeData( m, QClipboard::Clipboard );
724void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
726 if ( !mHelpCollapsed )
729 settings.
setValue( u
"/Processing/dialogBaseSplitter"_s, splitter->saveState() );
732 QDialog::closeEvent( e );
734 if ( !mAlgorithmTask && isFinalized() )
743void QgsProcessingAlgorithmDialogBase::runAlgorithm()
747void QgsProcessingAlgorithmDialogBase::setPercentage(
double percent )
750 if ( progressBar->maximum() == 0 )
751 progressBar->setMaximum( 100 );
752 progressBar->setValue( percent );
756void QgsProcessingAlgorithmDialogBase::setProgressText(
const QString &text )
758 lblProgress->setText( text );
759 setInfo( text,
false );
760 scrollToBottomOfLog();
767 const QString text =
algorithm->shortHelpString();
768 if ( !text.isEmpty() )
770 const QStringList paragraphs = text.split(
'\n' );
772 for (
const QString ¶graph : paragraphs )
774 help += u
"<p>%1</p>"_s.arg( paragraph );
776 result = u
"<h2>%1</h2>%2"_s.arg(
algorithm->displayName(), help );
778 else if ( !
algorithm->shortDescription().isEmpty() )
780 result = u
"<h2>%1</h2><p>%2</p>"_s.arg(
algorithm->displayName(),
algorithm->shortDescription() );
788 if (
algorithm->documentationFlags() & flag )
793 result += u
"<ul><li><i>%1</i></li></ul>"_s.arg( flags.join(
"</i></li><li><i>"_L1 ) );
797 result += u
"<p><b>%1</b></p>"_s.arg( tr(
"Warning: This algorithm is a potential security risk if executed with unchecked inputs, and may result in system damage or data leaks." ) );
801 result += u
"<p><b>%1</b></p>"_s.arg( tr(
"Warning: This algorithm has known issues. The results must be carefully validated by the user." ) );
807void QgsProcessingAlgorithmDialogBase::processEvents()
809 if ( mAlgorithmTask )
825 while ( ++nIters < 100 )
828 QCoreApplication::processEvents();
832void QgsProcessingAlgorithmDialogBase::scrollToBottomOfLog()
834 QScrollBar *sb = txtLog->verticalScrollBar();
835 sb->setValue( sb->maximum() );
838void QgsProcessingAlgorithmDialogBase::resetGui()
840 lblProgress->clear();
841 progressBar->setMaximum( 100 );
842 progressBar->setValue( 0 );
843 mButtonRun->setEnabled(
true );
844 mButtonChangeParameters->setEnabled(
true );
845 mButtonClose->setEnabled(
true );
848 mMainWidget->setEnabled(
true );
850 updateRunButtonVisibility();
851 resetAdditionalGui();
854void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility()
857 const bool runButtonVisible = mTabWidget->currentIndex() == 0;
858 mButtonRun->setVisible( runButtonVisible );
859 if ( runButtonVisible )
860 progressBar->resetFormat();
861 mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult && mButtonChangeParameters->isEnabled() );
864void QgsProcessingAlgorithmDialogBase::resetAdditionalGui()
868void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning()
870 mButtonRun->setEnabled(
false );
871 mButtonChangeParameters->setEnabled(
false );
874 mMainWidget->setEnabled(
false );
876 blockAdditionalControlsWhileRunning();
879void QgsProcessingAlgorithmDialogBase::blockAdditionalControlsWhileRunning()
888void QgsProcessingAlgorithmDialogBase::hideShortHelp()
890 textShortHelp->setVisible(
false );
895 mAlgorithmTask = task;
900QString QgsProcessingAlgorithmDialogBase::formatStringForLog(
const QString &
string )
903 s.replace(
'\n',
"<br>"_L1 );
907bool QgsProcessingAlgorithmDialogBase::isFinalized()
919 if ( mOverrideDefaultContextSettings )
929void QgsProcessingAlgorithmDialogBase::setInfo(
const QString &message,
bool isError,
bool escapeHtml,
bool isWarning )
931 constexpr int MESSAGE_COUNT_LIMIT = 10000;
933 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
935 ++mMessageLoggedCount;
939 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
940 txtLog->append( u
"<span style=\"color:red\">%1</span>"_s.arg( tr(
"Message log truncated" ) ) );
941 else if ( isError || isWarning )
942 txtLog->append( u
"<span style=\"color:%1\">%2</span>"_s.arg( isError ? u
"red"_s : u
"#b85a20"_s, escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
943 else if ( escapeHtml )
944 txtLog->append( u
"<span>%1</span"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
946 txtLog->append( u
"<span>%1</span>"_s.arg( formatStringForLog( message ) ) );
947 scrollToBottomOfLog();
951void QgsProcessingAlgorithmDialogBase::reject()
953 if ( !mAlgorithmTask && isFinalized() )
955 setAttribute( Qt::WA_DeleteOnClose );
964QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
970QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
975QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
977 return mButtonBox->button( QDialogButtonBox::Cancel );
980QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
985void QgsProcessingAlgorithmProgressDialog::reject()
994QgsProcessingContextOptionsWidget::QgsProcessingContextOptionsWidget( QWidget *parent )
998 setPanelTitle( tr(
"Algorithm Settings" ) );
1004 mTemporaryFolderWidget->setDialogTitle( tr(
"Select Temporary Directory" ) );
1006 mTemporaryFolderWidget->lineEdit()->setPlaceholderText( tr(
"Default" ) );
1037 mDistanceUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1067 mAreaUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1070 mThreadsSpinBox->setRange( 1, QThread::idealThreadCount() );
1082 whileBlocking( mComboInvalidFeatureFiltering )->setCurrentIndex( mComboInvalidFeatureFiltering->findData( QVariant::fromValue( context->
invalidGeometryCheck() ) ) );
1083 whileBlocking( mDistanceUnitsCombo )->setCurrentIndex( mDistanceUnitsCombo->findData( QVariant::fromValue( context->
distanceUnit() ) ) );
1084 whileBlocking( mAreaUnitsCombo )->setCurrentIndex( mAreaUnitsCombo->findData( QVariant::fromValue( context->
areaUnit() ) ) );
1087 whileBlocking( mLogLevelComboBox )->setCurrentIndex( mLogLevelComboBox->findData(
static_cast<int>( context->
logLevel() ) ) );
1100Qgis::AreaUnit QgsProcessingContextOptionsWidget::areaUnit()
const
1105QString QgsProcessingContextOptionsWidget::temporaryFolder()
1107 return mTemporaryFolderWidget->filePath();
1110int QgsProcessingContextOptionsWidget::maximumThreads()
const
1112 return mThreadsSpinBox->value();
1117 whileBlocking( mLogLevelComboBox )->setCurrentIndex( mLogLevelComboBox->findData(
static_cast<int>( level ) ) );
Provides global constants and enumerations for use throughout the application.
DistanceUnit
Units of distance.
@ Centimeters
Centimeters.
@ Millimeters
Millimeters.
@ Miles
Terrestrial miles.
@ Unknown
Unknown distance unit.
@ Degrees
Degrees, for planar geographic CRS distance measurements.
@ NauticalMiles
Nautical miles.
@ SquareCentimeters
Square centimeters.
@ SquareInches
Square inches.
@ SquareNauticalMiles
Square nautical miles.
@ SquareMillimeters
Square millimeters.
@ SquareYards
Square yards.
@ SquareKilometers
Square kilometers.
@ SquareMeters
Square meters.
@ Unknown
Unknown areal unit.
@ SquareDegrees
Square degrees, for planar geographic CRS area measurements.
@ SquareMiles
Square miles.
@ Warning
Warning message.
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
ProcessingAlgorithmDocumentationFlag
Flags describing algorithm behavior for documentation purposes.
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
InvalidGeometryCheck
Methods for handling of features with invalid geometries.
@ NoCheck
No invalid geometry checking.
@ AbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
@ SkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
@ NotAvailableInStandaloneTool
Algorithm should not be available from the standalone "qgis_process" tool. Used to flag algorithms wh...
@ SecurityRisk
The algorithm represents a potential security risk if executed with untrusted inputs.
@ DisplayNameIsLiteral
Algorithm's display name is a static literal string, and should not be translated or automatically fo...
@ KnownIssues
Algorithm has known issues.
ProcessingLogLevel
Logging level for algorithms to use when pushing feedback messages.
@ DefaultLevel
Default logging level.
@ Verbose
Verbose logging.
@ ModelDebug
Model debug level logging. Includes verbose logging and other outputs useful for debugging models.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
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 void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
@ HigDialogTitleIsTitleCase
Dialog titles should be title case.
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
static QgsGui::HigFlags higFlags()
Returns the platform's HIG flags.
static QUrl helpUrl(const QString &key)
Returns URI of the help topic for the given key.
static QVariant parseJson(const std::string &jsonString)
Converts JSON jsonString to a QVariant, in case of parsing error an invalid QVariant is returned and ...
static json jsonFromVariant(const QVariant &v)
Converts a QVariant v to a json object.
A bar for displaying non-blocking messages to the user.
QgsTask task which runs a QgsProcessingAlgorithm in a background task.
void executed(bool successful, const QVariantMap &results)
Emitted when the algorithm has finished execution.
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
Qgis::AreaUnit areaUnit() const
Returns the area unit to use for area calculations.
void setLogLevel(Qgis::ProcessingLogLevel level)
Sets the logging level for algorithms to use when pushing feedback messages to users.
void setMaximumThreads(int threads)
Sets the (optional) number of threads to use when running algorithms.
void setDistanceUnit(Qgis::DistanceUnit unit)
Sets the unit to use for distance calculations.
void setInvalidGeometryCheck(Qgis::InvalidGeometryCheck check)
Sets the behavior used for checking invalid geometries in input layers.
void setAreaUnit(Qgis::AreaUnit areaUnit)
Sets the unit to use for area calculations.
Qgis::DistanceUnit distanceUnit() const
Returns the distance unit to use for distance calculations.
Qgis::ProcessingLogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
Qgis::InvalidGeometryCheck invalidGeometryCheck() const
Returns the behavior used for checking invalid geometries in input layers.
void setTemporaryFolder(const QString &folder)
Sets the (optional) temporary folder to use when running algorithms.
QString temporaryFolder() const
Returns the (optional) temporary folder to use when running algorithms.
int maximumThreads() const
Returns the (optional) number of threads to use when running algorithms.
Base class for providing feedback from a processing algorithm.
virtual void pushCommandInfo(const QString &info)
Pushes an informational message containing a command from the algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void pushFormattedMessage(const QString &html, const QString &text)
Pushes a pre-formatted message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
virtual void pushConsoleInfo(const QString &info)
Pushes a console feedback message from the algorithm.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
static QVariantMap preprocessQgisProcessParameters(const QVariantMap ¶meters, bool &ok, QString &error)
Pre-processes a set of parameter values for the qgis_process command.
static QString documentationFlagToString(Qgis::ProcessingAlgorithmDocumentationFlag flag)
Converts a documentation flag to a translated string.
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Utility functions for working with strings.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
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.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
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
const QList< T > qgsEnumList()
Returns a list all enum entries.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.