From 320ec4b32e74fa948f122868ba5474a81fad5875 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 18 Feb 2010 17:31:34 -0500 Subject: Bug 588833 - Improve account selection heuristics for replies --- mail/em-utils.c | 133 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 45 deletions(-) (limited to 'mail') diff --git a/mail/em-utils.c b/mail/em-utils.c index a2a6705ae5..d664a635cb 100644 --- a/mail/em-utils.c +++ b/mail/em-utils.c @@ -2166,78 +2166,121 @@ em_utils_generate_account_hash (void) return account_hash; } +EAccount * +em_utils_guess_account (CamelMimeMessage *message, + CamelFolder *folder) +{ + EAccount *account = NULL; + + g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); + + if (folder != NULL) + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); + + /* check for newsgroup header */ + if (folder != NULL + && camel_medium_get_header (CAMEL_MEDIUM (message), "Newsgroups")) + account = guess_account_from_folder (folder); + + /* check for source folder */ + if (account == NULL && folder != NULL) + account = guess_account_from_folder (folder); + + /* then message source */ + if (account == NULL) + account = guess_account_from_message (message); + + return account; +} + EAccount * em_utils_guess_account_with_recipients (CamelMimeMessage *message, CamelFolder *folder) { - GHashTable *account_hash = NULL; EAccount *account = NULL; - GList *iter, *recipients = NULL; + EAccountList *account_list; + GHashTable *recipients; + EIterator *iter; const CamelInternetAddress *addr; const gchar *type; + const gchar *key; + + /* This policy is subject to debate and tweaking, + * but please also document the rational here. */ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); - account = em_utils_guess_account (message, folder); - if (account != NULL) - return account; + /* Build a set of email addresses in which to test for membership. + * Only the keys matter here; the values just need to be non-NULL. */ + recipients = g_hash_table_new (g_str_hash, g_str_equal); type = CAMEL_RECIPIENT_TYPE_TO; addr = camel_mime_message_get_recipients (message, type); - if (addr != NULL) - recipients = g_list_append (recipients, (gpointer) addr); + if (addr != NULL) { + gint index = 0; + + while (camel_internet_address_get (addr, index++, NULL, &key)) + g_hash_table_insert ( + recipients, (gpointer) key, + GINT_TO_POINTER (1)); + } type = CAMEL_RECIPIENT_TYPE_CC; addr = camel_mime_message_get_recipients (message, type); - if (addr != NULL) - recipients = g_list_append (recipients, (gpointer) addr); + if (addr != NULL) { + gint index = 0; - /* finally recipient (to/cc) in account table */ - account_hash = em_utils_generate_account_hash (); - for (iter = recipients; iter == NULL; iter = iter->next) { - const gchar *tmp; - gint ii = 0; + while (camel_internet_address_get (addr, index++, NULL, &key)) + g_hash_table_insert ( + recipients, (gpointer) key, + GINT_TO_POINTER (1)); + } - addr = (CamelInternetAddress *) iter->data; + /* First Preference: We were given a folder that maps to an + * enabled account, and that account's email address appears + * in the list of To: or Cc: recipients. */ - /* XXX Is this necessary? */ - if (addr == NULL) - continue; + if (folder != NULL) + account = guess_account_from_folder (folder); - while (camel_internet_address_get (addr, ii++, NULL, &tmp)) { - account = g_hash_table_lookup (account_hash, tmp); - if (account != NULL && account->enabled) - break; - } - } - g_hash_table_destroy (account_hash); + if (account == NULL || !account->enabled) + goto second_preference; - return account; -} + if ((key = account->id->address) == NULL) + goto second_preference; -EAccount * -em_utils_guess_account (CamelMimeMessage *message, - CamelFolder *folder) -{ - EAccount *account = NULL; + if (g_hash_table_lookup (recipients, key) != NULL) + goto exit; - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); +second_preference: - if (folder != NULL) - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); + /* Second Preference: Choose any enabled account whose email + * address appears in the list to To: or Cc: recipients. */ - /* check for newsgroup header */ - if (folder != NULL - && camel_medium_get_header (CAMEL_MEDIUM (message), "Newsgroups")) - account = guess_account_from_folder (folder); + account_list = e_get_account_list (); + iter = e_list_get_iterator (E_LIST (account_list)); + while (e_iterator_is_valid (iter)) { + account = (EAccount *) e_iterator_get (iter); + e_iterator_next (iter); - /* check for source folder */ - if (account == NULL && folder != NULL) - account = guess_account_from_folder (folder); + if (account == NULL || !account->enabled) + continue; - /* then message source */ - if (account == NULL) - account = guess_account_from_message (message); + if ((key = account->id->address) == NULL) + continue; + + if (g_hash_table_lookup (recipients, key) != NULL) { + g_object_unref (iter); + goto exit; + } + } + g_object_unref (iter); + + /* Last Preference: Defer to em_utils_guess_account(). */ + account = em_utils_guess_account (message, folder); + +exit: + g_hash_table_destroy (recipients); return account; } -- cgit v1.2.3