[rhythmbox] audiocd: add album info UI, hide 'album' column
- From: Jonathan Matthew <jmatthew src gnome org>
- To: svn-commits-list gnome org
- Subject: [rhythmbox] audiocd: add album info UI, hide 'album' column
- Date: Fri, 19 Jun 2009 00:35:26 -0400 (EDT)
commit d7dc14b15febb17315f690b0007bf96fcd72af85
Author: Jonathan Matthew <jonathan d14n org>
Date: Fri Jun 19 14:26:13 2009 +1000
audiocd: add album info UI, hide 'album' column
The album info UI is mostly copied from sound-juicer, with the addition
of the album artist sortname.
plugins/audiocd/album-info.ui | 196 +++++++++++++++++++++++++++++++++
plugins/audiocd/rb-audiocd-source.c | 202 +++++++++++++++++++++++++++++++++--
2 files changed, 391 insertions(+), 7 deletions(-)
---
diff --git a/plugins/audiocd/album-info.ui b/plugins/audiocd/album-info.ui
new file mode 100644
index 0000000..471f0f3
--- /dev/null
+++ b/plugins/audiocd/album-info.ui
@@ -0,0 +1,196 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkTable" id="album_info">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="album_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">A_lbum:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">album_entry</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_SHRINK | GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="artist_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Artist:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">artist_entry</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_SHRINK | GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="album_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkEntry" id="genre_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="year_label">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Year:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">year_entry</property>
+ <accessibility>
+ <relation type="label-for" target="year_entry"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="year_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">4</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="disc_number_label">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Disc:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">disc_number_entry</property>
+ <accessibility>
+ <relation type="label-for" target="disc_number_entry"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="disc_number_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="width_chars">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_SHRINK | GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="genre_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Genre:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">genre_entry</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_SHRINK | GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="artist_sort_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Artist s_ort order:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">artist_sort_entry</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_SHRINK | GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="artist_sort_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="artist_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/plugins/audiocd/rb-audiocd-source.c b/plugins/audiocd/rb-audiocd-source.c
index 1d1de18..b38d585 100644
--- a/plugins/audiocd/rb-audiocd-source.c
+++ b/plugins/audiocd/rb-audiocd-source.c
@@ -63,6 +63,7 @@ enum
};
static void rb_audiocd_source_dispose (GObject *object);
+static void rb_audiocd_source_finalize (GObject *object);
static GObject *rb_audiocd_source_constructor (GType type, guint n_construct_properties,
GObjectConstructParam *construct_properties);
static void impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@@ -75,10 +76,17 @@ static gboolean impl_uri_is_source (RBSource *source, const char *uri);
static void impl_delete_thyself (RBSource *source);
static GList* impl_get_ui_actions (RBSource *source);
+static void impl_pack_paned (RBBrowserSource *source, GtkWidget *paned);
+
static gpointer rb_audiocd_load_songs (RBAudioCdSource *source);
static void rb_audiocd_load_metadata (RBAudioCdSource *source, RhythmDB *db);
static void rb_audiocd_load_metadata_cancel (RBAudioCdSource *source);
+static gboolean update_album_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
+static gboolean update_genre_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
+static gboolean update_year_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
+static gboolean update_disc_number_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
+
typedef struct
{
gchar *device_path;
@@ -88,6 +96,14 @@ typedef struct
GstElement *cdda;
GstElement *fakesink;
+ GtkWidget *box;
+ GtkWidget *artist_entry;
+ GtkWidget *artist_sort_entry;
+ GtkWidget *album_entry;
+ GtkWidget *year_entry;
+ GtkWidget *genre_entry;
+ GtkWidget *disc_number_entry;
+
#ifdef HAVE_SJ_METADATA_GETTER
SjMetadataGetter *metadata;
#endif
@@ -104,9 +120,11 @@ rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
RBSourceClass *source_class = RB_SOURCE_CLASS (klass);
+ RBBrowserSourceClass *browser_source_class = RB_BROWSER_SOURCE_CLASS (klass);
object_class->constructor = rb_audiocd_source_constructor;
object_class->dispose = rb_audiocd_source_dispose;
+ object_class->finalize = rb_audiocd_source_finalize;
object_class->set_property = impl_set_property;
object_class->get_property = impl_get_property;
@@ -123,6 +141,9 @@ rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
source_class->impl_try_playlist = (RBSourceFeatureFunc) rb_true_function; /* shouldn't need this. */
source_class->impl_want_uri = impl_want_uri;
+ /* add the browser below the album info section */
+ browser_source_class->impl_pack_paned = impl_pack_paned;
+
g_object_class_override_property (object_class,
PROP_SEARCH_TYPE,
"search-type");
@@ -133,11 +154,10 @@ rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
static void
rb_audiocd_source_init (RBAudioCdSource *self)
{
-
}
static void
-rb_audiocd_source_dispose (GObject *object)
+rb_audiocd_source_finalize (GObject *object)
{
RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
@@ -147,6 +167,15 @@ rb_audiocd_source_dispose (GObject *object)
g_list_free (priv->tracks);
priv->tracks = NULL;
}
+
+ G_OBJECT_CLASS (rb_audiocd_source_parent_class)->finalize (object);
+}
+
+static void
+rb_audiocd_source_dispose (GObject *object)
+{
+ RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
+
if (priv->pipeline) {
gst_object_unref (GST_OBJECT (priv->pipeline));
priv->pipeline = NULL;
@@ -162,6 +191,8 @@ rb_audiocd_source_constructor (GType type,
{
RBAudioCdSource *source;
RBEntryView *entry_view;
+ RBPlugin *plugin;
+ char *ui_file;
source = RB_AUDIOCD_SOURCE (G_OBJECT_CLASS (rb_audiocd_source_parent_class)->
constructor (type, n_construct_properties, construct_properties));
@@ -172,6 +203,46 @@ rb_audiocd_source_constructor (GType type,
entry_view = rb_source_get_entry_view (RB_SOURCE (source));
rb_entry_view_set_sorting_order (entry_view, "Track", GTK_SORT_ASCENDING);
+ /* hide the 'album' column */
+ gtk_tree_view_column_set_visible (rb_entry_view_get_column (entry_view, RB_ENTRY_VIEW_COL_ALBUM), FALSE);
+
+ /* set up the album info widgets */
+ g_object_get (source, "plugin", &plugin, NULL);
+ ui_file = rb_plugin_find_file (plugin, "album-info.ui");
+ g_object_unref (plugin);
+
+ if (ui_file == NULL) {
+ g_warning ("couldn't find album-info.ui");
+ } else {
+ RBAudioCdSourcePrivate *priv;
+ GtkWidget *table;
+ GtkBuilder *builder;
+
+ priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+
+ builder = rb_builder_load (ui_file, NULL);
+ g_free (ui_file);
+
+ table = GTK_WIDGET (gtk_builder_get_object (builder, "album_info"));
+ g_assert (table != NULL);
+
+ priv->artist_entry = GTK_WIDGET (gtk_builder_get_object (builder, "artist_entry"));
+ priv->artist_sort_entry = GTK_WIDGET (gtk_builder_get_object (builder, "artist_sort_entry"));
+ priv->album_entry = GTK_WIDGET (gtk_builder_get_object (builder, "album_entry"));
+ priv->year_entry = GTK_WIDGET (gtk_builder_get_object (builder, "year_entry"));
+ priv->genre_entry = GTK_WIDGET (gtk_builder_get_object (builder, "genre_entry"));
+ priv->disc_number_entry = GTK_WIDGET (gtk_builder_get_object (builder, "disc_number_entry"));
+
+ g_signal_connect_object (priv->album_entry, "focus-out-event", G_CALLBACK (update_album_cb), source, 0);
+ g_signal_connect_object (priv->genre_entry, "focus-out-event", G_CALLBACK (update_genre_cb), source, 0);
+ g_signal_connect_object (priv->year_entry, "focus-out-event", G_CALLBACK (update_year_cb), source, 0);
+ g_signal_connect_object (priv->disc_number_entry, "focus-out-event", G_CALLBACK (update_disc_number_cb), source, 0);
+
+ gtk_box_pack_start (GTK_BOX (priv->box), table, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (priv->box), table, 0);
+ g_object_unref (builder);
+ }
+
g_object_ref (G_OBJECT (source));
g_thread_create ((GThreadFunc)rb_audiocd_load_songs, source, FALSE, NULL);
@@ -243,6 +314,16 @@ impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *ps
}
}
+static void
+impl_pack_paned (RBBrowserSource *source, GtkWidget *paned)
+{
+ RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+
+ priv->box = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show_all (priv->box);
+ gtk_container_add (GTK_CONTAINER (source), priv->box);
+ gtk_box_pack_start (GTK_BOX (priv->box), paned, TRUE, TRUE, 0);
+}
static void
entry_set_string_prop (RhythmDB *db,
@@ -579,7 +660,37 @@ metadata_cb (SjMetadataGetter *metadata,
return;
}
+ if (album->artist != NULL) {
+ gtk_entry_set_text (GTK_ENTRY (priv->artist_entry), album->artist);
+ }
+ if (album->artist_sortname != NULL) {
+ gtk_entry_set_text (GTK_ENTRY (priv->artist_sort_entry), album->artist_sortname);
+ }
+ if (album->title != NULL) {
+ gtk_entry_set_text (GTK_ENTRY (priv->album_entry), album->title);
+ }
+ if (album->release_date != NULL) {
+ char *year;
+ year = g_strdup_printf ("%d", g_date_get_year (album->release_date));
+ gtk_entry_set_text (GTK_ENTRY (priv->year_entry), year);
+ g_free (year);
+ }
+ if (album->disc_number != 0) {
+ char *num;
+ num = g_strdup_printf ("%d", album->disc_number);
+ gtk_entry_set_text (GTK_ENTRY (priv->disc_number_entry), num);
+ g_free (num);
+ }
+ if (album->genre != NULL) {
+ gtk_entry_set_text (GTK_ENTRY (priv->genre_entry), album->genre);
+ }
+
g_object_set (G_OBJECT (source), "name", album->title, NULL);
+ rb_debug ("musicbrainz_albumid: %s", album->album_id);
+ rb_debug ("musicbrainz_albumartistid: %s", album->artist_id);
+ rb_debug ("album artist: %s", album->artist);
+ rb_debug ("disc number: %d", album->disc_number);
+ rb_debug ("genre: %s", album->genre);
while (album->tracks && cd_track) {
TrackDetails *track = (TrackDetails*)album->tracks->data;
@@ -588,12 +699,9 @@ metadata_cb (SjMetadataGetter *metadata,
rb_debug ("storing metadata for %s - %s - %s", track->artist, album->title, track->title);
- rb_debug ("genre: %s", album->genre);
rb_debug ("musicbrainz_trackid: %s", track->track_id);
rb_debug ("musicbrainz_artistid: %s", track->artist_id);
- rb_debug ("musicbrainz_albumid: %s", album->album_id);
- rb_debug ("musicbrainz_albumartistid: %s", album->artist_id);
- rb_debug ("album sortname: %s", album->artist_sortname);
+ rb_debug ("artist sortname: %s", track->artist_sortname);
/* record track info in entry*/
entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_TITLE, track->title);
@@ -604,13 +712,20 @@ metadata_cb (SjMetadataGetter *metadata,
entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_MUSICBRAINZ_ARTISTID, track->artist_id);
entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMID, album->album_id);
entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID, album->artist_id);
- entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_ARTIST_SORTNAME, album->artist_sortname);
+ entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_ARTIST_SORTNAME, track->artist_sortname);
g_value_init (&value, G_TYPE_ULONG);
g_value_set_ulong (&value, track->duration);
rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &value);
g_value_unset (&value);
+ if (album->disc_number != 0) {
+ g_value_init (&value, G_TYPE_ULONG);
+ g_value_set_ulong (&value, album->disc_number);
+ rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
+ g_value_unset (&value);
+ }
+
/*album->release_date (could potentially have multiple values)*/
/* in current sj-structures.h, however, it does not */
@@ -851,3 +966,76 @@ impl_uri_is_source (RBSource *source, const char *uri)
return FALSE;
}
+static void
+update_tracks (RBAudioCdSource *source, RhythmDBPropType property, GValue *value)
+{
+ RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+ RhythmDB *db;
+ GList *i;
+
+ db = get_db_for_source (source);
+
+ for (i = priv->tracks; i != NULL; i = i->next) {
+ rhythmdb_entry_set (db, i->data, property, value);
+ }
+
+ rhythmdb_commit (db);
+ g_object_unref (db);
+}
+
+static void
+update_tracks_string (RBAudioCdSource *source, RhythmDBPropType property, const char *str)
+{
+ GValue v = {0, };
+ g_value_init (&v, G_TYPE_STRING);
+ g_value_set_string (&v, str);
+ update_tracks (source, property, &v);
+ g_value_unset (&v);
+}
+
+static gboolean
+update_album_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source)
+{
+ update_tracks_string (source, RHYTHMDB_PROP_ALBUM, gtk_entry_get_text (GTK_ENTRY (widget)));
+ return FALSE;
+}
+
+static gboolean
+update_genre_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source)
+{
+ update_tracks_string (source, RHYTHMDB_PROP_GENRE, gtk_entry_get_text (GTK_ENTRY (widget)));
+ return FALSE;
+}
+
+static gboolean
+update_year_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source)
+{
+ int year;
+ GDate date;
+ GValue v = {0, };
+
+ year = strtol (gtk_entry_get_text (GTK_ENTRY (widget)), NULL, 10);
+ g_date_clear (&date, 1);
+ g_date_set_dmy (&date, 1, 1, year);
+
+ g_value_init (&v, G_TYPE_ULONG);
+ g_value_set_ulong (&v, g_date_get_julian (&date));
+ update_tracks (source, RHYTHMDB_PROP_DATE, &v);
+ g_value_unset (&v);
+
+ return FALSE;
+}
+
+static gboolean
+update_disc_number_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source)
+{
+ GValue v = {0, };
+
+ g_value_init (&v, G_TYPE_ULONG);
+ g_value_set_ulong (&v, strtoul (gtk_entry_get_text (GTK_ENTRY (widget)), NULL, 10));
+ update_tracks (source, RHYTHMDB_PROP_DISC_NUMBER, &v);
+ g_value_unset (&v);
+
+ return FALSE;
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]