[gnome-music/wip/jfelder/core-mpris-playlists] mpris: Port playlists part to to the new model



commit 3e5d853e9096e0e4eb10155e631d6bd701585883
Author: Jean Felder <jfelder src gnome org>
Date:   Mon Jul 15 09:02:14 2019 +0200

    mpris: Port playlists part to to the new model

 gnomemusic/coremodel.py                         | 12 ++++++++
 gnomemusic/grilowrappers/grltrackerplaylists.py |  5 +++
 gnomemusic/mpris.py                             | 41 +++++++++++++++----------
 gnomemusic/views/playlistsview.py               | 38 +++++++++++++++++++++++
 4 files changed, 80 insertions(+), 16 deletions(-)
---
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 5cf842f2..6be3097c 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -32,6 +32,8 @@ from gnomemusic.widgets.songwidget import SongWidget
 class CoreModel(GObject.GObject):
 
     __gsignals__ = {
+        "activate-playlist": (
+            GObject.SignalFlags.RUN_FIRST, None, (Playlist,)),
         "artists-loaded": (GObject.SignalFlags.RUN_FIRST, None, ()),
         "playlist-loaded": (GObject.SignalFlags.RUN_FIRST, None, ()),
         "playlists-loaded": (GObject.SignalFlags.RUN_FIRST, None, ()),
@@ -295,6 +297,16 @@ class CoreModel(GObject.GObject):
         """
         self._grilo.create_playlist(playlist_title, callback)
 
+    def activate_playlist(self, playlist):
+        """Activates a playlist.
+
+        Selects the playlist and start playing.
+
+        :param Playlist playlist: playlist to activate
+        """
+        # FIXME: just a proxy
+        self.emit("activate-playlist", playlist)
+
     def search(self, text):
         self._grilo.search(text)
 
diff --git a/gnomemusic/grilowrappers/grltrackerplaylists.py b/gnomemusic/grilowrappers/grltrackerplaylists.py
index a1058e4f..16b39642 100644
--- a/gnomemusic/grilowrappers/grltrackerplaylists.py
+++ b/gnomemusic/grilowrappers/grltrackerplaylists.py
@@ -210,6 +210,10 @@ class GrlTrackerPlaylists(GObject.GObject):
 class Playlist(GObject.GObject):
     """ Base class of all playlists """
 
+    __gsignals__ = {
+        "playlist-loaded": (GObject.SignalFlags.RUN_FIRST, None, ()),
+    }
+
     METADATA_KEYS = [
         Grl.METADATA_KEY_ALBUM,
         Grl.METADATA_KEY_ALBUM_ARTIST,
@@ -320,6 +324,7 @@ class Playlist(GObject.GObject):
                 source, op_id, media, remaining, user_data, error):
             if not media:
                 self.props.count = self._model.get_n_items()
+                self.emit("playlist-loaded")
                 return
 
             coresong = CoreSong(media, self._coreselection, self._grilo)
diff --git a/gnomemusic/mpris.py b/gnomemusic/mpris.py
index 086973df..5c31a2df 100644
--- a/gnomemusic/mpris.py
+++ b/gnomemusic/mpris.py
@@ -32,7 +32,6 @@ from gnomemusic import log
 from gnomemusic.albumartcache import lookup_art_file_from_cache
 from gnomemusic.gstplayer import Playback
 from gnomemusic.player import PlayerPlaylist, RepeatMode
-from gnomemusic.playlists import Playlists
 
 logger = logging.getLogger(__name__)
 
@@ -293,12 +292,12 @@ class MPRIS(DBusInterface):
         self._player.connect(
             'playlist-changed', self._on_player_playlist_changed)
 
-        self._player_model = app.props.coremodel.props.playlist_sort
+        self._coremodel = app.props.coremodel
+        self._player_model = self._coremodel.props.playlist_sort
 
-        self._playlists = Playlists.get_default()
-        self._playlists_model = None
-        self._playlists.connect('playlist-renamed', self._on_playlist_renamed)
-        self._playlists.connect("notify::ready", self._on_playlists_loading)
+        self._playlists_model = self._coremodel.props.playlists_sort
+        self._playlists_loaded_id = self._coremodel.connect(
+            "playlists-loaded", self._on_playlists_loaded)
 
         self._player_previous_type = None
         self._path_list = []
@@ -310,6 +309,7 @@ class MPRIS(DBusInterface):
         self._previous_loop_status = ""
         self._previous_mpris_playlist = self._get_active_playlist()
         self._previous_playback_status = "Stopped"
+        self._previous_playlist_count = 0
 
     @log
     def _get_playback_status(self):
@@ -470,8 +470,9 @@ class MPRIS(DBusInterface):
         :return: a D-Bus id to uniquely identify the playlist
         :rtype: str
         """
+        # Smart Playlists do not have an id
         if playlist:
-            pl_id = playlist.props.pl_id
+            pl_id = playlist.props.pl_id or playlist.props.tag_text
         else:
             pl_id = "Invalid"
 
@@ -587,26 +588,34 @@ class MPRIS(DBusInterface):
         self._properties_changed(
             MPRIS.MEDIA_PLAYER2_PLAYLISTS_IFACE, properties, [])
 
-    def _on_playlists_loading(self, klass, param):
-        if not self._playlists.props.ready:
-            return
+    def _on_playlists_loaded(self, klass):
+        self._coremodel.disconnect(self._playlists_loaded_id)
+        for playlist in self._playlists_model:
+            playlist.connect("notify::title", self._on_playlist_renamed)
 
-        self._playlists_model = self._playlists.get_playlists_model()
         self._playlists_model.connect(
             "items-changed", self._on_playlists_count_changed)
         self._on_playlists_count_changed(None, None, 0, 0)
 
     @log
-    def _on_playlists_count_changed(self, klass, position, removed, added):
+    def _on_playlists_count_changed(self, model, position, removed, added):
         playlist_count = self._playlists_model.get_n_items()
+        if playlist_count == self._previous_playlist_count:
+            return
+
+        self._previous_playlist_count = playlist_count
         properties = {"PlaylistCount": GLib.Variant("u", playlist_count)}
         self._properties_changed(
             MPRIS.MEDIA_PLAYER2_PLAYLISTS_IFACE, properties, [])
 
+        if added == 0:
+            return
+
+        model[position].connect("notify::title", self._on_playlist_renamed)
+
     @log
-    def _on_playlist_renamed(self, playlists, renamed_playlist):
-        mpris_playlist = self._get_mpris_playlist_from_playlist(
-            renamed_playlist)
+    def _on_playlist_renamed(self, playlist, param):
+        mpris_playlist = self._get_mpris_playlist_from_playlist(playlist)
         self._dbus_emit_signal('PlaylistChanged', {'Playlist': mpris_playlist})
 
     def _raise(self):
@@ -753,7 +762,7 @@ class MPRIS(DBusInterface):
                 break
 
         if selected_playlist is not None:
-            self._playlists.activate_playlist(selected_playlist)
+            self._coremodel.activate_playlist(selected_playlist)
 
     def _get_playlists(self, index, max_count, order, reverse):
         """Gets a set of playlists (MPRIS Method).
diff --git a/gnomemusic/views/playlistsview.py b/gnomemusic/views/playlistsview.py
index bd2f598a..ec38ae98 100644
--- a/gnomemusic/views/playlistsview.py
+++ b/gnomemusic/views/playlistsview.py
@@ -112,6 +112,8 @@ class PlaylistsView(BaseView):
 
         self._loaded_id = self._coremodel.connect(
             "playlists-loaded", self._on_playlists_loaded)
+        self._coremodel.connect(
+            "activate-playlist", self._on_playlist_activation_request)
 
         self.show_all()
 
@@ -219,6 +221,42 @@ class PlaylistsView(BaseView):
         self._playlist_rename_action.set_enabled(not playlist.props.is_smart)
         self._playlist_delete_action.set_enabled(not playlist.props.is_smart)
 
+    def _on_playlist_activation_request(self, klass, playlist):
+        """Selects and starts playing a playlist.
+
+        If the view has not been populated yet, populate it and then
+        select the requested playlist. Otherwise, directly select the
+        requested playlist and start playing.
+
+        :param CoreModel klass: Main CorexModel
+        :param Playlist playlist: requested playlist
+        """
+        def _on_playlist_loaded(playlist):
+            playlist.disconnect(playlist_ready_id)
+            self._song_activated(None)
+
+        playlist_row = None
+        for row in self._sidebar:
+            if row.props.playlist == playlist:
+                playlist_row = row
+                break
+
+        if not playlist_row:
+            return
+
+        selection = self._sidebar.get_selected_row()
+        if selection.get_index() == playlist_row.get_index():
+            self._song_activated(None)
+            return
+
+        self._sidebar.select_row(row)
+        row.emit('activate')
+        if playlist.props.model.get_n_items() > 0:
+            self._song_activated(None)
+        else:
+            playlist_ready_id = playlist.connect(
+                "playlist-loaded", _on_playlist_loaded)
+
     def _create_song_widget(self, coresong, playlist):
         can_dnd = not playlist.props.is_smart
         song_widget = SongWidget(coresong, can_dnd, True)


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