From a38c13d523c8aa7fc70fb0970a73af18fe8fa216 Mon Sep 17 00:00:00 2001 From: "arnaud.morvan@camptocamp.com" Date: Sat, 17 Sep 2016 23:33:42 +0200 Subject: [PATCH] Create FieldMappingWrapper --- .../processing/algs/qgis/FieldsMapper.py | 8 - .../processing/algs/qgis/fieldsmapping.py | 4 + .../algs/qgis/ui/FieldsMapperDialogs.py | 143 ------------------ .../algs/qgis/ui/FieldsMappingPanel.py | 39 ++++- 4 files changed, 40 insertions(+), 154 deletions(-) delete mode 100644 python/plugins/processing/algs/qgis/ui/FieldsMapperDialogs.py diff --git a/python/plugins/processing/algs/qgis/FieldsMapper.py b/python/plugins/processing/algs/qgis/FieldsMapper.py index 609e292a181..3f74bcac418 100644 --- a/python/plugins/processing/algs/qgis/FieldsMapper.py +++ b/python/plugins/processing/algs/qgis/FieldsMapper.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/fieldsmapping.py b/python/plugins/processing/algs/qgis/fieldsmapping.py index e85ec663c59..12f4750a440 100644 --- a/python/plugins/processing/algs/qgis/fieldsmapping.py +++ b/python/plugins/processing/algs/qgis/fieldsmapping.py @@ -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 diff --git a/python/plugins/processing/algs/qgis/ui/FieldsMapperDialogs.py b/python/plugins/processing/algs/qgis/ui/FieldsMapperDialogs.py deleted file mode 100644 index c90f46bec1e..00000000000 --- a/python/plugins/processing/algs/qgis/ui/FieldsMapperDialogs.py +++ /dev/null @@ -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) diff --git a/python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py b/python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py index 6e24d1f1cb8..02cb595c1ad 100644 --- a/python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py +++ b/python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py @@ -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()