Skip to content

Commit

Permalink
Merge pull request #6754 from m-kuhn/processing_filter_algorithm
Browse files Browse the repository at this point in the history
 [FEATURE] Feature filter algorithm for processing models
  • Loading branch information
m-kuhn committed Apr 11, 2018
2 parents 9dc3ee4 + fbb4ef5 commit 29b080f
Show file tree
Hide file tree
Showing 43 changed files with 1,343 additions and 40 deletions.
4 changes: 1 addition & 3 deletions python/core/processing/qgsprocessingalgorithm.sip.in
Expand Up @@ -10,12 +10,10 @@




%ModuleHeaderCode
#include <qgsprocessingmodelalgorithm.h>
%End


class QgsProcessingAlgorithm
{
%Docstring
Expand Down Expand Up @@ -276,7 +274,7 @@ Returns true if this algorithm generates HTML outputs.
%End

QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0 ) const;
QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0, const QVariantMap &configuration = QVariantMap() ) const;
%Docstring
Executes the algorithm using the specified ``parameters``. This method internally
creates a copy of the algorithm before running it, so it is safe to call
Expand Down
1 change: 1 addition & 0 deletions python/core/processing/qgsprocessingparameters.sip.in
Expand Up @@ -168,6 +168,7 @@ their acceptable ranges, defaults, etc.
FlagAdvanced,
FlagHidden,
FlagOptional,
FlagIsModelOutput,
};
typedef QFlags<QgsProcessingParameterDefinition::Flag> Flags;

Expand Down
1 change: 0 additions & 1 deletion python/core/processing/qgsprocessingregistry.sip.in
Expand Up @@ -143,7 +143,6 @@ Return a list with all known parameter types.
.. versionadded:: 3.2
%End


signals:

void providerAdded( const QString &id );
Expand Down
2 changes: 2 additions & 0 deletions python/gui/gui_auto.sip
Expand Up @@ -45,6 +45,7 @@
%Include layertree/qgslayertreeembeddedconfigwidget.sip
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
%Include layout/qgslayoutviewmouseevent.sip
%Include processing/qgsprocessingguiregistry.sip
%Include raster/qgsrasterrendererwidget.sip
%Include symbology/qgssymbolwidgetcontext.sip
%Include qgisinterface.sip
Expand Down Expand Up @@ -311,5 +312,6 @@
%Include layout/qgslayoutviewtooltemporarymousepan.sip
%Include layout/qgslayoutviewtoolzoom.sip
%Include locator/qgslocatorwidget.sip
%Include processing/qgsprocessingalgorithmconfigurationwidget.sip
%Include processing/qgsprocessingalgorithmdialogbase.sip
%Include qgsadvanceddigitizingcanvasitem.sip
@@ -0,0 +1,79 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/







class QgsProcessingAlgorithmConfigurationWidget : QWidget
{
%Docstring
A configuration widget for processing algorithms allows providing additional
configuration options directly on algorithm level, in addition to parameters.

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsprocessingalgorithmconfigurationwidget.h"
%End
public:

QgsProcessingAlgorithmConfigurationWidget( QWidget *parent = 0 );
%Docstring
Creates a new QgsProcessingAlgorithmConfigurationWidget
%End
virtual ~QgsProcessingAlgorithmConfigurationWidget();

virtual QVariantMap configuration() const = 0;
%Docstring
Read the current configuration from this widget.
%End

virtual void setConfiguration( const QVariantMap &configuration ) = 0;
%Docstring
Set the configuration which this widget should represent.
%End
};


class QgsProcessingAlgorithmConfigurationWidgetFactory
{
%Docstring
Interface base class for factories for algorithm configuration widgets.

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsprocessingalgorithmconfigurationwidget.h"
%End
public:
virtual ~QgsProcessingAlgorithmConfigurationWidgetFactory();

virtual QgsProcessingAlgorithmConfigurationWidget *create( const QgsProcessingAlgorithm *algorithm ) const = 0 /Factory/;
%Docstring
Create a new configuration widget for ``algorithm``.
%End

virtual bool canCreateFor( const QgsProcessingAlgorithm *algorithm ) const = 0;
%Docstring
Check if this factory can create widgets for ``algorithm``.
%End
};


/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
Empty file.
68 changes: 68 additions & 0 deletions python/gui/processing/qgsprocessingguiregistry.sip.in
@@ -0,0 +1,68 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingguiregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsProcessingGuiRegistry
{
%Docstring
The QgsProcessingGuiRegistry is a home for widgets for processing
configuration widgets.

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsprocessingguiregistry.h"
%End
public:

QgsProcessingGuiRegistry();
%Docstring
Constructor. Should never be called manually, is already
created by :py:class:`QgsGui`.
%End
~QgsProcessingGuiRegistry();

void addAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory /Transfer/ );
%Docstring
Add a new configuration widget factory for customized algorithm configuration
widgets. Ownership is taken.

.. versionadded:: 3.2
%End

void removeAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory );
%Docstring
Remove a configuration widget factory for customized algorithm configuration
widgets.

.. versionadded:: 3.2
%End

QgsProcessingAlgorithmConfigurationWidget *algorithmConfigurationWidget( const QgsProcessingAlgorithm *algorithm ) const;
%Docstring
Get the configuration widget for an ``algorithm``. This widget will be shown
next to parameter widgets. Most algorithms do not have a configuration widget
and in this case, None will be returned.

.. versionadded:: 3.2
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingguiregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
7 changes: 7 additions & 0 deletions python/gui/qgsgui.sip.in
Expand Up @@ -60,6 +60,13 @@ Returns the global map layer action registry, used for registering map layer act
static QgsLayoutItemGuiRegistry *layoutItemGuiRegistry();
%Docstring
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
%End

static QgsProcessingGuiRegistry *processingGuiRegistry();
%Docstring
Returns the global processing gui registry, used for registering the GUI behavior of processing algorithms.

.. versionadded:: 3.2
%End

static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() );
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/modeler/ModelerGraphicItem.py
Expand Up @@ -208,7 +208,7 @@ def editElement(self):
self.scene.dialog.repaintModel()
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
elemAlg = self.element.algorithm()
dlg = ModelerParametersDialog(elemAlg, self.model, self.element.childId())
dlg = ModelerParametersDialog(elemAlg, self.model, self.element.childId(), self.element.configuration())
if dlg.exec_():
alg = dlg.createAlgorithm()
alg.setChildId(self.element.childId())
Expand Down
25 changes: 23 additions & 2 deletions python/plugins/processing/modeler/ModelerParametersDialog.py
Expand Up @@ -36,6 +36,7 @@
QHBoxLayout, QWidget)

from qgis.core import (Qgis,
QgsApplication,
QgsProcessingParameterDefinition,
QgsProcessingParameterPoint,
QgsProcessingParameterExtent,
Expand All @@ -52,7 +53,8 @@
QgsProcessingOutputDefinition,
QgsSettings)

from qgis.gui import (QgsMessageBar,
from qgis.gui import (QgsGui,
QgsMessageBar,
QgsScrollArea,
QgsFilterLineEdit,
QgsHelp)
Expand All @@ -63,13 +65,15 @@


class ModelerParametersDialog(QDialog):
def __init__(self, alg, model, algName=None):

def __init__(self, alg, model, algName=None, configuration=None):
QDialog.__init__(self)
self.setModal(True)

self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm
self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm
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
self.configuration = configuration

self.setupUi()
self.params = None
Expand All @@ -87,6 +91,8 @@ def setupUi(self):
self.wrappers = {}
self.valueItems = {}
self.dependentItems = {}
self.algorithmItem = None

self.resize(650, 450)
self.buttonBox = QDialogButtonBox()
self.buttonBox.setOrientation(Qt.Horizontal)
Expand Down Expand Up @@ -114,6 +120,10 @@ def setupUi(self):
line.setFrameShape(QFrame.HLine)
line.setFrameShadow(QFrame.Sunken)
self.verticalLayout.addWidget(line)
self.algorithmItem = QgsGui.instance().processingGuiRegistry().algorithmConfigurationWidget(self._alg)
if self.configuration:
self.algorithmItem.setConfiguration(self.configuration)
self.verticalLayout.addWidget(self.algorithmItem)

for param in self._alg.parameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
Expand Down Expand Up @@ -284,6 +294,9 @@ def createAlgorithm(self):
else:
alg.setChildId(self.childId)
alg.setDescription(self.descriptionBox.text())
if self.algorithmItem:
alg.setConfiguration(self.algorithmItem.configuration())
self._alg = alg.algorithm().create(self.algorithmItem.configuration())
for param in self._alg.parameterDefinitions():
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
Expand Down Expand Up @@ -320,6 +333,14 @@ def createAlgorithm(self):
output.setChildId(alg.childId())
output.setChildOutputName(dest.name())
outputs[name] = output

if dest.flags() & QgsProcessingParameterDefinition.FlagIsModelOutput:
if dest.name() not in outputs:
output = QgsProcessingModelOutput(dest.name(), dest.name())
output.setChildId(alg.childId())
output.setChildOutputName(dest.name())
outputs[dest.name()] = output

alg.setModelOutputs(outputs)

selectedOptions = self.dependenciesPanel.selectedoptions
Expand Down
8 changes: 7 additions & 1 deletion python/plugins/processing/tests/QgisAlgorithmsTest.py
Expand Up @@ -29,6 +29,7 @@

import nose2
import shutil
import os

from qgis.core import (QgsApplication,
QgsProcessingAlgorithm,
Expand All @@ -37,6 +38,8 @@
from qgis.analysis import (QgsNativeAlgorithms)
from qgis.testing import start_app, unittest
from processing.tools.dataobjects import createContext
from processing.core.ProcessingConfig import ProcessingConfig
from processing.modeler.ModelerUtils import ModelerUtils


class TestAlg(QgsProcessingAlgorithm):
Expand Down Expand Up @@ -66,19 +69,22 @@ class TestQgisAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
@classmethod
def setUpClass(cls):
start_app()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
from processing.core.Processing import Processing
Processing.initialize()
ProcessingConfig.setSettingValue(ModelerUtils.MODELS_FOLDER, os.path.join(os.path.dirname(__file__), 'models'))
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
cls.cleanup_paths = []
cls.in_place_layers = {}
cls.vector_layer_params = {}
cls._original_models_folder = ProcessingConfig.getSetting(ModelerUtils.MODELS_FOLDER)

@classmethod
def tearDownClass(cls):
from processing.core.Processing import Processing
Processing.deinitialize()
for path in cls.cleanup_paths:
shutil.rmtree(path)
ProcessingConfig.setSettingValue(ModelerUtils.MODELS_FOLDER, cls._original_models_folder)

def test_definition_file(self):
return 'qgis_algorithm_tests.yaml'
Expand Down

0 comments on commit 29b080f

Please sign in to comment.