Skip to content

Commit 54124bd

Browse files
committedJun 13, 2017
Restore batch algorithm mode following new processing API
1 parent 020537a commit 54124bd

File tree

5 files changed

+130
-98
lines changed

5 files changed

+130
-98
lines changed
 

‎python/plugins/processing/gui/AutofillDialog.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ class AutofillDialog(BASE, WIDGET):
4444
def __init__(self, alg):
4545
super(AutofillDialog, self).__init__(None)
4646
self.setupUi(self)
47+
self.mode = None
48+
self.param_index = None
49+
self.alg = alg
4750

4851
self.cmbFillType.currentIndexChanged.connect(self.toggleParameters)
4952

50-
for param in alg.parameterDefinitions():
53+
for param in self.alg.parameterDefinitions():
5154
self.cmbParameters.addItem(param.description())
5255

5356
def toggleParameters(self, index):
@@ -60,10 +63,10 @@ def toggleParameters(self, index):
6063

6164
def accept(self):
6265
self.mode = self.cmbFillType.currentIndex()
63-
self.param = self.cmbParameters.currentIndex()
66+
self.param_index = self.cmbParameters.currentIndex()
6467
QDialog.accept(self)
6568

6669
def reject(self):
6770
self.mode = None
68-
self.param = None
71+
self.param_index = None
6972
QDialog.reject(self)

‎python/plugins/processing/gui/BatchAlgorithmDialog.py

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,29 @@
2626

2727
__revision__ = '$Format:%H$'
2828

29+
from pprint import pformat
30+
import time
31+
2932
from qgis.PyQt.QtWidgets import QApplication, QMessageBox, QSizePolicy
3033
from qgis.PyQt.QtGui import QCursor
3134
from qgis.PyQt.QtCore import Qt
3235

33-
from qgis.core import QgsProcessingParameterDefinition
36+
from qgis.core import (QgsProcessingParameterDefinition,
37+
QgsProcessingParameterRasterOutput,
38+
QgsProcessingParameterFeatureSink,
39+
QgsProcessingOutputLayerDefinition,
40+
QgsProcessingOutputHtml,
41+
QgsProcessingOutputNumber,
42+
QgsProject)
43+
3444
from qgis.gui import QgsMessageBar
3545

3646
from processing.gui.BatchPanel import BatchPanel
3747
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
3848
from processing.gui.AlgorithmExecutor import execute
3949
from processing.gui.Postprocessing import handleAlgorithmResults
4050

41-
from processing.core.ProcessingResults import ProcessingResults
42-
43-
from processing.core.outputs import OutputNumber
44-
from processing.core.outputs import OutputString
45-
from processing.core.outputs import OutputHTML
51+
from processing.core.ProcessingResults import resultsList
4652

4753
from processing.tools.system import getTempFilename
4854
from processing.tools import dataobjects
@@ -56,7 +62,6 @@ def __init__(self, alg):
5662
AlgorithmDialogBase.__init__(self, alg)
5763

5864
self.alg = alg
59-
self.alg_parameters = []
6065

6166
self.setWindowTitle(self.tr('Batch Processing - {0}').format(self.alg.displayName()))
6267

@@ -69,11 +74,11 @@ def __init__(self, alg):
6974
self.layout().insertWidget(0, self.bar)
7075

7176
def accept(self):
72-
self.alg_parameters = []
73-
self.load = []
74-
self.canceled = False
77+
alg_parameters = []
78+
load = []
7579

7680
context = dataobjects.createContext()
81+
feedback = self.createFeedback()
7782

7883
for row in range(self.mainWidget.tblParameters.rowCount()):
7984
col = 0
@@ -87,82 +92,99 @@ def accept(self):
8792
self.bar.pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
8893
param.description(), row + 1),
8994
level=QgsMessageBar.WARNING, duration=5)
90-
self.algs = None
9195
return
9296
col += 1
93-
for out in alg.destinationParameterDefinitions():
97+
count_visible_outputs = 0
98+
for out in self.alg.destinationParameterDefinitions():
9499
if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
95100
continue
96101

102+
count_visible_outputs += 1
97103
widget = self.mainWidget.tblParameters.cellWidget(row, col)
98104
text = widget.getValue()
99-
if text.strip() != '':
100-
out.value = text
105+
if param.checkValueIsAcceptable(text, context):
106+
if isinstance(out, (QgsProcessingParameterRasterOutput,
107+
QgsProcessingParameterFeatureSink)):
108+
# load rasters and sinks on completion
109+
parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, context.project())
110+
else:
111+
parameters[out.name()] = text
101112
col += 1
102113
else:
103114
self.bar.pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
104115
out.description(), row + 1),
105116
level=QgsMessageBar.WARNING, duration=5)
106-
self.algs = None
107117
return
108118

109-
self.alg_parameters.append(parameters)
110-
if self.alg.countVisibleOutputs():
111-
widget = self.mainWidget.tblParameters.cellWidget(row, col)
112-
self.load.append(widget.currentIndex() == 0)
113-
else:
114-
self.load.append(False)
119+
alg_parameters.append(parameters)
115120

116121
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
117122
self.mainWidget.setEnabled(False)
123+
self.buttonCancel.setEnabled(True)
118124

119-
self.progressBar.setMaximum(len(self.algs))
120125
# Make sure the Log tab is visible before executing the algorithm
121126
try:
122127
self.tabWidget.setCurrentIndex(1)
123128
self.repaint()
124129
except:
125130
pass
126131

127-
for count, parameters in enumerate(self.alg_parameters):
128-
self.setText(self.tr('\nProcessing algorithm {0}/{1}...').format(count + 1, len(self.alg_parameters)))
132+
start_time = time.time()
133+
134+
algorithm_results = []
135+
for count, parameters in enumerate(alg_parameters):
136+
if feedback.isCanceled():
137+
break
138+
self.setText(self.tr('\nProcessing algorithm {0}/{1}...').format(count + 1, len(alg_parameters)))
129139
self.setInfo(self.tr('<b>Algorithm {0} starting...</b>').format(self.alg.displayName()), escape_html=False)
130-
ret, results = execute(self.alg, parameters, context, self.feedback)
131-
if ret and not self.canceled:
132-
if self.load[count]:
133-
handleAlgorithmResults(self.alg, context, self.feedback, False)
140+
141+
feedback.pushInfo(self.tr('Input parameters:'))
142+
feedback.pushCommandInfo(pformat(parameters))
143+
feedback.pushInfo('')
144+
145+
alg_start_time = time.time()
146+
ret, results = execute(self.alg, parameters, context, feedback)
147+
if ret:
134148
self.setInfo(self.tr('Algorithm {0} correctly executed...').format(self.alg.displayName()), escape_html=False)
149+
feedback.setProgress(100)
150+
feedback.pushInfo(
151+
self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
152+
feedback.pushInfo(self.tr('Results:'))
153+
feedback.pushCommandInfo(pformat(results))
154+
feedback.pushInfo('')
155+
algorithm_results.append(results)
135156
else:
136-
QApplication.restoreOverrideCursor()
137-
return
157+
break
138158

139-
self.finish()
159+
feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))
140160

141-
def finish(self):
142-
for count, parameters in enumerate(self.alg_parameters):
143-
self.loadHTMLResults(self.alg, count)
161+
handleAlgorithmResults(self.alg, context, feedback, False)
144162

145-
self.createSummaryTable()
163+
self.finish(algorithm_results)
164+
self.buttonCancel.setEnabled(False)
165+
166+
def finish(self, algorithm_results):
167+
for count, results in enumerate(algorithm_results):
168+
self.loadHTMLResults(results, count)
169+
170+
self.createSummaryTable(algorithm_results)
146171
QApplication.restoreOverrideCursor()
147172

148173
self.mainWidget.setEnabled(True)
149174
QMessageBox.information(self, self.tr('Batch processing'),
150175
self.tr('Batch processing completed'))
151176

152-
def loadHTMLResults(self, alg, num):
153-
for out in alg.outputs:
154-
if out.flags() & QgsProcessingParameterDefinition.FlagHidden or not out.open:
155-
continue
156-
157-
if isinstance(out, OutputHTML):
158-
ProcessingResults.addResult(
159-
'{} [{}]'.format(out.description(), num), out.value)
177+
def loadHTMLResults(self, results, num):
178+
for out in self.alg.outputDefinitions():
179+
if isinstance(out, QgsProcessingOutputHtml) and out.name() in results and results[out.name()]:
180+
resultsList.addResult(icon=self.alg.icon(), name='{} [{}]'.format(out.description(), num),
181+
result=results[out.name()])
160182

161-
def createSummaryTable(self):
183+
def createSummaryTable(self, algorithm_results):
162184
createTable = False
163185

164-
for out in self.algs[0].outputs:
165-
if isinstance(out, (OutputNumber, OutputString)):
186+
for out in self.alg.outputDefinitions():
187+
if isinstance(out, (QgsProcessingOutputNumber, QgsProcessingOutputString)):
166188
createTable = True
167189
break
168190

@@ -171,12 +193,12 @@ def createSummaryTable(self):
171193

172194
outputFile = getTempFilename('html')
173195
with codecs.open(outputFile, 'w', encoding='utf-8') as f:
174-
for alg in self.algs:
196+
for res in algorithm_results:
175197
f.write('<hr>\n')
176-
for out in alg.outputs:
177-
if isinstance(out, (OutputNumber, OutputString)):
178-
f.write('<p>{}: {}</p>\n'.format(out.description(), out.value))
198+
for out in self.alg.outputDefinitions():
199+
if isinstance(out, (QgsProcessingOutputNumber, QgsProcessingOutputString)) and out.name() in res:
200+
f.write('<p>{}: {}</p>\n'.format(out.description(), res[out.name()]))
179201
f.write('<hr>\n')
180202

181-
ProcessingResults.addResult(
182-
'{} [summary]'.format(self.algs[0].name), outputFile)
203+
resultsList.addResult(self.alg.icon(),
204+
'{} [summary]'.format(self.alg.name()), outputFile)

‎python/plugins/processing/gui/BatchInputSelectionPanel.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@
3636
from qgis.core import (QgsMapLayer,
3737
QgsSettings,
3838
QgsProject,
39-
QgsProcessingUtils)
39+
QgsProcessingUtils,
40+
QgsProcessingParameterMultipleLayers,
41+
QgsProcessingParameterRasterLayer,
42+
QgsProcessingParameterDefinition,
43+
QgsProcessingParameterTable,
44+
QgsProcessingParameterFeatureSource)
4045

4146
from processing.gui.MultipleInputDialog import MultipleInputDialog
4247

43-
from processing.core.parameters import ParameterMultipleInput
44-
from processing.core.parameters import ParameterRaster
45-
from processing.core.parameters import ParameterVector
46-
from processing.core.parameters import ParameterTable
4748
from processing.gui.ParameterGuiUtils import getFileFilter
4849
from processing.tools import dataobjects
4950

@@ -84,7 +85,7 @@ def _table(self):
8485
def showPopupMenu(self):
8586
popupmenu = QMenu()
8687

87-
if not (isinstance(self.param, ParameterMultipleInput) and
88+
if not (isinstance(self.param, QgsProcessingParameterMultipleLayers) and
8889
self.param.datatype == dataobjects.TYPE_FILE):
8990
selectLayerAction = QAction(
9091
self.tr('Select from open layers'), self.pushButton)
@@ -99,19 +100,22 @@ def showPopupMenu(self):
99100
popupmenu.exec_(QCursor.pos())
100101

101102
def showLayerSelectionDialog(self):
102-
if (isinstance(self.param, ParameterRaster) or
103-
(isinstance(self.param, ParameterMultipleInput) and
104-
self.param.datatype == dataobjects.TYPE_RASTER)):
103+
layers = []
104+
if (isinstance(self.param, QgsProcessingParameterRasterLayer) or
105+
(isinstance(self.param, QgsProcessingParameterMultipleLayers) and
106+
self.param.layerType() == QgsProcessingParameterDefinition.TypeRaster)):
105107
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
106-
elif isinstance(self.param, ParameterTable):
108+
elif isinstance(self.param, QgsProcessingParameterTable):
107109
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
108110
else:
109-
if isinstance(self.param, ParameterVector):
110-
datatype = self.param.datatype
111-
else:
112-
datatype = [self.param.datatype]
113-
if datatype != dataobjects.TYPE_VECTOR_ANY:
114-
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [datatype])
111+
datatypes = [QgsProcessingParameterDefinition.TypeVectorAny]
112+
if isinstance(self.param, QgsProcessingParameterFeatureSource):
113+
datatypes = self.param.dataTypes()
114+
elif isinstance(self.param, QgsProcessingParameterMultipleLayers):
115+
datatypes = [self.param.layerType()]
116+
117+
if QgsProcessingParameterDefinition.TypeVectorAny not in datatypes:
118+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), datatypes)
115119
else:
116120
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
117121

@@ -120,17 +124,17 @@ def showLayerSelectionDialog(self):
120124
if dlg.selectedoptions is not None:
121125
selected = dlg.selectedoptions
122126
if len(selected) == 1:
123-
self.setValue(layers[selected[0]])
127+
self.setValue(layers[selected[0]].id())
124128
else:
125-
if isinstance(self.param, ParameterMultipleInput):
126-
self.text.setText(';'.join(layers[idx].name() for idx in selected))
129+
if isinstance(self.param, QgsProcessingParameterMultipleLayers):
130+
self.text.setText(';'.join(layers[idx].id() for idx in selected))
127131
else:
128132
rowdif = len(selected) - (self._table().rowCount() - self.row)
129133
for i in range(rowdif):
130134
self._panel().addRow()
131135
for i, layeridx in enumerate(selected):
132136
self._table().cellWidget(i + self.row,
133-
self.col).setValue(layers[layeridx])
137+
self.col).setValue(layers[layeridx].id())
134138

135139
def showFileSelectionDialog(self):
136140
settings = QgsSettings()
@@ -156,7 +160,7 @@ def showFileSelectionDialog(self):
156160
self.text.setText(files[0])
157161
self.textEditingFinished()
158162
else:
159-
if isinstance(self.param, ParameterMultipleInput):
163+
if isinstance(self.param, QgsProcessingParameterMultipleLayers):
160164
self.text.setText(';'.join(str(f) for f in files))
161165
else:
162166
rowdif = len(files) - (self._table().rowCount() - self.row)

‎python/plugins/processing/gui/BatchOutputSelectionPanel.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,20 @@
3131
import os
3232
import re
3333

34-
from qgis.core import QgsMapLayer, QgsSettings
34+
from qgis.core import (QgsMapLayer,
35+
QgsSettings,
36+
QgsProcessingParameterFolderOutput,
37+
QgsProcessingParameterRasterLayer,
38+
QgsProcessingParameterFeatureSource,
39+
QgsProcessingParameterTable,
40+
QgsProcessingParameterMultipleLayers,
41+
QgsProcessingParameterBoolean,
42+
QgsProcessingParameterEnum,
43+
QgsProcessingParameterMatrix)
3544
from qgis.PyQt.QtWidgets import QWidget, QPushButton, QLineEdit, QHBoxLayout, QSizePolicy, QFileDialog
3645

3746
from processing.gui.AutofillDialog import AutofillDialog
38-
from processing.core.parameters import ParameterMultipleInput
39-
from processing.core.parameters import ParameterRaster
40-
from processing.core.parameters import ParameterTable
41-
from processing.core.parameters import ParameterVector
42-
from processing.core.parameters import ParameterBoolean
43-
from processing.core.parameters import ParameterSelection
44-
from processing.core.parameters import ParameterFixedTable
45-
from processing.core.outputs import OutputDirectory
47+
from processing.gui.ParameterGuiUtils import getFileFilter
4648

4749

4850
class BatchOutputSelectionPanel(QWidget):
@@ -71,11 +73,11 @@ def __init__(self, output, alg, row, col, panel):
7173
self.setLayout(self.horizontalLayout)
7274

7375
def showSelectionDialog(self):
74-
if isinstance(self.output, OutputDirectory):
76+
if isinstance(self.output, QgsProcessingParameterFolderOutput):
7577
self.selectDirectory()
7678
return
7779

78-
filefilter = self.output.getFileFilter(self.alg)
80+
filefilter = getFileFilter(self.output)
7981
settings = QgsSettings()
8082
if settings.contains('/Processing/LastBatchOutputPath'):
8183
path = str(settings.value('/Processing/LastBatchOutputPath'))
@@ -108,22 +110,23 @@ def showSelectionDialog(self):
108110
n = self.table.rowCount() - self.row
109111
for i in range(n):
110112
widget = self.table.cellWidget(i + self.row,
111-
dlg.param)
112-
param = self.alg.parameters[dlg.param]
113-
if isinstance(param, (ParameterRaster,
114-
ParameterVector, ParameterTable,
115-
ParameterMultipleInput)):
113+
dlg.param_index)
114+
param = self.alg.parameterDefinitions()[dlg.param_index]
115+
if isinstance(param, (QgsProcessingParameterRasterLayer,
116+
QgsProcessingParameterFeatureSource,
117+
QgsProcessingParameterTable,
118+
QgsProcessingParameterMultipleLayers)):
116119
v = widget.value()
117120
if isinstance(v, QgsMapLayer):
118121
s = v.name()
119122
else:
120123
s = os.path.basename(v)
121124
s = os.path.splitext(s)[0]
122-
elif isinstance(param, ParameterBoolean):
125+
elif isinstance(param, QgsProcessingParameterBoolean):
123126
s = str(widget.currentIndex() == 0)
124-
elif isinstance(param, ParameterSelection):
127+
elif isinstance(param, QgsProcessingParameterEnum):
125128
s = str(widget.currentText())
126-
elif isinstance(param, ParameterFixedTable):
129+
elif isinstance(param, QgsProcessingParameterMatrix):
127130
s = str(widget.table)
128131
else:
129132
s = str(widget.text())

‎python/plugins/processing/gui/BatchPanel.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def layerRegistryChanged(self):
9494

9595
def initWidgets(self):
9696
# If there are advanced parameters — show corresponding button
97-
for param in self.alg.parameters:
97+
for param in self.alg.parameterDefinitions():
9898
if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
9999
self.btnAdvanced.show()
100100
break
@@ -129,8 +129,8 @@ def initWidgets(self):
129129
self.tblParameters.setHorizontalHeaderItem(
130130
column, QTableWidgetItem(self.tr('Load in QGIS')))
131131

132-
# Add three empty rows by default
133-
for i in range(3):
132+
# Add two empty rows by default
133+
for i in range(2):
134134
self.addRow()
135135

136136
self.tblParameters.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)

0 commit comments

Comments
 (0)
Please sign in to comment.