[rhythmbox] add album-artist and album-artist-sortname fields
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] add album-artist and album-artist-sortname fields
- Date: Thu, 10 Jun 2010 06:59:36 +0000 (UTC)
commit 037e04efa59c8ea1e233d9f88ee619028463feca
Author: Jonathan Matthew <jonathan d14n org>
Date: Thu Jun 10 16:57:58 2010 +1000
add album-artist and album-artist-sortname fields
We don't do anything particularly intelligent with album artist
information yet, but at least we'll have it in the database now.
data/ui/song-info-multiple.ui | 91 ++++++++++++----
data/ui/song-info.ui | 105 +++++++++++++----
metadata/rb-metadata-common.c | 6 +
metadata/rb-metadata-gst-common.c | 12 ++
metadata/rb-metadata.h | 4 +-
plugins/audiocd/rb-audiocd-source.c | 100 ++++-------------
rhythmdb/rhythmdb-private.h | 2 +
rhythmdb/rhythmdb-tree.c | 12 ++-
rhythmdb/rhythmdb.c | 49 ++++++++
rhythmdb/rhythmdb.h | 8 +-
sources/rb-library-source.c | 27 ++---
widgets/rb-query-creator-properties.c | 2 +
widgets/rb-song-info.c | 200 +++++++++++++++++----------------
13 files changed, 380 insertions(+), 238 deletions(-)
---
diff --git a/data/ui/song-info-multiple.ui b/data/ui/song-info-multiple.ui
index ea06638..a6812ff 100644
--- a/data/ui/song-info-multiple.ui
+++ b/data/ui/song-info-multiple.ui
@@ -45,7 +45,7 @@
<object class="GtkLabel" id="album_label">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Album:</property>
+ <property name="label" translatable="yes">Albu_m:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">song_info_album</property>
</object>
@@ -78,8 +78,8 @@
<property name="mnemonic_widget">song_info_genre</property>
</object>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -94,8 +94,8 @@
<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>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
@@ -108,8 +108,8 @@
<property name="use_underline">True</property>
</object>
<packing>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -125,8 +125,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
@@ -140,8 +140,8 @@
<property name="mnemonic_widget">song_info_year</property>
</object>
<packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -156,8 +156,8 @@
<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="top_attach">4</property>
+ <property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing>
</child>
@@ -170,8 +170,8 @@
<property name="mnemonic_widget">song_info_disc_cur</property>
</object>
<packing>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -186,16 +186,38 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="album_artist_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Album a_rtist:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">song_info_album_artist</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkEntry" id="song_info_album_artist">
+ <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>
+ <property name="y_options"></property>
+ </packing>
</child>
</object>
</child>
@@ -213,7 +235,7 @@
<object class="GtkTable" id="song_info_sorting">
<property name="visible">True</property>
<property name="border_width">6</property>
- <property name="n_rows">2</property>
+ <property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
@@ -273,6 +295,35 @@
<property name="y_options">GTK_FILL</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="album_artist_sortname_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Album a_rtist sort order:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">song_info_album_artist_sortname</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="song_info_album_artist_sortname">
+ <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>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
diff --git a/data/ui/song-info.ui b/data/ui/song-info.ui
index 667a9b3..e6d7810 100644
--- a/data/ui/song-info.ui
+++ b/data/ui/song-info.ui
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<interface>
- <!-- interface-requires gtk+ 2.12 -->
+ <requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkNotebook" id="song_info_vbox">
<property name="visible">True</property>
@@ -75,7 +75,7 @@
<object class="GtkLabel" id="album_label">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Album:</property>
+ <property name="label" translatable="yes">Albu_m:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">song_info_album</property>
</object>
@@ -103,13 +103,13 @@
<object class="GtkLabel" id="trackn_label">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Track number:</property>
+ <property name="label" translatable="yes">Track _number:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">song_info_track_cur</property>
</object>
<packing>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -123,8 +123,8 @@
<property name="mnemonic_widget">song_info_genre</property>
</object>
<packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -143,8 +143,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="y_options"></property>
</packing>
</child>
@@ -161,8 +161,8 @@
<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="top_attach">4</property>
+ <property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing>
</child>
@@ -190,8 +190,8 @@
<property name="mnemonic_widget">song_info_disc_cur</property>
</object>
<packing>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -209,8 +209,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
<property name="y_options"></property>
</packing>
</child>
@@ -227,8 +227,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
<property name="y_options"></property>
</packing>
</child>
@@ -241,8 +241,8 @@
<property name="mnemonic_widget">song_info_year</property>
</object>
<packing>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -256,8 +256,8 @@
<property name="mnemonic_widget">song_info_comment</property>
</object>
<packing>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
@@ -279,8 +279,37 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="album_artist_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Album a_rtist:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">song_info_album_artist</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="song_info_album_artist">
+ <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">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
</packing>
</child>
</object>
@@ -340,7 +369,7 @@
<object class="GtkTable" id="song_info_sorting">
<property name="visible">True</property>
<property name="border_width">12</property>
- <property name="n_rows">2</property>
+ <property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
@@ -406,6 +435,34 @@
<property name="y_options"></property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="album_artist_sortname_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Album a_rtist sort order:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="song_info_album_artist_sortname">
+ <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>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
diff --git a/metadata/rb-metadata-common.c b/metadata/rb-metadata-common.c
index 7f4ec81..d0a4655 100644
--- a/metadata/rb-metadata-common.c
+++ b/metadata/rb-metadata-common.c
@@ -64,6 +64,8 @@
* @RB_METADATA_FIELD_MUSICBRAINZ_ALBUMARTISTID: MusicBrainz album artist ID
* @RB_METADATA_FIELD_ARTIST_SORTNAME: Person(s) responsible for the recording, as used for sorting
* @RB_METADATA_FIELD_ALBUM_SORTNAME: Album containing the recording, as used for sorting
+ * @RB_METADATA_FIELD_ALBUM_ARTIST: The artist of the entire album
+ * @RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME: The artist of the entire album, as it should be sorted
* @RB_METADATA_FIELD_LAST: invalid field
*
* Metadata fields that can be read from and written to files.
@@ -102,6 +104,8 @@ rb_metadata_get_field_type (RBMetaDataField field)
case RB_METADATA_FIELD_MUSICBRAINZ_ALBUMARTISTID:
case RB_METADATA_FIELD_ARTIST_SORTNAME:
case RB_METADATA_FIELD_ALBUM_SORTNAME:
+ case RB_METADATA_FIELD_ALBUM_ARTIST:
+ case RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME:
return G_TYPE_STRING;
case RB_METADATA_FIELD_DATE:
@@ -202,6 +206,8 @@ rb_metadata_field_get_type (void)
ENUM_ENTRY (RB_METADATA_FIELD_MUSICBRAINZ_ALBUMARTISTID, "musicbrainz-albumartistid"),
ENUM_ENTRY (RB_METADATA_FIELD_ARTIST_SORTNAME, "musicbrainz-sortname"),
ENUM_ENTRY (RB_METADATA_FIELD_ALBUM_SORTNAME, "album-sortname"),
+ ENUM_ENTRY (RB_METADATA_FIELD_ALBUM_ARTIST, "album-artist"),
+ ENUM_ENTRY (RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME, "album-artist-sortname"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("RBMetadataFieldType", values);
diff --git a/metadata/rb-metadata-gst-common.c b/metadata/rb-metadata-gst-common.c
index f021766..db20aa8 100644
--- a/metadata/rb-metadata-gst-common.c
+++ b/metadata/rb-metadata-gst-common.c
@@ -127,6 +127,12 @@ rb_metadata_gst_tag_to_field (const char *tag)
return RB_METADATA_FIELD_ARTIST_SORTNAME;
else if (!strcmp (tag, GST_TAG_ALBUM_SORTNAME))
return RB_METADATA_FIELD_ALBUM_SORTNAME;
+#if GST_CHECK_VERSION(0,10,25)
+ else if (!strcmp (tag, GST_TAG_ALBUM_ARTIST))
+ return RB_METADATA_FIELD_ALBUM_ARTIST;
+ else if (!strcmp (tag, GST_TAG_ALBUM_ARTIST_SORTNAME))
+ return RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME;
+#endif
else
return -1;
}
@@ -198,6 +204,12 @@ rb_metadata_gst_field_to_gst_tag (RBMetaDataField field)
return GST_TAG_ARTIST_SORTNAME;
case RB_METADATA_FIELD_ALBUM_SORTNAME:
return GST_TAG_ALBUM_SORTNAME;
+#if GST_CHECK_VERSION(0,10,25)
+ case RB_METADATA_FIELD_ALBUM_ARTIST:
+ return GST_TAG_ALBUM_ARTIST;
+ case RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME:
+ return GST_TAG_ALBUM_ARTIST_SORTNAME;
+#endif
default:
return NULL;
}
diff --git a/metadata/rb-metadata.h b/metadata/rb-metadata.h
index 214e6da..57a89ce 100644
--- a/metadata/rb-metadata.h
+++ b/metadata/rb-metadata.h
@@ -65,7 +65,9 @@ typedef enum
RB_METADATA_FIELD_MUSICBRAINZ_ALBUMID, /* string */
RB_METADATA_FIELD_MUSICBRAINZ_ALBUMARTISTID, /* string */
RB_METADATA_FIELD_ARTIST_SORTNAME, /* string */
- RB_METADATA_FIELD_ALBUM_SORTNAME, /* string */
+ RB_METADATA_FIELD_ALBUM_SORTNAME, /* string */
+ RB_METADATA_FIELD_ALBUM_ARTIST, /* string */
+ RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME, /* string */
RB_METADATA_FIELD_LAST /* nothing */
} RBMetaDataField;
diff --git a/plugins/audiocd/rb-audiocd-source.c b/plugins/audiocd/rb-audiocd-source.c
index f169389..50b6ffe 100644
--- a/plugins/audiocd/rb-audiocd-source.c
+++ b/plugins/audiocd/rb-audiocd-source.c
@@ -79,10 +79,8 @@ 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 void metadata_gather_cb (RhythmDB *db, RhythmDBEntry *entry, RBStringValueMap *data, RBAudioCdSource *source);
-static GValue *album_artist_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source);
-static GValue *album_artist_sortname_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source);
-
+static gboolean update_artist_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
+static gboolean update_artist_sort_cb (GtkWidget *widget, GdkEventFocus *event, 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);
@@ -262,7 +260,6 @@ rb_audiocd_source_constructed (GObject *object)
GtkTreeViewColumn *extract;
GtkWidget *widget;
GtkAction *action;
- RhythmDB *db;
RBPlugin *plugin;
RBShell *shell;
char *ui_file;
@@ -335,16 +332,6 @@ rb_audiocd_source_constructed (GObject *object)
/* hide the 'album' column */
gtk_tree_view_column_set_visible (rb_entry_view_get_column (entry_view, RB_ENTRY_VIEW_COL_ALBUM), FALSE);
- /* handle extra metadata requests for album artist and album artist sortname */
- db = get_db_for_source (source);
- g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-request::" RHYTHMDB_PROP_ALBUM_ARTIST,
- G_CALLBACK (album_artist_metadata_request_cb), source, 0);
- g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-request::" RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME,
- G_CALLBACK (album_artist_sortname_metadata_request_cb), source, 0);
- g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-gather",
- G_CALLBACK (metadata_gather_cb), source, 0);
- g_object_unref (db);
-
/* set up the album info widgets */
g_object_get (source, "plugin", &plugin, NULL);
ui_file = rb_plugin_find_file (plugin, "album-info.ui");
@@ -396,6 +383,8 @@ rb_audiocd_source_constructed (GObject *object)
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->artist_entry, "focus-out-event", G_CALLBACK (update_artist_cb), source, 0);
+ g_signal_connect_object (priv->artist_sort_entry, "focus-out-event", G_CALLBACK (update_artist_sort_cb), source, 0);
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);
@@ -873,6 +862,7 @@ metadata_cb (SjMetadataGetter *metadata,
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 ("album artist sortname: %s", album->artist_sortname);
rb_debug ("disc number: %d", album->disc_number);
rb_debug ("genre: %s", album->genre);
@@ -897,6 +887,8 @@ metadata_cb (SjMetadataGetter *metadata,
entry_set_string_prop (db, entry, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMID, TRUE, album->album_id);
entry_set_string_prop (db, entry, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID, TRUE, album->artist_id);
entry_set_string_prop (db, entry, RHYTHMDB_PROP_ARTIST_SORTNAME, TRUE, track->artist_sortname);
+ entry_set_string_prop (db, entry, RHYTHMDB_PROP_ALBUM_ARTIST, TRUE, album->artist);
+ entry_set_string_prop (db, entry, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, TRUE, album->artist_sortname);
g_value_init (&value, G_TYPE_ULONG);
g_value_set_ulong (&value, track->duration);
@@ -1153,70 +1145,6 @@ impl_uri_is_source (RBSource *source, const char *uri)
}
static void
-metadata_gather_cb (RhythmDB *db, RhythmDBEntry *entry, RBStringValueMap *data, RBAudioCdSource *source)
-{
- RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
- GValue value = {0,};
-
- if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
- return;
- }
-
- if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_entry)) > 0) {
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, gtk_entry_get_text (GTK_ENTRY (priv->artist_entry)));
- rb_string_value_map_set (data, RHYTHMDB_PROP_ALBUM_ARTIST, &value);
- g_value_unset (&value);
- }
-
- if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_sort_entry)) > 0) {
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, gtk_entry_get_text (GTK_ENTRY (priv->artist_sort_entry)));
- rb_string_value_map_set (data, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, &value);
- g_value_unset (&value);
- }
-}
-
-
-static GValue *
-album_artist_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source)
-{
- RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
- GValue *value = NULL;
-
- if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
- return NULL;
- }
-
- if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_entry)) > 0) {
- value = g_new0 (GValue, 1);
- g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, gtk_entry_get_text (GTK_ENTRY (priv->artist_entry)));
- }
-
- return value;
-}
-
-static GValue *
-album_artist_sortname_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source)
-{
- RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
- GValue *value = NULL;
-
- if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
- return NULL;
- }
-
- if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_sort_entry)) > 0) {
- value = g_new0 (GValue, 1);
- g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, gtk_entry_get_text (GTK_ENTRY (priv->artist_sort_entry)));
- }
-
- return value;
-}
-
-static void
update_tracks (RBAudioCdSource *source, RhythmDBPropType property, GValue *value)
{
RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
@@ -1244,6 +1172,20 @@ update_tracks_string (RBAudioCdSource *source, RhythmDBPropType property, const
}
static gboolean
+update_artist_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source)
+{
+ update_tracks_string (source, RHYTHMDB_PROP_ALBUM_ARTIST, gtk_entry_get_text (GTK_ENTRY (widget)));
+ return FALSE;
+}
+
+static gboolean
+update_artist_sort_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source)
+{
+ update_tracks_string (source, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, gtk_entry_get_text (GTK_ENTRY (widget)));
+ return FALSE;
+}
+
+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)));
diff --git a/rhythmdb/rhythmdb-private.h b/rhythmdb/rhythmdb-private.h
index 650a392..29e3e30 100644
--- a/rhythmdb/rhythmdb-private.h
+++ b/rhythmdb/rhythmdb-private.h
@@ -76,6 +76,7 @@ struct RhythmDBEntry_ {
RBRefString *title;
RBRefString *artist;
RBRefString *album;
+ RBRefString *album_artist;
RBRefString *genre;
RBRefString *comment;
RBRefString *musicbrainz_trackid;
@@ -84,6 +85,7 @@ struct RhythmDBEntry_ {
RBRefString *musicbrainz_albumartistid;
RBRefString *artist_sortname;
RBRefString *album_sortname;
+ RBRefString *album_artist_sortname;
gulong tracknum;
gulong discnum;
gulong duration;
diff --git a/rhythmdb/rhythmdb-tree.c b/rhythmdb/rhythmdb-tree.c
index f8655f3..963e764 100644
--- a/rhythmdb/rhythmdb-tree.c
+++ b/rhythmdb/rhythmdb-tree.c
@@ -973,11 +973,14 @@ save_entry (RhythmDBTree *db,
case RHYTHMDB_PROP_ARTIST:
save_entry_string(ctx, elt_name, rb_refstring_get (entry->artist));
break;
+ case RHYTHMDB_PROP_ALBUM_ARTIST:
+ save_entry_string_if_set(ctx, elt_name, rb_refstring_get (entry->album_artist));
+ break;
case RHYTHMDB_PROP_GENRE:
save_entry_string(ctx, elt_name, rb_refstring_get (entry->genre));
break;
case RHYTHMDB_PROP_COMMENT:
- save_entry_string(ctx, elt_name, rb_refstring_get (entry->comment));
+ save_entry_string_if_set(ctx, elt_name, rb_refstring_get (entry->comment));
break;
case RHYTHMDB_PROP_MUSICBRAINZ_TRACKID:
save_entry_string_if_set (ctx, elt_name, rb_refstring_get (entry->musicbrainz_trackid));
@@ -997,6 +1000,9 @@ save_entry (RhythmDBTree *db,
case RHYTHMDB_PROP_ALBUM_SORTNAME:
save_entry_string_if_set (ctx, elt_name, rb_refstring_get (entry->album_sortname));
break;
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
+ save_entry_string_if_set (ctx, elt_name, rb_refstring_get (entry->album_artist_sortname));
+ break;
case RHYTHMDB_PROP_TRACK_NUMBER:
save_entry_ulong (ctx, elt_name, entry->tracknum, FALSE);
break;
@@ -1104,14 +1110,18 @@ save_entry (RhythmDBTree *db,
case RHYTHMDB_PROP_GENRE_SORT_KEY:
case RHYTHMDB_PROP_ARTIST_SORT_KEY:
case RHYTHMDB_PROP_ALBUM_SORT_KEY:
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORT_KEY:
case RHYTHMDB_PROP_ARTIST_SORTNAME_SORT_KEY:
case RHYTHMDB_PROP_ALBUM_SORTNAME_SORT_KEY:
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_SORT_KEY:
case RHYTHMDB_PROP_TITLE_FOLDED:
case RHYTHMDB_PROP_GENRE_FOLDED:
case RHYTHMDB_PROP_ARTIST_FOLDED:
case RHYTHMDB_PROP_ALBUM_FOLDED:
+ case RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED:
case RHYTHMDB_PROP_ARTIST_SORTNAME_FOLDED:
case RHYTHMDB_PROP_ALBUM_SORTNAME_FOLDED:
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED:
case RHYTHMDB_PROP_LAST_PLAYED_STR:
case RHYTHMDB_PROP_PLAYBACK_ERROR:
case RHYTHMDB_PROP_FIRST_SEEN_STR:
diff --git a/rhythmdb/rhythmdb.c b/rhythmdb/rhythmdb.c
index 72caf36..ac6f173 100644
--- a/rhythmdb/rhythmdb.c
+++ b/rhythmdb/rhythmdb.c
@@ -606,6 +606,12 @@ metadata_field_from_prop (RhythmDBPropType prop,
case RHYTHMDB_PROP_ALBUM_SORTNAME:
*field = RB_METADATA_FIELD_ALBUM_SORTNAME;
return TRUE;
+ case RHYTHMDB_PROP_ALBUM_ARTIST:
+ *field = RB_METADATA_FIELD_ALBUM_ARTIST;
+ return TRUE;
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
+ *field = RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME;
+ return TRUE;
default:
return FALSE;
}
@@ -1662,12 +1668,14 @@ rhythmdb_entry_allocate (RhythmDB *db,
ret->artist = rb_refstring_ref (db->priv->empty_string);
ret->album = rb_refstring_ref (db->priv->empty_string);
ret->comment = rb_refstring_ref (db->priv->empty_string);
+ ret->album_artist = rb_refstring_ref (db->priv->empty_string);
ret->musicbrainz_trackid = rb_refstring_ref (db->priv->empty_string);
ret->musicbrainz_artistid = rb_refstring_ref (db->priv->empty_string);
ret->musicbrainz_albumid = rb_refstring_ref (db->priv->empty_string);
ret->musicbrainz_albumartistid = rb_refstring_ref (db->priv->empty_string);
ret->artist_sortname = rb_refstring_ref (db->priv->empty_string);
ret->album_sortname = rb_refstring_ref (db->priv->empty_string);
+ ret->album_artist_sortname = rb_refstring_ref (db->priv->empty_string);
ret->mimetype = rb_refstring_ref (db->priv->octet_stream_str);
ret->flags |= RHYTHMDB_ENTRY_LAST_PLAYED_DIRTY |
@@ -2084,6 +2092,17 @@ set_props_from_metadata (RhythmDB *db,
RB_METADATA_FIELD_COMMENT,
RHYTHMDB_PROP_COMMENT,
"");
+ /* album artist */
+ set_metadata_string_with_default (db, metadata, entry,
+ RB_METADATA_FIELD_ALBUM_ARTIST,
+ RHYTHMDB_PROP_ALBUM_ARTIST,
+ "");
+
+ /* album artist sortname */
+ set_metadata_string_with_default (db, metadata, entry,
+ RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME,
+ "");
}
static gboolean
@@ -3674,6 +3693,14 @@ rhythmdb_entry_set_internal (RhythmDB *db,
rb_refstring_unref (entry->album_sortname);
entry->album_sortname = rb_refstring_new (g_value_get_string (value));
break;
+ case RHYTHMDB_PROP_ALBUM_ARTIST:
+ rb_refstring_unref (entry->album_artist);
+ entry->album_artist = rb_refstring_new (g_value_get_string (value));
+ break;
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
+ rb_refstring_unref (entry->album_artist_sortname);
+ entry->album_artist_sortname = rb_refstring_new (g_value_get_string (value));
+ break;
case RHYTHMDB_PROP_HIDDEN:
if (g_value_get_boolean (value)) {
entry->flags |= RHYTHMDB_ENTRY_HIDDEN;
@@ -4437,6 +4464,8 @@ rhythmdb_prop_type_get_type (void)
ENUM_ENTRY (RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID, "Musicbrainz Album Artist ID (gchararray) [mb-albumartistid]"),
ENUM_ENTRY (RHYTHMDB_PROP_ARTIST_SORTNAME, "Artist Sortname (gchararray) [mb-artistsortname]"),
ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_SORTNAME, "Album Sortname (gchararray) [album-sortname]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_ARTIST, "Album Artist (gchararray) [album-artist]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, "Album Artist Sortname (gchararray) [album-artist-sortname]"),
ENUM_ENTRY (RHYTHMDB_PROP_DURATION, "Duration (gulong) [duration]"),
ENUM_ENTRY (RHYTHMDB_PROP_FILE_SIZE, "File Size (guint64) [file-size]"),
@@ -4461,6 +4490,8 @@ rhythmdb_prop_type_get_type (void)
ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_SORT_KEY, "Album sort key (gchararray) [album-sort-key]"),
ENUM_ENTRY (RHYTHMDB_PROP_ARTIST_SORTNAME_SORT_KEY, "Artist Sortname sort key (gchararray) [artist-sortname-sort-key]"),
ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_SORTNAME_SORT_KEY, "Album Sortname sort key (gchararray) [album-sortname-sort-key]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_ARTIST_SORT_KEY, "Album Artist sort key (gchararray) [album-artist-sort-key]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_SORT_KEY, "Album Artist Sortname sort key (gchararray) [album-artist-sortname-sort-key]"),
ENUM_ENTRY (RHYTHMDB_PROP_TITLE_FOLDED, "Title folded (gchararray) [title-folded]"),
ENUM_ENTRY (RHYTHMDB_PROP_GENRE_FOLDED, "Genre folded (gchararray) [genre-folded]"),
@@ -4468,6 +4499,8 @@ rhythmdb_prop_type_get_type (void)
ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_FOLDED, "Album folded (gchararray) [album-folded]"),
ENUM_ENTRY (RHYTHMDB_PROP_ARTIST_SORTNAME_FOLDED, "Artist Sortname folded (gchararray) [artist-sortname-folded]"),
ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_SORTNAME_FOLDED, "Album Sortname folded (gchararray) [album-sortname-folded]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED, "Album Artist folded (gchararray) [album-artist-sortname-folded]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED, "Album Artist Sortname folded (gchararray) [album-artist-sortname-folded]"),
ENUM_ENTRY (RHYTHMDB_PROP_LAST_PLAYED_STR, "Last Played (gchararray) [last-played-str]"),
ENUM_ENTRY (RHYTHMDB_PROP_PLAYBACK_ERROR, "Playback error string (gchararray) [playback-error]"),
ENUM_ENTRY (RHYTHMDB_PROP_HIDDEN, "Hidden (gboolean) [hidden]"),
@@ -5275,6 +5308,10 @@ rhythmdb_entry_get_string (RhythmDBEntry *entry,
return rb_refstring_get (entry->artist_sortname);
case RHYTHMDB_PROP_ALBUM_SORTNAME:
return rb_refstring_get (entry->album_sortname);
+ case RHYTHMDB_PROP_ALBUM_ARTIST:
+ return rb_refstring_get (entry->album_artist);
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
+ return rb_refstring_get (entry->album_artist_sortname);
case RHYTHMDB_PROP_MIMETYPE:
return rb_refstring_get (entry->mimetype);
case RHYTHMDB_PROP_TITLE_SORT_KEY:
@@ -5289,6 +5326,10 @@ rhythmdb_entry_get_string (RhythmDBEntry *entry,
return rb_refstring_get_sort_key (entry->artist_sortname);
case RHYTHMDB_PROP_ALBUM_SORTNAME_SORT_KEY:
return rb_refstring_get_sort_key (entry->album_sortname);
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORT_KEY:
+ return rb_refstring_get_sort_key (entry->album_artist);
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_SORT_KEY:
+ return rb_refstring_get_sort_key (entry->album_artist_sortname);
case RHYTHMDB_PROP_TITLE_FOLDED:
return rb_refstring_get_folded (entry->title);
case RHYTHMDB_PROP_ALBUM_FOLDED:
@@ -5301,6 +5342,10 @@ rhythmdb_entry_get_string (RhythmDBEntry *entry,
return rb_refstring_get_folded (entry->artist_sortname);
case RHYTHMDB_PROP_ALBUM_SORTNAME_FOLDED:
return rb_refstring_get_folded (entry->album_sortname);
+ case RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED:
+ return rb_refstring_get_folded (entry->album_artist);
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED:
+ return rb_refstring_get_folded (entry->album_artist_sortname);
case RHYTHMDB_PROP_LOCATION:
return rb_refstring_get (entry->location);
case RHYTHMDB_PROP_MOUNTPOINT:
@@ -5383,6 +5428,8 @@ rhythmdb_entry_get_refstring (RhythmDBEntry *entry,
return rb_refstring_ref (entry->album);
case RHYTHMDB_PROP_ARTIST:
return rb_refstring_ref (entry->artist);
+ case RHYTHMDB_PROP_ALBUM_ARTIST:
+ return rb_refstring_ref (entry->album_artist);
case RHYTHMDB_PROP_GENRE:
return rb_refstring_ref (entry->genre);
case RHYTHMDB_PROP_COMMENT:
@@ -5399,6 +5446,8 @@ rhythmdb_entry_get_refstring (RhythmDBEntry *entry,
return rb_refstring_ref (entry->artist_sortname);
case RHYTHMDB_PROP_ALBUM_SORTNAME:
return rb_refstring_ref (entry->album_sortname);
+ case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
+ return rb_refstring_ref (entry->album_artist_sortname);
case RHYTHMDB_PROP_MIMETYPE:
return rb_refstring_ref (entry->mimetype);
case RHYTHMDB_PROP_MOUNTPOINT:
diff --git a/rhythmdb/rhythmdb.h b/rhythmdb/rhythmdb.h
index 051ed39..970945e 100644
--- a/rhythmdb/rhythmdb.h
+++ b/rhythmdb/rhythmdb.h
@@ -216,6 +216,12 @@ typedef enum
RHYTHMDB_PROP_ARTIST_SORTNAME_FOLDED,
RHYTHMDB_PROP_ALBUM_SORTNAME_SORT_KEY,
RHYTHMDB_PROP_ALBUM_SORTNAME_FOLDED,
+ RHYTHMDB_PROP_ALBUM_ARTIST,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORT_KEY,
+ RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_SORT_KEY,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED,
RHYTHMDB_NUM_PROPERTIES
} RhythmDBPropType;
@@ -233,8 +239,6 @@ enum {
#define RHYTHMDB_PROP_STREAM_SONG_ALBUM "rb:stream-song-album"
#define RHYTHMDB_PROP_COVER_ART "rb:coverArt"
#define RHYTHMDB_PROP_COVER_ART_URI "rb:coverArt-uri"
-#define RHYTHMDB_PROP_ALBUM_ARTIST "rb:album-artist"
-#define RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME "rb:album-artist-sortname"
GType rhythmdb_query_type_get_type (void);
GType rhythmdb_prop_type_get_type (void);
diff --git a/sources/rb-library-source.c b/sources/rb-library-source.c
index 8960930..473fec3 100644
--- a/sources/rb-library-source.c
+++ b/sources/rb-library-source.c
@@ -861,28 +861,27 @@ filepath_parse_pattern (RhythmDB *db,
const char *p;
char *temp;
GString *s;
- GValue *value;
RBRefString *albumartist;
+ RBRefString *albumartist_sort;
if (pattern == NULL || pattern[0] == 0)
return g_strdup (" ");
- /* request album artist (this is sort of temporary) */
- value = rhythmdb_entry_request_extra_metadata (db, entry, RHYTHMDB_PROP_ALBUM_ARTIST);
- if (value != NULL) {
- albumartist = rb_refstring_new (g_value_get_string (value));
- g_value_unset (value);
- g_free (value);
- } else {
+ /* figure out album artist - use the plain artist field if not specified */
+ albumartist = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_ALBUM_ARTIST);
+ if (albumartist == NULL || g_strcmp0 (rb_refstring_get (albumartist), "") == 0) {
albumartist = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_ARTIST);
}
+ albumartist_sort = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME);
+ if (albumartist_sort == NULL || g_strcmp0 (rb_refstring_get (albumartist_sort), "") == 0) {
+ albumartist_sort = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_ARTIST_SORTNAME);
+ }
s = g_string_new (NULL);
p = pattern;
while (*p) {
char *string = NULL;
- char *t;
/* If not a % marker, copy and continue */
if (*p != '%') {
@@ -917,12 +916,10 @@ filepath_parse_pattern (RhythmDB *db,
string = sanitize_path (rb_refstring_get_folded (albumartist));
break;
case 's':
- string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME));
+ string = sanitize_path (rb_refstring_get (albumartist_sort));
break;
case 'S':
- t = g_utf8_strdown (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME), -1);
- string = sanitize_path (t);
- g_free (t);
+ string = sanitize_path (rb_refstring_get_folded (albumartist_sort));
break;
case 'y':
string = g_strdup_printf ("%u", (guint)rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_YEAR));
@@ -966,9 +963,7 @@ filepath_parse_pattern (RhythmDB *db,
string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME));
break;
case 'S':
- t = g_utf8_strdown (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME), -1);
- string = sanitize_path (t);
- g_free (t);
+ string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME_FOLDED));
break;
case 'n':
/* Track number */
diff --git a/widgets/rb-query-creator-properties.c b/widgets/rb-query-creator-properties.c
index 3ad4f84..5175bc1 100644
--- a/widgets/rb-query-creator-properties.c
+++ b/widgets/rb-query-creator-properties.c
@@ -73,6 +73,7 @@ const RBQueryCreatorPropertyOption property_options[] =
{ NC_("query-criteria", "Title"), RHYTHMDB_PROP_TITLE, RHYTHMDB_PROP_TITLE_FOLDED, &string_property_type },
{ NC_("query-criteria", "Artist"), RHYTHMDB_PROP_ARTIST, RHYTHMDB_PROP_ARTIST_FOLDED, &string_property_type },
{ NC_("query-criteria", "Album"), RHYTHMDB_PROP_ALBUM, RHYTHMDB_PROP_ALBUM_FOLDED, &string_property_type },
+ { NC_("query-criteria", "Album Artist"), RHYTHMDB_PROP_ALBUM_ARTIST, RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED, &string_property_type },
{ NC_("query-criteria", "Genre"), RHYTHMDB_PROP_GENRE, RHYTHMDB_PROP_GENRE_FOLDED, &string_property_type },
{ NC_("query-criteria", "Year"), RHYTHMDB_PROP_DATE, RHYTHMDB_PROP_DATE, &year_property_type },
{ NC_("query-criteria", "Rating"), RHYTHMDB_PROP_RATING, RHYTHMDB_PROP_RATING, &rating_property_type },
@@ -100,6 +101,7 @@ const RBQueryCreatorSortOption sort_options[] =
{
{ NC_("query-sort", "Artist"), "Artist", N_("_In reverse alphabetical order") },
{ NC_("query-sort", "Album"), "Album", N_("_In reverse alphabetical order") },
+ { NC_("query-sort", "Album Artist"), "AlbumArtist", N_("_In reverse alphabetical order") },
{ NC_("query-sort", "Genre"), "Genre", N_("_In reverse alphabetical order") },
{ NC_("query-sort", "Title"), "Title", N_("_In reverse alphabetical order") },
{ NC_("query-sort", "Rating"), "Rating", N_("W_ith more highly rated tracks first") },
diff --git a/widgets/rb-song-info.c b/widgets/rb-song-info.c
index e0859e4..59f1ef1 100644
--- a/widgets/rb-song-info.c
+++ b/widgets/rb-song-info.c
@@ -126,6 +126,7 @@ struct RBSongInfoPrivate
GtkWidget *title;
GtkWidget *artist;
GtkWidget *album;
+ GtkWidget *album_artist;
GtkWidget *genre;
GtkWidget *track_cur;
GtkWidget *disc_cur;
@@ -137,6 +138,7 @@ struct RBSongInfoPrivate
GtkWidget *artist_sortname;
GtkWidget *album_sortname;
+ GtkWidget *album_artist_sortname;
GtkWidget *bitrate;
GtkWidget *duration;
@@ -489,6 +491,7 @@ rb_song_info_constructed (GObject *object)
song_info->priv->artist = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_artist"));
song_info->priv->album = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_album"));
+ song_info->priv->album_artist = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_album_artist"));
song_info->priv->genre = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_genre"));
song_info->priv->year = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_year"));
song_info->priv->comment = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_comment"));
@@ -499,6 +502,7 @@ rb_song_info_constructed (GObject *object)
song_info->priv->artist_sortname = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_artist_sortname"));
song_info->priv->album_sortname = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_album_sortname"));
+ song_info->priv->album_artist_sortname = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_album_artist_sortname"));
rb_song_info_add_completion (GTK_ENTRY (song_info->priv->genre), song_info->priv->genres);
rb_song_info_add_completion (GTK_ENTRY (song_info->priv->artist), song_info->priv->artists);
@@ -506,6 +510,7 @@ rb_song_info_constructed (GObject *object)
rb_builder_boldify_label (builder, "album_label");
rb_builder_boldify_label (builder, "artist_label");
+ rb_builder_boldify_label (builder, "album_artist_label");
rb_builder_boldify_label (builder, "genre_label");
rb_builder_boldify_label (builder, "year_label");
rb_builder_boldify_label (builder, "comment_label");
@@ -513,6 +518,7 @@ rb_song_info_constructed (GObject *object)
rb_builder_boldify_label (builder, "discn_label");
rb_builder_boldify_label (builder, "artist_sortname_label");
rb_builder_boldify_label (builder, "album_sortname_label");
+ rb_builder_boldify_label (builder, "album_artist_sortname_label");
g_signal_connect_object (G_OBJECT (song_info->priv->artist),
"mnemonic-activate",
@@ -522,6 +528,10 @@ rb_song_info_constructed (GObject *object)
"mnemonic-activate",
G_CALLBACK (rb_song_info_mnemonic_cb),
NULL, 0);
+ g_signal_connect_object (G_OBJECT (song_info->priv->album_artist),
+ "mnemonic-activate",
+ G_CALLBACK (rb_song_info_mnemonic_cb),
+ NULL, 0);
g_signal_connect_object (G_OBJECT (song_info->priv->genre),
"mnemonic-activate",
G_CALLBACK (rb_song_info_mnemonic_cb),
@@ -546,6 +556,10 @@ rb_song_info_constructed (GObject *object)
"mnemonic-activate",
G_CALLBACK (rb_song_info_mnemonic_cb),
NULL, 0);
+ g_signal_connect_object (G_OBJECT (song_info->priv->album_artist_sortname),
+ "mnemonic-activate",
+ G_CALLBACK (rb_song_info_mnemonic_cb),
+ NULL, 0);
/* this widget has to be customly created */
song_info->priv->rating = GTK_WIDGET (rb_rating_new ());
@@ -565,6 +579,7 @@ rb_song_info_constructed (GObject *object)
gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->artist), editable);
gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->album), editable);
+ gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->album_artist), editable);
gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->genre), editable);
gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->year), editable);
gtk_text_view_set_editable (GTK_TEXT_VIEW (song_info->priv->comment), editable);
@@ -914,20 +929,24 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
{
gboolean mixed_artists = FALSE;
gboolean mixed_albums = FALSE;
+ gboolean mixed_album_artists = FALSE;
gboolean mixed_genres = FALSE;
gboolean mixed_years = FALSE;
gboolean mixed_disc_numbers = FALSE;
gboolean mixed_ratings = FALSE;
gboolean mixed_artist_sortnames = FALSE;
gboolean mixed_album_sortnames = FALSE;
+ gboolean mixed_album_artist_sortnames = FALSE;
const char *artist = NULL;
const char *album = NULL;
+ const char *album_artist = NULL;
const char *genre = NULL;
int year = 0;
int disc_number = 0;
double rating = 0.0; /* Zero is used for both "unrated" and "mixed ratings" too */
const char *artist_sortname = NULL;
const char *album_sortname = NULL;
+ const char *album_artist_sortname = NULL;
GList *l;
g_assert (song_info->priv->selected_entries);
@@ -936,28 +955,34 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
RhythmDBEntry *entry;
const char *entry_artist;
const char *entry_album;
+ const char *entry_album_artist;
const char *entry_genre;
int entry_year;
int entry_disc_number;
double entry_rating;
const char *entry_artist_sortname;
const char *entry_album_sortname;
+ const char *entry_album_artist_sortname;
entry = (RhythmDBEntry*)l->data;
entry_artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
entry_album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
+ entry_album_artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_ARTIST);
entry_genre = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
entry_year = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_YEAR);
entry_disc_number = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_NUMBER);
entry_rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING);
entry_artist_sortname = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME);
entry_album_sortname = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_SORTNAME);
+ entry_album_artist_sortname = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME);
/* grab first valid values */
if (artist == NULL)
artist = entry_artist;
if (album == NULL)
album = entry_album;
+ if (album_artist == NULL)
+ album_artist = entry_album_artist;
if (genre == NULL)
genre = entry_genre;
if (year == 0)
@@ -970,12 +995,16 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
artist_sortname = entry_artist_sortname;
if (album_sortname == NULL)
album_sortname = entry_album_sortname;
+ if (album_artist_sortname == NULL)
+ album_artist_sortname = entry_album_artist_sortname;
/* locate mixed values */
if (artist != entry_artist)
mixed_artists = TRUE;
if (album != entry_album)
mixed_albums = TRUE;
+ if (album_artist != entry_album_artist)
+ mixed_album_artists = TRUE;
if (genre != entry_genre)
mixed_genres = TRUE;
if (year != entry_year)
@@ -988,6 +1017,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
mixed_artist_sortnames = TRUE;
if (album_sortname != entry_album_sortname)
mixed_album_sortnames = TRUE;
+ if (album_artist_sortname != entry_album_artist_sortname)
+ mixed_album_artist_sortnames = TRUE;
/* don't continue search if everything is mixed */
if (mixed_artists && mixed_albums && mixed_genres &&
@@ -1000,6 +1031,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->artist), artist);
if (!mixed_albums && album != NULL)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->album), album);
+ if (!mixed_album_artists && album_artist != NULL)
+ gtk_entry_set_text (GTK_ENTRY (song_info->priv->album_artist), album_artist);
if (!mixed_genres && genre != NULL)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->genre), genre);
if (!mixed_years && year != 0)
@@ -1012,6 +1045,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->artist_sortname), artist_sortname);
if (!mixed_album_sortnames && album_sortname != NULL)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->album_sortname), album_sortname);
+ if (!mixed_album_artist_sortnames && album_artist_sortname != NULL)
+ gtk_entry_set_text (GTK_ENTRY (song_info->priv->album_artist_sortname), album_artist_sortname);
}
static void
@@ -1037,6 +1072,8 @@ rb_song_info_populate_dialog (RBSongInfo *song_info)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->artist), text);
text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ALBUM);
gtk_entry_set_text (GTK_ENTRY (song_info->priv->album), text);
+ text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ALBUM_ARTIST);
+ gtk_entry_set_text (GTK_ENTRY (song_info->priv->album_artist), text);
text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_GENRE);
gtk_entry_set_text (GTK_ENTRY (song_info->priv->genre), text);
@@ -1063,6 +1100,8 @@ rb_song_info_populate_dialog (RBSongInfo *song_info)
gtk_entry_set_text (GTK_ENTRY (song_info->priv->artist_sortname), text);
text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ALBUM_SORTNAME);
gtk_entry_set_text (GTK_ENTRY (song_info->priv->album_sortname), text);
+ text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME);
+ gtk_entry_set_text (GTK_ENTRY (song_info->priv->album_artist_sortname), text);
}
static void
@@ -1452,16 +1491,41 @@ rb_song_info_update_date_added (RBSongInfo *song_info)
gtk_label_set_text (GTK_LABEL (song_info->priv->date_added), str);
}
+static gboolean
+sync_string_property (RBSongInfo *dialog, RhythmDBPropType property, GtkWidget *entry)
+{
+ const char *new_text;
+ GValue val = {0,};
+ GList *t;
+ gboolean changed = FALSE;
+
+ new_text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (strlen (new_text) == 0)
+ return FALSE;
+
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_string (&val, new_text);
+ for (t = dialog->priv->selected_entries; t != NULL; t = t->next) {
+ const char *entry_value;
+ RhythmDBEntry *dbentry;
+
+ dbentry = (RhythmDBEntry *)t->data;
+ entry_value = rhythmdb_entry_get_string (dbentry, property);
+
+ if (g_strcmp0 (new_text, entry_value) == 0)
+ continue;
+ rhythmdb_entry_set (dialog->priv->db, dbentry, property, &val);
+ changed = TRUE;
+ }
+ g_value_unset (&val);
+ return changed;
+}
+
static void
rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
{
- const char *genre = gtk_entry_get_text (GTK_ENTRY (dialog->priv->genre));
- const char *artist = gtk_entry_get_text (GTK_ENTRY (dialog->priv->artist));
- const char *album = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album));
const char *year_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->year));
const char *discn_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->disc_cur));
- const char *artist_sortname = gtk_entry_get_text (GTK_ENTRY (dialog->priv->artist_sortname));
- const char *album_sortname = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album_sortname));
char *endptr;
GValue val = {0,};
@@ -1471,59 +1535,13 @@ rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
gboolean changed = FALSE;
RhythmDBEntry *entry;
- if (strlen (album) > 0) {
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, album);
- for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
- const char *entry_album;
-
- entry = (RhythmDBEntry *)tem->data;
- entry_album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
-
- if (g_strcmp0 (album, entry_album) == 0)
- continue;
- rhythmdb_entry_set (dialog->priv->db, entry,
- RHYTHMDB_PROP_ALBUM, &val);
- changed = TRUE;
- }
- g_value_unset (&val);
- }
-
- if (strlen (artist) > 0) {
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, artist);
- for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
- const char *entry_artist;
-
- entry = (RhythmDBEntry *)tem->data;
- entry_artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
-
- if (g_strcmp0 (artist, entry_artist) == 0)
- continue;
- rhythmdb_entry_set (dialog->priv->db, entry,
- RHYTHMDB_PROP_ARTIST, &val);
- changed = TRUE;
- }
- g_value_unset (&val);
- }
-
- if (strlen (genre) > 0) {
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, genre);
- for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
- const char *entry_genre;
-
- entry = (RhythmDBEntry *)tem->data;
- entry_genre = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
-
- if (g_strcmp0 (genre, entry_genre) == 0)
- continue;
- rhythmdb_entry_set (dialog->priv->db, entry,
- RHYTHMDB_PROP_GENRE, &val);
- changed = TRUE;
- }
- g_value_unset (&val);
- }
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_ALBUM, dialog->priv->album);
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_ARTIST, dialog->priv->artist);
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_ALBUM_ARTIST, dialog->priv->album_artist);
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_GENRE, dialog->priv->genre);
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_ARTIST_SORTNAME, dialog->priv->artist_sortname);
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_ALBUM_SORTNAME, dialog->priv->album_sortname);
+ changed |= sync_string_property (dialog, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, dialog->priv->album_artist_sortname);
if (strlen (year_str) > 0) {
GDate *date = NULL;
@@ -1575,42 +1593,6 @@ rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
g_value_unset (&val);
}
- if (strlen (artist_sortname) > 0) {
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, artist_sortname);
- for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
- const char *entry_artist_sortname;
-
- entry = (RhythmDBEntry *)tem->data;
- entry_artist_sortname = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME);
-
- if (g_strcmp0 (artist_sortname, entry_artist_sortname) == 0)
- continue;
- rhythmdb_entry_set (dialog->priv->db, entry,
- RHYTHMDB_PROP_ARTIST_SORTNAME, &val);
- changed = TRUE;
- }
- g_value_unset (&val);
- }
-
- if (strlen (album_sortname) > 0) {
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, album_sortname);
- for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
- const char *entry_album_sortname;
-
- entry = (RhythmDBEntry *)tem->data;
- entry_album_sortname = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_SORTNAME);
-
- if (g_strcmp0 (album_sortname, entry_album_sortname) == 0)
- continue;
- rhythmdb_entry_set (dialog->priv->db, entry,
- RHYTHMDB_PROP_ALBUM_SORTNAME, &val);
- changed = TRUE;
- }
- g_value_unset (&val);
- }
-
if (changed)
rhythmdb_commit (dialog->priv->db);
}
@@ -1622,11 +1604,13 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
const char *genre;
const char *artist;
const char *album;
+ const char *album_artist;
const char *tracknum_str;
const char *discnum_str;
const char *year_str;
const char *artist_sortname;
const char *album_sortname;
+ const char *album_artist_sortname;
const char *entry_string;
char *comment = NULL;
char *endptr;
@@ -1644,11 +1628,13 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
genre = gtk_entry_get_text (GTK_ENTRY (dialog->priv->genre));
artist = gtk_entry_get_text (GTK_ENTRY (dialog->priv->artist));
album = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album));
+ album_artist = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album_artist));
tracknum_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->track_cur));
discnum_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->disc_cur));
year_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->year));
artist_sortname = gtk_entry_get_text (GTK_ENTRY (dialog->priv->artist_sortname));
album_sortname = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album_sortname));
+ album_artist_sortname = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album_artist_sortname));
/* Get comment text (string is allocated) */
gtk_text_buffer_get_bounds (dialog->priv->comment_buffer, &start, &end);
@@ -1748,6 +1734,18 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
changed = TRUE;
}
+ entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_ARTIST);
+ if (g_strcmp0 (album_artist, entry_string)) {
+ type = rhythmdb_get_property_type (dialog->priv->db,
+ RHYTHMDB_PROP_ALBUM_ARTIST);
+ g_value_init (&val, type);
+ g_value_set_string (&val, album_artist);
+ rhythmdb_entry_set (dialog->priv->db, entry,
+ RHYTHMDB_PROP_ALBUM_ARTIST, &val);
+ g_value_unset (&val);
+ changed = TRUE;
+ }
+
entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
if (g_strcmp0 (genre, entry_string)) {
type = rhythmdb_get_property_type (dialog->priv->db,
@@ -1785,7 +1783,7 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
}
entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMMENT);
- if (strcmp (comment, entry_string)) {
+ if (g_strcmp0 (comment, entry_string)) {
type = rhythmdb_get_property_type (dialog->priv->db,
RHYTHMDB_PROP_COMMENT);
g_value_init (&val, type);
@@ -1796,6 +1794,18 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
changed = TRUE;
}
+ entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME);
+ if (g_strcmp0 (album_artist_sortname, entry_string)) {
+ type = rhythmdb_get_property_type (dialog->priv->db,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME);
+ g_value_init (&val, type);
+ g_value_set_string (&val, album_artist_sortname);
+ rhythmdb_entry_set (dialog->priv->db, entry,
+ RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, &val);
+ g_value_unset (&val);
+ changed = TRUE;
+ }
+
/* FIXME: when an entry is SYNCed, a changed signal is emitted, and
* this signal is also emitted, aren't they redundant?
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]