Skip to content
Permalink
Browse files

[processing] Input parameter name for in place algorithms is not

always fixed, so ensure we correctly obtain and use the correct
input parameter name

(cherry picked from commit 0a2b99c)
  • Loading branch information
nyalldawson committed Feb 19, 2021
1 parent 122725b commit ac6df582156bdc141f5894a51ff4cde7bed706f8
@@ -72,7 +72,11 @@ def __init__(self, alg, in_place=False, parent=None):
self.buttonBox().addButton(self.runAsBatchButton,
QDialogButtonBox.ResetRole) # reset role to ensure left alignment
else:
self.mainWidget().setParameters({'INPUT': self.active_layer})
in_place_input_parameter_name = 'INPUT'
if hasattr(alg, 'inputParameterName'):
in_place_input_parameter_name = alg.inputParameterName()

self.mainWidget().setParameters({in_place_input_parameter_name: self.active_layer})

self.runAsBatchButton = None
has_selection = self.active_layer and (self.active_layer.selectedFeatureCount() > 0)
@@ -102,7 +102,11 @@ def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exc
except AttributeError:
pass

active_layer = parameters['INPUT']
in_place_input_parameter_name = 'INPUT'
if hasattr(alg, 'inputParameterName'):
in_place_input_parameter_name = alg.inputParameterName()

active_layer = parameters[in_place_input_parameter_name]

# Run some checks and prepare the layer for in-place execution by:
# - getting the active layer and checking that it is a vector
@@ -137,7 +141,7 @@ def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exc
active_layer.selectAll()

# Make sure we are working on selected features only
parameters['INPUT'] = QgsProcessingFeatureSourceDefinition(active_layer.id(), True)
parameters[in_place_input_parameter_name] = QgsProcessingFeatureSourceDefinition(active_layer.id(), True)
parameters['OUTPUT'] = 'memory:'

req = QgsFeatureRequest(QgsExpression(r"$id < 0"))
@@ -300,14 +304,21 @@ def execute_in_place(alg, parameters, context=None, feedback=None):
if context is None:
context = dataobjects.createContext(feedback)

if 'INPUT' not in parameters or not parameters['INPUT']:
parameters['INPUT'] = iface.activeLayer()
in_place_input_parameter_name = 'INPUT'
if hasattr(alg, 'inputParameterName'):
in_place_input_parameter_name = alg.inputParameterName()
in_place_input_layer_name = 'INPUT'
if hasattr(alg, 'inputParameterDescription'):
in_place_input_layer_name = alg.inputParameterDescription()

if in_place_input_parameter_name not in parameters or not parameters[in_place_input_parameter_name]:
parameters[in_place_input_parameter_name] = iface.activeLayer()
ok, results = execute_in_place_run(alg, parameters, context=context, feedback=feedback)
if ok:
if isinstance(parameters['INPUT'], QgsProcessingFeatureSourceDefinition):
layer = alg.parameterAsVectorLayer({'INPUT': parameters['INPUT'].source}, 'INPUT', context)
elif isinstance(parameters['INPUT'], QgsVectorLayer):
layer = parameters['INPUT']
if isinstance(parameters[in_place_input_parameter_name], QgsProcessingFeatureSourceDefinition):
layer = alg.parameterAsVectorLayer({in_place_input_parameter_name: parameters[in_place_input_parameter_name].source}, in_place_input_layer_name, context)
elif isinstance(parameters[in_place_input_parameter_name], QgsVectorLayer):
layer = parameters[in_place_input_parameter_name]
if layer:
layer.triggerRepaint()
return ok, results
@@ -188,8 +188,12 @@ def triggerResult(self, result):
dlg.exec_()
return

in_place_input_parameter_name = 'INPUT'
if hasattr(alg, 'inputParameterName'):
in_place_input_parameter_name = alg.inputParameterName()

if [d for d in alg.parameterDefinitions() if
d.name() not in ('INPUT', 'OUTPUT')]:
d.name() not in (in_place_input_parameter_name, 'OUTPUT')]:
dlg = alg.createCustomParametersWidget(parent=iface.mainWindow())
if not dlg:
dlg = AlgorithmDialog(alg, True, parent=iface.mainWindow())
@@ -94,6 +94,10 @@ def initWidgets(self):
if isinstance(self.algorithm(), QgsProcessingModelAlgorithm):
widget_context.setModel(self.algorithm())

in_place_input_parameter_name = 'INPUT'
if hasattr(self.algorithm(), 'inputParameterName'):
in_place_input_parameter_name = self.algorithm().inputParameterName()

# Create widgets and put them in layouts
for param in self.algorithm().parameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
@@ -102,7 +106,7 @@ def initWidgets(self):
if param.isDestination():
continue
else:
if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
if self.in_place and param.name() in (in_place_input_parameter_name, 'OUTPUT'):
# don't show the input/output parameter widgets in in-place mode
# we still need to CREATE them, because other wrappers may need to interact
# with them (e.g. those parameters which need the input layer for field
@@ -155,7 +159,7 @@ def initWidgets(self):
if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue

if self.in_place and output.name() in ('INPUT', 'OUTPUT'):
if self.in_place and output.name() in (in_place_input_parameter_name, 'OUTPUT'):
continue

wrapper = QgsGui.processingGuiRegistry().createParameterWidgetWrapper(output, QgsProcessingGui.Standard)
@@ -248,7 +248,11 @@ def executeAlgorithm(self):
dlg.exec_()
return

if self.in_place_mode and not [d for d in alg.parameterDefinitions() if d.name() not in ('INPUT', 'OUTPUT')]:
in_place_input_parameter_name = 'INPUT'
if hasattr(alg, 'inputParameterName'):
in_place_input_parameter_name = alg.inputParameterName()

if self.in_place_mode and not [d for d in alg.parameterDefinitions() if d.name() not in (in_place_input_parameter_name, 'OUTPUT')]:
parameters = {}
feedback = MessageBarProgress(algname=alg.displayName())
ok, results = execute_in_place(alg, parameters, feedback=feedback)

0 comments on commit ac6df58

Please sign in to comment.