** Fix for bug #318842
authorMilan Crha <mcrha@redhat.com>
Mon, 5 Nov 2007 10:16:54 +0000 (10:16 +0000)
committerMilan Crha <mcrha@src.gnome.org>
Mon, 5 Nov 2007 10:16:54 +0000 (10:16 +0000)
2007-11-05  Milan Crha  <mcrha@redhat.com>

** Fix for bug #318842

* Sort sources within group alphabetically
in ESourceSelector and ESourceComboBox.
* e-source-selector.c: (compare_source_names), (get_sorted_sources):
* e-source-combo-box.c: (compare_source_names), (get_sorted_sources):
New helper functions to sort sources in a group.
* e-source-selector.c: (rebuild_model): Always sort sources and place
them on their right position, if not in a tree yet.
* e-source-combo-box.c: (source_list_changed_cb):
Add sources in sorted order within group.

svn path=/trunk/; revision=8183

libedataserverui/ChangeLog
libedataserverui/e-source-combo-box.c
libedataserverui/e-source-selector.c

index b1fe02c..e03d809 100644 (file)
@@ -1,3 +1,17 @@
+2007-11-05  Milan Crha  <mcrha@redhat.com>
+
+       ** Fix for bug #318842
+
+       * Sort sources within group alphabetically
+       in ESourceSelector and ESourceComboBox.
+       * e-source-selector.c: (compare_source_names), (get_sorted_sources):
+       * e-source-combo-box.c: (compare_source_names), (get_sorted_sources):
+       New helper functions to sort sources in a group.
+       * e-source-selector.c: (rebuild_model): Always sort sources and place
+       them on their right position, if not in a tree yet.
+       * e-source-combo-box.c: (source_list_changed_cb):
+       Add sources in sorted order within group.
+
 2007-11-02  Matthew Barnes  <mbarnes@redhat.com>
 
        ** Fixes bug #460649
index 1eda3d4..d410744 100644 (file)
@@ -51,6 +51,44 @@ enum {
 
 static gpointer parent_class = NULL;
 
+/**
+ * compare_source_names
+ * Compares sources by name.
+ **/
+static gint
+compare_source_names (gconstpointer a, gconstpointer b)
+{
+       g_return_val_if_fail (E_IS_SOURCE (a), -1);
+       g_return_val_if_fail (E_IS_SOURCE (b),  1);
+
+       return g_utf8_collate (e_source_peek_name (E_SOURCE (a)), e_source_peek_name (E_SOURCE (b)));
+}
+
+/**
+ * get_sorted_sources
+ * Creates copy of GSList of sources (do not increase reference count for data members),
+ * and sorts this list alphabetically by source names.
+ *
+ * @param sources List of sources.
+ * @return New GSList of sorted sources, should be freed by g_slist_free,
+ *         but do not unref data members.
+ **/
+static GSList *
+get_sorted_sources (GSList *sources)
+{
+       GSList *res = NULL, *p;
+
+       if (!sources)
+               return NULL;
+
+       for (p = sources; p != NULL; p = p->next)
+               res = g_slist_prepend (res, p->data);
+
+       res = g_slist_sort (res, compare_source_names);
+
+       return res;
+}
+
 static void
 source_list_changed_cb (ESourceList *source_list,
                         ESourceComboBox *source_combo_box)
@@ -62,7 +100,7 @@ source_list_changed_cb (ESourceList *source_list,
        GtkTreeIter iter;
        GtkTreePath *path;
        GSList *groups;
-       GSList *sources;
+       GSList *sources, *s;
        const gchar *name;
        const gchar *uid;
        gchar *indented_name;
@@ -96,15 +134,15 @@ source_list_changed_cb (ESourceList *source_list,
                        COLUMN_SOURCE, groups->data,
                        -1);
 
-               for (sources = e_source_group_peek_sources (groups->data);
-                       sources != NULL; sources = sources->next) {
+               sources = get_sorted_sources (e_source_group_peek_sources (groups->data));
+               for (s = sources; s != NULL; s = s->next) {
                        const gchar *color_spec;
                        GdkColor color;
 
-                       name = e_source_peek_name (sources->data);
+                       name = e_source_peek_name (s->data);
                        indented_name = g_strconcat ("    ", name, NULL);
 
-                       color_spec = e_source_peek_color_spec (sources->data);
+                       color_spec = e_source_peek_color_spec (s->data);
                        if (color_spec != NULL) {
                                gdk_color_parse (color_spec, &color);
                                visible = TRUE;
@@ -116,10 +154,10 @@ source_list_changed_cb (ESourceList *source_list,
                                COLUMN_COLOR, color_spec ? &color : NULL,
                                COLUMN_NAME, indented_name,
                                COLUMN_SENSITIVE, TRUE,
-                               COLUMN_SOURCE, sources->data,
+                               COLUMN_SOURCE, s->data,
                                -1);
 
-                       uid = e_source_peek_uid (sources->data);
+                       uid = e_source_peek_uid (s->data);
                        path = gtk_tree_model_get_path (model, &iter);
                        g_hash_table_insert (
                                priv->uid_index, g_strdup (uid),
@@ -128,6 +166,7 @@ source_list_changed_cb (ESourceList *source_list,
 
                        g_free (indented_name);
                }
+               g_slist_free (sources);
        }
 
        /* Set the visible column based on whether we've seen a color. */
index 71d7f1d..ca24b3d 100644 (file)
@@ -245,6 +245,44 @@ find_source (ESourceSelector *selector, ESource *source)
        return source;
 }
 
+/**
+ * compare_source_names
+ * Compares sources by name.
+ **/
+static gint
+compare_source_names (gconstpointer a, gconstpointer b)
+{
+       g_return_val_if_fail (E_IS_SOURCE (a), -1);
+       g_return_val_if_fail (E_IS_SOURCE (b),  1);
+
+       return g_utf8_collate (e_source_peek_name (E_SOURCE (a)), e_source_peek_name (E_SOURCE (b)));
+}
+
+/**
+ * get_sorted_sources
+ * Creates copy of GSList of sources (do not increase reference count for data members),
+ * and sorts this list alphabetically by source names.
+ *
+ * @param sources List of sources.
+ * @return New GSList of sorted sources, should be freed by g_slist_free,
+ *         but do not unref data members.
+ **/
+static GSList *
+get_sorted_sources (GSList *sources)
+{
+       GSList *res = NULL, *p;
+
+       if (!sources)
+               return NULL;
+
+       for (p = sources; p != NULL; p = p->next)
+               res = g_slist_prepend (res, p->data);
+
+       res = g_slist_sort (res, compare_source_names);
+
+       return res;
+}
+
 static void
 rebuild_model (ESourceSelector *selector)
 {
@@ -278,6 +316,7 @@ rebuild_model (ESourceSelector *selector)
                ESourceGroup *group = E_SOURCE_GROUP (p->data);
                GSList *sources, *q;
                GtkTreeRowReference *row_ref;
+               gint position;
                
                row_ref = g_hash_table_lookup (rebuild_data->remaining_uids, e_source_group_peek_uid (group));
                if (!row_ref) {
@@ -294,8 +333,8 @@ rebuild_model (ESourceSelector *selector)
                        gtk_tree_path_free (path);
                }
                
-               sources = e_source_group_peek_sources (group);
-               for (q = sources; q != NULL; q = q->next) {
+               sources = get_sorted_sources (e_source_group_peek_sources (group));
+               for (q = sources, position = 0; q != NULL; q = q->next, position++) {
                        ESource *source = E_SOURCE (q->data);
                        GtkTreeIter child_iter;
 
@@ -305,9 +344,9 @@ rebuild_model (ESourceSelector *selector)
                                        select_source (selector, source);
                                        rebuild_data->selection_changed = TRUE;
                                }
-                               gtk_tree_store_append (GTK_TREE_STORE (tree_store), &child_iter, &iter);
-                               gtk_tree_store_set (GTK_TREE_STORE (tree_store), &child_iter, 0, source, -1);
 
+                               gtk_tree_store_insert (GTK_TREE_STORE (tree_store), &child_iter, &iter, position);
+                               gtk_tree_store_set (GTK_TREE_STORE (tree_store), &child_iter, 0, source, -1);
                        } else {
                                GtkTreePath *path;
                                
@@ -319,6 +358,9 @@ rebuild_model (ESourceSelector *selector)
                                gtk_tree_path_free (path);
                        }
                }
+
+               if (sources)
+                       g_slist_free (sources);
        }
 
        if (rebuild_data->selection_changed)