[gnome-music/error] Add error symbol nearby the tracks, which cannot be played due to missing codecs.
- From: Vadim Rutkovsky <vrutkovsky src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/error] Add error symbol nearby the tracks, which cannot be played due to missing codecs.
- Date: Fri, 17 May 2013 11:23:05 +0000 (UTC)
commit 9f858bafe414b76eff50ebd2c6639b10c2db9fd7
Author: Vadim Rutkovsky <vrutkovs redhat com>
Date: Fri May 17 13:22:49 2013 +0200
Add error symbol nearby the tracks, which cannot be played due to missing codecs.
Also implements now playing icon status for Songs view
https://bugzilla.gnome.org/show_bug.cgi?id=699762
data/AlbumWidget.ui | 4 +-
data/ArtistAlbumWidget.ui | 4 +-
data/application.css | 5 --
src/player.js | 3 +-
src/view.js | 55 ++++++++++++++++++++---
src/widgets.js | 107 ++++++++++++++++++++++++++-------------------
6 files changed, 115 insertions(+), 63 deletions(-)
---
diff --git a/data/AlbumWidget.ui b/data/AlbumWidget.ui
index b11333c..5573fc0 100644
--- a/data/AlbumWidget.ui
+++ b/data/AlbumWidget.ui
@@ -218,8 +218,8 @@
<column type="gchararray"/>
<!-- column-name gboolean1 -->
<column type="gboolean"/>
- <!-- column-name GdkPixbuf1 -->
- <column type="GdkPixbuf"/>
+ <!-- column-name gchararray4 -->
+ <column type="gchararray"/>
<!-- column-name GObject1 -->
<column type="GObject"/>
<!-- column-name gboolean2 -->
diff --git a/data/ArtistAlbumWidget.ui b/data/ArtistAlbumWidget.ui
index cf84412..f6c4115 100644
--- a/data/ArtistAlbumWidget.ui
+++ b/data/ArtistAlbumWidget.ui
@@ -126,8 +126,8 @@
<column type="gchararray"/>
<!-- column-name gboolean1 -->
<column type="gboolean"/>
- <!-- column-name GdkPixbuf1 -->
- <column type="GdkPixbuf"/>
+ <!-- column-name gchararray4 -->
+ <column type="gchararray"/>
<!-- column-name GObject1 -->
<column type="GObject"/>
<!-- column-name gboolean2 -->
diff --git a/data/application.css b/data/application.css
index dc16ea0..107fbca 100644
--- a/data/application.css
+++ b/data/application.css
@@ -26,11 +26,6 @@
}
.songs-list {
- border-width: 0 0 0 1px;
- border-style: solid;
- border-color: shade(@borders, 0.90);
- padding: 0 1px;
-
box-shadow: inset 0 -1px shade(@borders, 1.30);
background-color: @theme_bg_color;
}
diff --git a/src/player.js b/src/player.js
index 552eaa6..0715fd5 100644
--- a/src/player.js
+++ b/src/player.js
@@ -24,10 +24,10 @@ const Lang = imports.lang;
const Gtk = imports.gi.Gtk;
const Gd = imports.gi.Gd;
const Gst = imports.gi.Gst;
+const GstPbutils = imports.gi.GstPbutils;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Grl = imports.gi.Grl;
-const GdkPixbug = imports.gi.GdkPixbuf;
const Signals = imports.signals;
const Gdk = imports.gi.Gdk;
@@ -58,6 +58,7 @@ const Player = new Lang.Class({
this.cache = AlbumArtCache.AlbumArtCache.getDefault();
Gst.init(null, 0);
+ this.discoverer = new GstPbutils.Discoverer();
this.player = Gst.ElementFactory.make("playbin", "player");
this.bus = this.player.get_bus();
this.bus.add_signal_watch();
diff --git a/src/view.js b/src/view.js
index 8085651..08a0781 100644
--- a/src/view.js
+++ b/src/view.js
@@ -41,6 +41,9 @@ const AlbumArtCache = imports.albumArtCache;
const Grilo = imports.grilo;
const albumArtCache = AlbumArtCache.AlbumArtCache.getDefault();
+const nowPlayingIconName = 'media-playback-start-symbolic';
+const errorIconName = 'dialog-error-symbolic';
+
function extractFileName(uri) {
var exp = /^.*[\\\/]|[.][^.]*$/g;
return unescape(uri.replace(exp, ''));
@@ -122,7 +125,8 @@ const ViewContainer = new Lang.Class({
GObject.TYPE_STRING,
GdkPixbuf.Pixbuf,
GObject.TYPE_OBJECT,
- GObject.TYPE_BOOLEAN
+ GObject.TYPE_BOOLEAN,
+ GObject.TYPE_STRING,
]);
this.view = new Gd.MainView({
shadow_type: Gtk.ShadowType.NONE
@@ -223,11 +227,22 @@ const ViewContainer = new Lang.Class({
if ((item.get_title() == null) && (item.get_url() != null)) {
item.set_title (extractFileName(item.get_url()));
}
- this._model.set(
- iter,
- [0, 1, 2, 3, 4, 5],
- [toString(item.get_id()), "", item.get_title(), artist, this._symbolicIcon, item]
- );
+ try{
+ if (item.get_url())
+ this.player.discoverer.discover_uri(item.get_url());
+ this._model.set(
+ iter,
+ [0, 1, 2, 3, 4, 5, 6, 7],
+ [toString(item.get_id()), "", item.get_title(), artist, this._symbolicIcon, item,
false, nowPlayingIconName]
+ );
+ } catch(err) {
+ log("failed to discover url " + item.get_url());
+ this._model.set(
+ iter,
+ [0, 1, 2, 3, 4, 5, 6, 7],
+ [toString(item.get_id()), "", item.get_title(), artist, this._symbolicIcon, item,
true, errorIconName]
+ );
+ }
GLib.idle_add(300, Lang.bind(this, this._updateAlbumArt, item, iter));
}
},
@@ -357,11 +372,26 @@ const Songs = new Lang.Class({
this._symbolicIcon = albumArtCache.makeDefaultIcon(this._iconHeight, this._iconWidth)
this._addListRenderers();
this.player = player;
+ this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
},
_onItemActivated: function (widget, id, path) {
- this.player.setPlaylist("Songs", null, this._model, this._model.get_iter(path)[1], 5);
- this.player.setPlaying(true);
+ var iter = this._model.get_iter(path)[1]
+ if (this._model.get_value(iter, 4) != errorIconName) {
+ this.player.setPlaylist("Songs", null, this._model, iter, 5);
+ this.player.setPlaying(true);
+ }
+ },
+
+ updateModel: function(player, playlist, currentIter){
+ if (playlist != this._model){
+ return false;}
+ if (this.iterToClean){
+ this._model.set_value(this.iterToClean, 6, false);
+ }
+ this._model.set_value(currentIter, 6, true);
+ this.iterToClean = currentIter.copy();
+ return false;
},
_addItem: function(source, param, item) {
@@ -371,6 +401,15 @@ const Songs = new Lang.Class({
_addListRenderers: function() {
let listWidget = this.view.get_generic_view();
+ let nowPlayingSymbolRenderer = new Gtk.CellRendererPixbuf({ xpad: 0 });
+ var columnNowPlaying = new Gtk.TreeViewColumn();
+ nowPlayingSymbolRenderer.set_property("xalign", 1.0);
+ columnNowPlaying.pack_start(nowPlayingSymbolRenderer, false)
+ columnNowPlaying.set_property('fixed-width', 24)
+ columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "visible", 6);
+ columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "icon_name", 4);
+ listWidget.insert_column(columnNowPlaying, 0)
+
let typeRenderer =
new Gd.StyledTextRenderer({ xpad: 0 });
typeRenderer.add_class('dim-label');
diff --git a/src/widgets.js b/src/widgets.js
index 083f97d..4075424 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -21,7 +21,6 @@
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
const Gd = imports.gi.Gd;
-const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
@@ -35,9 +34,8 @@ const grilo = Grilo.grilo;
const AlbumArtCache = imports.albumArtCache;
const albumArtCache = AlbumArtCache.AlbumArtCache.getDefault();
-const nowPlayingPixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
- "/usr/share/icons/gnome/scalable/actions/media-playback-start-symbolic.svg",
- -1, 16, true);
+const nowPlayingIconName = 'media-playback-start-symbolic';
+const errorIconName = 'dialog-error-symbolic';
const AlbumWidget = new Lang.Class({
Name: "AlbumWidget",
@@ -59,15 +57,18 @@ const AlbumWidget = new Lang.Class({
this.album=null;
this.view.connect('item-activated', Lang.bind(this,
function(widget, id, path) {
- this.player.stop();
- if (this.iterToClean && this.player.playlistId == this.album){
- let item = this.model.get_value(this.iterToClean, 5);
- this.model.set_value(this.iterToClean, 0, item.get_title());
- // Hide now playing icon
- this.model.set_value(this.iterToClean, 3, false);
+ let iter = this.model.get_iter(path)[1];
+ if (this.model.get_value(iter, 4) != errorIconName) {
+ this.player.stop();
+ if (this.iterToClean && this.player.playlistId == this.album){
+ let item = this.model.get_value(this.iterToClean, 5);
+ this.model.set_value(this.iterToClean, 0, item.get_title());
+ // Hide now playing icon
+ this.model.set_value(this.iterToClean, 3, false);
+ }
+ this.player.setPlaylist("Album", this.album, this.model, iter, 5);
+ this.player.setPlaying(true);
}
- this.player.setPlaylist("Album", this.album, this.model, this.model.get_iter(path)[1], 5);
- this.player.setPlaying(true);
})
);
@@ -99,15 +100,15 @@ const AlbumWidget = new Lang.Class({
cells[1].visible = false
let nowPlayingSymbolRenderer = new Gtk.CellRendererPixbuf({ xpad: 0 });
- nowPlayingSymbolRenderer.pixbuf = nowPlayingPixbuf;
var columnNowPlaying = new Gtk.TreeViewColumn();
nowPlayingSymbolRenderer.set_property("xalign", 1.0);
nowPlayingSymbolRenderer.set_property("yalign", 0.6);
- columnNowPlaying.pack_start(nowPlayingSymbolRenderer, false)
- columnNowPlaying.set_property('fixed-width', 24)
+ columnNowPlaying.pack_start(nowPlayingSymbolRenderer, false);
+ columnNowPlaying.set_property('fixed-width', 24);
columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "visible", 3);
- listWidget.insert_column(columnNowPlaying, 0)
+ columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "icon_name", 4);
+ listWidget.insert_column(columnNowPlaying, 0);
let typeRenderer =
new Gd.StyledTextRenderer({ xpad: 16 });
@@ -120,8 +121,7 @@ const AlbumWidget = new Lang.Class({
cols[0].clear_attributes(typeRenderer);
cols[0].add_attribute(typeRenderer, "markup", 0);
- let durationRenderer =
- new Gd.StyledTextRenderer({ xpad: 16 });
+ let durationRenderer = new Gd.StyledTextRenderer({ xpad: 16 });
durationRenderer.add_class('dim-label');
durationRenderer.set_property("ellipsize", 3);
durationRenderer.set_property("xalign", 1.0);
@@ -134,6 +134,7 @@ const AlbumWidget = new Lang.Class({
durationRenderer.text = this.player.secondsToString(duration);
}));
},
+
update: function (artist, album, item) {
let released_date = item.get_publication_date();
if (released_date != null) {
@@ -149,29 +150,28 @@ const AlbumWidget = new Lang.Class({
this.model = cachedPlaylist;
this.updateModel(this.player, cachedPlaylist, this.player.currentTrack);
} else {
- this.model = Gtk.ListStore.new([
- GObject.TYPE_STRING, /*title*/
- GObject.TYPE_STRING,
- GObject.TYPE_STRING,
- GObject.TYPE_BOOLEAN,/*icon shown*/
- GdkPixbuf.Pixbuf, /*icon*/
- GObject.TYPE_OBJECT, /*song object*/
- GObject.TYPE_BOOLEAN
- ]);
var tracks = [];
grilo.getAlbumSongs(item.get_id(), Lang.bind(this, function (source, prefs, track) {
if (track != null) {
tracks.push(track);
duration = duration + track.get_duration();
let iter = this.model.append();
- let path = "/usr/share/icons/gnome/scalable/actions/media-playback-start-symbolic.svg";
- let pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, -1, 16, true);
- let escapedTitle = GLib.markup_escape_text(track.get_title(), -1);
- this.model.set(iter,
- [0, 1, 2, 3, 4, 5],
- [ escapedTitle, "", "", false, nowPlayingPixbuf, track ]);
+ let escapedTitle = GLib.markup_escape_text(track.get_title(), track.get_title().length);
+ try{
+ this.player.discoverer.discover_uri(track.get_url());
+ this.model.set(iter,
+ [0, 1, 2, 3, 4, 5],
+ [ escapedTitle, "", "", false, nowPlayingIconName, track ]);
+ } catch(err) {
+ log("failed to discover url " + track.get_url());
+ this.model.set(iter,
+ [0, 1, 2, 3, 4, 5],
+ [ escapedTitle, "", "", true, errorIconName, track ]);
+ }
+
this.ui.get_object("running_length_label_info").set_text(
(parseInt(duration/60) + 1) + " min");
+
this.emit("track-added")
}
}));
@@ -247,7 +247,7 @@ const ArtistAlbums = new Lang.Class({
GObject.TYPE_STRING,
GObject.TYPE_STRING,
GObject.TYPE_BOOLEAN,/*icon shown*/
- GdkPixbuf.Pixbuf, /*icon*/
+ GObject.TYPE_STRING, /*icon*/
GObject.TYPE_OBJECT, /*song object*/
GObject.TYPE_BOOLEAN
]);
@@ -284,6 +284,9 @@ const ArtistAlbums = new Lang.Class({
let song = playlist.get_value(iter, 5);
let songWidget = song.songWidget;
+ if (!songWidget.can_be_played)
+ continue
+
let escapedTitle = GLib.markup_escape_text(song.get_title(), -1);
if (song == currentSong){
songWidget.nowPlayingSign.show();
@@ -308,7 +311,8 @@ const ArtistAlbums = new Lang.Class({
let song = this.model.get_value(iter, 5);
let songWidget = song.songWidget;
let escapedTitle = GLib.markup_escape_text(song.get_title(), -1);
- songWidget.nowPlayingSign.hide();
+ if (songWidget.can_be_played)
+ songWidget.nowPlayingSign.hide();
songWidget.title.set_markup("<span>" + escapedTitle + "</span>");
} while(this.model.iter_next(iter));
return false;
@@ -365,19 +369,32 @@ const ArtistAlbumWidget = new Lang.Class({
parseInt((i)%(this.tracks.length/2)), 1, 1);
track.songWidget = songWidget;
let iter = model.append();
- model.set(iter,
- [0, 1, 2, 3, 4, 5],
- [ track.get_title(), "", "", false, pixbuf, track]);
-
songWidget.iter = iter;
songWidget.model = model;
- songWidget.connect('button-release-event', Lang.bind(
- this, this.trackSelected));
songWidget.title = ui.get_object("title");
- songWidget.nowPlayingSign = ui.get_object("image1");
- songWidget.nowPlayingSign.set_from_pixbuf(nowPlayingPixbuf);
- songWidget.nowPlayingSign.set_alignment(0.0,0.6);
- songWidget.nowPlayingSign.set_no_show_all("true");
+
+ try{
+ this.player.discoverer.discover_uri(track.get_url());
+ model.set(iter,
+ [0, 1, 2, 3, 4, 5],
+ [ track.get_title(), "", "", false, nowPlayingIconName, track]);
+ songWidget.nowPlayingSign = ui.get_object("image1");
+ songWidget.nowPlayingSign.set_from_icon_name(nowPlayingIconName,
Gtk.IconSize.BUTTON);
+ songWidget.nowPlayingSign.set_no_show_all("true");
+ songWidget.nowPlayingSign.set_alignment(0.0,0.6);
+ songWidget.can_be_played = true;
+ songWidget.connect('button-release-event', Lang.bind(
+ this, this.trackSelected));
+ } catch(err) {
+ log("failed to discover url " + track.get_url());
+ this.model.set(iter,
+ [0, 1, 2, 3, 4, 5],
+ [ track.get_title(), "", "", true, errorIconName, track ]);
+ songWidget.nowPlayingSign = ui.get_object("image1");
+ songWidget.nowPlayingSign.set_from_icon_name(errorIconName, Gtk.IconSize.BUTTON);
+ songWidget.nowPlayingSign.set_alignment(0.0,0.6);
+ songWidget.can_be_played = false;
+ }
}
this.ui.get_object("grid1").show_all();
this.emit("tracks-loaded");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]