[processing] implemented parameter widget wrappers

Conflicts:
	python/plugins/processing/core/GeoAlgorithm.py
	python/plugins/processing/gui/ExtentSelectionPanel.py
	python/plugins/processing/modeler/ModelerParametersDialog.py
This commit is contained in:
volaya 2016-09-07 14:30:20 +02:00
parent 8cc9a50a52
commit b298c76ee4
10 changed files with 914 additions and 977 deletions

View File

@ -42,8 +42,7 @@ from processing.core.ProcessingLog import ProcessingLog
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.SilentProgress import SilentProgress
from processing.core.parameters import ParameterExtent
from processing.core.parameters import ParameterRaster, ParameterVector, ParameterMultipleInput, ParameterTable, Parameter
from processing.core.parameters import ParameterRaster, ParameterVector, ParameterMultipleInput, ParameterTable, Parameter, ParameterExtent
from processing.core.outputs import OutputVector, OutputRaster, OutputTable, OutputHTML, Output
from processing.algs.gdal.GdalUtils import GdalUtils
from processing.tools import dataobjects, vector
@ -363,56 +362,6 @@ class GeoAlgorithm(object):
if ext not in exts + ['dbf']:
out.value = out.value + '.' + exts[0]
def resolveTemporaryOutputs(self):
"""Sets temporary outputs (output.value = None) with a
temporary file instead.
"""
for out in self.outputs:
if not out.hidden and out.value is None:
setTempOutput(out, self)
def setOutputCRS(self):
layers = dataobjects.getAllLayers()
for param in self.parameters:
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
if param.value:
if isinstance(param, ParameterMultipleInput):
inputlayers = param.value.split(';')
else:
inputlayers = [param.value]
for inputlayer in inputlayers:
for layer in layers:
if layer.source() == inputlayer:
self.crs = layer.crs()
return
p = dataobjects.getObjectFromUri(inputlayer)
if p is not None:
self.crs = p.crs()
p = None
return
try:
from qgis.utils import iface
if iface is not None:
self.crs = iface.mapCanvas().mapSettings().destinationCrs()
except:
pass
def resolveDataObjects(self):
layers = dataobjects.getAllLayers()
for param in self.parameters:
if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable,
ParameterMultipleInput)):
if param.value:
if isinstance(param, ParameterMultipleInput):
inputlayers = param.value.split(';')
else:
inputlayers = [param.value]
for i, inputlayer in enumerate(inputlayers):
for layer in layers:
if layer.name() == inputlayer:
inputlayers[i] = layer.source()
break
param.setValue(";".join(inputlayers))
def canUseAutoExtent(self):
for param in self.parameters:
@ -468,6 +417,57 @@ class GeoAlgorithm(object):
self.xmax = max(self.xmax, layer.extent().xMaximum())
self.ymin = min(self.ymin, layer.extent().yMinimum())
self.ymax = max(self.ymax, layer.extent().yMaximum())
def resolveTemporaryOutputs(self):
"""Sets temporary outputs (output.value = None) with a
temporary file instead.
"""
for out in self.outputs:
if not out.hidden and out.value is None:
setTempOutput(out, self)
def setOutputCRS(self):
layers = dataobjects.getAllLayers()
for param in self.parameters:
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
if param.value:
if isinstance(param, ParameterMultipleInput):
inputlayers = param.value.split(';')
else:
inputlayers = [param.value]
for inputlayer in inputlayers:
for layer in layers:
if layer.source() == inputlayer:
self.crs = layer.crs()
return
p = dataobjects.getObjectFromUri(inputlayer)
if p is not None:
self.crs = p.crs()
p = None
return
try:
from qgis.utils import iface
if iface is not None:
self.crs = iface.mapCanvas().mapSettings().destinationCrs()
except:
pass
def resolveDataObjects(self):
layers = dataobjects.getAllLayers()
for param in self.parameters:
if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable,
ParameterMultipleInput)):
if param.value:
if isinstance(param, ParameterMultipleInput):
inputlayers = param.value.split(';')
else:
inputlayers = [param.value]
for i, inputlayer in enumerate(inputlayers):
for layer in layers:
if layer.name() == inputlayer:
inputlayers[i] = layer.source()
break
param.setValue(";".join(inputlayers))
def checkInputCRS(self):
"""It checks that all input layers use the same CRS. If so,

View File

@ -30,7 +30,9 @@ __revision__ = '$Format:%H$'
import sys
import os
import inspect
from inspect import isclass
from copy import deepcopy
from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import QgsRasterLayer, QgsVectorLayer
@ -52,7 +54,7 @@ def _splitParameterOptions(line):
isOptional = False
definition = tokens[1]
return isOptional, tokens[0], definition
def _createDescriptiveName(s):
return s.replace('_', ' ')
@ -82,8 +84,8 @@ class Parameter(object):
self.optional = parseBool(optional)
# TODO: make deep copy and deep update
self.metadata = self.default_metadata.copy()
self.metadata.update(metadata)
self.metadata = deepcopy(self.default_metadata)
self.metadata.update(deepcopy(metadata))
def setValue(self, obj):
"""
@ -133,7 +135,20 @@ class Parameter(object):
if context == '':
context = 'Parameter'
return QCoreApplication.translate(context, string)
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, basestring):
tokens = wrapper.split('.')
mod = __import__('.'.join(tokens[:-1]), fromlist=[tokens[-1]])
wrapper = getattr(mod, tokens[-1])
# or directly a class object
if isclass(wrapper):
wrapper = wrapper(self, dialog, row, col)
# or a wrapper instance
return wrapper
class ParameterBoolean(Parameter):
default_metadata = {
@ -162,7 +177,7 @@ class ParameterBoolean(Parameter):
param_type += 'optional '
param_type += 'boolean '
return '##' + self.name + '=' + param_type + str(self.default)
@classmethod
def fromScriptCode(self, line):
isOptional, name, definition = _splitParameterOptions(line)
@ -175,7 +190,7 @@ class ParameterBoolean(Parameter):
param = ParameterBoolean(name, descName)
param.optional = isOptional
return param
class ParameterCrs(Parameter):
@ -236,9 +251,13 @@ class ParameterDataObject(Parameter):
class ParameterExtent(Parameter):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.ExtentWidgetWrapper'
}
USE_MIN_COVERING_EXTENT = 'USE_MIN_COVERING_EXTENT'
def __init__(self, name='', description='', default=None, optional=False):
def __init__(self, name='', description='', default=None, optional=True):
Parameter.__init__(self, name, description, default, optional)
# The value is a string in the form "xmin, xmax, ymin, ymax"
@ -271,7 +290,7 @@ class ParameterExtent(Parameter):
param_type += 'optional '
param_type += 'extent'
return '##' + self.name + '=' + param_type
@classmethod
def fromScriptCode(self, line):
isOptional, name, definition = _splitParameterOptions(line)
@ -283,6 +302,10 @@ class ParameterExtent(Parameter):
class ParameterPoint(Parameter):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.PointWidgetWrapper'
}
def __init__(self, name='', description='', default=None, optional=False):
Parameter.__init__(self, name, description, default, optional)
# The value is a string in the form "x, y"
@ -326,6 +349,10 @@ class ParameterPoint(Parameter):
class ParameterFile(Parameter):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.FileWidgetWrapper'
}
def __init__(self, name='', description='', isFolder=False, optional=True, ext=None):
Parameter.__init__(self, name, description, None, parseBool(optional))
self.ext = ext
@ -371,6 +398,7 @@ class ParameterFile(Parameter):
class ParameterFixedTable(Parameter):
def __init__(self, name='', description='', numRows=3,
cols=['value'], fixedNumOfRows=False, optional=False):
@ -423,6 +451,11 @@ class ParameterMultipleInput(ParameterDataObject):
Its value is a string with substrings separated by semicolons,
each of which represents the data source location of each element.
"""
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.MultipleInputWidgetWrapper'
}
exported = None
@ -607,13 +640,18 @@ class ParameterMultipleInput(ParameterDataObject):
descName = _createDescriptiveName(name)
if definition.lower().strip() == 'multiple raster':
return ParameterMultipleInput(name, descName,
dataobjects.TYPE_RASTER, isOptional)
dataobjects.TYPE_RASTER, isOptional)
elif definition.lower().strip() == 'multiple vector':
return ParameterMultipleInput(name, definition,
dataobjects.TYPE_VECTOR_ANY, isOptional)
class ParameterNumber(Parameter):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.NumberWidgetWrapper'
}
def __init__(self, name='', description='', minValue=None, maxValue=None,
default=None, optional=False):
@ -716,6 +754,11 @@ class ParameterRange(Parameter):
class ParameterRaster(ParameterDataObject):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.RasterWidgetWrapper'
}
def __init__(self, name='', description='', optional=False, showSublayersDialog=True):
ParameterDataObject.__init__(self, name, description, None, optional)
@ -787,6 +830,11 @@ class ParameterRaster(ParameterDataObject):
return ParameterRaster(name, descName, optional=isOptional)
class ParameterSelection(Parameter):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.SelectionWidgetWrapper'
}
def __init__(self, name='', description='', options=[], default=None, isSource=False,
optional=False):
@ -838,9 +886,14 @@ class ParameterSelection(Parameter):
elif definition.lower().strip().startswith('selection'):
options = definition.strip()[len('selection '):].split(';')
return ParameterSelection(name, descName, options, optional=isOptional)
class ParameterString(Parameter):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.StringWidgetWrapper'
}
NEWLINE = '\n'
ESCAPED_NEWLINE = '\\n'
@ -894,6 +947,11 @@ class ParameterString(Parameter):
return ParameterString(name, descName, multiline=True, optional=isOptional)
class ParameterTable(ParameterDataObject):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.TableWidgetWrapper'
}
def __init__(self, name='', description='', optional=False):
ParameterDataObject.__init__(self, name, description, None, optional)
@ -976,11 +1034,13 @@ class ParameterTableField(Parameter):
"""A parameter representing a table field.
Its value is a string that represents the name of the field.
In a script you can use it with
##Field=[optional] field [number|string] Parentinput
"""
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.TableFieldWidgetWrapper'
}
DATA_TYPE_NUMBER = 0
DATA_TYPE_STRING = 1
DATA_TYPE_ANY = -1
@ -1040,10 +1100,10 @@ class ParameterTableField(Parameter):
else:
parent = definition.strip()[len('field') + 1:]
datatype = ParameterTableField.DATA_TYPE_ANY
return ParameterTableField(name, descName, parent, datatype, isOptional)
class ParameterTableMultipleField(Parameter):
"""A parameter representing several table fields.
@ -1129,6 +1189,11 @@ class ParameterTableMultipleField(Parameter):
class ParameterVector(ParameterDataObject):
default_metadata = {
'widget_wrapper': 'processing.gui.wrappers.VectorWidgetWrapper'
}
def __init__(self, name='', description='', datatype=[-1],
optional=False):
@ -1139,6 +1204,7 @@ class ParameterVector(ParameterDataObject):
datatype = [int(t) for t in datatype.split(',')]
self.datatype = datatype
self.exported = None
self.allowOnlyOpenedLayers = False
def setValue(self, obj):
self.exported = None
@ -1260,20 +1326,20 @@ class ParameterGeometryPredicate(Parameter):
return True
paramClasses = [c for c in sys.modules[__name__].__dict__.values() if inspect.isclass(c) and issubclass(c, Parameter)]
paramClasses = [c for c in sys.modules[__name__].__dict__.values() if isclass(c) and issubclass(c, Parameter)]
def getParameterFromString(s):
print s
#Try the parameter definitions used in description files
# Try the parameter definitions used in description files
if '|' in s:
tokens = s.split("|")
params = [t if unicode(t) != unicode(None) else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)
else: #try script syntax
else: # try script syntax
for paramClass in paramClasses:
try:
param = paramClass.fromScriptCode(s)
param = paramClass.fromScriptCode(s)
if param is not None:
return param
except AttributeError:

View File

@ -85,8 +85,8 @@ class AlgorithmDialog(AlgorithmDialogBase):
self.cornerWidget.setLayout(layout)
self.tabWidget.setCornerWidget(self.cornerWidget)
QgsMapLayerRegistry.instance().layerWasAdded.connect(self.mainWidget.layerAdded)
QgsMapLayerRegistry.instance().layersWillBeRemoved.connect(self.mainWidget.layersWillBeRemoved)
QgsMapLayerRegistry.instance().layerWasAdded.connect(self.mainWidget.layerRegistryChanged)
QgsMapLayerRegistry.instance().layersWillBeRemoved.connect(self.mainWidget.layerRegistryChanged)
def runAsBatch(self):
self.close()
@ -101,17 +101,9 @@ class AlgorithmDialog(AlgorithmDialogBase):
for param in params:
if param.hidden:
continue
if isinstance(param, ParameterExtent):
continue
wrapper = self.mainWidget.widget_wrappers[param.name]
wrapper = self.mainWidget.wrappers[param.name]
if not self.setParamValue(param, wrapper):
raise AlgorithmDialogBase.InvalidParameterValue(param, wrapper)
for param in params:
if isinstance(param, ParameterExtent):
wrapper = self.mainWidget.widget_wrappers[param.name]
if not self.setParamValue(param, wrapper):
raise AlgorithmDialogBase.InvalidParameterValue(param, wrapper)
raise AlgorithmDialogBase.InvalidParameterValue(param, wrapper.widget)
for output in outputs:
if output.hidden:
@ -135,61 +127,7 @@ class AlgorithmDialog(AlgorithmDialogBase):
return result
def setParamValue(self, param, wrapper, alg=None):
if wrapper.implemented:
return param.setValue(wrapper.value())
widget = wrapper.widget
if isinstance(param, ParameterRaster):
return param.setValue(widget.getValue())
elif isinstance(param, (ParameterVector, ParameterTable)):
try:
return param.setValue(widget.itemData(widget.currentIndex()))
except:
return param.setValue(widget.getValue())
elif isinstance(param, ParameterSelection):
return param.setValue(widget.currentIndex())
elif isinstance(param, ParameterFixedTable):
return param.setValue(widget.table)
elif isinstance(param, ParameterRange):
return param.setValue(widget.getValue())
elif isinstance(param, ParameterTableField):
if param.optional and widget.currentIndex() == 0:
return param.setValue(None)
return param.setValue(widget.currentText())
elif isinstance(param, ParameterTableMultipleField):
if param.optional and len(list(widget.get_selected_items())) == 0:
return param.setValue(None)
return param.setValue(list(widget.get_selected_items()))
elif isinstance(param, ParameterMultipleInput):
if param.datatype == dataobjects.TYPE_FILE:
return param.setValue(widget.selectedoptions)
else:
if param.datatype == dataobjects.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([param.datatype], sorting=False)
return param.setValue([options[i] for i in widget.selectedoptions])
elif isinstance(param, (ParameterNumber, ParameterFile,
ParameterExtent, ParameterPoint)):
return param.setValue(widget.getValue())
elif isinstance(param, ParameterString):
if param.multiline:
text = str(widget.toPlainText())
else:
text = widget.text()
if param.evaluateExpressions:
try:
text = self.evaluateExpression(text)
except:
pass
return param.setValue(text)
elif isinstance(param, ParameterGeometryPredicate):
return param.setValue(widget.value())
else:
return param.setValue(str(widget.text()))
return param.setValue(wrapper.value())
def accept(self):
self.settings.setValue("/Processing/dialogBase", self.saveGeometry())
@ -289,6 +227,6 @@ class AlgorithmDialog(AlgorithmDialogBase):
'\nOpen the results dialog to check it.'))
def closeEvent(self, evt):
QgsMapLayerRegistry.instance().layerWasAdded.disconnect(self.mainWidget.layerAdded)
QgsMapLayerRegistry.instance().layersWillBeRemoved.disconnect(self.mainWidget.layersWillBeRemoved)
QgsMapLayerRegistry.instance().layerWasAdded.disconnect(self.mainWidget.layerRegistryChanged)
QgsMapLayerRegistry.instance().layersWillBeRemoved.disconnect(self.mainWidget.layerRegistryChanged)
super(AlgorithmDialog, self).closeEvent(evt)

View File

@ -45,11 +45,10 @@ from processing.tools import dataobjects
class BatchInputSelectionPanel(QWidget):
def __init__(self, param, row, col, panel):
def __init__(self, param, row, col, dialog):
super(BatchInputSelectionPanel, self).__init__(None)
self.param = param
self.panel = panel
self.table = self.panel.tblParameters
self.dialog = dialog
self.row = row
self.col = col
self.horizontalLayout = QHBoxLayout(self)
@ -67,6 +66,12 @@ class BatchInputSelectionPanel(QWidget):
self.horizontalLayout.addWidget(self.pushButton)
self.setLayout(self.horizontalLayout)
def _panel(self):
return self.dialog.mainDialog()
def _table(self):
return self._panel().tblParameters
def showPopupMenu(self):
popupmenu = QMenu()
@ -108,11 +113,11 @@ class BatchInputSelectionPanel(QWidget):
if isinstance(self.param, ParameterMultipleInput):
self.text.setText(';'.join(layers[idx].name() for idx in selected))
else:
rowdif = len(selected) - (self.table.rowCount() - self.row)
rowdif = len(selected) - (self._table().rowCount() - self.row)
for i in range(rowdif):
self.panel.addRow()
self._panel().addRow()
for i, layeridx in enumerate(selected):
self.table.cellWidget(i + self.row,
self._table().cellWidget(i + self.row,
self.col).setText(layers[layeridx].name())
def showFileSelectionDialog(self):
@ -141,11 +146,11 @@ class BatchInputSelectionPanel(QWidget):
if isinstance(self.param, ParameterMultipleInput):
self.text.setText(';'.join(str(f) for f in files))
else:
rowdif = len(files) - (self.table.rowCount() - self.row)
rowdif = len(files) - (self._table().rowCount() - self.row)
for i in range(rowdif):
self.panel.addRow()
self._panel().addRow()
for i, f in enumerate(files):
self.table.cellWidget(i + self.row,
self._table().cellWidget(i + self.row,
self.col).setText(f)
def setText(self, text):

View File

@ -36,11 +36,7 @@ from qgis.PyQt.QtWidgets import QTableWidgetItem, QComboBox, QLineEdit, QHeaderV
from qgis.core import QgsApplication
from processing.gui.wrappers import (
DIALOG_BATCH,
wrapper_from_param,
NotYetImplementedWidgetWrapper,
)
from processing.gui.wrappers import NotYetImplementedWidgetWrapper
from processing.gui.FileSelectionPanel import FileSelectionPanel
from processing.gui.CrsSelectionPanel import CrsSelectionPanel
@ -77,7 +73,7 @@ class BatchPanel(BASE, WIDGET):
super(BatchPanel, self).__init__(None)
self.setupUi(self)
self.widget_wrappers = []
self.wrappers = []
self.btnAdvanced.hide()
@ -148,45 +144,15 @@ class BatchPanel(BASE, WIDGET):
self.tblParameters.horizontalHeader().setStretchLastSection(True)
def getWidgetWrapperFromParameter(self, param, row, col):
wrapper = wrapper_from_param(param) # , DIALOG_BATCH)
if wrapper is not None:
return wrapper
return param.wrapper(self.parent, row, col)
widget = self.getWidgetFromParameter(param, row, col)
wrapper = NotYetImplementedWidgetWrapper(param, widget)
return wrapper
def getWidgetFromParameter(self, param, row, col):
if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable,
ParameterMultipleInput)):
item = BatchInputSelectionPanel(param, row, col, self)
elif isinstance(param, ParameterSelection):
item = QComboBox()
item.addItems(param.options)
elif isinstance(param, ParameterFixedTable):
item = FixedTablePanel(param)
elif isinstance(param, ParameterExtent):
item = ExtentSelectionPanel(self.parent, self.alg, param.default)
elif isinstance(param, ParameterPoint):
item = PointSelectionPanel(self.parent, param.default)
elif isinstance(param, ParameterCrs):
item = CrsSelectionPanel(param.default)
elif isinstance(param, ParameterFile):
item = FileSelectionPanel(param.isFolder)
elif isinstance(param, ParameterGeometryPredicate):
if isinstance(param, ParameterGeometryPredicate):
item = GeometryPredicateSelectionPanel(param.enabledPredicates, rows=1)
width = max(self.tblParameters.columnWidth(col),
item.sizeHint().width())
self.tblParameters.setColumnWidth(col, width)
else:
item = QLineEdit()
if param.default is not None:
try:
item.setText(str(param.default))
except:
pass
return item
def load(self):
filename, selected_filter = QFileDialog.getOpenFileName(self,
@ -211,8 +177,8 @@ class BatchPanel(BASE, WIDGET):
continue
if param.name in params:
value = params[param.name]
wrapper = self.widget_wrappers[row][column]
self.setValueInWidgetWrapper(wrapper, value)
wrapper = self.wrappers[row][column]
wrapper.setValue(value)
column += 1
for out in self.alg.outputs:
@ -221,7 +187,7 @@ class BatchPanel(BASE, WIDGET):
if out.name in outputs:
value = outputs[out.name]
widget = self.tblParameters.cellWidget(row, column)
self.setValueInWidget(widget, value)
widget.setValue(value)
column += 1
except TypeError:
QMessageBox.critical(
@ -235,22 +201,14 @@ class BatchPanel(BASE, WIDGET):
self.setValueInWidget(wrapper.widget, value)
def setValueInWidget(self, widget, value):
if isinstance(widget, (BatchInputSelectionPanel, QLineEdit, FileSelectionPanel)):
widget.setText(str(value))
elif isinstance(widget, (BatchOutputSelectionPanel, GeometryPredicateSelectionPanel)):
widget.setValue(str(value))
elif isinstance(widget, QComboBox):
idx = widget.findText(str(value))
if idx != -1:
widget.setCurrentIndex(idx)
if isinstance(widget, (BatchOutputSelectionPanel, GeometryPredicateSelectionPanel)):
widget.setValue(unicode(value))
elif isinstance(widget, ExtentSelectionPanel):
if value is not None:
widget.setExtentFromString(value)
else:
widget.setExtentFromString('')
elif isinstance(widget, CrsSelectionPanel):
widget.setAuthId(value)
def save(self):
toSave = []
@ -265,7 +223,7 @@ class BatchPanel(BASE, WIDGET):
if isinstance(param, ParameterExtent):
col += 1
continue
wrapper = self.widget_wrappers[row][col]
wrapper = self.wrappers[row][col]
if not self.setParamValue(param, wrapper, alg):
self.parent.lblProgress.setText(
self.tr('<b>Missing parameter value: %s (row %d)</b>') % (param.description, row + 1))
@ -277,7 +235,7 @@ class BatchPanel(BASE, WIDGET):
if param.hidden:
continue
if isinstance(param, ParameterExtent):
wrapper = self.widget_wrappers[row][col]
wrapper = self.wrappers[row][col]
if not self.setParamValue(param, wrapper, alg):
self.parent.lblProgress.setText(
self.tr('<b>Missing parameter value: %s (row %d)</b>') % (param.description, row + 1))
@ -313,29 +271,17 @@ class BatchPanel(BASE, WIDGET):
return param.setValue(wrapper.value())
widget = wrapper.widget
if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable,
ParameterMultipleInput)):
value = widget.getText()
if str(value).strip() == '':
value = None
return param.setValue(value)
elif isinstance(param, ParameterSelection):
return param.setValue(widget.currentIndex())
elif isinstance(param, ParameterFixedTable):
return param.setValue(widget.table)
elif isinstance(param, ParameterExtent):
if isinstance(param, ParameterExtent):
if alg is not None:
widget.useNewAlg(alg)
return param.setValue(widget.getValue())
elif isinstance(param, (ParameterCrs, ParameterFile)):
return param.setValue(widget.getValue())
elif isinstance(param, ParameterGeometryPredicate):
return param.setValue(widget.value())
else:
return param.setValue(widget.text())
def setCellWrapper(self, row, column, wrapper):
self.widget_wrappers[row][column] = wrapper
self.wrappers[row][column] = wrapper
self.tblParameters.setCellWidget(row, column, wrapper.widget)
def addRow(self):
@ -369,12 +315,12 @@ class BatchPanel(BASE, WIDGET):
self.tblParameters.setCellWidget(row, column, item)
def removeRows(self):
#~ self.tblParameters.setUpdatesEnabled(False)
#~ indexes = self.tblParameters.selectionModel().selectedIndexes()
#~ indexes.sort()
#~ for i in reversed(indexes):
#~ self.tblParameters.model().removeRow(i.row())
#~ self.tblParameters.setUpdatesEnabled(True)
# ~ self.tblParameters.setUpdatesEnabled(False)
# ~ indexes = self.tblParameters.selectionModel().selectedIndexes()
# ~ indexes.sort()
# ~ for i in reversed(indexes):
# ~ self.tblParameters.model().removeRow(i.row())
# ~ self.tblParameters.setUpdatesEnabled(True)
if self.tblParameters.rowCount() > 2:
self.widget_wrappers.pop()
self.tblParameters.setRowCount(self.tblParameters.rowCount() - 1)

View File

@ -50,13 +50,13 @@ WIDGET, BASE = uic.loadUiType(
class ExtentSelectionPanel(BASE, WIDGET):
def __init__(self, dialog, alg, default=None):
def __init__(self, dialog, param):
super(ExtentSelectionPanel, self).__init__(None)
self.setupUi(self)
self.dialog = dialog
self.alg = alg
if alg.canUseAutoExtent():
self.param = param
if self.param.optional:
if hasattr(self.leText, 'setPlaceholderText'):
self.leText.setPlaceholderText(
self.tr('[Leave blank to use min covering extent]'))
@ -68,18 +68,19 @@ class ExtentSelectionPanel(BASE, WIDGET):
self.tool = RectangleMapTool(canvas)
self.tool.rectangleCreated.connect(self.updateExtent)
if default:
tokens = str(default).split(',')
if param.default:
tokens = param.default.split(',')
if len(tokens) == 4:
try:
float(tokens[0])
float(tokens[1])
float(tokens[2])
float(tokens[3])
self.leText.setText(str(default))
self.leText.setText(param.default)
except:
pass
def selectExtent(self):
popupmenu = QMenu()
useLayerExtentAction = QAction(
@ -93,7 +94,7 @@ class ExtentSelectionPanel(BASE, WIDGET):
selectOnCanvasAction.triggered.connect(self.selectOnCanvas)
useLayerExtentAction.triggered.connect(self.useLayerExtent)
if self.canUseAutoExtent():
if self.param.optional:
useMincoveringExtentAction = QAction(
self.tr('Use min covering extent from input layers'),
self.btnSelect)
@ -153,9 +154,10 @@ class ExtentSelectionPanel(BASE, WIDGET):
self.dialog.activateWindow()
def getValue(self):
if str(self.leText.text()).strip() == '':
if str(self.leText.text()).strip() != '':
return str(self.leText.text())
else:
return None
return str(self.leText.text())
def setExtentFromString(self, s):
self.leText.setText(s)

View File

@ -62,7 +62,7 @@ class NumberInputPanel(BASE, WIDGET):
if self.isInteger:
self.spnValue.setDecimals(0)
else:
#Guess reasonable step value
# Guess reasonable step value
if (maximum == 0 or maximum) and (minimum == 0 or minimum):
self.spnValue.setSingleStep(self.calculateStep(minimum, maximum))
@ -75,7 +75,7 @@ class NumberInputPanel(BASE, WIDGET):
else:
self.spnValue.setMinimum(-99999999)
#Set default value
# Set default value
if number == 0 or number:
self.spnValue.setValue(float(number))
self.spnValue.setClearValue(float(number))
@ -149,6 +149,9 @@ class NumberInputPanel(BASE, WIDGET):
def getValue(self):
return self.spnValue.value()
def setValue(self, value):
self.spnValue.setValue(value)
def calculateStep(self, minimum, maximum):
valueRange = maximum - minimum
if valueRange <= 1.0:

View File

@ -42,10 +42,7 @@ from qgis.PyQt.QtGui import QIcon
from processing.core.ProcessingConfig import ProcessingConfig
from processing.gui.wrappers import (
wrapper_from_param,
NotYetImplementedWidgetWrapper,
)
from processing.gui.wrappers import NotYetImplementedWidgetWrapper
from processing.gui.OutputSelectionPanel import OutputSelectionPanel
from processing.gui.InputLayerSelectorPanel import InputLayerSelectorPanel
@ -82,8 +79,6 @@ from processing.core.outputs import OutputRaster
from processing.core.outputs import OutputTable
from processing.core.outputs import OutputVector
from processing.tools import dataobjects
pluginPath = os.path.split(os.path.dirname(__file__))[0]
WIDGET, BASE = uic.loadUiType(
os.path.join(pluginPath, 'ui', 'widgetParametersPanel.ui'))
@ -105,7 +100,7 @@ class ParametersPanel(BASE, WIDGET):
self.parent = parent
self.alg = alg
self.valueItems = {}
self.widget_wrappers = {}
self.wrappers = {}
self.labels = {}
self.widgets = {}
self.checkBoxes = {}
@ -114,69 +109,9 @@ class ParametersPanel(BASE, WIDGET):
self.initWidgets()
def layerAdded(self, layer):
if layer.type() == QgsMapLayer.VectorLayer:
for param in self.alg.parameters:
if param.hidden:
continue
if isinstance(param, ParameterVector):
if dataobjects.canUseVectorLayer(layer, param.datatype):
widget = self.valueItems[param.name]
if isinstance(widget, InputLayerSelectorPanel):
widget = widget.cmbText
widget.addItem(self.getExtendedLayerName(layer), layer)
elif layer.type() == QgsMapLayer.RasterLayer and dataobjects.canUseRasterLayer(layer):
for param in self.alg.parameters:
if param.hidden:
continue
if isinstance(param, ParameterRaster):
widget = self.valueItems[param.name].cmbText
widget.addItem(self.getExtendedLayerName(layer), layer)
self.updateMultipleInputs()
def layersWillBeRemoved(self, layers):
for layer in layers:
self.layerRemoved(layer)
def layerRemoved(self, layer):
layer = QgsMapLayerRegistry.instance().mapLayer(layer)
widget = None
if layer.type() == QgsMapLayer.VectorLayer:
for param in self.alg.parameters:
if param.hidden:
continue
if isinstance(param, ParameterVector):
widget = self.valueItems[param.name]
if isinstance(widget, InputLayerSelectorPanel):
widget = widget.cmbText
elif layer.type() == QgsMapLayer.RasterLayer:
for param in self.alg.parameters:
if param.hidden:
continue
if isinstance(param, ParameterRaster):
widget = self.valueItems[param.name].cmbText
if widget is not None:
idx = widget.findData(layer)
if idx != -1:
widget.removeItem(idx)
self.updateMultipleInputs()
def updateMultipleInputs(self):
for param in self.alg.parameters:
if isinstance(param, ParameterMultipleInput) and param.datatype != dataobjects.TYPE_FILE:
if param.datatype == dataobjects.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([param.datatype], sorting=False)
opts = [self.getExtendedLayerName(opt) for opt in options]
widget = self.valueItems[param.name]
widget.updateForOptions(opts)
def layerRegistryChanged(self, layers):
for wrapper in self.wrappers.values():
wrapper.refresh()
def initWidgets(self):
# If there are advanced parameters — show corresponding groupbox
@ -201,12 +136,11 @@ class ParametersPanel(BASE, WIDGET):
pass
wrapper = self.getWidgetWrapperFromParameter(param)
self.widget_wrappers[param.name] = wrapper
self.wrappers[param.name] = wrapper
self.valueItems[param.name] = wrapper.widget
widget = wrapper.widget
if isinstance(param, ParameterVector) and \
not self.alg.allowOnlyOpenedLayers:
if isinstance(param, ParameterVector):
layout = QHBoxLayout()
layout.setSpacing(2)
layout.setMargin(0)
@ -222,28 +156,21 @@ class ParametersPanel(BASE, WIDGET):
widget = QWidget()
widget.setLayout(layout)
print wrapper
tooltips = self.alg.getParameterDescriptions()
widget.setToolTip(tooltips.get(param.name, param.description))
if isinstance(widget, QCheckBox):
widget.setText(desc)
if param.isAdvanced:
self.layoutAdvanced.addWidget(widget)
else:
self.layoutMain.insertWidget(
self.layoutMain.count() - 2, widget)
label = QLabel(desc)
# label.setToolTip(tooltip)
self.labels[param.name] = label
if param.isAdvanced:
self.layoutAdvanced.addWidget(label)
self.layoutAdvanced.addWidget(widget)
else:
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.layoutMain.insertWidget(
self.layoutMain.count() - 2, label)
self.layoutMain.insertWidget(
self.layoutMain.count() - 2, widget)
self.widgets[param.name] = widget
@ -262,24 +189,9 @@ class ParametersPanel(BASE, WIDGET):
self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
self.checkBoxes[output.name] = check
self.valueItems[output.name] = widget
wrapper = NotYetImplementedWidgetWrapper(output, widget)
self.widget_wrappers[output.name] = wrapper
if isinstance(output, OutputVector):
if output.base_input in self.dependentItems:
items = self.dependentItems[output.base_input]
else:
items = []
self.dependentItems[output.base_input] = items
items.append(output)
base_input = self.alg.getParameterFromName(output.base_input)
if isinstance(base_input, ParameterVector):
layers = dataobjects.getVectorLayers(base_input.datatype)
else:
layers = dataobjects.getTables()
if len(layers) > 0:
output.base_layer = layers[0]
for wrapper in self.wrappers.values():
wrapper.postInitialize(self.wrappers.values())
def buttonToggled(self, value):
if value:
@ -288,213 +200,11 @@ class ParametersPanel(BASE, WIDGET):
if button is not sender:
button.setChecked(False)
def getExtendedLayerName(self, layer):
authid = layer.crs().authid()
if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF) \
and authid is not None:
return u'{} [{}]'.format(layer.name(), authid)
else:
return layer.name()
def getWidgetWrapperFromParameter(self, param):
wrapper = wrapper_from_param(param)
if wrapper is not None:
return wrapper
widget = self.getWidgetFromParameter(param)
wrapper = NotYetImplementedWidgetWrapper(param, widget)
wrapper = param.wrapper(self.parent)
wrapper.widgetValueHasChanged.connect(self.widgetValueHasChanged)
return wrapper
def getWidgetFromParameter(self, param):
# TODO Create Parameter widget class that holds the logic
# for creating a widget that belongs to the parameter.
if isinstance(param, ParameterRaster):
layers = dataobjects.getRasterLayers()
items = []
if param.optional:
items.append((self.NOT_SELECTED, None))
for layer in layers:
items.append((self.getExtendedLayerName(layer), layer))
item = InputLayerSelectorPanel(items, param)
elif isinstance(param, ParameterVector):
if self.somethingDependsOnThisParameter(param) or self.alg.allowOnlyOpenedLayers:
item = QComboBox()
layers = dataobjects.getVectorLayers(param.datatype)
layers.sort(key=lambda lay: lay.name())
if param.optional:
item.addItem(self.NOT_SELECTED, None)
for layer in layers:
item.addItem(self.getExtendedLayerName(layer), layer)
item.currentIndexChanged.connect(self.updateDependentFields)
item.name = param.name
else:
layers = dataobjects.getVectorLayers(param.datatype)
items = []
if param.optional:
items.append((self.NOT_SELECTED, None))
for layer in layers:
items.append((self.getExtendedLayerName(layer), layer))
# if already set, put first in list
for i, (name, layer) in enumerate(items):
if layer and layer.source() == param.value:
items.insert(0, items.pop(i))
item = InputLayerSelectorPanel(items, param)
elif isinstance(param, ParameterTable):
if self.somethingDependsOnThisParameter(param):
item = QComboBox()
layers = dataobjects.getTables()
if param.optional:
item.addItem(self.NOT_SELECTED, None)
for layer in layers:
item.addItem(layer.name(), layer)
item.currentIndexChanged.connect(self.updateDependentFields)
item.name = param.name
else:
layers = dataobjects.getTables()
items = []
if param.optional:
items.append((self.NOT_SELECTED, None))
for layer in layers:
items.append((layer.name(), layer))
# if already set, put first in list
for i, (name, layer) in enumerate(items):
if layer and layer.source() == param.value:
items.insert(0, items.pop(i))
item = InputLayerSelectorPanel(items, param)
elif isinstance(param, ParameterTableField) or isinstance(param, ParameterTableMultipleField):
if isinstance(param, ParameterTableMultipleField):
item = ListMultiSelectWidget()
else:
item = QComboBox()
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.datatype)
else:
layers = dataobjects.getTables()
if len(layers) > 0:
if param.optional and isinstance(param, ParameterTableField):
item.addItem(self.tr('[not set]'))
item.addItems(self.getFields(layers[0], param.datatype))
elif isinstance(param, ParameterSelection):
item = QComboBox()
item.addItems(param.options)
if param.default:
item.setCurrentIndex(param.default)
elif isinstance(param, ParameterFixedTable):
item = FixedTablePanel(param)
elif isinstance(param, ParameterRange):
item = RangePanel(param)
elif isinstance(param, ParameterFile):
item = FileSelectionPanel(param.isFolder, param.ext)
elif isinstance(param, ParameterMultipleInput):
if param.datatype == dataobjects.TYPE_FILE:
item = MultipleInputPanel(datatype=dataobjects.TYPE_FILE)
else:
if param.datatype == dataobjects.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([param.datatype], sorting=False)
opts = [self.getExtendedLayerName(opt) for opt in options]
item = MultipleInputPanel(opts)
elif isinstance(param, ParameterNumber):
item = NumberInputPanel(param.default, param.min, param.max,
param.isInteger)
elif isinstance(param, ParameterExtent):
item = ExtentSelectionPanel(self.parent, self.alg, param.default)
elif isinstance(param, ParameterPoint):
item = PointSelectionPanel(self.parent, param.default)
elif isinstance(param, ParameterString):
if param.multiline:
verticalLayout = QVBoxLayout()
verticalLayout.setSizeConstraint(
QLayout.SetDefaultConstraint)
textEdit = QPlainTextEdit()
if param.default:
textEdit.setPlainText(param.default)
verticalLayout.addWidget(textEdit)
item = textEdit
else:
item = QLineEdit()
if param.default:
item.setText(str(param.default))
elif isinstance(param, ParameterGeometryPredicate):
item = GeometryPredicateSelectionPanel(param.enabledPredicates)
if param.left:
widget = self.valueItems[param.left]
if isinstance(widget, InputLayerSelectorPanel):
widget = widget.cmbText
widget.currentIndexChanged.connect(item.onLeftLayerChange)
item.leftLayer = widget.itemData(widget.currentIndex())
if param.right:
widget = self.valueItems[param.right]
if isinstance(widget, InputLayerSelectorPanel):
widget = widget.cmbText
widget.currentIndexChanged.connect(item.onRightLayerChange)
item.rightLayer = widget.itemData(widget.currentIndex())
item.updatePredicates()
if param.default:
item.setValue(param.default)
else:
item = QLineEdit()
if param.default:
item.setText(str(param.default))
return item
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())
if not layer:
return
children = self.dependentItems[sender.name]
for child in children:
if (isinstance(child, ParameterTableField) or isinstance(
child, ParameterTableMultipleField)):
widget = self.valueItems[child.name]
widget.clear()
if (self.alg.getParameterFromName(child.name).optional and
not isinstance(child, ParameterTableMultipleField)):
widget.addItem(self.tr('[not set]'))
widget.addItems(
self.getFields(layer, self.alg.getParameterFromName(
child.name).datatype))
if isinstance(child, OutputVector):
child.base_layer = layer
def getFields(self, layer, datatype):
fieldTypes = []
if datatype == ParameterTableField.DATA_TYPE_STRING:
fieldTypes = [QVariant.String]
elif datatype == ParameterTableField.DATA_TYPE_NUMBER:
fieldTypes = [QVariant.Int, QVariant.Double, QVariant.LongLong,
QVariant.UInt, QVariant.ULongLong]
fieldNames = set()
for field in layer.fields():
if not fieldTypes or field.type() in fieldTypes:
fieldNames.add(str(field.name()))
return sorted(list(fieldNames), cmp=locale.strcoll)
def somethingDependsOnThisParameter(self, parent):
for param in self.alg.parameters:
if isinstance(param, (ParameterTableField,
ParameterTableMultipleField)):
if param.parent == parent.name:
return True
for output in self.alg.outputs:
if isinstance(output, OutputVector):
if output.base_layer == parent.name:
return True
return False
def widgetValueHasChanged(self, wrapper):
for wrapper in self.wrappers.values():
wrapper.anotherParameterWidgetHasChanged(wrapper)

View File

@ -5,8 +5,9 @@
BooleanWidget.py
---------------------
Date : May 2016
Copyright : (C) 2016 by Arnaud Morvan
Copyright : (C) 2016 by Arnaud Morvan, Victor Olaya
Email : arnaud dot morvan at camptocamp dot com
volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
@ -26,34 +27,37 @@ __copyright__ = '(C) 2016, Arnaud Morvan'
__revision__ = '$Format:%H$'
from inspect import isclass
import locale
from qgis.core import QgsCoordinateReferenceSystem
from qgis.PyQt.QtWidgets import (
QCheckBox,
QComboBox,
)
from qgis.PyQt.QtWidgets import QCheckBox, QComboBox, QLineEdit, QPlainTextEdit
from qgis.PyQt.QtCore import pyqtSignal, QObject, QVariant
from processing.gui.NumberInputPanel import NumberInputPanel
from processing.gui.InputLayerSelectorPanel import InputLayerSelectorPanel
from processing.modeler.MultilineTextPanel import MultilineTextPanel
from processing.gui.CrsSelectionPanel import CrsSelectionPanel
from processing.gui.PointSelectionPanel import PointSelectionPanel
from processing.core.parameters import (ParameterBoolean, ParameterPoint, ParameterFile,
ParameterRaster, ParameterVector, ParameterNumber, ParameterString, ParameterTable,
ParameterTableField, ParameterExtent, ParameterFixedTable)
from processing.core.ProcessingConfig import ProcessingConfig
from processing.gui.FileSelectionPanel import FileSelectionPanel
from processing.core.outputs import (OutputFile, OutputRaster, OutputVector, OutputNumber,
OutputString, OutputTable, OutputExtent)
from processing.tools import dataobjects
from processing.gui.MultipleInputPanel import MultipleInputPanel
from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
from processing.gui.FixedTablePanel import FixedTablePanel
from processing.gui.ExtentSelectionPanel import ExtentSelectionPanel
DIALOG_STANDARD = 'standard'
DIALOG_BATCH = 'batch'
DIALOG_MODELER = 'modeler'
def wrapper_from_param(param, dialog=DIALOG_STANDARD):
wrapper = param.metadata.get('widget_wrapper', None)
# wrapper metadata should be a class path
if isinstance(wrapper, basestring):
tokens = wrapper.split('.')
mod = __import__('.'.join(tokens[:-1]), fromlist=[tokens[-1]])
wrapper = getattr(mod, tokens[-1])
# or directly a class object
if isclass(wrapper):
wrapper = wrapper(param=param, dialog=dialog)
# or a wrapper instance
return wrapper
class InvalidParameterValue(Exception):
pass
class NotYetImplementedWidgetWrapper():
@ -65,19 +69,43 @@ class NotYetImplementedWidgetWrapper():
self.param = param
self.widget = widget
dialogTypes = {"AlgorithmDialog":DIALOG_STANDARD,
"ModelerParametersDialog":DIALOG_MODELER,
"BatchAlgorithmDialog": DIALOG_BATCH}
class WidgetWrapper():
def getExtendedLayerName(layer):
authid = layer.crs().authid()
if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF) and authid is not None:
return u'{} [{}]'.format(layer.name(), authid)
else:
return layer.name()
class WidgetWrapper(QObject):
implemented = True # TODO: Should be removed at the end
widgetValueHasChanged = pyqtSignal(object)
def __init__(self, param, dialog=DIALOG_STANDARD):
def __init__(self, param, dialog, row=0, col=0):
QObject.__init__(self)
self.param = param
self.dialog = dialog
self.row = row
self.col = col
self.dialogType = dialogTypes[dialog.__class__.__name__]
self.widget = self.createWidget()
self.setValue(param.default)
if param.default is not None:
self.setValue(param.default)
def comboValue(self):
return self.widget.itemData(self.widget.currentIndex())
def comboValue(self, validator=None):
idx = self.widget.findText(self.widget.currentText())
if idx < 0:
v = self.widget.currentText().strip()
if validator is not None and not validator(v):
raise InvalidParameterValue()
return v
else:
return self.widget.itemData(self.widget.currentIndex())
def createWidget(self):
pass
@ -86,41 +114,68 @@ class WidgetWrapper():
pass
def setComboValue(self, value):
if isinstance(value, list):
value = value[0]
values = [self.widget.itemData(i) for i in range(self.widget.count())]
try:
idx = values.index(value)
self.widget.setCurrentIndex(idx)
except ValueError:
pass
if self.widget.isEditable():
if value is not None:
self.widget.setEditText(unicode(value))
def value(self):
pass
def anotherParameterWidgetHasChanged(self, wrapper):
pass
def postInitialize(self, wrappers):
pass
def refresh(self):
pass
class BooleanWidgetWrapper(WidgetWrapper):
def createWidget(self):
if self.dialog == DIALOG_STANDARD:
if self.dialogType == DIALOG_STANDARD:
return QCheckBox()
if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
elif self.dialogType == DIALOG_BATCH:
widget = QComboBox()
widget.addItem(widget.tr('Yes'), True)
widget.addItem(widget.tr('No'), False)
widget.addItem(self.tr('Yes'))
widget.addItem(self.tr('No'))
if self.param.default:
widget.setCurrentIndex(0)
else:
widget.setCurrentIndex(1)
return widget
else:
widget = QComboBox()
widget.addItem('Yes', True)
widget.addItem('No', False)
bools = self.dialog.getAvailableValuesOfType(ParameterBoolean, None)
for b in bools:
widget.addItem(self.dialog.resolveValueDescription(b), b)
if self.param.default:
widget.setCurrentIndex(0)
else:
widget.setCurrentIndex(1)
return widget
def setValue(self, value):
if self.dialog == DIALOG_STANDARD:
if self.dialogType == DIALOG_STANDARD:
self.widget.setChecked(value)
if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
else:
self.setComboValue(value)
def value(self):
if self.dialog == DIALOG_STANDARD:
if self.dialogType == DIALOG_STANDARD:
return self.widget.isChecked()
if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
else:
return self.comboValue()
@ -138,3 +193,590 @@ class CrsWidgetWrapper(WidgetWrapper):
def value(self):
return self.widget.getValue()
class ExtentWidgetWrapper(WidgetWrapper):
def createWidget(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return ExtentSelectionPanel(self.dialog, self.param)
else:
widget = QComboBox()
widget.setEditable(True)
extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent)
if self.param.optional:
widget.addItem(self.USE_MIN_COVERING_EXTENT, None)
for ex in extents:
widget.addItem(self.dialog.resolveValueDescription(ex), ex)
if not self.param.default:
widget.setEditText(self.param.default)
return widget
def setValue(self, value):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
self.widget.setExtentFromString(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return self.widget.getValue()
else:
idx = self.widget.findText(self.widget.currentText())
if idx < 0:
s = unicode(self.widget.currentText()).strip()
if s:
try:
tokens = s.split(',')
if len(tokens) != 4:
raise InvalidParameterValue()
for token in tokens:
float(token)
except:
raise InvalidParameterValue()
elif self.param.optional:
s = None
else:
raise InvalidParameterValue()
return s
else:
return self.widget.itemData(self.widget.currentIndex())
class PointWidgetWrapper(WidgetWrapper):
def createWidget(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return PointSelectionPanel(self.dialog, self.param.default)
else:
item = QComboBox()
item.setEditable(True)
points = self.dialog.getAvailableValuesOfType(ParameterPoint)
for p in points:
item.addItem(self.dialog.resolveValueDescription(p), p)
item.setEditText(unicode(self.param.default))
def setValue(self, value):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
self.widget.setPointFromString(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return self.widget.getValue()
else:
idx = self.widget.findText(self.widget.currentText())
if idx < 0:
s = unicode(self.widget.currentText()).strip()
if s:
try:
tokens = s.split(',')
if len(tokens) != 2:
raise InvalidParameterValue()
for token in tokens:
float(token)
except:
raise InvalidParameterValue()
elif self.param.optional:
s = None
else:
raise InvalidParameterValue()
return s
else:
return self.widget.itemData(self.widget.currentIndex())
class FileWidgetWrapper(WidgetWrapper):
def createWidget(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return FileSelectionPanel(self.param.isFolder, self.param.ext)
else:
widget = QComboBox()
widget.setEditable(True)
files = self.dialog.getAvailableValuesOfType(ParameterFile, OutputFile)
for f in files:
widget.addItem(self.dialog.resolveValueDescription(f), f)
return widget
def setValue(self, value):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
self.widget.setText(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return self.widget.getValue()
else:
return self.comboValue()
class FixedTableWidgetWrapper(WidgetWrapper):
def createWidget(self):
return FixedTablePanel(self.param)
def setValue(self, value):
pass
def value(self):
if self.dialogType == DIALOG_MODELER:
table = self.widget.table
if not bool(table) and not self.param.optional:
raise InvalidParameterValue()
return ParameterFixedTable.tableToString(table)
else:
return self.widget.table
class MultipleInputWidgetWrapper(WidgetWrapper):
def _getOptions(self):
if self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector)
elif self.param.datatype == dataobjects.TYPE_VECTOR_POINT:
options = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector,
[dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
elif self.param.datatype == dataobjects.TYPE_VECTOR_LINE:
options = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector,
[dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
elif self.param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
options = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector,
[dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
elif self.param.datatype == dataobjects.TYPE_RASTER:
options = self.dialog.getAvailableValuesOfType(ParameterRaster, OutputRaster)
else:
options = self.dialog.getAvailableValuesOfType(ParameterFile, OutputFile)
return options
def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
if self.param.datatype == dataobjects.TYPE_FILE:
return MultipleInputPanel(datatype=dataobjects.TYPE_FILE)
else:
if self.param.datatype == dataobjects.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
opts = [getExtendedLayerName(opt) for opt in options]
return MultipleInputPanel(opts)
elif self.dialogType == DIALOG_BATCH:
return BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
else:
options = [self.dialog.resolveValueDescription(opt) for opt in self._getOptions()]
return MultipleInputPanel(options)
def refresh(self):
if self.param.datatype != dataobjects.TYPE_FILE:
if self.param.datatype == dataobjects.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
opts = [self.getExtendedLayerName(opt) for opt in options]
self.widget.updateForOptions(opts)
def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
pass # TODO
elif self.dialogType == DIALOG_BATCH:
return self.widget.setText(value)
else:
options = self._getOptions()
selected = []
for i, opt in enumerate(options):
if opt in value:
selected.append(i)
self.widget.setSelectedItems(selected)
def value(self):
if self.dialogType == DIALOG_STANDARD:
if self.param.datatype == dataobjects.TYPE_FILE:
return self.param.setValue(self.widget.selectedoptions)
else:
if self.param.datatype == dataobjects.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
return self.param.setValue([options[i] for i in self.widget.selectedoptions])
elif self.dialogType == DIALOG_BATCH:
return self.widget.getText()
else:
options = self._getOptions()
values = [options[i] for i in self.widget.selectedoptions]
if len(values) == 0 and not self.param.optional:
raise InvalidParameterValue()
return values
class NumberWidgetWrapper(WidgetWrapper):
def createWidget(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return NumberInputPanel(self.param.default, self.param.min, self.param.max,
self.param.isInteger)
else:
widget = QComboBox()
widget.setEditable(True)
files = self.dialog.getAvailableValuesOfType(ParameterNumber, OutputNumber)
for f in files:
widget.addItem(self.dialog.resolveValueDescription(f), f)
return widget
def setValue(self, value):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
self.widget.setValue(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
return self.widget.getValue()
else:
def validator(v):
if str(v).strip():
try:
if self.param.isInteger:
int(v)
else:
float(v)
return True
except:
return False
else:
return self.param.optional
return self.comboValue(validator)
class RasterWidgetWrapper(WidgetWrapper):
NOT_SELECTED = '[Not selected]'
def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
layers = dataobjects.getRasterLayers()
items = []
if self.param.optional:
items.append((self.NOT_SELECTED, None))
for layer in layers:
items.append((getExtendedLayerName(layer), layer))
return InputLayerSelectorPanel(items, self.param)
elif self.dialogType == DIALOG_BATCH:
return BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
else:
widget = QComboBox()
widget.setEditable(True)
files = self.dialog.getAvailableValuesOfType(ParameterRaster, OutputRaster)
for f in files:
widget.addItem(self.dialog.resolveValueDescription(f), f)
return widget
def refresh(self):
self.widget.cmbText.clear()
layers = dataobjects.getRasterLayers(self)
layers.sort(key=lambda lay: lay.name())
if self.param.optional:
self.widget.cmbText.addItem(self.NOT_SELECTED, None)
for layer in layers:
self.widget.cmbText.addItem(getExtendedLayerName(layer), layer)
def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
pass # TODO
elif self.dialogType == DIALOG_BATCH:
return self.widget.setText(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType == DIALOG_STANDARD:
return self.widget.getValue()
elif self.dialogType == DIALOG_BATCH:
return self.widget.getText()
else:
return self.comboValue()
class SelectionWidgetWrapper(WidgetWrapper):
def createWidget(self):
widget = QComboBox()
widget.addItems(self.param.options)
if self.param.default:
widget.setCurrentIndex(self.param.default)
return widget
def setValue(self, value):
self.widget.setCurrentIndex(int(value))
def value(self):
return self.widget.currentIndex()
class VectorWidgetWrapper(WidgetWrapper):
NOT_SELECTED = '[Not selected]'
def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
widget = QComboBox()
self._populate(widget)
return widget
elif self.dialogType == DIALOG_BATCH:
return BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
else:
widget = QComboBox()
layers = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector)
if self.param.optional:
widget.addItem(self.NOT_SELECTED, None)
for layer in layers:
widget.addItem(self.dialog.resolveValueDescription(layer), layer)
return widget
def _populate(self, widget):
widget.clear()
layers = dataobjects.getVectorLayers(self.param.datatype)
layers.sort(key=lambda lay: lay.name())
if self.param.optional:
widget.addItem(self.NOT_SELECTED, None)
for layer in layers:
widget.addItem(getExtendedLayerName(layer), layer)
widget.currentIndexChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
widget.name = self.param.name
def refresh(self):
self._populate(self.widget)
def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
pass # TODO
elif self.dialogType == DIALOG_BATCH:
return self.widget.setText(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType == DIALOG_STANDARD:
try:
return self.widget.itemData(self.widget.currentIndex())
except:
return self.widget.getValue()
elif self.dialogType == DIALOG_BATCH:
return self.widget.getText()
else:
return self.comboValue()
class StringWidgetWrapper(WidgetWrapper):
def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
if self.param.multiline:
widget = QPlainTextEdit()
if self.param.default:
widget.setPlainText(self.param.default)
else:
widget = QLineEdit()
if self.param.default:
widget.setText(self.param.default)
elif self.dialogType == DIALOG_BATCH:
widget = QLineEdit()
if self.param.default:
widget.setText(self.param.default)
else:
strings = self.dialog.getAvailableValuesOfType(ParameterString, OutputString)
options = [(self.dialog.resolveValueDescription(s), s) for s in strings]
if self.param.multiline:
widget = MultilineTextPanel(options)
widget.setText(self.param.default or "")
else:
widget = QComboBox()
widget.setEditable(True)
for desc, val in options:
widget.addItem(desc, val)
widget.setEditText(self.param.default or "")
return widget
def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
pass # TODO
elif self.dialogType == DIALOG_BATCH:
self.widget.setText(value)
else:
if self.param.multiline:
self.widget.setValue(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType in DIALOG_STANDARD:
if self.param.multiline:
text = self.widget.toPlainText()
else:
text = self.widget.text()
if self.param.evaluateExpressions:
try:
text = self.evaluateExpression(text)
except:
pass
return text
if self.dialogType == DIALOG_BATCH:
text = self.widget.text()
if self.param.evaluateExpressions:
try:
text = self.evaluateExpression(text)
except:
pass
return text
else:
if self.param.multiline:
value = self.widget.getValue()
option = self.widget.getOption()
if option == MultilineTextPanel.USE_TEXT:
if value == '':
if self.param.optional:
return None
else:
raise InvalidParameterValue()
else:
return value
else:
return value
else:
def validator(v):
return bool(v) or self.param.optional
return self.comboValue(validator)
class TableWidgetWrapper(WidgetWrapper):
NOT_SELECTED = '[Not selected]'
def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
widget = QComboBox()
layers = dataobjects.getTables()
layers.sort(key=lambda lay: lay.name())
if self.param.optional:
widget.addItem(self.NOT_SELECTED, None)
for layer in layers:
widget.addItem(layer.name(), layer)
widget.currentIndexChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
widget.name = self.param.name
return widget
elif self.dialogType == DIALOG_BATCH:
return BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
else:
widget = QComboBox()
tables = self.getAvailableValuesOfType(ParameterTable, OutputTable)
layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
if self.param.optional:
widget.addItem(self.NOT_SELECTED, None)
for table in tables:
widget.addItem(self.dialog.resolveValueDescription(table), table)
for layer in layers:
widget.addItem(self.dialog.resolveValueDescription(layer), layer)
return widget
def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
pass # TODO
elif self.dialogType == DIALOG_BATCH:
return self.widget.setText(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType == DIALOG_STANDARD:
try:
return self.widget.itemData(self.widget.currentIndex())
except:
return self.widget.getValue()
elif self.dialogType == DIALOG_BATCH:
return self.widget.getText()
else:
return self.comboValue()
class TableFieldWidgetWrapper(WidgetWrapper):
NOT_SET = '[Not set]'
def createWidget(self):
if self.dialogType == DIALOG_STANDARD:
widget = QComboBox()
return widget
elif self.dialogType == DIALOG_BATCH:
item = QLineEdit()
if self.param.default is not None:
item.setText(self.param.default)
else:
widget = QComboBox()
widget.setEditable(True)
fields = self.getAvailableValuesOfType(ParameterTableField, None)
if self.param.optional:
widget.addItem(self.NOT_SELECTED, None)
for f in fields:
widget.addItem(self.resolveValueDescription(f), f)
return widget
def postInitialize(self, wrappers):
for wrapper in wrappers:
if wrapper.param.name == self.param.parent:
layer = wrapper.widget.itemData(wrapper.widget.currentIndex())
if layer is not None:
self.widget.clear()
if self.param.optional:
self.widget.addItem(self.tr(self.NOT_SET))
self.widget.addItems(self.getFields(layer, wrapper.param.datatype))
break
def getFields(self, layer, datatype):
fieldTypes = []
if datatype == ParameterTableField.DATA_TYPE_STRING:
fieldTypes = [QVariant.String]
elif datatype == ParameterTableField.DATA_TYPE_NUMBER:
fieldTypes = [QVariant.Int, QVariant.Double, QVariant.LongLong,
QVariant.UInt, QVariant.ULongLong]
fieldNames = set()
for field in layer.fields():
if not fieldTypes or field.type() in fieldTypes:
fieldNames.add(unicode(field.name()))
return sorted(list(fieldNames), cmp=locale.strcoll)
def setValue(self, value):
if self.dialogType == DIALOG_STANDARD:
pass # TODO
elif self.dialogType == DIALOG_BATCH:
return self.widget.setText(value)
else:
self.setComboValue(value)
def value(self):
if self.dialogType == DIALOG_STANDARD:
if self.param.optional and self.widget.currentIndex() == 0:
return None
return self.widget.currentText()
elif self.dialogType == DIALOG_BATCH:
return self.widget.text()
else:
return self.comboValue()
def anotherParameterWidgetHasChanged(self,wrapper):
if wrapper.param.name == self.param.parent:
layer = wrapper.value()
if layer is not None:
self.widget.clear()
if self.param.optional:
self.widget.addItem(self.tr(self.NOT_SET))
self.widget.addItems(self.getFields(layer, wrapper.param.datatype))

View File

@ -40,12 +40,7 @@ from qgis.core import QgsNetworkAccessManager
from qgis.gui import QgsMessageBar
from processing.gui.wrappers import (
DIALOG_MODELER,
wrapper_from_param,
NotYetImplementedWidgetWrapper,
)
from processing.gui.wrappers import NotYetImplementedWidgetWrapper, InvalidParameterValue
from processing.gui.CrsSelectionPanel import CrsSelectionPanel
from processing.gui.MultipleInputPanel import MultipleInputPanel
from processing.gui.FixedTablePanel import FixedTablePanel
@ -183,7 +178,7 @@ class ModelerParametersDialog(QDialog):
self.widgets = {}
self.checkBoxes = {}
self.showAdvanced = False
self.widget_wrappers = {}
self.wrappers = {}
self.valueItems = {}
self.dependentItems = {}
self.resize(650, 450)
@ -238,8 +233,8 @@ class ModelerParametersDialog(QDialog):
label = QLabel(desc)
self.labels[param.name] = label
wrapper = self.getWidgetWrapperFromParameter(param)
self.widget_wrappers[param.name] = wrapper
wrapper = param.wrapper(self)
self.wrappers[param.name] = wrapper
widget = wrapper.widget
self.valueItems[param.name] = widget
@ -255,7 +250,7 @@ class ModelerParametersDialog(QDialog):
self.widgets[param.name] = widget
self.verticalLayout.addWidget(label)
self.verticalLayout.addWidget(wrapper)
self.verticalLayout.addWidget(wrapper.widget)
for output in self._alg.outputs:
if output.hidden:
@ -396,135 +391,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 getWidgetWrapperFromParameter(self, param):
wrapper = wrapper_from_param(param, DIALOG_MODELER)
if wrapper is None:
widget = self.getWidgetFromParameter(param)
wrapper = NotYetImplementedWidgetWrapper(param, widget)
model_values = []
values = self.getAvailableValuesForParam(param)
for value in values:
model_values.append((self.resolveValueDescription(value), value))
input_wrapper = ModelerWidgetWrapper(wrapper, model_values)
return input_wrapper
def getWidgetFromParameter(self, param):
if isinstance(param, ParameterRaster):
item = QComboBox()
layers = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
if param.optional:
item.addItem(self.NOT_SELECTED, None)
for layer in layers:
item.addItem(self.resolveValueDescription(layer), layer)
elif isinstance(param, ParameterVector):
item = QComboBox()
layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
if param.optional:
item.addItem(self.NOT_SELECTED, None)
for layer in layers:
item.addItem(self.resolveValueDescription(layer), layer)
elif isinstance(param, ParameterTable):
item = QComboBox()
tables = self.getAvailableValuesOfType(ParameterTable, OutputTable)
layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
if param.optional:
item.addItem(self.NOT_SELECTED, None)
for table in tables:
item.addItem(self.resolveValueDescription(table), table)
for layer in layers:
item.addItem(self.resolveValueDescription(layer), layer)
elif isinstance(param, ParameterSelection):
item = QComboBox()
item.addItems(param.options)
item.setCurrentIndex(param.default or 0)
elif isinstance(param, ParameterFixedTable):
item = FixedTablePanel(param)
elif isinstance(param, ParameterRange):
item = RangePanel(param)
elif isinstance(param, ParameterMultipleInput):
if param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
elif param.datatype == dataobjects.TYPE_VECTOR_POINT:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_VECTOR_LINE:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_RASTER:
options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
else:
options = self.getAvailableValuesOfType(ParameterFile, OutputFile)
opts = []
for opt in options:
opts.append(self.resolveValueDescription(opt))
item = MultipleInputPanel(opts)
elif isinstance(param, ParameterString):
strings = self.getAvailableValuesOfType(ParameterString, OutputString)
options = [(self.resolveValueDescription(s), s) for s in strings]
if param.multiline:
item = MultilineTextPanel(options)
item.setText(str(param.default or ""))
else:
item = QComboBox()
item.setEditable(True)
for desc, val in options:
item.addItem(desc, val)
item.setEditText(str(param.default or ""))
elif isinstance(param, ParameterTableField):
item = QComboBox()
item.setEditable(True)
fields = self.getAvailableValuesOfType(ParameterTableField, None)
for f in fields:
item.addItem(self.resolveValueDescription(f), f)
elif isinstance(param, ParameterTableMultipleField):
item = QComboBox()
item.setEditable(True)
fields = self.getAvailableValuesOfType(ParameterTableMultipleField, None)
for f in fields:
item.addItem(self.resolveValueDescription(f), f)
elif isinstance(param, ParameterNumber):
item = QComboBox()
item.setEditable(True)
numbers = self.getAvailableValuesOfType(ParameterNumber, OutputNumber)
for n in numbers:
item.addItem(self.resolveValueDescription(n), n)
item.setEditText(str(param.default))
elif isinstance(param, ParameterExtent):
item = QComboBox()
item.setEditable(True)
extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent)
if self.canUseAutoExtent():
item.addItem(self.USE_MIN_COVERING_EXTENT, None)
for ex in extents:
item.addItem(self.resolveValueDescription(ex), ex)
if not self.canUseAutoExtent():
item.setEditText(str(param.default))
elif isinstance(param, ParameterPoint):
item = QComboBox()
item.setEditable(True)
points = self.getAvailableValuesOfType(ParameterPoint)
for p in points:
item.addItem(self.resolveValueDescription(p), p)
item.setEditText(str(param.default))
elif isinstance(param, ParameterFile):
item = QComboBox()
item.setEditable(True)
files = self.getAvailableValuesOfType(ParameterFile, OutputFile)
for f in files:
item.addItem(self.resolveValueDescription(f), f)
elif isinstance(param, ParameterGeometryPredicate):
item = GeometryPredicateSelectionPanel(param.enabledPredicates)
else:
item = QLineEdit()
try:
item.setText(str(param.default))
except:
pass
return item
def canUseAutoExtent(self):
for param in self._alg.parameters:
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
@ -559,22 +425,6 @@ class ModelerParametersDialog(QDialog):
self.tableWidget.setCellWidget(i, 1, item)
self.tableWidget.setRowHeight(i, 22)
def setComboBoxValue(self, combo, value, param):
if isinstance(value, list):
value = value[0]
items = [combo.itemData(i) for i in range(combo.count())]
try:
idx = items.index(value)
combo.setCurrentIndex(idx)
return
except ValueError:
pass
if combo.isEditable():
if value is not None:
combo.setEditText(str(value))
elif isinstance(param, ParameterSelection):
combo.setCurrentIndex(int(value))
def setPreviousValues(self):
if self._algName is not None:
alg = self.model.algs[self._algName]
@ -587,52 +437,8 @@ class ModelerParametersDialog(QDialog):
else:
value = param.default
wrapper = self.widget_wrappers[param.name]
if wrapper.implemented:
wrapper.setValue(value)
continue
widget = wrapper.widget
if isinstance(param, (
ParameterRaster,
ParameterVector,
ParameterTable,
ParameterTableField,
ParameterSelection,
ParameterNumber,
ParameterExtent,
ParameterFile,
ParameterPoint,
ParameterCrs
)):
self.setComboBoxValue(widget, value, param)
elif isinstance(param, ParameterString):
if param.multiline:
widget.setValue(value)
else:
self.setComboBoxValue(widget, value, param)
elif isinstance(param, ParameterFixedTable):
pass # TODO!
elif isinstance(param, ParameterMultipleInput):
if param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
elif param.datatype == dataobjects.TYPE_VECTOR_POINT:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_VECTOR_LINE:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_RASTER:
options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
else:
options = self.getAvailableValuesOfType(ParameterFile, OutputFile)
selected = []
for i, opt in enumerate(options):
if opt in value:
selected.append(i)
widget.setSelectedItems(selected)
elif isinstance(param, ParameterGeometryPredicate):
widget.setValue(value)
wrapper = self.wrappers[param.name]
wrapper.setValue(value)
for name, out in alg.outputs.items():
widget = self.valueItems[name].setText(out.description)
@ -654,7 +460,7 @@ class ModelerParametersDialog(QDialog):
for param in params:
if param.hidden:
continue
if not self.setParamValue(alg, param, self.widget_wrappers[param.name]):
if not self.setParamValue(alg, param, self.wrappers[param.name]):
self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description,
level=QgsMessageBar.WARNING)
return None
@ -671,194 +477,13 @@ class ModelerParametersDialog(QDialog):
return alg
def setParamValueLayerOrTable(self, alg, param, widget):
idx = widget.currentIndex()
if idx < 0:
return False
else:
value = widget.itemData(widget.currentIndex())
alg.params[param.name] = value
return True
def setParamTableFieldValue(self, alg, param, widget):
idx = widget.findText(widget.currentText())
if idx < 0:
s = str(widget.currentText()).strip()
if s == '':
if param.optional:
alg.params[param.name] = None
return True
else:
return False
else:
alg.params[param.name] = s
return True
else:
alg.params[param.name] = widget.itemData(widget.currentIndex())
return True
def setParamStringValue(self, alg, param, widget):
if param.multiline:
value = widget.getValue()
option = widget.getOption()
if option == MultilineTextPanel.USE_TEXT:
if value == '':
if param.optional:
alg.params[param.name] = None
return True
else:
return False
else:
alg.params[param.name] = value
else:
alg.params[param.name] = value
else:
idx = widget.findText(widget.currentText())
if idx < 0:
value = widget.currentText().strip()
if value == '':
if param.optional:
alg.params[param.name] = None
return True
else:
return False
else:
alg.params[param.name] = value
else:
alg.params[param.name] = widget.itemData(widget.currentIndex())
return True
def setParamFileValue(self, alg, param, widget):
idx = widget.findText(widget.currentText())
if idx < 0:
value = widget.currentText()
else:
value = widget.itemData(widget.currentIndex())
alg.params[param.name] = value
return True
def setParamNumberValue(self, alg, param, widget):
idx = widget.findText(widget.currentText())
if idx < 0:
s = widget.currentText().strip()
if s:
try:
value = float(s)
except:
return False
elif param.optional:
value = None
else:
return False
else:
value = widget.itemData(widget.currentIndex())
alg.params[param.name] = value
return True
def setParamExtentValue(self, alg, param, widget):
idx = widget.findText(widget.currentText())
if idx < 0:
s = str(widget.currentText()).strip()
if s:
try:
tokens = s.split(',')
if len(tokens) != 4:
return False
for token in tokens:
float(token)
except:
return False
elif param.optional:
s = None
else:
return False
alg.params[param.name] = [s]
else:
value = widget.itemData(widget.currentIndex())
alg.params[param.name] = value
return True
def setParamPointValue(self, alg, param, widget):
idx = widget.findText(widget.currentText())
if idx < 0:
s = str(widget.currentText()).strip()
if s:
try:
tokens = s.split(',')
if len(tokens) != 2:
return False
for token in tokens:
float(token)
except:
return False
elif param.optional:
s = None
else:
return False
alg.params[param.name] = [s]
else:
value = widget.itemData(widget.currentIndex())
alg.params[param.name] = value
return True
def setParamValue(self, alg, param, wrapper):
if wrapper.implemented:
alg.params[param.name] = wrapper.value()
return True
widget = wrapper.widget
if isinstance(param, (ParameterRaster, ParameterVector,
ParameterTable)):
return self.setParamValueLayerOrTable(alg, param, widget)
elif isinstance(param, ParameterString):
return self.setParamStringValue(alg, param, widget)
elif isinstance(param, ParameterNumber):
return self.setParamNumberValue(alg, param, widget)
elif isinstance(param, ParameterExtent):
return self.setParamExtentValue(alg, param, widget)
elif isinstance(param, ParameterPoint):
return self.setParamPointValue(alg, param, widget)
elif isinstance(param, ParameterFile):
return self.setParamFileValue(alg, param, widget)
elif isinstance(param, ParameterSelection):
alg.params[param.name] = widget.currentIndex()
return True
elif isinstance(param, ParameterRange):
alg.params[param.name] = widget.getValue()
return True
elif isinstance(param, ParameterFixedTable):
table = widget.table
if not bool(table) and not param.optional:
return False
alg.params[param.name] = ParameterFixedTable.tableToString(table)
return True
elif isinstance(param, (ParameterTableField,
ParameterTableMultipleField)):
return self.setParamTableFieldValue(alg, param, widget)
elif isinstance(param, ParameterMultipleInput):
if param.datatype == dataobjects.TYPE_VECTOR_ANY:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
elif param.datatype == dataobjects.TYPE_VECTOR_POINT:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_VECTOR_LINE:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
elif param.datatype == dataobjects.TYPE_RASTER:
options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
else:
options = self.getAvailableValuesOfType(ParameterFile, OutputFile)
values = [options[i] for i in widget.selectedoptions]
if len(values) == 0 and not param.optional:
return False
alg.params[param.name] = values
return True
elif isinstance(param, ParameterGeometryPredicate):
alg.params[param.name] = widget.value()
return True
else:
alg.params[param.name] = str(widget.text())
try:
value = wrapper.value()
alg.params[param.name] = value
return True
except InvalidParameterValue:
return False
def okPressed(self):
self.alg = self.createAlgorithm()