db: Add a child_set TableSubset to the Playlist
It defaults to a None pointer, but calling add_children() will set one up with an empty set. I also implement functions for adding, removing, and verifying child playlists. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
67b508384c
commit
85c18fb5fe
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2022 (c) Anna Schumaker
|
||||
"""A customized Gio.ListStore for tracking Playlist GObjects."""
|
||||
import sqlite3
|
||||
import typing
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gio
|
||||
from gi.repository import Gtk
|
||||
|
@ -28,6 +29,7 @@ class Playlist(table.Row):
|
|||
tracks_movable = GObject.Property(type=bool, default=False)
|
||||
current_trackid = GObject.Property(type=int)
|
||||
|
||||
child_set = GObject.Property(type=table.TableSubset)
|
||||
children = GObject.Property(type=Gtk.FilterListModel)
|
||||
|
||||
def __init__(self, table: Gio.ListModel, propertyid: int,
|
||||
|
@ -49,19 +51,27 @@ class Playlist(table.Row):
|
|||
return True
|
||||
|
||||
def add_children(self, child_table: table.Table,
|
||||
child_filter: Gtk.Filter) -> None:
|
||||
child_filter: Gtk.Filter,
|
||||
child_keys: set | None = None) -> None:
|
||||
"""Create a FilterListModel for this playlist's children."""
|
||||
child_keys = set() if child_keys is None else child_keys
|
||||
self.child_set = table.TableSubset(child_table, keys=child_keys)
|
||||
self.children = Gtk.FilterListModel.new(child_table, child_filter)
|
||||
self.children.set_incremental(True)
|
||||
|
||||
def do_update(self, column: str) -> bool:
|
||||
"""Update a Playlist object."""
|
||||
match column:
|
||||
case "propertyid" | "name" | "n-tracks" | "children" | \
|
||||
"user-tracks" | "tracks-loaded" | "tracks-movable": pass
|
||||
case "propertyid" | "name" | "n-tracks" | "child-set" | \
|
||||
"children" | "user-tracks" | "tracks-loaded" | \
|
||||
"tracks-movable": pass
|
||||
case _: return super().do_update(column)
|
||||
return True
|
||||
|
||||
def add_child(self, child: typing.Self) -> None:
|
||||
"""Add a child Playlist to this Playlist."""
|
||||
self.child_set.add_row(child)
|
||||
|
||||
def add_track(self, track: Track, *, idle: bool = False) -> None:
|
||||
"""Add a Track to this Playlist."""
|
||||
if self.table.add_track(self, track):
|
||||
|
@ -71,6 +81,10 @@ class Playlist(table.Row):
|
|||
"""Get a dictionary mapping for trackid -> sorted position."""
|
||||
return self.table.get_track_order(self)
|
||||
|
||||
def has_child(self, child: typing.Self) -> bool:
|
||||
"""Check if this Playlist has a specific child Playlist."""
|
||||
return child in self.child_set
|
||||
|
||||
def has_track(self, track: Track) -> bool:
|
||||
"""Check if a Track is on this Playlist."""
|
||||
return track in self.tracks
|
||||
|
@ -95,6 +109,10 @@ class Playlist(table.Row):
|
|||
self.tracks_loaded = False
|
||||
self.table.queue.push(self.load_tracks, now=not idle)
|
||||
|
||||
def remove_child(self, child: typing.Self) -> None:
|
||||
"""Remove a child Playlist from this Playlist."""
|
||||
self.child_set.remove_row(child)
|
||||
|
||||
def remove_track(self, track: table.Row, *, idle: bool = False) -> None:
|
||||
"""Remove a Track from this Playlist."""
|
||||
self.table.queue.push(self.__remove_track, track, now=not idle)
|
||||
|
|
|
@ -65,15 +65,28 @@ class TestPlaylistRow(unittest.TestCase):
|
|||
|
||||
def test_children(self):
|
||||
"""Test the child playlist properties."""
|
||||
self.assertIsNone(self.playlist.child_set)
|
||||
self.assertIsNone(self.playlist.children)
|
||||
|
||||
filter = Gtk.Filter()
|
||||
self.playlist.add_children(self.table, filter)
|
||||
table = emmental.db.table.Table(None)
|
||||
self.playlist.add_children(table, filter)
|
||||
|
||||
self.assertIsInstance(self.playlist.child_set,
|
||||
emmental.db.table.TableSubset)
|
||||
self.assertEqual(self.playlist.child_set.table, table)
|
||||
self.assertSetEqual(self.playlist.child_set.keyset.keys, set())
|
||||
|
||||
self.assertIsInstance(self.playlist.children, Gtk.FilterListModel)
|
||||
self.assertEqual(self.playlist.children.get_filter(), filter)
|
||||
self.assertEqual(self.playlist.children.get_model(), self.table)
|
||||
self.assertEqual(self.playlist.children.get_model(), table)
|
||||
self.assertTrue(self.playlist.children.get_incremental())
|
||||
|
||||
playlist2 = emmental.db.playlist.Playlist(table=self.table,
|
||||
propertyid=2, name="Plist2")
|
||||
playlist2.add_children(table, filter, {1, 2, 3})
|
||||
self.assertSetEqual(playlist2.child_set.keyset.keys, {1, 2, 3})
|
||||
|
||||
def test_parent(self):
|
||||
"""Test the parent playlist property."""
|
||||
self.assertIsNone(self.playlist.parent)
|
||||
|
@ -97,6 +110,15 @@ class TestPlaylistRow(unittest.TestCase):
|
|||
self.table.update.assert_called_with(self.playlist,
|
||||
prop, value)
|
||||
|
||||
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)
|
||||
self.playlist.add_children(table, Gtk.Filter())
|
||||
|
||||
self.playlist.add_child(child)
|
||||
self.assertIn(child, self.playlist.child_set)
|
||||
|
||||
def test_add_track(self):
|
||||
"""Test adding a track to the playlist."""
|
||||
self.playlist.add_track(self.track, idle=True)
|
||||
|
@ -122,6 +144,18 @@ class TestPlaylistRow(unittest.TestCase):
|
|||
{1: 3, 2: 2, 3: 1})
|
||||
self.table.get_track_order.assert_called_with(self.playlist)
|
||||
|
||||
def test_has_child(self):
|
||||
"""Test the playlist has_child() function."""
|
||||
table = emmental.db.table.Table(None)
|
||||
child = tests.util.table.MockRow(table=table, number=1)
|
||||
self.playlist.add_children(table, Gtk.Filter())
|
||||
|
||||
self.assertFalse(self.playlist.has_child(child))
|
||||
self.playlist.add_child(child)
|
||||
self.assertTrue(self.playlist.has_child(child))
|
||||
self.playlist.remove_child(child)
|
||||
self.assertFalse(self.playlist.has_child(child))
|
||||
|
||||
def test_has_track(self):
|
||||
"""Test the playlist has_track() function."""
|
||||
self.assertFalse(self.playlist.has_track(self.track))
|
||||
|
@ -141,6 +175,16 @@ class TestPlaylistRow(unittest.TestCase):
|
|||
self.assertTrue(self.playlist.move_track_up(self.track))
|
||||
self.table.move_track_up.assert_called_with(self.playlist, self.track)
|
||||
|
||||
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)
|
||||
self.playlist.add_children(table, Gtk.Filter())
|
||||
|
||||
self.playlist.add_child(child)
|
||||
self.playlist.remove_child(child)
|
||||
self.assertFalse(child in self.playlist.child_set)
|
||||
|
||||
def test_remove_track(self):
|
||||
"""Test removing a track from the playlist."""
|
||||
self.playlist.tracks.trackids.add(self.track.trackid)
|
||||
|
|
Loading…
Reference in New Issue