evolution r36635 - trunk/mail



Author: abharath
Date: Fri Oct 17 08:31:43 2008
New Revision: 36635
URL: http://svn.gnome.org/viewvc/evolution?rev=36635&view=rev

Log:
2008-10-17  Milan Crha  <mcrha redhat com>

       ** Fix for bug #364542

       * em-utils.c: (struct TryOpenEBookStruct), (try_open_e_book_cb),
       (try_open_e_book), (em_utils_in_addressbook),
       (em_utils_contact_photo):
       Stop when camel operation has been canceled. Also check for
       cancellation when opening EBook, thus the UI (preview) will
       not freeze with slow address books.


Modified:
   trunk/mail/ChangeLog
   trunk/mail/em-utils.c

Modified: trunk/mail/em-utils.c
==============================================================================
--- trunk/mail/em-utils.c	(original)
+++ trunk/mail/em-utils.c	Fri Oct 17 08:31:43 2008
@@ -64,6 +64,7 @@
 #include "message-tag-followup.h"
 
 #include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-flag.h>
 #include "e-util/e-util.h"
 #include "e-util/e-util-private.h"
 #include "e-util/e-mktemp.h"
@@ -2025,6 +2026,72 @@
 	g_clear_error(&err);
 }
 
+struct TryOpenEBookStruct {
+	GError **error;
+	EFlag *flag;
+	gboolean result;
+};
+
+static void
+try_open_e_book_cb (EBook *book, EBookStatus status, gpointer closure)
+{
+	struct TryOpenEBookStruct *data = (struct TryOpenEBookStruct *)closure;
+
+	if (!data)
+		return;
+
+	data->result = status == E_BOOK_ERROR_OK;
+
+	if (!data->result)
+		g_set_error (data->error, E_BOOK_ERROR, status, "EBookStatus returned %d", status);
+
+	e_flag_set (data->flag);
+}
+
+/**
+ * try_open_e_book:
+ * Tries to open address book asynchronously, but acts as synchronous.
+ * The advantage is it checks periodically whether the camel_operation
+ * has been canceled or not, and if so, then stops immediately, with
+ * result FALSE. Otherwise returns same as e_book_open
+ **/
+static gboolean
+try_open_e_book (EBook *book, gboolean only_if_exists, GError **error)
+{
+	struct TryOpenEBookStruct data;
+	gboolean canceled = FALSE;
+	EFlag *flag = e_flag_new ();
+
+	data.error = error;
+	data.flag = flag;
+	data.result = FALSE;
+
+	if (e_book_async_open (book, only_if_exists, try_open_e_book_cb, &data) != FALSE) {
+		e_flag_free (flag);
+		g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR, "Failed to call e_book_async_open.");
+		return FALSE;
+	}
+
+	while (canceled = camel_operation_cancel_check (NULL), !canceled && !e_flag_is_set (flag)) {
+		GTimeVal wait;
+
+		g_get_current_time (&wait);
+		g_time_val_add (&wait, 250000); /* waits 250ms */
+
+		e_flag_timed_wait (flag, &wait);
+	}
+
+	e_flag_free (flag);
+
+	if (canceled) {
+		g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CANCELLED, "Operation has been canceled.");
+		e_book_cancel_async_op (book, NULL);
+		return FALSE;
+	}
+
+	return data.result;
+}
+
 gboolean
 em_utils_in_addressbook (CamelInternetAddress *iaddr, gboolean local_only)
 {
@@ -2111,9 +2178,9 @@
 		hook = mail_cancel_hook_add(emu_addr_cancel_book, book);
 
 		/* ignore errors, but cancellation errors we don't try to go further either */
-		if (!e_book_open(book, TRUE, &err)
+		if (!try_open_e_book (book, TRUE, &err)
 		    || !e_book_get_contacts(book, query, &contacts, &err)) {
-			stop = err->domain == E_BOOK_ERROR && err->code == E_BOOK_ERROR_CANCELLED;
+			stop = err && err->domain == E_BOOK_ERROR && err->code == E_BOOK_ERROR_CANCELLED;
 			mail_cancel_hook_remove(hook);
 			g_object_unref(book);
 			d(g_warning("Can't get contacts: %s", err->message));
@@ -2129,6 +2196,8 @@
 			g_list_free(contacts);
 		}
 
+		stop = stop || camel_operation_cancel_check (NULL);
+
 		d(printf(" %s\n", stop?"found":"not found"));
 
 		g_object_unref(book);
@@ -2194,9 +2263,9 @@
 		source = s->data;
 
 		book = e_book_new(source, &err);
-		if (!e_book_open(book, TRUE, &err)
+		if (!try_open_e_book (book, TRUE, &err)
 		    || !e_book_get_contacts(book, query, &contacts, &err)) {
-			stop = err->domain == E_BOOK_ERROR && err->code == E_BOOK_ERROR_CANCELLED;
+			stop = err && err->domain == E_BOOK_ERROR && err->code == E_BOOK_ERROR_CANCELLED;
 			g_object_unref(book);
 			d(g_warning("Can't get contacts: %s", err->message));
 			g_clear_error(&err);
@@ -2214,6 +2283,9 @@
 			g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
 			g_list_free (contacts);
 		}
+
+		stop = stop || camel_operation_cancel_check (NULL);
+
 		g_object_unref (source); /* Is it? */
 		g_object_unref(book);
 	}



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