[gnome-music/wip/jfelder/3-34-playlist-update] grltrackerplaylists: Restore smart playlists update
- From: Jean Felder <jfelder src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/jfelder/3-34-playlist-update] grltrackerplaylists: Restore smart playlists update
- Date: Sat, 28 Mar 2020 20:25:08 +0000 (UTC)
commit 750ab91e0591a89fb0a9fea6ac17848848f2232a
Author: Jean Felder <jfelder src gnome org>
Date: Sat Mar 28 21:24:24 2020 +0100
grltrackerplaylists: Restore smart playlists update
This feature was lost during the core rewrite.
Everytime a change is triggered, two smart playlists might need to be
updated:
* the PlayerPlaylist (active_playlist)
* the currently actively viewed playlist
Besides, a smart playlist needs to be updated every time it becomes
visible.
An update method is introduced to update a smart playlist content. The
model of the SmartPlaylist is queried and compared with the previous
one to perform the correct insert and remove operations.
gnomemusic/coremodel.py | 1 +
gnomemusic/grilowrappers/grltrackerplaylists.py | 59 +++++++++++++++++++++++++
gnomemusic/grilowrappers/grltrackerwrapper.py | 1 +
gnomemusic/views/playlistsview.py | 12 +++++
4 files changed, 73 insertions(+)
---
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 09d5ac78..6188e03a 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -67,6 +67,7 @@ class CoreModel(GObject.GObject):
__gsignals__ = {
"artists-loaded": (GObject.SignalFlags.RUN_FIRST, None, ()),
"playlist-loaded": (GObject.SignalFlags.RUN_FIRST, None, (int,)),
+ "smart-playlist-change": (GObject.SignalFlags.RUN_FIRST, None, ())
}
active_playlist = GObject.Property(type=Playlist, default=None)
diff --git a/gnomemusic/grilowrappers/grltrackerplaylists.py b/gnomemusic/grilowrappers/grltrackerplaylists.py
index ec5072bd..51911acc 100644
--- a/gnomemusic/grilowrappers/grltrackerplaylists.py
+++ b/gnomemusic/grilowrappers/grltrackerplaylists.py
@@ -255,6 +255,20 @@ class GrlTrackerPlaylists(GObject.GObject):
self._tracker.update_blank_async(
query, GLib.PRIORITY_LOW, None, _create_cb, None)
+ def check_smart_playlist_change(self):
+ """Check if smart playlists need to be updated.
+
+ A smart playlist needs to be updated in two cases:
+ * it is being played (active_playlist)
+ * it is visible in PlaylistsView
+ """
+ active_playlist = self._coremodel.props.active_playlist
+ if (active_playlist is not None
+ and active_playlist.props.is_smart is True):
+ active_playlist.update()
+ else:
+ self._coremodel.emit("smart-playlist-change")
+
class Playlist(GObject.GObject):
""" Base class of all playlists """
@@ -711,6 +725,51 @@ class SmartPlaylist(Playlist):
return self._model
+ def update(self):
+ """Updates playlist model."""
+ if self._model is None:
+ return
+
+ new_model_medias = []
+
+ def _fill_new_model(source, op_id, media, remaining, error):
+ if error:
+ return
+
+ if not media:
+ self._finish_update(new_model_medias)
+ return
+
+ new_model_medias.append(media)
+
+ options = self._fast_options.copy()
+ self._source.query(
+ self.props.query, self.METADATA_KEYS, options, _fill_new_model)
+
+ def _finish_update(self, new_model_medias):
+ if not new_model_medias:
+ self._model.remove_all()
+ return
+
+ current_models_ids = [coresong.props.media.get_id()
+ for coresong in self._model]
+ new_model_ids = [media.get_id() for media in new_model_medias]
+
+ idx_to_delete = []
+ for idx, media_id in enumerate(current_models_ids):
+ if media_id not in new_model_ids:
+ idx_to_delete.insert(0, idx)
+
+ for idx in idx_to_delete:
+ self._model.remove(idx)
+ self.props.count -= 1
+
+ for idx, media in enumerate(new_model_medias):
+ if media.get_id() not in current_models_ids:
+ coresong = CoreSong(media, self._coreselection, self._grilo)
+ self._model.append(coresong)
+ self.props.count += 1
+
class MostPlayed(SmartPlaylist):
"""Most Played smart playlist"""
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index 1bfabe00..385804ae 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -164,6 +164,7 @@ class GrlTrackerWrapper(GObject.GObject):
self._check_album_change()
self._check_artist_change()
+ self._tracker_playlists.check_smart_playlist_change()
self._batch_changed_media_ids = {}
self._content_changed_timeout = None
diff --git a/gnomemusic/views/playlistsview.py b/gnomemusic/views/playlistsview.py
index 6c6be6f5..0b831f09 100644
--- a/gnomemusic/views/playlistsview.py
+++ b/gnomemusic/views/playlistsview.py
@@ -115,6 +115,9 @@ class PlaylistsView(BaseView):
self._active_playlist_id = self._coremodel.connect(
"notify::active-playlist", self._on_active_playlist_changed)
+ self._coremodel.connect(
+ "smart-playlist-change", self._on_smart_playlist_change)
+
self._model.connect("items-changed", self._on_playlists_model_changed)
self._on_playlists_model_changed(self._model, 0, 0, 0)
@@ -171,6 +174,13 @@ class PlaylistsView(BaseView):
self._sidebar.select_row(row_next)
self._on_playlist_activated(self._sidebar, row_next, True)
+ def _on_smart_playlist_change(self, coremodel):
+ selection = self._sidebar.get_selected_row()
+ current_playlist = selection.props.playlist
+ if (current_playlist is not None
+ and current_playlist.props.is_smart):
+ current_playlist.update()
+
@log
def _on_view_right_clicked(self, gesture, n_press, x, y):
requested_row = self._view.get_row_at_y(y)
@@ -234,6 +244,8 @@ class PlaylistsView(BaseView):
self._view.bind_model(
playlist.props.model, self._create_song_widget, playlist)
+ if playlist.props.is_smart:
+ playlist.update()
self._pl_ctrls.props.playlist = playlist
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]