X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fhildon2%2Fmodest-address-book.c;h=9da5e18c6599fbb64b2412705994496fb6d1e6ac;hp=2f31f2f97ca6b1320c7e474982e3445eaedb4b7b;hb=8e40f4976a7b7965b5fb3babdae3e4ffc1c03a92;hpb=d3b0c549d912673c3552eb0594c8f1d7e6784b7d diff --git a/src/hildon2/modest-address-book.c b/src/hildon2/modest-address-book.c index 2f31f2f..9da5e18 100644 --- a/src/hildon2/modest-address-book.c +++ b/src/hildon2/modest-address-book.c @@ -51,6 +51,9 @@ #include #include #include +#ifdef MODEST_PLATFORM_MAEMO +#include +#endif static OssoABookContactModel *contact_model = NULL; static EBook *book = NULL; @@ -149,6 +152,7 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor, _AB("addr_ti_dia_select_contacts"), OSSO_ABOOK_CAPS_EMAIL, OSSO_ABOOK_CONTACT_ORDER_NAME); + /* Enable multiselection */ osso_abook_contact_chooser_set_maximum_selection (OSSO_ABOOK_CONTACT_CHOOSER (contact_chooser), G_MAXUINT); @@ -733,6 +737,7 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, gint offset_delta = 0; gint last_length; GtkTextIter start_iter, end_iter; + gboolean empty_recipients = 0; g_return_val_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor), FALSE); @@ -758,7 +763,6 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, gchar *start_ptr, *end_ptr; gint start_pos, end_pos; const gchar *invalid_char_position = NULL; - gboolean store_address = FALSE; start_pos = (*((gint*) current_start->data)) + offset_delta; end_pos = (*((gint*) current_end->data)) + offset_delta; @@ -771,6 +775,7 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, /* Ignore empty addresses */ if (!g_strcmp0 (address, "")) { g_free (address); + empty_recipients++; goto next_address; } @@ -855,14 +860,13 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, addr_list, ""); g_slist_free (addr_list); - store_address = TRUE; } } /* so, it seems a valid address */ /* note: adding it the to the addressbook if it did not exist yet, * and adding it to the recent_list */ - if (result && address_list && store_address) + if (result && address_list) *address_list = g_slist_prepend (*address_list, address); else g_free (address); @@ -884,6 +888,10 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, gtk_text_buffer_place_cursor (buffer, &end_iter); } + /* Check that at least there is one non-empty recipient */ + if ((g_slist_length (start_indexes) - empty_recipients) == 0) + result = FALSE; + g_slist_foreach (start_indexes, (GFunc) g_free, NULL); g_slist_foreach (end_indexes, (GFunc) g_free, NULL); g_slist_free (start_indexes); @@ -893,72 +901,7 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, } -typedef struct _GetContactsInfo { - GMainLoop *mainloop; - GList *result; -} GetContactsInfo; - -static void -get_contacts_for_name_cb (EBook *book, - EBookStatus status, - GList *list, - gpointer userdata) -{ - GetContactsInfo *info = (GetContactsInfo *) userdata; - - if (status == E_BOOK_ERROR_OK) - info->result = list; - - g_main_loop_quit (info->mainloop); -} -static GList * -get_contacts_for_name (const gchar *name) -{ - EBookQuery *book_query = NULL; - GList *result; - gchar *unquoted; - GetContactsInfo *info; - EBookQuery *queries[10]; - gint i; - - if (name == NULL) - return NULL; - - unquoted = unquote_string (name); - - i = 0; - queries[i++] = e_book_query_field_test (E_CONTACT_GIVEN_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[i++] = e_book_query_field_test (E_CONTACT_FAMILY_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[i++] = e_book_query_field_test (E_CONTACT_NICKNAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - if (strchr (name, '@')) { - queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_1, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_2, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_3, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_4, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_BEGINS_WITH, unquoted); - } - queries[i] = e_book_query_field_test (E_CONTACT_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - book_query = e_book_query_or (i, queries, TRUE); - - g_free (unquoted); - - /* TODO: Make it launch a mainloop */ - info = g_slice_new (GetContactsInfo); - info->mainloop = g_main_loop_new (NULL, FALSE); - info->result = NULL; - if (e_book_async_get_contacts (book, book_query, get_contacts_for_name_cb, info) == 0) { - GDK_THREADS_LEAVE (); - g_main_loop_run (info->mainloop); - GDK_THREADS_ENTER (); - } - result = info->result; - e_book_query_unref (book_query); - g_main_loop_unref (info->mainloop); - g_slice_free (GetContactsInfo, info); - - return result; -} static void set_contact_from_display_name (EContact *contact, const gchar *disp_name) @@ -1005,27 +948,30 @@ set_contact_from_display_name (EContact *contact, const gchar *disp_name) } static GList * -select_contacts_for_name_dialog (const gchar *name) +select_contacts_for_name_dialog (const gchar *name, GList *external_contacts) { EBookQuery *book_query = NULL; EBookView *book_view = NULL; GList *result = NULL; gchar *unquoted; EBookQuery *queries[10]; + gint i=0; unquoted = unquote_string (name); - queries[0] = e_book_query_field_test (E_CONTACT_FULL_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[1] = e_book_query_field_test (E_CONTACT_GIVEN_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[2] = e_book_query_field_test (E_CONTACT_FAMILY_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[3] = e_book_query_field_test (E_CONTACT_NICKNAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[4] = e_book_query_field_test (E_CONTACT_EMAIL_1, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[5] = e_book_query_field_test (E_CONTACT_EMAIL_2, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[6] = e_book_query_field_test (E_CONTACT_EMAIL_3, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[7] = e_book_query_field_test (E_CONTACT_EMAIL_4, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[8] = e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_BEGINS_WITH, unquoted); - queries[9] = e_book_query_field_test (E_CONTACT_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); - book_query = e_book_query_or (10, queries, TRUE); + queries[i++] = e_book_query_field_test (E_CONTACT_FULL_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_GIVEN_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_FAMILY_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_NICKNAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); + if (strchr (name, '@')) { + queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_1, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_2, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_3, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL_4, E_BOOK_QUERY_BEGINS_WITH, unquoted); + queries[i++] = e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_BEGINS_WITH, unquoted); + } + queries[i] = e_book_query_field_test (E_CONTACT_NAME, E_BOOK_QUERY_BEGINS_WITH, unquoted); + book_query = e_book_query_or (i, queries, TRUE); e_book_get_book_view (book, book_query, NULL, -1, &book_view, NULL); e_book_query_unref (book_query); @@ -1037,8 +983,40 @@ select_contacts_for_name_dialog (const gchar *name) /* TODO: figure out how to make the contact chooser modal */ contact_dialog = osso_abook_contact_chooser_new_with_capabilities (NULL, _AB("addr_ti_dia_select_contacts"), - OSSO_ABOOK_CAPS_EMAIL, + OSSO_ABOOK_CAPS_ALL, OSSO_ABOOK_CONTACT_ORDER_NAME); + +#ifdef MODEST_PLATFORM_MAEMO + if (external_contacts) { + + GList *row_list = NULL; + while (external_contacts) { + + AsDbusRecipient *recipient = (AsDbusRecipient*)external_contacts->data; + external_contacts = g_list_next (external_contacts); + if (!recipient) + continue; + + char *uid = osso_abook_create_temporary_uid (); + OssoABookContact *contact = osso_abook_contact_new (); + osso_abook_contact_set_uid (contact, uid); + e_contact_set (E_CONTACT (contact), E_CONTACT_FULL_NAME, recipient->display_name); + osso_abook_contact_set_value (E_CONTACT (contact), EVC_EMAIL, recipient->email_address); + + OssoABookListStoreRow *row = osso_abook_list_store_row_new (contact); + row_list = g_list_prepend (row_list, row); + /* FIXME: unref row? */ + + g_free (uid); + } + + if (row_list) { + osso_abook_list_store_merge_rows (OSSO_ABOOK_LIST_STORE (contact_model), row_list); + g_list_free (row_list); + } + } +#endif + /* Enable multiselection */ osso_abook_contact_chooser_set_maximum_selection (OSSO_ABOOK_CONTACT_CHOOSER (contact_dialog), G_MAXUINT); @@ -1057,13 +1035,66 @@ select_contacts_for_name_dialog (const gchar *name) } static gboolean +contact_name_or_email_starts_with (OssoABookContact *contact, + gpointer user_data) +{ + const char *prefix = user_data; + GList *contacts, *l; + gboolean contact_match; + + contacts = osso_abook_contact_get_roster_contacts (contact); + contacts = g_list_prepend (contacts, contact); + + for (l = contacts; l; l = l->next) { + GList *attrs; + + contact_match = FALSE; + + attrs = e_vcard_get_attributes (E_VCARD (l->data)); + for (;attrs;attrs = attrs->next) { + EVCardAttribute *attr = attrs->data; + const char *name; + + name = e_vcard_attribute_get_name (attr); + + if (!g_strcmp0 (name, "N") || + (strchr (prefix, '@') && !g_strcmp0 (name, "EMAIL"))) { + GList *values = e_vcard_attribute_get_values (attr); + gchar *prefix_down = g_utf8_strdown (prefix, -1); + + for (;values; values = values->next) { + gchar *value_down = NULL; + + if (g_strcmp0 (values->data, "")) + value_down = g_utf8_strdown (values->data, -1); + + if (value_down && g_str_has_prefix (value_down, prefix_down)) { + contact_match = TRUE; + g_free (value_down); + g_free (prefix_down); + goto out; + } + g_free (value_down); + } + g_free (prefix_down); + } + } + } + out: + g_list_free (contacts); + + return contact_match; +} + +static gboolean resolve_address (const gchar *address, GSList **resolved_addresses, GSList **contact_ids, gboolean *canceled) { GList *resolved_contacts; - CheckNamesInfo *info;; + CheckNamesInfo *info; + OssoABookRoster *roster; g_return_val_if_fail (canceled, FALSE); @@ -1084,23 +1115,123 @@ resolve_address (const gchar *address, return FALSE; } - resolved_contacts = get_contacts_for_name (address); + roster = osso_abook_aggregator_get_default (NULL); + resolved_contacts = + osso_abook_aggregator_find_contacts_full ((OssoABookAggregator *) roster, + contact_name_or_email_starts_with, + (gpointer) address); +#ifdef MODEST_PLATFORM_MAEMO + GList *external_contacts = asdbus_resolve_recipients (address); +#else + GList *external_contacts = NULL; +#endif hide_check_names_banner (info); - if (resolved_contacts == NULL) { + if (resolved_contacts == NULL && NULL == external_contacts) { /* no matching contacts for the search string */ modest_platform_run_information_dialog (NULL, _("mcen_nc_no_matching_contacts"), FALSE); clean_check_names_banner (info); return FALSE; } - if (g_list_length (resolved_contacts) > 1) { +#ifdef MODEST_PLATFORM_MAEMO + /* check for duplicate emails and remove from external_contacts if any */ + if (resolved_contacts && external_contacts) { + + GList *node, *ex_node; + + for (ex_node = external_contacts; ex_node != NULL; ex_node = g_list_next (ex_node)) { + + AsDbusRecipient *recipient = (AsDbusRecipient*)ex_node->data; + if (!recipient) + continue; + + for (node = resolved_contacts; node != NULL; node = g_list_next (node)) { + + EContact *contact = (EContact*)node->data; + GList *emails = e_contact_get (contact, E_CONTACT_EMAIL); + if (!emails) + continue; + + if (g_list_find_custom (emails, recipient->email_address, (GCompareFunc) compare_addresses)) { + + g_free (recipient->display_name); + g_free (recipient->email_address); + g_free (recipient); + recipient = NULL; + ex_node->data = NULL; + } + + g_list_foreach (emails, (GFunc) g_free, NULL); + g_list_free (emails); + + if (!recipient) + break; + } + } + } +#endif + + if (g_list_length (resolved_contacts) + g_list_length (external_contacts) > 1) { /* show a dialog to select the contact from the resolved ones */ g_list_free (resolved_contacts); - resolved_contacts = select_contacts_for_name_dialog (address); + resolved_contacts = select_contacts_for_name_dialog (address, external_contacts); + +#ifdef MODEST_PLATFORM_MAEMO + if (external_contacts) { + + GList *node; + for (node = external_contacts; node != NULL; node = g_list_next (node)) { + + AsDbusRecipient *recipient = (AsDbusRecipient*)node->data; + if (!recipient) + continue; + + g_free (recipient->display_name); + g_free (recipient->email_address); + g_free (recipient); + } + + g_list_free (external_contacts); + external_contacts = NULL; + } +#endif } +#ifdef MODEST_PLATFORM_MAEMO + if (external_contacts) { + + gboolean found = FALSE; + GList *node; + for (node = external_contacts; node != NULL; node = g_list_next (node)) { + + AsDbusRecipient *recipient = (AsDbusRecipient*)node->data; + if (!recipient) + continue; + + GString *formatted_recipient = g_string_new (NULL); + g_string_printf (formatted_recipient, "\"%s\" <%s>", recipient->display_name, recipient->email_address); + + /* FIXME: why we have to have list of lists? */ + GSList *formattedlist = g_slist_append(NULL, formatted_recipient->str); + *resolved_addresses = g_slist_append (*resolved_addresses, formattedlist); + /* FIXME: how important is an UID? */ + *contact_ids = g_slist_append (*contact_ids, g_strdup ("temp-uid")); + found = TRUE; + + g_string_free (formatted_recipient, FALSE); /* character data segment is NOT freed */ + g_free (recipient->display_name); + g_free (recipient->email_address); + g_free (recipient); + } + + g_list_free (external_contacts); + external_contacts = NULL; + return found; + } +#endif + /* get the resolved contacts (can be no contact) */ if (resolved_contacts) { GList *node;