[gnome-music/wip/jfelder/expose-grilo-application-wide: 3/6] window: Propagate favorite status changes to all views



commit 5986c2463b99b8b56d1cf5dc1064fc46649f8768
Author: Jean Felder <jfelder src gnome org>
Date:   Fri May 3 14:08:30 2019 +0200

    window: Propagate favorite status changes to all views
    
    There are 4 differents views which allow to change the favorite status
    of a song:
    * AlbumsView via the AlbumWidget
    * SearchView
    * SongsView
    * PlaylistView
    
    Some of these views (AlbumWidget and SearchView) do not need to be
    refreshed because they are automatically updated when they are
    displayed. It means that only the SongsView and PlaylistView need to
    be refreshed a song favorite status changes.
    As media from the PlaylistView do not have the same id as the same
    media from an other view, two songs are considered as identical if
    they have the same song name and album name.
    
    Closes: #91

 gnomemusic/views/baseview.py     |  6 +-----
 gnomemusic/views/playlistview.py | 28 ++++++++++++++++++++++++++++
 gnomemusic/views/songsview.py    | 20 ++++++++++++++++++++
 gnomemusic/window.py             | 15 ++++++++++++++-
 4 files changed, 63 insertions(+), 6 deletions(-)
---
diff --git a/gnomemusic/views/baseview.py b/gnomemusic/views/baseview.py
index f694d2e2..be11d1bd 100644
--- a/gnomemusic/views/baseview.py
+++ b/gnomemusic/views/baseview.py
@@ -26,11 +26,8 @@ from gi.repository import GdkPixbuf, GObject, Gtk
 
 from gnomemusic import log
 from gnomemusic.grilo import grilo
-from gnomemusic.playlists import Playlists, StaticPlaylists
 from gnomemusic.widgets.starhandlerwidget import StarHandlerWidget
 
-playlists = Playlists.get_default()
-
 
 class BaseView(Gtk.Stack):
     """Base Class for all view classes"""
@@ -153,8 +150,7 @@ class BaseView(Gtk.Stack):
         Updates Favorites Playlist too.
         :param Grl.Media media: song to update
         """
-        grilo.toggle_favorite(media)
-        playlists.update_static_playlist(StaticPlaylists.Favorites)
+        self._window.refresh_views_favorite(self, media)
 
     @log
     def get_selected_songs(self, callback):
diff --git a/gnomemusic/views/playlistview.py b/gnomemusic/views/playlistview.py
index 1e6742ba..99a87eb0 100644
--- a/gnomemusic/views/playlistview.py
+++ b/gnomemusic/views/playlistview.py
@@ -783,3 +783,31 @@ class PlaylistView(BaseView):
         grilo.populate_playlists(
             self._offset, self._add_playlist_item, -1, data)
         self._init = True
+
+    @log
+    def refresh_favorite(self, media):
+        """Changes favorite icon of a song.
+
+        When an other view has changed the favorite status of a song,
+        this view needs to be refreshed.
+        If the visible playlist is the favorite one, it has already
+        been refreshed, so nothing needs to be done.
+
+        :param Grl.media media: song whose favorite status changed
+        """
+        static_playlist_id = StaticPlaylists.Favorites.ID
+        if (self._current_playlist is None
+                or self._current_playlist.get_id() == static_playlist_id):
+            return
+
+        # It is impossible to use the media ids because the media from
+        # the PlaylistView do not have the same ids as the ones from the
+        # other views.
+        # The same song can be present several times in a playlist. So,
+        # the loop cannot be exited.
+        media_title = utils.get_media_title(media)
+        media_album = utils.get_album_title(media)
+        for row in self.model:
+            if (utils.get_media_title(row[5]) == media_title
+                    and utils.get_album_title(row[5]) == media_album):
+                row[9] = not row[9]
diff --git a/gnomemusic/views/songsview.py b/gnomemusic/views/songsview.py
index 32a8f46d..90029a0f 100644
--- a/gnomemusic/views/songsview.py
+++ b/gnomemusic/views/songsview.py
@@ -295,3 +295,23 @@ class SongsView(BaseView):
         if not callback:
             return selected_songs
         callback(selected_songs)
+
+    @log
+    def refresh_favorite(self, media):
+        """Changes favorite icon of a song.
+
+        When an other view has changed the favorite status of a song,
+        this view needs to be refreshed.
+
+        :param Grl.media media: song whose favorite status changed
+        """
+        # It is impossible to use the media ids because the media from
+        # the PlaylistView do not have the same ids as the ones from the
+        # other views.
+        media_title = utils.get_media_title(media)
+        media_album = utils.get_album_title(media)
+        for row in self.model:
+            if (utils.get_media_title(row[5]) == media_title
+                    and utils.get_album_title(row[5]) == media_album):
+                row[9] = not row[9]
+                break
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 6af945ee..095ed094 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -36,7 +36,7 @@ from gnomemusic import log
 from gnomemusic.grilo import grilo
 from gnomemusic.mediakeys import MediaKeys
 from gnomemusic.player import RepeatMode
-from gnomemusic.playlists import Playlists
+from gnomemusic.playlists import Playlists, StaticPlaylists
 from gnomemusic.query import Query
 from gnomemusic.search import Search
 from gnomemusic.utils import View
@@ -521,3 +521,16 @@ class Window(Gtk.ApplicationWindow):
         :param bool visible: actionbar visibility
         """
         self._player_toolbar.set_visible(visible)
+
+    @log
+    def refresh_views_favorite(self, visible_view, media):
+        grilo.toggle_favorite(media)
+        playlists.update_static_playlist(StaticPlaylists.Favorites)
+
+        # FIXME: the refresh should be triggered by listening to the
+        # relevant tracker event.
+        # refresh the main views if necessary
+        list_views = [self.views[View.SONG], self.views[View.PLAYLIST]]
+        for view in list_views:
+            if view != visible_view:
+                view.refresh_favorite(media)


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