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() ? mAlgorithm->displayName() : u
"%1 - %2"_s.arg( mAlgorithm->group(), mAlgorithm->displayName() );
344 setWindowTitle( title );
346 const QString algHelp = formatHelp(
algorithm );
347 if ( algHelp.isEmpty() )
348 textShortHelp->hide();
351 textShortHelp->document()->setDefaultStyleSheet( QStringLiteral(
352 ".summary { margin-left: 10px; margin-right: 10px; }\n"
353 "h2 { color: #555555; padding-bottom: 15px; }\n"
354 "a { text - decoration: none; color: #3498db; font-weight: bold; }\n"
355 "p, ul, li { color: #666666; }\n"
356 "b { color: #333333; }\n"
357 "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 )
495void QgsProcessingAlgorithmDialogBase::openHelp()
497 QUrl algHelp = mAlgorithm->helpUrl();
498 if ( algHelp.isEmpty() && mAlgorithm->provider() )
501 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(
"_",
"-" ) ) )
505 if ( !algHelp.isEmpty() )
506 QDesktopServices::openUrl( algHelp );
509void QgsProcessingAlgorithmDialogBase::toggleCollapsed()
511 if ( mHelpCollapsed )
513 splitter->restoreState( mSplitterState );
514 mButtonCollapse->setArrowType( Qt::RightArrow );
518 mSplitterState = splitter->saveState();
519 splitter->setSizes( QList<int>() << 1 << 0 );
520 mButtonCollapse->setArrowType( Qt::LeftArrow );
522 mHelpCollapsed = !mHelpCollapsed;
525void QgsProcessingAlgorithmDialogBase::splitterChanged(
int,
int )
527 if ( splitter->sizes().at( 1 ) == 0 )
529 mHelpCollapsed =
true;
530 mButtonCollapse->setArrowType( Qt::LeftArrow );
534 mHelpCollapsed =
false;
535 mButtonCollapse->setArrowType( Qt::RightArrow );
539void QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged(
int )
541 updateRunButtonVisibility();
544void QgsProcessingAlgorithmDialogBase::linkClicked(
const QUrl &url )
546 QDesktopServices::openUrl( url.toString() );
549void QgsProcessingAlgorithmDialogBase::algExecuted(
bool successful,
const QVariantMap & )
551 mAlgorithmTask =
nullptr;
558 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
564 if ( isFinalized() && successful )
566 progressBar->setFormat( tr(
"Complete" ) );
570 if ( isFinalized() && !isVisible() )
577void QgsProcessingAlgorithmDialogBase::taskTriggered(
QgsTask *task )
579 if ( task == mAlgorithmTask )
583 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
589void QgsProcessingAlgorithmDialogBase::closeClicked()
595void QgsProcessingAlgorithmDialogBase::urlClicked(
const QUrl &url )
597 const QFileInfo file( url.toLocalFile() );
598 if ( file.exists() && !file.isDir() )
601 QDesktopServices::openUrl( url );
614void QgsProcessingAlgorithmDialogBase::reportError(
const QString &error,
bool fatalError )
616 setInfo( error,
true );
623void QgsProcessingAlgorithmDialogBase::pushWarning(
const QString &warning )
625 setInfo( warning,
false,
true,
true );
629void QgsProcessingAlgorithmDialogBase::pushInfo(
const QString &info )
635void QgsProcessingAlgorithmDialogBase::pushFormattedMessage(
const QString &html )
637 setInfo( html,
false,
false );
641void QgsProcessingAlgorithmDialogBase::pushCommandInfo(
const QString &command )
643 txtLog->append( u
"<code>%1<code>"_s.arg( formatStringForLog( command.toHtmlEscaped() ) ) );
644 scrollToBottomOfLog();
648void QgsProcessingAlgorithmDialogBase::pushDebugInfo(
const QString &message )
650 txtLog->append( u
"<span style=\"color:#777\">%1</span>"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
651 scrollToBottomOfLog();
655void QgsProcessingAlgorithmDialogBase::pushConsoleInfo(
const QString &info )
657 txtLog->append( u
"<code style=\"color:#777\">%1</code>"_s.arg( formatStringForLog( info.toHtmlEscaped() ) ) );
658 scrollToBottomOfLog();
662QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
664 QgsProcessingAlgorithmProgressDialog *dialog =
new QgsProcessingAlgorithmProgressDialog(
this );
665 dialog->setWindowModality( Qt::ApplicationModal );
666 dialog->setWindowTitle( windowTitle() );
667 dialog->setGeometry( geometry() );
668 connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
669 connect( dialog->cancelButton(), &QPushButton::clicked, buttonCancel, &QPushButton::click );
670 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
671 connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]() {
672 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
673 QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
674 sb->setValue( sb->maximum() );
679void QgsProcessingAlgorithmDialogBase::clearLog()
684void QgsProcessingAlgorithmDialogBase::saveLog()
687 const QString lastUsedDir = settings.
value( u
"/Processing/lastUsedLogDirectory"_s, QDir::homePath() ).toString();
690 const QString txtExt = tr(
"Text files" ) + u
" (*.txt *.TXT)"_s;
691 const QString htmlExt = tr(
"HTML files" ) + u
" (*.html *.HTML)"_s;
693 const QString path = QFileDialog::getSaveFileName(
this, tr(
"Save Log to File" ), lastUsedDir, txtExt +
";;" + htmlExt, &filter );
697 if ( path.isEmpty() )
702 settings.
setValue( u
"/Processing/lastUsedLogDirectory"_s, QFileInfo( path ).path() );
704 LogFormat format = FormatPlainText;
705 if ( filter == htmlExt )
709 saveLogToFile( path, format );
712void QgsProcessingAlgorithmDialogBase::copyLogToClipboard()
714 QMimeData *m =
new QMimeData();
715 m->setText( txtLog->toPlainText() );
716 m->setHtml( txtLog->toHtml() );
717 QClipboard *cb = QApplication::clipboard();
720 cb->setMimeData( m, QClipboard::Selection );
722 cb->setMimeData( m, QClipboard::Clipboard );
725void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
727 if ( !mHelpCollapsed )
730 settings.
setValue( u
"/Processing/dialogBaseSplitter"_s, splitter->saveState() );
733 QDialog::closeEvent( e );
735 if ( !mAlgorithmTask && isFinalized() )
744void 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()
867void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning()
869 mButtonRun->setEnabled(
false );
870 mButtonChangeParameters->setEnabled(
false );
873 mMainWidget->setEnabled(
false );
875 blockAdditionalControlsWhileRunning();
878void QgsProcessingAlgorithmDialogBase::blockAdditionalControlsWhileRunning()
886void QgsProcessingAlgorithmDialogBase::hideShortHelp()
888 textShortHelp->setVisible(
false );
893 mAlgorithmTask = task;
898QString QgsProcessingAlgorithmDialogBase::formatStringForLog(
const QString &
string )
901 s.replace(
'\n',
"<br>"_L1 );
905bool QgsProcessingAlgorithmDialogBase::isFinalized()
917 if ( mOverrideDefaultContextSettings )
927void QgsProcessingAlgorithmDialogBase::setInfo(
const QString &message,
bool isError,
bool escapeHtml,
bool isWarning )
929 constexpr int MESSAGE_COUNT_LIMIT = 10000;
931 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
933 ++mMessageLoggedCount;
937 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
938 txtLog->append( u
"<span style=\"color:red\">%1</span>"_s.arg( tr(
"Message log truncated" ) ) );
939 else if ( isError || isWarning )
940 txtLog->append( u
"<span style=\"color:%1\">%2</span>"_s.arg( isError ? u
"red"_s : u
"#b85a20"_s, escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
941 else if ( escapeHtml )
942 txtLog->append( u
"<span>%1</span"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
944 txtLog->append( u
"<span>%1</span>"_s.arg( formatStringForLog( message ) ) );
945 scrollToBottomOfLog();
949void QgsProcessingAlgorithmDialogBase::reject()
951 if ( !mAlgorithmTask && isFinalized() )
953 setAttribute( Qt::WA_DeleteOnClose );
962QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
968QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
973QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
975 return mButtonBox->button( QDialogButtonBox::Cancel );
978QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
983void QgsProcessingAlgorithmProgressDialog::reject()
991QgsProcessingContextOptionsWidget::QgsProcessingContextOptionsWidget( QWidget *parent )
995 setPanelTitle( tr(
"Algorithm Settings" ) );
1001 mTemporaryFolderWidget->setDialogTitle( tr(
"Select Temporary Directory" ) );
1003 mTemporaryFolderWidget->lineEdit()->setPlaceholderText( tr(
"Default" ) );
1033 mDistanceUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1062 mAreaUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1065 mThreadsSpinBox->setRange( 1, QThread::idealThreadCount() );
1077 whileBlocking( mComboInvalidFeatureFiltering )->setCurrentIndex( mComboInvalidFeatureFiltering->findData( QVariant::fromValue( context->
invalidGeometryCheck() ) ) );
1078 whileBlocking( mDistanceUnitsCombo )->setCurrentIndex( mDistanceUnitsCombo->findData( QVariant::fromValue( context->
distanceUnit() ) ) );
1079 whileBlocking( mAreaUnitsCombo )->setCurrentIndex( mAreaUnitsCombo->findData( QVariant::fromValue( context->
areaUnit() ) ) );
1082 whileBlocking( mLogLevelComboBox )->setCurrentIndex( mLogLevelComboBox->findData(
static_cast<int>( context->
logLevel() ) ) );
1095Qgis::AreaUnit QgsProcessingContextOptionsWidget::areaUnit()
const
1100QString QgsProcessingContextOptionsWidget::temporaryFolder()
1102 return mTemporaryFolderWidget->filePath();
1105int QgsProcessingContextOptionsWidget::maximumThreads()
const
1107 return mThreadsSpinBox->value();
1112 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.