Skip to content

Commit c59c405

Browse files
committed
oweditdomain: Indicate items with warnings with a yellow color
Hide/show warning on change
1 parent 09df730 commit c59c405

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

Orange/widgets/data/oweditdomain.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,9 @@ def variable_icon(var):
15771577
#: (`List[Union[ReinterpretTransform, Transform]]`)
15781578
TransformRole = Qt.UserRole + 42
15791579

1580+
#: Any warnings applying to the transform (`list[tuple[Msg, str]]`)
1581+
RestoreWarningRole = TransformRole + 1
1582+
15801583

15811584
class VariableEditDelegate(QStyledItemDelegate):
15821585
ReinterpretNames = {
@@ -1624,9 +1627,16 @@ def initStyleOption(self, option, index):
16241627
option.font.setItalic(True)
16251628

16261629
multiplicity = index.data(MultiplicityRole)
1630+
warnings = index.data(RestoreWarningRole)
1631+
1632+
def set_color(palette: QPalette, color):
1633+
palette.setBrush(QPalette.Text, QBrush(color))
1634+
palette.setBrush(QPalette.HighlightedText, QBrush(color))
1635+
16271636
if isinstance(multiplicity, int) and multiplicity > 1:
1628-
option.palette.setBrush(QPalette.Text, QBrush(Qt.red))
1629-
option.palette.setBrush(QPalette.HighlightedText, QBrush(Qt.red))
1637+
set_color(option.palette, Qt.red)
1638+
elif warnings:
1639+
set_color(option.palette, Qt.yellow)
16301640

16311641
def helpEvent(self, event: QHelpEvent, view: QAbstractItemView,
16321642
option: QStyleOptionViewItem, index: QModelIndex) -> bool:
@@ -2123,6 +2133,7 @@ def reset_selected(self):
21232133
modified = []
21242134
for ind in self.selected_var_indices():
21252135
midx = model.index(ind)
2136+
model.setData(midx, None, RestoreWarningRole)
21262137
if midx.data(TransformRole):
21272138
model.setData(midx, [], TransformRole)
21282139
var = midx.data(Qt.EditRole)
@@ -2133,6 +2144,7 @@ def reset_selected(self):
21332144
self._on_variable_changed):
21342145
self._editor.set_data(modified)
21352146
self._invalidate()
2147+
self._update_restore_warnings()
21362148

21372149
def reset_all(self):
21382150
"""Reset all variables to their original state."""
@@ -2141,8 +2153,10 @@ def reset_all(self):
21412153
for i in range(model.rowCount()):
21422154
midx = model.index(i)
21432155
model.setData(midx, [], TransformRole)
2156+
model.setData(midx, None, RestoreWarningRole)
21442157
self.open_editor()
21452158
self._invalidate()
2159+
self._update_restore_warnings()
21462160

21472161
def selected_var_indices(self):
21482162
"""Return the current selected variable indices."""
@@ -2199,7 +2213,6 @@ def _restore(self):
21992213
model = self.variables_model
22002214
hints = self._domain_change_hints
22012215
first_key = None
2202-
msgs = []
22032216
for i in range(model.rowCount()):
22042217
midx = model.index(i, 0)
22052218
coldesc = model.data(midx, Qt.EditRole) # type: DataVector
@@ -2208,9 +2221,9 @@ def _restore(self):
22082221
key, tr = res
22092222
if tr:
22102223
self._store_transform(coldesc.vtype, tr, key)
2211-
tr, msgs_ = self._sanitize_transform(coldesc.vtype, tr)
2224+
tr, msgs = self._sanitize_transform(coldesc.vtype, tr)
22122225
model.setData(midx, tr, TransformRole)
2213-
msgs.extend(msgs_)
2226+
model.setData(midx, msgs, RestoreWarningRole)
22142227
if first_key is None:
22152228
first_key = key
22162229
# Reduce the number of hints to MAX_HINTS, but keep all current hints
@@ -2219,9 +2232,7 @@ def _restore(self):
22192232
(key := next(iter(hints))) != first_key:
22202233
del hints[key] # pylint: disable=unsupported-delete-operation
22212234

2222-
# Show warnings for non-applicable transforms
2223-
for msg, names in groupby(msgs, key=itemgetter(0)):
2224-
msg(", ".join(map(itemgetter(1), names)))
2235+
self._update_restore_warnings()
22252236

22262237
# Restore the current variable selection
22272238
selected_rows = [i for i, vec in enumerate(model)
@@ -2230,6 +2241,19 @@ def _restore(self):
22302241
selected_rows = [0]
22312242
itemmodels.select_rows(self.variables_view, selected_rows)
22322243

2244+
def _update_restore_warnings(self):
2245+
def messages(midx):
2246+
msgs = model.data(midx, RestoreWarningRole)
2247+
return msgs or []
2248+
model = self.variables_model
2249+
msgs = chain.from_iterable(
2250+
messages(model.index(i)) for i in range(model.rowCount())
2251+
)
2252+
self.Warning.cat_mapping_does_not_apply.clear()
2253+
# Show warnings for non-applicable transforms
2254+
for msg, names in groupby(msgs, key=itemgetter(0)):
2255+
msg(", ".join(map(itemgetter(1), names)))
2256+
22332257
def _on_selection_changed(self, _, deselected):
22342258
# If the user deselected the last item, select it back with disabled
22352259
# signals, so nothing happens
@@ -2278,8 +2302,10 @@ def _on_variable_changed(self):
22782302
*editor.get_data()):
22792303
midx = model.index(idx, 0)
22802304
model.setData(midx, transform, TransformRole)
2305+
model.setData(midx, None, RestoreWarningRole)
22812306
self._store_transform(var, transform)
22822307
self._invalidate()
2308+
self._update_restore_warnings()
22832309

22842310
def _store_transform(
22852311
self, var: Variable, transform: Iterable[Transform], deconvar=None

Orange/widgets/data/tests/test_oweditdomain.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from Orange.widgets.data.owcolor import OWColor, ColorRole
4141
from Orange.widgets.tests.base import WidgetTest, GuiTest
4242
from Orange.widgets.tests.utils import contextMenu
43+
from Orange.widgets.utils.itemmodels import select_row
4344
from Orange.widgets.utils import colorpalettes
4445
from Orange.tests import test_filename, assert_array_nanequal
4546

@@ -382,6 +383,10 @@ def restore(state):
382383
self.assertEqual(output.domain.class_var.values,
383384
("Iris-setosa", "Iris-versicolor", "Iris-virginica"))
384385

386+
select_row(w.variables_view, 4)
387+
w.reset_selected()
388+
self.assertFalse(w.Warning.cat_mapping_does_not_apply.is_shown())
389+
385390
restore({viris: [("Rename", ("A")), ("NonexistantTransform", ("AA",))]})
386391
tr = model.data(model.index(4), TransformRole)
387392
self.assertEqual(tr, [Rename("A")])

Orange/widgets/utils/itemmodels.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
__all__ = [
3838
"PyListModel", "VariableListModel", "PyListModelTooltip", "DomainModel",
3939
"AbstractSortTableModel", "PyTableModel", "TableModel",
40-
"ModelActionsWidget", "ListSingleSelectionModel"
40+
"ModelActionsWidget", "ListSingleSelectionModel",
41+
"select_row", "select_rows", "signal_blocking"
4142
]
4243

44+
4345
@contextmanager
4446
def signal_blocking(obj):
4547
blocked = obj.signalsBlocked()

0 commit comments

Comments
 (0)