[gnome-music/wip/jfelder/coredisc-updates: 10/12] coreartist: Add a flattenlistmodel




commit 41922b651995f64ef51dceae68a900ac68475213
Author: Jean Felder <jfelder src gnome org>
Date:   Fri Nov 13 11:30:25 2020 +0100

    coreartist: Add a flattenlistmodel
    
    CoreArtist contains a model which is a list of all the albums of the
    artist. Then, each CoreAlbum has a model wich contains all the songs
    of the disc. When playing an artist a flattenlistmodel is created on
    the fly to have a list of all the songs of the artist. This works
    reliably but it's impossible to update the player playlist when a
    CoreAlbum is added because the playlist listens to the artist model
    change instead of the flatten model changes.
    
    This issue is fixed by adding a new flatten model to CoreArtist which
    contains all the songs of the artist. This new model can directly be
    used to create a player playlist.
    
    CoreArtist now contains 2 models:
    - model contains all the songs of the artist
    - albums_model contains all the albums of the artist

 gnomemusic/coreartist.py                 | 69 +++++++++++++++++++++++---------
 gnomemusic/coremodel.py                  | 12 +-----
 gnomemusic/widgets/artistalbumswidget.py |  2 +-
 3 files changed, 54 insertions(+), 29 deletions(-)
---
diff --git a/gnomemusic/coreartist.py b/gnomemusic/coreartist.py
index 1630d3fb6..8f397a5eb 100644
--- a/gnomemusic/coreartist.py
+++ b/gnomemusic/coreartist.py
@@ -22,12 +22,19 @@
 # code, but you are not obligated to do so.  If you do not wish to do so,
 # delete this exception statement from your version.
 
+from __future__ import annotations
+
+import typing
+
 import gi
 gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
 from gi.repository import Gfm, Gio, Grl, GObject
 
 from gnomemusic.artistart import ArtistArt
+from gnomemusic.coresong import CoreSong
 import gnomemusic.utils as utils
+if typing.TYPE_CHECKING:
+    from gnomemusic.corealbum import CoreAlbum
 
 
 class CoreArtist(GObject.GObject):
@@ -52,43 +59,69 @@ class CoreArtist(GObject.GObject):
         self._selected = False
         self._thumbnail = None
 
+        self._albums_model_proxy = Gio.ListStore.new(Gio.ListModel)
+        self._albums_model_filter = Gfm.FilterListModel.new(
+            self._coremodel.props.albums)
+        self._albums_model_sort = Gfm.SortListModel.new(
+            self._albums_model_filter,
+            utils.wrap_list_store_sort_func(self._album_sort))
+
         self.update(media)
 
     def update(self, media):
         self.props.media = media
         self.props.artist = utils.get_artist_name(media)
 
-    def _get_artist_album_model(self):
-        albums_model_filter = Gfm.FilterListModel.new(
-            self._coremodel.props.albums)
-        albums_model_filter.set_filter_func(lambda a: False)
+    @staticmethod
+    def _album_sort(album_a: CoreAlbum, album_b: CoreAlbum) -> None:
+        return album_a.props.year > album_b.props.year
 
-        albums_model_sort = Gfm.SortListModel.new(albums_model_filter)
+    def _load_artist_album_model(self):
+        self._model = Gfm.FlattenListModel.new(
+            CoreSong, self._albums_model_proxy)
 
+        self._albums_model_filter.set_filter_func(lambda a: False)
         self._coregrilo.get_artist_albums(
-            self.props.media, albums_model_filter)
-
-        def _album_sort(album_a, album_b):
-            return album_a.props.year > album_b.props.year
+            self.props.media, self._albums_model_filter)
 
-        albums_model_sort.set_sort_func(
-            utils.wrap_list_store_sort_func(_album_sort))
+        self._albums_model_sort.connect(
+            "items-changed", self._on_albums_changed)
 
-        return albums_model_sort
-
-    @GObject.Property(type=Gio.ListModel, default=None)
+    @GObject.Property(type=Gfm.FlattenListModel, default=None)
     def model(self):
+        """Model which contains all the songs of an artist.
+
+        :returns: songs model
+        :rtype: Gfm.FlattenListModel
+        """
         if self._model is None:
-            self._model = self._get_artist_album_model()
-            self._model.connect("items-changed", self._on_items_changed)
+            self._load_artist_album_model()
 
         return self._model
 
-    def _on_items_changed(self, model, pos, removed, added):
+    @GObject.Property(type=Gio.ListModel, flags=GObject.ParamFlags.READABLE)
+    def albums_model(self) -> Gio.ListModel:
+        """Model which contains all the albums of an artists.
+
+        :returns: albums model
+        :rtype: Gfm.SortListModel
+        """
+        if self._model is None:
+            self._load_artist_album_model()
+
+        return self._albums_model_sort
+
+    def _on_albums_changed(self, model, pos, removed, added):
         with self.freeze_notify():
-            for corealbum in self._model:
+            for corealbum in model:
                 corealbum.props.selected = self.props.selected
 
+            if added > 0:
+                for i in range(added):
+                    corealbum = model[pos + i]
+                    self._albums_model_proxy.append(
+                        corealbum.props.model)
+
     @GObject.Property(type=bool, default=False)
     def selected(self):
         return self._selected
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index a75542de6..0275d64d6 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -246,17 +246,9 @@ class CoreModel(GObject.GObject):
                 songs_added.append(song)
 
         elif playlist_type == PlayerPlaylist.Type.ARTIST:
-            proxy_model = Gio.ListStore.new(Gio.ListModel)
-
-            for artist_album in model:
-                for disc in artist_album.model:
-                    proxy_model.append(disc.props.model)
-
-            self._flatten_model = Gfm.FlattenListModel.new(
-                CoreSong, proxy_model)
-            self._current_playlist_model = self._flatten_model
+            self._current_playlist_model = model
 
-            for model_song in self._flatten_model:
+            for model_song in model:
                 song = CoreSong(self._application, model_song.props.media)
                 _bind_song_properties(model_song, song)
                 songs_added.append(song)
diff --git a/gnomemusic/widgets/artistalbumswidget.py b/gnomemusic/widgets/artistalbumswidget.py
index 701ff9991..2a66582b2 100644
--- a/gnomemusic/widgets/artistalbumswidget.py
+++ b/gnomemusic/widgets/artistalbumswidget.py
@@ -49,7 +49,7 @@ class ArtistAlbumsWidget(Gtk.ListBox):
 
         self._application = application
         self._artist = coreartist
-        self._model = coreartist.props.model
+        self._model = coreartist.props.albums_model
         self._player = self._application.props.player
 
         self._cover_size_group = Gtk.SizeGroup.new(


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]