diff options
-rw-r--r-- | addressbook/ChangeLog | 17 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-quick-add.c | 76 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-quick-add.h | 2 | ||||
-rw-r--r-- | addressbook/gui/widgets/eab-popup-control.c | 45 | ||||
-rw-r--r-- | addressbook/gui/widgets/eab-popup-control.h | 1 | ||||
-rw-r--r-- | mail/ChangeLog | 11 | ||||
-rw-r--r-- | mail/em-popup.c | 53 | ||||
-rw-r--r-- | mail/em-utils.c | 73 | ||||
-rw-r--r-- | mail/em-utils.h | 1 |
9 files changed, 254 insertions, 25 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 12e10b7471..87922f0685 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,20 @@ +2008-03-13 Milan Crha <mcrha@redhat.com> + + ** Fix for bug #273177 + + * gui/contact-editor/e-contact-quick-add.h: + (e_contact_quick_add_vcard): + * gui/contact-editor/e-contact-quick-add.c: (struct _QuickAdd), + (quick_add_unref), (quick_add_set_vcard), (clicked_cb), + (build_quick_add_dialog), (e_contact_quick_add_vcard): + Allow adding also whole vCard with this dialog. + * gui/widgets/eab-popup-control.h: (struct _EABPopupControl): + * gui/widgets/eab-popup-control.c: (eab_popup_control_set_vcard), + (eab_popup_control_cleanup), (eab_popup_control_set_vcard), + (eab_popup_control_no_matches), (set_prop), (get_prop), + (eab_popup_control_new): + New property 'vcard', if set, has higher precedence than name/email. + 2008-03-11 Matthew Barnes <mbarnes@redhat.com> ** Fixes part of bug #513951 diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c index e2c06256bc..704b3ca8d2 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.c +++ b/addressbook/gui/contact-editor/e-contact-quick-add.c @@ -49,6 +49,7 @@ typedef struct _QuickAdd QuickAdd; struct _QuickAdd { gchar *name; gchar *email; + gchar *vcard; EContact *contact; EBook *book; @@ -92,6 +93,7 @@ quick_add_unref (QuickAdd *qa) if (qa->refs == 0) { g_free (qa->name); g_free (qa->email); + g_free (qa->vcard); g_object_unref (qa->contact); g_free (qa); } @@ -119,6 +121,16 @@ quick_add_set_email (QuickAdd *qa, const gchar *email) } static void +quick_add_set_vcard (QuickAdd *qa, const gchar *vcard) +{ + if (vcard == qa->vcard) + return; + + g_free (qa->vcard); + qa->vcard = g_strdup (vcard); +} + +static void merge_cb (EBook *book, EBookStatus status, gpointer closure) { QuickAdd *qa = (QuickAdd *) closure; @@ -232,7 +244,7 @@ clicked_cb (GtkWidget *w, gint button, gpointer closure) QuickAdd *qa = (QuickAdd *) closure; /* Get data out of entries. */ - if (button == GTK_RESPONSE_OK || button == QUICK_ADD_RESPONSE_EDIT_FULL) { + if (!qa->vcard && (button == GTK_RESPONSE_OK || button == QUICK_ADD_RESPONSE_EDIT_FULL)) { gchar *name = NULL; gchar *email = NULL; @@ -341,11 +353,16 @@ build_quick_add_dialog (QuickAdd *qa) if (qa->name) gtk_entry_set_text (GTK_ENTRY (qa->name_entry), qa->name); - qa->email_entry = gtk_entry_new (); if (qa->email) gtk_entry_set_text (GTK_ENTRY (qa->email_entry), qa->email); + if (qa->vcard) { + /* when adding vCard, then do not allow change name or email */ + gtk_widget_set_sensitive (qa->name_entry, FALSE); + gtk_widget_set_sensitive (qa->email_entry, FALSE); + } + gconf_client = gconf_client_get_default (); source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/addressbook/sources"); g_object_unref (gconf_client); @@ -555,3 +572,58 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g g_free (name); g_free (email); } + +void +e_contact_quick_add_vcard (const gchar *vcard, EContactQuickAddCallback cb, gpointer closure) +{ + QuickAdd *qa; + GtkWidget *dialog; + EContact *contact; + + /* We need to have *something* to work with. */ + if (vcard == NULL) { + if (cb) + cb (NULL, closure); + return; + } + + qa = quick_add_new (); + qa->cb = cb; + qa->closure = closure; + quick_add_set_vcard (qa, vcard); + + contact = e_contact_new_from_vcard (qa->vcard); + + if (contact) { + GList *emails; + char *name; + EContactName *contact_name; + + g_object_unref (qa->contact); + qa->contact = contact; + + contact_name = e_contact_get (qa->contact, E_CONTACT_NAME); + name = e_contact_name_to_string (contact_name); + quick_add_set_name (qa, name); + g_free (name); + e_contact_name_free (contact_name); + + emails = e_contact_get (qa->contact, E_CONTACT_EMAIL); + if (emails) { + quick_add_set_email (qa, emails->data); + + g_list_foreach (emails, (GFunc)g_free, NULL); + g_list_free (emails); + } + } else { + if (cb) + cb (NULL, closure); + + quick_add_unref (qa); + g_warning ("Contact's vCard parsing failed!"); + return; + } + + dialog = build_quick_add_dialog (qa); + gtk_widget_show_all (dialog); +} diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.h b/addressbook/gui/contact-editor/e-contact-quick-add.h index cdb539b1b0..d29ef430c1 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.h +++ b/addressbook/gui/contact-editor/e-contact-quick-add.h @@ -36,5 +36,7 @@ void e_contact_quick_add (const gchar *name, const gchar *email, void e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer closure); +void e_contact_quick_add_vcard (const gchar *vcard, EContactQuickAddCallback cb, gpointer closure); + #endif /* __E_CONTACT_QUICK_ADD_H__ */ diff --git a/addressbook/gui/widgets/eab-popup-control.c b/addressbook/gui/widgets/eab-popup-control.c index 94e46e0524..a30a4456a6 100644 --- a/addressbook/gui/widgets/eab-popup-control.c +++ b/addressbook/gui/widgets/eab-popup-control.c @@ -57,6 +57,7 @@ static void eab_popup_control_set_name (EABPopupControl *pop, const gchar *name); static void eab_popup_control_set_email (EABPopupControl *pop, const gchar *email); +static void eab_popup_control_set_vcard (EABPopupControl *pop, const gchar *vcard); static GtkObjectClass *parent_class; @@ -110,6 +111,9 @@ eab_popup_control_cleanup (EABPopupControl *pop) g_free (pop->email); pop->email = NULL; + + g_free (pop->vcard); + pop->vcard = NULL; } static void @@ -253,6 +257,26 @@ eab_popup_control_set_email (EABPopupControl *pop, const gchar *email) eab_popup_control_schedule_refresh (pop); } +static void +eab_popup_control_set_vcard (EABPopupControl *pop, const gchar *vcard) +{ + g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop)); + + /* We only allow the vcard to be set once. */ + if (pop->vcard) + return; + + g_free (pop->name); + g_free (pop->email); + + pop->name = NULL; + pop->email = NULL; + + pop->vcard = g_strdup (vcard); + + eab_popup_control_schedule_refresh (pop); +} + void eab_popup_control_construct (EABPopupControl *pop) { @@ -332,7 +356,9 @@ emit_event (EABPopupControl *pop, const char *event) static void eab_popup_control_no_matches (EABPopupControl *pop) { - if (pop->email && *pop->email) { + if (pop->vcard && *pop->vcard) + e_contact_quick_add_vcard (pop->vcard, NULL, NULL); + else if (pop->email && *pop->email) { if (pop->name && *pop->name) e_contact_quick_add (pop->name, pop->email, NULL, NULL); else @@ -361,7 +387,8 @@ eab_popup_control_query (EABPopupControl *pop) enum { PROPERTY_NAME, PROPERTY_EMAIL, - PROPERTY_TRANSITORY + PROPERTY_TRANSITORY, + PROPERTY_VCARD }; static void @@ -379,6 +406,10 @@ set_prop (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Envi eab_popup_control_set_email (pop, BONOBO_ARG_GET_STRING (arg)); break; + case PROPERTY_VCARD: + eab_popup_control_set_vcard (pop, BONOBO_ARG_GET_STRING (arg)); + break; + default: g_return_if_reached (); } @@ -403,6 +434,10 @@ get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environmen BONOBO_ARG_SET_BOOLEAN (arg, pop->transitory); break; + case PROPERTY_VCARD: + BONOBO_ARG_SET_STRING (arg, pop->vcard); + break; + default: g_return_if_reached (); } @@ -435,7 +470,11 @@ eab_popup_control_new (void) BONOBO_ARG_BOOLEAN, NULL, NULL, BONOBO_PROPERTY_READABLE); - bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (bag)), NULL); + bonobo_property_bag_add (bag, "vcard", PROPERTY_VCARD, + BONOBO_ARG_STRING, NULL, NULL, + BONOBO_PROPERTY_WRITEABLE | BONOBO_PROPERTY_READABLE); + + bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (bag)), NULL); bonobo_object_unref (BONOBO_OBJECT (bag)); addy->es = bonobo_event_source_new (); diff --git a/addressbook/gui/widgets/eab-popup-control.h b/addressbook/gui/widgets/eab-popup-control.h index 1d7ee36f0a..79e134e812 100644 --- a/addressbook/gui/widgets/eab-popup-control.h +++ b/addressbook/gui/widgets/eab-popup-control.h @@ -50,6 +50,7 @@ struct _EABPopupControl { gchar *name; gchar *email; + gchar *vcard; GtkWidget *name_widget; GtkWidget *email_widget; diff --git a/mail/ChangeLog b/mail/ChangeLog index 84a224755f..54a820c72b 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,14 @@ +2008-03-13 Milan Crha <mcrha@redhat.com> + + ** Fix for bug #273177 + + * em-utils.h: (em_utils_add_vcard): + * em-utils.c: (emu_add_address_or_vcard), + (em_utils_add_address), (em_utils_add_vcard): + New function to add whole vCard to addressbook. + * em-popup.c: (emp_add_vcard), (emp_standard_menu_factory): + Add popup menu item to vcard attachments. + 2008-03-12 Matthew Barnes <mbarnes@redhat.com> ** Fixes breakage caused by bug #513951 diff --git a/mail/em-popup.c b/mail/em-popup.c index 53797b0fdb..d44d206414 100644 --- a/mail/em-popup.c +++ b/mail/em-popup.c @@ -56,6 +56,7 @@ #include <camel/camel-mime-utils.h> #include <camel/camel-mime-part.h> #include <camel/camel-url.h> +#include <camel/camel-stream-mem.h> #include <camel/camel-vee-folder.h> #include <camel/camel-vtrash-folder.h> @@ -697,6 +698,40 @@ emp_standard_items_free(EPopup *ep, GSList *items, void *data) } static void +emp_add_vcard (EPopup *ep, EPopupItem *item, void *data) +{ + EPopupTarget *target = ep->target; + CamelMimePart *part; + CamelDataWrapper *content; + CamelStreamMem *mem; + + + if (target->type == EM_POPUP_TARGET_ATTACHMENTS) + part = ((EAttachment *) ((EMPopupTargetAttachments *) target)->attachments->data)->body; + else + part = ((EMPopupTargetPart *) target)->part; + + if (!part) + return; + + content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + mem = CAMEL_STREAM_MEM (camel_stream_mem_new ()); + + if (camel_data_wrapper_decode_to_stream (content, CAMEL_STREAM (mem)) == -1 || + !mem->buffer->data) + g_warning ("Read part's content failed!"); + else { + GString *vcard = g_string_new_len ((const gchar *) mem->buffer->data, mem->buffer->len); + + em_utils_add_vcard (target->widget, vcard->str); + + g_string_free (vcard, TRUE); + } + + camel_object_unref (mem); +} + +static void emp_standard_menu_factory(EPopup *emp, void *data) { int i, len; @@ -768,7 +803,6 @@ emp_standard_menu_factory(EPopup *emp, void *data) apps = gnome_vfs_mime_get_all_applications(name_type); } } - g_free (mime_type); if (apps) { GString *label = g_string_new(""); @@ -800,6 +834,23 @@ emp_standard_menu_factory(EPopup *emp, void *data) g_string_free(label, TRUE); g_list_free(apps); } + + if (g_ascii_strcasecmp (mime_type, "text/x-vcard") == 0|| + g_ascii_strcasecmp (mime_type, "text/vcard") == 0) { + EPopupItem *item; + + item = g_malloc0 (sizeof (*item)); + item->type = E_POPUP_ITEM; + item->path = "00.00.vcf.00"; /* make it first item */ + item->label = _("_Add to Address Book"); + item->activate = emp_add_vcard; + item->user_data = NULL; + item->image = "contact-new"; + + e_popup_add_items (emp, g_slist_append (NULL, item), NULL, NULL, NULL); + } + + g_free (mime_type); } for (i=0;i<len;i++) { diff --git a/mail/em-utils.c b/mail/em-utils.c index 0c81fbe8bd..94d4fdc6ef 100644 --- a/mail/em-utils.c +++ b/mail/em-utils.c @@ -666,39 +666,51 @@ emu_add_address_cb(BonoboListener *listener, const char *name, const CORBA_any * g_free(type); } -/** - * em_utils_add_address: - * @parent: - * @email: - * - * Add address @email to the addressbook. - **/ -void em_utils_add_address(struct _GtkWidget *parent, const char *email) +/* one of email or vcard should be always NULL, never both of them */ +static void +emu_add_address_or_vcard (struct _GtkWidget *parent, const char *email, const char *vcard) { - CamelInternetAddress *cia; GtkWidget *win; GtkWidget *control; /*GtkWidget *socket;*/ - char *buf; + char *email_buf = NULL; - cia = camel_internet_address_new (); - if (camel_address_decode ((CamelAddress *) cia, email) == -1) { + if (email) { + CamelInternetAddress *cia; + + cia = camel_internet_address_new (); + if (camel_address_decode ((CamelAddress *) cia, email) == -1) { + camel_object_unref (cia); + return; + } + + email_buf = camel_address_format ((CamelAddress *) cia); camel_object_unref (cia); - return; } - buf = camel_address_format ((CamelAddress *) cia); - camel_object_unref (cia); - win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title((GtkWindow *)win, _("Add address")); - gtk_window_set_transient_for((GtkWindow *)win, ((GtkWindow *)parent)); + + if (parent && !GTK_IS_WINDOW (parent)) { + parent = gtk_widget_get_toplevel (parent); + if (!parent || !(GTK_WIDGET_TOPLEVEL (parent))) + parent = NULL; + } + + if (parent) + gtk_window_set_transient_for((GtkWindow *)win, ((GtkWindow *)parent)); + gtk_window_set_position((GtkWindow *)win, GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_type_hint((GtkWindow *)win, GDK_WINDOW_TYPE_HINT_DIALOG); control = bonobo_widget_new_control("OAFIID:GNOME_Evolution_Addressbook_AddressPopup:" BASE_VERSION, CORBA_OBJECT_NIL); - bonobo_widget_set_property((BonoboWidget *)control, "email", TC_CORBA_string, buf, NULL); - g_free (buf); + + if (email_buf) + bonobo_widget_set_property ((BonoboWidget *) control, "email", TC_CORBA_string, email_buf, NULL); + else + bonobo_widget_set_property ((BonoboWidget *) control, "vcard", TC_CORBA_string, vcard, NULL); + + g_free (email_buf); bonobo_event_source_client_add_listener(bonobo_widget_get_objref((BonoboWidget *)control), emu_add_address_cb, NULL, NULL, win); @@ -709,6 +721,29 @@ void em_utils_add_address(struct _GtkWidget *parent, const char *email) gtk_widget_show_all(win); } +/** + * em_utils_add_address: + * @parent: + * @email: + * + * Add address @email to the addressbook. + **/ +void +em_utils_add_address (struct _GtkWidget *parent, const char *email) +{ + emu_add_address_or_vcard (parent, email, NULL); +} + +/** + * em_utils_add_vcard: + * Adds whole vCard to the addressbook. + **/ +void +em_utils_add_vcard (struct _GtkWidget *parent, const char *vcard) +{ + emu_add_address_or_vcard (parent, NULL, vcard); +} + /* ********************************************************************** */ /* Flag-for-Followup... */ diff --git a/mail/em-utils.h b/mail/em-utils.h index 587e2c18b7..2b8fae822c 100644 --- a/mail/em-utils.h +++ b/mail/em-utils.h @@ -61,6 +61,7 @@ gboolean em_utils_save_part_to_file(struct _GtkWidget *parent, const char *filen void em_utils_save_messages (struct _GtkWidget *parent, struct _CamelFolder *folder, GPtrArray *uids); void em_utils_add_address(struct _GtkWidget *parent, const char *email); +void em_utils_add_vcard(struct _GtkWidget *parent, const char *vcard); void em_utils_flag_for_followup (struct _GtkWidget *parent, struct _CamelFolder *folder, GPtrArray *uids); void em_utils_flag_for_followup_clear (struct _GtkWidget *parent, struct _CamelFolder *folder, GPtrArray *uids); |