diff --git a/python/plugins/grassprovider/Grass7Algorithm.py b/python/plugins/grassprovider/Grass7Algorithm.py index edf5d4bcb9c4..afd2df28c0b7 100644 --- a/python/plugins/grassprovider/Grass7Algorithm.py +++ b/python/plugins/grassprovider/Grass7Algorithm.py @@ -451,8 +451,11 @@ def processAlgorithm(self, original_parameters, context, feedback): else: outputs[outName] = parameters[outName] if isinstance(out, QgsProcessingOutputHtml): - self.convertToHtml(self.fileOutputs[outName]) - + if self.module and hasattr(self.module, 'convertToHtml'): + func = getattr(self.module, 'convertToHtml') + func(self, self.fileOutputs[outName], outputs) + else: + self.convertToHtml(self.fileOutputs[outName]) return outputs def processInputs(self, parameters, context, feedback): diff --git a/python/plugins/grassprovider/description/g.extension.list.txt b/python/plugins/grassprovider/description/g.extension.list.txt index f6db41eeb5df..06ab65f69440 100644 --- a/python/plugins/grassprovider/description/g.extension.list.txt +++ b/python/plugins/grassprovider/description/g.extension.list.txt @@ -1,7 +1,5 @@ g.extension g.extension.list - List GRASS addons. General (g.*) -QgsProcessingParameterBoolean|-l|List available extensions in the official GRASS GIS Addons repository|False -QgsProcessingParameterBoolean|-c|List available extensions in the official GRASS GIS Addons repository including module description|False -QgsProcessingParameterBoolean|-a|List locally installed extensions|False -QgsProcessingParameterFileDestination|html|List of addons|Html files (*.html)|addons_list.html|False +QgsProcessingParameterEnum|list|List|Locally installed extensions;Extensions available in the official GRASS GIS Addons repository;Extensions available in the official GRASS GIS Addons repository including module description|False|0|False +QgsProcessingParameterFileDestination|html|List of addons|Html files (*.html)|addons_list.html|True diff --git a/python/plugins/grassprovider/description/g.version.txt b/python/plugins/grassprovider/description/g.version.txt new file mode 100644 index 000000000000..8f323657031d --- /dev/null +++ b/python/plugins/grassprovider/description/g.version.txt @@ -0,0 +1,11 @@ +g.version +g.version - Display GRASS GIS version info.
Prints only version if run with no options checked. +General (g.*) +QgsProcessingParameterBoolean|-c|Print copyright message|False +QgsProcessingParameterBoolean|-x|Print citation options|False +QgsProcessingParameterBoolean|-b|Print build information|False +QgsProcessingParameterBoolean|-r|Print GIS library revision number and date|True +QgsProcessingParameterBoolean|-e|Print info for additional libraries|True +QgsProcessingParameterBoolean|-g|Print in shell script style (with Git commit reference)|False +QgsProcessingParameterBoolean|--verbose|Print verbose output|False +QgsProcessingParameterFileDestination|html|Output file|Html files (*.html)|grass_version_info.html|True diff --git a/python/plugins/grassprovider/ext/g_extension_list.py b/python/plugins/grassprovider/ext/g_extension_list.py index 03050268aaad..37862cc73024 100644 --- a/python/plugins/grassprovider/ext/g_extension_list.py +++ b/python/plugins/grassprovider/ext/g_extension_list.py @@ -19,6 +19,31 @@ __date__ = 'May 2023' __copyright__ = '(C) 2023, Alister Hood' +from qgis.core import QgsProcessingParameterBoolean + def processInputs(alg, parameters, context, feedback): - pass + # get the option we want to run + # we would need to update the if statements below if the order in the description file is changed + selectedOption = alg.parameterAsInt(parameters, 'list', context) + # Locally installed extensions + if selectedOption == 0: + optionString = '-a' + # Extensions available in the official GRASS GIS Addons repository + elif selectedOption == 1: + optionString = '-l' + # Extensions available in the official GRASS GIS Addons repository including module description + else: + optionString = '-c' + param = QgsProcessingParameterBoolean(optionString, '', True) + alg.addParameter(param) + # Don't forget to remove the old input parameter + alg.removeParameter('list') + + +def convertToHtml(alg, fileName, outputs): + # don't copy this for something that will have lots of data like r.stats + # it will be very slow + outputs['GRASS_ADDONS'] = open(fileName, 'r').read() + # this will read the file a second time, but calling it saves us duplicating the code here + alg.convertToHtml(fileName) diff --git a/python/plugins/grassprovider/ext/g_version.py b/python/plugins/grassprovider/ext/g_version.py new file mode 100644 index 000000000000..46cbe4d87b4e --- /dev/null +++ b/python/plugins/grassprovider/ext/g_version.py @@ -0,0 +1,32 @@ +""" +*************************************************************************** + g_version.py + ------------------ + Date : May 2023 + Copyright : (C) 2023 by Alister Hood + Email : alister.hood at gmail dot com +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +""" + +__author__ = 'Alister Hood' +__date__ = 'May 2023' +__copyright__ = '(C) 2023, Alister Hood' + + +def processInputs(alg, parameters, context, feedback): + pass + + +def convertToHtml(alg, fileName, outputs): + # don't copy this for something that will have lots of data like r.stats + # it will be very slow + outputs['GRASS_VERSIONINFO'] = open(fileName, 'r').read() + # this will read the file a second time, but calling it saves us duplicating the code here + alg.convertToHtml(fileName) diff --git a/python/plugins/grassprovider/grass7.txt b/python/plugins/grassprovider/grass7.txt index 21e76a2487aa..f38666ee77ea 100644 --- a/python/plugins/grassprovider/grass7.txt +++ b/python/plugins/grassprovider/grass7.txt @@ -1,4 +1,4 @@ -A short guide for creating and editing GRASS GIS 7 algorithms: +A short guide for creating and editing GRASS GIS 7/8 algorithms: ----------------------------------------------------------------------- Each GRASS command, to be executed from a processing framework element such as the toolbox @@ -169,18 +169,20 @@ There are 4 different levels where you can add logic: - Processing inputs import: if you need to do more than importing input layers. - Processing the command itself: if you need to chain more than one GRASS command for your algorithm. - Processing the outputs: if you need to do special things before exporting layers or if you need special export methods. +- Customising html outputs: if you need to do special processing to an html output, or save the raw output to an output variable. -Whenever you want to add some logic on one (or more) level(s), you have to create a .py file named according to the algorithm name in python/plugins/grassprovider/ext, replacing '.' with '_'. -Then you need to create methods using the respective names: +To add some logic on one or more of these levels you have to create a .py file named according to the algorithm name in python/plugins/grassprovider/ext, replacing '.' with '_'. +Then create methods using the respective names: - Input parameters: checkParameterValuesBeforeExecuting - Inputs import: processInputs - Command: processCommand - Outputs: processOutputs +- Custom html outputs: convertToHtml -If there is a Python file with the algorithm name in the ext directory, methods will be imported from the file and run instead of the common methods (there are "standard" processCommand/processInputs/processOutputs/checkParameterValuesBeforeExecuting methods in the code of the GRASS provider for QGIS Processing, in python/plugins/grassprovider/Grass7Algorithm.py). +If there is a Python file with the algorithm name in the ext directory, these methods will be imported from the file. +In the case of processCommand, processInputs, processOutputs and convertToHtml these will override the "standard" versions of these methods in the code of the GRASS provider. +You will need to read (and understand) the code for the standard methods in python/plugins/grassprovider/Grass7Algorithm.py. If we take the example of v.what.rast, there is an ext file: ext/v_what_rast.py. In this file there is a processCommand method. It just launches the standard processCommand but with the delOutputs option set to True (we do not want to have standard outputs). Then there is also a customized processOutputs which exports the input vector as an output for QGIS. We need to do this because v.what.rast modifies values directly in the input vector layer instead of generating a new output, so we have to build this output ourself. - -If you want to do special things in the ext mechanism, you will need to read (and understand) the GRASS provider code standard methods in Grass7Algorithm.py. diff --git a/python/plugins/processing/gui/AlgorithmDialog.py b/python/plugins/processing/gui/AlgorithmDialog.py index 30873a956a54..1bea1e4229f5 100644 --- a/python/plugins/processing/gui/AlgorithmDialog.py +++ b/python/plugins/processing/gui/AlgorithmDialog.py @@ -19,7 +19,6 @@ __date__ = 'August 2012' __copyright__ = '(C) 2012, Victor Olaya' -from pprint import pformat import datetime import time @@ -283,9 +282,11 @@ def on_complete(ok, results): if ok: self.feedback.pushInfo( self.tr(elapsed_time(start_time, 'Execution completed in'))) - self.feedback.pushInfo(self.tr('Results:')) + self.feedback.pushInfo(self.tr('Results:\n')) r = {k: v for k, v in results.items() if k not in ('CHILD_RESULTS', 'CHILD_INPUTS')} - self.feedback.pushCommandInfo(pformat(r)) + for i in r: + self.feedback.pushInfo(i) + self.feedback.pushCommandInfo(r[i]) else: self.feedback.reportError( self.tr(elapsed_time(start_time, 'Execution failed after')))