Skip to content

Commit

Permalink
settings: Do not clear schema_only settings on close_context
Browse files Browse the repository at this point in the history
* undo changes to settings from gh-2301
* change selection restore in scatter plot and linear projection accordingly
  • Loading branch information
ales-erjavec committed Oct 18, 2017
1 parent ab97e2c commit c4e8017
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 20 deletions.
11 changes: 0 additions & 11 deletions Orange/widgets/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,17 +787,6 @@ def close_context(self, widget):
if widget.current_context is None:
return

# Clear schema-only settings when *closing* the context
# FIXME: Sadly, schema-only settings aren't cleared when non-contextual
# SettingsHandler is used. Example: widget has non-contextual
# SettingsHandler, user loads schema that includes widget, user
# passes new data to widget => widget's schema-only settings still
# have previous values because equivalent of below reset was never
# called (i.e. `close_context()`).
for name, setting in self.known_settings.items():
if setting.schema_only:
setattr(widget, name, setting.default)

self.settings_from_widget(widget)
widget.current_context = None

Expand Down
12 changes: 12 additions & 0 deletions Orange/widgets/tests/test_context_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class SimpleWidget:
settings_version = 1

setting = Setting(42)
schema_only_setting = Setting(None, schema_only=True)

context_setting = ContextSetting(42)

Expand Down Expand Up @@ -181,6 +182,17 @@ def test_write_defaults_stores_version(self):
for c in contexts:
self.assertEqual(c.values.get("__version__", 0xBAD), 1)

def test_close_context(self):
handler = ContextHandler()
handler.bind(SimpleWidget)
widget = SimpleWidget()
widget.storeSpecificSettings = Mock()
handler.initialize(widget)
widget.schema_only_setting = 0xD06F00D
widget.current_context = handler.new_context()
handler.close_context(widget)
self.assertEqual(widget.schema_only_setting, 0xD06F00D)


class TestSettingsPrinter(TestCase):
def test_formats_contexts(self):
Expand Down
10 changes: 8 additions & 2 deletions Orange/widgets/visualize/owlinearprojection.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ def __init__(self):
self.__legend = None
self.__selection_item = None
self.__replot_requested = False
#: Remember the saved state to restore
self.__pending_selection_restore = self.selection_indices
self.selection_indices = None

box = gui.vBox(self.controlArea, "Axes")

Expand Down Expand Up @@ -425,6 +428,7 @@ def sizeHint(self):

def clear(self):
self.data = None
self.selection_indices = None
self._subset_mask = None
self._selection_mask = None
self.varmodel_selected[:] = []
Expand Down Expand Up @@ -515,8 +519,9 @@ def set_data(self, data):
if set(selected_keys).issubset(set(state.keys())):
pass

if self.selection_indices is not None:
self.select_indices(self.selection_indices)
if self.__pending_selection_restore is not None:
self.select_indices(self.__pending_selection_restore)
self.__pending_selection_restore = None

# update the defaults state (the encoded state must contain
# all variables in the input domain)
Expand Down Expand Up @@ -951,6 +956,7 @@ def commit(self):
indices = numpy.flatnonzero(self._selection_mask)
if len(indices) > 0:
subset = self.data[indices]
indices = indices.tolist()

self.selection_indices = indices
self.Outputs.selected_data.send(subset)
Expand Down
17 changes: 12 additions & 5 deletions Orange/widgets/visualize/owscatterplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class Outputs:

attr_x = ContextSetting(None)
attr_y = ContextSetting(None)

#: Serialized selection state to be restored
selection_group = Setting(None, schema_only=True)

graph = SettingProvider(OWScatterPlotGraph)
Expand Down Expand Up @@ -144,6 +146,9 @@ def __init__(self):
self.attribute_selection_list = None # list of Orange.data.Variable
self.__timer = QTimer(self, interval=1200)
self.__timer.timeout.connect(self.add_data)
#: Remember the saved state to restore
self.__pending_selection_restore = self.selection_group
self.selection_group = None

common_options = dict(
labelWidth=50, orientation=Qt.Horizontal, sendSelectedValue=True,
Expand Down Expand Up @@ -335,7 +340,9 @@ def handleNewSignals(self):
self.update_graph()
self.cb_class_density.setEnabled(self.graph.can_draw_density())
self.cb_reg_line.setEnabled(self.graph.can_draw_regresssion_line())
self.apply_selection()
if self.data is not None and self.__pending_selection_restore is not None:
self.apply_selection(self.__pending_selection_restore)
self.__pending_selection_restore = None
self.unconditional_commit()

def prepare_data(self):
Expand Down Expand Up @@ -368,11 +375,11 @@ def sparse_to_dense(self, input_data=None):
dmx.Y = dmx.Y.toarray()
return dmx

def apply_selection(self):
"""Apply selection saved in workflow."""
if self.data is not None and self.selection_group is not None:
def apply_selection(self, selection):
"""Apply `selection` to the current plot."""
if self.data is not None:
self.graph.selection = np.zeros(len(self.data), dtype=np.uint8)
self.selection_group = [x for x in self.selection_group if x[0] < len(self.data)]
self.selection_group = [x for x in selection if x[0] < len(self.data)]
selection_array = np.array(self.selection_group).T
self.graph.selection[selection_array[0]] = selection_array[1]
self.graph.update_colors(keep_colors=True)
Expand Down
10 changes: 8 additions & 2 deletions Orange/widgets/visualize/tests/test_owscatterplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,10 @@ def test_saving_selection(self):

def test_points_selection(self):
# Opening widget with saved selection should restore it
self.widget.selection_group = [(i, 1) for i in range(50)]
self.widget = self.create_widget(
OWScatterPlot, stored_settings={
"selection_group": [(i, 1) for i in range(50)]}
)
self.send_signal(self.widget.Inputs.data, self.data) # iris
selected_data = self.get_output(self.widget.Outputs.selected_data)
self.assertEqual(len(selected_data), 50)
Expand All @@ -253,7 +256,10 @@ def test_migrate_selection(self):
def test_invalid_points_selection(self):
# if selection contains rows that are not present in the current
# dataset, widget should select what can be selected.
self.widget.selection_group = [(i, 1) for i in range(50)]
self.widget = self.create_widget(
OWScatterPlot, stored_settings={
"selection_group": [(i, 1) for i in range(50)]}
)
self.send_signal(self.widget.Inputs.data, self.data[:10])
selected_data = self.get_output(self.widget.Outputs.selected_data)
self.assertEqual(len(selected_data), 10)
Expand Down

0 comments on commit c4e8017

Please sign in to comment.