playlist: Give playlists functions for moving individual tracks
The move_track_up() and move_track_down() functions are used to manually arrange the tracks in a playlist. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
edaa275ba5
commit
45ddb22cc7
|
@ -29,6 +29,18 @@ class Playlist(model.TrackidModel):
|
||||||
self.on_trackids_reset(plist.tracks)
|
self.on_trackids_reset(plist.tracks)
|
||||||
self.notify("sort-order")
|
self.notify("sort-order")
|
||||||
|
|
||||||
|
def __track_moved(self, track: db.tracks.Track, *, offset: int) -> None:
|
||||||
|
index = self.index(track)
|
||||||
|
new_pos = index + offset
|
||||||
|
n_changed = abs(offset) + 1
|
||||||
|
|
||||||
|
del self.trackids[index]
|
||||||
|
self.trackids.insert(new_pos, track.trackid)
|
||||||
|
|
||||||
|
self.__sort_keys = self.__playlist.get_track_order()
|
||||||
|
self.items_changed(position=min(index, new_pos),
|
||||||
|
removed=n_changed, added=n_changed)
|
||||||
|
|
||||||
def do_get_sort_key(self, trackid: int) -> int:
|
def do_get_sort_key(self, trackid: int) -> int:
|
||||||
"""Get a sort key for the given trackid."""
|
"""Get a sort key for the given trackid."""
|
||||||
if (key := self.__sort_keys.get(trackid)) is None:
|
if (key := self.__sort_keys.get(trackid)) is None:
|
||||||
|
@ -60,6 +72,20 @@ class Playlist(model.TrackidModel):
|
||||||
if track is not None:
|
if track is not None:
|
||||||
return super().index(track.trackid)
|
return super().index(track.trackid)
|
||||||
|
|
||||||
|
def move_track_down(self, track: db.tracks.Track) -> None:
|
||||||
|
"""Move a track earlier in the sort order."""
|
||||||
|
if self.__playlist is not None:
|
||||||
|
need_handling = self.__sort_order == "user"
|
||||||
|
if self.__playlist.move_track_down(track) and need_handling:
|
||||||
|
self.__track_moved(track, offset=1)
|
||||||
|
|
||||||
|
def move_track_up(self, track: db.tracks.Track) -> None:
|
||||||
|
"""Move a track earlier in the sort order."""
|
||||||
|
if self.__playlist is not None:
|
||||||
|
need_handling = self.__sort_order == "user"
|
||||||
|
if self.__playlist.move_track_up(track) and need_handling:
|
||||||
|
self.__track_moved(track, offset=-1)
|
||||||
|
|
||||||
def remove_track(self, track: db.tracks.Track) -> None:
|
def remove_track(self, track: db.tracks.Track) -> None:
|
||||||
"""Remove a track from the playlist."""
|
"""Remove a track from the playlist."""
|
||||||
if self.__playlist is not None:
|
if self.__playlist is not None:
|
||||||
|
|
|
@ -73,6 +73,74 @@ class TestPlaylist(tests.util.TestCase):
|
||||||
self.assertIsNone(super(type(self.playlist), self.playlist).index(0))
|
self.assertIsNone(super(type(self.playlist), self.playlist).index(0))
|
||||||
self.assertIsNone(self.playlist.index(None))
|
self.assertIsNone(self.playlist.index(None))
|
||||||
|
|
||||||
|
def test_move_track_down(self):
|
||||||
|
"""Test the playlist move_track_down() function."""
|
||||||
|
self.playlist.move_track_down(self.track1)
|
||||||
|
|
||||||
|
self.db_plist.add_track(self.track1)
|
||||||
|
self.db_plist.add_track(self.track2)
|
||||||
|
self.db_plist.add_track(self.track3)
|
||||||
|
self.playlist.playlist = self.db_plist
|
||||||
|
|
||||||
|
items_changed = unittest.mock.Mock()
|
||||||
|
self.playlist.connect("items-changed", items_changed)
|
||||||
|
|
||||||
|
self.playlist.move_track_down(self.track2)
|
||||||
|
self.assertEqual(self.db_plist.sort_order, "user")
|
||||||
|
self.assertDictEqual(self.playlist._Playlist__sort_keys,
|
||||||
|
{self.track1.trackid: 0,
|
||||||
|
self.track3.trackid: 1,
|
||||||
|
self.track2.trackid: 2})
|
||||||
|
self.assertListEqual(self.playlist.trackids, [self.track1.trackid,
|
||||||
|
self.track3.trackid,
|
||||||
|
self.track2.trackid])
|
||||||
|
items_changed.assert_called_once_with(self.playlist, 0, 3, 3)
|
||||||
|
|
||||||
|
items_changed.reset_mock()
|
||||||
|
self.playlist.move_track_down(self.track1)
|
||||||
|
self.assertDictEqual(self.playlist._Playlist__sort_keys,
|
||||||
|
{self.track3.trackid: 0,
|
||||||
|
self.track1.trackid: 1,
|
||||||
|
self.track2.trackid: 2})
|
||||||
|
self.assertListEqual(self.playlist.trackids, [self.track3.trackid,
|
||||||
|
self.track1.trackid,
|
||||||
|
self.track2.trackid])
|
||||||
|
items_changed.assert_called_once_with(self.playlist, 0, 2, 2)
|
||||||
|
|
||||||
|
def test_move_track_up(self):
|
||||||
|
"""Test the playlist move_track_up() function."""
|
||||||
|
self.playlist.move_track_up(self.track1)
|
||||||
|
|
||||||
|
self.db_plist.add_track(self.track1)
|
||||||
|
self.db_plist.add_track(self.track2)
|
||||||
|
self.db_plist.add_track(self.track3)
|
||||||
|
self.playlist.playlist = self.db_plist
|
||||||
|
|
||||||
|
items_changed = unittest.mock.Mock()
|
||||||
|
self.playlist.connect("items-changed", items_changed)
|
||||||
|
|
||||||
|
self.playlist.move_track_up(self.track2)
|
||||||
|
self.assertEqual(self.db_plist.sort_order, "user")
|
||||||
|
self.assertDictEqual(self.playlist._Playlist__sort_keys,
|
||||||
|
{self.track2.trackid: 0,
|
||||||
|
self.track1.trackid: 1,
|
||||||
|
self.track3.trackid: 2})
|
||||||
|
self.assertListEqual(self.playlist.trackids, [self.track2.trackid,
|
||||||
|
self.track1.trackid,
|
||||||
|
self.track3.trackid])
|
||||||
|
items_changed.assert_called_once_with(self.playlist, 0, 3, 3)
|
||||||
|
|
||||||
|
items_changed.reset_mock()
|
||||||
|
self.playlist.move_track_up(self.track3)
|
||||||
|
self.assertDictEqual(self.playlist._Playlist__sort_keys,
|
||||||
|
{self.track2.trackid: 0,
|
||||||
|
self.track3.trackid: 1,
|
||||||
|
self.track1.trackid: 2})
|
||||||
|
self.assertListEqual(self.playlist.trackids, [self.track2.trackid,
|
||||||
|
self.track3.trackid,
|
||||||
|
self.track1.trackid])
|
||||||
|
items_changed.assert_called_once_with(self.playlist, 1, 2, 2)
|
||||||
|
|
||||||
def test_remove_track(self):
|
def test_remove_track(self):
|
||||||
"""Test the playlist remove_track() function."""
|
"""Test the playlist remove_track() function."""
|
||||||
self.playlist.remove_track(self.track1)
|
self.playlist.remove_track(self.track1)
|
||||||
|
|
Loading…
Reference in New Issue