[rhythmbox] add album-artist and album-artist-sortname fields



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">&#x25CF;</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">&#x25CF;</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">&#x25CF;</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">&#x25CF;</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]