aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2014-05-20 18:12:44 +0800
committerMilan Crha <mcrha@redhat.com>2014-05-20 18:12:44 +0800
commitfd688bf25fc58455ae58a3f9d5754aab5af1e74c (patch)
tree8effefdbd1dd0eca78c07ca15a233a6d6314f04c
parent24630c83cf188de9637ee7a139f463112a341166 (diff)
downloadgsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.tar
gsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.tar.gz
gsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.tar.bz2
gsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.tar.lz
gsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.tar.xz
gsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.tar.zst
gsoc2013-evolution-fd688bf25fc58455ae58a3f9d5754aab5af1e74c.zip
Custom mail account order reset on an account add or remove
It was quite discouraging to change order of mail accounts when it reset to default sort order when a new account had been added or an old removed. Rather than reset the order, the Evolution should adapt the account count change properly, same as sort newly added accounts by the default sort function.
-rw-r--r--mail/e-mail-account-store.c121
1 files changed, 91 insertions, 30 deletions
diff --git a/mail/e-mail-account-store.c b/mail/e-mail-account-store.c
index 2a6439c1b1..70c7cf3c12 100644
--- a/mail/e-mail-account-store.c
+++ b/mail/e-mail-account-store.c
@@ -125,7 +125,7 @@ mail_account_store_get_iter (EMailAccountStore *store,
static gint
mail_account_store_default_compare (CamelService *service_a,
CamelService *service_b,
- EMailAccountStore *store)
+ gpointer user_data)
{
const gchar *display_name_a;
const gchar *display_name_b;
@@ -160,6 +160,29 @@ mail_account_store_default_compare (CamelService *service_a,
return g_utf8_collate (display_name_a, display_name_b);
}
+static gint
+mail_account_store_get_defailt_index (EMailAccountStore *store,
+ CamelService *service)
+{
+ GQueue *current_order;
+ gint intended_position;
+
+ g_return_val_if_fail (E_IS_MAIL_ACCOUNT_STORE (store), -1);
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), -1);
+
+ current_order = g_queue_new ();
+ e_mail_account_store_queue_services (store, current_order);
+
+ g_queue_insert_sorted (current_order, service,
+ (GCompareDataFunc) mail_account_store_default_compare, NULL);
+
+ intended_position = g_queue_index (current_order, service);
+
+ g_queue_free (current_order);
+
+ return intended_position;
+}
+
static void
mail_account_store_update_row (EMailAccountStore *store,
CamelService *service,
@@ -1115,10 +1138,10 @@ e_mail_account_store_add_service (EMailAccountStore *store,
ESourceRegistry *registry;
ESource *collection;
ESource *source;
- GtkTreeIter iter;
- const gchar *filename;
+ GtkTreeIter iter, sibling;
const gchar *icon_name = NULL;
const gchar *uid;
+ gint intended_position;
gboolean builtin;
gboolean enabled;
gboolean online_account = FALSE;
@@ -1181,19 +1204,12 @@ e_mail_account_store_add_service (EMailAccountStore *store,
g_object_unref (source);
- /* Where do we insert new services now that accounts can be
- * reordered? This is just a simple policy I came up with.
- * It's certainly subject to debate and tweaking.
- *
- * Always insert new services in row 0 initially. Then test
- * for the presence of the sort order file. If present, the
- * user has messed around with the ordering so leave the new
- * service at row 0. If not present, services are sorted in
- * their default order. So re-apply the default order using
- * e_mail_account_store_reorder_services(store, NULL) so the
- * new service moves to its proper default position. */
-
- gtk_list_store_prepend (GTK_LIST_STORE (store), &iter);
+ intended_position = mail_account_store_get_defailt_index (store, service);
+ if (intended_position >= 0 &&
+ gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &sibling, NULL, intended_position))
+ gtk_list_store_insert_before (GTK_LIST_STORE (store), &iter, &sibling);
+ else
+ gtk_list_store_prepend (GTK_LIST_STORE (store), &iter);
gtk_list_store_set (
GTK_LIST_STORE (store), &iter,
@@ -1218,11 +1234,6 @@ e_mail_account_store_add_service (EMailAccountStore *store,
g_signal_emit (store, signals[SERVICE_ENABLED], 0, service);
else
g_signal_emit (store, signals[SERVICE_DISABLED], 0, service);
-
- filename = store->priv->sort_order_filename;
-
- if (!g_file_test (filename, G_FILE_TEST_EXISTS))
- e_mail_account_store_reorder_services (store, NULL);
}
void
@@ -1425,6 +1436,56 @@ e_mail_account_store_have_enabled_service (EMailAccountStore *store,
return found;
}
+static GQueue *
+mail_account_store_ensure_all_services_in_queue (GQueue *current_order,
+ GQueue *ordered_services)
+{
+ GHashTable *known_services;
+ GHashTableIter iter;
+ gpointer key, value;
+ GQueue *use_order;
+ GList *link;
+
+ g_return_val_if_fail (current_order != NULL, NULL);
+ g_return_val_if_fail (ordered_services != NULL, NULL);
+
+ known_services = g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (link = g_queue_peek_head_link (current_order); link != NULL; link = g_list_next (link)) {
+ CamelService *service = link->data;
+
+ if (!service)
+ continue;
+
+ g_hash_table_insert (known_services, (gpointer) camel_service_get_uid (service), service);
+ }
+
+ use_order = g_queue_new ();
+
+ for (link = g_queue_peek_head_link (ordered_services); link != NULL; link = g_list_next (link)) {
+ CamelService *service = link->data, *found;
+
+ if (!service)
+ continue;
+
+ found = g_hash_table_lookup (known_services, camel_service_get_uid (service));
+ if (found) {
+ g_hash_table_remove (known_services, camel_service_get_uid (found));
+ g_queue_push_tail (use_order, found);
+ }
+ }
+
+ g_hash_table_iter_init (&iter, known_services);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_queue_insert_sorted (use_order, value, (GCompareDataFunc)
+ mail_account_store_default_compare, NULL);
+ }
+
+ g_hash_table_destroy (known_services);
+
+ return use_order;
+}
+
void
e_mail_account_store_reorder_services (EMailAccountStore *store,
GQueue *ordered_services)
@@ -1447,13 +1508,6 @@ e_mail_account_store_reorder_services (EMailAccountStore *store,
if (ordered_services != NULL && g_queue_is_empty (ordered_services))
ordered_services = NULL;
- /* If the length of the custom ordering disagrees with the
- * number of rows in the store, revert to default ordering. */
- if (ordered_services != NULL) {
- if (g_queue_get_length (ordered_services) != n_children)
- ordered_services = NULL;
- }
-
use_default_order = (ordered_services == NULL);
/* Build a queue of CamelServices in the order they appear in
@@ -1468,7 +1522,11 @@ e_mail_account_store_reorder_services (EMailAccountStore *store,
g_queue_sort (
default_order, (GCompareDataFunc)
- mail_account_store_default_compare, store);
+ mail_account_store_default_compare, NULL);
+
+ ordered_services = default_order;
+ } else {
+ default_order = mail_account_store_ensure_all_services_in_queue (current_order, ordered_services);
ordered_services = default_order;
}
@@ -1488,7 +1546,8 @@ e_mail_account_store_reorder_services (EMailAccountStore *store,
old_pos = g_queue_link_index (current_order, matching_link);
matching_link->data = NULL;
- new_order[new_pos++] = old_pos;
+ if (new_pos < n_children)
+ new_order[new_pos++] = old_pos;
}
if (new_pos == n_children) {
@@ -1496,6 +1555,8 @@ e_mail_account_store_reorder_services (EMailAccountStore *store,
g_signal_emit (
store, signals[SERVICES_REORDERED], 0,
use_default_order);
+ } else {
+ g_warn_if_reached ();
}
g_free (new_order);