[rhythmbox] Bug 737058 - Part 1: Add disc total and track total to the DB



commit b488e62f9474f9086b561daecb3ca1739edeb505
Author: Hubert Figuière <hub figuiere net>
Date:   Sat Sep 20 19:11:47 2014 -0400

    Bug 737058 - Part 1: Add disc total and track total to the DB

 configure.ac                  |    2 +-
 data/ui/song-info-multiple.ui |   41 +++++++++++---
 data/ui/song-info.ui          |   84 +++++++++++++++++++++++++----
 rhythmdb/rhythmdb-private.h   |    2 +
 rhythmdb/rhythmdb-tree.c      |   13 ++++-
 rhythmdb/rhythmdb.c           |   40 ++++++++++++++
 rhythmdb/rhythmdb.h           |    2 +
 widgets/rb-song-info.c        |  120 ++++++++++++++++++++++++++++++++---------
 8 files changed, 257 insertions(+), 47 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 78681fe..449a04c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ GNOME_MAINTAINER_MODE_DEFINES
 # Increment on interface addition, reset on removal
 RHYTHMBOX_CORE_AGE=0
 # Increment on interface add, remove, or change
-RHYTHMBOX_CORE_CURRENT=8
+RHYTHMBOX_CORE_CURRENT=9
 # Increment on source change, reset when CURRENT changes.
 RHYTHMBOX_CORE_REVISION=0
 
diff --git a/data/ui/song-info-multiple.ui b/data/ui/song-info-multiple.ui
index 42f09f8..4b42dcb 100644
--- a/data/ui/song-info-multiple.ui
+++ b/data/ui/song-info-multiple.ui
@@ -12,7 +12,7 @@
         <property name="can_focus">False</property>
         <property name="border_width">6</property>
         <property name="n_rows">7</property>
-        <property name="n_columns">2</property>
+        <property name="n_columns">4</property>
         <property name="column_spacing">12</property>
         <property name="row_spacing">6</property>
         <child>
@@ -24,7 +24,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="y_options"/>
           </packing>
         </child>
@@ -37,7 +37,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="top_attach">1</property>
             <property name="bottom_attach">2</property>
             <property name="y_options"/>
@@ -98,7 +98,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="top_attach">4</property>
             <property name="bottom_attach">5</property>
             <property name="y_options"/>
@@ -131,7 +131,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="top_attach">6</property>
             <property name="bottom_attach">7</property>
             <property name="x_options">GTK_FILL</property>
@@ -163,7 +163,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="top_attach">5</property>
             <property name="bottom_attach">6</property>
             <property name="y_options"/>
@@ -223,7 +223,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="top_attach">2</property>
             <property name="bottom_attach">3</property>
             <property name="y_options"/>
@@ -252,12 +252,37 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
+            <property name="right_attach">4</property>
             <property name="top_attach">3</property>
             <property name="bottom_attach">4</property>
             <property name="y_options"/>
           </packing>
         </child>
+        <child>
+          <object class="GtkLabel" id="disc_total_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">of</property>
+          </object>
+          <packing>
+            <property name="left_attach">2</property>
+            <property name="right_attach">3</property>
+            <property name="top_attach">7</property>
+            <property name="bottom_attach">8</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="song_info_disc_total">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">3</property>
+            <property name="right_attach">4</property>
+            <property name="top_attach">7</property>
+            <property name="bottom_attach">8</property>
+          </packing>
+        </child>
       </object>
     </child>
     <child type="tab">
diff --git a/data/ui/song-info.ui b/data/ui/song-info.ui
index 1c0c41b..176b763 100644
--- a/data/ui/song-info.ui
+++ b/data/ui/song-info.ui
@@ -18,7 +18,7 @@
             <property name="can_focus">False</property>
             <property name="border_width">12</property>
             <property name="n_rows">8</property>
-            <property name="n_columns">2</property>
+            <property name="n_columns">4</property>
             <property name="column_spacing">12</property>
             <property name="row_spacing">6</property>
             <child>
@@ -33,7 +33,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="y_options"/>
               </packing>
             </child>
@@ -49,7 +49,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">1</property>
                 <property name="bottom_attach">2</property>
                 <property name="y_options"/>
@@ -67,7 +67,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">2</property>
                 <property name="bottom_attach">3</property>
                 <property name="y_options"/>
@@ -142,6 +142,8 @@
                 <property name="invisible_char">●</property>
                 <property name="activates_default">True</property>
                 <property name="width_chars">3</property>
+                <property name="max_width_chars">4</property>
+                <property name="input_purpose">digits</property>
                 <accessibility>
                   <relation type="labelled-by" target="trackn_label"/>
                 </accessibility>
@@ -151,6 +153,7 @@
                 <property name="right_attach">2</property>
                 <property name="top_attach">6</property>
                 <property name="bottom_attach">7</property>
+                <property name="x_options">GTK_FILL</property>
                 <property name="y_options"/>
               </packing>
             </child>
@@ -166,7 +169,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">5</property>
                 <property name="bottom_attach">6</property>
                 <property name="y_options"/>
@@ -210,6 +213,8 @@
                 <property name="can_focus">True</property>
                 <property name="invisible_char">●</property>
                 <property name="activates_default">True</property>
+                <property name="max_width_chars">4</property>
+                <property name="input_purpose">digits</property>
                 <accessibility>
                   <relation type="labelled-by" target="discn_label"/>
                 </accessibility>
@@ -219,6 +224,7 @@
                 <property name="right_attach">2</property>
                 <property name="top_attach">7</property>
                 <property name="bottom_attach">8</property>
+                <property name="x_options">GTK_FILL</property>
                 <property name="y_options"/>
               </packing>
             </child>
@@ -234,7 +240,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">8</property>
                 <property name="bottom_attach">9</property>
                 <property name="y_options"/>
@@ -268,7 +274,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">9</property>
                 <property name="bottom_attach">10</property>
                 <property name="y_options"/>
@@ -320,7 +326,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">10</property>
                 <property name="bottom_attach">11</property>
               </packing>
@@ -349,7 +355,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">3</property>
                 <property name="bottom_attach">4</property>
                 <property name="y_options"/>
@@ -379,12 +385,70 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">4</property>
                 <property name="top_attach">4</property>
                 <property name="bottom_attach">5</property>
                 <property name="y_options"/>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel" id="track_total_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">of</property>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">6</property>
+                <property name="bottom_attach">7</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="disc_total_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">of</property>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">7</property>
+                <property name="bottom_attach">8</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="song_info_track_total">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="max_width_chars">4</property>
+                <property name="input_purpose">digits</property>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="top_attach">6</property>
+                <property name="bottom_attach">7</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"/>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="song_info_disc_total">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="max_width_chars">4</property>
+                <property name="input_purpose">digits</property>
+              </object>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="top_attach">7</property>
+                <property name="bottom_attach">8</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"/>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
diff --git a/rhythmdb/rhythmdb-private.h b/rhythmdb/rhythmdb-private.h
index 1310136..a8abc58 100644
--- a/rhythmdb/rhythmdb-private.h
+++ b/rhythmdb/rhythmdb-private.h
@@ -89,7 +89,9 @@ struct _RhythmDBEntry {
        RBRefString *album_sortname;
        RBRefString *album_artist_sortname;
        gulong tracknum;
+       gulong tracktotal;
        gulong discnum;
+       gulong disctotal;
        gulong duration;
        gulong bitrate;
        double bpm;
diff --git a/rhythmdb/rhythmdb-tree.c b/rhythmdb/rhythmdb-tree.c
index c4c7295..d92a8ba 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.9"
-#define RHYTHMDB_TREE_XML_VERSION_INT 190
+#define RHYTHMDB_TREE_XML_VERSION "2.0"
+#define RHYTHMDB_TREE_XML_VERSION_INT 200
 
 static void destroy_tree_property (RhythmDBTreeProperty *prop);
 static RhythmDBTreeProperty *get_or_create_album (RhythmDBTree *db, RhythmDBTreeProperty *artist,
@@ -400,6 +400,9 @@ rhythmdb_tree_parser_start_element (struct RhythmDBTreeLoadContext *ctx,
                                        case 180:
                                                rb_debug ("reloading all file metadata to get composer tag");
                                                ctx->reload_all_metadata = TRUE;
+                                       case 190:
+                                               rb_debug ("reloading all files metadata to get total tracks 
and discs");
+                                               ctx->reload_all_metadata = TRUE;
                                        case RHYTHMDB_TREE_XML_VERSION_INT:
                                                /* current version */
                                                break;
@@ -1039,9 +1042,15 @@ save_entry (RhythmDBTree *db,
                case RHYTHMDB_PROP_TRACK_NUMBER:
                        save_entry_ulong (ctx, elt_name, entry->tracknum, FALSE);
                        break;
+               case RHYTHMDB_PROP_TRACK_TOTAL:
+                       save_entry_ulong (ctx, elt_name, entry->tracktotal, FALSE);
+                       break;
                case RHYTHMDB_PROP_DISC_NUMBER:
                        save_entry_ulong (ctx, elt_name, entry->discnum, FALSE);
                        break;
+               case RHYTHMDB_PROP_DISC_TOTAL:
+                       save_entry_ulong (ctx, elt_name, entry->disctotal, FALSE);
+                       break;
                case RHYTHMDB_PROP_DATE:
                        if (g_date_valid (&entry->date))
                                save_entry_ulong (ctx, elt_name, g_date_get_julian (&entry->date), TRUE);
diff --git a/rhythmdb/rhythmdb.c b/rhythmdb/rhythmdb.c
index 2a0c33c..ad6bd40 100644
--- a/rhythmdb/rhythmdb.c
+++ b/rhythmdb/rhythmdb.c
@@ -86,7 +86,9 @@ static const RhythmDBPropertyDef rhythmdb_properties[] = {
        PROP_ENTRY(ARTIST, G_TYPE_STRING, "artist"),
        PROP_ENTRY(ALBUM, G_TYPE_STRING, "album"),
        PROP_ENTRY(TRACK_NUMBER, G_TYPE_ULONG, "track-number"),
+       PROP_ENTRY(TRACK_TOTAL, G_TYPE_ULONG, "track-total"),
        PROP_ENTRY(DISC_NUMBER, G_TYPE_ULONG, "disc-number"),
+       PROP_ENTRY(DISC_TOTAL, G_TYPE_ULONG, "disc-total"),
        PROP_ENTRY(DURATION, G_TYPE_ULONG, "duration"),
        PROP_ENTRY(FILE_SIZE, G_TYPE_UINT64, "file-size"),
        PROP_ENTRY(LOCATION, G_TYPE_STRING, "location"),
@@ -646,9 +648,15 @@ metadata_field_from_prop (RhythmDBPropType prop,
        case RHYTHMDB_PROP_TRACK_NUMBER:
                *field = RB_METADATA_FIELD_TRACK_NUMBER;
                return TRUE;
+       case RHYTHMDB_PROP_TRACK_TOTAL:
+               *field = RB_METADATA_FIELD_MAX_TRACK_NUMBER;
+               return TRUE;
        case RHYTHMDB_PROP_DISC_NUMBER:
                *field = RB_METADATA_FIELD_DISC_NUMBER;
                return TRUE;
+       case RHYTHMDB_PROP_DISC_TOTAL:
+               *field = RB_METADATA_FIELD_MAX_DISC_NUMBER;
+               return TRUE;
        case RHYTHMDB_PROP_DATE:
                *field = RB_METADATA_FIELD_DATE;
                return TRUE;
@@ -1929,6 +1937,17 @@ set_props_from_metadata (RhythmDB *db,
                                     RHYTHMDB_PROP_TRACK_NUMBER, &val);
        g_value_unset (&val);
 
+       /* track total */
+       if (!rb_metadata_get (metadata,
+                             RB_METADATA_FIELD_MAX_TRACK_NUMBER,
+                             &val)) {
+               g_value_init (&val, G_TYPE_ULONG);
+               g_value_set_ulong (&val, 0);
+       }
+       rhythmdb_entry_set_internal (db, entry, TRUE,
+                                    RHYTHMDB_PROP_TRACK_TOTAL, &val);
+       g_value_unset (&val);
+
        /* disc number */
        if (!rb_metadata_get (metadata,
                              RB_METADATA_FIELD_DISC_NUMBER,
@@ -1940,6 +1959,17 @@ set_props_from_metadata (RhythmDB *db,
                                     RHYTHMDB_PROP_DISC_NUMBER, &val);
        g_value_unset (&val);
 
+       /* disc total */
+       if (!rb_metadata_get (metadata,
+                             RB_METADATA_FIELD_MAX_DISC_NUMBER,
+                             &val)) {
+               g_value_init (&val, G_TYPE_ULONG);
+               g_value_set_ulong (&val, 0);
+       }
+       rhythmdb_entry_set_internal (db, entry, TRUE,
+                                    RHYTHMDB_PROP_DISC_TOTAL, &val);
+       g_value_unset (&val);
+
        /* duration */
        if (rb_metadata_get (metadata,
                             RB_METADATA_FIELD_DURATION,
@@ -3415,9 +3445,15 @@ rhythmdb_entry_set_internal (RhythmDB *db,
                case RHYTHMDB_PROP_TRACK_NUMBER:
                        entry->tracknum = g_value_get_ulong (value);
                        break;
+               case RHYTHMDB_PROP_TRACK_TOTAL:
+                       entry->tracktotal = g_value_get_ulong (value);
+                       break;
                case RHYTHMDB_PROP_DISC_NUMBER:
                        entry->discnum = g_value_get_ulong (value);
                        break;
+               case RHYTHMDB_PROP_DISC_TOTAL:
+                       entry->disctotal = g_value_get_ulong (value);
+                       break;
                case RHYTHMDB_PROP_DURATION:
                        entry->duration = g_value_get_ulong (value);
                        break;
@@ -5051,8 +5087,12 @@ rhythmdb_entry_get_ulong (RhythmDBEntry *entry,
                return entry->id;
        case RHYTHMDB_PROP_TRACK_NUMBER:
                return entry->tracknum;
+       case RHYTHMDB_PROP_TRACK_TOTAL:
+               return entry->tracktotal;
        case RHYTHMDB_PROP_DISC_NUMBER:
                return entry->discnum;
+       case RHYTHMDB_PROP_DISC_TOTAL:
+               return entry->disctotal;
        case RHYTHMDB_PROP_DURATION:
                return entry->duration;
        case RHYTHMDB_PROP_MTIME:
diff --git a/rhythmdb/rhythmdb.h b/rhythmdb/rhythmdb.h
index 2c796a0..08cc82b 100644
--- a/rhythmdb/rhythmdb.h
+++ b/rhythmdb/rhythmdb.h
@@ -99,7 +99,9 @@ typedef enum
        RHYTHMDB_PROP_ARTIST,
        RHYTHMDB_PROP_ALBUM,
        RHYTHMDB_PROP_TRACK_NUMBER,
+       RHYTHMDB_PROP_TRACK_TOTAL,
        RHYTHMDB_PROP_DISC_NUMBER,
+       RHYTHMDB_PROP_DISC_TOTAL,
        RHYTHMDB_PROP_DURATION,
        RHYTHMDB_PROP_FILE_SIZE,
        RHYTHMDB_PROP_LOCATION,
diff --git a/widgets/rb-song-info.c b/widgets/rb-song-info.c
index 7f51770..cfe4fed 100644
--- a/widgets/rb-song-info.c
+++ b/widgets/rb-song-info.c
@@ -128,7 +128,9 @@ struct RBSongInfoPrivate
        GtkWidget   *composer;
        GtkWidget   *genre;
        GtkWidget   *track_cur;
+       GtkWidget   *track_total;
        GtkWidget   *disc_cur;
+       GtkWidget   *disc_total;
        GtkWidget   *year;
        GtkWidget   *comment;
        GtkTextBuffer *comment_buffer;
@@ -372,6 +374,7 @@ rb_song_info_construct_single (RBSongInfo *song_info, GtkBuilder *builder, gbool
        song_info->priv->notebook      = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_vbox"));
        song_info->priv->title         = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_title"));
        song_info->priv->track_cur     = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_track_cur"));
+       song_info->priv->track_total   = GTK_WIDGET (gtk_builder_get_object (builder, 
"song_info_track_total"));
        song_info->priv->bitrate       = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_bitrate"));
        song_info->priv->duration      = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_duration"));
        song_info->priv->bpm           = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_bpm"));
@@ -406,6 +409,10 @@ rb_song_info_construct_single (RBSongInfo *song_info, GtkBuilder *builder, gbool
                                 "mnemonic-activate",
                                 G_CALLBACK (rb_song_info_mnemonic_cb),
                                 NULL, 0);
+       g_signal_connect_object (G_OBJECT (song_info->priv->track_total),
+                                "mnemonic-activate",
+                                G_CALLBACK (rb_song_info_mnemonic_cb),
+                                NULL, 0);
        g_signal_connect_object (G_OBJECT (song_info->priv->comment),
                                 "mnemonic-activate",
                                 G_CALLBACK (rb_song_info_mnemonic_cb),
@@ -413,6 +420,7 @@ rb_song_info_construct_single (RBSongInfo *song_info, GtkBuilder *builder, gbool
 
        gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->title), editable);
        gtk_editable_set_editable  (GTK_EDITABLE (song_info->priv->track_cur), editable);
+       gtk_editable_set_editable  (GTK_EDITABLE (song_info->priv->track_total), editable);
        gtk_text_view_set_editable (GTK_TEXT_VIEW (song_info->priv->comment), editable);
 
        /* default focus */
@@ -502,6 +510,7 @@ rb_song_info_constructed (GObject *object)
        song_info->priv->playback_error_box = GTK_WIDGET (gtk_builder_get_object (builder, 
"song_info_error_box"));
        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->disc_total = GTK_WIDGET (gtk_builder_get_object (builder, "song_info_disc_total"));
 
        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"));
@@ -553,6 +562,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->disc_total),
+                                "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),
@@ -593,6 +606,7 @@ rb_song_info_constructed (GObject *object)
        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);
+       gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->disc_total), editable);
 
        /* Finish construction */
        if (song_info->priv->current_entry) {
@@ -957,6 +971,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
        gboolean mixed_genres = FALSE;
        gboolean mixed_years = FALSE;
        gboolean mixed_disc_numbers = FALSE;
+       gboolean mixed_disc_totals = FALSE;
        gboolean mixed_ratings = FALSE;
        gboolean mixed_artist_sortnames = FALSE;
        gboolean mixed_album_sortnames = FALSE;
@@ -969,6 +984,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
        const char *genre = NULL;
        int year = 0;
        int disc_number = 0;
+       int disc_total = 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;
@@ -987,6 +1003,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                const char *entry_genre;
                int entry_year;
                int entry_disc_number;
+               int entry_disc_total;
                double entry_rating;
                const char *entry_artist_sortname;
                const char *entry_album_sortname;
@@ -1001,6 +1018,7 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                entry_genre = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
                entry_year = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_YEAR);
                entry_disc_number = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_NUMBER);
+               entry_disc_total = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_TOTAL);
                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);
@@ -1022,6 +1040,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                        year = entry_year;
                if (disc_number == 0)
                        disc_number = entry_disc_number;
+               if (disc_total == 0)
+                       disc_total = entry_disc_total;
                if (fabs(rating) < EPSILON)
                        rating = entry_rating;
                if (artist_sortname == NULL)
@@ -1048,6 +1068,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                        mixed_years = TRUE;
                if (disc_number != entry_disc_number)
                        mixed_disc_numbers = TRUE;
+               if (disc_total != entry_disc_total)
+                       mixed_disc_totals = TRUE;
                if (fabs(rating - entry_rating) >= EPSILON)
                        mixed_ratings = TRUE;
                if (artist_sortname != entry_artist_sortname)
@@ -1062,7 +1084,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                /* don't continue search if everything is mixed */
                if (mixed_artists && mixed_albums && mixed_album_artists &&
                    mixed_composers && mixed_genres && mixed_years &&
-                   mixed_disc_numbers && mixed_ratings &&
+                   mixed_disc_numbers && mixed_disc_totals &&
+                   mixed_ratings &&
                    mixed_artist_sortnames && mixed_album_sortnames &&
                    mixed_album_artist_sortnames && mixed_composer_sortnames)
                        break;
@@ -1082,6 +1105,8 @@ rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
                rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->year), year);
        if (!mixed_disc_numbers && disc_number != 0)
                rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->disc_cur), disc_number);
+       if (!mixed_disc_totals && disc_total != 0)
+               rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->disc_total), disc_total);
        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)
@@ -1127,8 +1152,12 @@ rb_song_info_populate_dialog (RBSongInfo *song_info)
 
        num = rhythmdb_entry_get_ulong (song_info->priv->current_entry, RHYTHMDB_PROP_TRACK_NUMBER);
        rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->track_cur), num);
+       num = rhythmdb_entry_get_ulong (song_info->priv->current_entry, RHYTHMDB_PROP_TRACK_TOTAL);
+       rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->track_total), num);
        num = rhythmdb_entry_get_ulong (song_info->priv->current_entry, RHYTHMDB_PROP_DISC_NUMBER);
        rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->disc_cur), num);
+       num = rhythmdb_entry_get_ulong (song_info->priv->current_entry, RHYTHMDB_PROP_DISC_TOTAL);
+       rb_song_info_populate_num_field (GTK_ENTRY (song_info->priv->disc_total), num);
        dnum = rhythmdb_entry_get_double (song_info->priv->current_entry, RHYTHMDB_PROP_BPM);
        rb_song_info_populate_dnum_field (GTK_ENTRY (song_info->priv->bpm), dnum);
        text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_COMMENT);
@@ -1572,17 +1601,50 @@ sync_string_property (RBSongInfo *dialog, RhythmDBPropType property, GtkWidget *
        return changed;
 }
 
+static gboolean
+sync_ulong_property (RBSongInfo *dialog, RhythmDBPropType property, GtkWidget *entry)
+{
+       const char *new_text;
+       gint val_int;
+       GValue val = {0,};
+       GList *tem;
+       gboolean changed = FALSE;
+       char *endptr;
+
+       new_text = gtk_entry_get_text (GTK_ENTRY (entry));
+       val_int = g_ascii_strtoull (new_text, &endptr, 10);
+
+       if (endptr != new_text) {
+
+               g_value_init (&val, G_TYPE_ULONG);
+               g_value_set_ulong (&val, val_int);
+
+               for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
+                       RhythmDBEntry *dbentry;
+                       gulong entry_num;
+
+                       dbentry = (RhythmDBEntry *)tem->data;
+                       entry_num = rhythmdb_entry_get_ulong (dbentry, property);
+
+                       if (val_int != entry_num) {
+                               rhythmdb_entry_set (dialog->priv->db, dbentry,
+                                                   property, &val);
+                               changed = TRUE;
+                       }
+               }
+               g_value_unset (&val);
+       }
+       return changed;
+}
+
 static void
 rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
 {
        const char *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));
-
        char *endptr;
        GValue val = {0,};
        GList *tem;
        gint year;
-       gint discn;
        gboolean changed = FALSE;
        RhythmDBEntry *entry;
 
@@ -1623,28 +1685,8 @@ rb_song_info_sync_entries_multiple (RBSongInfo *dialog)
 
        }
 
-       discn = g_ascii_strtoull (discn_str, &endptr, 10);
-       if (endptr != discn_str) {
-               GType type;
-               type = rhythmdb_get_property_type (dialog->priv->db,
-                                                  RHYTHMDB_PROP_DISC_NUMBER);
-               g_value_init (&val, type);
-               g_value_set_ulong (&val, discn);
-
-               for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
-                       gulong entry_disc_num;
-
-                       entry = (RhythmDBEntry *)tem->data;
-                       entry_disc_num = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_NUMBER);
-
-                       if (discn != entry_disc_num) {
-                               rhythmdb_entry_set (dialog->priv->db, entry,
-                                                   RHYTHMDB_PROP_DISC_NUMBER, &val);
-                               changed = TRUE;
-                       }
-               }
-               g_value_unset (&val);
-       }
+       changed |= sync_ulong_property(dialog, RHYTHMDB_PROP_DISC_NUMBER, dialog->priv->disc_cur);
+       changed |= sync_ulong_property(dialog, RHYTHMDB_PROP_DISC_TOTAL, dialog->priv->disc_total);
 
        if (changed)
                rhythmdb_commit (dialog->priv->db);
@@ -1660,7 +1702,9 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
        const char *album_artist;
        const char *composer;
        const char *tracknum_str;
+       const char *tracktotal_str;
        const char *discnum_str;
+       const char *disctotal_str;
        const char *year_str;
        const char *artist_sortname;
        const char *album_sortname;
@@ -1672,7 +1716,9 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
        char *endptr;
        GType type;
        gulong tracknum;
+       gulong tracktotal;
        gulong discnum;
+       gulong disctotal;
        gulong year;
        gulong entry_val;
        gdouble bpm;
@@ -1689,7 +1735,9 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
        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));
+       tracktotal_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->track_total));
        discnum_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->disc_cur));
+       disctotal_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->disc_total));
        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));
@@ -1715,6 +1763,16 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
                changed = TRUE;
        }
 
+       tracktotal = g_ascii_strtoull (tracktotal_str, &endptr, 10);
+       entry_val = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_TOTAL);
+       if ((endptr != tracktotal_str) && (tracktotal != entry_val)) {
+               g_value_init (&val, G_TYPE_ULONG);
+               g_value_set_ulong (&val, tracktotal);
+               rhythmdb_entry_set (dialog->priv->db, entry, RHYTHMDB_PROP_TRACK_TOTAL, &val);
+               g_value_unset (&val);
+               changed = TRUE;
+       }
+
        discnum = g_ascii_strtoull (discnum_str, &endptr, 10);
        entry_val = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_NUMBER);
        if ((endptr != discnum_str) && (discnum != entry_val)) {
@@ -1727,6 +1785,16 @@ rb_song_info_sync_entry_single (RBSongInfo *dialog)
                changed = TRUE;
        }
 
+       disctotal = g_ascii_strtoull (disctotal_str, &endptr, 10);
+       entry_val = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_TOTAL);
+       if ((endptr != discnum_str) && (discnum != entry_val)) {
+               g_value_init (&val, G_TYPE_ULONG);
+               g_value_set_ulong (&val, disctotal);
+               rhythmdb_entry_set (dialog->priv->db, entry, RHYTHMDB_PROP_DISC_TOTAL, &val);
+               g_value_unset (&val);
+               changed = TRUE;
+       }
+
        year = g_ascii_strtoull (year_str, &endptr, 10);
        entry_val = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_YEAR);
        if ((endptr != year_str) &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]