From 61dfc2a5862ab3c69b30950f9ca1ccb9f46f39e9 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Wed, 19 Oct 2022 13:29:06 -0400 Subject: [PATCH] tracklist: Create a MediumName TrackRow The MediumName TrackRow is used to combine the album and medium names into a single string. This means we won't need to have a separate medium name column that is empty for most tracks. Signed-off-by: Anna Schumaker --- emmental/tracklist/row.py | 44 +++++++++++++++++++++++++++++++ emmental/tracklist/trackview.py | 1 + tests/test_settings.py | 4 +++ tests/tracklist/test_row.py | 23 +++++++++++++++- tests/tracklist/test_trackview.py | 28 +++++++++++++++----- 5 files changed, 93 insertions(+), 7 deletions(-) diff --git a/emmental/tracklist/row.py b/emmental/tracklist/row.py index 458dd53..a854c0e 100644 --- a/emmental/tracklist/row.py +++ b/emmental/tracklist/row.py @@ -240,6 +240,50 @@ class AlbumString(InscriptionRow): self.bind_to_self("mediumid", "mediumid") +class MediumString(InscriptionRow): + """A Track Row to display Album and Medium names.""" + + album = GObject.Property(type=str) + medium = GObject.Property(type=str) + + def __init__(self, listitem: Gtk.ListItem, property: str, **kwargs): + """Initialize a MediumName inscription.""" + super().__init__(listitem, property, **kwargs) + self.connect("notify", self.__update_string) + + def __unbind_medium_name(self) -> None: + binding = getattr(self, "medium_binding", None) + if binding is not None: + binding.unbind() + setattr(self, "medium_binding", None) + + def __rebind_medium_name(self) -> None: + medium = self.item.get_medium() + self.medium = medium.name + setattr(self, "medium_binding", + medium.bind_property("name", self, "medium")) + + def __update_string(self, row: InscriptionRow, param) -> None: + match param.name: + case "mediumid": + self.rebind_album("album", to_self=True) + self.__rebind_medium_name() + case "album" | "medium": + medium = f":\n{self.medium}" if len(self.medium) else "" + album = self.item.get_medium().get_album().name + self.child.set_text(f"{album}{medium}") + + def do_bind(self) -> None: + """Bind an album name and medium name to the Inscription.""" + super().do_bind() + self.bind_to_self("mediumid", "mediumid") + + def do_unbind(self) -> None: + """Unbind the album and medium name from the Inscription.""" + super().do_unbind() + self.__unbind_medium_name() + + class AlbumCover(TrackRow): """A Track Row to display Album art.""" diff --git a/emmental/tracklist/trackview.py b/emmental/tracklist/trackview.py index 1ff62a4..7331569 100644 --- a/emmental/tracklist/trackview.py +++ b/emmental/tracklist/trackview.py @@ -37,6 +37,7 @@ class TrackView(Gtk.Frame): self.__append_column("Length", "length", row.LengthString, xalign=1.0, numeric=True) self.__append_column("Artist", "artist", row.TrackString, width=250) + self.__append_column("Album", "name", row.MediumString, width=350) self.__append_column("Album Artist", "artist", row.AlbumString, width=250, visible=False) self.__append_column("Release", "release", row.AlbumString, diff --git a/tests/test_settings.py b/tests/test_settings.py index 0874abf..512bb4a 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -127,6 +127,7 @@ class TestSettings(unittest.TestCase): self.assertEqual(self.settings["tracklist.title.size"], 300) self.assertEqual(self.settings["tracklist.length.size"], -1) self.assertEqual(self.settings["tracklist.artist.size"], 250) + self.assertEqual(self.settings["tracklist.album.size"], 350) self.assertEqual(self.settings["tracklist.album-artist.size"], 250) self.assertEqual(self.settings["tracklist.release.size"], 115) self.assertEqual(self.settings["tracklist.play-count.size"], 135) @@ -143,6 +144,7 @@ class TestSettings(unittest.TestCase): self.assertEqual(self.settings["tracklist.title.size"], 123) self.assertEqual(self.settings["tracklist.length.size"], 123) self.assertEqual(self.settings["tracklist.artist.size"], 123) + self.assertEqual(self.settings["tracklist.album.size"], 123) self.assertEqual(self.settings["tracklist.album-artist.size"], 123) self.assertEqual(self.settings["tracklist.release.size"], 123) self.assertEqual(self.settings["tracklist.play-count.size"], 123) @@ -158,6 +160,7 @@ class TestSettings(unittest.TestCase): self.assertTrue(self.settings["tracklist.title.visible"]) self.assertTrue(self.settings["tracklist.length.visible"]) self.assertTrue(self.settings["tracklist.artist.visible"]) + self.assertTrue(self.settings["tracklist.album.visible"]) self.assertFalse(self.settings["tracklist.album-artist.visible"]) self.assertTrue(self.settings["tracklist.release.visible"]) self.assertTrue(self.settings["tracklist.play-count.visible"]) @@ -174,6 +177,7 @@ class TestSettings(unittest.TestCase): self.assertFalse(self.settings["tracklist.title.visible"]) self.assertFalse(self.settings["tracklist.length.visible"]) self.assertFalse(self.settings["tracklist.artist.visible"]) + self.assertFalse(self.settings["tracklist.album.visible"]) self.assertTrue(self.settings["tracklist.album-artist.visible"]) self.assertFalse(self.settings["tracklist.release.visible"]) self.assertFalse(self.settings["tracklist.play-count.visible"]) diff --git a/tests/tracklist/test_row.py b/tests/tracklist/test_row.py index ba43b5d..24f4b86 100644 --- a/tests/tracklist/test_row.py +++ b/tests/tracklist/test_row.py @@ -23,7 +23,7 @@ class TestTrackRowWidgets(tests.util.TestCase): self.library = self.sql.libraries.create(pathlib.Path("/a/b")) self.album = self.sql.albums.create("Test Album", "Artist", "2023", cover=tests.util.COVER_JPG) - self.medium = self.sql.media.create(self.album, "", number=1) + self.medium = self.sql.media.create(self.album, "Medium", number=1) self.year = self.sql.years.create(2023) self.track = self.sql.tracks.create(self.library, pathlib.Path("/a/b/1.ogg"), @@ -170,6 +170,27 @@ class TestTrackRowWidgets(tests.util.TestCase): row.unbind() self.assertIsNone(row.album_binding) + def test_medium_string(self): + """Test the Medium String widget.""" + row = emmental.tracklist.row.MediumString(self.listitem, "name") + self.assertIsInstance(row, emmental.tracklist.row.InscriptionRow) + self.assertEqual(row.property, "name") + self.assertEqual(row.medium, "") + + row.bind() + self.assertEqual(row.medium, "Medium") + self.assertEqual(row.child.get_text(), "Test Album:\nMedium") + + self.medium.rename("New Name") + self.assertEqual(row.medium, "New Name") + self.assertEqual(row.child.get_text(), "Test Album:\nNew Name") + + album = self.sql.albums.create("Other Album", "Other Artist", "2023") + medium = self.sql.media.create(album, "", number=4) + self.track.mediumid = medium.mediumid + self.assertEqual(row.medium, "") + self.assertEqual(row.child.get_text(), "Other Album") + def test_album_cover(self): """Test the Album Cover widget.""" self.assertDictEqual(emmental.tracklist.row.AlbumCover.Cache, {}) diff --git a/tests/tracklist/test_trackview.py b/tests/tracklist/test_trackview.py index aeef852..9353234 100644 --- a/tests/tracklist/test_trackview.py +++ b/tests/tracklist/test_trackview.py @@ -187,7 +187,23 @@ class TestTrackViewColumns(tests.util.TestCase): self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) self.assertFalse(self.listitem.listrow.child.has_css_class("numeric")) - def test_album_artist_column(self, i: int = 6): + def test_album_column(self, i: int = 6): + """Test the artist column.""" + self.assertEqual(self.columns[i].get_title(), "Album") + self.assertEqual(self.columns[i].get_fixed_width(), 350) + self.assertTrue(self.columns[i].get_resizable()) + self.assertTrue(self.columns[i].get_visible()) + + factory = self.columns[i].get_factory() + self.assertIsInstance(factory, emmental.factory.Factory) + self.assertEqual(factory.row_type, emmental.tracklist.row.MediumString) + + factory.emit("setup", self.listitem) + self.assertEqual(self.listitem.listrow.property, "name") + self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) + self.assertFalse(self.listitem.listrow.child.has_css_class("numeric")) + + def test_album_artist_column(self, i: int = 7): """Test the album artist column.""" self.assertEqual(self.columns[i].get_title(), "Album Artist") self.assertEqual(self.columns[i].get_fixed_width(), 250) @@ -203,7 +219,7 @@ class TestTrackViewColumns(tests.util.TestCase): self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) self.assertFalse(self.listitem.listrow.child.has_css_class("numeric")) - def test_release_column(self, i: int = 7): + def test_release_column(self, i: int = 8): """Test the release date column.""" self.assertEqual(self.columns[i].get_title(), "Release") self.assertEqual(self.columns[i].get_fixed_width(), 115) @@ -219,7 +235,7 @@ class TestTrackViewColumns(tests.util.TestCase): self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) self.assertTrue(self.listitem.listrow.child.has_css_class("numeric")) - def test_playcount_column(self, i: int = 8): + def test_playcount_column(self, i: int = 9): """Test the play count column.""" self.assertEqual(self.columns[i].get_title(), "Play Count") self.assertEqual(self.columns[i].get_fixed_width(), 135) @@ -236,7 +252,7 @@ class TestTrackViewColumns(tests.util.TestCase): self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) self.assertTrue(self.listitem.listrow.child.has_css_class("numeric")) - def test_last_started_column(self, i: int = 9): + def test_last_started_column(self, i: int = 10): """Test the last started column.""" self.assertEqual(self.columns[i].get_title(), "Last Started") self.assertEqual(self.columns[i].get_fixed_width(), 250) @@ -253,7 +269,7 @@ class TestTrackViewColumns(tests.util.TestCase): self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) self.assertTrue(self.listitem.listrow.child.has_css_class("numeric")) - def test_last_played_column(self, i: int = 10): + def test_last_played_column(self, i: int = 11): """Test the last played column.""" self.assertEqual(self.columns[i].get_title(), "Last Played") self.assertEqual(self.columns[i].get_fixed_width(), 250) @@ -270,7 +286,7 @@ class TestTrackViewColumns(tests.util.TestCase): self.assertEqual(self.listitem.listrow.child.get_xalign(), 0.0) self.assertTrue(self.listitem.listrow.child.has_css_class("numeric")) - def test_filepath_column(self, i: int = 11): + def test_filepath_column(self, i: int = 12): """Test the last played column.""" self.assertEqual(self.columns[i].get_title(), "Filepath") self.assertEqual(self.columns[i].get_fixed_width(), -1)