[evolution] Adapt to vFolder changes from evolution-data-server



commit c88d3170304e1892b221d0581a3cd3c767de4281
Author: Milan Crha <mcrha redhat com>
Date:   Wed May 30 18:46:49 2012 +0200

    Adapt to vFolder changes from evolution-data-server

 data/org.gnome.evolution.mail.gschema.xml.in |    5 +++
 libemail-engine/mail-vfolder.c               |   22 +++++++++++-----
 mail/e-mail-reader.c                         |    9 +++++-
 mail/message-list.c                          |   36 +++++++++++++++++++++-----
 modules/mail/e-mail-shell-backend.c          |   11 ++++++++
 modules/mail/e-mail-shell-settings.c         |    5 +++
 modules/mail/e-mail-shell-view-actions.c     |   20 +++++++++++---
 modules/mail/e-mail-shell-view-actions.h     |    2 +
 modules/mail/e-mail-shell-view.c             |   16 ++++++++---
 ui/evolution-mail.ui                         |    1 +
 10 files changed, 102 insertions(+), 25 deletions(-)
---
diff --git a/data/org.gnome.evolution.mail.gschema.xml.in b/data/org.gnome.evolution.mail.gschema.xml.in
index f75ead7..ae54f0c 100644
--- a/data/org.gnome.evolution.mail.gschema.xml.in
+++ b/data/org.gnome.evolution.mail.gschema.xml.in
@@ -245,6 +245,11 @@
       <_summary>Enable local folders</_summary>
       <_description>Whether to show local folders (On This Computer) in a folder tree</_description>
     </key>
+    <key name="enable-unmatched" type="b">
+      <default>true</default>
+      <_summary>Enable Unmatched search folder</_summary>
+      <_description>Enable Unmatched search folder within Search Folders. It does nothing if 'enable-vfolders' is false.</_description>
+    </key>
     <key name="enable-vfolders" type="b">
       <default>true</default>
       <_summary>Enable search folders</_summary>
diff --git a/libemail-engine/mail-vfolder.c b/libemail-engine/mail-vfolder.c
index aed9668..dd083fa 100644
--- a/libemail-engine/mail-vfolder.c
+++ b/libemail-engine/mail-vfolder.c
@@ -108,7 +108,7 @@ vfolder_setup_exec (struct _setup_msg *m,
 	}
 
 	if (!vfolder_shutdown)
-		camel_vee_folder_set_folders ((CamelVeeFolder *) m->folder, list);
+		camel_vee_folder_set_folders ((CamelVeeFolder *) m->folder, list, cancellable);
 
 	l = list;
 	while (l) {
@@ -128,6 +128,8 @@ vfolder_setup_free (struct _setup_msg *m)
 {
 	GList *l;
 
+	camel_folder_thaw (m->folder);
+
 	g_object_unref (m->session);
 	g_object_unref (m->folder);
 	g_free (m->query);
@@ -173,6 +175,8 @@ vfolder_setup (EMailSession *session,
 	m->sources_uri = sources_uri;
 	m->sources_folder = sources_folder;
 
+	camel_folder_freeze (m->folder);
+
 	id = m->base.seq;
 	mail_msg_slow_ordered_push (m);
 
@@ -254,9 +258,9 @@ vfolder_adduri_exec (struct _adduri_msg *m,
 		while (l && !vfolder_shutdown) {
 			if (m->remove)
 				camel_vee_folder_remove_folder (
-					CAMEL_VEE_FOLDER (l->data), folder);
+					CAMEL_VEE_FOLDER (l->data), folder, cancellable);
 			else
-				camel_vee_folder_add_folder ((CamelVeeFolder *) l->data, folder);
+				camel_vee_folder_add_folder ((CamelVeeFolder *) l->data, folder, cancellable);
 			l = l->next;
 		}
 		g_object_unref (folder);
@@ -272,8 +276,8 @@ static void
 vfolder_adduri_free (struct _adduri_msg *m)
 {
 	g_object_unref (m->session);
-	g_list_foreach (m->folders, (GFunc) g_object_unref, NULL);
-	g_list_free (m->folders);
+	g_list_foreach (m->folders, (GFunc) camel_folder_thaw, NULL);
+	g_list_free_full (m->folders, g_object_unref);
 	g_free (m->uri);
 }
 
@@ -301,6 +305,8 @@ vfolder_adduri (EMailSession *session,
 	m->uri = g_strdup (uri);
 	m->remove = remove;
 
+	g_list_foreach (m->folders, (GFunc) camel_folder_freeze, NULL);
+
 	id = m->base.seq;
 	mail_msg_slow_ordered_push (m);
 
@@ -877,10 +883,12 @@ store_folder_deleted_cb (CamelStore *store,
 	gchar *user;
 
 	d(printf("Folder deleted: %s\n", info->name));
-	store = store;
 
-	/* Warning not thread safe, but might be enough */
+	/* Unmatched folder doesn't have any rule */
+	if (g_strcmp0 (CAMEL_UNMATCHED_NAME, info->full_name) == 0)
+		return;
 
+	/* Warning not thread safe, but might be enough */
 	G_LOCK (vfolder);
 
 	/* delete it from our list */
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 2cc78f8..a5a66e3 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -3042,8 +3042,8 @@ mail_reader_set_folder (EMailReader *reader,
 
 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
 
-	/* Only synchronize the folder if we're online. */
-	if (previous_folder != NULL && e_shell_get_online (shell))
+	/* Only synchronize the real folder if we're online. */
+	if (previous_folder != NULL && (CAMEL_IS_VEE_FOLDER (previous_folder) || e_shell_get_online (shell)))
 		mail_sync_folder (previous_folder, NULL, NULL);
 
 	/* Skip the rest if we're already viewing the folder. */
@@ -3059,6 +3059,11 @@ mail_reader_set_folder (EMailReader *reader,
 
 	priv->folder_was_just_selected = (folder != NULL);
 
+	/* this is to make sure any post-poned changes in Search Folders
+	   will be propagated on folder selection */
+	if (folder && CAMEL_IS_VEE_FOLDER (folder))
+		mail_sync_folder (folder, NULL, NULL);
+
 	message_list_set_folder (
 		MESSAGE_LIST (message_list), folder, outgoing);
 
diff --git a/mail/message-list.c b/mail/message-list.c
index 89c7f94..94957c0 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -4447,6 +4447,7 @@ struct sort_array_data {
 	GPtrArray *sort_columns; /* struct sort_column_data in order of sorting */
 	GHashTable *message_infos; /* uid -> struct sort_message_info_data */
 	gpointer cmp_cache;
+	GCancellable *cancellable;
 };
 
 static gint
@@ -4470,10 +4471,16 @@ cmp_array_uids (gconstpointer a,
 	g_return_val_if_fail (md2 != NULL, 0);
 	g_return_val_if_fail (md2->mi != NULL, 0);
 
-	if (!sort_data->ml || sort_data->folder != sort_data->ml->folder)
+	if (!sort_data->ml ||
+	    sort_data->folder != sort_data->ml->folder ||
+	    g_cancellable_is_cancelled (sort_data->cancellable))
 		return 0;
 
-	for (i = 0; res == 0 && i < sort_data->sort_columns->len; i++) {
+	for (i = 0;
+	     res == 0
+	     && i < sort_data->sort_columns->len
+	     && !g_cancellable_is_cancelled (sort_data->cancellable);
+	     i++) {
 		gpointer v1, v2;
 		struct sort_column_data *scol = g_ptr_array_index (sort_data->sort_columns, i);
 
@@ -4524,7 +4531,8 @@ free_message_info_data (gpointer uid,
 
 static void
 ml_sort_uids_by_tree (MessageList *ml,
-                      GPtrArray *uids)
+                      GPtrArray *uids,
+		      GCancellable *cancellable)
 {
 	ETreeTableAdapter *adapter;
 	ETableSortInfo *sort_info;
@@ -4532,6 +4540,9 @@ ml_sort_uids_by_tree (MessageList *ml,
 	struct sort_array_data sort_data;
 	guint i, len;
 
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	g_return_if_fail (ml != NULL);
 	g_return_if_fail (ml->folder != NULL);
 	g_return_if_fail (uids != NULL);
@@ -4554,8 +4565,13 @@ ml_sort_uids_by_tree (MessageList *ml,
 	sort_data.sort_columns = g_ptr_array_sized_new (len);
 	sort_data.message_infos = g_hash_table_new (g_str_hash, g_str_equal);
 	sort_data.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
+	sort_data.cancellable = cancellable;
 
-	for (i = 0; i < len && ml->folder == sort_data.folder; i++) {
+	for (i = 0;
+	     i < len
+	     && ml->folder == sort_data.folder
+	     && !g_cancellable_is_cancelled (cancellable);
+	     i++) {
 		ETableSortColumn scol;
 		struct sort_column_data *data = g_new0 (struct sort_column_data, 1);
 
@@ -4571,7 +4587,11 @@ ml_sort_uids_by_tree (MessageList *ml,
 
 	camel_folder_summary_prepare_fetch_all (ml->folder->summary, NULL);
 
-	for (i = 0; i < uids->len && ml->folder == sort_data.folder; i++) {
+	for (i = 0;
+	     i < uids->len
+	     && ml->folder == sort_data.folder
+	     && !g_cancellable_is_cancelled (cancellable);
+	     i++) {
 		gchar *uid;
 		CamelMessageInfo *mi;
 		struct sort_message_info_data *md;
@@ -4590,9 +4610,11 @@ ml_sort_uids_by_tree (MessageList *ml,
 		g_hash_table_insert (sort_data.message_infos, uid, md);
 	}
 
-	if (sort_data.folder == ml->folder)
+	if (sort_data.folder == ml->folder && !g_cancellable_is_cancelled (cancellable))
 		g_qsort_with_data (uids->pdata, uids->len, sizeof (gpointer), cmp_array_uids, &sort_data);
 
+	camel_folder_summary_unlock (sort_data.folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
 	g_hash_table_foreach (sort_data.message_infos, (GHFunc) free_message_info_data, &sort_data);
 	g_hash_table_destroy (sort_data.message_infos);
 
@@ -4745,7 +4767,7 @@ regen_list_exec (struct _regen_list_msg *m,
 	if (!g_cancellable_is_cancelled (cancellable)) {
 		/* update/build a new tree */
 		if (m->dotree) {
-			ml_sort_uids_by_tree (m->ml, uids);
+			ml_sort_uids_by_tree (m->ml, uids, cancellable);
 
 			if (m->tree)
 				camel_folder_thread_messages_apply (m->tree, uids);
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index ab85d4e..709626b 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -425,11 +425,15 @@ static void
 mail_shell_backend_constructed (GObject *object)
 {
 	EShell *shell;
+	EShellSettings *shell_settings;
 	EShellBackend *shell_backend;
+	EMailSession *mail_session;
+	CamelService *vstore;
 	GtkWidget *preferences_window;
 
 	shell_backend = E_SHELL_BACKEND (object);
 	shell = e_shell_backend_get_shell (shell_backend);
+	shell_settings = e_shell_get_shell_settings (shell);
 
 	/* Chain up to parent's constructed() method. */
 	G_OBJECT_CLASS (e_mail_shell_backend_parent_class)->constructed (object);
@@ -499,6 +503,13 @@ mail_shell_backend_constructed (GObject *object)
 		NULL,
 		em_network_prefs_new,
 		500);
+
+	mail_session = e_mail_backend_get_session (E_MAIL_BACKEND (object));
+	vstore = camel_session_get_service (CAMEL_SESSION (mail_session), E_MAIL_SESSION_VFOLDER_UID);
+	g_object_bind_property (
+		shell_settings, "mail-enable-unmatched-search-folder",
+		vstore, "unmatched-enabled",
+		G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
 }
 
 static void
diff --git a/modules/mail/e-mail-shell-settings.c b/modules/mail/e-mail-shell-settings.c
index 7d1fba1..1838a06 100644
--- a/modules/mail/e-mail-shell-settings.c
+++ b/modules/mail/e-mail-shell-settings.c
@@ -136,6 +136,11 @@ e_mail_shell_settings_init (EShellBackend *shell_backend)
 		"trash-empty-on-exit");
 
 	e_shell_settings_install_property_for_key (
+		"mail-enable-unmatched-search-folder",
+		MAIL_SCHEMA,
+		"enable-unmatched");
+
+	e_shell_settings_install_property_for_key (
 		"mail-enable-search-folders",
 		MAIL_SCHEMA,
 		"enable-vfolders");
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index 5487920..bcda07c 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -1556,7 +1556,14 @@ static GtkToggleActionEntry mail_toggle_entries[] = {
 	  "<Control>t",
 	  N_("Threaded message list"),
 	  NULL,  /* Handled by property bindings */
-	  FALSE }
+	  FALSE },
+
+	{ "mail-vfolder-unmatched-enable",
+	  NULL,
+	  N_("_Unmatched Folder Enabled"),
+	  NULL,
+	  N_("Toggles whether Unmatched search folder is enabled"),
+	  NULL }
 };
 
 static GtkRadioActionEntry mail_view_entries[] = {
@@ -1759,9 +1766,6 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view)
 	gtk_action_group_add_actions (
 		action_group, mail_entries,
 		G_N_ELEMENTS (mail_entries), mail_shell_view);
-	e_action_group_add_popup_actions (
-		action_group, mail_popup_entries,
-		G_N_ELEMENTS (mail_popup_entries));
 	gtk_action_group_add_toggle_actions (
 		action_group, mail_toggle_entries,
 		G_N_ELEMENTS (mail_toggle_entries), mail_shell_view);
@@ -1777,6 +1781,9 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view)
 		action_group, mail_scope_entries,
 		G_N_ELEMENTS (mail_scope_entries),
 		MAIL_SCOPE_CURRENT_FOLDER, NULL, NULL);
+	e_action_group_add_popup_actions (
+		action_group, mail_popup_entries,
+		G_N_ELEMENTS (mail_popup_entries));
 
 	/* Search Folder Actions */
 	action_group = ACTION_GROUP (SEARCH_FOLDERS);
@@ -1811,6 +1818,11 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view)
 		ACTION (MAIL_VIEW_VERTICAL), "current-value",
 		G_SETTINGS_BIND_DEFAULT);
 
+	g_settings_bind (
+		settings, "enable-unmatched",
+		ACTION (MAIL_VFOLDER_UNMATCHED_ENABLE), "active",
+		G_SETTINGS_BIND_DEFAULT);
+
 	g_object_unref (settings);
 
 	/* Fine tuning. */
diff --git a/modules/mail/e-mail-shell-view-actions.h b/modules/mail/e-mail-shell-view-actions.h
index ac682b3..a78ce2c 100644
--- a/modules/mail/e-mail-shell-view-actions.h
+++ b/modules/mail/e-mail-shell-view-actions.h
@@ -203,6 +203,8 @@
 	E_SHELL_WINDOW_ACTION ((window), "mail-tools-subscriptions")
 #define E_SHELL_WINDOW_ACTION_MAIL_UNDELETE(window) \
 	E_SHELL_WINDOW_ACTION ((window), "mail-undelete")
+#define E_SHELL_WINDOW_ACTION_MAIL_VFOLDER_UNMATCHED_ENABLE(window) \
+	E_SHELL_WINDOW_ACTION ((window), "mail-vfolder-unmatched-enable")
 #define E_SHELL_WINDOW_ACTION_MAIL_VIEW_CLASSIC(window) \
 	E_SHELL_WINDOW_ACTION ((window), "mail-view-classic")
 #define E_SHELL_WINDOW_ACTION_MAIL_VIEW_VERTICAL(window) \
diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c
index 1f459eb..1a08251 100644
--- a/modules/mail/e-mail-shell-view.c
+++ b/modules/mail/e-mail-shell-view.c
@@ -69,7 +69,7 @@ search_results_exec (SearchResultsMsg *msg,
 	g_list_foreach (copied_list, (GFunc) g_object_ref, NULL);
 
 	camel_vee_folder_set_folders (
-		CAMEL_VEE_FOLDER (msg->folder), copied_list);
+		CAMEL_VEE_FOLDER (msg->folder), copied_list, cancellable);
 
 	g_list_foreach (copied_list, (GFunc) g_object_unref, NULL);
 	g_list_free (copied_list);
@@ -528,7 +528,7 @@ all_accounts:
 
 	/* Skip the search if we already have the results. */
 	if (search_folder != NULL)
-		if (g_strcmp0 (query, search_folder->expression) == 0)
+		if (g_strcmp0 (query, camel_vee_folder_get_expression (search_folder)) == 0)
 			goto execute;
 
 	/* Disable the scope combo while search is in progress. */
@@ -558,7 +558,7 @@ all_accounts:
 
 	search_folder = (CamelVeeFolder *) camel_vee_folder_new (
 		CAMEL_STORE (service), _("All Account Search"),
-		CAMEL_STORE_VEE_FOLDER_AUTO);
+		0);
 	priv->search_account_all = search_folder;
 
 	cache = e_mail_session_get_folder_cache (session);
@@ -632,7 +632,7 @@ current_account:
 
 	/* Skip the search if we already have the results. */
 	if (search_folder != NULL)
-		if (g_strcmp0 (query, search_folder->expression) == 0)
+		if (g_strcmp0 (query, camel_vee_folder_get_expression (search_folder)) == 0)
 			goto execute;
 
 	/* Disable the scope combo while search is in progress. */
@@ -719,7 +719,7 @@ current_account:
 
 	search_folder = (CamelVeeFolder *) camel_vee_folder_new (
 		CAMEL_STORE (service), _("Account Search"),
-		CAMEL_STORE_VEE_FOLDER_AUTO);
+		0);
 	priv->search_account_current = search_folder;
 
 	camel_vee_folder_set_expression (search_folder, query);
@@ -832,6 +832,7 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	gboolean folder_has_unread_rec = FALSE;
 	gboolean folder_tree_and_message_list_agree = TRUE;
 	gboolean store_is_subscribable;
+	gboolean store_is_vstore = FALSE;
 	gboolean any_store_is_subscribable = FALSE;
 
 	/* Chain up to parent's update_actions() method. */
@@ -880,6 +881,8 @@ mail_shell_view_update_actions (EShellView *shell_view)
 		service = CAMEL_SERVICE (store);
 		uid = camel_service_get_uid (service);
 		account = e_get_account_by_uid (uid);
+
+		store_is_vstore = g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0;
 	} else
 		account = NULL;
 
@@ -1020,6 +1023,9 @@ mail_shell_view_update_actions (EShellView *shell_view)
 	sensitive = any_store_is_subscribable;
 	gtk_action_set_sensitive (action, sensitive);
 
+	action = ACTION (MAIL_VFOLDER_UNMATCHED_ENABLE);
+	gtk_action_set_visible (action, folder_is_store && store_is_vstore);
+
 	e_mail_shell_view_update_popup_labels (mail_shell_view);
 }
 
diff --git a/ui/evolution-mail.ui b/ui/evolution-mail.ui
index d1030ff..0f0969d 100644
--- a/ui/evolution-mail.ui
+++ b/ui/evolution-mail.ui
@@ -96,6 +96,7 @@
     <menuitem action='mail-popup-manage-subscriptions'/>
     <menuitem action='mail-popup-account-expunge'/>
     <menuitem action='mail-popup-account-disable'/>
+    <menuitem action='mail-vfolder-unmatched-enable'/>
     <separator/>
     <menuitem action='mail-popup-folder-unsubscribe'/>
     <separator/>



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