From 237f1f7e2dc7372071254ebf2ac267e140e2e6da Mon Sep 17 00:00:00 2001 From: gacarrillor Date: Sat, 7 Mar 2020 14:23:51 -0500 Subject: [PATCH 1/3] [processing][needs-docs] Adjust status of controls in algorithm dialog + Run button is not shown anymore in the Log tab, therefore, you can only run algorithms from the Parameters tab. + While running an algorithm, the Parameters tab is now blocked. + When an algorithm execution finishes (either successfully or not), a new button Change Parameters is shown in the Log tab. + The Batch Algorithm Dialog is now consistent with the described behavior (before, it blocked the Parameters panel, but not the tab; and it was the only dialog blocking parameters widgets). These changes were applied to the Algorithm Dialog and Batch Algorithm Dialog, and work on Edit in place dialogs as well. --- .../qgsprocessingalgorithmdialogbase.sip.in | 27 ++++++++++++ .../plugins/processing/gui/AlgorithmDialog.py | 6 ++- .../processing/gui/BatchAlgorithmDialog.py | 6 ++- .../qgsprocessingalgorithmdialogbase.cpp | 44 +++++++++++++++++++ .../qgsprocessingalgorithmdialogbase.h | 30 +++++++++++++ 5 files changed, 110 insertions(+), 3 deletions(-) diff --git a/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in b/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in index 08a57654acf..ed90881afeb 100644 --- a/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in +++ b/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in @@ -73,6 +73,11 @@ Returns the main widget for the dialog, usually a panel for configuring algorith void showLog(); %Docstring Switches the dialog to the log page. +%End + + void showParameters(); +%Docstring +Switches the dialog to the parameters page. %End bool wasExecuted() const; @@ -195,6 +200,11 @@ Returns the dialog's run button. QPushButton *cancelButton(); %Docstring Returns the dialog's cancel button. +%End + + QPushButton *changeParametersButton(); +%Docstring +Returns the dialog's change parameters button. %End QDialogButtonBox *buttonBox(); @@ -221,6 +231,12 @@ Sets whether the algorithm was executed through the dialog. .. seealso:: :py:func:`setResults` %End + void setExecutedAnyResult( bool executedAnyResult ); +%Docstring +Sets whether the algorithm was executed through the dialog (no matter the result). +%End + + void setResults( const QVariantMap &results ); %Docstring Sets the algorithm results. @@ -238,6 +254,17 @@ Displays an info ``message`` in the dialog's log. void resetGui(); %Docstring Resets the dialog's gui, ready for another algorithm execution. +%End + + void updateRunButtonVisibility(); +%Docstring +Sets visibility for mutually exclusive buttons Run and Change Parameters. +%End + + void blockControlsWhileRunning(); +%Docstring +Blocks run and changeParameters buttons and parameters tab while the +algorithm is running. %End QgsMessageBar *messageBar(); diff --git a/python/plugins/processing/gui/AlgorithmDialog.py b/python/plugins/processing/gui/AlgorithmDialog.py index c6a7628ee46..7b8e2a9d117 100644 --- a/python/plugins/processing/gui/AlgorithmDialog.py +++ b/python/plugins/processing/gui/AlgorithmDialog.py @@ -90,6 +90,8 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase): self.buttonBox().button(QDialogButtonBox.Close).setText(QCoreApplication.translate("AlgorithmDialog", "Cancel")) self.setWindowTitle(self.windowTitle() + ' | ' + self.active_layer.name()) + self.updateRunButtonVisibility() + def getParametersPanel(self, alg, parent): return ParametersPanel(parent, alg, self.in_place) @@ -189,7 +191,9 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase): QMessageBox.warning( self, self.tr('Unable to execute algorithm'), msg) return - self.runButton().setEnabled(False) + + self.blockControlsWhileRunning() + self.setExecutedAnyResult(True) self.cancelButton().setEnabled(False) buttons = self.mainWidget().iterateButtons self.iterateParam = None diff --git a/python/plugins/processing/gui/BatchAlgorithmDialog.py b/python/plugins/processing/gui/BatchAlgorithmDialog.py index e4fd423f9b2..2c44f99b2a9 100644 --- a/python/plugins/processing/gui/BatchAlgorithmDialog.py +++ b/python/plugins/processing/gui/BatchAlgorithmDialog.py @@ -77,6 +77,8 @@ class BatchAlgorithmDialog(QgsProcessingAlgorithmDialogBase): self.btnRunSingle.clicked.connect(self.runAsSingle) self.buttonBox().addButton(self.btnRunSingle, QDialogButtonBox.ResetRole) # reset role to ensure left alignment + self.updateRunButtonVisibility() + def runAsSingle(self): self.close() @@ -106,7 +108,8 @@ class BatchAlgorithmDialog(QgsProcessingAlgorithmDialogBase): with OverrideCursor(Qt.WaitCursor): - self.mainWidget().setEnabled(False) + self.blockControlsWhileRunning() + self.setExecutedAnyResult(True) self.cancelButton().setEnabled(True) # Make sure the Log tab is visible before executing the algorithm @@ -178,7 +181,6 @@ class BatchAlgorithmDialog(QgsProcessingAlgorithmDialogBase): self.loadHTMLResults(results['results'], count) self.createSummaryTable(algorithm_results, errors) - self.mainWidget().setEnabled(True) self.resetGui() def loadHTMLResults(self, results, num): diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp index 206cbeb19ec..1bb7e53b5b4 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp @@ -105,6 +105,10 @@ QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *par buttonCancel->setEnabled( false ); mButtonClose = mButtonBox->button( QDialogButtonBox::Close ); + mButtonChangeParameters = new QPushButton( tr( "Change Parameters" ) ); + mButtonBox->addButton( mButtonChangeParameters, QDialogButtonBox::ActionRole ); + + connect( mButtonChangeParameters, &QPushButton::clicked, this, &QgsProcessingAlgorithmDialogBase::showParameters ); connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsProcessingAlgorithmDialogBase::openHelp ); connect( mButtonCollapse, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::toggleCollapsed ); connect( splitter, &QSplitter::splitterMoved, this, &QgsProcessingAlgorithmDialogBase::splitterChanged ); @@ -113,6 +117,8 @@ QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *par connect( mButtonCopyLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::copyLogToClipboard ); connect( mButtonClearLog, &QToolButton::clicked, this, &QgsProcessingAlgorithmDialogBase::clearLog ); + connect( mTabWidget, &QTabWidget::currentChanged, this, &QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged ); + mMessageBar = new QgsMessageBar(); mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ); verticalLayout->insertWidget( 0, mMessageBar ); @@ -239,6 +245,11 @@ void QgsProcessingAlgorithmDialogBase::showLog() mTabWidget->setCurrentIndex( 1 ); } +void QgsProcessingAlgorithmDialogBase::showParameters() +{ + mTabWidget->setCurrentIndex( 0 ); +} + QPushButton *QgsProcessingAlgorithmDialogBase::runButton() { return mButtonRun; @@ -249,6 +260,11 @@ QPushButton *QgsProcessingAlgorithmDialogBase::cancelButton() return buttonCancel; } +QPushButton *QgsProcessingAlgorithmDialogBase::changeParametersButton() +{ + return mButtonChangeParameters; +} + void QgsProcessingAlgorithmDialogBase::clearProgress() { progressBar->setMaximum( 0 ); @@ -259,6 +275,11 @@ void QgsProcessingAlgorithmDialogBase::setExecuted( bool executed ) mExecuted = executed; } +void QgsProcessingAlgorithmDialogBase::setExecutedAnyResult( bool executedAnyResult ) +{ + mExecutedAnyResult = executedAnyResult; +} + void QgsProcessingAlgorithmDialogBase::setResults( const QVariantMap &results ) { mResults = results; @@ -311,6 +332,11 @@ void QgsProcessingAlgorithmDialogBase::splitterChanged( int, int ) } } +void QgsProcessingAlgorithmDialogBase::mTabWidget_currentChanged( int ) +{ + updateRunButtonVisibility(); +} + void QgsProcessingAlgorithmDialogBase::linkClicked( const QUrl &url ) { QDesktopServices::openUrl( url.toString() ); @@ -553,7 +579,25 @@ void QgsProcessingAlgorithmDialogBase::resetGui() progressBar->setMaximum( 100 ); progressBar->setValue( 0 ); mButtonRun->setEnabled( true ); + mButtonChangeParameters->setEnabled( true ); mButtonClose->setEnabled( true ); + mTabWidget->setTabEnabled( 0, true ); // Enable Parameters tab + updateRunButtonVisibility(); +} + +void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility() +{ + // Activate run button if current tab is Parameters + bool runButtonVisible = mTabWidget->currentIndex() == 0; + mButtonRun->setVisible( runButtonVisible ); + mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult ); +} + +void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning() +{ + mButtonRun->setEnabled( false ); + mButtonChangeParameters->setEnabled( false ); + mTabWidget->setTabEnabled( 0, false ); // Disable Parameters tab } QgsMessageBar *QgsProcessingAlgorithmDialogBase::messageBar() diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.h b/src/gui/processing/qgsprocessingalgorithmdialogbase.h index 89cf00fb77f..7f8672cbe7f 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.h +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.h @@ -133,6 +133,11 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: */ void showLog(); + /** + * Switches the dialog to the parameters page. + */ + void showParameters(); + /** * Returns TRUE if an algorithm was executed in the dialog. * \see results() @@ -244,6 +249,11 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: */ QPushButton *cancelButton(); + /** + * Returns the dialog's change parameters button. + */ + QPushButton *changeParametersButton(); + /** * Returns the dialog's button box. */ @@ -266,6 +276,12 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: */ void setExecuted( bool executed ); + /** + * Sets whether the algorithm was executed through the dialog (no matter the result). + */ + void setExecutedAnyResult( bool executedAnyResult ); + + /** * Sets the algorithm results. * \see results() @@ -283,6 +299,17 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: */ void resetGui(); + /** + * Sets visibility for mutually exclusive buttons Run and Change Parameters. + */ + void updateRunButtonVisibility(); + + /** + * Blocks run and changeParameters buttons and parameters tab while the + * algorithm is running. + */ + void blockControlsWhileRunning(); + /** * Returns the dialog's message bar. */ @@ -324,6 +351,7 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: void toggleCollapsed(); void splitterChanged( int pos, int index ); + void mTabWidget_currentChanged( int index ); void linkClicked( const QUrl &url ); void algExecuted( bool successful, const QVariantMap &results ); void taskTriggered( QgsTask *task ); @@ -333,11 +361,13 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: QPushButton *mButtonRun = nullptr; QPushButton *mButtonClose = nullptr; + QPushButton *mButtonChangeParameters = nullptr; QByteArray mSplitterState; QToolButton *mButtonCollapse = nullptr; QgsMessageBar *mMessageBar = nullptr; bool mExecuted = false; + bool mExecutedAnyResult = false; QVariantMap mResults; QWidget *mMainWidget = nullptr; std::unique_ptr< QgsProcessingAlgorithm > mAlgorithm; From 0153dc805e879fdc5961c485a9b6c150d23c48cd Mon Sep 17 00:00:00 2001 From: gacarrillor Date: Sat, 7 Mar 2020 17:16:03 -0500 Subject: [PATCH 2/3] [processing] Disable runAsBatch/runAsSingle buttons during algorithm execution --- .../qgsprocessingalgorithmdialogbase.sip.in | 12 ++++++++++++ python/plugins/processing/gui/AlgorithmDialog.py | 8 ++++++++ .../plugins/processing/gui/BatchAlgorithmDialog.py | 6 ++++++ .../processing/qgsprocessingalgorithmdialogbase.cpp | 12 ++++++++++++ .../processing/qgsprocessingalgorithmdialogbase.h | 12 ++++++++++++ 5 files changed, 50 insertions(+) diff --git a/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in b/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in index ed90881afeb..973b3320320 100644 --- a/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in +++ b/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in @@ -254,6 +254,12 @@ Displays an info ``message`` in the dialog's log. void resetGui(); %Docstring Resets the dialog's gui, ready for another algorithm execution. +%End + + virtual void resetAdditionalGui(); +%Docstring +For subclasses to register their own GUI controls to be reset, ready +for another algorithm execution. %End void updateRunButtonVisibility(); @@ -265,6 +271,12 @@ Sets visibility for mutually exclusive buttons Run and Change Parameters. %Docstring Blocks run and changeParameters buttons and parameters tab while the algorithm is running. +%End + + virtual void blockAdditionalControlsWhileRunning(); +%Docstring +For subclasses to register their own GUI controls to be blocked while +the algorithm is running. %End QgsMessageBar *messageBar(); diff --git a/python/plugins/processing/gui/AlgorithmDialog.py b/python/plugins/processing/gui/AlgorithmDialog.py index 7b8e2a9d117..f1633d0b575 100644 --- a/python/plugins/processing/gui/AlgorithmDialog.py +++ b/python/plugins/processing/gui/AlgorithmDialog.py @@ -101,6 +101,14 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase): dlg.show() dlg.exec_() + def resetAdditionalGui(self): + if not self.in_place: + self.runAsBatchButton.setEnabled(True) + + def blockAdditionalControlsWhileRunning(self): + if not self.in_place: + self.runAsBatchButton.setEnabled(False) + def setParameters(self, parameters): self.mainWidget().setParameters(parameters) diff --git a/python/plugins/processing/gui/BatchAlgorithmDialog.py b/python/plugins/processing/gui/BatchAlgorithmDialog.py index 2c44f99b2a9..ff42a2d1e0b 100644 --- a/python/plugins/processing/gui/BatchAlgorithmDialog.py +++ b/python/plugins/processing/gui/BatchAlgorithmDialog.py @@ -87,6 +87,12 @@ class BatchAlgorithmDialog(QgsProcessingAlgorithmDialogBase): dlg.show() dlg.exec_() + def resetAdditionalGui(self): + self.btnRunSingle.setEnabled(True) + + def blockAdditionalControlsWhileRunning(self): + self.btnRunSingle.setEnabled(False) + def runAlgorithm(self): alg_parameters = [] diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp index 1bb7e53b5b4..f400917e39a 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp @@ -583,6 +583,7 @@ void QgsProcessingAlgorithmDialogBase::resetGui() mButtonClose->setEnabled( true ); mTabWidget->setTabEnabled( 0, true ); // Enable Parameters tab updateRunButtonVisibility(); + resetAdditionalGui(); } void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility() @@ -593,11 +594,22 @@ void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility() mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult ); } +void QgsProcessingAlgorithmDialogBase::resetAdditionalGui() +{ + +} + void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning() { mButtonRun->setEnabled( false ); mButtonChangeParameters->setEnabled( false ); mTabWidget->setTabEnabled( 0, false ); // Disable Parameters tab + blockAdditionalControlsWhileRunning(); +} + +void QgsProcessingAlgorithmDialogBase::blockAdditionalControlsWhileRunning() +{ + } QgsMessageBar *QgsProcessingAlgorithmDialogBase::messageBar() diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.h b/src/gui/processing/qgsprocessingalgorithmdialogbase.h index 7f8672cbe7f..2739510c350 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.h +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.h @@ -299,6 +299,12 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: */ void resetGui(); + /** + * For subclasses to register their own GUI controls to be reset, ready + * for another algorithm execution. + */ + virtual void resetAdditionalGui(); + /** * Sets visibility for mutually exclusive buttons Run and Change Parameters. */ @@ -310,6 +316,12 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, private Ui:: */ void blockControlsWhileRunning(); + /** + * For subclasses to register their own GUI controls to be blocked while + * the algorithm is running. + */ + virtual void blockAdditionalControlsWhileRunning(); + /** * Returns the dialog's message bar. */ From 871a3c0e679331ed7c039135c8e73bf43559833c Mon Sep 17 00:00:00 2001 From: gacarrillor Date: Sun, 8 Mar 2020 08:16:57 -0500 Subject: [PATCH 3/3] [processing] Disable Parameters panel during algorithm execution (not the whole tab) --- .../processing/qgsprocessingalgorithmdialogbase.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp index f400917e39a..5c47cc40d0c 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp @@ -581,7 +581,10 @@ void QgsProcessingAlgorithmDialogBase::resetGui() mButtonRun->setEnabled( true ); mButtonChangeParameters->setEnabled( true ); mButtonClose->setEnabled( true ); - mTabWidget->setTabEnabled( 0, true ); // Enable Parameters tab + if ( mMainWidget ) + { + mMainWidget->setEnabled( true ); + } updateRunButtonVisibility(); resetAdditionalGui(); } @@ -591,7 +594,7 @@ void QgsProcessingAlgorithmDialogBase::updateRunButtonVisibility() // Activate run button if current tab is Parameters bool runButtonVisible = mTabWidget->currentIndex() == 0; mButtonRun->setVisible( runButtonVisible ); - mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult ); + mButtonChangeParameters->setVisible( !runButtonVisible && mExecutedAnyResult && mButtonChangeParameters->isEnabled() ); } void QgsProcessingAlgorithmDialogBase::resetAdditionalGui() @@ -603,7 +606,10 @@ void QgsProcessingAlgorithmDialogBase::blockControlsWhileRunning() { mButtonRun->setEnabled( false ); mButtonChangeParameters->setEnabled( false ); - mTabWidget->setTabEnabled( 0, false ); // Disable Parameters tab + if ( mMainWidget ) + { + mMainWidget->setEnabled( false ); + } blockAdditionalControlsWhileRunning(); }