Skip to content

Commit 29b080f

Browse files
authored
Merge pull request #6754 from m-kuhn/processing_filter_algorithm
[FEATURE] Feature filter algorithm for processing models
2 parents 9dc3ee4 + fbb4ef5 commit 29b080f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1343
-40
lines changed

python/core/processing/qgsprocessingalgorithm.sip.in

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010

1111

1212

13-
1413
%ModuleHeaderCode
1514
#include <qgsprocessingmodelalgorithm.h>
1615
%End
1716

18-
1917
class QgsProcessingAlgorithm
2018
{
2119
%Docstring
@@ -276,7 +274,7 @@ Returns true if this algorithm generates HTML outputs.
276274
%End
277275

278276
QVariantMap run( const QVariantMap &parameters,
279-
QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0 ) const;
277+
QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0, const QVariantMap &configuration = QVariantMap() ) const;
280278
%Docstring
281279
Executes the algorithm using the specified ``parameters``. This method internally
282280
creates a copy of the algorithm before running it, so it is safe to call

python/core/processing/qgsprocessingparameters.sip.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ their acceptable ranges, defaults, etc.
168168
FlagAdvanced,
169169
FlagHidden,
170170
FlagOptional,
171+
FlagIsModelOutput,
171172
};
172173
typedef QFlags<QgsProcessingParameterDefinition::Flag> Flags;
173174

python/core/processing/qgsprocessingregistry.sip.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ Return a list with all known parameter types.
143143
.. versionadded:: 3.2
144144
%End
145145

146-
147146
signals:
148147

149148
void providerAdded( const QString &id );

python/gui/gui_auto.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
%Include layertree/qgslayertreeembeddedconfigwidget.sip
4646
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
4747
%Include layout/qgslayoutviewmouseevent.sip
48+
%Include processing/qgsprocessingguiregistry.sip
4849
%Include raster/qgsrasterrendererwidget.sip
4950
%Include symbology/qgssymbolwidgetcontext.sip
5051
%Include qgisinterface.sip
@@ -311,5 +312,6 @@
311312
%Include layout/qgslayoutviewtooltemporarymousepan.sip
312313
%Include layout/qgslayoutviewtoolzoom.sip
313314
%Include locator/qgslocatorwidget.sip
315+
%Include processing/qgsprocessingalgorithmconfigurationwidget.sip
314316
%Include processing/qgsprocessingalgorithmdialogbase.sip
315317
%Include qgsadvanceddigitizingcanvasitem.sip
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
14+
15+
class QgsProcessingAlgorithmConfigurationWidget : QWidget
16+
{
17+
%Docstring
18+
A configuration widget for processing algorithms allows providing additional
19+
configuration options directly on algorithm level, in addition to parameters.
20+
21+
.. versionadded:: 3.2
22+
%End
23+
24+
%TypeHeaderCode
25+
#include "qgsprocessingalgorithmconfigurationwidget.h"
26+
%End
27+
public:
28+
29+
QgsProcessingAlgorithmConfigurationWidget( QWidget *parent = 0 );
30+
%Docstring
31+
Creates a new QgsProcessingAlgorithmConfigurationWidget
32+
%End
33+
virtual ~QgsProcessingAlgorithmConfigurationWidget();
34+
35+
virtual QVariantMap configuration() const = 0;
36+
%Docstring
37+
Read the current configuration from this widget.
38+
%End
39+
40+
virtual void setConfiguration( const QVariantMap &configuration ) = 0;
41+
%Docstring
42+
Set the configuration which this widget should represent.
43+
%End
44+
};
45+
46+
47+
class QgsProcessingAlgorithmConfigurationWidgetFactory
48+
{
49+
%Docstring
50+
Interface base class for factories for algorithm configuration widgets.
51+
52+
.. versionadded:: 3.2
53+
%End
54+
55+
%TypeHeaderCode
56+
#include "qgsprocessingalgorithmconfigurationwidget.h"
57+
%End
58+
public:
59+
virtual ~QgsProcessingAlgorithmConfigurationWidgetFactory();
60+
61+
virtual QgsProcessingAlgorithmConfigurationWidget *create( const QgsProcessingAlgorithm *algorithm ) const = 0 /Factory/;
62+
%Docstring
63+
Create a new configuration widget for ``algorithm``.
64+
%End
65+
66+
virtual bool canCreateFor( const QgsProcessingAlgorithm *algorithm ) const = 0;
67+
%Docstring
68+
Check if this factory can create widgets for ``algorithm``.
69+
%End
70+
};
71+
72+
73+
/************************************************************************
74+
* This file has been generated automatically from *
75+
* *
76+
* src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h *
77+
* *
78+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
79+
************************************************************************/

python/gui/processing/qgsprocessingconfigurationwidgets.sip.in

Whitespace-only changes.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/gui/processing/qgsprocessingguiregistry.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
14+
class QgsProcessingGuiRegistry
15+
{
16+
%Docstring
17+
The QgsProcessingGuiRegistry is a home for widgets for processing
18+
configuration widgets.
19+
20+
.. versionadded:: 3.2
21+
%End
22+
23+
%TypeHeaderCode
24+
#include "qgsprocessingguiregistry.h"
25+
%End
26+
public:
27+
28+
QgsProcessingGuiRegistry();
29+
%Docstring
30+
Constructor. Should never be called manually, is already
31+
created by :py:class:`QgsGui`.
32+
%End
33+
~QgsProcessingGuiRegistry();
34+
35+
void addAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory /Transfer/ );
36+
%Docstring
37+
Add a new configuration widget factory for customized algorithm configuration
38+
widgets. Ownership is taken.
39+
40+
.. versionadded:: 3.2
41+
%End
42+
43+
void removeAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory );
44+
%Docstring
45+
Remove a configuration widget factory for customized algorithm configuration
46+
widgets.
47+
48+
.. versionadded:: 3.2
49+
%End
50+
51+
QgsProcessingAlgorithmConfigurationWidget *algorithmConfigurationWidget( const QgsProcessingAlgorithm *algorithm ) const;
52+
%Docstring
53+
Get the configuration widget for an ``algorithm``. This widget will be shown
54+
next to parameter widgets. Most algorithms do not have a configuration widget
55+
and in this case, None will be returned.
56+
57+
.. versionadded:: 3.2
58+
%End
59+
60+
};
61+
62+
/************************************************************************
63+
* This file has been generated automatically from *
64+
* *
65+
* src/gui/processing/qgsprocessingguiregistry.h *
66+
* *
67+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
68+
************************************************************************/

python/gui/qgsgui.sip.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ Returns the global map layer action registry, used for registering map layer act
6060
static QgsLayoutItemGuiRegistry *layoutItemGuiRegistry();
6161
%Docstring
6262
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
63+
%End
64+
65+
static QgsProcessingGuiRegistry *processingGuiRegistry();
66+
%Docstring
67+
Returns the global processing gui registry, used for registering the GUI behavior of processing algorithms.
68+
69+
.. versionadded:: 3.2
6370
%End
6471

6572
static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() );

python/plugins/processing/modeler/ModelerGraphicItem.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def editElement(self):
208208
self.scene.dialog.repaintModel()
209209
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
210210
elemAlg = self.element.algorithm()
211-
dlg = ModelerParametersDialog(elemAlg, self.model, self.element.childId())
211+
dlg = ModelerParametersDialog(elemAlg, self.model, self.element.childId(), self.element.configuration())
212212
if dlg.exec_():
213213
alg = dlg.createAlgorithm()
214214
alg.setChildId(self.element.childId())

python/plugins/processing/modeler/ModelerParametersDialog.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
QHBoxLayout, QWidget)
3737

3838
from qgis.core import (Qgis,
39+
QgsApplication,
3940
QgsProcessingParameterDefinition,
4041
QgsProcessingParameterPoint,
4142
QgsProcessingParameterExtent,
@@ -52,7 +53,8 @@
5253
QgsProcessingOutputDefinition,
5354
QgsSettings)
5455

55-
from qgis.gui import (QgsMessageBar,
56+
from qgis.gui import (QgsGui,
57+
QgsMessageBar,
5658
QgsScrollArea,
5759
QgsFilterLineEdit,
5860
QgsHelp)
@@ -63,13 +65,15 @@
6365

6466

6567
class ModelerParametersDialog(QDialog):
66-
def __init__(self, alg, model, algName=None):
68+
69+
def __init__(self, alg, model, algName=None, configuration=None):
6770
QDialog.__init__(self)
6871
self.setModal(True)
6972

7073
self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm
7174
self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm
7275
self.childId = algName # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
76+
self.configuration = configuration
7377

7478
self.setupUi()
7579
self.params = None
@@ -87,6 +91,8 @@ def setupUi(self):
8791
self.wrappers = {}
8892
self.valueItems = {}
8993
self.dependentItems = {}
94+
self.algorithmItem = None
95+
9096
self.resize(650, 450)
9197
self.buttonBox = QDialogButtonBox()
9298
self.buttonBox.setOrientation(Qt.Horizontal)
@@ -114,6 +120,10 @@ def setupUi(self):
114120
line.setFrameShape(QFrame.HLine)
115121
line.setFrameShadow(QFrame.Sunken)
116122
self.verticalLayout.addWidget(line)
123+
self.algorithmItem = QgsGui.instance().processingGuiRegistry().algorithmConfigurationWidget(self._alg)
124+
if self.configuration:
125+
self.algorithmItem.setConfiguration(self.configuration)
126+
self.verticalLayout.addWidget(self.algorithmItem)
117127

118128
for param in self._alg.parameterDefinitions():
119129
if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
@@ -284,6 +294,9 @@ def createAlgorithm(self):
284294
else:
285295
alg.setChildId(self.childId)
286296
alg.setDescription(self.descriptionBox.text())
297+
if self.algorithmItem:
298+
alg.setConfiguration(self.algorithmItem.configuration())
299+
self._alg = alg.algorithm().create(self.algorithmItem.configuration())
287300
for param in self._alg.parameterDefinitions():
288301
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
289302
continue
@@ -320,6 +333,14 @@ def createAlgorithm(self):
320333
output.setChildId(alg.childId())
321334
output.setChildOutputName(dest.name())
322335
outputs[name] = output
336+
337+
if dest.flags() & QgsProcessingParameterDefinition.FlagIsModelOutput:
338+
if dest.name() not in outputs:
339+
output = QgsProcessingModelOutput(dest.name(), dest.name())
340+
output.setChildId(alg.childId())
341+
output.setChildOutputName(dest.name())
342+
outputs[dest.name()] = output
343+
323344
alg.setModelOutputs(outputs)
324345

325346
selectedOptions = self.dependenciesPanel.selectedoptions

python/plugins/processing/tests/QgisAlgorithmsTest.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import nose2
3131
import shutil
32+
import os
3233

3334
from qgis.core import (QgsApplication,
3435
QgsProcessingAlgorithm,
@@ -37,6 +38,8 @@
3738
from qgis.analysis import (QgsNativeAlgorithms)
3839
from qgis.testing import start_app, unittest
3940
from processing.tools.dataobjects import createContext
41+
from processing.core.ProcessingConfig import ProcessingConfig
42+
from processing.modeler.ModelerUtils import ModelerUtils
4043

4144

4245
class TestAlg(QgsProcessingAlgorithm):
@@ -66,19 +69,22 @@ class TestQgisAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
6669
@classmethod
6770
def setUpClass(cls):
6871
start_app()
69-
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
7072
from processing.core.Processing import Processing
7173
Processing.initialize()
74+
ProcessingConfig.setSettingValue(ModelerUtils.MODELS_FOLDER, os.path.join(os.path.dirname(__file__), 'models'))
75+
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
7276
cls.cleanup_paths = []
7377
cls.in_place_layers = {}
7478
cls.vector_layer_params = {}
79+
cls._original_models_folder = ProcessingConfig.getSetting(ModelerUtils.MODELS_FOLDER)
7580

7681
@classmethod
7782
def tearDownClass(cls):
7883
from processing.core.Processing import Processing
7984
Processing.deinitialize()
8085
for path in cls.cleanup_paths:
8186
shutil.rmtree(path)
87+
ProcessingConfig.setSettingValue(ModelerUtils.MODELS_FOLDER, cls._original_models_folder)
8288

8389
def test_definition_file(self):
8490
return 'qgis_algorithm_tests.yaml'

0 commit comments

Comments
 (0)