aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-utils.c
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2008-10-17 16:31:43 +0800
committerBharath Acharya <abharath@src.gnome.org>2008-10-17 16:31:43 +0800
commit7d9f28248b4472b9a9d1953b5be9e0179de0ec45 (patch)
tree98a0bede6c0e4eb9dc4284da6b0abbd30ed5c3fd /mail/em-utils.c
parent2df699c7fa7f4b38c32fa6e7db34b10b568c61e0 (diff)
downloadgsoc2013-evolution-7d9f28248b4472b9a9d1953b5be9e0179de0ec45.tar.gz
gsoc2013-evolution-7d9f28248b4472b9a9d1953b5be9e0179de0ec45.tar.zst
gsoc2013-evolution-7d9f28248b4472b9a9d1953b5be9e0179de0ec45.zip
** Fix for bug #364542
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. svn path=/trunk/; revision=36635
Diffstat (limited to 'mail/em-utils.c')
-rw-r--r--mail/em-utils.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 01b18eb461..9b091c68cf 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -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 @@ emu_addr_cancel_book(void *data)
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 @@ em_utils_in_addressbook (CamelInternetAddress *iaddr, gboolean local_only)
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 @@ em_utils_in_addressbook (CamelInternetAddress *iaddr, gboolean local_only)
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 @@ em_utils_contact_photo (struct _CamelInternetAddress *cia, gboolean local)
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 @@ em_utils_contact_photo (struct _CamelInternetAddress *cia, gboolean local)
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);
}