2828from Orange .classification import SimpleTreeLearner
2929
3030
31+ DisplayMethodRole = Qt .UserRole
32+ StateRole = DisplayMethodRole + 0xf4
33+
34+
3135class 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
597633def main (argv = None ):
598634 from AnyQt .QtWidgets import QApplication
0 commit comments