Create FieldMappingWrapper

This commit is contained in:
arnaud.morvan@camptocamp.com 2016-09-17 23:33:42 +02:00 committed by volaya
parent affc8f7ca5
commit a38c13d523
4 changed files with 40 additions and 154 deletions

View File

@ -37,8 +37,6 @@ from processing.core.outputs import OutputVector
from processing.tools import dataobjects, vector
from .fieldsmapping import ParameterFieldsMapping
from .ui.FieldsMapperDialogs import (FieldsMapperParametersDialog,
FieldsMapperModelerParametersDialog)
class FieldsMapper(GeoAlgorithm):
@ -151,9 +149,3 @@ class FieldsMapper(GeoAlgorithm):
raise GeoAlgorithmExecutionException(
self.tr('An error occurred while evaluating the calculation'
' string:\n') + error)
def getCustomParametersDialog(self):
return FieldsMapperParametersDialog(self)
def getCustomModelerParametersDialog(self, modelAlg, algName=None):
return FieldsMapperModelerParametersDialog(self, modelAlg, algName)

View File

@ -33,6 +33,10 @@ from processing.core.parameters import Parameter
class ParameterFieldsMapping(Parameter):
default_metadata = {
'widget_wrapper': 'processing.algs.qgis.ui.FieldsMappingPanel.FieldsMappingWidgetWrapper'
}
def __init__(self, name='', description='', parent=None):
Parameter.__init__(self, name, description)
self.parent = parent

View File

@ -1,143 +0,0 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
FieldsMapper.py
---------------------
Date : October 2014
Copyright : (C) 2014 by Arnaud Morvan
Email : arnaud dot morvan at camptocamp dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
from builtins import str
__author__ = 'Arnaud Morvan'
__date__ = 'October 2014'
__copyright__ = '(C) 2014, Arnaud Morvan'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
from qgis.PyQt.QtWidgets import QComboBox, QSpacerItem
from processing.core.parameters import ParameterVector
from processing.tools import dataobjects
from processing.gui.ParametersPanel import ParametersPanel
from processing.gui.AlgorithmDialog import AlgorithmDialog, AlgorithmDialogBase
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
from processing.algs.qgis.fieldsmapping import ParameterFieldsMapping
from .FieldsMappingPanel import FieldsMappingPanel
class FieldsMapperParametersPanel(ParametersPanel):
def __init__(self, parent, alg):
ParametersPanel.__init__(self, parent, alg)
item = self.layoutMain.itemAt(self.layoutMain.count() - 1)
if isinstance(item, QSpacerItem):
self.layoutMain.removeItem(item)
item = None
def getWidgetFromParameter(self, param):
if isinstance(param, ParameterFieldsMapping):
item = FieldsMappingPanel()
if param.parent in self.dependentItems:
items = self.dependentItems[param.parent]
else:
items = []
self.dependentItems[param.parent] = items
items.append(param)
parent = self.alg.getParameterFromName(param.parent)
if isinstance(parent, ParameterVector):
layers = dataobjects.getVectorLayers(parent.shapetype)
else:
layers = dataobjects.getTables()
if len(layers) > 0:
item.setLayer(layers[0])
return item
return ParametersPanel.getWidgetFromParameter(self, param)
def updateDependentFields(self):
sender = self.sender()
if not isinstance(sender, QComboBox):
return
if sender.name not in self.dependentItems:
return
layer = sender.itemData(sender.currentIndex())
children = self.dependentItems[sender.name]
for child in children:
widget = self.valueItems[child.name]
if isinstance(widget, FieldsMappingPanel):
widget.setLayer(layer)
ParametersPanel.updateDependentFields(self)
def somethingDependsOnThisParameter(self, parent):
for param in self.alg.parameters:
if isinstance(param, ParameterFieldsMapping):
if param.parent == parent.name:
return True
return ParametersPanel.somethingDependsOnThisParameter(self, parent)
class FieldsMapperParametersDialog(AlgorithmDialog):
def __init__(self, alg):
AlgorithmDialogBase.__init__(self, alg)
self.alg = alg
self.setMainWidget(FieldsMapperParametersPanel(self, alg))
def setParamValue(self, param, widget, alg=None):
if isinstance(param, ParameterFieldsMapping):
return param.setValue(widget.value())
return AlgorithmDialog.setParamValue(self, param, widget, alg)
class FieldsMapperModelerParametersDialog(ModelerParametersDialog):
def __init__(self, alg, model, algName=None):
ModelerParametersDialog.__init__(self, alg, model, algName)
paramsLayout = self.paramPanel.layout()
item = paramsLayout.itemAt(paramsLayout.count() - 1)
if isinstance(item, QSpacerItem):
paramsLayout.removeItem(item)
item = None
def getWidgetFromParameter(self, param):
if isinstance(param, ParameterFieldsMapping):
return FieldsMappingPanel()
return ModelerParametersDialog.getWidgetFromParameter(self, param)
def setPreviousValues(self):
ModelerParametersDialog.setPreviousValues(self)
if self._algName is not None:
alg = self.model.algs[self._algName]
for param in alg.algorithm.parameters:
if isinstance(param, ParameterFieldsMapping):
widget = self.valueItems[param.name]
value = alg.params[param.name]
if isinstance(value, str):
# convert to list because of ModelerAlgorithme.resolveValue behavior with lists
value = eval(value)
widget.setValue(value)
def setParamValue(self, alg, param, widget):
if isinstance(param, ParameterFieldsMapping):
# convert to unicode because of ModelerAlgorithme.resolveValue behavior with lists
alg.params[param.name] = str(widget.value())
return True
return ModelerParametersDialog.setParamValue(self, alg, param, widget)

View File

@ -31,13 +31,14 @@ import os
from collections import OrderedDict
from qgis.PyQt import uic
from qgis.PyQt.QtGui import QBrush, QIcon
from qgis.PyQt.QtGui import QBrush, QIcon, QSpacerItem
from qgis.PyQt.QtWidgets import QComboBox, QHeaderView, QLineEdit, QMessageBox, QSpinBox, QStyledItemDelegate
from qgis.PyQt.QtCore import QItemSelectionModel, QAbstractTableModel, QModelIndex, QVariant, Qt, pyqtSlot
from qgis.core import QgsExpression, QgsExpressionContextUtils, QgsApplication
from qgis.core import QgsExpression, QgsExpressionContextUtils, QgsApplication, QgsFeature
from qgis.gui import QgsFieldExpressionWidget
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
from processing.tools import dataobjects
pluginPath = os.path.dirname(__file__)
@ -93,7 +94,7 @@ class FieldsMappingModel(QAbstractTableModel):
if self._layer is None:
return
context = QgsExpressionContextUtils.createFeatureBasedContext(QgsFeature(), self._layer.fields())
for feature in dp.getFeatures():
for feature in self._layer.getFeatures():
context.setFeature(feature)
expression.evaluate(context)
if expression.hasEvalError():
@ -473,3 +474,35 @@ class FieldsMappingPanel(BASE, WIDGET):
if layer is None:
return
self.model.loadLayerFields(layer)
class FieldsMappingWidgetWrapper(WidgetWrapper):
def createWidget(self):
return FieldsMappingPanel()
def postInitialize(self, wrappers):
for wrapper in wrappers:
if wrapper.param.name == self.param.parent:
wrapper.widgetValueHasChanged.connect(self.parentLayerChanged)
break
layers = dataobjects.getTables()
if len(layers) > 0:
# as first item in combobox is already selected
self.widget.setLayer(layers[0])
# remove exiting spacers to get FieldsMappingPanel fully expanded
if self.dialogType in (DIALOG_STANDARD, DIALOG_MODELER):
layout = self.widget.parent().layout()
spacer = layout.itemAt(layout.count() - 1)
if isinstance(spacer, QSpacerItem):
layout.removeItem(spacer)
def parentLayerChanged(self):
self.widget.setLayer(self.sender().value())
def setValue(self, value):
self.widget.setValue(value)
def value(self):
return self.widget.value()