X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fhildon2%2Fmodest-address-book.c;h=783c02ce6771209a666166a0e57f28a27102f4cf;hp=9d1ab658e79d3abe7d73b3b6d06f9f470130bda6;hb=c3ac189b10be518611b467d9c9f0f733748f598e;hpb=a6f2014ab1650908e8ee043223ed7090c7928e2a diff --git a/src/hildon2/modest-address-book.c b/src/hildon2/modest-address-book.c index 9d1ab65..783c02c 100644 --- a/src/hildon2/modest-address-book.c +++ b/src/hildon2/modest-address-book.c @@ -49,19 +49,20 @@ #include #include #include +#include static OssoABookContactModel *contact_model = NULL; static EBook *book = NULL; static EBookView * book_view = NULL; -static GSList *get_recipients_for_given_contact(EContact * contact); +static GSList *get_recipients_for_given_contact (EContact * contact, gboolean *canceled); static void commit_contact(EContact * contact, gboolean is_new); -static gchar *get_email_addr_from_user(const gchar * given_name); +static gchar *get_email_addr_from_user(const gchar * given_name, gboolean *canceled); static gchar *ui_get_formatted_email_id(gchar * current_given_name, gchar * current_sur_name, gchar * current_email_id); -static gchar *run_add_email_addr_to_contact_dlg(const gchar * contact_name); +static gchar *run_add_email_addr_to_contact_dlg(const gchar * contact_name, gboolean *canceled); static GSList *select_email_addrs_for_contact(GList * email_addr_list); -static gboolean resolve_address (const gchar *address, GSList **resolved_addresses, gchar **contact_id); +static gboolean resolve_address (const gchar *address, GSList **resolved_addresses, gchar **contact_id, gboolean *canceled); static gchar *unquote_string (const gchar *str); @@ -123,13 +124,79 @@ open_addressbook () return TRUE; /* FIXME */ } +typedef struct _OpenAddressbookSyncInfo { + gboolean retval; + GMainLoop *mainloop; +} OpenAddressbookSyncInfo; + +static void +get_book_view_sync_cb (EBook *book, EBookStatus status, EBookView *bookview, gpointer data) +{ + OpenAddressbookSyncInfo *info = (OpenAddressbookSyncInfo *) data; + + if (status != E_BOOK_ERROR_OK) { + g_object_unref (book); + book = NULL; + info->retval = FALSE; + g_main_loop_quit (info->mainloop); + return; + } + book_view = bookview; + + if (contact_model) +#if MODEST_ABOOK_API < 4 + osso_abook_tree_model_set_book_view (OSSO_ABOOK_TREE_MODEL (contact_model), + book_view); +#else /* MODEST_ABOOK_API < 4 */ + osso_abook_list_store_set_book_view (OSSO_ABOOK_LIST_STORE (contact_model), + book_view); +#endif /* MODEST_ABOOK_API < 4 */ + + e_book_view_start (book_view); + info->retval = TRUE; + g_main_loop_quit (info->mainloop); +} + +static void +book_open_sync_cb (EBook *view, EBookStatus status, gpointer data) +{ + EBookQuery *query = NULL; + OpenAddressbookSyncInfo *info = (OpenAddressbookSyncInfo *) data; + + if (status != E_BOOK_ERROR_OK) { + g_object_unref (book); + book = NULL; + info->retval = FALSE; + g_main_loop_quit (info->mainloop); + return; + } + query = e_book_query_any_field_contains (""); + e_book_async_get_book_view (book, query, NULL, -1, get_book_view_sync_cb, info); + e_book_query_unref (query); +} + static gboolean open_addressbook_sync () { + OpenAddressbookSyncInfo *info; + gboolean retval; + book = e_book_new_system_addressbook (NULL); if (!book) return FALSE; + info = g_slice_new (OpenAddressbookSyncInfo); + info->mainloop = g_main_loop_new (NULL, FALSE); + info->retval = FALSE; + if (e_book_async_open (book, FALSE, book_open_sync_cb, info) == E_BOOK_ERROR_OK) { + GDK_THREADS_LEAVE (); + g_main_loop_run (info->mainloop); + GDK_THREADS_ENTER (); + } + retval = info->retval; + g_main_loop_unref (info->mainloop); + g_slice_free (OpenAddressbookSyncInfo, info); + /* Make it launch a main loop */ return e_book_open (book, FALSE, NULL); } @@ -220,8 +287,9 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor) for (node = contacts_list; node != NULL; node = g_list_next (node)) { EContact *contact = (EContact *) node->data; + gboolean canceled; - email_addrs_per_contact = get_recipients_for_given_contact (contact); + email_addrs_per_contact = get_recipients_for_given_contact (contact, &canceled); if (email_addrs_per_contact) { econtact_id = (gchar *) e_contact_get_const (contact, E_CONTACT_UID); modest_recpt_editor_add_resolved_recipient (MODEST_RECPT_EDITOR (recpt_editor), @@ -259,7 +327,9 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor) * @param Contact of type #EContact * @return List of resolved recipient strings, to be freed by calling function. */ -static GSList *get_recipients_for_given_contact(EContact * contact) +static GSList * +get_recipients_for_given_contact (EContact * contact, + gboolean *canceled) { gchar *givenname = NULL; gchar *familyname = NULL; @@ -301,15 +371,15 @@ static GSList *get_recipients_for_given_contact(EContact * contact) /*Launch the 'Add e-mail addr to contact' dialog if required */ if (email_not_present) { #if MODEST_ABOOK_API < 4 - display_name = osso_abook_contact_get_display_name(contact); + display_name = osso_abook_contact_get_display_name(contact); #else OssoABookContact *abook_contact; - + abook_contact = osso_abook_contact_new_from_template (contact); display_name = osso_abook_contact_get_display_name(abook_contact); #endif - emailid = get_email_addr_from_user(display_name); + emailid = get_email_addr_from_user(display_name, canceled); if (emailid) { e_contact_set(contact, E_CONTACT_EMAIL_1, emailid); commit_contact(contact, FALSE); @@ -365,17 +435,20 @@ commit_contact(EContact * contact, gboolean is_new) { g_return_if_fail (contact); g_return_if_fail (book); - + if (!contact || !book) return; - + #if MODEST_ABOOK_API < 4 osso_abook_contact_commit(contact, is_new, book); #else if (OSSO_ABOOK_IS_CONTACT (contact)) { - osso_abook_contact_commit(contact, is_new, book, NULL); + osso_abook_contact_commit(OSSO_ABOOK_CONTACT(contact), is_new, book, NULL); } else { - e_book_commit_contact (book, contact, NULL); + if (is_new) + e_book_add_contact (book, contact, NULL); + else + e_book_commit_contact (book, contact, NULL); } #endif /* MODEST_ABOOK_API < 2 */ } @@ -390,7 +463,7 @@ commit_contact(EContact * contact, gboolean is_new) * @return E-mail address string entered by user, to be freed by calling function. */ static gchar * -get_email_addr_from_user(const gchar * given_name) +get_email_addr_from_user(const gchar * given_name, gboolean *canceled) { gchar *notification = NULL; gchar *email_addr = NULL; @@ -406,7 +479,7 @@ get_email_addr_from_user(const gchar * given_name) g_free(notification); if (note_response == GTK_RESPONSE_OK) { - email_addr = run_add_email_addr_to_contact_dlg(given_name); + email_addr = run_add_email_addr_to_contact_dlg (given_name, canceled); } return email_addr; @@ -449,11 +522,14 @@ ui_get_formatted_email_id(gchar * current_given_name, * It allows user to enter an e-mail address, and shows appropriate infonote if the * entered string is not a valid e-mail address. * + * It must return TRUE in canceled if the dialog was canceled by the user + * * @param contact_name Full name of the contact * @return E-mail address string entered by user, to be freed by calling function. */ static gchar * -run_add_email_addr_to_contact_dlg(const gchar * contact_name) +run_add_email_addr_to_contact_dlg(const gchar * contact_name, + gboolean *canceled) { GtkWidget *add_email_addr_to_contact_dlg = NULL; GtkSizeGroup *size_group = NULL; @@ -464,26 +540,35 @@ run_add_email_addr_to_contact_dlg(const gchar * contact_name) gchar *new_email_addr = NULL; gboolean run_dialog = TRUE; + g_return_val_if_fail (canceled, NULL); + + *canceled = FALSE; + add_email_addr_to_contact_dlg = gtk_dialog_new_with_buttons(_("mcen_ti_add_email_title"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL); + _HL("wdgt_bd_save"), GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(add_email_addr_to_contact_dlg), FALSE); +#ifdef MODEST_TOOLKIT_HILDON2 + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (add_email_addr_to_contact_dlg)->vbox), + HILDON_MARGIN_DOUBLE); +#endif /*Set app_name & state_save related tags to the window */ size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); name_label = gtk_label_new(contact_name); - gtk_misc_set_alignment(GTK_MISC(name_label), 0, 0); + gtk_misc_set_alignment(GTK_MISC(name_label), 0.0, 0.5); cptn_cntrl = - hildon_caption_new(size_group, _("mcen_ia_add_email_name"), name_label, NULL, - HILDON_CAPTION_OPTIONAL); + modest_maemo_utils_create_captioned (size_group, NULL, + _("mcen_ia_add_email_name"), FALSE, + name_label); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(add_email_addr_to_contact_dlg)->vbox), cptn_cntrl, FALSE, FALSE, 0); - email_entry = gtk_entry_new(); - cptn_cntrl = - hildon_caption_new(size_group, _("mcen_fi_add_email_name"), email_entry, NULL, - HILDON_CAPTION_OPTIONAL); + email_entry = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH); + cptn_cntrl = modest_maemo_utils_create_captioned (size_group, NULL, + _("mcen_fi_add_email_name"), FALSE, + email_entry); hildon_gtk_entry_set_input_mode(GTK_ENTRY(email_entry), HILDON_GTK_INPUT_MODE_FULL); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(add_email_addr_to_contact_dlg)->vbox), cptn_cntrl, TRUE, TRUE, 0); @@ -497,14 +582,14 @@ run_add_email_addr_to_contact_dlg(const gchar * contact_name) if (result == GTK_RESPONSE_ACCEPT) { const gchar *invalid_char_offset = NULL; - new_email_addr = g_strdup(gtk_entry_get_text(GTK_ENTRY(email_entry))); + new_email_addr = g_strdup(hildon_entry_get_text(HILDON_ENTRY(email_entry))); new_email_addr = g_strstrip(new_email_addr); if (!modest_text_utils_validate_email_address (new_email_addr, &invalid_char_offset)) { gtk_widget_grab_focus(email_entry); if ((invalid_char_offset != NULL)&&(*invalid_char_offset != '\0')) { gchar *char_in_string = g_strdup_printf ("%c", *invalid_char_offset); gchar *message = g_strdup_printf( - dgettext("hildon-common-strings", "ckdg_ib_illegal_characters_entered"), + _CS("ckdg_ib_illegal_characters_entered"), char_in_string); hildon_banner_show_information ( add_email_addr_to_contact_dlg, NULL, message ); @@ -517,6 +602,8 @@ run_add_email_addr_to_contact_dlg(const gchar * contact_name) g_free(new_email_addr); new_email_addr = NULL; } + } else { + *canceled = TRUE; } } @@ -537,77 +624,40 @@ static GSList * select_email_addrs_for_contact(GList * email_addr_list) { GtkWidget *select_email_addr_dlg = NULL; - GtkWidget *view = NULL, *scrolledwindow = NULL; - GtkTreeSelection *selection = NULL; - GtkCellRenderer *renderer = NULL; - GtkTreeViewColumn *col = NULL; - GtkListStore *list_store = NULL; - GtkTreeModel *model = NULL; - GtkTreeIter iter; - GList *pathslist = NULL, *node = NULL; - gint result = -1; - gchar *email_addr = NULL; GSList *selected_email_addr_list = NULL; + GList *node; + GtkWidget *selector; + gint result = -1; if (!email_addr_list) return NULL; - select_email_addr_dlg = - gtk_dialog_new_with_buttons(_("mcen_ti_select_email_title"), - NULL, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL); - gtk_dialog_set_has_separator(GTK_DIALOG(select_email_addr_dlg), FALSE); - - /* Make the window approximately big enough, because it doesn't resize to be big enough - * for the window title text: */ - gtk_window_set_default_size (GTK_WINDOW (select_email_addr_dlg), MODEST_DIALOG_WINDOW_MAX_HEIGHT, -1); - - scrolledwindow = gtk_scrolled_window_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(select_email_addr_dlg)->vbox), scrolledwindow, TRUE, - TRUE, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - view = gtk_tree_view_new(); - col = gtk_tree_view_column_new(); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); - gtk_tree_view_column_pack_start(col, renderer, TRUE); - gtk_tree_view_column_add_attribute(col, renderer, "text", 0); - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - gtk_container_add(GTK_CONTAINER(scrolledwindow), view); - - list_store = gtk_list_store_new(1, G_TYPE_STRING); - model = GTK_TREE_MODEL(list_store); - gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); + select_email_addr_dlg = hildon_picker_dialog_new (NULL); + gtk_window_set_title (GTK_WINDOW (select_email_addr_dlg), _("mcen_ti_select_email_title")); + selector = hildon_touch_selector_new_text (); for (node = email_addr_list; node != NULL && node->data != NULL; node = node->next) { + gchar *email_addr; email_addr = g_strstrip(g_strdup(node->data)); - gtk_list_store_append(list_store, &iter); - gtk_list_store_set(list_store, &iter, 0, email_addr, -1); + hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), email_addr); g_free(email_addr); } - gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter); - gtk_tree_selection_select_iter (selection, &iter); + hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (select_email_addr_dlg), + HILDON_TOUCH_SELECTOR (selector)); + gtk_window_set_default_size (GTK_WINDOW (select_email_addr_dlg), MODEST_DIALOG_WINDOW_MAX_HEIGHT, -1); + gtk_widget_show_all(select_email_addr_dlg); result = gtk_dialog_run(GTK_DIALOG(select_email_addr_dlg)); - if (result == GTK_RESPONSE_ACCEPT) { - pathslist = gtk_tree_selection_get_selected_rows(selection, NULL); - for (node = pathslist; node != NULL; node = node->next) { - if (gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) node->data)) { - gtk_tree_model_get(model, &iter, 0, &email_addr, -1); - selected_email_addr_list = - g_slist_append(selected_email_addr_list, g_strdup(email_addr)); - g_free(email_addr); - } - } + if (result == GTK_RESPONSE_OK) { + gchar *current_text; + + current_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector)); + selected_email_addr_list = g_slist_append (selected_email_addr_list, current_text); + } - gtk_list_store_clear(list_store); gtk_widget_destroy(select_email_addr_dlg); return selected_email_addr_list; } @@ -680,7 +730,7 @@ show_check_names_banner (gpointer userdata) GtkWidget **banner = (GtkWidget **) userdata; gdk_threads_enter (); - *banner = modest_platform_animation_banner (NULL, NULL, _("mail_ib_checking_names")); + *banner = hildon_banner_show_animation (NULL, NULL, _("mail_ib_checking_names")); gdk_threads_leave (); return FALSE; @@ -750,19 +800,20 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, gboolean updat if (!modest_text_utils_validate_recipient (address, &invalid_char_position)) { if ((invalid_char_position != NULL) && (*invalid_char_position != '\0')) { gchar *char_in_string = g_strdup_printf("%c", *invalid_char_position); - gchar *message = g_strdup_printf( - dgettext("hildon-common-strings", "ckdg_ib_illegal_characters_entered"), - char_in_string); + gchar *message = + g_strdup_printf(_CS("ckdg_ib_illegal_characters_entered"), + char_in_string); g_free (char_in_string); hildon_banner_show_information (NULL, NULL, message ); - g_free (message); + g_free (message); result = FALSE; } else if (strstr (address, "@") == NULL) { /* here goes searching in addressbook */ + gboolean canceled; gchar *contact_id = NULL; GSList *resolved_addresses = NULL; - result = resolve_address (address, &resolved_addresses, &contact_id); + result = resolve_address (address, &resolved_addresses, &contact_id, &canceled); if (result) { gint new_length; @@ -779,7 +830,13 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, gboolean updat recipients = modest_recpt_editor_get_recipients (recpt_editor); new_length = g_utf8_strlen (recipients, -1); offset_delta = offset_delta + new_length - last_length; - last_length = new_length; + last_length = new_length; + } else if (canceled) { + /* We have to remove the recipient if not resolved */ + modest_recpt_editor_replace_with_resolved_recipient (recpt_editor, + &start_iter, &end_iter, + NULL, + NULL); } } else { /* this address is not valid, select it and return control to user showing banner */ @@ -840,12 +897,32 @@ modest_address_book_check_names (ModestRecptEditor *recpt_editor, gboolean updat } +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 *full_name_book_query = NULL; GList *result; gchar *unquoted; + GetContactsInfo *info; if (name == NULL) return NULL; @@ -854,8 +931,19 @@ get_contacts_for_name (const gchar *name) full_name_book_query = e_book_query_field_test (E_CONTACT_FULL_NAME, E_BOOK_QUERY_CONTAINS, unquoted); g_free (unquoted); - e_book_get_contacts (book, full_name_book_query, &result, NULL); + /* 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, full_name_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 (full_name_book_query); + g_main_loop_unref (info->mainloop); + g_slice_free (GetContactsInfo, info); return result; } @@ -899,7 +987,6 @@ select_contacts_for_name_dialog (const gchar *name) _AB("addr_ti_dia_select_contacts"), OSSO_ABOOK_CAPS_EMAIL, OSSO_ABOOK_CONTACT_ORDER_NAME); - osso_abook_contact_chooser_set_model (OSSO_ABOOK_CONTACT_CHOOSER (contact_dialog), contact_model); @@ -915,30 +1002,36 @@ select_contacts_for_name_dialog (const gchar *name) } static gboolean -resolve_address (const gchar *address, GSList **resolved_addresses, gchar **contact_id) +resolve_address (const gchar *address, + GSList **resolved_addresses, + gchar **contact_id, + gboolean *canceled) { GList *resolved_contacts; guint banner_timeout; GtkWidget *banner = NULL; + g_return_val_if_fail (canceled, FALSE); + + *canceled = FALSE; banner_timeout = g_timeout_add (500, show_check_names_banner, &banner); contact_model = osso_abook_contact_model_new (); if (!open_addressbook_sync ()) { + hide_check_names_banner (&banner, banner_timeout); if (contact_model) { g_object_unref (contact_model); contact_model = NULL; } return FALSE; } + hide_check_names_banner (&banner, banner_timeout); resolved_contacts = get_contacts_for_name (address); if (resolved_contacts == NULL) { /* no matching contacts for the search string */ modest_platform_run_information_dialog (NULL, _("mcen_nc_no_matching_contacts"), FALSE); - hide_check_names_banner (&banner, banner_timeout); - return FALSE; } @@ -946,19 +1039,17 @@ resolve_address (const gchar *address, GSList **resolved_addresses, gchar **cont /* show a dialog to select the contact from the resolved ones */ g_list_free (resolved_contacts); - hide_check_names_banner (&banner, banner_timeout); resolved_contacts = select_contacts_for_name_dialog (address); banner_timeout = g_timeout_add (500, show_check_names_banner, &banner); } - + /* get the resolved contacts (can be no contact) */ if (resolved_contacts) { gboolean found; EContact *contact = (EContact *) resolved_contacts->data; - *resolved_addresses = get_recipients_for_given_contact (contact); - hide_check_names_banner (&banner, banner_timeout); + *resolved_addresses = get_recipients_for_given_contact (contact, canceled); if (*resolved_addresses) { *contact_id = g_strdup (e_contact_get_const (contact, E_CONTACT_UID)); found = TRUE; @@ -973,7 +1064,6 @@ resolve_address (const gchar *address, GSList **resolved_addresses, gchar **cont } else { /* cancelled dialog to select more than one contact or * selected no contact */ - hide_check_names_banner (&banner, banner_timeout); return FALSE; } @@ -996,7 +1086,7 @@ unquote_string (const gchar *str) if (*p == '\\') { g_string_append_unichar (buffer, g_utf8_get_char (p)); p = g_utf8_next_char (p); - + } g_string_append_unichar (buffer, g_utf8_get_char (p)); p = g_utf8_next_char (p);