[rhythmbox] song-info: add 'sorting' tab, containing album and artist sort names



commit 3e5e42b72332dfd65cf7caaf05cfb1073eae0a6f
Author: Jamie Nicol <jamie thenicols net>
Date:   Sat Jan 30 21:31:17 2010 +1000

    song-info: add 'sorting' tab, containing album and artist sort names
    
    Part of bug #133444.

 data/ui/song-info-multiple.ui |   80 +++++++++++++++++++++++++++++-
 data/ui/song-info.ui          |   89 ++++++++++++++++++++++++++++++++-
 widgets/rb-song-info.c        |  110 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 275 insertions(+), 4 deletions(-)
---
diff --git a/data/ui/song-info-multiple.ui b/data/ui/song-info-multiple.ui
index 8926b39..ea06638 100644
--- a/data/ui/song-info-multiple.ui
+++ b/data/ui/song-info-multiple.ui
@@ -4,7 +4,6 @@
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkNotebook" id="song_info_notebook">
     <property name="visible">True</property>
-    <property name="show_tabs">False</property>
     <property name="show_border">False</property>
     <child>
       <object class="GtkTable" id="song_info_basic">
@@ -210,5 +209,84 @@
         <property name="tab_fill">False</property>
       </packing>
     </child>
+    <child>
+      <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_columns">2</property>
+        <property name="column_spacing">12</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkEntry" id="song_info_artist_sortname">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">&#x25CF;</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="song_info_album_sortname">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">&#x25CF;</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="album_sortname_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Albu_m sort order:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">song_info_album_sortname</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="artist_sortname_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">_Artist sort order:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">song_info_artist_sortname</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label2">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Sorting</property>
+      </object>
+      <packing>
+        <property name="position">1</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
   </object>
 </interface>
diff --git a/data/ui/song-info.ui b/data/ui/song-info.ui
index 0d455d7..2bde9d0 100644
--- a/data/ui/song-info.ui
+++ b/data/ui/song-info.ui
@@ -303,6 +303,91 @@
       </packing>
     </child>
     <child>
+      <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_columns">2</property>
+        <property name="column_spacing">12</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkEntry" id="song_info_artist_sortname">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">&#x25CF;</property>
+            <property name="activates_default">True</property>
+            <accessibility>
+              <relation type="labelled-by" target="artist_label"/>
+            </accessibility>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="song_info_album_sortname">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">&#x25CF;</property>
+            <property name="activates_default">True</property>
+            <accessibility>
+              <relation type="labelled-by" target="album_label"/>
+            </accessibility>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="album_sortname_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Albu_m sort order:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">song_info_album_sortname</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="artist_sortname_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">_Artist sort order:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">song_info_artist_sortname</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"></property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Sorting</property>
+      </object>
+      <packing>
+        <property name="position">2</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
       <object class="GtkTable" id="song_info_additional">
         <property name="visible">True</property>
         <property name="border_width">12</property>
@@ -635,7 +720,7 @@
         </child>
       </object>
       <packing>
-        <property name="position">1</property>
+        <property name="position">2</property>
         <property name="tab_fill">False</property>
       </packing>
     </child>
@@ -646,7 +731,7 @@
         <property name="use_underline">True</property>
       </object>
       <packing>
-        <property name="position">1</property>
+        <property name="position">2</property>
         <property name="tab_fill">False</property>
       </packing>
     </child>
diff --git a/widgets/rb-song-info.c b/widgets/rb-song-info.c
index 875863b..e33bae3 100644
--- a/widgets/rb-song-info.c
+++ b/widgets/rb-song-info.c
@@ -133,6 +133,9 @@ struct RBSongInfoPrivate
 	GtkWidget   *playback_error_box;
 	GtkWidget   *playback_error_label;
 
+	GtkWidget   *artist_sortname;
+	GtkWidget   *album_sortname;
+
 	GtkWidget   *bitrate;
 	GtkWidget   *duration;
 	GtkWidget   *name;
@@ -490,6 +493,9 @@ rb_song_info_constructed (GObject *object)
 	song_info->priv->playback_error_label = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_error_label"));
 	song_info->priv->disc_cur = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_disc_cur"));
 
+	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"));
+
 	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);
 	rb_song_info_add_completion (GTK_ENTRY (song_info->priv->album), song_info->priv->albums);
@@ -500,6 +506,8 @@ rb_song_info_constructed (GObject *object)
 	rb_builder_boldify_label (builder, "year_label");
 	rb_builder_boldify_label (builder, "rating_label");
 	rb_builder_boldify_label (builder, "discn_label");
+	rb_builder_boldify_label (builder, "artist_sortname_label");
+	rb_builder_boldify_label (builder, "album_sortname_label");
 
 	g_signal_connect_object (G_OBJECT (song_info->priv->artist),
 				 "mnemonic-activate",
@@ -521,6 +529,14 @@ 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->artist_sortname),
+				 "mnemonic-activate",
+				 G_CALLBACK (rb_song_info_mnemonic_cb),
+				 NULL, 0);
+	g_signal_connect_object (G_OBJECT (song_info->priv->album_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 ());
@@ -888,12 +904,16 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 	gboolean mixed_years = FALSE;
 	gboolean mixed_disc_numbers = FALSE;
 	gboolean mixed_ratings = FALSE;
+	gboolean mixed_artist_sortnames = FALSE;
+	gboolean mixed_album_sortnames = FALSE;
 	const char *artist = NULL;
 	const char *album = 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;
 	GList *l;
 
 	g_assert (song_info->priv->selected_entries);
@@ -906,6 +926,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 		int entry_year;
 		int entry_disc_number;
 		double entry_rating;
+		const char *entry_artist_sortname;
+		const char *entry_album_sortname;
 
 		entry = (RhythmDBEntry*)l->data;
 		entry_artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
@@ -914,6 +936,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 		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);
 
 		/* grab first valid values */
 		if (artist == NULL)
@@ -928,6 +952,10 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 			disc_number = entry_disc_number;
 		if (fabs(rating) < EPSILON)
 			rating = entry_rating;
+		if (artist_sortname == NULL)
+			artist_sortname = entry_artist_sortname;
+		if (album_sortname == NULL)
+			album_sortname = entry_album_sortname;
 
 		/* locate mixed values */
 		if (artist != entry_artist)
@@ -942,10 +970,15 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 			mixed_disc_numbers = TRUE;
 		if (fabs(rating - entry_rating) >= EPSILON)
 			mixed_ratings = TRUE;
+		if (artist_sortname != entry_artist_sortname)
+			mixed_artist_sortnames = TRUE;
+		if (album_sortname != entry_album_sortname)
+			mixed_album_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_years && mixed_disc_numbers && mixed_ratings &&
+		    mixed_artist_sortnames && mixed_album_sortnames)
 			break;
 	}
 
@@ -961,6 +994,10 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 		rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->disc_cur), disc_number);
 	if (!mixed_ratings && fabs(rating) >= EPSILON)
 		g_object_set (G_OBJECT (song_info->priv->rating), "rating", rating, NULL);
+	if (!mixed_artist_sortnames && artist_sortname != NULL)
+		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);
 }
 
 static void
@@ -1004,6 +1041,11 @@ rb_song_info_populate_dialog (RBSongInfo *song_info)
 	rb_song_info_update_rating (song_info);
 	rb_song_info_update_year (song_info);
 	rb_song_info_update_playback_error (song_info);
+
+	text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ARTIST_SORTNAME);
+	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);
 }
 
 static void
@@ -1401,6 +1443,8 @@ rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
 	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,};
@@ -1514,6 +1558,42 @@ 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 (strcmp (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 (strcmp (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);
 }
@@ -1528,6 +1608,8 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
 	const char *tracknum_str;
 	const char *discnum_str;
 	const char *year_str;
+	const char *artist_sortname;
+	const char *album_sortname;
 	const char *entry_string;
 	char *endptr;
 	GType type;
@@ -1546,6 +1628,8 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
 	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));
 
 	g_signal_emit (dialog, rb_song_info_signals[PRE_METADATA_CHANGE], 0,
 		       entry);
@@ -1653,6 +1737,30 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
 		changed = TRUE;
 	}
 
+	entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME);
+	if (strcmp (artist_sortname, entry_string)) {
+		type = rhythmdb_get_property_type (dialog->priv->db,
+						   RHYTHMDB_PROP_ARTIST_SORTNAME);
+		g_value_init (&val, type);
+		g_value_set_string (&val, artist_sortname);
+		rhythmdb_entry_set (dialog->priv->db, entry,
+				    RHYTHMDB_PROP_ARTIST_SORTNAME, &val);
+		g_value_unset (&val);
+		changed = TRUE;
+	}
+
+	entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_SORTNAME);
+	if (strcmp (album_sortname, entry_string)) {
+		type = rhythmdb_get_property_type (dialog->priv->db,
+						   RHYTHMDB_PROP_ALBUM_SORTNAME);
+		g_value_init (&val, type);
+		g_value_set_string (&val, album_sortname);
+		rhythmdb_entry_set (dialog->priv->db, entry,
+				    RHYTHMDB_PROP_ALBUM_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]