25 #include <QToolButton> 26 #include <QDesktopServices> 31 QgsProcessingAlgorithmDialogFeedback::QgsProcessingAlgorithmDialogFeedback()
36 void QgsProcessingAlgorithmDialogFeedback::setProgressText(
const QString &text )
38 emit progressTextChanged( text );
41 void QgsProcessingAlgorithmDialogFeedback::reportError(
const QString &error,
bool fatalError )
43 emit errorReported( error, fatalError );
46 void QgsProcessingAlgorithmDialogFeedback::pushInfo(
const QString &info )
48 emit infoPushed( info );
51 void QgsProcessingAlgorithmDialogFeedback::pushCommandInfo(
const QString &info )
53 emit commandInfoPushed( info );
56 void QgsProcessingAlgorithmDialogFeedback::pushDebugInfo(
const QString &info )
58 emit debugInfoPushed( info );
61 void QgsProcessingAlgorithmDialogFeedback::pushConsoleInfo(
const QString &info )
63 emit consoleInfoPushed( info );
70 QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags )
71 : QDialog( parent, flags )
76 splitter->setCollapsible( 0,
false );
79 QSplitterHandle *splitterHandle = splitter->handle( 1 );
80 QVBoxLayout *handleLayout =
new QVBoxLayout();
81 handleLayout->setContentsMargins( 0, 0, 0, 0 );
82 mButtonCollapse =
new QToolButton( splitterHandle );
83 mButtonCollapse->setAutoRaise(
true );
84 mButtonCollapse->setFixedSize( 12, 12 );
85 mButtonCollapse->setCursor( Qt::ArrowCursor );
86 handleLayout->addWidget( mButtonCollapse );
87 handleLayout->addStretch();
88 splitterHandle->setLayout( handleLayout );
93 splitter->restoreState( settings.
value( QStringLiteral(
"/Processing/dialogBaseSplitter" ), QByteArray() ).toByteArray() );
94 mSplitterState = splitter->saveState();
95 splitterChanged( 0, 0 );
97 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsProcessingAlgorithmDialogBase::closeClicked );
98 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QgsProcessingAlgorithmDialogBase::accept );
101 mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
102 mButtonRun->setText( tr(
"Run" ) );
104 buttonCancel->setEnabled(
false );
105 mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
107 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsProcessingAlgorithmDialogBase::openHelp );
108 connect( mButtonCollapse, &QToolButton::clicked,
this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed );
109 connect( splitter, &QSplitter::splitterMoved,
this, &QgsProcessingAlgorithmDialogBase::splitterChanged );
112 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
113 verticalLayout->insertWidget( 0, mMessageBar );
120 mAlgorithm = algorithm;
121 setWindowTitle( mAlgorithm->displayName() );
123 QString algHelp = formatHelp( algorithm );
124 if ( algHelp.isEmpty() )
125 textShortHelp->hide();
128 textShortHelp->document()->setDefaultStyleSheet( QStringLiteral(
".summary { margin-left: 10px; margin-right: 10px; }\n" 129 "h2 { color: #555555; padding-bottom: 15px; }\n" 130 "a { text - decoration: none; color: #3498db; font-weight: bold; }\n" 131 "p { color: #666666; }\n" 132 "b { color: #333333; }\n" 133 "dl dd { margin - bottom: 5px; }" ) );
134 textShortHelp->setHtml( algHelp );
135 connect( textShortHelp, &QTextBrowser::anchorClicked,
this, &QgsProcessingAlgorithmDialogBase::linkClicked );
139 mButtonRun->setText( tr(
"Run in Background" ) );
147 void QgsProcessingAlgorithmDialogBase::setMainWidget( QWidget *widget )
151 mMainWidget->deleteLater();
154 mMainWidget = widget;
155 mTabWidget->widget( 0 )->layout()->addWidget( mMainWidget );
158 QWidget *QgsProcessingAlgorithmDialogBase::mainWidget()
163 QVariantMap QgsProcessingAlgorithmDialogBase::getParameterValues()
const 165 return QVariantMap();
170 auto feedback = qgis::make_unique< QgsProcessingAlgorithmDialogFeedback >();
172 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::commandInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushCommandInfo );
173 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::consoleInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushConsoleInfo );
174 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::debugInfoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushDebugInfo );
175 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::errorReported,
this, &QgsProcessingAlgorithmDialogBase::reportError );
176 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::infoPushed,
this, &QgsProcessingAlgorithmDialogBase::pushInfo );
177 connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::progressTextChanged,
this, &QgsProcessingAlgorithmDialogBase::setProgressText );
179 return feedback.release();
182 QDialogButtonBox *QgsProcessingAlgorithmDialogBase::buttonBox()
187 QTabWidget *QgsProcessingAlgorithmDialogBase::tabWidget()
192 void QgsProcessingAlgorithmDialogBase::showLog()
194 mTabWidget->setCurrentIndex( 1 );
197 QPushButton *QgsProcessingAlgorithmDialogBase::runButton()
202 QPushButton *QgsProcessingAlgorithmDialogBase::cancelButton()
207 void QgsProcessingAlgorithmDialogBase::clearProgress()
209 progressBar->setMaximum( 0 );
212 void QgsProcessingAlgorithmDialogBase::setExecuted(
bool executed )
214 mExecuted = executed;
217 void QgsProcessingAlgorithmDialogBase::setResults(
const QVariantMap &results )
227 void QgsProcessingAlgorithmDialogBase::accept()
231 void QgsProcessingAlgorithmDialogBase::openHelp()
233 QUrl algHelp = mAlgorithm->helpUrl();
234 if ( algHelp.isEmpty() )
236 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() ) ) );
239 if ( !algHelp.isEmpty() )
240 QDesktopServices::openUrl( algHelp );
243 void QgsProcessingAlgorithmDialogBase::toggleCollapsed()
245 if ( mHelpCollapsed )
247 splitter->restoreState( mSplitterState );
248 mButtonCollapse->setArrowType( Qt::RightArrow );
252 mSplitterState = splitter->saveState();
253 splitter->setSizes( QList<int>() << 1 << 0 );
254 mButtonCollapse->setArrowType( Qt::LeftArrow );
256 mHelpCollapsed = !mHelpCollapsed;
259 void QgsProcessingAlgorithmDialogBase::splitterChanged(
int,
int )
261 if ( splitter->sizes().at( 1 ) == 0 )
263 mHelpCollapsed =
true;
264 mButtonCollapse->setArrowType( Qt::LeftArrow );
268 mHelpCollapsed =
false;
269 mButtonCollapse->setArrowType( Qt::RightArrow );
273 void QgsProcessingAlgorithmDialogBase::linkClicked(
const QUrl &url )
275 QDesktopServices::openUrl( url.toString() );
278 void QgsProcessingAlgorithmDialogBase::algExecuted(
bool successful,
const QVariantMap & )
280 mAlgorithmTask =
nullptr;
287 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
301 void QgsProcessingAlgorithmDialogBase::taskTriggered(
QgsTask *task )
303 if ( task == mAlgorithmTask )
307 setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
313 void QgsProcessingAlgorithmDialogBase::closeClicked()
319 void QgsProcessingAlgorithmDialogBase::reportError(
const QString &error,
bool fatalError )
321 setInfo( error,
true );
328 void QgsProcessingAlgorithmDialogBase::pushInfo(
const QString &info )
334 void QgsProcessingAlgorithmDialogBase::pushCommandInfo(
const QString &command )
336 txtLog->append( QStringLiteral(
"<code>%1<code>" ).arg( formatStringForLog( command.toHtmlEscaped() ) ) );
337 scrollToBottomOfLog();
341 void QgsProcessingAlgorithmDialogBase::pushDebugInfo(
const QString &message )
343 txtLog->append( QStringLiteral(
"<span style=\"color:blue\">%1</span>" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
344 scrollToBottomOfLog();
348 void QgsProcessingAlgorithmDialogBase::pushConsoleInfo(
const QString &info )
350 txtLog->append( QStringLiteral(
"<code><span style=\"color:blue\">%1</darkgray></code>" ).arg( formatStringForLog( info.toHtmlEscaped() ) ) );
351 scrollToBottomOfLog();
355 QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
357 QgsProcessingAlgorithmProgressDialog *dialog =
new QgsProcessingAlgorithmProgressDialog(
this );
358 dialog->setWindowModality( Qt::ApplicationModal );
359 dialog->setWindowTitle( windowTitle() );
360 connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
361 connect( dialog->cancelButton(), &QPushButton::clicked, buttonCancel, &QPushButton::click );
362 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
363 connect( txtLog, &QTextEdit::textChanged, dialog, [
this, dialog]()
365 dialog->logTextEdit()->setHtml( txtLog->toHtml() );
366 QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
367 sb->setValue( sb->maximum() );
372 void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
374 QDialog::closeEvent( e );
376 if ( !mAlgorithmTask )
385 void QgsProcessingAlgorithmDialogBase::setPercentage(
double percent )
388 if ( progressBar->maximum() == 0 )
389 progressBar->setMaximum( 100 );
390 progressBar->setValue( percent );
394 void QgsProcessingAlgorithmDialogBase::setProgressText(
const QString &text )
396 lblProgress->setText( text );
397 setInfo( text,
false );
398 scrollToBottomOfLog();
405 if ( !text.isEmpty() )
407 QStringList paragraphs = text.split(
'\n' );
409 for (
const QString ¶graph : paragraphs )
411 help += QStringLiteral(
"<p>%1</p>" ).arg( paragraph );
413 return QStringLiteral(
"<h2>%1</h2>%2" ).arg( algorithm->
displayName(), help );
419 void QgsProcessingAlgorithmDialogBase::processEvents()
421 if ( mAlgorithmTask )
438 while ( QCoreApplication::hasPendingEvents() && ++nIters < 100 )
441 QCoreApplication::processEvents();
445 void QgsProcessingAlgorithmDialogBase::scrollToBottomOfLog()
447 QScrollBar *sb = txtLog->verticalScrollBar();
448 sb->setValue( sb->maximum() );
451 void QgsProcessingAlgorithmDialogBase::resetGui()
453 lblProgress->clear();
454 progressBar->setMaximum( 100 );
455 progressBar->setValue( 0 );
456 mButtonRun->setEnabled(
true );
457 mButtonClose->setEnabled(
true );
460 QgsMessageBar *QgsProcessingAlgorithmDialogBase::messageBar()
465 void QgsProcessingAlgorithmDialogBase::hideShortHelp()
467 textShortHelp->setVisible(
false );
472 mAlgorithmTask = task;
477 QString QgsProcessingAlgorithmDialogBase::formatStringForLog(
const QString &
string )
480 s.replace(
'\n', QStringLiteral(
"<br>" ) );
484 void QgsProcessingAlgorithmDialogBase::setInfo(
const QString &message,
bool isError,
bool escapeHtml )
487 txtLog->append( QStringLiteral(
"<span style=\"color:red\">%1</span>" ).arg( formatStringForLog( message ) ) );
488 else if ( escapeHtml )
489 txtLog->append( formatStringForLog( message.toHtmlEscaped() ) );
491 txtLog->append( formatStringForLog( message ) );
492 scrollToBottomOfLog();
500 QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
507 QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
512 QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
514 return mButtonBox->button( QDialogButtonBox::Cancel );
517 QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
522 void QgsProcessingAlgorithmProgressDialog::reject()
Base class for providing feedback from a processing algorithm.
void taskTriggered(QgsTask *task)
Emitted when a task is triggered.
void cancel()
Tells the internal routines that the current operation should be canceled. This should be run by the ...
This class is a composition of two QSettings instances:
A bar for displaying non-blocking messages to the user.
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users...
static QgsGui * instance()
Returns a pointer to the singleton instance.
virtual QString shortHelpString() const
Returns a localised short helper string for the algorithm.
Abstract base class for processing algorithms.
static QUrl helpUrl(const QString &key)
Returns URI of the help topic for the given key.
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.
Algorithm is not thread safe and cannot be run in a background thread, e.g. for algorithms which mani...
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
Abstract base class for long running background tasks.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
virtual QString displayName() const =0
Returns the translated algorithm name, which should be used for any user-visible display of the algor...
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...
QgsTask task which runs a QgsProcessingAlgorithm in a background task.
Contains information about the context in which a processing algorithm is executed.
void executed(bool successful, const QVariantMap &results)
Emitted when the algorithm has finished execution.