diff --git a/emmental/tracklist/__init__.py b/emmental/tracklist/__init__.py index 3552f8f..d04a20f 100644 --- a/emmental/tracklist/__init__.py +++ b/emmental/tracklist/__init__.py @@ -29,8 +29,11 @@ class Card(Gtk.Box): self._trackview = trackview.TrackView(sql, margin_start=6, margin_end=6) self._visible_cols = buttons.VisibleColumns(self._trackview.columns) + self._unselect = Gtk.Button(icon_name="edit-select-none-symbolic", + has_frame=False, sensitive=False) self._top_left.append(self._visible_cols) + self._top_left.append(self._unselect) self._top_box.set_start_widget(self._top_left) self._top_box.set_center_widget(self._filter) @@ -38,12 +41,18 @@ class Card(Gtk.Box): self.append(self._top_box) self.append(self._trackview) + self._trackview.bind_property("have-selected", self._unselect, + "sensitive") self.bind_property("playlist", self._trackview, "playlist") self._filter.connect("search-changed", self.__search_changed) + self._unselect.connect("clicked", self.__clear_selection) self.add_css_class("card") + def __clear_selection(self, unselect: Gtk.Button) -> None: + self._trackview.clear_selected_tracks() + def __search_changed(self, filter: entry.Filter) -> None: self.sql.tracks.filter(filter.get_query()) diff --git a/emmental/tracklist/selection.py b/emmental/tracklist/selection.py index d04a1b6..9d7bf4c 100644 --- a/emmental/tracklist/selection.py +++ b/emmental/tracklist/selection.py @@ -28,4 +28,3 @@ class OSD(Gtk.Overlay): def clear_selection(self, *args) -> None: """Clear the current selection.""" self.selection.unselect_all() - self.__selection_changed(self.selection, 0, 0) diff --git a/icons/scalable/actions/edit-select-none-symbolic.svg b/icons/scalable/actions/edit-select-none-symbolic.svg new file mode 100644 index 0000000..ce4f5e0 --- /dev/null +++ b/icons/scalable/actions/edit-select-none-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/tests/tracklist/test_tracklist.py b/tests/tracklist/test_tracklist.py index 8df7418..5a15298 100644 --- a/tests/tracklist/test_tracklist.py +++ b/tests/tracklist/test_tracklist.py @@ -52,6 +52,25 @@ class TestTracklist(tests.util.TestCase): self.assertEqual(self.tracklist._top_left.get_first_child(), self.tracklist._visible_cols) + def test_unselect(self): + """Test the unselect button.""" + self.assertIsInstance(self.tracklist._unselect, Gtk.Button) + self.assertEqual(self.tracklist._unselect.get_icon_name(), + "edit-select-none-symbolic") + self.assertFalse(self.tracklist._unselect.get_has_frame()) + + self.assertFalse(self.tracklist._unselect.get_sensitive()) + self.tracklist._trackview.have_selected = True + self.assertTrue(self.tracklist._unselect.get_sensitive()) + + with unittest.mock.patch.object(self.tracklist._trackview, + "clear_selected_tracks") as mock_clear: + self.tracklist._unselect.emit("clicked") + mock_clear.assert_called() + + self.assertEqual(self.tracklist._visible_cols.get_next_sibling(), + self.tracklist._unselect) + def test_filter(self): """Test the Tracklist Filter entry.""" self.assertIsInstance(self.tracklist._filter, emmental.entry.Filter)