Skip to content

Commit 1672d43

Browse files
committed
Raster calc: refresh layers list if a layer is renamed or added/removed
Fixes #20601 - bug: Raster calculator produces empty results layer and no error message if input layer is one that has been renamed in QGIS layers panel
1 parent 49da1c3 commit 1672d43

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

python/plugins/processing/algs/qgis/ui/RasterCalculatorWidgets.py

+32-17
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
import re
2929
import json
3030

31+
from qgis.utils import iface
3132
from qgis.PyQt import uic
33+
from qgis.PyQt.QtCore import Qt
3234
from qgis.PyQt.QtGui import QTextCursor
3335
from qgis.PyQt.QtWidgets import (QLineEdit, QPushButton, QLabel,
34-
QComboBox, QSpacerItem, QSizePolicy)
36+
QComboBox, QSpacerItem, QSizePolicy,
37+
QListWidgetItem)
3538

3639
from qgis.core import (QgsProcessingUtils,
3740
QgsProcessingParameterDefinition,
@@ -187,8 +190,20 @@ def fillPredefined(self):
187190
def setList(self, options):
188191
self.options = options
189192
self.listWidget.clear()
190-
for opt in options.keys():
191-
self.listWidget.addItem(opt)
193+
entries = QgsRasterCalculatorEntry.rasterEntries()
194+
195+
def _find_source(name):
196+
for entry in entries:
197+
if entry.ref == name:
198+
return entry.raster.source()
199+
return ''
200+
201+
for name in options.keys():
202+
item = QListWidgetItem(name, self.listWidget)
203+
tooltip = _find_source(name)
204+
if tooltip:
205+
item.setData(Qt.ToolTipRole, tooltip)
206+
self.listWidget.addItem(item)
192207

193208
def setValue(self, value):
194209
self.text.setPlainText(value)
@@ -202,28 +217,28 @@ class ExpressionWidgetWrapper(WidgetWrapper):
202217
def _panel(self, options):
203218
return ExpressionWidget(options)
204219

220+
def _get_options(self):
221+
entries = QgsRasterCalculatorEntry.rasterEntries()
222+
options = {}
223+
for entry in entries:
224+
options[entry.ref] = entry.ref
225+
return options
226+
205227
def createWidget(self):
206228
if self.dialogType == DIALOG_STANDARD:
207-
entries = QgsRasterCalculatorEntry.rasterEntries()
208-
options = {}
209-
for entry in entries:
210-
options[entry.ref] = entry.ref
211-
return self._panel(options)
229+
if iface is not None and iface.layerTreeView() is not None and iface.layerTreeView().layerTreeModel() is not None:
230+
iface.layerTreeView().layerTreeModel().dataChanged.connect(self.refresh)
231+
return self._panel(self._get_options())
212232
elif self.dialogType == DIALOG_BATCH:
213233
return QLineEdit()
214234
else:
215235
layers = self.dialog.getAvailableValuesOfType([QgsProcessingParameterRasterLayer], [QgsProcessingOutputRasterLayer])
216236
options = {self.dialog.resolveValueDescription(lyr): "{}@1".format(self.dialog.resolveValueDescription(lyr)) for lyr in layers}
217-
return self._panel(options)
237+
self.widget = self._panel(options)
238+
return self.widget
218239

219-
def refresh(self):
220-
# TODO: check if avoid code duplication with self.createWidget
221-
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
222-
options = {}
223-
for lyr in layers:
224-
for n in range(lyr.bandCount()):
225-
options[lyr.name()] = '{:s}@{:d}'.format(lyr.name(), n + 1)
226-
self.widget.setList(options)
240+
def refresh(self, *args):
241+
self.widget.setList(self._get_options())
227242

228243
def setValue(self, value):
229244
if self.dialogType == DIALOG_STANDARD:

src/app/qgsrastercalcdialog.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ QVector<QgsRasterCalculatorEntry> QgsRasterCalcDialog::rasterEntries() const
153153
return entries;
154154
}
155155

156+
156157
void QgsRasterCalcDialog::setExtentSize( int width, int height, QgsRectangle bbox )
157158
{
158159
mNColumnsSpinBox->setValue( width );
@@ -168,6 +169,7 @@ void QgsRasterCalcDialog::setExtentSize( int width, int height, QgsRectangle bbo
168169
void QgsRasterCalcDialog::insertAvailableRasterBands()
169170
{
170171
mAvailableRasterBands = QgsRasterCalculatorEntry::rasterEntries().toList();
172+
mRasterBandsListWidget->clear();
171173
for ( const auto &entry : qgis::as_const( mAvailableRasterBands ) )
172174
{
173175
QgsRasterLayer *rlayer = entry.raster;

0 commit comments

Comments
 (0)