[rhythmbox] artsearch: add an album art page to song info dialogs
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] artsearch: add an album art page to song info dialogs
- Date: Wed, 28 Jan 2015 22:34:22 +0000 (UTC)
commit 38dadb1737aaed836dc0d68a4884af694fd3cfe8
Author: Jonathan Matthew <jonathan d14n org>
Date: Wed Dec 24 12:08:07 2014 +1000
artsearch: add an album art page to song info dialogs
This displays the current album art for the track, and allows it to be
re-fetched, cleared, or replaced with a selected file.
plugins/artsearch/Makefile.am | 1 +
plugins/artsearch/artsearch.py | 14 ++++-
plugins/artsearch/songinfo.py | 139 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 153 insertions(+), 1 deletions(-)
---
diff --git a/plugins/artsearch/Makefile.am b/plugins/artsearch/Makefile.am
index 69a0f2c..397ec80 100644
--- a/plugins/artsearch/Makefile.am
+++ b/plugins/artsearch/Makefile.am
@@ -4,6 +4,7 @@ plugindir = $(PLUGINDIR)/artsearch
plugindatadir = $(PLUGINDATADIR)/artsearch
plugin_PYTHON = \
artsearch.py \
+ songinfo.py \
embedded.py \
lastfm.py \
local.py \
diff --git a/plugins/artsearch/artsearch.py b/plugins/artsearch/artsearch.py
index 990fca2..5c03dec 100644
--- a/plugins/artsearch/artsearch.py
+++ b/plugins/artsearch/artsearch.py
@@ -29,6 +29,8 @@ from gi.repository import GObject, Peas, RB, GdkPixbuf
import gettext
gettext.install('rhythmbox', RB.locale_dir())
+from songinfo import AlbumArtPage
+
import oldcache
from lastfm import LastFMSearch
from local import LocalSearch
@@ -67,11 +69,17 @@ class ArtSearchPlugin (GObject.GObject, Peas.Activatable):
self.art_store = RB.ExtDB(name="album-art")
self.req_id = self.art_store.connect("request", self.album_art_requested)
+ shell = self.object
+ self.csi_id = shell.connect("create_song_info", self.create_song_info)
+
def do_deactivate (self):
self.art_store.disconnect(self.req_id)
self.req_id = 0
self.art_store = None
- self.object = None
+
+ shell = self.object
+ shell.disconnect(self.csi_id)
+ self.csi_id = 0
def album_art_requested(self, store, key, last_time):
searches = []
@@ -84,3 +92,7 @@ class ArtSearchPlugin (GObject.GObject, Peas.Activatable):
s = Search(store, key, last_time, searches)
return s.next_search()
+
+ def create_song_info(self, shell, song_info, is_multiple):
+ if is_multiple is False:
+ x = AlbumArtPage(shell, song_info)
diff --git a/plugins/artsearch/songinfo.py b/plugins/artsearch/songinfo.py
new file mode 100644
index 0000000..f104041
--- /dev/null
+++ b/plugins/artsearch/songinfo.py
@@ -0,0 +1,139 @@
+# -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*-
+#
+# Copyright (C) 2014 Jonathan Matthew
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# The Rhythmbox authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and Rhythmbox. This permission is above and beyond the permissions granted
+# by the GPL license by which Rhythmbox is covered. If you modify this code
+# you may extend this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this exception
+# statement from your version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from gi.repository import RB, Gtk
+
+class AlbumArtPage(object):
+ def __init__(self, shell, song_info):
+ self.visible = False
+ self.art_key = None
+
+ self.shell = shell
+ self.song_info = song_info
+ self.entry = song_info.props.current_entry
+ self.art_store = RB.ExtDB(name="album-art")
+ self.art_store.connect("added", self.art_added_cb)
+
+ grid = Gtk.Grid(hexpand=True, vexpand=True, margin=6, row_spacing=6)
+
+ self.image = RB.FadingImage(fallback="rhythmbox-missing-artwork", use_tooltip=False)
+ self.image.props.hexpand = True
+ self.image.props.vexpand = True
+ grid.attach(self.image, 0, 0, 1, 1)
+
+ buttons = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL)
+ buttons.set_spacing(6)
+ buttons.set_layout(Gtk.ButtonBoxStyle.CENTER)
+ grid.attach(buttons, 0, 1, 1, 1)
+
+ clear = Gtk.Button(label=_("Clear"), use_underline=True)
+ clear.connect('clicked', self.clear_button_cb)
+ buttons.add(clear)
+
+ fetch = Gtk.Button(label=_("_Fetch"), use_underline=True)
+ fetch.connect('clicked', self.fetch_button_cb)
+ buttons.add(fetch)
+
+ browse_file = Gtk.Button(label=_("_Browse"), use_underline=True)
+ browse_file.connect('clicked', self.browse_button_cb)
+ buttons.add(browse_file)
+
+ self.page_num = song_info.append_page(_("Album Art"), grid)
+
+ self.ec_id = song_info.connect("notify::current-entry", self.entry_changed_cb)
+ self.sp_id = grid.get_parent().connect("switch-page", self.switch_page_cb)
+
+ def art_update(self, key, data):
+ db = self.shell.props.db
+ if db.entry_matches_ext_db_key(self.entry, key):
+ self.image.set_pixbuf(data)
+ self.art_key = key
+
+ def art_added_cb(self, db, key, filename, data):
+ print("art added?")
+ self.art_update(key, data)
+
+ def art_request_cb(self, key, filename, data):
+ print("art request finished?")
+ self.art_update(key, data)
+
+ def get_art(self, entry, user_explicit=False):
+ self.image.start(100)
+ key = entry.create_ext_db_key(RB.RhythmDBPropType.ALBUM)
+ if user_explicit:
+ key.add_info("user-explicit", "true")
+ self.art_store.request(key, self.art_request_cb)
+
+ def storage_key(self, entry):
+ key = RB.ExtDBKey.create_storage("album", entry.get_string(RB.RhythmDBPropType.ALBUM))
+ artist = entry.get_string(RB.RhythmDBPropType.ALBUM_ARTIST)
+ if artist is None or artist == "" or artist == _("Unknown"):
+ artist = entry.get_string(RB.RhythmDBPropType.ARTIST)
+ key.add_field("artist", artist)
+ return key
+
+ def entry_changed_cb(self, pspec, duh):
+ self.entry = self.song_info.props.current_entry
+
+ db = self.shell.props.db
+ if self.art_key and db.entry_matches_ext_db_key(self.entry, self.art_key):
+ return
+
+ self.art_key = None
+ if self.visible:
+ self.get_art(self.entry, False)
+
+ def switch_page_cb(self, notebook, page, page_num):
+ if self.art_key is not None:
+ return
+
+ self.visible = (page_num == self.page_num)
+ if self.visible:
+ self.get_art(self.entry, False)
+
+ def clear_button_cb(self, button):
+ key = self.storage_key(self.entry)
+ self.art_store.store(key, RB.ExtDBSourceType.USER_EXPLICIT, None)
+
+ def fetch_button_cb(self, button):
+ if self.art_key is not None:
+ self.art_store.delete(self.art_key)
+ self.get_art(self.entry, True)
+
+ def browse_file_response_cb(self, dialog, response):
+ if response == Gtk.ResponseType.OK:
+ key = self.storage_key(self.entry)
+ self.art_store.store_uri(key, RB.ExtDBSourceType.USER_EXPLICIT, dialog.get_uri())
+
+ dialog.destroy()
+
+ def browse_button_cb(self, button):
+ d = Gtk.FileChooserDialog(_("Select new artwork"), self.shell.props.window,
Gtk.FileChooserAction.OPEN)
+ d.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
+ d.add_button(_("_Select"), Gtk.ResponseType.OK)
+ d.set_default_response(Gtk.ResponseType.OK)
+ d.connect("response", self.browse_file_response_cb)
+ d.show_all()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]