18#include <nlohmann/json.hpp>
35#include <QApplication>
37#include <QDesktopServices>
44#include "moc_qgsprocessingalgorithmdialogbase.cpp"
48QgsProcessingAlgorithmDialogFeedback::QgsProcessingAlgorithmDialogFeedback()
52void QgsProcessingAlgorithmDialogFeedback::setProgressText(
const QString &text )
55 emit progressTextChanged( text );
58void QgsProcessingAlgorithmDialogFeedback::reportError(
const QString &error,
bool fatalError )
61 emit errorReported( error, fatalError );
64void QgsProcessingAlgorithmDialogFeedback::pushWarning(
const QString &warning )
67 emit warningPushed( warning );
70void QgsProcessingAlgorithmDialogFeedback::pushInfo(
const QString &info )
73 emit infoPushed( info );
76void QgsProcessingAlgorithmDialogFeedback::pushCommandInfo(
const QString &info )
79 emit commandInfoPushed( info );
82void QgsProcessingAlgorithmDialogFeedback::pushDebugInfo(
const QString &info )
85 emit debugInfoPushed( info );
88void QgsProcessingAlgorithmDialogFeedback::pushConsoleInfo(
const QString &info )
91 emit consoleInfoPushed( info );
94void QgsProcessingAlgorithmDialogFeedback::pushFormattedMessage(
const QString &html,
const QString &text )
97 emit formattedMessagePushed( html );
104QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags, DialogMode mode )
105 : QDialog( parent, flags )
111 splitter->setCollapsible( 0,
false );
114 QSplitterHandle *splitterHandle = splitter->handle( 1 );
115 QVBoxLayout *handleLayout =
new QVBoxLayout();
116 handleLayout->setContentsMargins( 0, 0, 0, 0 );
117 mButtonCollapse =
new QToolButton( splitterHandle );
118 mButtonCollapse->setAutoRaise(
true );
119 mButtonCollapse->setFixedSize( 12, 12 );
120 mButtonCollapse->setCursor( Qt::ArrowCursor );
121 handleLayout->addWidget( mButtonCollapse );
122 handleLayout->addStretch();
123 splitterHandle->setLayout( handleLayout );
127 txtLog->setOpenLinks(
false );
128 connect( txtLog, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmDialogBase::urlClicked );
131 splitter->restoreState( settings.
value( QStringLiteral(
"/Processing/dialogBaseSplitter" ), QByteArray() ).toByteArray() );
132 mSplitterState = splitter->saveState();
133 splitterChanged( 0, 0 );
136 mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
137 mButtonRun->setText( tr(
"Run" ) );
140 mButtonChangeParameters = mButtonBox->button( QDialogButtonBox::Yes );
141 mButtonChangeParameters->setText( tr(
"Change Parameters" ) );
143 buttonCancel->setEnabled(
false );
144 mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
148 case DialogMode::Single:
150 mAdvancedButton =
new QPushButton( tr(
"Advanced" ) );
151 mAdvancedMenu =
new QMenu(
this );
152 mAdvancedButton->setMenu( mAdvancedMenu );
154 mContextSettingsAction =
new QAction( tr(
"Algorithm Settingsā¦" ), mAdvancedMenu );
156 mAdvancedMenu->addAction( mContextSettingsAction );
158 connect( mContextSettingsAction, &QAction::triggered,
this, [
this] {
161 mTabWidget->setCurrentIndex( 0 );
163 if ( !mContextOptionsWidget )
165 mContextOptionsWidget =
new QgsProcessingContextOptionsWidget();
166 mContextOptionsWidget->setFromContext( processingContext() );
167 mContextOptionsWidget->setLogLevel( mLogLevel );
168 panel->openPanel( mContextOptionsWidget );
171 mOverrideDefaultContextSettings =
true;
172 mGeometryCheck = mContextOptionsWidget->invalidGeometryCheck();
173 mDistanceUnits = mContextOptionsWidget->distanceUnit();
174 mAreaUnits = mContextOptionsWidget->areaUnit();
175 mTemporaryFolderOverride = mContextOptionsWidget->temporaryFolder();
176 mMaximumThreads = mContextOptionsWidget->maximumThreads();
177 mLogLevel = mContextOptionsWidget->logLevel();
182 mAdvancedMenu->addSeparator();
184 QAction *copyAsPythonCommand =
new QAction( tr(
"Copy as Python Command" ), mAdvancedMenu );
187 mAdvancedMenu->addAction( copyAsPythonCommand );
188 connect( copyAsPythonCommand, &QAction::triggered,
this, [
this] {
195 const QString command = alg->asPythonCommand( createProcessingParameters(), *context );
196 QMimeData *m =
new QMimeData();
197 m->setText( command );
198 QClipboard *cb = QApplication::clipboard();
201 cb->setMimeData( m, QClipboard::Selection );
203 cb->setMimeData( m, QClipboard::Clipboard );
207 mCopyAsQgisProcessCommand =
new QAction( tr(
"Copy as qgis_process Command" ), mAdvancedMenu );
209 mAdvancedMenu->addAction( mCopyAsQgisProcessCommand );
211 connect( mCopyAsQgisProcessCommand, &QAction::triggered,
this, [
this] {
219 const QString command = alg->asQgisProcessCommand( createProcessingParameters(), *context, ok );
222 mMessageBar->pushMessage( tr(
"Current settings cannot be specified as arguments to qgis_process (Pipe parameters as JSON to qgis_process instead)" ),
Qgis::MessageLevel::Warning );
226 QMimeData *m =
new QMimeData();
227 m->setText( command );
228 QClipboard *cb = QApplication::clipboard();
231 cb->setMimeData( m, QClipboard::Selection );
233 cb->setMimeData( m, QClipboard::Clipboard );
238 mAdvancedMenu->addSeparator();
240 QAction *copyAsJson =
new QAction( tr(
"Copy as JSON" ), mAdvancedMenu );
243 mAdvancedMenu->addAction( copyAsJson );
244 connect( copyAsJson, &QAction::triggered,
this, [
this] {
251 const QVariantMap properties = alg->asMap( createProcessingParameters(), *context );
254 QMimeData *m =
new QMimeData();
256 QClipboard *cb = QApplication::clipboard();
259 cb->setMimeData( m, QClipboard::Selection );
261 cb->setMimeData( m, QClipboard::Clipboard );
265 mPasteJsonAction =
new QAction( tr(
"Paste Settings" ), mAdvancedMenu );
268 mAdvancedMenu->addAction( mPasteJsonAction );
269 connect( mPasteJsonAction, &QAction::triggered,
this, [
this] {
270 const QString text = QApplication::clipboard()->text();
271 if ( text.isEmpty() )
274 const QVariantMap parameterValues =
QgsJsonUtils::parseJson( text ).toMap().value( QStringLiteral(
"inputs" ) ).toMap();
275 if ( parameterValues.isEmpty() )
282 setParameters( preparedValues );
285 mButtonBox->addButton( mAdvancedButton, QDialogButtonBox::ResetRole );
289 case DialogMode::Batch:
295 connect( mAdvancedMenu, &QMenu::aboutToShow,
this, [
this] {
297 mPasteJsonAction->setEnabled( !QApplication::clipboard()->text().isEmpty() );
301 connect( mButtonRun, &QPushButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::runAlgorithm );
302 connect( mButtonChangeParameters, &QPushButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::showParameters );
303 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsProcessingAlgorithmDialogBase::closeClicked );
304 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsProcessingAlgorithmDialogBase::openHelp );
305 connect( mButtonCollapse, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed );
306 connect( splitter, &QSplitter::splitterMoved,
this, &QgsProcessingAlgorithmDialogBase::splitterChanged );
308 connect( mButtonSaveLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::saveLog );
309 connect( mButtonCopyLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::copyLogToClipboard );
310 connect( mButtonClearLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::clearLog );
312 connect( mTabWidget, &QTabWidget::currentChanged,
this, &QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged );
315 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
316 verticalLayout->insertWidget( 0, mMessageBar );
321QgsProcessingAlgorithmDialogBase::~QgsProcessingAlgorithmDialogBase() =
default;
323void QgsProcessingAlgorithmDialogBase::setParameters(
const QVariantMap & )
332 title = mAlgorithm->group().isEmpty()
334 : QStringLiteral(
"%1 - %2" ).arg(
QgsStringUtils::capitalize( mAlgorithm->group(),
Qgis::Capitalization::TitleCase ),
QgsStringUtils::capitalize( mAlgorithm->displayName(),
Qgis::Capitalization::TitleCase ) );
338 title = mAlgorithm->group().isEmpty()
339 ? mAlgorithm->displayName()
340 : QStringLiteral(
"%1 - %2" ).arg( mAlgorithm->group(), mAlgorithm->displayName() );
343 setWindowTitle( title );
345 const QString algHelp = formatHelp(
algorithm );
346 if ( algHelp.isEmpty() )
347 textShortHelp->hide();
350 textShortHelp->document()->setDefaultStyleSheet( QStringLiteral(
".summary { margin-left: 10px; margin-right: 10px; }\n"
351 "h2 { color: #555555; padding-bottom: 15px; }\n"
352 "a { text - decoration: none; color: #3498db; font-weight: bold; }\n"
353 "p, ul, li { color: #666666; }\n"
354 "b { color: #333333; }\n"
355 "dl dd { margin - bottom: 5px; }" ) );
356 textShortHelp->setHtml( algHelp );
357 connect( textShortHelp, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmDialogBase::linkClicked );
358 textShortHelp->show();
363 mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Help ) );
366 const QString warning =
algorithm->provider() ?
algorithm->provider()->warningMessage() : QString();
367 if ( !warning.isEmpty() )
375 return mAlgorithm.get();
378void QgsProcessingAlgorithmDialogBase::setMainWidget(
QgsPanelWidget *widget )
382 mMainWidget->deleteLater();
385 mPanelStack->setMainPanel( widget );
388 mMainWidget = widget;
397void QgsProcessingAlgorithmDialogBase::saveLogToFile(
const QString &path,
const LogFormat format )
399 QFile logFile( path );
400 if ( !logFile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
404 QTextStream fout( &logFile );
408 case FormatPlainText:
409 fout << txtLog->toPlainText();
413 fout << txtLog->toHtml();
420 auto feedback = std::make_unique<QgsProcessingAlgorithmDialogFeedback>();
422 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::commandInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushCommandInfo );
423 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::consoleInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushConsoleInfo );
424 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::debugInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushDebugInfo );
425 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::errorReported,
this, &QgsProcessingAlgorithmDialogBase::reportError );
426 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::warningPushed,
this, &QgsProcessingAlgorithmDialogBase::pushWarning );
427 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::infoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushInfo );
428 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::formattedMessagePushed,
this, &QgsProcessingAlgorithmDialogBase::pushFormattedMessage );
429 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::progressTextChanged,
this, &QgsProcessingAlgorithmDialogBase::setProgressText );
431 return feedback.release();
434QDialogButtonBox *QgsProcessingAlgorithmDialogBase::buttonBox()
439QTabWidget *QgsProcessingAlgorithmDialogBase::tabWidget()
444void QgsProcessingAlgorithmDialogBase::showLog()
446 mTabWidget->setCurrentIndex( 1 );
449void QgsProcessingAlgorithmDialogBase::showParameters()
451 mTabWidget->setCurrentIndex( 0 );
454QPushButton *QgsProcessingAlgorithmDialogBase::runButton()
459QPushButton *QgsProcessingAlgorithmDialogBase::cancelButton()
464QPushButton *QgsProcessingAlgorithmDialogBase::changeParametersButton()
466 return mButtonChangeParameters;
469void QgsProcessingAlgorithmDialogBase::clearProgress()
471 progressBar->setMaximum( 0 );
474void QgsProcessingAlgorithmDialogBase::setExecuted(
bool executed )
476 mExecuted = executed;
479void QgsProcessingAlgorithmDialogBase::setExecutedAnyResult(
bool executedAnyResult )
481 mExecutedAnyResult = executedAnyResult;
484void QgsProcessingAlgorithmDialogBase::setResults(
const QVariantMap &results )
493void QgsProcessingAlgorithmDialogBase::openHelp()
495 QUrl algHelp = mAlgorithm->helpUrl();
496 if ( algHelp.isEmpty() && mAlgorithm->provider() )
498 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().replace(
"_",
"-" ) ) ) );
501 if ( !algHelp.isEmpty() )
502 QDesktopServices::openUrl( algHelp );
505void QgsProcessingAlgorithmDialogBase::toggleCollapsed()
507 if ( mHelpCollapsed )
509 splitter->restoreState( mSplitterState );
510 mButtonCollapse->setArrowType( Qt::RightArrow );
514 mSplitterState = splitter->saveState();
515 splitter->setSizes( QList<int>() << 1 << 0 );
516 mButtonCollapse->setArrowType( Qt::LeftArrow );
518 mHelpCollapsed = !mHelpCollapsed;
521void QgsProcessingAlgorithmDialogBase::splitterChanged(
int,
int )
523 if ( splitter->sizes().at( 1 ) == 0 )
525 mHelpCollapsed =
true;
526 mButtonCollapse->setArrowType( Qt::LeftArrow );
530 mHelpCollapsed =
false;
531 mButtonCollapse->setArrowType( Qt::RightArrow );
535void QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged(
int )
537 updateRunButtonVisibility();
540void QgsProcessingAlgorithmDialogBase::linkClicked(
const QUrl &url )
542 QDesktopServices::openUrl( url.toString() );
545void QgsProcessingAlgorithmDialogBase::algExecuted(
bool successful,
const QVariantMap & )
547 mAlgorithmTask =
nullptr;
554 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
560 if ( isFinalized() && successful )
562 progressBar->setFormat( tr(
"Complete" ) );
566 if ( isFinalized() && !isVisible() )
573void QgsProcessingAlgorithmDialogBase::taskTriggered(
QgsTask *task )
575 if ( task == mAlgorithmTask )
579 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
585void QgsProcessingAlgorithmDialogBase::closeClicked()
591void QgsProcessingAlgorithmDialogBase::urlClicked(
const QUrl &url )
593 const QFileInfo file( url.toLocalFile() );
594 if ( file.exists() && !file.isDir() )
597 QDesktopServices::openUrl( url );
610void QgsProcessingAlgorithmDialogBase::reportError(
const QString &error,
bool fatalError )
612 setInfo( error,
true );
619void QgsProcessingAlgorithmDialogBase::pushWarning(
const QString &warning )
621 setInfo( warning,
false,
true,
true );
625void QgsProcessingAlgorithmDialogBase::pushInfo(
const QString &info )
631void QgsProcessingAlgorithmDialogBase::pushFormattedMessage(
const QString &html )
633 setInfo( html,
false,
false );
637void QgsProcessingAlgorithmDialogBase::pushCommandInfo(
const QString &command )
639 txtLog->append( QStringLiteral(
"<code>%1<code>" ).arg( formatStringForLog( command.toHtmlEscaped() ) ) );
640 scrollToBottomOfLog();
644void QgsProcessingAlgorithmDialogBase::pushDebugInfo(
const QString &message )
646 txtLog->append( QStringLiteral(
"<span style=\"color:#777\">%1</span>" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
647 scrollToBottomOfLog();
651void QgsProcessingAlgorithmDialogBase::pushConsoleInfo(
const QString &info )
653 txtLog->append( QStringLiteral(
"<code style=\"color:#777\">%1</code>" ).arg( formatStringForLog( info.toHtmlEscaped() ) ) );
654 scrollToBottomOfLog();
658QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
660 QgsProcessingAlgorithmProgressDialog *dialog =
new QgsProcessingAlgorithmProgressDialog(
this );
661 dialog->setWindowModality( Qt::ApplicationModal );
662 dialog->setWindowTitle( windowTitle() );
663 dialog->setGeometry( geometry() );
664 connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
665 connect( dialog->cancelButton(), &QPushButton::clicked, buttonCancel, &QPushButton::click );
666 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
667 connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]() {
668 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
669 QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
670 sb->setValue( sb->maximum() );
675void QgsProcessingAlgorithmDialogBase::clearLog()
680void QgsProcessingAlgorithmDialogBase::saveLog()
683 const QString lastUsedDir = settings.
value( QStringLiteral(
"/Processing/lastUsedLogDirectory" ), QDir::homePath() ).toString();
686 const QString txtExt = tr(
"Text files" ) + QStringLiteral(
" (*.txt *.TXT)" );
687 const QString htmlExt = tr(
"HTML files" ) + QStringLiteral(
" (*.html *.HTML)" );
689 const QString path = QFileDialog::getSaveFileName(
this, tr(
"Save Log to File" ), lastUsedDir, txtExt +
";;" + htmlExt, &filter );
693 if ( path.isEmpty() )
698 settings.
setValue( QStringLiteral(
"/Processing/lastUsedLogDirectory" ), QFileInfo( path ).path() );
700 LogFormat format = FormatPlainText;
701 if ( filter == htmlExt )
705 saveLogToFile( path, format );
708void QgsProcessingAlgorithmDialogBase::copyLogToClipboard()
710 QMimeData *m =
new QMimeData();
711 m->setText( txtLog->toPlainText() );
712 m->setHtml( txtLog->toHtml() );
713 QClipboard *cb = QApplication::clipboard();
716 cb->setMimeData( m, QClipboard::Selection );
718 cb->setMimeData( m, QClipboard::Clipboard );
721void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
723 if ( !mHelpCollapsed )
726 settings.
setValue( QStringLiteral(
"/Processing/dialogBaseSplitter" ), splitter->saveState() );
729 QDialog::closeEvent( e );
731 if ( !mAlgorithmTask && isFinalized() )
740void QgsProcessingAlgorithmDialogBase::runAlgorithm()
744void QgsProcessingAlgorithmDialogBase::setPercentage(
double percent )
747 if ( progressBar->maximum() == 0 )
748 progressBar->setMaximum( 100 );
749 progressBar->setValue( percent );
753void QgsProcessingAlgorithmDialogBase::setProgressText(
const QString &text )
755 lblProgress->setText( text );
756 setInfo( text,
false );
757 scrollToBottomOfLog();
764 const QString text =
algorithm->shortHelpString();
765 if ( !text.isEmpty() )
767 const QStringList paragraphs = text.split(
'\n' );
769 for (
const QString ¶graph : paragraphs )
771 help += QStringLiteral(
"<p>%1</p>" ).arg( paragraph );
773 result = QStringLiteral(
"<h2>%1</h2>%2" ).arg(
algorithm->displayName(), help );
775 else if ( !
algorithm->shortDescription().isEmpty() )
777 result = QStringLiteral(
"<h2>%1</h2><p>%2</p>" ).arg(
algorithm->displayName(),
algorithm->shortDescription() );
785 if (
algorithm->documentationFlags() & flag )
790 result += QStringLiteral(
"<ul><li><i>%1</i></li></ul>" ).arg( flags.join( QLatin1String(
"</i></li><li><i>" ) ) );
794 result += QStringLiteral(
"<p><b>%1</b></p>" ).arg( tr(
"Warning: This algorithm is a potential security risk if executed with unchecked inputs, and may result in system damage or data leaks." ) );
798 result += QStringLiteral(
"<p><b>%1</b></p>" ).arg( tr(
"Warning: This algorithm has known issues. The results must be carefully validated by the user." ) );
804void QgsProcessingAlgorithmDialogBase::processEvents()
806 if ( mAlgorithmTask )
822 while ( ++nIters < 100 )
825 QCoreApplication::processEvents();
829void QgsProcessingAlgorithmDialogBase::scrollToBottomOfLog()
831 QScrollBar *sb = txtLog->verticalScrollBar();
832 sb->setValue( sb->maximum() );
835void QgsProcessingAlgorithmDialogBase::resetGui()
837 lblProgress->clear();
838 progressBar->setMaximum( 100 );
839 progressBar->setValue( 0 );
840 mButtonRun->setEnabled(
true );
841 mButtonChangeParameters->setEnabled(
true );
842 mButtonClose->setEnabled(
true );
845 mMainWidget->setEnabled(
true );
847 updateRunButtonVisibility();
848 resetAdditionalGui();
851void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility()
854 const bool runButtonVisible = mTabWidget->currentIndex() == 0;
855 mButtonRun->setVisible( runButtonVisible );
856 if ( runButtonVisible )
857 progressBar->resetFormat();
858 mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult && mButtonChangeParameters->isEnabled() );
861void QgsProcessingAlgorithmDialogBase::resetAdditionalGui()
865void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning()
867 mButtonRun->setEnabled(
false );
868 mButtonChangeParameters->setEnabled(
false );
871 mMainWidget->setEnabled(
false );
873 blockAdditionalControlsWhileRunning();
876void QgsProcessingAlgorithmDialogBase::blockAdditionalControlsWhileRunning()
885void QgsProcessingAlgorithmDialogBase::hideShortHelp()
887 textShortHelp->setVisible(
false );
892 mAlgorithmTask = task;
897QString QgsProcessingAlgorithmDialogBase::formatStringForLog(
const QString &
string )
900 s.replace(
'\n', QLatin1String(
"<br>" ) );
904bool QgsProcessingAlgorithmDialogBase::isFinalized()
916 if ( mOverrideDefaultContextSettings )
926void QgsProcessingAlgorithmDialogBase::setInfo(
const QString &message,
bool isError,
bool escapeHtml,
bool isWarning )
928 constexpr int MESSAGE_COUNT_LIMIT = 10000;
930 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
932 ++mMessageLoggedCount;
936 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
937 txtLog->append( QStringLiteral(
"<span style=\"color:red\">%1</span>" ).arg( tr(
"Message log truncated" ) ) );
938 else if ( isError || isWarning )
939 txtLog->append( QStringLiteral(
"<span style=\"color:%1\">%2</span>" ).arg( isError ? QStringLiteral(
"red" ) : QStringLiteral(
"#b85a20" ), escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
940 else if ( escapeHtml )
941 txtLog->append( QStringLiteral(
"<span>%1</span" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
943 txtLog->append( QStringLiteral(
"<span>%1</span>" ).arg( formatStringForLog( message ) ) );
944 scrollToBottomOfLog();
948void QgsProcessingAlgorithmDialogBase::reject()
950 if ( !mAlgorithmTask && isFinalized() )
952 setAttribute( Qt::WA_DeleteOnClose );
961QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
967QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
972QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
974 return mButtonBox->button( QDialogButtonBox::Cancel );
977QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
982void QgsProcessingAlgorithmProgressDialog::reject()
991QgsProcessingContextOptionsWidget::QgsProcessingContextOptionsWidget( QWidget *parent )
995 setPanelTitle( tr(
"Algorithm Settings" ) );
1001 mTemporaryFolderWidget->setDialogTitle( tr(
"Select Temporary Directory" ) );
1003 mTemporaryFolderWidget->lineEdit()->setPlaceholderText( tr(
"Default" ) );
1034 mDistanceUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1064 mAreaUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1067 mThreadsSpinBox->setRange( 1, QThread::idealThreadCount() );
1079 whileBlocking( mComboInvalidFeatureFiltering )->setCurrentIndex( mComboInvalidFeatureFiltering->findData( QVariant::fromValue( context->
invalidGeometryCheck() ) ) );
1080 whileBlocking( mDistanceUnitsCombo )->setCurrentIndex( mDistanceUnitsCombo->findData( QVariant::fromValue( context->
distanceUnit() ) ) );
1081 whileBlocking( mAreaUnitsCombo )->setCurrentIndex( mAreaUnitsCombo->findData( QVariant::fromValue( context->
areaUnit() ) ) );
1084 whileBlocking( mLogLevelComboBox )->setCurrentIndex( mLogLevelComboBox->findData(
static_cast<int>( context->
logLevel() ) ) );
1097Qgis::AreaUnit QgsProcessingContextOptionsWidget::areaUnit()
const
1102QString QgsProcessingContextOptionsWidget::temporaryFolder()
1104 return mTemporaryFolderWidget->filePath();
1107int QgsProcessingContextOptionsWidget::maximumThreads()
const
1109 return mThreadsSpinBox->value();
1114 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.