[gnome-music/playlists: 2/2] implement playlist view



commit 4411477b1930fb8bf0910e666c6d4c28b1c3080c
Author: Eslam Mostafa <me eslammostafa com>
Date:   Fri Jun 28 01:16:42 2013 +0200

    implement playlist view

 src/grilo.js   |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 src/view.js    |   29 +++++++++++++++++++++++++----
 src/widgets.js |    6 ++++++
 3 files changed, 75 insertions(+), 6 deletions(-)
---
diff --git a/src/grilo.js b/src/grilo.js
index 4128f03..56d9692 100644
--- a/src/grilo.js
+++ b/src/grilo.js
@@ -18,6 +18,7 @@
  *
  */
 
+const GLib = imports.gi.GLib;
 const Grl = imports.gi.Grl;
 const Lang = imports.lang;
 const Signals = imports.signals;
@@ -30,12 +31,17 @@ const Grilo = new Lang.Class({
     Name: 'Grilo',
 
     _init: function() {
+        this.playlistPath = GLib.build_filenamev([GLib.get_user_data_dir(), "gnome-music", "playlists"]);
+        if (!GLib.file_test(this.playlistPath, GLib.FileTest.IS_DIR))
+            GLib.mkdir_with_parents(this.playlistPath, parseInt("0755", 8));
+
         this.registry = Grl.Registry.get_default ();
         this.registry.load_all_plugins();
 
         let sources = {};
         this.sources = sources;
         this.tracker = null;
+        this.filesystem = this.registry.lookup_source("grl-filesystem");
 
         this.registry.connect ("source_added",
             Lang.bind(this, this._onSourceAdded));
@@ -77,6 +83,26 @@ const Grilo = new Lang.Class({
         this.populateItems (Query.songs, offset, callback)
     },
 
+    populatePlaylists: function (offset, callback, count=50) {
+        if (!GLib.file_test(this.playlistPath, GLib.FileTest.IS_DIR))
+            return;
+        var options = Grl.OperationOptions.new(null);
+        options.set_flags(Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
+        options.set_skip(offset);
+        options.set_count(count);
+        grilo.filesystem.get_media_from_uri(
+            GLib.filename_to_uri(this.playlistPath, null),
+            [Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_URL, Grl.METADATA_KEY_MIME],
+            options,
+            Lang.bind(this, function(source, id, media) {
+                grilo.filesystem.browse(
+                    media,
+                    [Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_URL, Grl.METADATA_KEY_MIME],
+                    options,
+                    Lang.bind(this, callback, null));
+            }));
+    },
+
     populateItems: function (query, offset, callback, count=50) {
         var options = Grl.OperationOptions.new(null);
         options.set_flags (Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
@@ -84,7 +110,7 @@ const Grilo = new Lang.Class({
         options.set_count(count);
         grilo.tracker.query(
             query,
-                [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST, 
Grl.METADATA_KEY_ALBUM, Grl.METADATA_KEY_DURATION, Grl.METADATA_KEY_THUMBNAIL, 
Grl.METADATA_KEY_CREATION_DATE],
+                [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST, 
Grl.METADATA_KEY_CREATION_DATE],
                 options,
                 Lang.bind(this, callback, null));
     },
@@ -95,11 +121,27 @@ const Grilo = new Lang.Class({
         options.set_flags (Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
         grilo.tracker.query(
             query,
-                [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST, 
Grl.METADATA_KEY_ALBUM, Grl.METADATA_KEY_DURATION, Grl.METADATA_KEY_THUMBNAIL, 
Grl.METADATA_KEY_CREATION_DATE],
+                [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST, 
Grl.METADATA_KEY_CREATION_DATE],
                 options,
                 Lang.bind(this, callback, null));
     },
 
+    getPlaylistSongs: function (playlist_url, callback) {
+        var options = Grl.OperationOptions.new(null);
+        options.set_flags(Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
+        grilo.filesystem.get_media_from_uri(
+            playlist_url,
+            [Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_URL, Grl.METADATA_KEY_MIME],
+            options,
+            Lang.bind(this, function(source, id, media) {
+                grilo.filesystem.browse(
+                    media,
+                    [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST, 
Grl.METADATA_KEY_ALBUM, Grl.METADATA_KEY_CREATION_DATE, Grl.METADATA_KEY_DURATION],
+                    options,
+                    Lang.bind(this, callback, null));
+            }));
+    },
+
     _searchCallback: function search_cb () {
         log ("yeah");
     },
diff --git a/src/view.js b/src/view.js
index 9ede6a8..5b7a616 100644
--- a/src/view.js
+++ b/src/view.js
@@ -477,18 +477,23 @@ const Playlists = new Lang.Class({
     _init: function(header_bar, player) {
         this.parent("Playlists", header_bar, true);
         this.player= player;
+        this._playlists = [];
         this.view.set_view_type(Gd.MainViewType.LIST);
         this.view.set_hexpand(false);
         this.view.get_style_context().add_class("artist-panel");
         this.view.get_generic_view().get_selection().set_mode(Gtk.SelectionMode.SINGLE);
         this._songsListWidget = new Widgets.SongsList(this.player);
-        /*let builder = new Gtk.Builder();
+        let builder = new Gtk.Builder();
         builder.add_from_resource('/org/gnome/music/PlaylistControls.ui');
-        let controls = builder.get_object('container');*/
+        let controls = builder.get_object('container');
+        builder.add_from_resource('/org/gnome/music/PlaylistSongs.ui');
+        let songsFrame = builder.get_object('container');
+        let viewport = builder.get_object('viewport');
+        viewport.add(this._songsListWidget);
         this._grid.attach(new Gtk.Separator(), 0, 1, 1, 1);
         //this._grid.attach(controls, 0, 2, 1, 1);
         this._grid.attach(new Gtk.Separator({orientation: Gtk.Orientation.VERTICAL}), 1, 0, 1, 3);
-        this._grid.attach(this._songsListWidget, 2, 0, 2, 3);
+        this._grid.attach(songsFrame, 2, 0, 2, 3);
         this._addListRenderers();
         if(Gtk.Settings.get_default().gtk_application_prefer_dark_theme) {
             this.view.get_generic_view().get_style_context().add_class("artist-panel-dark");
@@ -539,7 +544,8 @@ const Playlists = new Lang.Class({
         var url = item.get_string(Grl.METADATA_KEY_URL)
         if (this._playlists[playlist.toLowerCase()] == undefined) {
             var iter = this._model.append();
-            this._playlists[playlist.toLowerCase()] = {"iter": iter, "url": url}
+            this._playlists[playlist.toLowerCase()] = {"iter": iter, "url": url, "songs": {}}
+            this.populatePlaylistSongs(playlist);
             this._model.set(
                 iter,
                 [0, 1, 2, 3],
@@ -553,4 +559,19 @@ const Playlists = new Lang.Class({
             grilo.populatePlaylists(this._offset, Lang.bind(this, this._addItem, null));
         }
     },
+
+    populatePlaylistSongs: function(playlist) {
+        if(grilo.filesystem != null) {
+            grilo.getPlaylistSongs(this._playlists[playlist.toLowerCase()]['url'], Lang.bind(this, 
+            function(source, param, item){
+                this._offset += 1;
+                if (item == null)
+                    return;
+                if ((item.get_title() == null) && (item.get_url() != null)) {
+                    song.set_title (extractFileName(item.get_url()));
+                }
+                this._playlists[playlist.toLowerCase()]['songs'].append(songs);
+            }, null));
+        }
+    }
 });
diff --git a/src/widgets.js b/src/widgets.js
index 1806b43..2c86766 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -662,6 +662,12 @@ const SongsList = new Lang.Class({
         this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
     },
 
+    update: function(title, playlist) {
+        this.playlist = playlist;
+        this._model.clear();
+        this.show_all();
+    },
+
     updateModel: function(player, playlist, currentIter){
         if (playlist != this._model){
             return false;}


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