Repository: biolab/orange3

Issue:
Show proper state for disabled check boxes
Many widgets disable check boxes when they are not applicable. For instance, if "Split by" in Distribution is set to None, check boxes Stack columns and Show probabilities are disabled. However, if they are checked they remain checked (so that they are checked when they are re-enabled). The widget itself ignored the state, but the information that the user sees is wrong.

https://github.com/biolab/orange-widget-base/pull/30 in orange-widget-base (merged, but not yet released) resolves this by introducing an argument `stateWhenDisabled`. In case of Distributions, settings `stateWhenDisabled=False` would ensure that check boxes would be shown as unchecked when they are disabled, although the underlying setting is still `True`. When reenabled, the box will be shown as checked.

Somebody would need to go through all widgets, or perhaps just search the code for `setDisabled` and `setEnabled`, see whether it disables check boxes and if so, provide the `stateWhenDisable` argument with the proper value.

This PR won't be mergeable until orange-widget-base is released.


Discussion:

Resolving patch:
diff --git a/Orange/widgets/unsupervised/owdistances.py b/Orange/widgets/unsupervised/owdistances.py
--- a/Orange/widgets/unsupervised/owdistances.py
+++ b/Orange/widgets/unsupervised/owdistances.py
@@ -111,7 +111,8 @@ def __init__(self):
             box, self, "normalized_dist", "Normalized",
             callback=self._invalidate,
             tooltip=("All dimensions are (implicitly) scaled to a common"
-                     "scale to normalize the influence across the domain.")
+                     "scale to normalize the influence across the domain."),
+            stateWhenDisabled=False
         )
         _, metric = METRICS[self.metric_idx]
         self.normalization_check.setEnabled(metric.supports_normalization)
diff --git a/Orange/widgets/utils/plot/owplotgui.py b/Orange/widgets/utils/plot/owplotgui.py
--- a/Orange/widgets/utils/plot/owplotgui.py
+++ b/Orange/widgets/utils/plot/owplotgui.py
@@ -575,14 +575,15 @@ def _get_callback(self, name, master=None):
         else:
             return name
 
-    def _check_box(self, widget, value, label, cb_name):
+    def _check_box(self, widget, value, label, cb_name, stateWhenDisabled=None):
         '''
             Adds a :obj:`.QCheckBox` to ``widget``.
             When the checkbox is toggled, the attribute ``value`` of the plot object is set to
             the checkbox' check state, and the callback ``cb_name`` is called.
         '''
         args = dict(master=self._plot, value=value, label=label,
-                    callback=self._get_callback(cb_name, self._plot))
+                    callback=self._get_callback(cb_name, self._plot),
+                    stateWhenDisabled=stateWhenDisabled)
         if isinstance(widget.layout(), QGridLayout):
             widget = widget.layout()
         if isinstance(widget, QGridLayout):
@@ -627,7 +628,8 @@ def class_density_check_box(self, widget):
         self._master.cb_class_density = \
             self._check_box(widget=widget, value="class_density",
                             label="Show color regions",
-                            cb_name=self._plot.update_density)
+                            cb_name=self._plot.update_density,
+                            stateWhenDisabled=False)
 
     def regression_line_check_box(self, widget):
         self._master.cb_reg_line = \
diff --git a/Orange/widgets/visualize/owboxplot.py b/Orange/widgets/visualize/owboxplot.py
--- a/Orange/widgets/visualize/owboxplot.py
+++ b/Orange/widgets/visualize/owboxplot.py
@@ -252,13 +252,15 @@ def __init__(self):
         self.stretching_box.sizeHint = self.display_box.sizeHint
         gui.checkBox(
             box, self, 'stretched', "Stretch bars",
-            callback=self.display_changed)
+            callback=self.display_changed,
+            stateWhenDisabled=False)
         gui.checkBox(
             box, self, 'show_labels', "Show box labels",
             callback=self.display_changed)
         self.sort_cb = gui.checkBox(
             box, self, 'sort_freqs', "Sort by subgroup frequencies",
-            callback=self.display_changed)
+            callback=self.display_changed,
+            stateWhenDisabled=False)
 
         gui.vBox(self.mainArea, addSpace=True)
         self.box_scene = QGraphicsScene()
@@ -451,9 +453,9 @@ def reset_all_data(self):
         self.update_display_box()
 
     def grouping_changed(self):
-        self.controls.stretched.setDisabled(self.group_var is self.attribute)
         self.apply_attr_sorting()
         self.update_graph()
+        self.controls.stretched.setDisabled(self.group_var is self.attribute)
 
     def select_box_items(self):
         temp_cond = self.conditions.copy()
@@ -463,9 +465,9 @@ def select_box_items(self):
                                 [c.conditions for c in temp_cond])
 
     def attr_changed(self):
-        self.controls.stretched.setDisabled(self.group_var is self.attribute)
         self.apply_group_sorting()
         self.update_graph()
+        self.controls.stretched.setDisabled(self.group_var is self.attribute)
 
     def update_graph(self):
         self.compute_box_data()


Test patch: