Repository: biolab/orange3

Issue:
Data table: Select full rows results in an error
<!-- 
Thanks for taking the time to report a bug!
If you're raising an issue about an add-on (i.e., installed via Options > Add-ons), raise an issue in the relevant add-on's issue tracker instead. See: https://github.com/biolab?q=orange3
To fix the bug, we need to be able to reproduce it. Please answer the following questions to the best of your ability.
-->


**What's wrong?**
<!-- Be specific, clear, and concise. Include screenshots if relevant. -->
<!-- If you're getting an error message, copy it, and enclose it with three backticks (```). -->
On `Data Table` widget, clicking upon `Select full rows` results in an error:
```
Traceback (most recent call last):
  File "/Users/vesna/orange-widget-base/orangewidget/gui.py", line 1971, in __call__
    self.func(**kwds)
  File "/Users/vesna/orange3/Orange/widgets/data/owtable.py", line 622, in _on_select_rows_changed
    for slot in self._inputs.values():
AttributeError: 'list' object has no attribute 'values'
```

**How can we reproduce the problem?** 
<!-- Upload a zip with the .ows file and data. -->
<!-- Describe the steps (open this widget, click there, then add this...) -->
File -> Data Table (Click Select full rows in control area)


**What's your environment?**
<!-- To find your Orange version, see "Help → About → Version" or `Orange.version.full_version` in code -->
- Operating system: macOS Catalina
- Orange version: master
- How you installed Orange: pip



Discussion:
Thanks! Looks like a regression of #4860 

Resolving patch:
diff --git a/Orange/widgets/data/owtable.py b/Orange/widgets/data/owtable.py
--- a/Orange/widgets/data/owtable.py
+++ b/Orange/widgets/data/owtable.py
@@ -593,7 +593,7 @@ def _update_variable_labels(self, view):
 
     def _on_show_variable_labels_changed(self):
         """The variable labels (var.attribues) visibility was changed."""
-        for slot in self._inputs.values():
+        for slot in self._inputs:
             self._update_variable_labels(slot.view)
 
     def _on_distribution_color_changed(self):
@@ -619,7 +619,7 @@ def _on_distribution_color_changed(self):
             tab.reset()
 
     def _on_select_rows_changed(self):
-        for slot in self._inputs.values():
+        for slot in self._inputs:
             selection_model = slot.view.selectionModel()
             selection_model.setSelectBlocks(not self.select_rows)
             if self.select_rows:


Test patch:
diff --git a/Orange/widgets/data/tests/test_owtable.py b/Orange/widgets/data/tests/test_owtable.py
--- a/Orange/widgets/data/tests/test_owtable.py
+++ b/Orange/widgets/data/tests/test_owtable.py
@@ -60,7 +60,7 @@ def test_reset_select(self):
 
     def _select_data(self):
         self.widget.selected_cols = list(range(len(self.data.domain.variables)))
-        self.widget.selected_rows = list(range(0, len(self.data.domain.variables), 10))
+        self.widget.selected_rows = list(range(0, len(self.data), 10))
         self.widget.set_selection()
         return self.widget.selected_rows
 
@@ -168,6 +168,34 @@ def test_show_distributions(self):
             w.grab()
         w.controls.show_distributions.toggle()
 
+    def test_whole_rows(self):
+        w = self.widget
+        self.send_signal(w.Inputs.data, self.data, 0)
+        self.assertTrue(w.select_rows)  # default value
+        with excepthook_catch():
+            w.controls.select_rows.toggle()
+        self.assertFalse(w.select_rows)
+        w.selected_cols = [0, 1]
+        w.selected_rows = [0, 1, 2, 3]
+        w.set_selection()
+        out = self.get_output(w.Outputs.selected_data)
+        self.assertEqual(out.domain,
+                         Domain([self.data.domain.attributes[0]], self.data.domain.class_var))
+        with excepthook_catch():
+            w.controls.select_rows.toggle()
+        out = self.get_output(w.Outputs.selected_data)
+        self.assertTrue(w.select_rows)
+        self.assertEqual(out.domain,
+                         self.data.domain)
+
+    def test_show_attribute_labels(self):
+        w = self.widget
+        self.send_signal(w.Inputs.data, self.data, 0)
+        self.assertTrue(w.show_attribute_labels)  # default value
+        with excepthook_catch():
+            w.controls.show_attribute_labels.toggle()
+        self.assertFalse(w.show_attribute_labels)
+
 
 if __name__ == "__main__":
     unittest.main()