aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook')
-rw-r--r--addressbook/ChangeLog19
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.c47
-rw-r--r--addressbook/gui/widgets/e-minicard.c23
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c86
-rw-r--r--addressbook/gui/widgets/eab-gui-util.c97
-rw-r--r--addressbook/gui/widgets/eab-gui-util.h4
6 files changed, 236 insertions, 40 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 2b5060cbc0..947bfcc9af 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,22 @@
+2008-01-21 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #324604 inspired by patch of makuchaku (Mayank)
+
+ * gui/widgets/eab-gui-util.h:
+ * gui/widgets/eab-gui-util.c: (eab_parse_qp_email),
+ (eab_parse_qp_email_to_html): New helper functions for decoding
+ email addresses from RFC822 or RFC2047 form to UTF-8.
+ * gui/widgets/e-minicard.c: (add_email_field):
+ * gui/widgets/eab-contact-display.c: (render_contact_list),
+ (render_contact), (eab_contact_display_render_compact):
+ * gui/widgets/e-addressbook-table-adapter.c:
+ (struct _EAddressbookTableAdapterPrivate), (addressbook_dispose),
+ (addressbook_value_at), (addressbook_set_value_at), (remove_contacts),
+ (modify_contact), (model_changed), (eab_table_adapter_construct):
+ * gui/widgets/eab-gui-util.c: (get_email),
+ (eab_send_contact_list_as_attachment):
+ Ensure the print of the email is transformed from RFC822 or RFC2047.
+
2008-01-20 Srinivasa Ragavan <sragavan@novell.com>
* gui/widgets/e-addressbook-view.etspec: Revert my last patch.
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c
index b208952245..95e3b214a9 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c
@@ -15,6 +15,8 @@ struct _EAddressbookTableAdapterPrivate {
EABModel *model;
int create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
+
+ GHashTable *emails;
};
#define PARENT_TYPE e_table_model_get_type()
@@ -54,6 +56,9 @@ addressbook_dispose(GObject *object)
if (adapter->priv) {
unlink_model(adapter);
+ g_hash_table_remove_all (adapter->priv->emails);
+ g_hash_table_destroy (adapter->priv->emails);
+
g_free (adapter->priv);
adapter->priv = NULL;
}
@@ -92,6 +97,28 @@ addressbook_value_at (ETableModel *etc, int col, int row)
value = e_contact_get_const((EContact*)eab_model_contact_at (priv->model, row), col);
+ if (value && *value && (col == E_CONTACT_EMAIL_1 || col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3)) {
+ char *val = g_hash_table_lookup (priv->emails, value);
+
+ if (val) {
+ /* we have this already cached, so use value from the cache */
+ value = val;
+ } else {
+ char *name = NULL, *mail = NULL;
+
+ if (eab_parse_qp_email (value, &name, &mail))
+ val = g_strdup_printf ("%s <%s>", name, mail);
+ else
+ val = g_strdup (value);
+
+ g_free (name);
+ g_free (mail);
+
+ g_hash_table_insert (priv->emails, g_strdup (value), val);
+ value = val;
+ }
+ }
+
return (void *)(value ? value : "");
}
@@ -122,9 +149,17 @@ addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val)
e_table_model_pre_change(etc);
+ if (col == E_CONTACT_EMAIL_1 || col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3) {
+ const char *old_value = e_contact_get_const (contact, col);
+
+ /* remove old value from cache and use new one */
+ if (old_value && *old_value)
+ g_hash_table_remove (priv->emails, old_value);
+ }
+
e_contact_set(contact, col, (void *) val);
eab_merging_book_commit_contact (eab_model_get_ebook (priv->model),
- contact, contact_modified_cb, NULL);
+ contact, contact_modified_cb, etc);
g_object_unref (contact);
@@ -266,6 +301,8 @@ remove_contacts (EABModel *model,
GArray *indices = (GArray *) data;
int count = indices->len;
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
e_table_model_pre_change (E_TABLE_MODEL (adapter));
if (count == 1)
@@ -279,6 +316,9 @@ modify_contact (EABModel *model,
gint index,
EAddressbookTableAdapter *adapter)
{
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
+
e_table_model_pre_change (E_TABLE_MODEL (adapter));
e_table_model_row_changed (E_TABLE_MODEL (adapter), index);
}
@@ -287,6 +327,9 @@ static void
model_changed (EABModel *model,
EAddressbookTableAdapter *adapter)
{
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
+
e_table_model_pre_change (E_TABLE_MODEL (adapter));
e_table_model_changed (E_TABLE_MODEL (adapter));
}
@@ -340,6 +383,8 @@ eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
"model_changed",
G_CALLBACK(model_changed),
adapter);
+
+ priv->emails = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_free);
}
ETableModel *
diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c
index c0fd0b5994..02119d1c7e 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -839,7 +839,6 @@ add_email_field (EMinicard *e_minicard, GList *email_list, gdouble left_width, i
GnomeCanvasGroup *group;
EMinicardField *minicard_field;
char *name;
- char *string;
GList *l, *le;
int count =0;
GList *emails = e_contact_get (e_minicard->contact, E_CONTACT_EMAIL);
@@ -847,20 +846,32 @@ add_email_field (EMinicard *e_minicard, GList *email_list, gdouble left_width, i
for (l=email_list, le=emails; l!=NULL && count < limit && le!=NULL; l = l->next, le=le->next) {
const gchar *tmp;
+ char *email = NULL;
+ char *string = NULL;
+ char *full_string = NULL;
+ gboolean parser_check;
tmp = get_email_location ((EVCardAttribute *) l->data);
if (tmp)
name = g_strdup_printf ("%s:", tmp);
else
name = g_strdup ("");
- string = e_text_to_html (le->data, 0);
+
+ parser_check = eab_parse_qp_email ((const gchar *) le->data, &string, &email);
+ if (parser_check) {
+ /* if true, we had a quoted printable mail address */
+ full_string = g_strdup_printf ("%s <%s>", string, email);
+ } else {
+ /* we got a NON-quoted printable string */
+ string = g_strdup (le->data);
+ }
new_item = e_minicard_label_new(group);
gnome_canvas_item_set( new_item,
"width", e_minicard->width - 4.0,
"fieldname", name,
- "field", string,
+ "field", parser_check ? full_string : string,
"max_field_name_length", left_width,
"editable", FALSE /* e_minicard->editable */,
NULL );
@@ -882,8 +893,10 @@ add_email_field (EMinicard *e_minicard, GList *email_list, gdouble left_width, i
e_minicard->fields = g_list_append( e_minicard->fields, minicard_field);
e_canvas_item_move_absolute(new_item, 2, e_minicard->height);
count++;
- g_free(name);
- g_free(string);
+ g_free (name);
+ g_free (string);
+ g_free (full_string);
+ g_free (email);
}
g_list_foreach (emails, (GFunc) g_free, NULL);
g_list_free (emails);
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index 7510d72189..a93f86e2ea 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -488,10 +488,18 @@ render_contact_list (GtkHTMLStream *html_stream, EContact *contact)
email_list = e_contact_get (contact, E_CONTACT_EMAIL);
for (l = email_list; l; l = l->next) {
- char *html = e_text_to_html (l->data, E_TEXT_TO_HTML_CONVERT_ADDRESSES);
- gtk_html_stream_printf (html_stream, "%s<br>", html);
- g_free (html);
+ gchar *value;
+
+ value = eab_parse_qp_email_to_html (l->data);
+
+ if (!value)
+ value = e_text_to_html (l->data, E_TEXT_TO_HTML_CONVERT_ADDRESSES);
+
+ gtk_html_stream_printf (html_stream, "%s<br>", value);
+
+ g_free (value);
}
+
gtk_html_stream_printf (html_stream, "</td></tr></table>");
}
@@ -542,18 +550,35 @@ render_contact (GtkHTMLStream *html_stream, EContact *contact)
email_attr_list = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
for (l = email_list, al=email_attr_list; l && al; l = l->next, al = al->next) {
-#ifdef HANDLE_MAILTO_INTERNALLY
- char *html = e_text_to_html (l->data, 0);
+ char *html = NULL, *name = NULL, *mail = NULL;
char *attr_str = (char *)get_email_location ((EVCardAttribute *) al->data);
- g_string_append_printf (accum, "%s<a href=\"internal-mailto:%d\">%s</a> <font color=" HEADER_COLOR ">(%s)</font>", nl, email_num, html, attr_str?attr_str:"");
- email_num ++;
- g_free (html);
- nl = "<br>";
+#ifdef HANDLE_MAILTO_INTERNALLY
+ if (!eab_parse_qp_email (l->data, &name, &mail))
+ mail = e_text_to_html (l->data, 0);
+
+ g_string_append_printf (accum, "%s%s%s<a href=\"internal-mailto:%d\">%s</a>%s <font color=" HEADER_COLOR ">(%s)</font>",
+ nl,
+ name ? name : "",
+ name ? " &lt;" : "",
+ email_num,
+ mail,
+ name ? "&gt;" : "",
+ attr_str ? attr_str : "");
+ email_num ++;
#else
- g_string_append_printf (accum, "%s%s <font color=" HEADER_COLOR ">(%s)</font>", nl, (char*)l->data, get_email_location ((EVCardAttribute *) al->data));
- nl = "\n";
+ html = eab_parse_qp_email_to_html (l->data);
+
+ if (!html)
+ html = e_text_to_html (l->data, E_TEXT_TO_HTML_CONVERT_ADDRESSES);
+
+ g_string_append_printf (accum, "%s%s <font color=" HEADER_COLOR ">(%s)</font>", nl, html, attr_str ? attr_str : "");
#endif
+ nl = "<br>";
+
+ g_free (html);
+ g_free (name);
+ g_free (mail);
}
g_list_foreach (email_list, (GFunc)g_free, NULL);
g_list_free (email_list);
@@ -821,29 +846,34 @@ eab_contact_display_render_compact (EABContactDisplay *display, EContact *contac
g_free (html);
}
+ #define print_email() { \
+ html = eab_parse_qp_email_to_html (str); \
+ \
+ if (!html) \
+ html = e_text_to_html (str, 0); \
+ \
+ gtk_html_stream_printf (html_stream, "%s%s", comma ? ", " : "", html); \
+ g_free (html); \
+ comma = TRUE; \
+ }
+
gtk_html_stream_printf (html_stream, "<b>%s:</b> ", _("Email"));
str = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
- if (str) {
- html = e_text_to_html (str, 0);
- gtk_html_stream_printf (html_stream, "%s", str);
- g_free (html);
- comma = TRUE;
- }
+ if (str)
+ print_email ();
+
str = e_contact_get_const (contact, E_CONTACT_EMAIL_2);
- if (str) {
- html = e_text_to_html (str, 0);
- gtk_html_stream_printf (html_stream, "%s%s", comma ? ", " : "", str);
- g_free (html);
- comma = TRUE;
- }
+ if (str)
+ print_email ();
+
str = e_contact_get_const (contact, E_CONTACT_EMAIL_3);
- if (str) {
- html = e_text_to_html (str, 0);
- gtk_html_stream_printf (html_stream, "%s%s", comma ? ", " : "", str);
- g_free (html);
- }
+ if (str)
+ print_email ();
+
gtk_html_stream_write (html_stream, "<br>", 4);
+ #undef print_email
+
str = e_contact_get_const (contact, E_CONTACT_HOMEPAGE_URL);
if (str) {
html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c
index 9124583b82..842e954f20 100644
--- a/addressbook/gui/widgets/eab-gui-util.c
+++ b/addressbook/gui/widgets/eab-gui-util.c
@@ -34,11 +34,15 @@
#include "util/eab-book-util.h"
#include <libebook/e-destination.h>
#include "e-util/e-error.h"
+#include "e-util/e-html-utils.h"
#include "misc/e-image-chooser.h"
#include <e-util/e-icon-factory.h>
#include "eab-contact-merging.h"
#include <gnome.h>
+/* we link to camel for decoding quoted printable email addresses */
+#include <camel/camel-mime-utils.h>
+
#include "addressbook/gui/contact-editor/eab-editor.h"
#include "addressbook/gui/contact-editor/e-contact-editor.h"
#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
@@ -932,6 +936,25 @@ eab_send_to_contact_and_email_num_list (GList *c)
CORBA_exception_free (&ev);
}
+static const char *
+get_email (EContact *contact, EContactField field_id, gchar **to_free)
+{
+ char *name = NULL, *mail = NULL;
+ const char *value = e_contact_get_const (contact, field_id);
+
+ *to_free = NULL;
+
+ if (eab_parse_qp_email (value, &name, &mail)) {
+ *to_free = g_strdup_printf ("%s <%s>", name, mail);
+ value = *to_free;
+ }
+
+ g_free (name);
+ g_free (mail);
+
+ return value;
+}
+
static void
eab_send_contact_list_as_attachment (GList *contacts)
{
@@ -1005,18 +1028,25 @@ eab_send_contact_list_as_attachment (GList *contacts)
} else {
EContact *contact = contacts->data;
const gchar *tempstr2;
+ gchar *tempfree = NULL;
tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS);
if (!tempstr2 || !*tempstr2)
tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
if (!tempstr2 || !*tempstr2)
tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG);
- if (!tempstr2 || !*tempstr2)
- tempstr2 = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
- if (!tempstr2 || !*tempstr2)
- tempstr2 = e_contact_get_const (contact, E_CONTACT_EMAIL_2);
- if (!tempstr2 || !*tempstr2)
- tempstr2 = e_contact_get_const (contact, E_CONTACT_EMAIL_3);
+ if (!tempstr2 || !*tempstr2) {
+ g_free (tempfree);
+ tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree);
+ }
+ if (!tempstr2 || !*tempstr2) {
+ g_free (tempfree);
+ tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree);
+ }
+ if (!tempstr2 || !*tempstr2) {
+ g_free (tempfree);
+ tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree);
+ }
if (!tempstr2 || !*tempstr2)
tempstr = g_strdup_printf (_("Contact information"));
@@ -1024,6 +1054,7 @@ eab_send_contact_list_as_attachment (GList *contacts)
tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);
subject = CORBA_string_dup (tempstr);
g_free (tempstr);
+ g_free (tempfree);
}
GNOME_Evolution_Composer_setHeaders (composer_server, "", to_list, cc_list, bcc_list, subject, &ev);
@@ -1118,3 +1149,57 @@ eab_create_image_chooser_widget(gchar *name,
return w;
}
+
+/* To parse something like...
+=?UTF-8?Q?=E0=A4=95=E0=A4=95=E0=A4=AC=E0=A5=82=E0=A5=8B=E0=A5=87?=\t\n=?UTF-8?Q?=E0=A4=B0?=\t\n<aa@aa.ccom>
+and return the decoded representation of name & email parts.
+*/
+gboolean
+eab_parse_qp_email (const gchar *string, gchar **name, gchar **email)
+{
+ struct _camel_header_address *address;
+ gboolean res = FALSE;
+
+ address = camel_header_address_decode (string, "UTF-8");
+
+ if (!address)
+ return FALSE;
+
+ /* report success only when we have filled both name and email address */
+ if (address->type == CAMEL_HEADER_ADDRESS_NAME && address->name && *address->name && address->v.addr && *address->v.addr) {
+ *name = g_strdup (address->name);
+ *email = g_strdup (address->v.addr);
+ res = TRUE;
+ }
+
+ camel_header_address_unref (address);
+
+ return res;
+}
+
+/* This is only wrapper to parse_qp_mail, it decodes string and if returned TRUE,
+ then makes one string and returns it, otherwise returns NULL.
+ Returned string is usable to place directly into GtkHtml stream.
+ Returned value should be freed with g_free. */
+char *
+eab_parse_qp_email_to_html (const gchar *string)
+{
+ char *name = NULL, *mail = NULL;
+ char *html_name, *html_mail;
+ char *value;
+
+ if (!eab_parse_qp_email (string, &name, &mail))
+ return NULL;
+
+ html_name = e_text_to_html (name, 0);
+ html_mail = e_text_to_html (mail, E_TEXT_TO_HTML_CONVERT_ADDRESSES);
+
+ value = g_strdup_printf ("%s &lt;%s&gt;", html_name, html_mail);
+
+ g_free (html_name);
+ g_free (html_mail);
+ g_free (name);
+ g_free (mail);
+
+ return value;
+}
diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h
index 96459e42f1..9dc8f67818 100644
--- a/addressbook/gui/widgets/eab-gui-util.h
+++ b/addressbook/gui/widgets/eab-gui-util.h
@@ -77,6 +77,10 @@ GtkWidget *eab_create_image_chooser_widget (gchar *name, gchar *string1, gchar *
ESource *eab_select_source (const gchar *title, const gchar *message,
const gchar *select_uid, GtkWindow *parent);
+/* To parse quoted printable address & return email & name fields */
+gboolean eab_parse_qp_email (const gchar *string, gchar **name, gchar **email);
+char *eab_parse_qp_email_to_html (const gchar *string);
+
G_END_DECLS
#endif /* __E_ADDRESSBOOK_UTIL_H__ */