[gnome-music/wip/jfelder/coredisc-updates: 8/12] corealbum: Add a flattenlistmodel
- From: Jean Felder <jfelder src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/jfelder/coredisc-updates: 8/12] corealbum: Add a flattenlistmodel
- Date: Fri, 20 Nov 2020 22:44:27 +0000 (UTC)
commit 864ae6923ebd2caf8a2f8fdc32fe236e14e5e166
Author: Jean Felder <jfelder src gnome org>
Date: Fri Nov 13 00:35:55 2020 +0100
corealbum: Add a flattenlistmodel
CoreAlbum contains a model which is a list of all the discs of the
album. Then, each CoreDisc has a model wich contains all the songs of
the disc. When playing an album a flattenlistmodel is created on the
fly to have a list of all the songs of the album. This works reliably
but it's impossible to update the player playlist when a CoreDisc is
added because the playlist listens to the album model change instead
of the flatten model changes.
This issue is fixed by adding a new flatten model to CoreAlbum which
contains all the songs of the album. This new model can directly be
used to create a player playlist.
CoreAlbum now contains 2 models:
- model contains all the songs of the album
- disc_model contains all the discs of the album
gnomemusic/corealbum.py | 64 +++++++++++++++++++++++----------
gnomemusic/coremodel.py | 11 ++----
gnomemusic/widgets/albumwidget.py | 4 +--
gnomemusic/widgets/artistalbumwidget.py | 6 ++--
4 files changed, 53 insertions(+), 32 deletions(-)
---
diff --git a/gnomemusic/corealbum.py b/gnomemusic/corealbum.py
index 86d49fd27..f73e64d95 100644
--- a/gnomemusic/corealbum.py
+++ b/gnomemusic/corealbum.py
@@ -22,6 +22,10 @@
# 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
@@ -29,6 +33,9 @@ from gi.repository import Gfm, Gio, Grl, GObject
import gnomemusic.utils as utils
from gnomemusic.albumart import AlbumArt
+from gnomemusic.coresong import CoreSong
+if typing.TYPE_CHECKING:
+ from gnomemusic.coredisc import CoreDisc
class CoreAlbum(GObject.GObject):
@@ -57,6 +64,14 @@ class CoreAlbum(GObject.GObject):
self._selected = False
self._thumbnail = None
+ self._disc_model_proxy = Gio.ListStore.new(Gio.ListModel)
+ self._disc_model = Gio.ListStore()
+ self._disc_model_sort = Gfm.SortListModel.new(
+ self._disc_model,
+ utils.wrap_list_store_sort_func(self._disc_order_sort))
+ self._disc_model_sort.connect(
+ "items-changed", self._on_core_items_changed)
+
self.update(media)
def update(self, media):
@@ -71,19 +86,14 @@ class CoreAlbum(GObject.GObject):
self.props.url = media.get_url()
self.props.year = utils.get_media_year(media)
- def _get_album_model(self):
- disc_model = Gio.ListStore()
- disc_model_sort = Gfm.SortListModel.new(disc_model)
-
- def _disc_order_sort(disc_a, disc_b):
- return disc_a.props.disc_nr - disc_b.props.disc_nr
+ @staticmethod
+ def _disc_order_sort(disc_a: CoreDisc, disc_b: CoreDisc) -> int:
+ return disc_a.props.disc_nr - disc_b.props.disc_nr
- disc_model_sort.set_sort_func(
- utils.wrap_list_store_sort_func(_disc_order_sort))
-
- self._coregrilo.get_album_discs(self.props.media, disc_model)
-
- return disc_model_sort
+ def _load_album_model(self):
+ self._coregrilo.get_album_discs(self.props.media, self._disc_model)
+ self._model = Gfm.FlattenListModel.new(
+ CoreSong, self._disc_model_proxy)
@GObject.Property(
type=bool, default=False, flags=GObject.ParamFlags.READABLE)
@@ -96,16 +106,33 @@ class CoreAlbum(GObject.GObject):
return self._model is not None
@GObject.Property(
- type=Gio.ListModel, default=None, flags=GObject.ParamFlags.READABLE)
+ type=Gfm.FlattenListModel, default=None,
+ flags=GObject.ParamFlags.READABLE)
def model(self):
+ """Model which contains all the songs of an album.
+
+ :returns: songs model
+ :rtype: Gfm.FlattenListModel
+ """
if not self.props.model_loaded:
- self._model = self._get_album_model()
- self._model.connect("items-changed", self._on_list_items_changed)
- self._model.items_changed(0, 0, self._model.get_n_items())
+ self._load_album_model()
return self._model
- def _on_list_items_changed(self, model, position, removed, added):
+ @GObject.Property(
+ type=Gfm.SortListModel, flags=GObject.ParamFlags.READABLE)
+ def disc_model(self) -> Gfm.SortListModel:
+ """Model which contains all the discs of an album.
+
+ :returns: discs model
+ :rtype: Gfm.SortListModel
+ """
+ if not self.props.model_loaded:
+ self._load_album_model()
+
+ return self._disc_model_sort
+
+ def _on_core_items_changed(self, model, position, removed, added):
with self.freeze_notify():
for coredisc in model:
coredisc.props.selected = self.props.selected
@@ -113,13 +140,14 @@ class CoreAlbum(GObject.GObject):
if added > 0:
for i in range(added):
coredisc = model[position + i]
+ self._disc_model_proxy.append(coredisc.props.model)
coredisc.connect(
"notify::duration", self._on_duration_changed)
def _on_duration_changed(self, coredisc, duration):
duration = 0
- for coredisc in self.props.model:
+ for coredisc in self._disc_model:
duration += coredisc.props.duration
self.props.duration = duration
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 2a3f7967a..a75542de6 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -238,16 +238,9 @@ class CoreModel(GObject.GObject):
songs_added = []
if playlist_type == PlayerPlaylist.Type.ALBUM:
- proxy_model = Gio.ListStore.new(Gio.ListModel)
-
- for disc in 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/albumwidget.py b/gnomemusic/widgets/albumwidget.py
index bdb11d754..3a8b1206c 100644
--- a/gnomemusic/widgets/albumwidget.py
+++ b/gnomemusic/widgets/albumwidget.py
@@ -84,7 +84,7 @@ class AlbumWidget(Gtk.EventBox):
"""
if self._corealbum:
self._corealbum.disconnect(self._duration_signal_id)
- self._corealbum.props.model.disconnect(self._model_signal_id)
+ self._corealbum.props.disc_model.disconnect(self._model_signal_id)
self._corealbum = corealbum
@@ -103,7 +103,7 @@ class AlbumWidget(Gtk.EventBox):
self._set_composer_label(corealbum)
- self._album_model = self._corealbum.props.model
+ self._album_model = self._corealbum.props.disc_model
self._model_signal_id = self._album_model.connect_after(
"items-changed", self._on_model_items_changed)
self._disc_list_box.bind_model(self._album_model, self._create_widget)
diff --git a/gnomemusic/widgets/artistalbumwidget.py b/gnomemusic/widgets/artistalbumwidget.py
index 5993e7cb3..af21abed3 100644
--- a/gnomemusic/widgets/artistalbumwidget.py
+++ b/gnomemusic/widgets/artistalbumwidget.py
@@ -85,12 +85,12 @@ class ArtistAlbumWidget(Gtk.Box):
if self._cover_size_group:
self._cover_size_group.add_widget(self._art_stack)
- corealbum.props.model.connect_after(
+ corealbum.props.disc_model.connect_after(
"items-changed", self._on_model_items_changed)
self._disc_list_box.bind_model(
- corealbum.props.model, self._create_widget)
+ corealbum.props.disc_model, self._create_widget)
- corealbum.props.model.items_changed(0, 0, 0)
+ corealbum.props.disc_model.items_changed(0, 0, 0)
def _create_widget(self, disc):
disc_box = DiscBox(disc)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]