[processing] fixed problems when opening/removing layers while alg dialog is open

This commit is contained in:
volaya 2016-01-18 14:16:31 +01:00
parent e0f1137059
commit 4c34871f0a
5 changed files with 110 additions and 20 deletions

View File

@ -25,7 +25,7 @@ __copyright__ = '(C) 2015, Victor Olaya'
__revision__ = '$Format:%H$'
from qgis.core import *
from PyQt4.QtGui import *
from processing.gui.AlgorithmDialog import AlgorithmDialog
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
@ -55,6 +55,8 @@ class GdalAlgorithmDialog(AlgorithmDialog):
self.mainWidget.parametersHaveChanged()
QgsMapLayerRegistry.instance().layerWasAdded.connect(self.mainWidget.layerAdded)
QgsMapLayerRegistry.instance().layersWillBeRemoved.connect(self.mainWidget.layersWillBeRemoved)
class GdalParametersPanel(ParametersPanel):

View File

@ -29,6 +29,8 @@ from PyQt4.QtCore import Qt
from PyQt4.QtGui import QMessageBox, QApplication, QCursor, QColor, QPalette, QPushButton, QWidget,\
QVBoxLayout
from qgis.core import *
from processing.core.ProcessingLog import ProcessingLog
from processing.core.ProcessingConfig import ProcessingConfig
@ -81,6 +83,10 @@ class AlgorithmDialog(AlgorithmDialogBase):
cornerWidget.setLayout(layout)
self.tabWidget.setCornerWidget(cornerWidget)
QgsMapLayerRegistry.instance().layerWasAdded.connect(self.mainWidget.layerAdded)
QgsMapLayerRegistry.instance().layersWillBeRemoved.connect(self.mainWidget.layersWillBeRemoved)
def runAsBatch(self):
dlg = BatchAlgorithmDialog(self.alg)
dlg.show()
@ -256,3 +262,8 @@ class AlgorithmDialog(AlgorithmDialogBase):
self.setInfo(
self.tr('HTML output has been generated by this algorithm.'
'\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)
super(AlgorithmDialog, self).closeEvent(evt)

View File

@ -73,3 +73,16 @@ class MultipleInputPanel(BASE, WIDGET):
self.leText.setText(
self.tr('%d elements selected') % len(self.selectedoptions))
self.selectionChanged.emit()
def updateForOptions(self, options):
selectedoptions = []
selected = [self.options[i] for i in self.selectedoptions]
for sel in selected:
try:
idx = options.index(sel)
selectedoptions.append(idx)
except ValueError:
pass
self.options = options
self.setSelectedItems(selectedoptions)

View File

@ -10,8 +10,7 @@
Email : volayaf at gmail dot com
otb at c-s dot fr (CS SI)
Contributors : Victor Olaya
Alexia Mondot (CS SI) - managing the new parameter
ParameterMultipleExternalInput
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
@ -33,6 +32,8 @@ __revision__ = '$Format:%H$'
import os
import locale
from qgis.core import *
from PyQt4 import uic
from PyQt4.QtCore import QCoreApplication, QVariant
from PyQt4.QtGui import QWidget, QLayout, QVBoxLayout, QHBoxLayout, QToolButton, QIcon, QLabel, QCheckBox, QComboBox, QLineEdit, QPlainTextEdit
@ -102,6 +103,70 @@ 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.shapetype):
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 != ParameterMultipleInput.TYPE_FILE:
if param.datatype == ParameterMultipleInput.TYPE_RASTER:
options = dataobjects.getRasterLayers(sorting=False)
elif param.datatype == ParameterMultipleInput.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 initWidgets(self):
#tooltips = self.alg.getParameterDescriptions()
@ -304,9 +369,7 @@ class ParametersPanel(BASE, WIDGET):
options = dataobjects.getVectorLayers(sorting=False)
else:
options = dataobjects.getVectorLayers([param.datatype], sorting=False)
opts = []
for opt in options:
opts.append(self.getExtendedLayerName(opt))
opts = [self.getExtendedLayerName(opt) for opt in options]
item = MultipleInputPanel(opts)
elif isinstance(param, ParameterNumber):
item = NumberInputPanel(param.default, param.min, param.max,

View File

@ -74,13 +74,7 @@ def getSupportedOutputTableExtensions():
def getRasterLayers(sorting=True):
layers = QgsProject.instance().layerTreeRoot().findLayers()
raster = []
for layer in layers:
mapLayer = layer.layer()
if mapLayer.type() == QgsMapLayer.RasterLayer:
if mapLayer.providerType() == 'gdal': # only gdal file-based layers
raster.append(mapLayer)
raster = [lay.layer() for lay in layers if lay.layer() is not None and canUseRasterLayer(lay.layer())]
if sorting:
return sorted(raster, key=lambda layer: layer.name().lower())
else:
@ -89,18 +83,25 @@ def getRasterLayers(sorting=True):
def getVectorLayers(shapetype=[-1], sorting=True):
layers = QgsProject.instance().layerTreeRoot().findLayers()
vector = []
for layer in layers:
mapLayer = layer.layer()
if mapLayer.type() == QgsMapLayer.VectorLayer and mapLayer.dataProvider().name() != "grass":
if (mapLayer.hasGeometryType() and
(shapetype == ALL_TYPES or mapLayer.geometryType() in shapetype)):
vector.append(mapLayer)
vector = [lay.layer() for lay in layers if canUseVectorLayer(lay.layer(), shapetype)]
if sorting:
return sorted(vector, key=lambda layer: layer.name().lower())
else:
return vector
def canUseVectorLayer(layer, shapetype):
if layer.type() == QgsMapLayer.VectorLayer and layer.dataProvider().name() != "grass":
if (layer.hasGeometryType() and
(shapetype == ALL_TYPES or layer.geometryType() in shapetype)):
return True
return False
def canUseRasterLayer(layer):
if layer.type() == QgsMapLayer.RasterLayer:
if layer.providerType() == 'gdal': # only gdal file-based layers
return True
return False
def getAllLayers():
layers = []