[rhythmbox] Add composer tag support



commit b708659815ed4c133f381eeaf5cda2a29747a8bb
Author: David Mooter <theexternvoid gmail com>
Date:   Mon Apr 8 17:40:37 2013 -0400

    Add composer tag support
    
    * View and edit the composer tag and composer sort tag in the two song info
    dialogs.
    * Preferences can add composer as a column to the library browser.
    * Ability to sort the library by the composer column.
    * Search results include composer tag.
    * Ability to use composer as a parameter in automatic playlists.
    * Incremented version to 1.9 for rhythm DB, reloads all metadata so as to get
    the composer into the DB.
    * Italian translation of a few new strings related to composer. (It's my other
    language, might as well do that, too.)
    
    Plug-ins:
    * iPod support was programmed and tested. Composer tag is now copied to the
    iTunes DB on the iPod.

 data/ui/general-prefs.ui              |   60 ++++++++++++-------
 data/ui/song-info-multiple.ui         |   89 +++++++++++++++++++++++-----
 data/ui/song-info.ui                  |  105 +++++++++++++++++++++++++--------
 metadata/rb-metadata-common.c         |    6 ++
 metadata/rb-metadata-gst-common.c     |    8 +++
 metadata/rb-metadata.h                |    2 +
 plugins/ipod/rb-ipod-source.c         |   15 +++++
 po/it.po                              |    9 +++
 rhythmdb/rhythmdb-private.h           |    2 +
 rhythmdb/rhythmdb-property-model.c    |   22 +++++++
 rhythmdb/rhythmdb-query-model.c       |   45 ++++++++++++++
 rhythmdb/rhythmdb-query-model.h       |    4 +
 rhythmdb/rhythmdb-query.c             |    1 +
 rhythmdb/rhythmdb-tree.c              |   18 +++++-
 rhythmdb/rhythmdb.c                   |   55 +++++++++++++++++-
 rhythmdb/rhythmdb.h                   |    7 ++
 shell/rb-shell-preferences.c          |    1 +
 sources/rb-browser-source.c           |    1 +
 sources/rb-playlist-source.c          |    1 +
 widgets/rb-entry-view.c               |   15 +++++
 widgets/rb-entry-view.h               |    3 +-
 widgets/rb-query-creator-properties.c |    2 +
 widgets/rb-song-info.c                |   78 +++++++++++++++++++++++-
 23 files changed, 481 insertions(+), 68 deletions(-)
---
diff --git a/data/ui/general-prefs.ui b/data/ui/general-prefs.ui
index 4a1833d..e7d8fed 100644
--- a/data/ui/general-prefs.ui
+++ b/data/ui/general-prefs.ui
@@ -241,9 +241,9 @@
                                 <property name="y_options"></property>
                               </packing>
                             </child>
-                            <child>
-                              <object class="GtkCheckButton" id="album_check">
-                                <property name="label" translatable="yes">A_lbum</property>
+                           <child>
+                              <object class="GtkCheckButton" id="composer_check">
+                                <property name="label" translatable="yes">_Composer</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
@@ -257,6 +257,22 @@
                                 <property name="y_options"></property>
                               </packing>
                             </child>
+                             <child>
+                              <object class="GtkCheckButton" id="album_check">
+                                <property name="label" translatable="yes">A_lbum</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
                             <child>
                               <object class="GtkCheckButton" id="year_check">
                                 <property name="label" translatable="yes">_Year</property>
@@ -285,8 +301,8 @@
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
                                 <property name="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -302,10 +318,8 @@
                                 <property name="draw_indicator">True</property>
                               </object>
                               <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="left_attach">2</property>
+                                <property name="right_attach">3</property>
                                 <property name="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -323,6 +337,8 @@
                               <packing>
                                 <property name="left_attach">2</property>
                                 <property name="right_attach">3</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
                                 <property name="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -340,8 +356,8 @@
                               <packing>
                                 <property name="left_attach">2</property>
                                 <property name="right_attach">3</property>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
+                                <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>
@@ -359,8 +375,8 @@
                               <packing>
                                 <property name="left_attach">2</property>
                                 <property name="right_attach">3</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="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -378,8 +394,8 @@
                               <packing>
                                 <property name="left_attach">2</property>
                                 <property name="right_attach">3</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="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -397,8 +413,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="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -416,8 +432,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="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
@@ -435,8 +451,8 @@
                               <packing>
                                 <property name="left_attach">1</property>
                                 <property name="right_attach">2</property>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
+                                <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>
@@ -454,6 +470,8 @@
                               <packing>
                                 <property name="left_attach">1</property>
                                 <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
                                 <property name="x_options">GTK_FILL</property>
                                 <property name="y_options"></property>
                               </packing>
diff --git a/data/ui/song-info-multiple.ui b/data/ui/song-info-multiple.ui
index a6812ff..18a1c5f 100644
--- a/data/ui/song-info-multiple.ui
+++ b/data/ui/song-info-multiple.ui
@@ -78,8 +78,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>
@@ -94,8 +94,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>
@@ -108,8 +108,8 @@
             <property name="use_underline">True</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>
@@ -125,8 +125,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="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">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>
@@ -156,8 +156,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>
@@ -170,8 +170,8 @@
             <property name="mnemonic_widget">song_info_disc_cur</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>
@@ -186,8 +186,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>
@@ -219,6 +219,34 @@
             <property name="y_options"></property>
           </packing>
         </child>
+        <child>
+          <object class="GtkLabel" id="composer_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">_Composer:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">song_info_composer</property>
+          </object>
+          <packing>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="song_info_composer">
+            <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>
     </child>
     <child type="tab">
@@ -324,6 +352,35 @@
             <property name="y_options">GTK_FILL</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkLabel" id="composer_sortname_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">_Composer sort order:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">song_info_composer_sortname</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_composer_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">3</property>
+            <property name="bottom_attach">4</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 9fcc6c4..644bf48 100644
--- a/data/ui/song-info.ui
+++ b/data/ui/song-info.ui
@@ -108,8 +108,8 @@
                 <property name="mnemonic_widget">song_info_track_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>
@@ -123,8 +123,8 @@
                 <property name="mnemonic_widget">song_info_genre</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>
@@ -143,8 +143,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>
@@ -161,8 +161,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>
@@ -190,8 +190,8 @@
                 <property name="mnemonic_widget">song_info_disc_cur</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>
@@ -209,8 +209,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>
@@ -227,8 +227,8 @@
               <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>
                 <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">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>
@@ -265,8 +265,8 @@
               <packing>
                 <property name="left_attach">1</property>
                 <property name="right_attach">2</property>
-                <property name="top_attach">8</property>
-                <property name="bottom_attach">9</property>
+                <property name="top_attach">9</property>
+                <property name="bottom_attach">10</property>
                 <property name="y_options"></property>
               </packing>
             </child>
@@ -291,8 +291,8 @@
                 <property name="angle">0</property>
               </object>
               <packing>
-                <property name="top_attach">8</property>
-                <property name="bottom_attach">9</property>
+                <property name="top_attach">9</property>
+                <property name="bottom_attach">10</property>
                 <property name="x_options">fill</property>
                 <property name="y_options"></property>
               </packing>
@@ -306,8 +306,8 @@
                 <property name="mnemonic_widget">song_info_comment</property>
               </object>
               <packing>
-                <property name="top_attach">9</property>
-                <property name="bottom_attach">10</property>
+                <property name="top_attach">10</property>
+                <property name="bottom_attach">11</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options"></property>
               </packing>
@@ -329,8 +329,8 @@
               <packing>
                 <property name="left_attach">1</property>
                 <property name="right_attach">2</property>
-                <property name="top_attach">9</property>
-                <property name="bottom_attach">10</property>
+                <property name="top_attach">10</property>
+                <property name="bottom_attach">11</property>
               </packing>
             </child>
             <child>
@@ -362,6 +362,35 @@
                 <property name="y_options"></property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel" id="composer_label">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">_Composer:</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">song_info_composer</property>
+              </object>
+              <packing>
+                <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>
+            </child>
+            <child>
+              <object class="GtkEntry" id="song_info_composer">
+                <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">4</property>
+                <property name="bottom_attach">5</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="position">0</property>
@@ -513,6 +542,34 @@
             <property name="y_options">GTK_FILL</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkLabel" id="composer_sortname_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">_Composer sort order:</property>
+            <property name="use_underline">True</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_composer_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">3</property>
+            <property name="bottom_attach">4</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 d401e37..31b555b 100644
--- a/metadata/rb-metadata-common.c
+++ b/metadata/rb-metadata-common.c
@@ -67,6 +67,8 @@
  * @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_COMPOSER: The composer of the recording
+ * @RB_METADATA_FIELD_COMPOSER_SORTNAME: The composer of the recording, as it should be sorted
  * @RB_METADATA_FIELD_LAST:  invalid field
  *
  * Metadata fields that can be read from and written to files.
@@ -107,6 +109,8 @@ rb_metadata_get_field_type (RBMetaDataField field)
        case RB_METADATA_FIELD_ALBUM_SORTNAME:
        case RB_METADATA_FIELD_ALBUM_ARTIST:
        case RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME:
+       case RB_METADATA_FIELD_COMPOSER:
+       case RB_METADATA_FIELD_COMPOSER_SORTNAME:
                return G_TYPE_STRING;
 
        case RB_METADATA_FIELD_DATE:
@@ -209,6 +213,8 @@ rb_metadata_field_get_type (void)
                        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"),
+                       ENUM_ENTRY (RB_METADATA_FIELD_COMPOSER, "composer"),
+                       ENUM_ENTRY (RB_METADATA_FIELD_COMPOSER_SORTNAME, "composer-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 42774cb..b384334 100644
--- a/metadata/rb-metadata-gst-common.c
+++ b/metadata/rb-metadata-gst-common.c
@@ -108,6 +108,10 @@ rb_metadata_gst_tag_to_field (const char *tag)
                return RB_METADATA_FIELD_ALBUM_ARTIST;
        else if (!strcmp (tag, GST_TAG_ALBUM_ARTIST_SORTNAME))
                return RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME;
+       else if (!strcmp (tag, GST_TAG_COMPOSER))
+               return RB_METADATA_FIELD_COMPOSER;
+       else if (!strcmp (tag, GST_TAG_COMPOSER_SORTNAME))
+               return RB_METADATA_FIELD_COMPOSER_SORTNAME;
        else
                return -1;
 }
@@ -185,6 +189,10 @@ rb_metadata_gst_field_to_gst_tag (RBMetaDataField field)
                return GST_TAG_ALBUM_ARTIST;
        case RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME:
                return GST_TAG_ALBUM_ARTIST_SORTNAME;
+       case RB_METADATA_FIELD_COMPOSER:
+               return GST_TAG_COMPOSER;
+       case RB_METADATA_FIELD_COMPOSER_SORTNAME:
+               return GST_TAG_COMPOSER_SORTNAME;
        default:
                return NULL;
        }
diff --git a/metadata/rb-metadata.h b/metadata/rb-metadata.h
index 8d57cae..0314080 100644
--- a/metadata/rb-metadata.h
+++ b/metadata/rb-metadata.h
@@ -69,6 +69,8 @@ typedef enum
        RB_METADATA_FIELD_ALBUM_SORTNAME,          /* string */
        RB_METADATA_FIELD_ALBUM_ARTIST,            /* string */
        RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME,   /* string */
+       RB_METADATA_FIELD_COMPOSER,            /* string */
+       RB_METADATA_FIELD_COMPOSER_SORTNAME,   /* string */
 
        RB_METADATA_FIELD_LAST                     /* nothing */
 } RBMetaDataField;
diff --git a/plugins/ipod/rb-ipod-source.c b/plugins/ipod/rb-ipod-source.c
index 13de14f..f0f6db7 100644
--- a/plugins/ipod/rb-ipod-source.c
+++ b/plugins/ipod/rb-ipod-source.c
@@ -786,9 +786,12 @@ create_ipod_song_from_entry (RhythmDBEntry *entry, guint64 filesize, const char
        track->title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
        track->album = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);
        track->artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
+       track->composer = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_COMPOSER);
        track->albumartist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM_ARTIST);
        track->sort_artist = rhythmdb_entry_dup_string (entry,
                                                        RHYTHMDB_PROP_ARTIST_SORTNAME);
+       track->sort_composer = rhythmdb_entry_dup_string (entry,
+                                                       RHYTHMDB_PROP_COMPOSER_SORTNAME);
        track->sort_album = rhythmdb_entry_dup_string (entry,
                                                        RHYTHMDB_PROP_ALBUM_SORTNAME);
        track->sort_albumartist = rhythmdb_entry_dup_string (entry,
@@ -1001,6 +1004,12 @@ add_ipod_song_to_db (RBiPodSource *source, RhythmDB *db, Itdb_Track *song)
        entry_set_string_prop (RHYTHMDB (db), entry,
                               RHYTHMDB_PROP_ARTIST, song->artist);
 
+       if (song->composer != NULL) {
+                entry_set_string_prop (RHYTHMDB (db), entry,
+                                       RHYTHMDB_PROP_COMPOSER,
+                                       song->composer);
+       }
+
        if (song->albumartist != NULL) {
                 entry_set_string_prop (RHYTHMDB (db), entry,
                                        RHYTHMDB_PROP_ALBUM_ARTIST,
@@ -1013,6 +1022,12 @@ add_ipod_song_to_db (RBiPodSource *source, RhythmDB *db, Itdb_Track *song)
                                        song->sort_artist);
         }
 
+       if (song->sort_composer != NULL) {
+                entry_set_string_prop (RHYTHMDB (db), entry,
+                                       RHYTHMDB_PROP_COMPOSER_SORTNAME,
+                                       song->composer);
+       }
+
         if (song->sort_album != NULL) {
                 entry_set_string_prop (RHYTHMDB (db), entry,
                                        RHYTHMDB_PROP_ALBUM_SORTNAME,
diff --git a/po/it.po b/po/it.po
index d918885..a55159e 100644
--- a/po/it.po
+++ b/po/it.po
@@ -4568,3 +4568,12 @@ msgstr "Sulla scrivania"
 #: ../widgets/rb-song-info.c:1256
 msgid "Unknown location"
 msgstr "Posizione sconosciuta"
+
+msgid "Composer"
+msgstr "Compositore"
+
+msgid "_Composer:"
+msgstr "_Compositore:"
+
+msgid "_Composer sort order:"
+msgstr "Ordinamento _compositore:"
diff --git a/rhythmdb/rhythmdb-private.h b/rhythmdb/rhythmdb-private.h
index f0ed813..1310136 100644
--- a/rhythmdb/rhythmdb-private.h
+++ b/rhythmdb/rhythmdb-private.h
@@ -75,6 +75,7 @@ struct _RhythmDBEntry {
        /* metadata */
        RBRefString *title;
        RBRefString *artist;
+       RBRefString *composer;
        RBRefString *album;
        RBRefString *album_artist;
        RBRefString *genre;
@@ -84,6 +85,7 @@ struct _RhythmDBEntry {
        RBRefString *musicbrainz_albumid;
        RBRefString *musicbrainz_albumartistid;
        RBRefString *artist_sortname;
+       RBRefString *composer_sortname;
        RBRefString *album_sortname;
        RBRefString *album_artist_sortname;
        gulong tracknum;
diff --git a/rhythmdb/rhythmdb-property-model.c b/rhythmdb/rhythmdb-property-model.c
index c905984..4facbce 100644
--- a/rhythmdb/rhythmdb-property-model.c
+++ b/rhythmdb/rhythmdb-property-model.c
@@ -136,6 +136,7 @@ enum {
        TARGET_LOCATION,
        TARGET_ENTRIES,
        TARGET_URIS,
+       TARGET_COMPOSERS
 };
 
 static const GtkTargetEntry targets_album  [] = {
@@ -158,11 +159,17 @@ static const GtkTargetEntry targets_location [] = {
        { "application/x-rhythmbox-entry", 0, TARGET_ENTRIES },
        { "text/uri-list", 0, TARGET_URIS },
 };
+static const GtkTargetEntry targets_composer [] = {
+       { "text/x-rhythmbox-composer", 0, TARGET_COMPOSERS },
+       { "application/x-rhythmbox-entry", 0, TARGET_ENTRIES },
+       { "text/uri-list", 0, TARGET_URIS },
+};
 
 static GtkTargetList *rhythmdb_property_model_album_drag_target_list = NULL;
 static GtkTargetList *rhythmdb_property_model_artist_drag_target_list = NULL;
 static GtkTargetList *rhythmdb_property_model_genre_drag_target_list = NULL;
 static GtkTargetList *rhythmdb_property_model_location_drag_target_list = NULL;
+static GtkTargetList *rhythmdb_property_model_composer_drag_target_list = NULL;
 
 struct RhythmDBPropertyModelPrivate
 {
@@ -426,6 +433,10 @@ rhythmdb_property_model_set_property (GObject *object,
                case RHYTHMDB_PROP_LOCATION:
                        append_sort_property (model, RHYTHMDB_PROP_TITLE);
                        break;
+               case RHYTHMDB_PROP_COMPOSER:
+                       append_sort_property (model, RHYTHMDB_PROP_COMPOSER_SORTNAME);
+                       append_sort_property (model, RHYTHMDB_PROP_COMPOSER);
+                       break;
                default:
                        g_assert_not_reached ();
                        break;
@@ -483,6 +494,10 @@ rhythmdb_property_model_init (RhythmDBPropertyModel *model)
                rhythmdb_property_model_location_drag_target_list =
                        gtk_target_list_new (targets_location,
                                             G_N_ELEMENTS (targets_location));
+       if (!rhythmdb_property_model_composer_drag_target_list)
+               rhythmdb_property_model_composer_drag_target_list =
+                       gtk_target_list_new (targets_composer,
+                                            G_N_ELEMENTS (targets_composer));
 
        model->priv = RHYTHMDB_PROPERTY_MODEL_GET_PRIVATE (model);
 
@@ -1215,6 +1230,9 @@ rhythmdb_property_model_drag_data_get (RbTreeDragSource *dragsource,
        case RHYTHMDB_PROP_LOCATION:
                drag_target_list = rhythmdb_property_model_location_drag_target_list;
                break;
+       case RHYTHMDB_PROP_COMPOSER:
+               drag_target_list = rhythmdb_property_model_composer_drag_target_list;
+               break;
        default:
                g_assert_not_reached ();
        }
@@ -1385,6 +1403,10 @@ rhythmdb_property_model_enable_drag (RhythmDBPropertyModel *model,
                targets = targets_location;
                n_elements = G_N_ELEMENTS (targets_location);
                break;
+       case RHYTHMDB_PROP_COMPOSER:
+               targets = targets_composer;
+               n_elements = G_N_ELEMENTS (targets_composer);
+               break;
        default:
                g_assert_not_reached ();
        }
diff --git a/rhythmdb/rhythmdb-query-model.c b/rhythmdb/rhythmdb-query-model.c
index abb1a55..acbe5d9 100644
--- a/rhythmdb/rhythmdb-query-model.c
+++ b/rhythmdb/rhythmdb-query-model.c
@@ -3034,6 +3034,51 @@ rhythmdb_query_model_artist_sort_func (RhythmDBEntry *a,
 }
 
 /**
+ * rhythmdb_query_model_composer_sort_func:
+ * @a: a #RhythmDBEntry
+ * @b: a #RhythmDBEntry
+ * @data: nothing
+ *
+ * Sort function for sorting by composer.  Sorts by composer, then
+ * album, then disc number, then track number, then title.
+ *
+ * Returns: result of sort comparison between a and b.
+ */
+gint
+rhythmdb_query_model_composer_sort_func (RhythmDBEntry *a,
+                                      RhythmDBEntry *b,
+                                      gpointer data)
+{
+       const char *a_val;
+       const char *b_val;
+       gint ret;
+
+       a_val = rhythmdb_entry_get_string (a, RHYTHMDB_PROP_COMPOSER_SORTNAME_SORT_KEY);
+       if (a_val[0] == '\0') {
+               a_val = rhythmdb_entry_get_string (a, RHYTHMDB_PROP_COMPOSER_SORT_KEY);
+       }
+       b_val = rhythmdb_entry_get_string (b, RHYTHMDB_PROP_COMPOSER_SORTNAME_SORT_KEY);
+       if (b_val[0] == '\0') {
+               b_val = rhythmdb_entry_get_string (b, RHYTHMDB_PROP_COMPOSER_SORT_KEY);
+       }
+
+       if (a_val == NULL) {
+               if (b_val == NULL)
+                       ret = 0;
+               else
+                       ret = -1;
+       } else if (b_val == NULL)
+               ret = 1;
+       else
+               ret = strcmp (a_val, b_val);
+
+       if (ret != 0)
+               return ret;
+       else
+               return rhythmdb_query_model_album_sort_func (a, b, data);
+}
+
+/**
  * rhythmdb_query_model_genre_sort_func:
  * @a: a #RhythmDBEntry
  * @b: a #RhythmDBEntry
diff --git a/rhythmdb/rhythmdb-query-model.h b/rhythmdb/rhythmdb-query-model.h
index db4c3f7..fd575ec 100644
--- a/rhythmdb/rhythmdb-query-model.h
+++ b/rhythmdb/rhythmdb-query-model.h
@@ -172,6 +172,10 @@ gint                       rhythmdb_query_model_artist_sort_func   (RhythmDBEntry *a,
                                                                 RhythmDBEntry *b,
                                                                 gpointer data);
 
+gint                   rhythmdb_query_model_composer_sort_func (RhythmDBEntry *a,
+                                                                RhythmDBEntry *b,
+                                                                gpointer data);
+
 gint                   rhythmdb_query_model_genre_sort_func    (RhythmDBEntry *a,
                                                                 RhythmDBEntry *b,
                                                                 gpointer data);
diff --git a/rhythmdb/rhythmdb-query.c b/rhythmdb/rhythmdb-query.c
index c8fbd77..3e7c075 100644
--- a/rhythmdb/rhythmdb-query.c
+++ b/rhythmdb/rhythmdb-query.c
@@ -756,6 +756,7 @@ rhythmdb_query_preprocess (RhythmDB *db, GPtrArray *query)
                        case RHYTHMDB_PROP_TITLE_FOLDED:
                        case RHYTHMDB_PROP_GENRE_FOLDED:
                        case RHYTHMDB_PROP_ARTIST_FOLDED:
+                       case RHYTHMDB_PROP_COMPOSER_FOLDED:
                        case RHYTHMDB_PROP_ALBUM_FOLDED:
                        {
                                /* as we are matching against a folded property, the string needs to also be 
folded */
diff --git a/rhythmdb/rhythmdb-tree.c b/rhythmdb/rhythmdb-tree.c
index 4c26eba..c4c7295 100644
--- a/rhythmdb/rhythmdb-tree.c
+++ b/rhythmdb/rhythmdb-tree.c
@@ -115,8 +115,8 @@ static void rhythmdb_hash_tree_foreach (RhythmDB *adb,
                                        gpointer data);
 
 /* Update both of those! */
-#define RHYTHMDB_TREE_XML_VERSION "1.8"
-#define RHYTHMDB_TREE_XML_VERSION_INT 180
+#define RHYTHMDB_TREE_XML_VERSION "1.9"
+#define RHYTHMDB_TREE_XML_VERSION_INT 190
 
 static void destroy_tree_property (RhythmDBTreeProperty *prop);
 static RhythmDBTreeProperty *get_or_create_album (RhythmDBTree *db, RhythmDBTreeProperty *artist,
@@ -397,6 +397,9 @@ rhythmdb_tree_parser_start_element (struct RhythmDBTreeLoadContext *ctx,
                                        case 170:
                                                rb_debug ("reloading all file metadata to get new media 
types");
                                                ctx->reload_all_metadata = TRUE;
+                                       case 180:
+                                               rb_debug ("reloading all file metadata to get composer tag");
+                                               ctx->reload_all_metadata = TRUE;
                                        case RHYTHMDB_TREE_XML_VERSION_INT:
                                                /* current version */
                                                break;
@@ -997,6 +1000,9 @@ save_entry (RhythmDBTree *db,
                case RHYTHMDB_PROP_ARTIST:
                        save_entry_string(ctx, elt_name, rb_refstring_get (entry->artist));
                        break;
+               case RHYTHMDB_PROP_COMPOSER:
+                       save_entry_string_if_set(ctx, elt_name, rb_refstring_get (entry->composer));
+                       break;
                case RHYTHMDB_PROP_ALBUM_ARTIST:
                        save_entry_string_if_set(ctx, elt_name, rb_refstring_get (entry->album_artist));
                        break;
@@ -1021,6 +1027,9 @@ save_entry (RhythmDBTree *db,
                case RHYTHMDB_PROP_ARTIST_SORTNAME:
                        save_entry_string_if_set (ctx, elt_name, rb_refstring_get (entry->artist_sortname));
                        break;
+               case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+                       save_entry_string_if_set (ctx, elt_name, rb_refstring_get (entry->composer_sortname));
+                       break;
                case RHYTHMDB_PROP_ALBUM_SORTNAME:
                        save_entry_string_if_set (ctx, elt_name, rb_refstring_get (entry->album_sortname));
                        break;
@@ -1136,17 +1145,21 @@ save_entry (RhythmDBTree *db,
                case RHYTHMDB_PROP_TITLE_SORT_KEY:
                case RHYTHMDB_PROP_GENRE_SORT_KEY:
                case RHYTHMDB_PROP_ARTIST_SORT_KEY:
+               case RHYTHMDB_PROP_COMPOSER_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_COMPOSER_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_COMPOSER_FOLDED:
                case RHYTHMDB_PROP_ALBUM_FOLDED:
                case RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED:
                case RHYTHMDB_PROP_ARTIST_SORTNAME_FOLDED:
+               case RHYTHMDB_PROP_COMPOSER_SORTNAME_FOLDED:
                case RHYTHMDB_PROP_ALBUM_SORTNAME_FOLDED:
                case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED:
                case RHYTHMDB_PROP_LAST_PLAYED_STR:
@@ -1855,6 +1868,7 @@ search_match_properties (RhythmDB *db,
                RHYTHMDB_PROP_TITLE_FOLDED,
                RHYTHMDB_PROP_ALBUM_FOLDED,
                RHYTHMDB_PROP_ARTIST_FOLDED,
+               RHYTHMDB_PROP_COMPOSER_FOLDED,
                RHYTHMDB_PROP_GENRE_FOLDED
        };
        gboolean islike = TRUE;
diff --git a/rhythmdb/rhythmdb.c b/rhythmdb/rhythmdb.c
index 74967e3..3ead1a1 100644
--- a/rhythmdb/rhythmdb.c
+++ b/rhythmdb/rhythmdb.c
@@ -151,9 +151,16 @@ static const RhythmDBPropertyDef rhythmdb_properties[] = {
        PROP_ENTRY(ALBUM_ARTIST_SORTNAME, G_TYPE_STRING, "album-artist-sortname"),
        PROP_ENTRY(ALBUM_ARTIST_SORTNAME_SORT_KEY, G_TYPE_STRING, "album-artist-sortname-sort-key"),
        PROP_ENTRY(ALBUM_ARTIST_SORTNAME_FOLDED, G_TYPE_STRING, "album-artist-sortname-folded"),
-
+       
        PROP_ENTRY(BPM, G_TYPE_DOUBLE, "beats-per-minute"),
 
+       PROP_ENTRY(COMPOSER, G_TYPE_STRING, "composer"),
+       PROP_ENTRY(COMPOSER_SORT_KEY, G_TYPE_STRING, "composer-sort-key"),
+       PROP_ENTRY(COMPOSER_FOLDED, G_TYPE_STRING, "composer-folded"),
+       PROP_ENTRY(COMPOSER_SORTNAME, G_TYPE_STRING, "composer-sortname"),
+       PROP_ENTRY(COMPOSER_SORTNAME_SORT_KEY, G_TYPE_STRING, "composer-sortname-sort-key"),
+       PROP_ENTRY(COMPOSER_SORTNAME_FOLDED, G_TYPE_STRING, "composer-sortname-folded"),
+
        { 0, 0, 0, 0 }
 };
 
@@ -672,6 +679,12 @@ metadata_field_from_prop (RhythmDBPropType prop,
        case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
                *field = RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME;
                return TRUE;
+       case RHYTHMDB_PROP_COMPOSER:
+               *field = RB_METADATA_FIELD_COMPOSER;
+               return TRUE;
+       case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+               *field = RB_METADATA_FIELD_COMPOSER_SORTNAME;
+               return TRUE;
        default:
                return FALSE;
        }
@@ -1636,6 +1649,7 @@ rhythmdb_entry_allocate (RhythmDB *db,
        ret->title = rb_refstring_ref (db->priv->empty_string);
        ret->genre = rb_refstring_ref (db->priv->empty_string);
        ret->artist = rb_refstring_ref (db->priv->empty_string);
+       ret->composer = 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);
@@ -1644,6 +1658,7 @@ rhythmdb_entry_allocate (RhythmDB *db,
        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->composer_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->media_type = rb_refstring_ref (db->priv->octet_stream_str);
@@ -1833,6 +1848,7 @@ rhythmdb_entry_finalize (RhythmDBEntry *entry)
        rb_refstring_unref (entry->title);
        rb_refstring_unref (entry->genre);
        rb_refstring_unref (entry->artist);
+       rb_refstring_unref (entry->composer);
        rb_refstring_unref (entry->album);
        rb_refstring_unref (entry->comment);
        rb_refstring_unref (entry->musicbrainz_trackid);
@@ -1840,6 +1856,7 @@ rhythmdb_entry_finalize (RhythmDBEntry *entry)
        rb_refstring_unref (entry->musicbrainz_albumid);
        rb_refstring_unref (entry->musicbrainz_albumartistid);
        rb_refstring_unref (entry->artist_sortname);
+       rb_refstring_unref (entry->composer_sortname);
        rb_refstring_unref (entry->album_sortname);
        rb_refstring_unref (entry->media_type);
 
@@ -2057,6 +2074,18 @@ set_props_from_metadata (RhythmDB *db,
                                          RB_METADATA_FIELD_ALBUM_ARTIST_SORTNAME,
                                          RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME,
                                          "");
+
+       /* composer */
+       set_metadata_string_with_default (db, metadata, entry,
+                                         RB_METADATA_FIELD_COMPOSER,
+                                         RHYTHMDB_PROP_COMPOSER,
+                                         _("Unknown"));
+
+       /* composer sortname */
+       set_metadata_string_with_default (db, metadata, entry,
+                                         RB_METADATA_FIELD_COMPOSER_SORTNAME,
+                                         RHYTHMDB_PROP_COMPOSER_SORTNAME,
+                                         "");
 }
 
 static void
@@ -3510,6 +3539,14 @@ rhythmdb_entry_set_internal (RhythmDB *db,
                        rb_refstring_unref (entry->album_artist_sortname);
                        entry->album_artist_sortname = rb_refstring_new (g_value_get_string (value));
                        break;
+               case RHYTHMDB_PROP_COMPOSER:
+                       rb_refstring_unref (entry->composer);
+                       entry->composer = rb_refstring_new (g_value_get_string (value));
+                       break;
+               case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+                       rb_refstring_unref (entry->composer_sortname);
+                       entry->composer_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;
@@ -4736,6 +4773,10 @@ rhythmdb_entry_get_string (RhythmDBEntry *entry,
                return rb_refstring_get (entry->album_artist);
        case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
                return rb_refstring_get (entry->album_artist_sortname);
+       case RHYTHMDB_PROP_COMPOSER:
+               return rb_refstring_get (entry->composer);
+       case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+               return rb_refstring_get (entry->composer_sortname);
        case RHYTHMDB_PROP_MEDIA_TYPE:
                return rb_refstring_get (entry->media_type);
        case RHYTHMDB_PROP_TITLE_SORT_KEY:
@@ -4754,6 +4795,10 @@ rhythmdb_entry_get_string (RhythmDBEntry *entry,
                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_COMPOSER_SORT_KEY:
+               return rb_refstring_get_sort_key (entry->composer);
+       case RHYTHMDB_PROP_COMPOSER_SORTNAME_SORT_KEY:
+               return rb_refstring_get_sort_key (entry->composer_sortname);
        case RHYTHMDB_PROP_TITLE_FOLDED:
                return rb_refstring_get_folded (entry->title);
        case RHYTHMDB_PROP_ALBUM_FOLDED:
@@ -4770,6 +4815,10 @@ rhythmdb_entry_get_string (RhythmDBEntry *entry,
                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_COMPOSER_FOLDED:
+               return rb_refstring_get_folded (entry->composer);
+       case RHYTHMDB_PROP_COMPOSER_SORTNAME_FOLDED:
+               return rb_refstring_get_folded (entry->composer_sortname);
        case RHYTHMDB_PROP_LOCATION:
                return rb_refstring_get (entry->location);
        case RHYTHMDB_PROP_MOUNTPOINT:
@@ -4854,6 +4903,8 @@ rhythmdb_entry_get_refstring (RhythmDBEntry *entry,
                return rb_refstring_ref (entry->artist);
        case RHYTHMDB_PROP_ALBUM_ARTIST:
                return rb_refstring_ref (entry->album_artist);
+       case RHYTHMDB_PROP_COMPOSER:
+               return rb_refstring_ref (entry->composer);
        case RHYTHMDB_PROP_GENRE:
                return rb_refstring_ref (entry->genre);
        case RHYTHMDB_PROP_COMMENT:
@@ -4872,6 +4923,8 @@ rhythmdb_entry_get_refstring (RhythmDBEntry *entry,
                return rb_refstring_ref (entry->album_sortname);
        case RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME:
                return rb_refstring_ref (entry->album_artist_sortname);
+       case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+               return rb_refstring_ref (entry->composer_sortname);
        case RHYTHMDB_PROP_MEDIA_TYPE:
                return rb_refstring_ref (entry->media_type);
        case RHYTHMDB_PROP_MOUNTPOINT:
diff --git a/rhythmdb/rhythmdb.h b/rhythmdb/rhythmdb.h
index 23ee7b9..2c796a0 100644
--- a/rhythmdb/rhythmdb.h
+++ b/rhythmdb/rhythmdb.h
@@ -167,6 +167,13 @@ typedef enum
        RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED,
        RHYTHMDB_PROP_BPM,
 
+       RHYTHMDB_PROP_COMPOSER,
+       RHYTHMDB_PROP_COMPOSER_SORT_KEY,
+       RHYTHMDB_PROP_COMPOSER_FOLDED,
+       RHYTHMDB_PROP_COMPOSER_SORTNAME,
+       RHYTHMDB_PROP_COMPOSER_SORTNAME_SORT_KEY,
+       RHYTHMDB_PROP_COMPOSER_SORTNAME_FOLDED,
+       
        RHYTHMDB_NUM_PROPERTIES
 } RhythmDBPropType;
 
diff --git a/shell/rb-shell-preferences.c b/shell/rb-shell-preferences.c
index e1d4711..19fad98 100644
--- a/shell/rb-shell-preferences.c
+++ b/shell/rb-shell-preferences.c
@@ -97,6 +97,7 @@ struct {
 } column_checks[] = {
        { "track_check",        RHYTHMDB_PROP_TRACK_NUMBER },
        { "artist_check",       RHYTHMDB_PROP_ARTIST },
+       { "composer_check",     RHYTHMDB_PROP_COMPOSER },
        { "album_check",        RHYTHMDB_PROP_ALBUM },
        { "year_check",         RHYTHMDB_PROP_DATE },
        { "last_played_check",  RHYTHMDB_PROP_LAST_PLAYED },
diff --git a/sources/rb-browser-source.c b/sources/rb-browser-source.c
index eed4ac6..b315d2c 100644
--- a/sources/rb-browser-source.c
+++ b/sources/rb-browser-source.c
@@ -349,6 +349,7 @@ rb_browser_source_constructed (GObject *object)
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_GENRE, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ARTIST, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ALBUM, FALSE);
+       rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_COMPOSER, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_YEAR, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_DURATION, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_QUALITY, FALSE);
diff --git a/sources/rb-playlist-source.c b/sources/rb-playlist-source.c
index 3215805..7e39d21 100644
--- a/sources/rb-playlist-source.c
+++ b/sources/rb-playlist-source.c
@@ -332,6 +332,7 @@ rb_playlist_source_constructed (GObject *object)
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TITLE, TRUE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_GENRE, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ARTIST, FALSE);
+       rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_COMPOSER, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ALBUM, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_YEAR, FALSE);
        rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_DURATION, FALSE);
diff --git a/widgets/rb-entry-view.c b/widgets/rb-entry-view.c
index afa4075..02a3e9c 100644
--- a/widgets/rb-entry-view.c
+++ b/widgets/rb-entry-view.c
@@ -49,6 +49,7 @@
  * @RB_ENTRY_VIEW_COL_TRACK_NUMBER: the track number column
  * @RB_ENTRY_VIEW_COL_TITLE: the title column
  * @RB_ENTRY_VIEW_COL_ARTIST: the artist column
+ * @RB_ENTRY_VIEW_COL_COMPOSER: the composer column
  * @RB_ENTRY_VIEW_COL_ALBUM: the album column
  * @RB_ENTRY_VIEW_COL_GENRE: the genre column
  * @RB_ENTRY_VIEW_COL_DURATION: the duration column
@@ -1278,6 +1279,9 @@ rb_entry_view_get_column (RBEntryView *view, RBEntryViewColumn coltype)
        case RB_ENTRY_VIEW_COL_ARTIST:
                propid = RHYTHMDB_PROP_ARTIST;
                break;
+       case RB_ENTRY_VIEW_COL_COMPOSER:
+               propid = RHYTHMDB_PROP_COMPOSER;
+               break;
        case RB_ENTRY_VIEW_COL_ALBUM:
                propid = RHYTHMDB_PROP_ALBUM;
                break;
@@ -1440,6 +1444,16 @@ rb_entry_view_append_column (RBEntryView *view,
                key = "Artist";
                ellipsize = TRUE;
                break;
+       case RB_ENTRY_VIEW_COL_COMPOSER:
+               propid = RHYTHMDB_PROP_COMPOSER;
+               cell_data->propid = propid;
+               cell_data_func = (GtkTreeCellDataFunc) rb_entry_view_string_cell_data_func;
+               sort_propid = RHYTHMDB_PROP_COMPOSER_SORT_KEY;
+               sort_func = (GCompareDataFunc) rhythmdb_query_model_composer_sort_func;
+               title = _("Composer");
+               key = "Composer";
+               ellipsize = TRUE;
+               break;
        case RB_ENTRY_VIEW_COL_ALBUM:
                propid = RHYTHMDB_PROP_ALBUM;
                cell_data->propid = propid;
@@ -2579,6 +2593,7 @@ rb_entry_view_column_get_type (void)
                        ENUM_ENTRY (RB_ENTRY_VIEW_COL_TRACK_NUMBER, "track-number"),
                        ENUM_ENTRY (RB_ENTRY_VIEW_COL_TITLE, "title"),
                        ENUM_ENTRY (RB_ENTRY_VIEW_COL_ARTIST, "artist"),
+                       ENUM_ENTRY (RB_ENTRY_VIEW_COL_COMPOSER, "composer"),
                        ENUM_ENTRY (RB_ENTRY_VIEW_COL_ALBUM, "album"),
                        ENUM_ENTRY (RB_ENTRY_VIEW_COL_GENRE, "genre"),
                        ENUM_ENTRY (RB_ENTRY_VIEW_COL_COMMENT, "comment"),
diff --git a/widgets/rb-entry-view.h b/widgets/rb-entry-view.h
index e9741e4..e60d400 100644
--- a/widgets/rb-entry-view.h
+++ b/widgets/rb-entry-view.h
@@ -60,7 +60,8 @@ typedef enum {
        RB_ENTRY_VIEW_COL_LAST_SEEN,
        RB_ENTRY_VIEW_COL_LOCATION,
        RB_ENTRY_VIEW_COL_BPM,
-       RB_ENTRY_VIEW_COL_ERROR
+       RB_ENTRY_VIEW_COL_ERROR,
+       RB_ENTRY_VIEW_COL_COMPOSER
 } RBEntryViewColumn;
 
 GType rb_entry_view_column_get_type (void);
diff --git a/widgets/rb-query-creator-properties.c b/widgets/rb-query-creator-properties.c
index 148970b..d4d165b 100644
--- a/widgets/rb-query-creator-properties.c
+++ b/widgets/rb-query-creator-properties.c
@@ -76,6 +76,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", "Composer"), RHYTHMDB_PROP_COMPOSER, RHYTHMDB_PROP_COMPOSER_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 },
@@ -104,6 +105,7 @@ const int num_property_options = G_N_ELEMENTS (property_options);
 const RBQueryCreatorSortOption sort_options[] =
 {
        { NC_("query-sort", "Artist"), "Artist", N_("_In reverse alphabetical order") },
+       { NC_("query-sort", "Composer"), "Composer", 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") },
diff --git a/widgets/rb-song-info.c b/widgets/rb-song-info.c
index 9a2ada7..7f51770 100644
--- a/widgets/rb-song-info.c
+++ b/widgets/rb-song-info.c
@@ -125,6 +125,7 @@ struct RBSongInfoPrivate
        GtkWidget   *artist;
        GtkWidget   *album;
        GtkWidget   *album_artist;
+       GtkWidget   *composer;
        GtkWidget   *genre;
        GtkWidget   *track_cur;
        GtkWidget   *disc_cur;
@@ -138,6 +139,7 @@ struct RBSongInfoPrivate
        GtkWidget   *artist_sortname;
        GtkWidget   *album_sortname;
        GtkWidget   *album_artist_sortname;
+       GtkWidget   *composer_sortname;
 
        GtkWidget   *bitrate;
        GtkWidget   *duration;
@@ -491,8 +493,10 @@ rb_song_info_constructed (GObject *object)
        }
 
        song_info->priv->artist = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_artist"));
+       song_info->priv->composer = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_composer"));
        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->composer = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_composer"));
        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->playback_error_box = GTK_WIDGET (gtk_builder_get_object (builder, 
"song_info_error_box"));
@@ -502,6 +506,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"));
+       song_info->priv->composer_sortname = GTK_WIDGET (gtk_builder_get_object (builder, 
"song_info_composer_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);
@@ -510,6 +515,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, "composer_label");
        rb_builder_boldify_label (builder, "genre_label");
        rb_builder_boldify_label (builder, "year_label");
        rb_builder_boldify_label (builder, "rating_label");
@@ -517,6 +523,7 @@ rb_song_info_constructed (GObject *object)
        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");
+       rb_builder_boldify_label (builder, "composer_sortname_label");
 
        g_signal_connect_object (G_OBJECT (song_info->priv->artist),
                                 "mnemonic-activate",
@@ -530,6 +537,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->composer),
+                                "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),
@@ -554,6 +565,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->composer_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 ());
@@ -574,6 +589,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->composer), editable);
        gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->genre), editable);
        gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->year), editable);
        gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->disc_cur), editable);
@@ -937,6 +953,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
        gboolean mixed_artists = FALSE;
        gboolean mixed_albums = FALSE;
        gboolean mixed_album_artists = FALSE;
+       gboolean mixed_composers = FALSE;
        gboolean mixed_genres = FALSE;
        gboolean mixed_years = FALSE;
        gboolean mixed_disc_numbers = FALSE;
@@ -944,9 +961,11 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
        gboolean mixed_artist_sortnames = FALSE;
        gboolean mixed_album_sortnames = FALSE;
        gboolean mixed_album_artist_sortnames = FALSE;
+       gboolean mixed_composer_sortnames = FALSE;
        const char *artist = NULL;
        const char *album = NULL;
        const char *album_artist = NULL;
+       const char *composer = NULL;
        const char *genre = NULL;
        int year = 0;
        int disc_number = 0;
@@ -954,6 +973,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
        const char *artist_sortname = NULL;
        const char *album_sortname = NULL;
        const char *album_artist_sortname = NULL;
+       const char *composer_sortname = NULL;
        GList *l;
 
        g_assert (song_info->priv->selected_entries);
@@ -963,6 +983,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                const char *entry_artist;
                const char *entry_album;
                const char *entry_album_artist;
+               const char *entry_composer;
                const char *entry_genre;
                int entry_year;
                int entry_disc_number;
@@ -970,11 +991,13 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                const char *entry_artist_sortname;
                const char *entry_album_sortname;
                const char *entry_album_artist_sortname;
+               const char *entry_composer_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_composer = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER);
                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);
@@ -982,6 +1005,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                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);
+               entry_composer_sortname = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER_SORTNAME);
 
                /* grab first valid values */
                if (artist == NULL)
@@ -990,6 +1014,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                        album = entry_album;
                if (album_artist == NULL)
                        album_artist = entry_album_artist;
+               if (composer == NULL)
+                       composer = entry_composer;
                if (genre == NULL)
                        genre = entry_genre;
                if (year == 0)
@@ -1004,6 +1030,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                        album_sortname = entry_album_sortname;
                if (album_artist_sortname == NULL)
                        album_artist_sortname = entry_album_artist_sortname;
+               if (composer_sortname == NULL)
+                       composer_sortname = entry_composer_sortname;
 
                /* locate mixed values */
                if (artist != entry_artist)
@@ -1012,6 +1040,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                        mixed_albums = TRUE;
                if (album_artist != entry_album_artist)
                        mixed_album_artists = TRUE;
+               if (composer != entry_composer)
+                       mixed_composers = TRUE;
                if (genre != entry_genre)
                        mixed_genres = TRUE;
                if (year != entry_year)
@@ -1026,11 +1056,15 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                        mixed_album_sortnames = TRUE;
                if (album_artist_sortname != entry_album_artist_sortname)
                        mixed_album_artist_sortnames = TRUE;
+               if (composer_sortname != entry_composer_sortname)
+                       mixed_composer_sortnames = TRUE;
 
                /* don't continue search if everything is mixed */
-               if (mixed_artists && mixed_albums && mixed_genres &&
-                   mixed_years && mixed_disc_numbers && mixed_ratings &&
-                   mixed_artist_sortnames && mixed_album_sortnames)
+               if (mixed_artists && mixed_albums && mixed_album_artists &&
+                   mixed_composers && mixed_genres && mixed_years &&
+                   mixed_disc_numbers && mixed_ratings &&
+                   mixed_artist_sortnames && mixed_album_sortnames &&
+                   mixed_album_artist_sortnames && mixed_composer_sortnames)
                        break;
        }
 
@@ -1040,6 +1074,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                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_composers && composer != NULL)
+               gtk_entry_set_text (GTK_ENTRY (song_info->priv->composer), composer);
        if (!mixed_genres && genre != NULL)
                gtk_entry_set_text (GTK_ENTRY (song_info->priv->genre), genre);
        if (!mixed_years && year != 0)
@@ -1054,6 +1090,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                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);
+       if (!mixed_composer_sortnames && composer_sortname != NULL)
+               gtk_entry_set_text (GTK_ENTRY (song_info->priv->composer_sortname), composer_sortname);
 }
 
 static void
@@ -1082,6 +1120,8 @@ rb_song_info_populate_dialog (RBSongInfo *song_info)
        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_COMPOSER);
+       gtk_entry_set_text (GTK_ENTRY (song_info->priv->composer), 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);
 
@@ -1111,6 +1151,8 @@ rb_song_info_populate_dialog (RBSongInfo *song_info)
        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);
+       text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_COMPOSER_SORTNAME);
+       gtk_entry_set_text (GTK_ENTRY (song_info->priv->composer_sortname), text);
 }
 
 static void
@@ -1547,10 +1589,12 @@ rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
        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_COMPOSER, dialog->priv->composer);
        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);
+       changed |= sync_string_property (dialog, RHYTHMDB_PROP_COMPOSER_SORTNAME, 
dialog->priv->composer_sortname);
 
        if (strlen (year_str) > 0) {
                GDate *date = NULL;
@@ -1614,12 +1658,14 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
        const char *artist;
        const char *album;
        const char *album_artist;
+       const char *composer;
        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 *composer_sortname;
        const char *entry_string;
        const char *bpm_str;
        char *comment = NULL;
@@ -1641,12 +1687,14 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
        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));
+       composer = gtk_entry_get_text (GTK_ENTRY (dialog->priv->composer));
        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));
+       composer_sortname = gtk_entry_get_text (GTK_ENTRY (dialog->priv->composer_sortname));
 
        /* Get comment text (string is allocated) */
        gtk_text_buffer_get_bounds (dialog->priv->comment_buffer, &start, &end);
@@ -1769,6 +1817,18 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
                changed = TRUE;
        }
 
+       entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER);
+       if (g_strcmp0 (composer, entry_string)) {
+               type = rhythmdb_get_property_type (dialog->priv->db,
+                                                  RHYTHMDB_PROP_COMPOSER);
+               g_value_init (&val, type);
+               g_value_set_string (&val, composer);
+               rhythmdb_entry_set (dialog->priv->db, entry,
+                                   RHYTHMDB_PROP_COMPOSER, &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,
@@ -1829,6 +1889,18 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
                changed = TRUE;
        }
 
+       entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER_SORTNAME);
+       if (g_strcmp0 (composer_sortname, entry_string)) {
+               type = rhythmdb_get_property_type (dialog->priv->db,
+                                                  RHYTHMDB_PROP_COMPOSER_SORTNAME);
+               g_value_init (&val, type);
+               g_value_set_string (&val, composer_sortname);
+               rhythmdb_entry_set (dialog->priv->db, entry,
+                                   RHYTHMDB_PROP_COMPOSER_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]