playlist: Create a SortPlaylistModel

This is a Gio.ListModel for the current playlist's sort order that has
extra functions for rearranging or reversing the sort fields.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-11-07 20:12:51 -05:00
parent fc83b66fbe
commit 35e3085c6a
2 changed files with 186 additions and 0 deletions

View File

@ -86,6 +86,54 @@ class PlaylistSelection(Gtk.MultiSelection):
def set_playlist(self, plist): return self.get_model().set_playlist(plist)
class SortPlaylistModel(Gtk.StringList):
def __init__(self):
Gtk.StringList.__init__(self)
self.playlist = None
self.connect("items-changed", self.order_changed)
def get_index(self, string):
fields = [ self.get_string(i).split()[0] for i in range(self.get_n_items()) ]
return fields.index(string)
def get_direction(self, string):
return self.get_string(self.get_index(string)).split()[1]
def set_playlist(self, plist):
self.handler_block_by_func(self.order_changed)
self.playlist = plist
order = [ f for f in plist.sort if f.split()[0] not in ( "discs.number", "tracks.trackid") ]
self.splice(0, self.get_n_items(), order)
self.handler_unblock_by_func(self.order_changed)
def append(self, field):
super().append(f"{field} ASC")
def remove(self, field):
super().remove(self.get_index(field))
def move_up(self, field):
if (index := self.get_index(field)) > 0:
self.splice(index - 1, 2, [ self.get_string(index),
self.get_string(index - 1) ])
def move_down(self, field):
if (index := self.get_index(field)) < (self.get_n_items() - 1):
self.splice(index, 2, [ self.get_string(index + 1),
self.get_string(index) ])
def reverse(self, field):
index = self.get_index(field)
dir = 'DESC' if self.get_direction(field) == 'ASC' else 'ASC'
self.splice(index, 1, [ f"{field} {dir}" ])
def order_changed(self, model, pos, rm, add):
order = [ self.get_string(i) for i in range(self.get_n_items()) ]
if i := self.get_index("tracks.number"):
order.insert(i, f"discs.number {self.get_direction('tracks.number')}")
self.playlist.sort = order
class TagModel(GObject.GObject, Gio.ListModel):
def __init__(self, tag=None):
GObject.GObject.__init__(self)

View File

@ -127,6 +127,144 @@ class TestPlaylistSelectionModel(unittest.TestCase):
self.assertIsNone(selection.get_playlist())
class TestSortPlaylistModel(unittest.TestCase):
def setUp(self):
db.reset()
def test_init(self):
sort = model.SortPlaylistModel()
self.assertIsInstance(sort, Gtk.StringList)
self.assertIsNone(sort.playlist)
def test_set_playlist(self):
collection = db.user.Table.find("Collection")
sort = model.SortPlaylistModel()
sort.set_playlist(collection)
self.assertEqual(sort.playlist, collection)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number ASC")
def test_append(self):
collection = db.user.Table.find("Collection")
sort = model.SortPlaylistModel()
sort.set_playlist(collection)
sort.append("tracks.title")
self.assertEqual(sort.get_n_items(), 5)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number ASC")
self.assertEqual(sort.get_string(4), "tracks.title ASC")
self.assertEqual(collection.sort, [ "artists.sort ASC",
"albums.release ASC",
"albums.sort ASC",
"discs.number ASC",
"tracks.number ASC",
"tracks.title ASC",
"tracks.trackid ASC" ])
def test_remove(self):
collection = db.user.Table.find("Collection")
sort = model.SortPlaylistModel()
sort.set_playlist(collection)
sort.remove("albums.release")
self.assertEqual(sort.get_n_items(), 3)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.sort ASC")
self.assertEqual(sort.get_string(2), "tracks.number ASC")
self.assertEqual(collection.sort, [ "artists.sort ASC",
"albums.sort ASC",
"discs.number ASC",
"tracks.number ASC",
"tracks.trackid ASC" ])
def test_move_up(self):
collection = db.user.Table.find("Collection")
sort = model.SortPlaylistModel()
sort.set_playlist(collection)
sort.move_up("albums.release")
self.assertEqual(sort.get_n_items(), 4)
self.assertEqual(sort.get_string(0), "albums.release ASC")
self.assertEqual(sort.get_string(1), "artists.sort ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number ASC")
self.assertEqual(collection.sort, [ "albums.release ASC",
"artists.sort ASC",
"albums.sort ASC",
"discs.number ASC",
"tracks.number ASC",
"tracks.trackid ASC" ])
sort.move_up("artists.sort")
self.assertEqual(sort.get_n_items(), 4)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number ASC")
def test_move_down(self):
collection = db.user.Table.find("Collection")
sort = model.SortPlaylistModel()
sort.set_playlist(collection)
sort.move_down("albums.sort")
self.assertEqual(sort.get_n_items(), 4)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "tracks.number ASC")
self.assertEqual(sort.get_string(3), "albums.sort ASC")
self.assertEqual(collection.sort, [ "artists.sort ASC",
"albums.release ASC",
"discs.number ASC",
"tracks.number ASC",
"albums.sort ASC",
"tracks.trackid ASC" ])
sort.move_down("tracks.number")
self.assertEqual(sort.get_n_items(), 4)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number ASC")
def test_reverse(self):
collection = db.user.Table.find("Collection")
sort = model.SortPlaylistModel()
sort.set_playlist(collection)
sort.reverse("tracks.number")
self.assertEqual(sort.get_n_items(), 4)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number DESC")
self.assertEqual(collection.sort, [ "artists.sort ASC",
"albums.release ASC",
"albums.sort ASC",
"discs.number DESC",
"tracks.number DESC",
"tracks.trackid ASC" ])
sort.reverse("tracks.number")
self.assertEqual(sort.get_n_items(), 4)
self.assertEqual(sort.get_string(0), "artists.sort ASC")
self.assertEqual(sort.get_string(1), "albums.release ASC")
self.assertEqual(sort.get_string(2), "albums.sort ASC")
self.assertEqual(sort.get_string(3), "tracks.number ASC")
class TestTagModel(unittest.TestCase):
def setUp(self):
self.changed = (None, None, None)