88
99import datetime
1010from enum import IntEnum
11+ from itertools import chain
1112from typing import Any , Optional , Tuple , List
1213
1314import numpy as np
2425 ContinuousVariable , TimeVariable , Domain , Variable
2526from Orange .widgets import widget , gui
2627from Orange .widgets .data .utils .histogram import Histogram
27- from Orange .widgets .settings import ContextSetting , DomainContextHandler
28+ from Orange .widgets .settings import Setting , ContextSetting , \
29+ DomainContextHandler
2830from Orange .widgets .utils .itemmodels import DomainModel , AbstractSortTableModel
2931from Orange .widgets .utils .signals import Input , Output
3032from Orange .widgets .utils .widgetpreview import WidgetPreview
@@ -685,13 +687,14 @@ class Outputs:
685687 buttons_area_orientation = Qt .Vertical
686688
687689 settingsHandler = DomainContextHandler ()
690+ settings_version = 2
688691
689- auto_commit = ContextSetting (True )
692+ auto_commit = Setting (True )
690693 color_var = ContextSetting (None ) # type: Optional[Variable]
691694 # filter_string = ContextSetting('')
692695
693- sorting = ContextSetting ((0 , Qt .DescendingOrder ))
694- selected_rows = ContextSetting ([])
696+ sorting = Setting ((0 , Qt .DescendingOrder ))
697+ selected_vars = ContextSetting ([], schema_only = True )
695698
696699 def __init__ (self ):
697700 super ().__init__ ()
@@ -753,7 +756,7 @@ def _filter_table_variables(self):
753756 def set_data (self , data ):
754757 # Clear outputs and reset widget state
755758 self .closeContext ()
756- self .selected_rows = []
759+ self .selected_vars = []
757760 self .model .resetSorting ()
758761 self .Outputs .reduced_data .send (None )
759762 self .Outputs .statistics .send (None )
@@ -786,10 +789,10 @@ def __restore_selection(self):
786789 """Restore the selection on the table view from saved settings."""
787790 selection_model = self .table_view .selectionModel ()
788791 selection = QItemSelection ()
789- # self.selected_rows can be list or numpy.array, thus
790- # pylint: disable=len-as-condition
791- if len ( self .selected_rows ):
792- for row in self .model .mapFromSourceRows (self . selected_rows ):
792+ if self .selected_vars :
793+ var_indices = { var : i for i , var in enumerate ( self . model . variables )}
794+ selected_indices = [ var_indices [ var ] for var in self .selected_vars ]
795+ for row in self .model .mapFromSourceRows (selected_indices ):
793796 selection .append (QItemSelectionRange (
794797 self .model .index (row , 0 ),
795798 self .model .index (row , self .model .columnCount () - 1 )
@@ -816,22 +819,21 @@ def __color_var_changed(self, *_):
816819 self .model .set_target_var (self .color_var )
817820
818821 def on_select (self ):
819- self . selected_rows = list (self .model .mapToSourceRows ([
822+ selection_indices = list (self .model .mapToSourceRows ([
820823 i .row () for i in self .table_view .selectionModel ().selectedRows ()
821824 ]))
825+ self .selected_vars = list (self .model .variables [selection_indices ])
822826 self .commit ()
823827
824828 def commit (self ):
825- # self.selected_rows can be list or numpy.array, thus
826- # pylint: disable=len-as-condition
827- if not len (self .selected_rows ):
829+ if not self .selected_vars :
828830 self .info .set_output_summary (self .info .NoOutput )
829831 self .Outputs .reduced_data .send (None )
830832 self .Outputs .statistics .send (None )
831833 return
832834
833835 # Send a table with only selected columns to output
834- variables = self .model . variables [ self . selected_rows ]
836+ variables = self .selected_vars
835837 self .info .set_output_summary (len (self .data [:, variables ]),
836838 format_summary_details (self .data [:, variables ]))
837839 self .Outputs .reduced_data .send (self .data [:, variables ])
@@ -850,6 +852,26 @@ def commit(self):
850852 def send_report (self ):
851853 pass
852854
855+ @classmethod
856+ def migrate_context (cls , context , version ):
857+ if not version or version < 2 :
858+ selected_rows = context .values .pop ("selected_rows" , None )
859+ if not selected_rows :
860+ selected_vars = []
861+ else :
862+ # This assumes that dict was saved by Python >= 3.6 so dict is
863+ # ordered; if not, context hasn't had worked anyway.
864+ all_vars = [
865+ (var , tpe )
866+ for (var , tpe ) in chain (context .attributes .items (),
867+ context .metas .items ())
868+ # it would be nicer to use cls.HIDDEN_VAR_TYPES, but there
869+ # is no suitable conversion function, and StringVariable (3)
870+ # was the only hidden var when settings_version < 2, so:
871+ if tpe != 3 ]
872+ selected_vars = [all_vars [i ] for i in selected_rows ]
873+ context .values ["selected_vars" ] = selected_vars , - 3
874+
853875
854876if __name__ == '__main__' : # pragma: no cover
855877 WidgetPreview (OWFeatureStatistics ).run (Table ("iris" ))
0 commit comments