|
65 | 65 | QgsProcessingParameterRasterDestination,
|
66 | 66 | QgsProcessingParameterVectorDestination,
|
67 | 67 | QgsProcessingParameterFeatureSink,
|
68 |
| - QgsProcessingOutputLayerDefinition |
| 68 | + QgsProcessingOutputLayerDefinition, |
| 69 | + QgsExpressionContextUtils, |
| 70 | + QgsExpression |
69 | 71 | )
|
70 | 72 | from qgis.gui import (
|
71 | 73 | QgsProcessingParameterWidgetContext,
|
72 | 74 | QgsProcessingContextGenerator,
|
73 |
| - QgsFindFilesByPatternDialog |
| 75 | + QgsFindFilesByPatternDialog, |
| 76 | + QgsExpressionBuilderDialog |
74 | 77 | )
|
75 | 78 | from qgis.utils import iface
|
76 | 79 |
|
@@ -120,12 +123,20 @@ def createMenu(self):
|
120 | 123 | fill_down_action.setToolTip(self.tr('Copy the first value down to all other rows'))
|
121 | 124 | self.menu.addAction(fill_down_action)
|
122 | 125 |
|
| 126 | + calculate_by_expression = QAction(QCoreApplication.translate('BatchPanel', 'Calculate by Expression…'), |
| 127 | + self.menu) |
| 128 | + calculate_by_expression.setIcon(QgsApplication.getThemeIcon('/mActionCalculateField.svg')) |
| 129 | + calculate_by_expression.triggered.connect(self.calculateByExpression) |
| 130 | + calculate_by_expression.setToolTip(self.tr('Calculates parameter values by evaluating an expression')) |
| 131 | + self.menu.addAction(calculate_by_expression) |
| 132 | + |
123 | 133 | if isinstance(self.parameterDefinition, (QgsProcessingParameterFile,
|
124 | 134 | QgsProcessingParameterMapLayer,
|
125 | 135 | QgsProcessingParameterRasterLayer,
|
126 | 136 | QgsProcessingParameterMeshLayer,
|
127 | 137 | QgsProcessingParameterVectorLayer,
|
128 | 138 | QgsProcessingParameterFeatureSource)):
|
| 139 | + self.menu.addSeparator() |
129 | 140 | find_by_pattern_action = QAction(QCoreApplication.translate('BatchPanel', 'Add Files by Pattern…'),
|
130 | 141 | self.menu)
|
131 | 142 | find_by_pattern_action.triggered.connect(self.addFilesByPattern)
|
@@ -177,6 +188,51 @@ def addFilesByPattern(self):
|
177 | 188 | for row, file in enumerate(files):
|
178 | 189 | self.setRowValue(first_row + row, file, context)
|
179 | 190 |
|
| 191 | + def calculateByExpression(self): |
| 192 | + """ |
| 193 | + Calculates parameter values by evaluating expressions. |
| 194 | + """ |
| 195 | + context = dataobjects.createContext() |
| 196 | + expression_context = context.expressionContext() |
| 197 | + |
| 198 | + # use the first row parameter values as a preview during expression creation |
| 199 | + params = self.panel.parametersForRow(0, warnOnInvalid=False) |
| 200 | + alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context) |
| 201 | + |
| 202 | + # create explicit variables corresponding to every parameter |
| 203 | + for k, v in params.items(): |
| 204 | + alg_scope.setVariable(k, v, True) |
| 205 | + |
| 206 | + expression_context.appendScope(alg_scope) |
| 207 | + |
| 208 | + # mark the parameter variables as highlighted for discoverability |
| 209 | + highlighted_vars = expression_context.highlightedVariables() |
| 210 | + highlighted_vars.extend(list(params.keys())) |
| 211 | + expression_context.setHighlightedVariables(highlighted_vars) |
| 212 | + |
| 213 | + dlg = QgsExpressionBuilderDialog(layer=None, context=context.expressionContext()) |
| 214 | + if not dlg.exec_(): |
| 215 | + return |
| 216 | + |
| 217 | + for row in range(self.panel.batchRowCount()): |
| 218 | + params = self.panel.parametersForRow(row, warnOnInvalid=False) |
| 219 | + |
| 220 | + # remove previous algorithm scope -- we need to rebuild this completely, using the |
| 221 | + # other parameter values from the current row |
| 222 | + expression_context.popScope() |
| 223 | + alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context) |
| 224 | + |
| 225 | + for k, v in params.items(): |
| 226 | + alg_scope.setVariable(k, v, True) |
| 227 | + |
| 228 | + expression_context.appendScope(alg_scope) |
| 229 | + |
| 230 | + # rebuild a new expression every time -- we don't want the expression compiler to replace |
| 231 | + # variables with precompiled values |
| 232 | + exp = QgsExpression(dlg.expressionText()) |
| 233 | + value = exp.evaluate(expression_context) |
| 234 | + self.setRowValue(row, value, context) |
| 235 | + |
180 | 236 |
|
181 | 237 | class BatchPanel(BASE, WIDGET):
|
182 | 238 | PARAMETERS = "PARAMETERS"
|
|
0 commit comments