[gnome-music/wip/mschraal/playlists-fixes: 1/3] grltrackerplaylists: Restore smart playlists update
- From: Marinus Schraal <mschraal src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/mschraal/playlists-fixes: 1/3] grltrackerplaylists: Restore smart playlists update
- Date: Fri, 21 Feb 2020 11:24:39 +0000 (UTC)
commit 49d7300ba2992e0dde1e864d1d421bbdb72296b8
Author: Jean Felder <jfelder src gnome org>
Date: Tue Feb 18 14:29:10 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/widgets/playlistswidget.py | 11 +++++
4 files changed, 72 insertions(+)
---
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 37c8f230..4e76c346 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -68,6 +68,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 f63da4af..3aa09f2a 100644
--- a/gnomemusic/grilowrappers/grltrackerplaylists.py
+++ b/gnomemusic/grilowrappers/grltrackerplaylists.py
@@ -257,6 +257,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 """
@@ -729,6 +743,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 fb3568a4..0e3b559a 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -166,6 +166,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/widgets/playlistswidget.py b/gnomemusic/widgets/playlistswidget.py
index 216269ac..164e9a73 100644
--- a/gnomemusic/widgets/playlistswidget.py
+++ b/gnomemusic/widgets/playlistswidget.py
@@ -75,12 +75,17 @@ class PlaylistsWidget(Gtk.Box):
playlist_play_action = self._window.lookup_action("playlist_play")
playlist_play_action.connect("activate", self._on_play_playlist)
+ self._coremodel.connect(
+ "smart-playlist-change", self._on_smart_playlist_change)
+
def _on_current_playlist_changed(self, playlists_view, value):
"""Update view with content from selected playlist"""
playlist = self._playlists_view.props.current_playlist
self._songs_list.bind_model(
playlist.props.model, self._create_song_widget, playlist)
+ if playlist.props.is_smart:
+ playlist.update()
self._pl_ctrls.props.playlist = playlist
@@ -121,6 +126,12 @@ class PlaylistsWidget(Gtk.Box):
current_playlist = self._playlists_view.props.current_playlist
current_playlist.reorder(source_position, target_position)
+ def _on_smart_playlist_change(self, coremodel):
+ current_playlist = self._playlists_view.props.current_playlist
+ if (current_playlist is not None
+ and current_playlist.props.is_smart):
+ current_playlist.update()
+
@Gtk.Template.Callback()
def _songs_list_right_click(self, gesture, n_press, x, y):
requested_row = self._songs_list.get_row_at_y(y)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]