Skip to content

Commit f8591bd

Browse files
committed
owimpute: Store state in the model
1 parent 4f1a91f commit f8591bd

File tree

1 file changed

+56
-20
lines changed

1 file changed

+56
-20
lines changed

Orange/widgets/data/owimpute.py

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@
2828
from Orange.classification import SimpleTreeLearner
2929

3030

31+
DisplayMethodRole = Qt.UserRole
32+
StateRole = DisplayMethodRole + 0xf4
33+
34+
3135
class DisplayFormatDelegate(QStyledItemDelegate):
3236
def initStyleOption(self, option, index):
3337
super().initStyleOption(option, index)
34-
method = index.data(Qt.UserRole)
38+
method = index.data(DisplayMethodRole)
3539
var = index.model()[index.row()]
3640
if method:
3741
option.text = method.format_variable(var)
@@ -140,7 +144,8 @@ class Error(OWWidget.Error):
140144
settingsHandler = settings.DomainContextHandler()
141145

142146
_default_method_index = settings.Setting(int(Method.Leave)) # type: int
143-
variable_state = settings.ContextSetting({}) # type: VariableState
147+
# Per-variable imputation state (synced in storeSpecificSettings)
148+
_variable_imputation_state = settings.ContextSetting({}) # type: VariableState
144149

145150
autocommit = settings.Setting(True)
146151

@@ -281,13 +286,15 @@ def set_default_method(self, index):
281286
def set_data(self, data):
282287
self.closeContext()
283288
self.varmodel[:] = []
284-
self.variable_state = {} # type: VariableState
289+
self._variable_imputation_state = {} # type: VariableState
285290
self.modified = False
286291
self.data = data
287292

288293
if data is not None:
289294
self.varmodel[:] = data.domain.variables
290295
self.openContext(data.domain)
296+
# restore per variable imputation state
297+
self._restore_state(self._variable_imputation_state)
291298

292299
self.update_varview()
293300
self.unconditional_commit()
@@ -314,10 +321,9 @@ def get_method_for_column(self, column_index):
314321
Return the imputation method for column by its index.
315322
"""
316323
assert 0 <= column_index < len(self.varmodel)
317-
var = self.varmodel[column_index] # type: Orange.data.Variable
318-
try:
319-
state = self.variable_state[var_key(var)]
320-
except KeyError:
324+
idx = self.varmodel.index(column_index, 0)
325+
state = idx.data(StateRole)
326+
if state is None:
321327
state = (Method.AsAboveSoBelow, ())
322328
return self.create_imputer(state[0], *state[1])
323329

@@ -478,8 +484,8 @@ def send_report(self):
478484
def _on_var_selection_changed(self):
479485
indexes = self.selection.selectedIndexes()
480486
defmethod = (Method.AsAboveSoBelow, ())
481-
methods = [self.variable_state.get(var_key(var), defmethod)
482-
for var in variables]
487+
methods = [index.data(StateRole) for index in indexes]
488+
methods = [m if m is not None else defmethod for m in methods]
483489
methods = set(methods)
484490
selected_vars = [self.varmodel[index.row()] for index in indexes]
485491
has_discrete = any(var.is_discrete for var in selected_vars)
@@ -494,7 +500,7 @@ def _on_var_selection_changed(self):
494500
self.variable_button_group.button(m).setChecked(True)
495501

496502
if method_type == Method.Default:
497-
(fixed_value, ) = parameters
503+
(fixed_value,) = parameters
498504

499505
elif self.variable_button_group.checkedButton() is not None:
500506
# Uncheck the current button
@@ -550,9 +556,7 @@ def set_method_for_indexes(self, indexes, method_index):
550556
# type: (List[QModelIndex], Method) -> None
551557
if method_index == Method.AsAboveSoBelow:
552558
for index in indexes:
553-
var = self.varmodel[index.row()]
554-
assert isinstance(var, Orange.data.Variable)
555-
self.variable_state.pop(var_key(var), None)
559+
self.varmodel.setData(index, None, StateRole)
556560
elif method_index == Method.Default:
557561
current = self.value_stack.currentWidget()
558562
if current is self.value_combo:
@@ -561,15 +565,11 @@ def set_method_for_indexes(self, indexes, method_index):
561565
value = self.value_double.value()
562566
for index in indexes:
563567
state = (int(Method.Default), (value,))
564-
var = self.varmodel[index.row()]
565-
assert isinstance(var, Orange.data.Variable)
566-
self.variable_state[var_key(var)] = state
568+
self.varmodel.setData(index, state, StateRole)
567569
else:
568570
state = (int(method_index), ())
569571
for index in indexes:
570-
var = self.varmodel[index.row()]
571-
assert isinstance(var, Orange.data.Variable)
572-
self.variable_state[var_key(var)] = state
572+
self.varmodel.setData(index, state, StateRole)
573573

574574
self.update_varview(indexes)
575575
self._invalidate()
@@ -581,7 +581,7 @@ def update_varview(self, indexes=None):
581581
for index in indexes:
582582
self.varmodel.setData(
583583
index, self.get_method_for_column(index.row()),
584-
Qt.UserRole)
584+
DisplayMethodRole)
585585

586586
def _on_value_selected(self):
587587
# The fixed 'Value' in the widget has been changed by the user.
@@ -593,6 +593,42 @@ def reset_variable_state(self):
593593
self.set_method_for_indexes(indexes, Method.AsAboveSoBelow)
594594
self.variable_button_group.button(Method.AsAboveSoBelow).setChecked(True)
595595

596+
def _store_state(self):
597+
# type: () -> VariableState
598+
"""
599+
Save the current variable imputation state
600+
"""
601+
state = {} # type: VariableState
602+
for i, var in enumerate(self.varmodel):
603+
index = self.varmodel.index(i)
604+
m = index.data(StateRole)
605+
if m is not None:
606+
state[var_key(var)] = m
607+
return state
608+
609+
def _restore_state(self, state):
610+
# type: (VariableState) -> None
611+
"""
612+
Restore the variable imputation state from the saved state
613+
"""
614+
def check(state):
615+
# check if state is a proper State
616+
if isinstance(state, tuple) and len(state) == 2:
617+
m, p = state
618+
if isinstance(m, int) and isinstance(p, tuple) and \
619+
0 <= m < len(Method):
620+
return True
621+
return False
622+
623+
for i, var in enumerate(self.varmodel):
624+
m = state.get(var_key(var), None)
625+
if check(m):
626+
self.varmodel.setData(self.varmodel.index(i), m, StateRole)
627+
628+
def storeSpecificSettings(self):
629+
self._variable_imputation_state = self._store_state()
630+
super().storeSpecificSettings()
631+
596632

597633
def main(argv=None):
598634
from AnyQt.QtWidgets import QApplication

0 commit comments

Comments
 (0)