diff --git a/python/plugins/processing/algs/gdal/GdalAlgorithmDialog.py b/python/plugins/processing/algs/gdal/GdalAlgorithmDialog.py index a3093d76c77..6097ef8edff 100644 --- a/python/plugins/processing/algs/gdal/GdalAlgorithmDialog.py +++ b/python/plugins/processing/algs/gdal/GdalAlgorithmDialog.py @@ -78,7 +78,8 @@ class GdalParametersPanel(ParametersPanel): self.parametersHaveChanged() def connectParameterSignals(self): - for w in list(self.widgets.values()): + for wrapper in list(self.wrappers.values()): + w = wrapper.widget if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): diff --git a/python/plugins/processing/core/GeoAlgorithm.py b/python/plugins/processing/core/GeoAlgorithm.py index f7bd2360490..8350d11e964 100644 --- a/python/plugins/processing/core/GeoAlgorithm.py +++ b/python/plugins/processing/core/GeoAlgorithm.py @@ -16,9 +16,6 @@ * * *************************************************************************** """ -from builtins import str -from builtins import object - __author__ = 'Victor Olaya' __date__ = 'August 2012' @@ -38,6 +35,9 @@ from qgis.PyQt.QtCore import QCoreApplication, QSettings from qgis.core import QgsVectorLayer, QgsRasterLayer +from builtins import str +from builtins import object +from processing.gui.ParametersPanel import ParametersPanel from processing.core.ProcessingLog import ProcessingLog from processing.core.ProcessingConfig import ProcessingConfig from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException @@ -46,10 +46,8 @@ from processing.core.parameters import ParameterRaster, ParameterVector, Paramet from processing.core.outputs import OutputVector, OutputRaster, OutputTable, OutputHTML, Output from processing.algs.gdal.GdalUtils import GdalUtils from processing.tools import dataobjects, vector -from processing.tools.system import setTempOutput from processing.algs.help import shortHelp - class GeoAlgorithm(object): def __init__(self): @@ -134,6 +132,10 @@ class GeoAlgorithm(object): """ pass + + def getParametersPanel(self, parent): + return ParametersPanel(parent, self) + def getCustomParametersDialog(self): """If the algorithm has a custom parameters dialog, it should be returned here, ready to be executed. @@ -183,6 +185,12 @@ class GeoAlgorithm(object): calling from the console. """ return None + + def processBeforeAddingToModeler(self, alg, model): + """Add here any task that has to be performed before adding an algorithm + to a model, such as changing the value of a parameter depending on value + of another one""" + pass # ========================================================= diff --git a/python/plugins/processing/core/parameters.py b/python/plugins/processing/core/parameters.py index 8f822e3af80..68e3ffd03df 100644 --- a/python/plugins/processing/core/parameters.py +++ b/python/plugins/processing/core/parameters.py @@ -123,7 +123,6 @@ class Parameter(object): self.optional = parseBool(optional) - # TODO: make deep copy and deep update self.metadata = deepcopy(self.default_metadata) self.metadata.update(deepcopy(metadata)) @@ -179,7 +178,7 @@ class Parameter(object): def wrapper(self, dialog, row=0, col=0): wrapper = self.metadata.get('widget_wrapper', None) # wrapper metadata should be a class path - if isinstance(wrapper, str): + if isinstance(wrapper, basestring): tokens = wrapper.split('.') mod = __import__('.'.join(tokens[:-1]), fromlist=[tokens[-1]]) wrapper = getattr(mod, tokens[-1]) @@ -362,7 +361,10 @@ class ParameterExtent(Parameter): return False def getValueAsCommandLineParameter(self): - return '"' + str(self.value) + '"' + if self.value is not None: + return '"' + str(self.value) + '"' + else: + return str(None) def getAsScriptCode(self): param_type = '' @@ -582,8 +584,8 @@ class ParameterMultipleInput(ParameterDataObject): exported = None - def __init__(self, name='', description='', datatype=-1, optional=False): - ParameterDataObject.__init__(self, name, description, None, optional) + def __init__(self, name='', description='', datatype=-1, optional=False, metadata={}): + ParameterDataObject.__init__(self, name, description, None, optional, metadata=metadata) self.datatype = int(float(datatype)) self.exported = None self.minNumInputs = 0 @@ -1133,8 +1135,8 @@ class ParameterString(Parameter): ESCAPED_NEWLINE = '\\n' def __init__(self, name='', description='', default=None, multiline=False, - optional=False, evaluateExpressions=False): - Parameter.__init__(self, name, description, default, optional) + optional=False, evaluateExpressions=False, metadata={}): + Parameter.__init__(self, name, description, default, optional, metadata) self.multiline = parseBool(multiline) self.evaluateExpressions = parseBool(evaluateExpressions) diff --git a/python/plugins/processing/gui/AlgorithmDialog.py b/python/plugins/processing/gui/AlgorithmDialog.py index 052b6e2cdfa..01915df38ba 100644 --- a/python/plugins/processing/gui/AlgorithmDialog.py +++ b/python/plugins/processing/gui/AlgorithmDialog.py @@ -39,7 +39,6 @@ from processing.core.ProcessingLog import ProcessingLog from processing.core.ProcessingConfig import ProcessingConfig from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog -from processing.gui.ParametersPanel import ParametersPanel from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase from processing.gui.AlgorithmExecutor import runalg, runalgIterating from processing.gui.Postprocessing import handleAlgorithmResults @@ -63,7 +62,7 @@ class AlgorithmDialog(AlgorithmDialogBase): self.alg = alg - self.setMainWidget(ParametersPanel(self, alg)) + self.setMainWidget(alg.getParametersPanel(self)) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) @@ -99,14 +98,17 @@ class AlgorithmDialog(AlgorithmDialogBase): for output in outputs: if output.hidden: continue - output.value = self.mainWidget.valueItems[output.name].getValue() + output.value = self.mainWidget.outputWidgets[output.name].getValue() if isinstance(output, (OutputRaster, OutputVector, OutputTable)): output.open = self.mainWidget.checkBoxes[output.name].isChecked() return True - def setParamValue(self, param, wrapper, alg=None): - return param.setValue(wrapper.value()) + def setParamValue(self, param, wrapper): + if wrapper.widget: + return param.setValue(wrapper.value()) + else: + return True def checkExtentCRS(self): unmatchingCRS = False @@ -131,7 +133,7 @@ class AlgorithmDialog(AlgorithmDialogBase): if p.crs() != projectCRS: unmatchingCRS = True if isinstance(param, ParameterExtent): - value = self.mainWidget.valueItems[param.name].leText.text().strip() + value = self.mainWidget.wrappers[param.name].widget.leText.text().strip() if value: hasExtent = True diff --git a/python/plugins/processing/gui/ExtentSelectionPanel.py b/python/plugins/processing/gui/ExtentSelectionPanel.py index 6ec0d34208a..4ff826716c4 100644 --- a/python/plugins/processing/gui/ExtentSelectionPanel.py +++ b/python/plugins/processing/gui/ExtentSelectionPanel.py @@ -59,7 +59,7 @@ class ExtentSelectionPanel(BASE, WIDGET): if self.param.optional: if hasattr(self.leText, 'setPlaceholderText'): self.leText.setPlaceholderText( - self.tr('[Use "auto" to use min covering extent]')) + self.tr('[Leave blank to use min covering extent]')) self.btnSelect.clicked.connect(self.selectExtent) @@ -104,7 +104,7 @@ class ExtentSelectionPanel(BASE, WIDGET): popupmenu.exec_(QCursor.pos()) def useMinCoveringExtent(self): - self.leText.setText('auto') + self.leText.setText('') def useLayerExtent(self): CANVAS_KEY = 'Use canvas extent' diff --git a/python/plugins/processing/gui/ParametersPanel.py b/python/plugins/processing/gui/ParametersPanel.py index 20ed8b3e493..8bd9b6c0190 100644 --- a/python/plugins/processing/gui/ParametersPanel.py +++ b/python/plugins/processing/gui/ParametersPanel.py @@ -67,10 +67,9 @@ class ParametersPanel(BASE, WIDGET): self.parent = parent self.alg = alg - self.valueItems = {} self.wrappers = {} + self.outputWidgets = {} self.labels = {} - self.widgets = {} self.checkBoxes = {} self.dependentItems = {} self.iterateButtons = {} @@ -102,41 +101,39 @@ class ParametersPanel(BASE, WIDGET): wrapper = self.getWidgetWrapperFromParameter(param) self.wrappers[param.name] = wrapper - self.valueItems[param.name] = wrapper.widget widget = wrapper.widget - if isinstance(param, ParameterVector): - layout = QHBoxLayout() - layout.setSpacing(2) - layout.setMargin(0) - layout.addWidget(widget) - button = QToolButton() - icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png')) - button.setIcon(icon) - button.setToolTip(self.tr('Iterate over this layer')) - button.setCheckable(True) - layout.addWidget(button) - self.iterateButtons[param.name] = button - button.toggled.connect(self.buttonToggled) - widget = QWidget() - widget.setLayout(layout) - - tooltips = self.alg.getParameterDescriptions() - widget.setToolTip(tooltips.get(param.name, param.description)) - - label = QLabel(desc) - # label.setToolTip(tooltip) - self.labels[param.name] = label - if param.isAdvanced: - self.layoutAdvanced.addWidget(label) - self.layoutAdvanced.addWidget(widget) - else: - self.layoutMain.insertWidget( - self.layoutMain.count() - 2, label) - self.layoutMain.insertWidget( - self.layoutMain.count() - 2, widget) - - self.widgets[param.name] = widget + if widget is not None: + if isinstance(param, ParameterVector): + layout = QHBoxLayout() + layout.setSpacing(2) + layout.setMargin(0) + layout.addWidget(widget) + button = QToolButton() + icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png')) + button.setIcon(icon) + button.setToolTip(self.tr('Iterate over this layer')) + button.setCheckable(True) + layout.addWidget(button) + self.iterateButtons[param.name] = button + button.toggled.connect(self.buttonToggled) + widget = QWidget() + widget.setLayout(layout) + + tooltips = self.alg.getParameterDescriptions() + widget.setToolTip(tooltips.get(param.name, param.description)) + + label = QLabel(desc) + # label.setToolTip(tooltip) + self.labels[param.name] = label + if param.isAdvanced: + self.layoutAdvanced.addWidget(label) + self.layoutAdvanced.addWidget(widget) + else: + self.layoutMain.insertWidget( + self.layoutMain.count() - 2, label) + self.layoutMain.insertWidget( + self.layoutMain.count() - 2, widget) for output in self.alg.outputs: if output.hidden: @@ -152,8 +149,7 @@ class ParametersPanel(BASE, WIDGET): check.setChecked(True) self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) self.checkBoxes[output.name] = check - self.valueItems[output.name] = widget - + self.outputWidgets[output.name] = widget for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) diff --git a/python/plugins/processing/gui/wrappers.py b/python/plugins/processing/gui/wrappers.py index 7cdff13a281..e4309e02380 100644 --- a/python/plugins/processing/gui/wrappers.py +++ b/python/plugins/processing/gui/wrappers.py @@ -831,7 +831,7 @@ class StringWidgetWrapper(WidgetWrapper): else: text = self.widget.getValue() return text - if self.dialogType == DIALOG_BATCH: + elif self.dialogType == DIALOG_BATCH: return self.widget.text() else: if self.param.multiline: diff --git a/python/plugins/processing/modeler/ModelerParametersDialog.py b/python/plugins/processing/modeler/ModelerParametersDialog.py index 0c4df307f36..d5dc14f2c27 100644 --- a/python/plugins/processing/modeler/ModelerParametersDialog.py +++ b/python/plugins/processing/modeler/ModelerParametersDialog.py @@ -146,20 +146,21 @@ class ModelerParametersDialog(QDialog): self.wrappers[param.name] = wrapper widget = wrapper.widget - self.valueItems[param.name] = widget - if param.name in list(tooltips.keys()): - tooltip = tooltips[param.name] - else: - tooltip = param.description - label.setToolTip(tooltip) - widget.setToolTip(tooltip) - if param.isAdvanced: - label.setVisible(self.showAdvanced) - widget.setVisible(self.showAdvanced) - self.widgets[param.name] = widget - - self.verticalLayout.addWidget(label) - self.verticalLayout.addWidget(widget) + if widget: + self.valueItems[param.name] = widget + if param.name in list(tooltips.keys()): + tooltip = tooltips[param.name] + else: + tooltip = param.description + label.setToolTip(tooltip) + widget.setToolTip(tooltip) + if param.isAdvanced: + label.setVisible(self.showAdvanced) + widget.setVisible(self.showAdvanced) + self.widgets[param.name] = widget + + self.verticalLayout.addWidget(label) + self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: @@ -301,34 +302,6 @@ class ModelerParametersDialog(QDialog): alg = self.model.algs[value.alg] return self.tr("'%s' from algorithm '%s'") % (alg.algorithm.getOutputFromName(value.output).description, alg.description) - def setTableContent(self): - params = self._alg.parameters - outputs = self._alg.outputs - visibleParams = [p for p in params if not p.hidden] - visibleOutputs = [p for o in outputs if not o.hidden] - self.tableWidget.setRowCount(len(visibleParams) + len(visibleOutputs)) - - for i, param in visibleParams: - item = QTableWidgetItem(param.description) - item.setFlags(Qt.ItemIsEnabled) - self.tableWidget.setItem(i, 0, item) - item = self.getWidgetFromParameter(param) - self.valueItems[param.name] = item - self.tableWidget.setCellWidget(i, 1, item) - self.tableWidget.setRowHeight(i, 22) - - for i, output in visibleOutputs: - item = QTableWidgetItem(output.description + '<' - + output.__module__.split('.')[-1] + '>') - item.setFlags(Qt.ItemIsEnabled) - self.tableWidget.setItem(i, 0, item) - item = QLineEdit() - if hasattr(item, 'setPlaceholderText'): - item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) - self.valueItems[output.name] = item - self.tableWidget.setCellWidget(i, 1, item) - self.tableWidget.setRowHeight(i, 22) - def setPreviousValues(self): if self._algName is not None: alg = self.model.algs[self._algName] @@ -376,12 +349,14 @@ class ModelerParametersDialog(QDialog): for selected in selectedOptions: alg.dependencies.append(availableDependencies[selected].name) + self._alg.processBeforeAddingToModeler(alg, self.model) return alg def setParamValue(self, alg, param, wrapper): try: - value = wrapper.value() - alg.params[param.name] = value + if wrapper.widget: + value = wrapper.value() + alg.params[param.name] = value return True except InvalidParameterValue: return False