18#include <nlohmann/json.hpp>
36#include <QApplication>
38#include <QDesktopServices>
47#include "moc_qgsprocessingalgorithmwidgetbase.cpp"
49using namespace Qt::StringLiterals;
57QgsProcessingFeedbackGenerator::~QgsProcessingFeedbackGenerator()
64QgsProcessingAlgorithmWidgetBase::QgsProcessingAlgorithmWidgetBase(
73 splitter->setCollapsible( 0,
false );
76 QSplitterHandle *splitterHandle = splitter->handle( 1 );
77 QVBoxLayout *handleLayout =
new QVBoxLayout();
78 handleLayout->setContentsMargins( 0, 0, 0, 0 );
79 mButtonCollapse =
new QToolButton( splitterHandle );
80 mButtonCollapse->setAutoRaise(
true );
81 mButtonCollapse->setFixedSize( 12, 12 );
82 mButtonCollapse->setCursor( Qt::ArrowCursor );
83 handleLayout->addWidget( mButtonCollapse );
84 handleLayout->addStretch();
85 splitterHandle->setLayout( handleLayout );
89 txtLog->setOpenLinks(
false );
90 connect( txtLog, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmWidgetBase::urlClicked );
93 splitter->restoreState( settings.
value( u
"/Processing/dialogBaseSplitter"_s, QByteArray() ).toByteArray() );
94 mSplitterState = splitter->saveState();
95 splitterChanged( 0, 0 );
98 mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
99 mButtonRun->setText( tr(
"Run" ) );
102 mButtonChangeParameters = mButtonBox->button( QDialogButtonBox::Yes );
103 mButtonChangeParameters->setText( tr(
"Change Parameters" ) );
105 connect( buttonCancel, &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::cancel );
106 buttonCancel->setEnabled(
false );
107 mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
110 parentWindow = qobject_cast< QMainWindow * >( QApplication::activeWindow() );
112 bool defaultIsDocked =
false;
113 QString dockId = u
"ProcessingAlgorithm"_s;
114 if ( flags.testFlags( QgsProcessingAlgorithmWidgetBase::WidgetFlag::NoDocking ) )
117 dockId = u
"ProcessingAlgorithmNonDockable"_s;
121 dockId = u
"ProcessingAlgorithmForceDocked"_s;
124 mDockableWidgetHelper
125 =
new QgsDockableWidgetHelper( tr(
"Processing" ),
this, parentWindow, dockId, QStringList(), initialState, defaultIsDocked, Qt::DockWidgetArea::RightDockWidgetArea, QgsDockableWidgetHelper::Option::RaiseTab );
126 connect( mDockableWidgetHelper, &QgsDockableWidgetHelper::closed,
this, &QgsProcessingAlgorithmWidgetBase::closeClicked );
130 case QgsProcessingAlgorithmWidgetBase::WidgetMode::Single:
132 mAdvancedButton =
new QPushButton( tr(
"Advanced" ) );
133 mAdvancedMenu =
new QMenu(
this );
134 mAdvancedButton->setMenu( mAdvancedMenu );
136 mContextSettingsAction =
new QAction( tr(
"Algorithm Settingsā¦" ), mAdvancedMenu );
138 mAdvancedMenu->addAction( mContextSettingsAction );
140 connect( mContextSettingsAction, &QAction::triggered,
this, [
this] {
143 mTabWidget->setCurrentIndex( 0 );
145 if ( !mContextOptionsWidget )
147 mContextOptionsWidget =
new QgsProcessingContextOptionsWidget();
148 mContextOptionsWidget->setFromContext( processingContext() );
149 mContextOptionsWidget->setLogLevel( mLogLevel );
150 panel->openPanel( mContextOptionsWidget );
153 mOverrideDefaultContextSettings =
true;
154 mGeometryCheck = mContextOptionsWidget->invalidGeometryCheck();
155 mDistanceUnits = mContextOptionsWidget->distanceUnit();
156 mAreaUnits = mContextOptionsWidget->areaUnit();
157 mTemporaryFolderOverride = mContextOptionsWidget->temporaryFolder();
158 mMaximumThreads = mContextOptionsWidget->maximumThreads();
159 mLogLevel = mContextOptionsWidget->logLevel();
164 mAdvancedMenu->addSeparator();
166 QAction *copyAsPythonCommand =
new QAction( tr(
"Copy as Python Command" ), mAdvancedMenu );
169 mAdvancedMenu->addAction( copyAsPythonCommand );
170 connect( copyAsPythonCommand, &QAction::triggered,
this, [
this] {
177 const QString command = alg->asPythonCommand( createProcessingParameters(), *context );
178 QMimeData *m =
new QMimeData();
179 m->setText( command );
180 QClipboard *cb = QApplication::clipboard();
183 cb->setMimeData( m, QClipboard::Selection );
185 cb->setMimeData( m, QClipboard::Clipboard );
189 mCopyAsQgisProcessCommand =
new QAction( tr(
"Copy as qgis_process Command" ), mAdvancedMenu );
191 mAdvancedMenu->addAction( mCopyAsQgisProcessCommand );
193 connect( mCopyAsQgisProcessCommand, &QAction::triggered,
this, [
this] {
201 const QString command = alg->asQgisProcessCommand( createProcessingParameters(), *context, ok );
204 mMessageBar->pushMessage( tr(
"Current settings cannot be specified as arguments to qgis_process (Pipe parameters as JSON to qgis_process instead)" ),
Qgis::MessageLevel::Warning );
208 QMimeData *m =
new QMimeData();
209 m->setText( command );
210 QClipboard *cb = QApplication::clipboard();
213 cb->setMimeData( m, QClipboard::Selection );
215 cb->setMimeData( m, QClipboard::Clipboard );
220 mAdvancedMenu->addSeparator();
222 QAction *copyAsJson =
new QAction( tr(
"Copy as JSON" ), mAdvancedMenu );
225 mAdvancedMenu->addAction( copyAsJson );
226 connect( copyAsJson, &QAction::triggered,
this, [
this] {
233 const QVariantMap properties = alg->asMap( createProcessingParameters(), *context );
236 QMimeData *m =
new QMimeData();
238 QClipboard *cb = QApplication::clipboard();
241 cb->setMimeData( m, QClipboard::Selection );
243 cb->setMimeData( m, QClipboard::Clipboard );
247 mPasteJsonAction =
new QAction( tr(
"Paste Settings" ), mAdvancedMenu );
250 mAdvancedMenu->addAction( mPasteJsonAction );
251 connect( mPasteJsonAction, &QAction::triggered,
this, [
this] {
252 const QString text = QApplication::clipboard()->text();
253 if ( text.isEmpty() )
257 if ( parameterValues.isEmpty() )
264 setParameters( preparedValues );
267 mButtonBox->addButton( mAdvancedButton, QDialogButtonBox::ResetRole );
271 case QgsProcessingAlgorithmWidgetBase::WidgetMode::Batch:
277 connect( mAdvancedMenu, &QMenu::aboutToShow,
this, [
this] {
279 mPasteJsonAction->setEnabled( !QApplication::clipboard()->text().isEmpty() );
283 connect( mButtonRun, &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::runAlgorithm );
284 connect( mButtonChangeParameters, &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::showParameters );
285 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsProcessingAlgorithmWidgetBase::closeClicked );
286 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsProcessingAlgorithmWidgetBase::openHelp );
287 connect( mButtonCollapse, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::toggleCollapsed );
288 connect( splitter, &QSplitter::splitterMoved,
this, &QgsProcessingAlgorithmWidgetBase::splitterChanged );
290 connect( mButtonSaveLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::saveLog );
291 connect( mButtonCopyLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::copyLogToClipboard );
292 connect( mButtonClearLog, &QToolButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::clearLog );
294 connect( mTabWidget, &QTabWidget::currentChanged,
this, &QgsProcessingAlgorithmWidgetBase::mTabWidget_currentChanged );
297 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
298 verticalLayout->insertWidget( 0, mMessageBar );
303QgsProcessingAlgorithmWidgetBase::~QgsProcessingAlgorithmWidgetBase()
305 delete mDockableWidgetHelper;
308void QgsProcessingAlgorithmWidgetBase::setParameters(
const QVariantMap & )
311void QgsProcessingAlgorithmWidgetBase::setTitle(
const QString &title )
313 mDockableWidgetHelper->setWindowTitle( title );
316void QgsProcessingAlgorithmWidgetBase::exec()
322 mDockableWidgetHelper->setSettingKeyDockId( u
"ProcessingAlgorithmNonDockable"_s );
323 mDockableWidgetHelper->toggleDockMode(
false );
324 mDockableWidgetHelper->dialog()->exec();
333 title = mAlgorithm->group().isEmpty()
335 : u
"%1 - %2"_s.arg(
QgsStringUtils::capitalize( mAlgorithm->group(),
Qgis::Capitalization::TitleCase ),
QgsStringUtils::capitalize( mAlgorithm->displayName(),
Qgis::Capitalization::TitleCase ) );
339 title = mAlgorithm->group().isEmpty() ? mAlgorithm->displayName() : u
"%1 - %2"_s.arg( mAlgorithm->group(), mAlgorithm->displayName() );
341 mDockableWidgetHelper->setWindowTitle( title );
343 const QString algHelp = formatHelp(
algorithm );
344 if ( algHelp.isEmpty() )
345 textShortHelp->hide();
348 textShortHelp->document()->setDefaultStyleSheet( QStringLiteral(
349 ".summary { margin-left: 10px; margin-right: 10px; }\n"
350 "h2 { color: #555555; padding-bottom: 15px; }\n"
351 "a { text - decoration: none; color: #3498db; font-weight: bold; }\n"
352 "p, ul, li { color: #666666; }\n"
353 "b { color: #333333; }\n"
354 "dl dd { margin - bottom: 5px; }"
356 textShortHelp->setHtml( algHelp );
357 connect( textShortHelp, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmWidgetBase::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 QgsProcessingAlgorithmWidgetBase::setMainWidget(
QgsPanelWidget *widget )
382 mMainWidget->deleteLater();
385 mPanelStack->setMainPanel( widget );
388 mMainWidget = widget;
397void QgsProcessingAlgorithmWidgetBase::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 QgsProcessingAlgorithmWidgetBase::LogFormat::FormatPlainText:
409 fout << txtLog->toPlainText();
412 case QgsProcessingAlgorithmWidgetBase::LogFormat::FormatHtml:
413 fout << txtLog->toHtml();
418void QgsProcessingAlgorithmWidgetBase::registerProcessingFeedbackGenerator( QgsProcessingFeedbackGenerator *factory )
420 mFeedbackFactory = factory;
425 std::unique_ptr< QgsProcessingFeedback > feedback;
426 if ( mFeedbackFactory )
428 feedback.reset( mFeedbackFactory->createFeedback() );
432 feedback = std::make_unique< QgsProcessingFeedback >();
444 return feedback.release();
447QDialogButtonBox *QgsProcessingAlgorithmWidgetBase::buttonBox()
452QTabWidget *QgsProcessingAlgorithmWidgetBase::tabWidget()
457void QgsProcessingAlgorithmWidgetBase::showLog()
459 mTabWidget->setCurrentIndex( 1 );
462void QgsProcessingAlgorithmWidgetBase::showParameters()
464 mTabWidget->setCurrentIndex( 0 );
467QPushButton *QgsProcessingAlgorithmWidgetBase::runButton()
472QPushButton *QgsProcessingAlgorithmWidgetBase::cancelButton()
477QPushButton *QgsProcessingAlgorithmWidgetBase::changeParametersButton()
479 return mButtonChangeParameters;
482void QgsProcessingAlgorithmWidgetBase::clearProgress()
484 progressBar->setMaximum( 0 );
487void QgsProcessingAlgorithmWidgetBase::setExecuted(
bool executed )
489 mExecuted = executed;
492void QgsProcessingAlgorithmWidgetBase::setExecutedAnyResult(
bool executedAnyResult )
494 mExecutedAnyResult = executedAnyResult;
497void QgsProcessingAlgorithmWidgetBase::setResults(
const QVariantMap &results )
505void QgsProcessingAlgorithmWidgetBase::openHelp()
507 QUrl algHelp = mAlgorithm->helpUrl();
508 if ( algHelp.isEmpty() && mAlgorithm->provider() )
511 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(
"_",
"-" ) ) )
515 if ( !algHelp.isEmpty() )
516 QDesktopServices::openUrl( algHelp );
519void QgsProcessingAlgorithmWidgetBase::toggleCollapsed()
521 if ( mHelpCollapsed )
523 splitter->restoreState( mSplitterState );
524 mButtonCollapse->setArrowType( Qt::RightArrow );
528 mSplitterState = splitter->saveState();
529 splitter->setSizes( QList<int>() << 1 << 0 );
530 mButtonCollapse->setArrowType( Qt::LeftArrow );
532 mHelpCollapsed = !mHelpCollapsed;
535void QgsProcessingAlgorithmWidgetBase::splitterChanged(
int,
int )
537 if ( splitter->sizes().at( 1 ) == 0 )
539 mHelpCollapsed =
true;
540 mButtonCollapse->setArrowType( Qt::LeftArrow );
544 mHelpCollapsed =
false;
545 mButtonCollapse->setArrowType( Qt::RightArrow );
549void QgsProcessingAlgorithmWidgetBase::mTabWidget_currentChanged(
int )
551 updateRunButtonVisibility();
554void QgsProcessingAlgorithmWidgetBase::linkClicked(
const QUrl &url )
556 QDesktopServices::openUrl( url.toString() );
559void QgsProcessingAlgorithmWidgetBase::algExecuted(
bool successful,
const QVariantMap & )
561 mAlgorithmTask =
nullptr;
571 if ( isFinalized() && successful )
573 progressBar->setFormat( tr(
"Complete" ) );
577 if ( isFinalized() && !isVisible() )
584void QgsProcessingAlgorithmWidgetBase::taskTriggered(
QgsTask *task )
586 if ( task == mAlgorithmTask )
593void QgsProcessingAlgorithmWidgetBase::showWidget()
595 mDockableWidgetHelper->setUserVisible(
true );
598void QgsProcessingAlgorithmWidgetBase::closeClicked()
600 disconnect( mDockableWidgetHelper, &QgsDockableWidgetHelper::closed,
this, &QgsProcessingAlgorithmWidgetBase::closeClicked );
604 mDockableWidgetHelper->setUserVisible(
false );
613void QgsProcessingAlgorithmWidgetBase::urlClicked(
const QUrl &url )
615 const QFileInfo file( url.toLocalFile() );
616 if ( file.exists() && !file.isDir() )
619 QDesktopServices::openUrl( url );
632void QgsProcessingAlgorithmWidgetBase::reportError(
const QString &error,
bool fatalError )
634 setInfo( error,
true );
641void QgsProcessingAlgorithmWidgetBase::pushWarning(
const QString &warning )
643 setInfo( warning,
false,
true,
true );
647void QgsProcessingAlgorithmWidgetBase::pushInfo(
const QString &info )
653void QgsProcessingAlgorithmWidgetBase::pushFormattedMessage(
const QString &html )
655 setInfo( html,
false,
false );
659void QgsProcessingAlgorithmWidgetBase::pushCommandInfo(
const QString &command )
661 txtLog->append( u
"<code>%1<code>"_s.arg( formatStringForLog( command.toHtmlEscaped() ) ) );
662 scrollToBottomOfLog();
666void QgsProcessingAlgorithmWidgetBase::pushDebugInfo(
const QString &message )
668 txtLog->append( u
"<span style=\"color:#777\">%1</span>"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
669 scrollToBottomOfLog();
673void QgsProcessingAlgorithmWidgetBase::pushConsoleInfo(
const QString &info )
675 txtLog->append( u
"<code style=\"color:#777\">%1</code>"_s.arg( formatStringForLog( info.toHtmlEscaped() ) ) );
676 scrollToBottomOfLog();
680QDialog *QgsProcessingAlgorithmWidgetBase::createProgressDialog()
682 QgsProcessingAlgorithmProgressDialog *dialog =
new QgsProcessingAlgorithmProgressDialog(
this );
683 dialog->setWindowModality( Qt::ApplicationModal );
684 dialog->setWindowTitle( windowTitle() );
685 dialog->setGeometry( geometry() );
686 connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
687 connect( dialog->cancelButton(), &QPushButton::clicked,
this, &QgsProcessingAlgorithmWidgetBase::cancel );
688 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
689 connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]() {
690 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
691 QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
692 sb->setValue( sb->maximum() );
697void QgsProcessingAlgorithmWidgetBase::clearLog()
702void QgsProcessingAlgorithmWidgetBase::saveLog()
705 const QString lastUsedDir = settings.
value( u
"/Processing/lastUsedLogDirectory"_s, QDir::homePath() ).toString();
708 const QString txtExt = tr(
"Text files" ) + u
" (*.txt *.TXT)"_s;
709 const QString htmlExt = tr(
"HTML files" ) + u
" (*.html *.HTML)"_s;
711 const QString path = QFileDialog::getSaveFileName(
this, tr(
"Save Log to File" ), lastUsedDir, txtExt +
";;" + htmlExt, &filter );
715 if ( path.isEmpty() )
720 settings.
setValue( u
"/Processing/lastUsedLogDirectory"_s, QFileInfo( path ).path() );
722 LogFormat format = QgsProcessingAlgorithmWidgetBase::LogFormat::FormatPlainText;
723 if ( filter == htmlExt )
725 format = QgsProcessingAlgorithmWidgetBase::LogFormat::FormatHtml;
727 saveLogToFile( path, format );
730void QgsProcessingAlgorithmWidgetBase::copyLogToClipboard()
732 QMimeData *m =
new QMimeData();
733 m->setText( txtLog->toPlainText() );
734 m->setHtml( txtLog->toHtml() );
735 QClipboard *cb = QApplication::clipboard();
738 cb->setMimeData( m, QClipboard::Selection );
740 cb->setMimeData( m, QClipboard::Clipboard );
743void QgsProcessingAlgorithmWidgetBase::closeEvent( QCloseEvent *e )
745 if ( !mHelpCollapsed )
748 settings.
setValue( u
"/Processing/dialogBaseSplitter"_s, splitter->saveState() );
751 QWidget::closeEvent( e );
753 if ( !mAlgorithmTask && isFinalized() )
762void QgsProcessingAlgorithmWidgetBase::runAlgorithm()
765void QgsProcessingAlgorithmWidgetBase::setPercentage(
double percent )
768 if ( progressBar->maximum() == 0 )
769 progressBar->setMaximum( 100 );
770 progressBar->setValue( percent );
774void QgsProcessingAlgorithmWidgetBase::setProgressText(
const QString &text )
776 lblProgress->setText( text );
777 setInfo( text,
false );
778 scrollToBottomOfLog();
785 const QString text =
algorithm->shortHelpString();
786 if ( !text.isEmpty() )
788 const QStringList paragraphs = text.split(
'\n' );
790 for (
const QString ¶graph : paragraphs )
792 help += u
"<p>%1</p>"_s.arg( paragraph );
794 result = u
"<h2>%1</h2>%2"_s.arg(
algorithm->displayName(), help );
796 else if ( !
algorithm->shortDescription().isEmpty() )
798 result = u
"<h2>%1</h2><p>%2</p>"_s.arg(
algorithm->displayName(),
algorithm->shortDescription() );
806 if (
algorithm->documentationFlags() & flag )
811 result += u
"<ul><li><i>%1</i></li></ul>"_s.arg( flags.join(
"</i></li><li><i>"_L1 ) );
815 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." ) );
819 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." ) );
825void QgsProcessingAlgorithmWidgetBase::processEvents()
827 if ( mAlgorithmTask )
843 while ( ++nIters < 100 )
846 QCoreApplication::processEvents();
850void QgsProcessingAlgorithmWidgetBase::scrollToBottomOfLog()
852 QScrollBar *sb = txtLog->verticalScrollBar();
853 sb->setValue( sb->maximum() );
856void QgsProcessingAlgorithmWidgetBase::resetGui()
858 lblProgress->clear();
859 progressBar->setMaximum( 100 );
860 progressBar->setValue( 0 );
861 mButtonRun->setEnabled(
true );
862 mButtonChangeParameters->setEnabled(
true );
863 mButtonClose->setEnabled(
true );
866 mMainWidget->setEnabled(
true );
868 updateRunButtonVisibility();
869 resetAdditionalGui();
872void QgsProcessingAlgorithmWidgetBase::updateRunButtonVisibility()
875 const bool runButtonVisible = mTabWidget->currentIndex() == 0;
876 mButtonRun->setVisible( runButtonVisible );
877 if ( runButtonVisible )
878 progressBar->resetFormat();
879 mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult && mButtonChangeParameters->isEnabled() );
882void QgsProcessingAlgorithmWidgetBase::resetAdditionalGui()
885void QgsProcessingAlgorithmWidgetBase::blockControlsWhileRunning()
887 mButtonRun->setEnabled(
false );
888 mButtonChangeParameters->setEnabled(
false );
891 mMainWidget->setEnabled(
false );
893 blockAdditionalControlsWhileRunning();
896void QgsProcessingAlgorithmWidgetBase::blockAdditionalControlsWhileRunning()
904void QgsProcessingAlgorithmWidgetBase::hideShortHelp()
906 textShortHelp->setVisible(
false );
911 mAlgorithmTask = task;
916void QgsProcessingAlgorithmWidgetBase::disconnectCurrentTask()
918 if ( mAlgorithmTask )
921 mAlgorithmTask =
nullptr;
925QString QgsProcessingAlgorithmWidgetBase::formatStringForLog(
const QString &
string )
928 s.replace(
'\n',
"<br>"_L1 );
932bool QgsProcessingAlgorithmWidgetBase::isFinalized()
937bool QgsProcessingAlgorithmWidgetBase::isRunning()
942void QgsProcessingAlgorithmWidgetBase::cancel()
944 emit cancelRequested();
954 if ( mOverrideDefaultContextSettings )
964void QgsProcessingAlgorithmWidgetBase::setInfo(
const QString &message,
bool isError,
bool escapeHtml,
bool isWarning )
966 constexpr int MESSAGE_COUNT_LIMIT = 10000;
968 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
970 ++mMessageLoggedCount;
974 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
975 txtLog->append( u
"<span style=\"color:red\">%1</span>"_s.arg( tr(
"Message log truncated" ) ) );
976 else if ( isError || isWarning )
977 txtLog->append( u
"<span style=\"color:%1\">%2</span>"_s.arg( isError ? u
"red"_s : u
"#b85a20"_s, escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
978 else if ( escapeHtml )
979 txtLog->append( u
"<span>%1</span"_s.arg( formatStringForLog( message.toHtmlEscaped() ) ) );
981 txtLog->append( u
"<span>%1</span>"_s.arg( formatStringForLog( message ) ) );
982 scrollToBottomOfLog();
986void QgsProcessingAlgorithmWidgetBase::reject()
988 if ( !mAlgorithmTask && isFinalized() )
990 setAttribute( Qt::WA_DeleteOnClose );
993 mDockableWidgetHelper->reject();
996void QgsProcessingAlgorithmWidgetBase::forceClose()
998 disconnectCurrentTask();
1006QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
1012QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
1014 return mProgressBar;
1017QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
1019 return mButtonBox->button( QDialogButtonBox::Cancel );
1022QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
1027void QgsProcessingAlgorithmProgressDialog::reject()
1035QgsProcessingContextOptionsWidget::QgsProcessingContextOptionsWidget( QWidget *parent )
1039 setPanelTitle( tr(
"Algorithm Settings" ) );
1045 mTemporaryFolderWidget->setDialogTitle( tr(
"Select Temporary Directory" ) );
1047 mTemporaryFolderWidget->lineEdit()->setPlaceholderText( tr(
"Default" ) );
1077 mDistanceUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1106 mAreaUnitsCombo->addItem( title, QVariant::fromValue( unit ) );
1109 mThreadsSpinBox->setRange( 1, QThread::idealThreadCount() );
1121 whileBlocking( mComboInvalidFeatureFiltering )->setCurrentIndex( mComboInvalidFeatureFiltering->findData( QVariant::fromValue( context->
invalidGeometryCheck() ) ) );
1122 whileBlocking( mDistanceUnitsCombo )->setCurrentIndex( mDistanceUnitsCombo->findData( QVariant::fromValue( context->
distanceUnit() ) ) );
1123 whileBlocking( mAreaUnitsCombo )->setCurrentIndex( mAreaUnitsCombo->findData( QVariant::fromValue( context->
areaUnit() ) ) );
1126 whileBlocking( mLogLevelComboBox )->setCurrentIndex( mLogLevelComboBox->findData(
static_cast<int>( context->
logLevel() ) ) );
1139Qgis::AreaUnit QgsProcessingContextOptionsWidget::areaUnit()
const
1144QString QgsProcessingContextOptionsWidget::temporaryFolder()
1146 return mTemporaryFolderWidget->filePath();
1149int QgsProcessingContextOptionsWidget::maximumThreads()
const
1151 return mThreadsSpinBox->value();
1156 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.
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.