2012-10-05 23:28:47 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
"""
|
|
|
|
***************************************************************************
|
|
|
|
ParametersPanel.py
|
|
|
|
---------------------
|
|
|
|
Date : August 2012
|
|
|
|
Copyright : (C) 2012 by Victor Olaya
|
|
|
|
Email : volayaf at gmail 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. *
|
|
|
|
* *
|
|
|
|
***************************************************************************
|
|
|
|
"""
|
|
|
|
|
|
|
|
__author__ = 'Victor Olaya'
|
|
|
|
__date__ = 'August 2012'
|
|
|
|
__copyright__ = '(C) 2012, Victor Olaya'
|
|
|
|
# This will get replaced with a git SHA1 when you do a git archive
|
|
|
|
__revision__ = '$Format:%H$'
|
|
|
|
|
2012-09-15 18:25:25 +03:00
|
|
|
import os
|
|
|
|
import locale
|
2013-02-01 13:09:39 +04:00
|
|
|
|
2012-09-15 18:25:25 +03:00
|
|
|
from PyQt4 import QtCore, QtGui
|
2013-02-01 13:09:39 +04:00
|
|
|
|
2012-09-15 18:25:25 +03:00
|
|
|
from sextante.core.QGisLayers import QGisLayers
|
2013-02-01 13:09:39 +04:00
|
|
|
from sextante.core.SextanteConfig import SextanteConfig
|
|
|
|
|
|
|
|
from sextante.gui.OutputSelectionPanel import OutputSelectionPanel
|
2012-09-15 18:25:25 +03:00
|
|
|
from sextante.gui.InputLayerSelectorPanel import InputLayerSelectorPanel
|
2013-02-01 13:09:39 +04:00
|
|
|
from sextante.gui.FixedTablePanel import FixedTablePanel
|
|
|
|
from sextante.gui.RangePanel import RangePanel
|
|
|
|
from sextante.gui.MultipleInputPanel import MultipleInputPanel
|
|
|
|
from sextante.gui.NumberInputPanel import NumberInputPanel
|
|
|
|
from sextante.gui.ExtentSelectionPanel import ExtentSelectionPanel
|
|
|
|
from sextante.gui.FileSelectionPanel import FileSelectionPanel
|
|
|
|
from sextante.gui.CrsSelectionPanel import CrsSelectionPanel
|
|
|
|
|
|
|
|
from sextante.parameters.ParameterRaster import ParameterRaster
|
2012-09-15 18:25:25 +03:00
|
|
|
from sextante.parameters.ParameterVector import ParameterVector
|
|
|
|
from sextante.parameters.ParameterTable import ParameterTable
|
|
|
|
from sextante.parameters.ParameterBoolean import ParameterBoolean
|
|
|
|
from sextante.parameters.ParameterTableField import ParameterTableField
|
|
|
|
from sextante.parameters.ParameterSelection import ParameterSelection
|
|
|
|
from sextante.parameters.ParameterFixedTable import ParameterFixedTable
|
|
|
|
from sextante.parameters.ParameterRange import ParameterRange
|
|
|
|
from sextante.parameters.ParameterMultipleInput import ParameterMultipleInput
|
|
|
|
from sextante.parameters.ParameterNumber import ParameterNumber
|
|
|
|
from sextante.parameters.ParameterExtent import ParameterExtent
|
|
|
|
from sextante.parameters.ParameterFile import ParameterFile
|
|
|
|
from sextante.parameters.ParameterCrs import ParameterCrs
|
2013-02-01 13:09:39 +04:00
|
|
|
from sextante.parameters.ParameterString import ParameterString
|
|
|
|
|
2012-09-15 18:25:25 +03:00
|
|
|
from sextante.outputs.OutputRaster import OutputRaster
|
|
|
|
from sextante.outputs.OutputTable import OutputTable
|
|
|
|
from sextante.outputs.OutputVector import OutputVector
|
|
|
|
|
|
|
|
class ParametersPanel(QtGui.QWidget):
|
|
|
|
|
|
|
|
NOT_SELECTED = "[Not selected]"
|
|
|
|
|
|
|
|
def __init__(self, parent, alg):
|
|
|
|
super(ParametersPanel, self).__init__(None)
|
|
|
|
self.parent = parent
|
|
|
|
self.alg = alg;
|
|
|
|
self.valueItems = {}
|
|
|
|
self.labels = {}
|
|
|
|
self.widgets = {}
|
|
|
|
self.checkBoxes = {}
|
|
|
|
self.dependentItems = {}
|
|
|
|
self.iterateButtons = {}
|
|
|
|
self.showAdvanced = False
|
|
|
|
self.initGUI()
|
|
|
|
|
|
|
|
def initGUI(self):
|
|
|
|
tooltips = self.alg.getParameterDescriptions()
|
|
|
|
tableLike = SextanteConfig.getSetting(SextanteConfig.TABLE_LIKE_PARAM_PANEL)
|
|
|
|
if tableLike:
|
|
|
|
self.tableWidget = QtGui.QTableWidget()
|
|
|
|
self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
|
|
|
|
self.tableWidget.setColumnCount(2)
|
|
|
|
self.tableWidget.setColumnWidth(0,300)
|
|
|
|
self.tableWidget.setColumnWidth(1,300)
|
|
|
|
self.tableWidget.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Parameter"))
|
|
|
|
self.tableWidget.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("Value"))
|
|
|
|
self.tableWidget.verticalHeader().setVisible(False)
|
|
|
|
self.tableWidget.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
|
|
|
|
self.setTableContent()
|
|
|
|
self.verticalLayout = QtGui.QVBoxLayout()
|
|
|
|
self.verticalLayout.setSpacing(0)
|
|
|
|
self.verticalLayout.setMargin(0)
|
|
|
|
self.verticalLayout.addWidget(self.tableWidget)
|
|
|
|
self.setLayout(self.verticalLayout)
|
|
|
|
else:
|
|
|
|
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
|
|
|
self.verticalLayout = QtGui.QVBoxLayout()
|
|
|
|
self.verticalLayout.setSpacing(5)
|
|
|
|
self.verticalLayout.setMargin(20)
|
|
|
|
for param in self.alg.parameters:
|
|
|
|
if param.isAdvanced:
|
|
|
|
self.advancedButton = QtGui.QPushButton()
|
|
|
|
self.advancedButton.setText("Show advanced parameters")
|
2013-02-17 23:03:17 +01:00
|
|
|
self.advancedButton.setMaximumWidth(250)
|
2012-09-15 18:25:25 +03:00
|
|
|
QtCore.QObject.connect(self.advancedButton, QtCore.SIGNAL("clicked()"), self.showAdvancedParametersClicked)
|
|
|
|
self.verticalLayout.addWidget(self.advancedButton)
|
|
|
|
break
|
|
|
|
for param in self.alg.parameters:
|
|
|
|
if param.hidden:
|
|
|
|
continue
|
|
|
|
desc = param.description
|
|
|
|
if isinstance(param, ParameterExtent):
|
|
|
|
desc += "(xmin, xmax, ymin, ymax)"
|
|
|
|
label = QtGui.QLabel(desc)
|
|
|
|
self.labels[param.name] = label
|
|
|
|
widget = self.getWidgetFromParameter(param)
|
|
|
|
self.valueItems[param.name] = widget
|
2013-07-23 18:57:06 +02:00
|
|
|
if isinstance(param, ParameterVector) and not self.alg.allowOnlyOpenedLayers:
|
2012-09-15 18:25:25 +03:00
|
|
|
layout = QtGui.QHBoxLayout()
|
|
|
|
layout.setSpacing(2)
|
|
|
|
layout.setMargin(0)
|
|
|
|
layout.addWidget(widget)
|
|
|
|
button = QtGui.QToolButton()
|
|
|
|
icon = QtGui.QIcon(os.path.dirname(__file__) + "/../images/iterate.png")
|
|
|
|
button.setIcon(icon)
|
|
|
|
button.setToolTip("Iterate over this layer")
|
|
|
|
button.setCheckable(True)
|
|
|
|
button.setMaximumWidth(30)
|
|
|
|
button.setMaximumHeight(30)
|
|
|
|
layout.addWidget(button)
|
|
|
|
self.iterateButtons[param.name] = button
|
|
|
|
QtCore.QObject.connect(button, QtCore.SIGNAL("toggled(bool)"), self.buttonToggled)
|
|
|
|
widget = QtGui.QWidget()
|
|
|
|
widget.setLayout(layout)
|
|
|
|
if param.name in 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:
|
|
|
|
continue
|
|
|
|
label = QtGui.QLabel(output.description)
|
|
|
|
widget = OutputSelectionPanel(output,self.alg)
|
|
|
|
self.verticalLayout.addWidget(label)
|
|
|
|
self.verticalLayout.addWidget(widget)
|
2012-12-12 00:47:29 +01:00
|
|
|
if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
|
2012-09-15 18:25:25 +03:00
|
|
|
check = QtGui.QCheckBox()
|
|
|
|
check.setText("Open output file after running algorithm")
|
|
|
|
check.setChecked(True)
|
|
|
|
self.verticalLayout.addWidget(check)
|
|
|
|
self.checkBoxes[output.name] = check
|
|
|
|
self.valueItems[output.name] = widget
|
|
|
|
|
|
|
|
self.verticalLayout.addStretch(1000)
|
|
|
|
self.setLayout(self.verticalLayout)
|
|
|
|
|
|
|
|
def showAdvancedParametersClicked(self):
|
|
|
|
self.showAdvanced = not self.showAdvanced
|
|
|
|
if self.showAdvanced:
|
|
|
|
self.advancedButton.setText("Hide advanced parameters")
|
|
|
|
else:
|
|
|
|
self.advancedButton.setText("Show advanced parameters")
|
|
|
|
for param in self.alg.parameters:
|
|
|
|
if param.isAdvanced:
|
|
|
|
self.labels[param.name].setVisible(self.showAdvanced)
|
|
|
|
self.widgets[param.name].setVisible(self.showAdvanced)
|
|
|
|
|
|
|
|
def buttonToggled(self, value):
|
|
|
|
if value:
|
|
|
|
sender = self.sender()
|
|
|
|
for button in self.iterateButtons.values():
|
|
|
|
if button is not sender:
|
|
|
|
button.setChecked(False)
|
|
|
|
|
2013-02-06 21:00:26 +01:00
|
|
|
def getExtendedLayerName(self, layer):
|
2013-02-17 23:03:17 +01:00
|
|
|
authid = layer.crs().authid()
|
2013-02-28 22:08:32 +01:00
|
|
|
if SextanteConfig.getSetting(SextanteConfig.SHOW_CRS_DEF) and authid is not None:
|
2013-02-17 23:03:17 +01:00
|
|
|
return layer.name() + " [" + str(authid) +"]"
|
2013-02-06 21:00:26 +01:00
|
|
|
else:
|
|
|
|
return layer.name()
|
2013-02-07 01:09:39 +01:00
|
|
|
|
2012-09-15 18:25:25 +03:00
|
|
|
def getWidgetFromParameter(self, param):
|
|
|
|
if isinstance(param, ParameterRaster):
|
|
|
|
layers = QGisLayers.getRasterLayers()
|
|
|
|
items = []
|
|
|
|
if (param.optional):
|
|
|
|
items.append((self.NOT_SELECTED, None))
|
|
|
|
for layer in layers:
|
2013-02-06 21:00:26 +01:00
|
|
|
items.append((self.getExtendedLayerName(layer), layer))
|
2012-09-15 18:25:25 +03:00
|
|
|
item = InputLayerSelectorPanel(items)
|
|
|
|
elif isinstance(param, ParameterVector):
|
2013-07-23 18:57:06 +02:00
|
|
|
if self.somethingDependsOnThisParameter(param) or self.alg.allowOnlyOpenedLayers:
|
2012-09-15 18:25:25 +03:00
|
|
|
item = QtGui.QComboBox()
|
|
|
|
layers = QGisLayers.getVectorLayers(param.shapetype)
|
|
|
|
if (param.optional):
|
2013-02-07 23:40:43 +01:00
|
|
|
item.addItem(self.NOT_SELECTED, None)
|
2012-09-15 18:25:25 +03:00
|
|
|
for layer in layers:
|
2013-02-07 23:40:43 +01:00
|
|
|
item.addItem(self.getExtendedLayerName(layer), layer)
|
2012-09-15 18:25:25 +03:00
|
|
|
item.currentIndexChanged.connect(self.updateDependentFields)
|
|
|
|
item.name = param.name
|
|
|
|
else:
|
|
|
|
layers = QGisLayers.getVectorLayers(param.shapetype)
|
|
|
|
items = []
|
|
|
|
if (param.optional):
|
|
|
|
items.append((self.NOT_SELECTED, None))
|
|
|
|
for layer in layers:
|
2013-02-06 21:00:26 +01:00
|
|
|
items.append((self.getExtendedLayerName(layer), layer))
|
2012-09-15 18:25:25 +03:00
|
|
|
item = InputLayerSelectorPanel(items)
|
|
|
|
elif isinstance(param, ParameterTable):
|
|
|
|
if self.somethingDependsOnThisParameter(param):
|
|
|
|
item = QtGui.QComboBox()
|
|
|
|
layers = QGisLayers.getTables()
|
|
|
|
if (param.optional):
|
2013-02-07 23:40:43 +01:00
|
|
|
item.addItem(self.NOT_SELECTED, None)
|
2012-09-15 18:25:25 +03:00
|
|
|
for layer in layers:
|
2013-02-07 23:40:43 +01:00
|
|
|
item.addItem(layer.name(), layer)
|
2012-09-15 18:25:25 +03:00
|
|
|
item.currentIndexChanged.connect(self.updateDependentFields)
|
|
|
|
item.name = param.name
|
|
|
|
else:
|
|
|
|
layers = QGisLayers.getTables()
|
|
|
|
items = []
|
|
|
|
if (param.optional):
|
|
|
|
items.append((self.NOT_SELECTED, None))
|
|
|
|
for layer in layers:
|
|
|
|
items.append((layer.name(), layer))
|
|
|
|
item = InputLayerSelectorPanel(items)
|
|
|
|
elif isinstance(param, ParameterBoolean):
|
|
|
|
item = QtGui.QComboBox()
|
|
|
|
item.addItem("Yes")
|
|
|
|
item.addItem("No")
|
|
|
|
if param.default:
|
|
|
|
item.setCurrentIndex(0)
|
|
|
|
else:
|
|
|
|
item.setCurrentIndex(1)
|
|
|
|
elif isinstance(param, ParameterTableField):
|
|
|
|
item = QtGui.QComboBox()
|
|
|
|
if param.parent in self.dependentItems:
|
|
|
|
items = self.dependentItems[param.parent]
|
|
|
|
else:
|
|
|
|
items = []
|
|
|
|
self.dependentItems[param.parent] = items
|
|
|
|
items.append(param.name)
|
|
|
|
parent = self.alg.getParameterFromName(param.parent)
|
|
|
|
if isinstance(parent, ParameterVector):
|
|
|
|
layers = QGisLayers.getVectorLayers(parent.shapetype)
|
|
|
|
else:
|
|
|
|
layers = QGisLayers.getTables()
|
|
|
|
if len(layers)>0:
|
|
|
|
item.addItems(self.getFields(layers[0], param.datatype))
|
|
|
|
elif isinstance(param, ParameterSelection):
|
|
|
|
item = QtGui.QComboBox()
|
|
|
|
item.addItems(param.options)
|
|
|
|
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)
|
|
|
|
elif isinstance(param, ParameterMultipleInput):
|
|
|
|
if param.datatype == ParameterMultipleInput.TYPE_RASTER:
|
|
|
|
options = QGisLayers.getRasterLayers()
|
|
|
|
elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
|
|
|
|
options = QGisLayers.getVectorLayers()
|
|
|
|
else:
|
|
|
|
options = QGisLayers.getVectorLayers(param.datatype)
|
|
|
|
opts = []
|
|
|
|
for opt in options:
|
2013-02-06 21:00:26 +01:00
|
|
|
opts.append(self.getExtendedLayerName(opt))
|
2013-02-03 10:26:43 +01:00
|
|
|
item = MultipleInputPanel(opts)
|
2012-09-15 18:25:25 +03:00
|
|
|
elif isinstance(param, ParameterNumber):
|
|
|
|
item = NumberInputPanel(param.default, param.isInteger)
|
|
|
|
elif isinstance(param, ParameterExtent):
|
|
|
|
item = ExtentSelectionPanel(self.parent, self.alg, param.default)
|
|
|
|
elif isinstance(param, ParameterCrs):
|
|
|
|
item = CrsSelectionPanel(param.default)
|
|
|
|
elif isinstance(param, ParameterString):
|
|
|
|
if param.multiline:
|
|
|
|
verticalLayout = QtGui.QVBoxLayout()
|
|
|
|
verticalLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
|
|
|
|
textEdit = QtGui.QPlainTextEdit()
|
|
|
|
textEdit.setPlainText(param.default)
|
|
|
|
verticalLayout.addWidget(textEdit)
|
|
|
|
item = textEdit
|
|
|
|
else:
|
|
|
|
item = QtGui.QLineEdit()
|
|
|
|
item.setText(str(param.default))
|
|
|
|
else:
|
|
|
|
item = QtGui.QLineEdit()
|
|
|
|
item.setText(str(param.default))
|
|
|
|
|
|
|
|
return item
|
|
|
|
|
|
|
|
def updateDependentFields(self):
|
|
|
|
sender = self.sender()
|
|
|
|
if not isinstance(sender, QtGui.QComboBox):
|
|
|
|
return
|
|
|
|
if not sender.name in self.dependentItems:
|
|
|
|
return
|
2013-06-09 16:04:44 +02:00
|
|
|
layer = sender.itemData(sender.currentIndex())
|
2012-09-15 18:25:25 +03:00
|
|
|
children = self.dependentItems[sender.name]
|
|
|
|
for child in children:
|
|
|
|
widget = self.valueItems[child]
|
|
|
|
widget.clear()
|
|
|
|
widget.addItems(self.getFields(layer, self.alg.getParameterFromName(child).datatype))
|
|
|
|
|
|
|
|
def getFields(self, layer, datatype):
|
|
|
|
fieldTypes = []
|
|
|
|
if datatype == ParameterTableField.DATA_TYPE_STRING:
|
|
|
|
fieldTypes = [QtCore.QVariant.String]
|
|
|
|
elif datatype == ParameterTableField.DATA_TYPE_NUMBER:
|
|
|
|
fieldTypes = [QtCore.QVariant.Int, QtCore.QVariant.Double]
|
|
|
|
|
|
|
|
fieldNames = []
|
2013-02-01 13:09:39 +04:00
|
|
|
fields = layer.pendingFields()
|
2012-09-15 18:25:25 +03:00
|
|
|
if len(fieldTypes) == 0:
|
2013-02-01 13:09:39 +04:00
|
|
|
for field in fields:
|
2012-09-15 18:25:25 +03:00
|
|
|
if not field.name() in fieldNames:
|
|
|
|
fieldNames.append( unicode( field.name() ) )
|
|
|
|
else:
|
2013-02-01 13:09:39 +04:00
|
|
|
for field in fields:
|
2012-09-15 18:25:25 +03:00
|
|
|
if field.type() in fieldTypes and not field.name() in fieldNames:
|
|
|
|
fieldNames.append( unicode( field.name() ) )
|
|
|
|
return sorted( fieldNames, cmp=locale.strcoll )
|
|
|
|
|
|
|
|
def somethingDependsOnThisParameter(self, parent):
|
|
|
|
for param in self.alg.parameters:
|
|
|
|
if isinstance(param, ParameterTableField):
|
|
|
|
if param.parent == parent.name:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def setTableContent(self):
|
|
|
|
params = self.alg.parameters
|
|
|
|
outputs = self.alg.outputs
|
|
|
|
numParams = 0
|
|
|
|
for param in params:
|
|
|
|
if not param.hidden:
|
|
|
|
numParams += 1
|
|
|
|
numOutputs = 0
|
|
|
|
for output in outputs:
|
|
|
|
if not output.hidden:
|
|
|
|
numOutputs += 1
|
|
|
|
self.tableWidget.setRowCount(numParams + numOutputs)
|
|
|
|
|
|
|
|
i=0
|
|
|
|
for param in params:
|
|
|
|
if param.hidden:
|
|
|
|
continue
|
|
|
|
item = QtGui.QTableWidgetItem(param.description)
|
|
|
|
item.setFlags(QtCore.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)
|
|
|
|
i+=1
|
|
|
|
|
|
|
|
for output in outputs:
|
|
|
|
if output.hidden:
|
|
|
|
continue
|
|
|
|
item = QtGui.QTableWidgetItem(output.description + "<" + output.__module__.split(".")[-1] + ">")
|
|
|
|
item.setFlags(QtCore.Qt.ItemIsEnabled)
|
|
|
|
self.tableWidget.setItem(i,0, item)
|
|
|
|
item = OutputSelectionPanel(output,self.alg)
|
|
|
|
self.valueItems[output.name] = item
|
|
|
|
self.tableWidget.setCellWidget(i,1, item)
|
|
|
|
self.tableWidget.setRowHeight(i,22)
|
|
|
|
i+=1
|