Skip to content

Commit 592c9b2

Browse files
committed
Expose fields mapping parameter to modeler
1 parent eba96fb commit 592c9b2

File tree

3 files changed

+116
-51
lines changed

3 files changed

+116
-51
lines changed

python/plugins/processing/algs/qgis/FieldsMapper.py

+46-43
Original file line numberDiff line numberDiff line change
@@ -54,49 +54,8 @@ def tags(self):
5454
return self.tr('attributes,table').split(',')
5555

5656
def initParameters(self, config=None):
57-
58-
class ParameterFieldsMapping(QgsProcessingParameterDefinition):
59-
60-
def __init__(self, name, description, parentLayerParameterName='INPUT'):
61-
super().__init__(name, description)
62-
self._parentLayerParameter = parentLayerParameterName
63-
64-
def clone(self):
65-
copy = ParameterFieldsMapping(self.name(), self.description(), self._parentLayerParameter)
66-
return copy
67-
68-
def type(self):
69-
return 'fields_mapping'
70-
71-
def checkValueIsAcceptable(self, value, context=None):
72-
if not isinstance(value, list):
73-
return False
74-
for field_def in value:
75-
if not isinstance(field_def, dict):
76-
return False
77-
if 'name' not in field_def.keys():
78-
return False
79-
if 'type' not in field_def.keys():
80-
return False
81-
if 'expression' not in field_def.keys():
82-
return False
83-
return True
84-
85-
def valueAsPythonString(self, value, context):
86-
return str(value)
87-
88-
def asScriptCode(self):
89-
raise NotImplementedError()
90-
91-
@classmethod
92-
def fromScriptCode(cls, name, description, isOptional, definition):
93-
raise NotImplementedError()
94-
95-
def parentLayerParameter(self):
96-
return self._parentLayerParameter
97-
98-
fields_mapping = ParameterFieldsMapping(self.FIELDS_MAPPING,
99-
description=self.tr('Fields mapping'))
57+
fields_mapping = FieldsMapper.ParameterFieldsMapping(self.FIELDS_MAPPING,
58+
description=self.tr('Fields mapping'))
10059
fields_mapping.setMetadata({
10160
'widget_wrapper': 'processing.algs.qgis.ui.FieldsMappingPanel.FieldsMappingWidgetWrapper'
10261
})
@@ -181,3 +140,47 @@ def processFeature(self, feature, context, feedback):
181140
feature.setAttributes(attributes)
182141
self._row_number += 1
183142
return [feature]
143+
144+
class ParameterFieldsMapping(QgsProcessingParameterDefinition):
145+
146+
def __init__(self, name, description='', parentLayerParameterName='INPUT'):
147+
super().__init__(name, description)
148+
self._parentLayerParameter = parentLayerParameterName
149+
150+
def clone(self):
151+
copy = FieldsMapper.ParameterFieldsMapping(self.name(), self.description(), self._parentLayerParameter)
152+
return copy
153+
154+
def type(self):
155+
return self.typeName()
156+
157+
@staticmethod
158+
def typeName():
159+
return 'fields_mapping'
160+
161+
def checkValueIsAcceptable(self, value, context=None):
162+
if not isinstance(value, list):
163+
return False
164+
for field_def in value:
165+
if not isinstance(field_def, dict):
166+
return False
167+
if 'name' not in field_def.keys():
168+
return False
169+
if 'type' not in field_def.keys():
170+
return False
171+
if 'expression' not in field_def.keys():
172+
return False
173+
return True
174+
175+
def valueAsPythonString(self, value, context):
176+
return str(value)
177+
178+
def asScriptCode(self):
179+
raise NotImplementedError()
180+
181+
@classmethod
182+
def fromScriptCode(cls, name, description, isOptional, definition):
183+
raise NotImplementedError()
184+
185+
def parentLayerParameter(self):
186+
return self._parentLayerParameter

python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py

+27
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
from qgis.core import (QgsApplication,
3737
QgsProcessingProvider)
3838

39+
from PyQt5.QtCore import QCoreApplication
40+
3941
from processing.script import ScriptUtils
4042

4143
from .QgisAlgorithm import QgisAlgorithm
@@ -154,6 +156,7 @@
154156

155157

156158
class QgisAlgorithmProvider(QgsProcessingProvider):
159+
fieldMappingParameterName = QCoreApplication.translate('Processing', 'Fields Mapper')
157160

158161
def __init__(self):
159162
super().__init__()
@@ -317,5 +320,29 @@ def loadAlgorithms(self):
317320
for a in self.externalAlgs:
318321
self.addAlgorithm(a)
319322

323+
def load(self):
324+
success = super().load()
325+
326+
from processing.core.Processing import Processing
327+
328+
if success:
329+
Processing.registerParameter(
330+
'Fields Mapper',
331+
self.fieldMappingParameterName,
332+
parameter=FieldsMapper.ParameterFieldsMapping,
333+
metadata={'widget_wrapper': 'processing.algs.qgis.ui.FieldsMappingPanel.FieldsMappingWidgetWrapper'}
334+
)
335+
336+
return success
337+
338+
def unload(self):
339+
super().unload()
340+
from processing.core.Processing import Processing
341+
Processing.unregisterParameter(self.fieldMappingParameterName)
342+
343+
def createParameter(self, type, name):
344+
if type == 'fields_mapping':
345+
return FieldsMapper.ParameterFieldsMapping(name)
346+
320347
def supportsNonFileBasedOutput(self):
321348
return True

python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py

+43-8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
QVariant,
3737
Qt,
3838
pyqtSlot,
39+
QCoreApplication
3940
)
4041
from qgis.PyQt.QtWidgets import (
4142
QComboBox,
@@ -45,6 +46,8 @@
4546
QMessageBox,
4647
QSpinBox,
4748
QStyledItemDelegate,
49+
QWidget,
50+
QVBoxLayout
4851
)
4952

5053
from qgis.core import (
@@ -58,8 +61,9 @@
5861
)
5962
from qgis.gui import QgsFieldExpressionWidget
6063

61-
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
64+
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER, DIALOG_BATCH
6265
from processing.tools import dataobjects
66+
from processing.algs.qgis.FieldsMapper import FieldsMapper
6367

6468

6569
pluginPath = os.path.dirname(__file__)
@@ -141,7 +145,10 @@ def columnCount(self, parent=QModelIndex()):
141145
def rowCount(self, parent=QModelIndex()):
142146
if parent.isValid():
143147
return 0
144-
return self._mapping.__len__()
148+
try:
149+
return len(self._mapping)
150+
except TypeError:
151+
return 0
145152

146153
def headerData(self, section, orientation, role=Qt.DisplayRole):
147154
if role == Qt.DisplayRole:
@@ -473,9 +480,31 @@ def __init__(self, *args, **kwargs):
473480
self._layer = None
474481

475482
def createWidget(self):
476-
panel = FieldsMappingPanel()
477-
panel.dialogType = self.dialogType
478-
return panel
483+
self.panel = FieldsMappingPanel()
484+
self.panel.dialogType = self.dialogType
485+
486+
if self.dialogType == DIALOG_MODELER:
487+
self.combobox = QComboBox()
488+
self.combobox.addItem(QCoreApplication.translate('Processing', '[Preconfigure]'), None)
489+
fieldsMappingInputs = self.dialog.getAvailableValuesOfType(FieldsMapper.ParameterFieldsMapping)
490+
for input in fieldsMappingInputs:
491+
self.combobox.addItem(self.dialog.resolveValueDescription(input), input)
492+
493+
def updatePanelEnabledState():
494+
if self.combobox.currentData() is None:
495+
self.panel.setEnabled(True)
496+
else:
497+
self.panel.setEnabled(False)
498+
499+
self.combobox.currentIndexChanged.connect(updatePanelEnabledState)
500+
501+
widget = QWidget()
502+
widget.setLayout(QVBoxLayout())
503+
widget.layout().addWidget(self.combobox)
504+
widget.layout().addWidget(self.panel)
505+
return widget
506+
else:
507+
return self.panel
479508

480509
def postInitialize(self, wrappers):
481510
for wrapper in wrappers:
@@ -506,10 +535,16 @@ def setLayer(self, layer):
506535
if not isinstance(layer, QgsVectorLayer):
507536
layer = None
508537
self._layer = layer
509-
self.widget.setLayer(self._layer)
538+
self.panel.setLayer(self._layer)
510539

511540
def setValue(self, value):
512-
self.widget.setValue(value)
541+
self.panel.setValue(value)
513542

514543
def value(self):
515-
return self.widget.value()
544+
if self.dialogType == DIALOG_MODELER:
545+
if self.combobox.currentData() is None:
546+
return self.panel.value()
547+
else:
548+
return self.comboValue(combobox=self.combobox)
549+
else:
550+
return self.panel.value()

0 commit comments

Comments
 (0)