Skip to content

Commit

Permalink
Expose fields mapping parameter to modeler
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Mar 1, 2018
1 parent eba96fb commit 592c9b2
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 51 deletions.
89 changes: 46 additions & 43 deletions python/plugins/processing/algs/qgis/FieldsMapper.py
Expand Up @@ -54,49 +54,8 @@ def tags(self):
return self.tr('attributes,table').split(',')

def initParameters(self, config=None):

class ParameterFieldsMapping(QgsProcessingParameterDefinition):

def __init__(self, name, description, parentLayerParameterName='INPUT'):
super().__init__(name, description)
self._parentLayerParameter = parentLayerParameterName

def clone(self):
copy = ParameterFieldsMapping(self.name(), self.description(), self._parentLayerParameter)
return copy

def type(self):
return 'fields_mapping'

def checkValueIsAcceptable(self, value, context=None):
if not isinstance(value, list):
return False
for field_def in value:
if not isinstance(field_def, dict):
return False
if 'name' not in field_def.keys():
return False
if 'type' not in field_def.keys():
return False
if 'expression' not in field_def.keys():
return False
return True

def valueAsPythonString(self, value, context):
return str(value)

def asScriptCode(self):
raise NotImplementedError()

@classmethod
def fromScriptCode(cls, name, description, isOptional, definition):
raise NotImplementedError()

def parentLayerParameter(self):
return self._parentLayerParameter

fields_mapping = ParameterFieldsMapping(self.FIELDS_MAPPING,
description=self.tr('Fields mapping'))
fields_mapping = FieldsMapper.ParameterFieldsMapping(self.FIELDS_MAPPING,
description=self.tr('Fields mapping'))
fields_mapping.setMetadata({
'widget_wrapper': 'processing.algs.qgis.ui.FieldsMappingPanel.FieldsMappingWidgetWrapper'
})
Expand Down Expand Up @@ -181,3 +140,47 @@ def processFeature(self, feature, context, feedback):
feature.setAttributes(attributes)
self._row_number += 1
return [feature]

class ParameterFieldsMapping(QgsProcessingParameterDefinition):

def __init__(self, name, description='', parentLayerParameterName='INPUT'):
super().__init__(name, description)
self._parentLayerParameter = parentLayerParameterName

def clone(self):
copy = FieldsMapper.ParameterFieldsMapping(self.name(), self.description(), self._parentLayerParameter)
return copy

def type(self):
return self.typeName()

@staticmethod
def typeName():
return 'fields_mapping'

def checkValueIsAcceptable(self, value, context=None):
if not isinstance(value, list):
return False
for field_def in value:
if not isinstance(field_def, dict):
return False
if 'name' not in field_def.keys():
return False
if 'type' not in field_def.keys():
return False
if 'expression' not in field_def.keys():
return False
return True

def valueAsPythonString(self, value, context):
return str(value)

def asScriptCode(self):
raise NotImplementedError()

@classmethod
def fromScriptCode(cls, name, description, isOptional, definition):
raise NotImplementedError()

def parentLayerParameter(self):
return self._parentLayerParameter
27 changes: 27 additions & 0 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Expand Up @@ -36,6 +36,8 @@
from qgis.core import (QgsApplication,
QgsProcessingProvider)

from PyQt5.QtCore import QCoreApplication

from processing.script import ScriptUtils

from .QgisAlgorithm import QgisAlgorithm
Expand Down Expand Up @@ -154,6 +156,7 @@


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

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -317,5 +320,29 @@ def loadAlgorithms(self):
for a in self.externalAlgs:
self.addAlgorithm(a)

def load(self):
success = super().load()

from processing.core.Processing import Processing

if success:
Processing.registerParameter(
'Fields Mapper',
self.fieldMappingParameterName,
parameter=FieldsMapper.ParameterFieldsMapping,
metadata={'widget_wrapper': 'processing.algs.qgis.ui.FieldsMappingPanel.FieldsMappingWidgetWrapper'}
)

return success

def unload(self):
super().unload()
from processing.core.Processing import Processing
Processing.unregisterParameter(self.fieldMappingParameterName)

def createParameter(self, type, name):
if type == 'fields_mapping':
return FieldsMapper.ParameterFieldsMapping(name)

def supportsNonFileBasedOutput(self):
return True
51 changes: 43 additions & 8 deletions python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py
Expand Up @@ -36,6 +36,7 @@
QVariant,
Qt,
pyqtSlot,
QCoreApplication
)
from qgis.PyQt.QtWidgets import (
QComboBox,
Expand All @@ -45,6 +46,8 @@
QMessageBox,
QSpinBox,
QStyledItemDelegate,
QWidget,
QVBoxLayout
)

from qgis.core import (
Expand All @@ -58,8 +61,9 @@
)
from qgis.gui import QgsFieldExpressionWidget

from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER, DIALOG_BATCH
from processing.tools import dataobjects
from processing.algs.qgis.FieldsMapper import FieldsMapper


pluginPath = os.path.dirname(__file__)
Expand Down Expand Up @@ -141,7 +145,10 @@ def columnCount(self, parent=QModelIndex()):
def rowCount(self, parent=QModelIndex()):
if parent.isValid():
return 0
return self._mapping.__len__()
try:
return len(self._mapping)
except TypeError:
return 0

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

def createWidget(self):
panel = FieldsMappingPanel()
panel.dialogType = self.dialogType
return panel
self.panel = FieldsMappingPanel()
self.panel.dialogType = self.dialogType

if self.dialogType == DIALOG_MODELER:
self.combobox = QComboBox()
self.combobox.addItem(QCoreApplication.translate('Processing', '[Preconfigure]'), None)
fieldsMappingInputs = self.dialog.getAvailableValuesOfType(FieldsMapper.ParameterFieldsMapping)
for input in fieldsMappingInputs:
self.combobox.addItem(self.dialog.resolveValueDescription(input), input)

def updatePanelEnabledState():
if self.combobox.currentData() is None:
self.panel.setEnabled(True)
else:
self.panel.setEnabled(False)

self.combobox.currentIndexChanged.connect(updatePanelEnabledState)

widget = QWidget()
widget.setLayout(QVBoxLayout())
widget.layout().addWidget(self.combobox)
widget.layout().addWidget(self.panel)
return widget
else:
return self.panel

def postInitialize(self, wrappers):
for wrapper in wrappers:
Expand Down Expand Up @@ -506,10 +535,16 @@ def setLayer(self, layer):
if not isinstance(layer, QgsVectorLayer):
layer = None
self._layer = layer
self.widget.setLayer(self._layer)
self.panel.setLayer(self._layer)

def setValue(self, value):
self.widget.setValue(value)
self.panel.setValue(value)

def value(self):
return self.widget.value()
if self.dialogType == DIALOG_MODELER:
if self.combobox.currentData() is None:
return self.panel.value()
else:
return self.comboValue(combobox=self.combobox)
else:
return self.panel.value()

0 comments on commit 592c9b2

Please sign in to comment.