18#include <nlohmann/json.hpp>
37#include <QApplication>
39#include <QDesktopServices>
48#include "moc_qgsprocessingalgorithmwidgetbase.cpp"
50using namespace Qt::StringLiterals;
58QgsProcessingFeedbackGenerator::~QgsProcessingFeedbackGenerator()
65QgsProcessingAlgorithmWidgetBase::QgsProcessingAlgorithmWidgetBase(
74 splitter->setCollapsible( 0,
false );
77 QSplitterHandle *splitterHandle = splitter->handle( 1 );
78 QVBoxLayout *handleLayout =
new QVBoxLayout();
79 handleLayout->setContentsMargins( 0, 0, 0, 0 );
80 mButtonCollapse =
new QToolButton( splitterHandle );
81 mButtonCollapse->setAutoRaise(
true );
82 mButtonCollapse->setFixedSize( 12, 12 );
83 mButtonCollapse->setCursor( Qt::ArrowCursor );
84 handleLayout->addWidget( mButtonCollapse );
85 handleLayout->addStretch();
86 splitterHandle->setLayout( handleLayout );
90 txtLog->setOpenLinks(
false );
91 connect( txtLog, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmWidgetBase::urlClicked );
94 splitter->restoreState( settings.
value( u
"/Processing/dialogBaseSplitter"_s, QByteArray() ).toByteArray() );
95 mSplitterState = splitter->saveState();
96 splitterChanged( 0, 0 );
99 mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
100 mButtonRun->setText( tr(
"Run" ) );
103 mButtonChangeParameters = mButtonBox->button( QDialogButtonBox::Yes );
104 mButtonChangeParameters->setText( tr(
"Change Parameters" ) );
106 connect( buttonCancel, &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::cancel );
107 buttonCancel->setEnabled(
false );
108 mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
111 parentWindow = qobject_cast< QMainWindow * >( QApplication::activeWindow() );
113 bool defaultIsDocked =
false;
114 QString dockId = u
"ProcessingAlgorithm"_s;
115 if ( flags.testFlags( QgsProcessingAlgorithmWidgetBase::WidgetFlag::NoDocking ) )
118 dockId = u
"ProcessingAlgorithmNonDockable"_s;
122 dockId = u
"ProcessingAlgorithmForceDocked"_s;
125 mDockableWidgetHelper
126 =
new QgsDockableWidgetHelper( tr(
"Processing" ),
this, parentWindow, dockId, QStringList(), initialState, defaultIsDocked, Qt::DockWidgetArea::RightDockWidgetArea, QgsDockableWidgetHelper::Option::RaiseTab );
127 connect( mDockableWidgetHelper, &QgsDockableWidgetHelper::closed,
this, &QgsProcessingAlgorithmWidgetBase::closeClicked );
131 case QgsProcessingAlgorithmWidgetBase::WidgetMode::Single:
133 mAdvancedButton =
new QPushButton( tr(
"Advanced" ) );
134 mAdvancedMenu =
new QMenu(
this );
135 mAdvancedButton->setMenu( mAdvancedMenu );
137 mContextSettingsAction =
new QAction( tr(
"Algorithm Settingsā¦" ), mAdvancedMenu );
139 mAdvancedMenu->addAction( mContextSettingsAction );
141 connect( mContextSettingsAction, &QAction::triggered,
this, [
this] {
144 mTabWidget->setCurrentIndex( 0 );
146 if ( !mContextOptionsWidget )
148 mContextOptionsWidget =
new QgsProcessingContextOptionsWidget();
149 mContextOptionsWidget->setFromContext( processingContext() );
150 mContextOptionsWidget->setLogLevel( mLogLevel );
151 panel->openPanel( mContextOptionsWidget );
154 mOverrideDefaultContextSettings =
true;
155 mGeometryCheck = mContextOptionsWidget->invalidGeometryCheck();
156 mDistanceUnits = mContextOptionsWidget->distanceUnit();
157 mAreaUnits = mContextOptionsWidget->areaUnit();
158 mTemporaryFolderOverride = mContextOptionsWidget->temporaryFolder();
159 mMaximumThreads = mContextOptionsWidget->maximumThreads();
160 mLogLevel = mContextOptionsWidget->logLevel();
165 mAdvancedMenu->addSeparator();
167 QAction *copyAsPythonCommand =
new QAction( tr(
"Copy as Python Command" ), mAdvancedMenu );
170 mAdvancedMenu->addAction( copyAsPythonCommand );
171 connect( copyAsPythonCommand, &QAction::triggered,
this, [
this] {
178 const QString command = alg->asPythonCommand( createProcessingParameters(), *context );
179 QMimeData *m =
new QMimeData();
180 m->setText( command );
181 QClipboard *cb = QApplication::clipboard();
183 if ( cb->supportsSelection() )
185 cb->setMimeData( m, QClipboard::Selection );
187 cb->setMimeData( m, QClipboard::Clipboard );
191 mCopyAsQgisProcessCommand =
new QAction( tr(
"Copy as qgis_process Command" ), mAdvancedMenu );
193 mAdvancedMenu->addAction( mCopyAsQgisProcessCommand );
195 connect( mCopyAsQgisProcessCommand, &QAction::triggered,
this, [
this] {
203 const QString command = alg->asQgisProcessCommand( createProcessingParameters(), *context, ok );
206 mMessageBar->pushMessage( tr(
"Current settings cannot be specified as arguments to qgis_process (Pipe parameters as JSON to qgis_process instead)" ),
Qgis::MessageLevel::Warning );
210 QMimeData *m =
new QMimeData();
211 m->setText( command );
212 QClipboard *cb = QApplication::clipboard();
214 if ( cb->supportsSelection() )
216 cb->setMimeData( m, QClipboard::Selection );
218 cb->setMimeData( m, QClipboard::Clipboard );
223 mAdvancedMenu->addSeparator();
225 QAction *copyAsJson =
new QAction( tr(
"Copy as JSON" ), mAdvancedMenu );
228 mAdvancedMenu->addAction( copyAsJson );
229 connect( copyAsJson, &QAction::triggered,
this, [
this] {
236 const QVariantMap properties = alg->asMap( createProcessingParameters(), *context );
239 QMimeData *m =
new QMimeData();
241 QClipboard *cb = QApplication::clipboard();
243 if ( cb->supportsSelection() )
245 cb->setMimeData( m, QClipboard::Selection );
247 cb->setMimeData( m, QClipboard::Clipboard );
251 mPasteJsonAction =
new QAction( tr(
"Paste Settings" ), mAdvancedMenu );
254 mAdvancedMenu->addAction( mPasteJsonAction );
255 connect( mPasteJsonAction, &QAction::triggered,
this, [
this] {
256 const QString text = QApplication::clipboard()->text();
257 if ( text.isEmpty() )
261 if ( parameterValues.isEmpty() )
268 setParameters( preparedValues );
271 mButtonBox->addButton( mAdvancedButton, QDialogButtonBox::ResetRole );
275 case QgsProcessingAlgorithmWidgetBase::WidgetMode::Batch:
281 connect( mAdvancedMenu, &QMenu::aboutToShow,
this, [
this] {
283 mPasteJsonAction->setEnabled( !QApplication::clipboard()->text().isEmpty() );
287 connect( mButtonRun, &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::runAlgorithm );
288 connect( mButtonChangeParameters, &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::showParameters );
289 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsProcessingAlgorithmWidgetBase::closeClicked );
290 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsProcessingAlgorithmWidgetBase::openHelp );
291 connect( mButtonCollapse, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::toggleCollapsed );
292 connect( splitter, &QSplitter::splitterMoved,
this, &QgsProcessingAlgorithmWidgetBase::splitterChanged );
294 connect( mButtonSaveLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::saveLog );
295 connect( mButtonCopyLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::copyLogToClipboard );
296 connect( mButtonClearLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::clearLog );
298 connect( mTabWidget, &QTabWidget::currentChanged,
this, &QgsProcessingAlgorithmWidgetBase::mTabWidget_currentChanged );
301 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
302 verticalLayout->insertWidget( 0, mMessageBar );
307QgsProcessingAlgorithmWidgetBase::~QgsProcessingAlgorithmWidgetBase()
309 delete mDockableWidgetHelper;
312void QgsProcessingAlgorithmWidgetBase::setParameters(
const QVariantMap & )
315void QgsProcessingAlgorithmWidgetBase::setTitle(
const QString &title )
317 mDockableWidgetHelper->setWindowTitle( title );
320void QgsProcessingAlgorithmWidgetBase::exec()
326 mDockableWidgetHelper->setSettingKeyDockId( u
"ProcessingAlgorithmNonDockable"_s );
327 mDockableWidgetHelper->toggleDockMode(
false );
328 mDockableWidgetHelper->dialog()->exec();
337 title = mAlgorithm->group().isEmpty()
339 : u
"%1 - %2"_s.arg(
QgsStringUtils::capitalize( mAlgorithm->group(),
Qgis::Capitalization::TitleCase ),
QgsStringUtils::capitalize( mAlgorithm->displayName(),
Qgis::Capitalization::TitleCase ) );
343 title = mAlgorithm->group().isEmpty() ? mAlgorithm->displayName() : u
"%1 - %2"_s.arg( mAlgorithm->group(), mAlgorithm->displayName() );
345 mDockableWidgetHelper->setWindowTitle( title );
347 const QString algHelp = formatHelp(
algorithm );
348 if ( algHelp.isEmpty() )
349 textShortHelp->hide();
352 textShortHelp->document()->setDefaultStyleSheet( QStringLiteral(
353 ".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; }"
360 textShortHelp->setHtml( algHelp );
361 connect( textShortHelp, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmWidgetBase::linkClicked );
362 textShortHelp->show();
367 mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Help ) );
370 const QString warning =
algorithm->provider() ?
algorithm->provider()->warningMessage() : QString();
371 if ( !warning.isEmpty() )
379 return mAlgorithm.get();
382void QgsProcessingAlgorithmWidgetBase::setMainWidget(
QgsPanelWidget *widget )
386 mMainWidget->deleteLater();
389 mPanelStack->setMainPanel( widget );
392 mMainWidget = widget;
401void QgsProcessingAlgorithmWidgetBase::saveLogToFile(
const QString &path,
const LogFormat format )
403 QFile logFile( path );
404 if ( !logFile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
408 QTextStream fout( &logFile );
412 case QgsProcessingAlgorithmWidgetBase::LogFormat::FormatPlainText:
413 fout << txtLog->toPlainText();
416 case QgsProcessingAlgorithmWidgetBase::LogFormat::FormatHtml:
417 fout << txtLog->toHtml();
422void QgsProcessingAlgorithmWidgetBase::registerProcessingFeedbackGenerator( QgsProcessingFeedbackGenerator *factory )
424 mFeedbackFactory = factory;
429 std::unique_ptr< QgsProcessingFeedback > feedback;
430 if ( mFeedbackFactory )
432 feedback.reset( mFeedbackFactory->createFeedback() );
436 feedback = std::make_unique< QgsProcessingFeedback >();
448 return feedback.release();
451QDialogButtonBox *QgsProcessingAlgorithmWidgetBase::buttonBox()
456QTabWidget *QgsProcessingAlgorithmWidgetBase::tabWidget()
461void QgsProcessingAlgorithmWidgetBase::showLog()
463 mTabWidget->setCurrentIndex( 1 );
466void QgsProcessingAlgorithmWidgetBase::showParameters()
468 mTabWidget->setCurrentIndex( 0 );
471QPushButton *QgsProcessingAlgorithmWidgetBase::runButton()
476QPushButton *QgsProcessingAlgorithmWidgetBase::cancelButton()
481QPushButton *QgsProcessingAlgorithmWidgetBase::changeParametersButton()
483 return mButtonChangeParameters;
486void QgsProcessingAlgorithmWidgetBase::clearProgress()
488 progressBar->setMaximum( 0 );
491void QgsProcessingAlgorithmWidgetBase::setExecuted(
bool executed )
493 mExecuted = executed;
496void QgsProcessingAlgorithmWidgetBase::setExecutedAnyResult(
bool executedAnyResult )
498 mExecutedAnyResult = executedAnyResult;
501void QgsProcessingAlgorithmWidgetBase::setResults(
const QVariantMap &results )
509void QgsProcessingAlgorithmWidgetBase::openHelp()
511 QUrl algHelp = mAlgorithm->helpUrl();
512 if ( algHelp.isEmpty() && mAlgorithm->provider() && !mAlgorithm->provider()->helpId().isEmpty() )
515 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(
"_",
"-" ) ) )
519 if ( !algHelp.isEmpty() )
520 QDesktopServices::openUrl( algHelp );
523void QgsProcessingAlgorithmWidgetBase::toggleCollapsed()
525 if ( mHelpCollapsed )
527 splitter->restoreState( mSplitterState );
528 mButtonCollapse->setArrowType( Qt::RightArrow );
532 mSplitterState = splitter->saveState();
533 splitter->setSizes( QList<int>() << 1 << 0 );
534 mButtonCollapse->setArrowType( Qt::LeftArrow );
536 mHelpCollapsed = !mHelpCollapsed;
539void QgsProcessingAlgorithmWidgetBase::splitterChanged(
int,
int )
541 if ( splitter->sizes().at( 1 ) == 0 )
543 mHelpCollapsed =
true;
544 mButtonCollapse->setArrowType( Qt::LeftArrow );
548 mHelpCollapsed =
false;
549 mButtonCollapse->setArrowType( Qt::RightArrow );
553void QgsProcessingAlgorithmWidgetBase::mTabWidget_currentChanged(
int )
555 updateRunButtonVisibility();
558void QgsProcessingAlgorithmWidgetBase::linkClicked(
const QUrl &url )
560 if ( url.toString() ==
"#help"_L1 )
566 QDesktopServices::openUrl( url.toString() );
569void QgsProcessingAlgorithmWidgetBase::algExecuted(
bool successful,
const QVariantMap & )
571 mAlgorithmTask =
nullptr;
581 if ( isFinalized() && successful )
583 progressBar->setFormat( tr(
"Complete" ) );
587 if ( isFinalized() && !isVisible() )
594void QgsProcessingAlgorithmWidgetBase::taskTriggered(
QgsTask *task )
596 if ( task == mAlgorithmTask )
603void QgsProcessingAlgorithmWidgetBase::showWidget()
605 mDockableWidgetHelper->setUserVisible(
true );
608void QgsProcessingAlgorithmWidgetBase::closeClicked()
610 disconnect( mDockableWidgetHelper, &QgsDockableWidgetHelper::closed,
this, &QgsProcessingAlgorithmWidgetBase::closeClicked );
614 mDockableWidgetHelper->setUserVisible(
false );
623void QgsProcessingAlgorithmWidgetBase::urlClicked(
const QUrl &url )
625 const QFileInfo file( url.toLocalFile() );
626 if ( file.exists() && !file.isDir() )
629 QDesktopServices::openUrl( url );
642void QgsProcessingAlgorithmWidgetBase::reportError(
const QString &error,
bool fatalError )
644 setInfo( error,
true );
651void QgsProcessingAlgorithmWidgetBase::pushWarning(
const QString &warning )
653 setInfo( warning,
false,
true,
true );
657void QgsProcessingAlgorithmWidgetBase::pushInfo(
const QString &info )
663void QgsProcessingAlgorithmWidgetBase::pushFormattedMessage(
const QString &html )
665 setInfo( html,
false,
false );
669void QgsProcessingAlgorithmWidgetBase::pushCommandInfo(
const QString &command )
671 txtLog->append( u
"<code>%1<code>"_s.arg( formatStringForLog( command.toHtmlEscaped() ) ) );
672 scrollToBottomOfLog();
676void QgsProcessingAlgorithmWidgetBase::pushDebugInfo(
const QString &message )
678 txtLog->append( u
"<span style=\"color:#777\">%1</span>"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
679 scrollToBottomOfLog();
683void QgsProcessingAlgorithmWidgetBase::pushConsoleInfo(
const QString &info )
685 txtLog->append( u
"<code style=\"color:#777\">%1</code>"_s.arg( formatStringForLog( info.toHtmlEscaped() ) ) );
686 scrollToBottomOfLog();
690QDialog *QgsProcessingAlgorithmWidgetBase::createProgressDialog()
692 QgsProcessingAlgorithmProgressDialog *dialog =
new QgsProcessingAlgorithmProgressDialog(
this );
693 dialog->setWindowModality( Qt::ApplicationModal );
694 dialog->setWindowTitle( windowTitle() );
695 dialog->setGeometry( geometry() );
696 connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
697 connect( dialog->cancelButton(), &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::cancel );
698 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
699 connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]() {
700 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
701 QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
702 sb->setValue( sb->maximum() );
707void QgsProcessingAlgorithmWidgetBase::clearLog()
712void QgsProcessingAlgorithmWidgetBase::saveLog()
715 const QString lastUsedDir = settings.
value( u
"/Processing/lastUsedLogDirectory"_s, QDir::homePath() ).toString();
718 const QString txtExt = tr(
"Text files" ) + u
" (*.txt *.TXT)"_s;
719 const QString htmlExt = tr(
"HTML files" ) + u
" (*.html *.HTML)"_s;
721 const QString path = QFileDialog::getSaveFileName(
this, tr(
"Save Log to File" ), lastUsedDir, txtExt +
";;" + htmlExt, &filter );
725 if ( path.isEmpty() )
730 settings.
setValue( u
"/Processing/lastUsedLogDirectory"_s, QFileInfo( path ).path() );
732 LogFormat format = QgsProcessingAlgorithmWidgetBase::LogFormat::FormatPlainText;
733 if ( filter == htmlExt )
735 format = QgsProcessingAlgorithmWidgetBase::LogFormat::FormatHtml;
737 saveLogToFile( path, format );
740void QgsProcessingAlgorithmWidgetBase::copyLogToClipboard()
742 QMimeData *m =
new QMimeData();
743 m->setText( txtLog->toPlainText() );
744 m->setHtml( txtLog->toHtml() );
745 QClipboard *cb = QApplication::clipboard();
747 if ( cb->supportsSelection() )
749 cb->setMimeData( m, QClipboard::Selection );
751 cb->setMimeData( m, QClipboard::Clipboard );
754void QgsProcessingAlgorithmWidgetBase::closeEvent( QCloseEvent *e )
756 if ( !mHelpCollapsed )
759 settings.
setValue( u
"/Processing/dialogBaseSplitter"_s, splitter->saveState() );
762 QWidget::closeEvent( e );
764 if ( !mAlgorithmTask && isFinalized() )
773void QgsProcessingAlgorithmWidgetBase::runAlgorithm()
776void QgsProcessingAlgorithmWidgetBase::setPercentage(
double percent )
779 if ( progressBar->maximum() == 0 )
780 progressBar->setMaximum( 100 );
781 progressBar->setValue( percent );
785void QgsProcessingAlgorithmWidgetBase::setProgressText(
const QString &text )
787 lblProgress->setText( text );
788 setInfo( text,
false );
789 scrollToBottomOfLog();
796 const QString text =
algorithm->shortHelpString();
797 if ( !text.isEmpty() )
799 const QStringList paragraphs = text.split(
'\n' );
801 for (
const QString ¶graph : paragraphs )
803 help += u
"<p>%1</p>"_s.arg( paragraph );
805 result = u
"<h2>%1</h2>%2"_s.arg(
algorithm->displayName(), help );
807 else if ( !
algorithm->shortDescription().isEmpty() )
809 result = u
"<h2>%1</h2><p>%2</p>"_s.arg(
algorithm->displayName(),
algorithm->shortDescription() );
812 const QList< QgsAcademicReference > references =
algorithm->academicReferences();
813 if ( !references.empty() )
815 QStringList referenceStrings;
818 referenceStrings << reference.asHtml();
820 result += u
"<h4>%1</h4>"_s.arg( tr(
"References" ) );
821 result += u
"<ul><li>%1</li></ul>"_s.arg( referenceStrings.join(
"</li><li>"_L1 ) );
829 if (
algorithm->documentationFlags() & flag )
834 result += u
"<ul><li><i>%1</i></li></ul>"_s.arg( flags.join(
"</i></li><li><i>"_L1 ) );
838 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." ) );
842 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." ) );
850 const QString linkHtml = QStringLiteral( R
"(<a href="#help">%1</a>)" ).arg( tr( "Algorithm documentation" ) );
854 const QString implementationSourceUri =
algorithm->implementationSourceUri();
855 if ( !implementationSourceUri.isEmpty() )
857 const QString linkHtml = QStringLiteral( R
"(<a href="%1">%2</a>)" ).arg( implementationSourceUri, tr( "Algorithm source code" ) );
861 if ( !links.empty() )
863 result += u
"<h4>%1</h4>"_s.arg( tr(
"Links" ) );
864 result += u
"<ul><li>%1</li></ul>"_s.arg( links.join(
"</li><li>"_L1 ) );
870void QgsProcessingAlgorithmWidgetBase::processEvents()
872 if ( mAlgorithmTask )
888 while ( ++nIters < 100 )
891 QCoreApplication::processEvents();
895void QgsProcessingAlgorithmWidgetBase::scrollToBottomOfLog()
897 QScrollBar *sb = txtLog->verticalScrollBar();
898 sb->setValue( sb->maximum() );
901void QgsProcessingAlgorithmWidgetBase::resetGui()
903 lblProgress->clear();
904 progressBar->setMaximum( 100 );
905 progressBar->setValue( 0 );
906 mButtonRun->setEnabled(
true );
907 mButtonChangeParameters->setEnabled(
true );
908 mButtonClose->setEnabled(
true );
911 mMainWidget->setEnabled(
true );
913 updateRunButtonVisibility();
914 resetAdditionalGui();
917void QgsProcessingAlgorithmWidgetBase::updateRunButtonVisibility()
920 const bool runButtonVisible = mTabWidget->currentIndex() == 0;
921 mButtonRun->setVisible( runButtonVisible );
922 if ( runButtonVisible )
923 progressBar->resetFormat();
924 mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult && mButtonChangeParameters->isEnabled() );
927void QgsProcessingAlgorithmWidgetBase::resetAdditionalGui()
930void QgsProcessingAlgorithmWidgetBase::blockControlsWhileRunning()
932 mButtonRun->setEnabled(
false );
933 mButtonChangeParameters->setEnabled(
false );
936 mMainWidget->setEnabled(
false );
938 blockAdditionalControlsWhileRunning();
941void QgsProcessingAlgorithmWidgetBase::blockAdditionalControlsWhileRunning()
949void QgsProcessingAlgorithmWidgetBase::hideShortHelp()
951 textShortHelp->setVisible(
false );
956 mAlgorithmTask = task;
961void QgsProcessingAlgorithmWidgetBase::disconnectCurrentTask()
963 if ( mAlgorithmTask )
966 mAlgorithmTask =
nullptr;
970QString QgsProcessingAlgorithmWidgetBase::formatStringForLog(
const QString &
string )
973 s.replace(
'\n',
"<br>"_L1 );
977bool QgsProcessingAlgorithmWidgetBase::isFinalized()
982bool QgsProcessingAlgorithmWidgetBase::isRunning()
987void QgsProcessingAlgorithmWidgetBase::cancel()
989 emit cancelRequested();
999 if ( mOverrideDefaultContextSettings )
1009void QgsProcessingAlgorithmWidgetBase::setInfo(
const QString &message,
bool isError,
bool escapeHtml,
bool isWarning )
1011 constexpr int MESSAGE_COUNT_LIMIT = 10000;
1013 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
1015 ++mMessageLoggedCount;
1019 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
1020 txtLog->append( u
"<span style=\"color:red\">%1</span>"_s.arg( tr(
"Message log truncated" ) ) );
1021 else if ( isError || isWarning )
1022 txtLog->append( u
"<span style=\"color:%1\">%2</span>"_s.arg( isError ? u
"red"_s : u
"#b85a20"_s, escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
1023 else if ( escapeHtml )
1024 txtLog->append( u
"<span>%1</span"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
1026 txtLog->append( u
"<span>%1</span>"_s.arg( formatStringForLog( message ) ) );
1027 scrollToBottomOfLog();
1031void QgsProcessingAlgorithmWidgetBase::reject()
1033 if ( !mAlgorithmTask && isFinalized() )
1035 setAttribute( Qt::WA_DeleteOnClose );
1038 mDockableWidgetHelper->reject();
1041void QgsProcessingAlgorithmWidgetBase::forceClose()
1043 disconnectCurrentTask();
1051QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
1057QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
1059 return mProgressBar;
1062QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
1064 return mButtonBox->button( QDialogButtonBox::Cancel );
1067QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
1072void QgsProcessingAlgorithmProgressDialog::reject()
1080QgsProcessingContextOptionsWidget::QgsProcessingContextOptionsWidget( QWidget *parent )
1084 setPanelTitle( tr(
"Algorithm Settings" ) );
1090 mTemporaryFolderWidget->setDialogTitle( tr(
"Select Temporary Directory" ) );
1092 mTemporaryFolderWidget->lineEdit()->setPlaceholderText( tr(
"Default" ) );
1122 mDistanceUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1151 mAreaUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1154 mThreadsSpinBox->setRange( 1, QThread::idealThreadCount() );
1166 whileBlocking( mComboInvalidFeatureFiltering )->setCurrentIndex( mComboInvalidFeatureFiltering->findData( QVariant::fromValue( context->
invalidGeometryCheck() ) ) );
1167 whileBlocking( mDistanceUnitsCombo )->setCurrentIndex( mDistanceUnitsCombo->findData( QVariant::fromValue( context->
distanceUnit() ) ) );
1168 whileBlocking( mAreaUnitsCombo )->setCurrentIndex( mAreaUnitsCombo->findData( QVariant::fromValue( context->
areaUnit() ) ) );
1171 whileBlocking( mLogLevelComboBox )->setCurrentIndex( mLogLevelComboBox->findData(
static_cast<int>( context->
logLevel() ) ) );
1184Qgis::AreaUnit QgsProcessingContextOptionsWidget::areaUnit()
const
1189QString QgsProcessingContextOptionsWidget::temporaryFolder()
1191 return mTemporaryFolderWidget->filePath();
1194int QgsProcessingContextOptionsWidget::maximumThreads()
const
1196 return mThreadsSpinBox->value();
1201 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.
DockableWidgetInitialState
Dockable widget initial states.
@ ForceDocked
Force the widget to be docked.
@ ForceDialog
Force the widget to be shown in a dialog.
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.
Encapsulates an academic reference and formats it according to style guidelines.
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.
void warningPushed(const QString &text)
Emitted when an warning is pushed.
void infoPushed(const QString &text)
Emitted when information text is pushed.
void errorReported(const QString &text, bool fatalError)
Emitted when an error is reported.
void progressTextChanged(const QString &text)
Emitted when the progress text is changed.
void debugInfoPushed(const QString &text)
Emitted when debug information text is pushed.
void formattedMessagePushed(const QString &html)
Emitted when a formatted html message is pushed.
void commandInfoPushed(const QString &text)
Emitted when command information text is pushed.
void consoleInfoPushed(const QString &text)
Emitted when console information text is pushed.
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.