From 7d9f28248b4472b9a9d1953b5be9e0179de0ec45 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 17 Oct 2008 08:31:43 +0000 Subject: ** Fix for bug #364542 2008-10-17 Milan Crha ** 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 --- mail/ChangeLog | 10 ++++++++ mail/em-utils.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 4 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index de2af048fa..57ddb77b0f 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,13 @@ +2008-10-17 Milan Crha + + ** 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. + 2008-10-07 Bharath Acharya ** Fix for bug #555203 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 +#include #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); } -- cgit v1.2.3