QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsprocessingalgorithmdialogbase.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingalgorithmdialogbase.cpp
3  ------------------------------------
4  Date : November 2017
5  Copyright : (C) 2017 Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgssettings.h"
18 #include "qgshelp.h"
19 #include "qgsmessagebar.h"
20 #include "qgsgui.h"
23 #include "qgstaskmanager.h"
25 #include "qgsstringutils.h"
26 #include "qgsapplication.h"
27 #include <QToolButton>
28 #include <QDesktopServices>
29 #include <QScrollBar>
30 #include <QApplication>
31 #include <QClipboard>
32 #include <QFileDialog>
33 
34 
36 
37 void QgsProcessingAlgorithmDialogFeedback::setProgressText( const QString &text )
38 {
39  emit progressTextChanged( text );
40 }
41 
42 void QgsProcessingAlgorithmDialogFeedback::reportError( const QString &error, bool fatalError )
43 {
44  emit errorReported( error, fatalError );
45 }
46 
47 void QgsProcessingAlgorithmDialogFeedback::pushInfo( const QString &info )
48 {
49  emit infoPushed( info );
50 }
51 
52 void QgsProcessingAlgorithmDialogFeedback::pushCommandInfo( const QString &info )
53 {
54  emit commandInfoPushed( info );
55 }
56 
57 void QgsProcessingAlgorithmDialogFeedback::pushDebugInfo( const QString &info )
58 {
59  emit debugInfoPushed( info );
60 }
61 
62 void QgsProcessingAlgorithmDialogFeedback::pushConsoleInfo( const QString &info )
63 {
64  emit consoleInfoPushed( info );
65 }
66 
67 //
68 // QgsProcessingAlgorithmDialogBase
69 //
70 
71 QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *parent, Qt::WindowFlags flags )
72  : QDialog( parent, flags )
73 {
74  setupUi( this );
75 
76  //don't collapse parameters panel
77  splitter->setCollapsible( 0, false );
78 
79  // add collapse button to splitter
80  QSplitterHandle *splitterHandle = splitter->handle( 1 );
81  QVBoxLayout *handleLayout = new QVBoxLayout();
82  handleLayout->setContentsMargins( 0, 0, 0, 0 );
83  mButtonCollapse = new QToolButton( splitterHandle );
84  mButtonCollapse->setAutoRaise( true );
85  mButtonCollapse->setFixedSize( 12, 12 );
86  mButtonCollapse->setCursor( Qt::ArrowCursor );
87  handleLayout->addWidget( mButtonCollapse );
88  handleLayout->addStretch();
89  splitterHandle->setLayout( handleLayout );
90 
92 
93  QgsSettings settings;
94  splitter->restoreState( settings.value( QStringLiteral( "/Processing/dialogBaseSplitter" ), QByteArray() ).toByteArray() );
95  mSplitterState = splitter->saveState();
96  splitterChanged( 0, 0 );
97 
98  connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsProcessingAlgorithmDialogBase::closeClicked );
99  connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsProcessingAlgorithmDialogBase::runAlgorithm );
100 
101  // Rename OK button to Run
102  mButtonRun = mButtonBox->button( QDialogButtonBox::Ok );
103  mButtonRun->setText( tr( "Run" ) );
104 
105  buttonCancel->setEnabled( false );
106  mButtonClose = mButtonBox->button( QDialogButtonBox::Close );
107 
108  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsProcessingAlgorithmDialogBase::openHelp );
109  connect( mButtonCollapse, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed );
110  connect( splitter, &QSplitter::splitterMoved, this, &QgsProcessingAlgorithmDialogBase::splitterChanged );
111 
112  connect( mButtonSaveLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::saveLog );
113  connect( mButtonCopyLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::copyLogToClipboard );
114  connect( mButtonClearLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::clearLog );
115 
116  mMessageBar = new QgsMessageBar();
117  mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
118  verticalLayout->insertWidget( 0, mMessageBar );
119 
120  connect( QgsApplication::taskManager(), &QgsTaskManager::taskTriggered, this, &QgsProcessingAlgorithmDialogBase::taskTriggered );
121 }
122 
123 QgsProcessingAlgorithmDialogBase::~QgsProcessingAlgorithmDialogBase() = default;
124 
125 void QgsProcessingAlgorithmDialogBase::setAlgorithm( QgsProcessingAlgorithm *algorithm )
126 {
127  mAlgorithm.reset( algorithm );
128  QString title;
130  {
131  title = QgsStringUtils::capitalize( mAlgorithm->displayName(), QgsStringUtils::TitleCase );
132  }
133  else
134  {
135  title = mAlgorithm->displayName();
136  }
137  setWindowTitle( title );
138 
139  QString algHelp = formatHelp( algorithm );
140  if ( algHelp.isEmpty() )
141  textShortHelp->hide();
142  else
143  {
144  textShortHelp->document()->setDefaultStyleSheet( QStringLiteral( ".summary { margin-left: 10px; margin-right: 10px; }\n"
145  "h2 { color: #555555; padding-bottom: 15px; }\n"
146  "a { text - decoration: none; color: #3498db; font-weight: bold; }\n"
147  "p { color: #666666; }\n"
148  "b { color: #333333; }\n"
149  "dl dd { margin - bottom: 5px; }" ) );
150  textShortHelp->setHtml( algHelp );
151  connect( textShortHelp, &QTextBrowser::anchorClicked, this, &QgsProcessingAlgorithmDialogBase::linkClicked );
152  }
153 
154  if ( algorithm->helpUrl().isEmpty() && algorithm->provider()->helpId().isEmpty() )
155  {
156  mButtonBox->removeButton( mButtonBox->button( QDialogButtonBox::Help ) );
157  }
158 }
159 
161 {
162  return mAlgorithm.get();
163 }
164 
165 void QgsProcessingAlgorithmDialogBase::setMainWidget( QWidget *widget )
166 {
167  if ( mMainWidget )
168  {
169  mMainWidget->deleteLater();
170  }
171 
172  mMainWidget = widget;
173  mTabWidget->widget( 0 )->layout()->addWidget( mMainWidget );
174 }
175 
176 QWidget *QgsProcessingAlgorithmDialogBase::mainWidget()
177 {
178  return mMainWidget;
179 }
180 
181 QVariantMap QgsProcessingAlgorithmDialogBase::getParameterValues() const
182 {
183  return QVariantMap();
184 }
185 
186 void QgsProcessingAlgorithmDialogBase::saveLogToFile( const QString &path, const LogFormat format )
187 {
188  QFile logFile( path );
189  if ( !logFile.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
190  {
191  return;
192  }
193  QTextStream fout( &logFile );
194 
195  switch ( format )
196  {
197  case FormatPlainText:
198  fout << txtLog->toPlainText();
199  break;
200 
201  case FormatHtml:
202  fout << txtLog->toHtml();
203  break;
204  }
205 }
206 
207 QgsProcessingFeedback *QgsProcessingAlgorithmDialogBase::createFeedback()
208 {
209  auto feedback = qgis::make_unique< QgsProcessingAlgorithmDialogFeedback >();
210  connect( feedback.get(), &QgsProcessingFeedback::progressChanged, this, &QgsProcessingAlgorithmDialogBase::setPercentage );
211  connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::commandInfoPushed, this, &QgsProcessingAlgorithmDialogBase::pushCommandInfo );
212  connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::consoleInfoPushed, this, &QgsProcessingAlgorithmDialogBase::pushConsoleInfo );
213  connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::debugInfoPushed, this, &QgsProcessingAlgorithmDialogBase::pushDebugInfo );
214  connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::errorReported, this, &QgsProcessingAlgorithmDialogBase::reportError );
215  connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::infoPushed, this, &QgsProcessingAlgorithmDialogBase::pushInfo );
216  connect( feedback.get(), &QgsProcessingAlgorithmDialogFeedback::progressTextChanged, this, &QgsProcessingAlgorithmDialogBase::setProgressText );
217  connect( buttonCancel, &QPushButton::clicked, feedback.get(), &QgsProcessingFeedback::cancel );
218  return feedback.release();
219 }
220 
221 QDialogButtonBox *QgsProcessingAlgorithmDialogBase::buttonBox()
222 {
223  return mButtonBox;
224 }
225 
226 QTabWidget *QgsProcessingAlgorithmDialogBase::tabWidget()
227 {
228  return mTabWidget;
229 }
230 
231 void QgsProcessingAlgorithmDialogBase::showLog()
232 {
233  mTabWidget->setCurrentIndex( 1 );
234 }
235 
236 QPushButton *QgsProcessingAlgorithmDialogBase::runButton()
237 {
238  return mButtonRun;
239 }
240 
241 QPushButton *QgsProcessingAlgorithmDialogBase::cancelButton()
242 {
243  return buttonCancel;
244 }
245 
246 void QgsProcessingAlgorithmDialogBase::clearProgress()
247 {
248  progressBar->setMaximum( 0 );
249 }
250 
251 void QgsProcessingAlgorithmDialogBase::setExecuted( bool executed )
252 {
253  mExecuted = executed;
254 }
255 
256 void QgsProcessingAlgorithmDialogBase::setResults( const QVariantMap &results )
257 {
258  mResults = results;
259 }
260 
261 void QgsProcessingAlgorithmDialogBase::finished( bool, const QVariantMap &, QgsProcessingContext &, QgsProcessingFeedback * )
262 {
263 
264 }
265 
266 void QgsProcessingAlgorithmDialogBase::openHelp()
267 {
268  QUrl algHelp = mAlgorithm->helpUrl();
269  if ( algHelp.isEmpty() )
270  {
271  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() ) ) );
272  }
273 
274  if ( !algHelp.isEmpty() )
275  QDesktopServices::openUrl( algHelp );
276 }
277 
278 void QgsProcessingAlgorithmDialogBase::toggleCollapsed()
279 {
280  if ( mHelpCollapsed )
281  {
282  splitter->restoreState( mSplitterState );
283  mButtonCollapse->setArrowType( Qt::RightArrow );
284  }
285  else
286  {
287  mSplitterState = splitter->saveState();
288  splitter->setSizes( QList<int>() << 1 << 0 );
289  mButtonCollapse->setArrowType( Qt::LeftArrow );
290  }
291  mHelpCollapsed = !mHelpCollapsed;
292 }
293 
294 void QgsProcessingAlgorithmDialogBase::splitterChanged( int, int )
295 {
296  if ( splitter->sizes().at( 1 ) == 0 )
297  {
298  mHelpCollapsed = true;
299  mButtonCollapse->setArrowType( Qt::LeftArrow );
300  }
301  else
302  {
303  mHelpCollapsed = false;
304  mButtonCollapse->setArrowType( Qt::RightArrow );
305  }
306 }
307 
308 void QgsProcessingAlgorithmDialogBase::linkClicked( const QUrl &url )
309 {
310  QDesktopServices::openUrl( url.toString() );
311 }
312 
313 void QgsProcessingAlgorithmDialogBase::algExecuted( bool successful, const QVariantMap & )
314 {
315  mAlgorithmTask = nullptr;
316 
317  if ( !successful )
318  {
319  // show dialog to display errors
320  show();
321  raise();
322  setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
323  activateWindow();
324  showLog();
325  }
326  else
327  {
328  // delete dialog if closed
329  if ( !isVisible() )
330  {
331  deleteLater();
332  }
333  }
334 }
335 
336 void QgsProcessingAlgorithmDialogBase::taskTriggered( QgsTask *task )
337 {
338  if ( task == mAlgorithmTask )
339  {
340  show();
341  raise();
342  setWindowState( ( windowState() & ~Qt::WindowMinimized ) | Qt::WindowActive );
343  activateWindow();
344  showLog();
345  }
346 }
347 
348 void QgsProcessingAlgorithmDialogBase::closeClicked()
349 {
350  reject();
351  close();
352 }
353 
354 void QgsProcessingAlgorithmDialogBase::reportError( const QString &error, bool fatalError )
355 {
356  setInfo( error, true );
357  if ( fatalError )
358  resetGui();
359  showLog();
360  processEvents();
361 }
362 
363 void QgsProcessingAlgorithmDialogBase::pushInfo( const QString &info )
364 {
365  setInfo( info );
366  processEvents();
367 }
368 
369 void QgsProcessingAlgorithmDialogBase::pushCommandInfo( const QString &command )
370 {
371  txtLog->append( QStringLiteral( "<code>%1<code>" ).arg( formatStringForLog( command.toHtmlEscaped() ) ) );
372  scrollToBottomOfLog();
373  processEvents();
374 }
375 
376 void QgsProcessingAlgorithmDialogBase::pushDebugInfo( const QString &message )
377 {
378  txtLog->append( QStringLiteral( "<span style=\"color:#777\">%1</span>" ).arg( formatStringForLog( message.toHtmlEscaped() ) ) );
379  scrollToBottomOfLog();
380  processEvents();
381 }
382 
383 void QgsProcessingAlgorithmDialogBase::pushConsoleInfo( const QString &info )
384 {
385  txtLog->append( QStringLiteral( "<code style=\"color:#777\">%1</code>" ).arg( formatStringForLog( info.toHtmlEscaped() ) ) );
386  scrollToBottomOfLog();
387  processEvents();
388 }
389 
390 QDialog *QgsProcessingAlgorithmDialogBase::createProgressDialog()
391 {
392  QgsProcessingAlgorithmProgressDialog *dialog = new QgsProcessingAlgorithmProgressDialog( this );
393  dialog->setWindowModality( Qt::ApplicationModal );
394  dialog->setWindowTitle( windowTitle() );
395  dialog->setGeometry( geometry() ); // match size/position to this dialog
396  connect( progressBar, &QProgressBar::valueChanged, dialog->progressBar(), &QProgressBar::setValue );
397  connect( dialog->cancelButton(), &QPushButton::clicked, buttonCancel, &QPushButton::click );
398  dialog->logTextEdit()->setHtml( txtLog->toHtml() );
399  connect( txtLog, &QTextEdit::textChanged, dialog, [this, dialog]()
400  {
401  dialog->logTextEdit()->setHtml( txtLog->toHtml() );
402  QScrollBar *sb = dialog->logTextEdit()->verticalScrollBar();
403  sb->setValue( sb->maximum() );
404  } );
405  return dialog;
406 }
407 
408 void QgsProcessingAlgorithmDialogBase::clearLog()
409 {
410  txtLog->clear();
411 }
412 
413 void QgsProcessingAlgorithmDialogBase::saveLog()
414 {
415  QgsSettings settings;
416  QString lastUsedDir = settings.value( QStringLiteral( "/Processing/lastUsedLogDirectory" ), QDir::homePath() ).toString();
417 
418  QString filter;
419  const QString txtExt = tr( "Text files" ) + QStringLiteral( " (*.txt *.TXT)" );
420  const QString htmlExt = tr( "HTML files" ) + QStringLiteral( " (*.html *.HTML)" );
421 
422  QString path = QFileDialog::getSaveFileName( this, tr( "Save Log to File" ), lastUsedDir, txtExt + ";;" + htmlExt, &filter );
423  if ( path.isEmpty() )
424  {
425  return;
426  }
427 
428  settings.setValue( QStringLiteral( "/Processing/lastUsedLogDirectory" ), QFileInfo( path ).path() );
429 
430  LogFormat format = FormatPlainText;
431  if ( filter == htmlExt )
432  {
433  format = FormatHtml;
434  }
435  saveLogToFile( path, format );
436 }
437 
438 void QgsProcessingAlgorithmDialogBase::copyLogToClipboard()
439 {
440  QMimeData *m = new QMimeData();
441  m->setText( txtLog->toPlainText() );
442  m->setHtml( txtLog->toHtml() );
443  QClipboard *cb = QApplication::clipboard();
444 
445 #ifdef Q_OS_LINUX
446  cb->setMimeData( m, QClipboard::Selection );
447 #endif
448  cb->setMimeData( m, QClipboard::Clipboard );
449 }
450 
451 void QgsProcessingAlgorithmDialogBase::closeEvent( QCloseEvent *e )
452 {
453  if ( !mHelpCollapsed )
454  {
455  QgsSettings settings;
456  settings.setValue( QStringLiteral( "/Processing/dialogBaseSplitter" ), splitter->saveState() );
457  }
458 
459  QDialog::closeEvent( e );
460 
461  if ( !mAlgorithmTask )
462  {
463  // when running a background task, the dialog is kept around and deleted only when the task
464  // completes. But if not running a task, we auto cleanup (later - gotta give callers a chance
465  // to retrieve results and execution status).
466  deleteLater();
467  }
468 }
469 
470 void QgsProcessingAlgorithmDialogBase::runAlgorithm()
471 {
472 
473 }
474 
475 void QgsProcessingAlgorithmDialogBase::setPercentage( double percent )
476 {
477  // delay setting maximum progress value until we know algorithm reports progress
478  if ( progressBar->maximum() == 0 )
479  progressBar->setMaximum( 100 );
480  progressBar->setValue( percent );
481  processEvents();
482 }
483 
484 void QgsProcessingAlgorithmDialogBase::setProgressText( const QString &text )
485 {
486  lblProgress->setText( text );
487  setInfo( text, false );
488  scrollToBottomOfLog();
489  processEvents();
490 }
491 
492 QString QgsProcessingAlgorithmDialogBase::formatHelp( QgsProcessingAlgorithm *algorithm )
493 {
494  QString text = algorithm->shortHelpString();
495  if ( !text.isEmpty() )
496  {
497  QStringList paragraphs = text.split( '\n' );
498  QString help;
499  for ( const QString &paragraph : paragraphs )
500  {
501  help += QStringLiteral( "<p>%1</p>" ).arg( paragraph );
502  }
503  return QStringLiteral( "<h2>%1</h2>%2" ).arg( algorithm->displayName(), help );
504  }
505  else if ( !algorithm->shortDescription().isEmpty() )
506  {
507  return QStringLiteral( "<h2>%1</h2><p>%2</p>" ).arg( algorithm->displayName(), algorithm->shortDescription() );
508  }
509  else
510  return QString();
511 }
512 
513 void QgsProcessingAlgorithmDialogBase::processEvents()
514 {
515  if ( mAlgorithmTask )
516  {
517  // no need to call this - the algorithm is running in a thread.
518  // in fact, calling it causes a crash on Windows when the algorithm
519  // is running in a background thread... unfortunately we need something
520  // like this for non-threadable algorithms, otherwise there's no chance
521  // for users to hit cancel or see progress updates...
522  return;
523  }
524 
525  // So that we get a chance of hitting the Abort button
526 #ifdef Q_OS_LINUX
527  // For some reason on Windows hasPendingEvents() always return true,
528  // but one iteration is actually enough on Windows to get good interactivity
529  // whereas on Linux we must allow for far more iterations.
530  // For safety limit the number of iterations
531  int nIters = 0;
532  while ( QCoreApplication::hasPendingEvents() && ++nIters < 100 )
533 #endif
534  {
535  QCoreApplication::processEvents();
536  }
537 }
538 
539 void QgsProcessingAlgorithmDialogBase::scrollToBottomOfLog()
540 {
541  QScrollBar *sb = txtLog->verticalScrollBar();
542  sb->setValue( sb->maximum() );
543 }
544 
545 void QgsProcessingAlgorithmDialogBase::resetGui()
546 {
547  lblProgress->clear();
548  progressBar->setMaximum( 100 );
549  progressBar->setValue( 0 );
550  mButtonRun->setEnabled( true );
551  mButtonClose->setEnabled( true );
552 }
553 
554 QgsMessageBar *QgsProcessingAlgorithmDialogBase::messageBar()
555 {
556  return mMessageBar;
557 }
558 
559 void QgsProcessingAlgorithmDialogBase::hideShortHelp()
560 {
561  textShortHelp->setVisible( false );
562 }
563 
564 void QgsProcessingAlgorithmDialogBase::setCurrentTask( QgsProcessingAlgRunnerTask *task )
565 {
566  mAlgorithmTask = task;
567  connect( mAlgorithmTask, &QgsProcessingAlgRunnerTask::executed, this, &QgsProcessingAlgorithmDialogBase::algExecuted );
568  QgsApplication::taskManager()->addTask( mAlgorithmTask );
569 }
570 
571 QString QgsProcessingAlgorithmDialogBase::formatStringForLog( const QString &string )
572 {
573  QString s = string;
574  s.replace( '\n', QStringLiteral( "<br>" ) );
575  return s;
576 }
577 
578 void QgsProcessingAlgorithmDialogBase::setInfo( const QString &message, bool isError, bool escapeHtml )
579 {
580  if ( isError )
581  txtLog->append( QStringLiteral( "<span style=\"color:red\">%1</span>" ).arg( escapeHtml ? formatStringForLog( message.toHtmlEscaped() ) : formatStringForLog( message ) ) );
582  else if ( escapeHtml )
583  txtLog->append( formatStringForLog( message.toHtmlEscaped() ) );
584  else
585  txtLog->append( formatStringForLog( message ) );
586  scrollToBottomOfLog();
587  processEvents();
588 }
589 
590 //
591 // QgsProcessingAlgorithmProgressDialog
592 //
593 
594 QgsProcessingAlgorithmProgressDialog::QgsProcessingAlgorithmProgressDialog( QWidget *parent )
595  : QDialog( parent )
596 {
597  setupUi( this );
598 }
599 
600 QProgressBar *QgsProcessingAlgorithmProgressDialog::progressBar()
601 {
602  return mProgressBar;
603 }
604 
605 QPushButton *QgsProcessingAlgorithmProgressDialog::cancelButton()
606 {
607  return mButtonBox->button( QDialogButtonBox::Cancel );
608 }
609 
610 QTextEdit *QgsProcessingAlgorithmProgressDialog::logTextEdit()
611 {
612  return mTxtLog;
613 }
614 
615 void QgsProcessingAlgorithmProgressDialog::reject()
616 {
617 
618 }
619 
620 
621 
virtual QString helpUrl() const
Returns a url pointing to the algorithm&#39;s help page.
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 ...
Definition: qgsfeedback.h:85
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
Dialog titles should be title case.
Definition: qgsgui.h:170
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QgsProcessingProvider * provider() const
Returns the provider to which this algorithm belongs.
virtual QString helpId() const
Returns the provider help id string, used for creating QgsHelp urls for algorithms belong to this pro...
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
Algorithm&#39;s display name is a static literal string, and should not be translated or automatically fo...
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:45
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users...
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.
Definition: qgshelp.cpp:41
static QgsTaskManager * taskManager()
Returns the application&#39;s task manager, used for managing application wide background task handling...
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
static QString capitalize(const QString &string, 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.
Abstract base class for long running background tasks.
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
static QgsGui::HigFlags higFlags()
Returns the platform&#39;s HIG flags.
Definition: qgsgui.cpp:146
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
virtual QString displayName() const =0
Returns the translated algorithm name, which should be used for any user-visible display of the algor...
virtual QString shortDescription() const
Returns an optional translated short description of the algorithm.
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...
Definition: qgsgui.cpp:127
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.