+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
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)
GtkTreeIter iter;
GtkTreePath *path;
GSList *groups;
- GSList *sources;
+ GSList *sources, *s;
const gchar *name;
const gchar *uid;
gchar *indented_name;
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;
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),
g_free (indented_name);
}
+ g_slist_free (sources);
}
/* Set the visible column based on whether we've seen a color. */
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)
{
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) {
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;
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;
gtk_tree_path_free (path);
}
}
+
+ if (sources)
+ g_slist_free (sources);
}
if (rebuild_data->selection_changed)