diff --git a/emmental/db/playlist.py b/emmental/db/playlist.py index 174d480..2dee870 100644 --- a/emmental/db/playlist.py +++ b/emmental/db/playlist.py @@ -69,6 +69,8 @@ class Playlist(table.Row): def add_child(self, child: typing.Self) -> None: """Add a child Playlist to this Playlist.""" self.child_set.add_row(child) + if self.child_set.keyset.n_keys == 1: + self.table.refilter(Gtk.FilterChange.LESS_STRICT) def add_track(self, track: Track, *, idle: bool = False) -> None: """Add a Track to this Playlist.""" @@ -110,6 +112,8 @@ class Playlist(table.Row): def remove_child(self, child: typing.Self) -> None: """Remove a child Playlist from this Playlist.""" self.child_set.remove_row(child) + if self.child_set.keyset.n_keys == 0: + self.table.refilter(Gtk.FilterChange.MORE_STRICT) def remove_track(self, track: table.Row, *, idle: bool = False) -> None: """Remove a Track from this Playlist.""" @@ -154,6 +158,10 @@ class Table(table.Table): def __create_tree(self, plist: Playlist) -> Gtk.FilterListModel | None: return plist.children + def __refilter(self, change_how: Gtk.FilterChange) -> bool: + self.get_filter().changed(change_how) + return True + def do_add_track(self, playlist: Playlist, track: Track) -> bool: """Add a Track to the Playlist.""" raise NotImplementedError @@ -255,6 +263,11 @@ class Table(table.Table): playlist.sort_order = "user" return res + def refilter(self, change_how: Gtk.FilterChange) -> None: + """Schedule refiltering the Table.""" + self.queue.cancel_task(self.__refilter) + self.queue.push(self.__refilter, change_how, first=True) + def remove_system_track(self, playlist: Playlist, track: Track) -> bool: """Remove a Track from a system Playlist.""" return self.sql("""DELETE FROM system_tracks diff --git a/tests/db/test_playlist.py b/tests/db/test_playlist.py index 0e05a9d..820a1a7 100644 --- a/tests/db/test_playlist.py +++ b/tests/db/test_playlist.py @@ -21,6 +21,7 @@ class TestPlaylistRow(unittest.TestCase): self.table.move_track_up = unittest.mock.Mock(return_value=True) self.table.get_trackids = unittest.mock.Mock(return_value={1, 2, 3}) self.table.get_track_order = unittest.mock.Mock() + self.table.refilter = unittest.mock.Mock() self.table.queue = emmental.db.idle.Queue() self.table.update = unittest.mock.Mock(return_value=True) @@ -114,11 +115,16 @@ class TestPlaylistRow(unittest.TestCase): def test_add_child(self): """Test adding a child playlist to the playlist.""" table = emmental.db.table.Table(None) - child = tests.util.table.MockRow(table=table, number=1) + child1 = tests.util.table.MockRow(table=table, number=1) + child2 = tests.util.table.MockRow(table=table, number=2) self.playlist.add_children(table, set()) - self.playlist.add_child(child) - self.assertIn(child, self.playlist.child_set) + self.playlist.add_child(child1) + self.assertIn(child1, self.playlist.child_set) + self.table.refilter.assert_called_with(Gtk.FilterChange.LESS_STRICT) + + self.playlist.add_child(child2) + self.table.refilter.assert_called_once() def test_add_track(self): """Test adding a track to the playlist.""" @@ -179,12 +185,19 @@ class TestPlaylistRow(unittest.TestCase): def test_remove_child(self): """Test removing a child playlist from the playlist.""" table = emmental.db.table.Table(None) - child = tests.util.table.MockRow(table=table, number=1) + child1 = tests.util.table.MockRow(table=table, number=1) + child2 = tests.util.table.MockRow(table=table, number=2) self.playlist.add_children(table, set()) + self.playlist.add_child(child1) + self.playlist.add_child(child2) + self.table.refilter.reset_mock() - self.playlist.add_child(child) - self.playlist.remove_child(child) - self.assertFalse(child in self.playlist.child_set) + self.playlist.remove_child(child1) + self.assertFalse(child1 in self.playlist.child_set) + self.table.refilter.assert_not_called() + + self.playlist.remove_child(child2) + self.table.refilter.assert_called_with(Gtk.FilterChange.MORE_STRICT) def test_remove_track(self): """Test removing a track from the playlist.""" @@ -403,6 +416,27 @@ class TestPlaylistTable(tests.util.TestCase): self.table.move_track_up(plist, self.track) self.assertEqual(plist.sort_order, "user") + def test_refilter(self): + """Test refiltering the playlist table.""" + self.table.queue.push(unittest.mock.Mock()) + + with unittest.mock.patch.object(self.table.get_filter(), + "changed") as mock_changed: + self.table.refilter(Gtk.FilterChange.MORE_STRICT) + self.assertEqual(self.table.queue[0], + (self.table._Table__refilter, + Gtk.FilterChange.MORE_STRICT)) + mock_changed.assert_not_called() + + self.table.refilter(Gtk.FilterChange.LESS_STRICT) + self.assertEqual(self.table.queue[0], + (self.table._Table__refilter, + Gtk.FilterChange.LESS_STRICT)) + mock_changed.assert_not_called() + + self.table.queue.complete() + mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT) + def test_remove_track(self): """Test adding a track to a playlist.""" self.assertTrue(self.table.system_tracks)