From a269411bacc7a7ce549db591204a868a7a8b2184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Wed, 28 Mar 2012 18:39:13 +0200 Subject: WebKit port - port addressbook, calendar and update composer to keep working with GtkHtml --- addressbook/gui/widgets/Makefile.am | 3 + addressbook/gui/widgets/eab-contact-display.c | 1189 ++------------------- addressbook/gui/widgets/eab-contact-formatter.c | 1267 +++++++++++++++++++++++ addressbook/gui/widgets/eab-contact-formatter.h | 89 ++ addressbook/importers/Makefile.am | 5 +- 5 files changed, 1426 insertions(+), 1127 deletions(-) create mode 100644 addressbook/gui/widgets/eab-contact-formatter.c create mode 100644 addressbook/gui/widgets/eab-contact-formatter.h (limited to 'addressbook') diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am index 546a218ff2..19c9c4f72b 100644 --- a/addressbook/gui/widgets/Makefile.am +++ b/addressbook/gui/widgets/Makefile.am @@ -10,6 +10,7 @@ libeabwidgets_la_CPPFLAGS = \ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \ -DEVOLUTION_RULEDIR=\"$(ruledir)\" \ -DEVOLUTION_IMAGESDIR=\"${imagesdir}\" \ + -DEVOLUTION_PRIVDATADIR=\"${privdatadir}\" \ -I$(top_srcdir) \ -I$(top_srcdir)/filter \ -I$(top_srcdir)/widgets \ @@ -32,6 +33,8 @@ libeabwidgets_la_SOURCES = \ eab-config.c \ eab-contact-display.c \ eab-contact-display.h \ + eab-contact-formatter.c \ + eab-contact-formatter.h \ eab-gui-util.c \ eab-gui-util.h \ e-minicard.c \ diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c index 8ade5c5026..fe1728c3b1 100644 --- a/addressbook/gui/widgets/eab-contact-display.c +++ b/addressbook/gui/widgets/eab-contact-display.c @@ -25,6 +25,7 @@ #endif #include "eab-contact-display.h" +#include "eab-contact-formatter.h" #include "eab-gui-util.h" #include "e-util/e-util.h" @@ -39,9 +40,6 @@ #include #include -#include -#include -#include #define EAB_CONTACT_DISPLAY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -52,18 +50,13 @@ struct _EABContactDisplayPrivate { EContact *contact; - EABContactDisplayMode mode; - GtkOrientation orientation; - gboolean show_maps; - - GHashTable *closed_lists; /* see render_contact_list_ * */ + EABContactFormatter *formatter; }; enum { PROP_0, PROP_CONTACT, PROP_MODE, - PROP_ORIENTATION, PROP_SHOW_MAPS }; @@ -72,35 +65,6 @@ enum { LAST_SIGNAL }; -static struct { - const gchar *name; - const gchar *pretty_name; -} -common_location[] = -{ - { "WORK", N_ ("Work") }, - { "HOME", N_ ("Home") }, - { "OTHER", N_ ("Other") } -}; - -#define HTML_HEADER "\n\n" \ - "\n\n\n" - -#define HEADER_COLOR "#7f7f7f" -#define IMAGE_COL_WIDTH "20" -#define CONTACT_LIST_ICON "stock_contact-list" -#define AIM_ICON "im-aim" -#define GROUPWISE_ICON "im-nov" -#define ICQ_ICON "im-icq" -#define JABBER_ICON "im-jabber" -#define MSN_ICON "im-msn" -#define YAHOO_ICON "im-yahoo" -#define GADUGADU_ICON "im-gadugadu" -#define SKYPE_ICON "stock_people" -#define VIDEOCONF_ICON "stock_video-conferencing" - -#define MAX_COMPACT_IMAGE_DIMENSION 48 - static const gchar *ui = "" " " @@ -202,899 +166,37 @@ static GtkActionEntry internal_mailto_entries[] = { }; static void -render_address_link (GString *buffer, - EContact *contact, - gint map_type) -{ - EContactAddress *adr; - GString *link = g_string_new (""); - - adr = e_contact_get (contact, map_type); - if (adr && - (adr->street || adr->locality || adr->region || adr->country)) { - gchar *escaped; - - if (adr->street && *adr->street) g_string_append_printf (link, "%s, ", adr->street); - if (adr->locality && *adr->locality) g_string_append_printf (link, "%s, ", adr->locality); - if (adr->region && *adr->region) g_string_append_printf (link, "%s, ", adr->region); - if (adr->country && *adr->country) g_string_append_printf (link, "%s", adr->country); - - escaped = g_uri_escape_string (link->str, NULL, TRUE); - g_string_assign (link, escaped); - g_free (escaped); - - g_string_prepend (link, "%s", _("Open map")); - } - - if (adr) - e_contact_address_free (adr); - - g_string_append (buffer, link->str); - g_string_free (link, TRUE); -} - -static void -accum_address (GString *buffer, - EContact *contact, - const gchar *html_label, - EContactField adr_field, - EContactField label_field) -{ - EContactAddress *adr; - const gchar *label; - GString *map_link = g_string_new ("
"); - - render_address_link (map_link, contact, adr_field); - - label = e_contact_get_const (contact, label_field); - if (label) { - gchar *html = e_text_to_html (label, E_TEXT_TO_HTML_CONVERT_NL); - - if (TEXT_IS_RIGHT_TO_LEFT) - g_string_append_printf (buffer, "%s%s:%s", html, html_label, map_link->str); - else - g_string_append_printf (buffer, "%s:%s%s", html_label, map_link->str, html); - - g_free (html); - g_string_free (map_link, TRUE); - return; - } - - adr = e_contact_get (contact, adr_field); - if (adr && - (adr->po || adr->ext || adr->street || adr->locality || adr->region || adr->code || adr->country)) { - if (TEXT_IS_RIGHT_TO_LEFT) - g_string_append_printf (buffer, ""); - else - g_string_append_printf (buffer, "%s:%s", html_label, map_link->str); - - if (adr->po && *adr->po) g_string_append_printf (buffer, "%s
", adr->po); - if (adr->ext && *adr->ext) g_string_append_printf (buffer, "%s
", adr->ext); - if (adr->street && *adr->street) g_string_append_printf (buffer, "%s
", adr->street); - if (adr->locality && *adr->locality) g_string_append_printf (buffer, "%s
", adr->locality); - if (adr->region && *adr->region) g_string_append_printf (buffer, "%s
", adr->region); - if (adr->code && *adr->code) g_string_append_printf (buffer, "%s
", adr->code); - if (adr->country && *adr->country) g_string_append_printf (buffer, "%s
", adr->country); - - if (TEXT_IS_RIGHT_TO_LEFT) - g_string_append_printf (buffer, "%s:%s", html_label, map_link->str); - else - g_string_append_printf (buffer, ""); - } - if (adr) - e_contact_address_free (adr); - - g_string_free (map_link, TRUE); -} - -static void -accum_name_value (GString *buffer, - const gchar *label, - const gchar *str, - const gchar *icon, - guint html_flags) -{ - gchar *value = e_text_to_html (str, html_flags); - - if (TEXT_IS_RIGHT_TO_LEFT) { - g_string_append_printf ( - buffer, "" - "%s " - "" - "%s:", - value, label); - g_string_append_printf ( - buffer, ""); - if (icon != NULL) - g_string_append_printf ( - buffer, "", icon); - else - g_string_append_printf (buffer, ""); - } else { - g_string_append_printf ( - buffer, ""); - if (icon != NULL) - g_string_append_printf ( - buffer, "", icon); - g_string_append_printf ( - buffer, "" - "%s:" - " %s", - label, value); - } - - g_free (value); -} - -static void -accum_attribute (GString *buffer, - EContact *contact, - const gchar *html_label, - EContactField field, - const gchar *icon, - guint html_flags) -{ - const gchar *str; - - str = e_contact_get_const (contact, field); - - if (str != NULL && *str != '\0') - accum_name_value (buffer, html_label, str, icon, html_flags); -} - -static void -accum_time_attribute (GString *buffer, - EContact *contact, - const gchar *html_label, - EContactField field, - const gchar *icon, - guint html_flags) -{ - EContactDate *date; - GDate *gdate = NULL; - gchar sdate[100]; - - date = e_contact_get (contact, field); - if (date) { - gdate = g_date_new_dmy ( date->day, - date->month, - date->year ); - g_date_strftime (sdate, 100, "%x", gdate); - g_date_free (gdate); - accum_name_value (buffer, html_label, sdate, icon, html_flags); - e_contact_date_free (date); - } -} - -static void -accum_multival_attribute (GString *buffer, - EContact *contact, - const gchar *html_label, - EContactField field, - const gchar *icon, - guint html_flags) -{ - GList *val_list, *l; - - /* Workaround till bug [1] is fixed. - * [1] https://bugzilla.gnome.org/show_bug.cgi?id=473862 */ - icon = NULL; - - val_list = e_contact_get (contact, field); - for (l = val_list; l; l = l->next) { - const gchar *str = (const gchar *) l->data; - accum_name_value (buffer, html_label, str, icon, html_flags); - } - g_list_foreach (val_list, (GFunc) g_free, NULL); - g_list_free (val_list); -} - -static void -start_block (GString *buffer, - const gchar *label) -{ - g_string_append_printf ( - buffer, "" - "%s" - "", label); -} - -static void -end_block (GString *buffer) -{ - g_string_append (buffer, " "); -} - -static const gchar * -get_email_location (EVCardAttribute *attr) -{ - gint i; - - for (i = 0; i < G_N_ELEMENTS (common_location); i++) { - if (e_vcard_attribute_has_type (attr, common_location[i].name)) - return _(common_location[i].pretty_name); - } - - return _("Other"); -} - -static void -render_title_block (GString *buffer, - EContact *contact) +contact_formatting_finished (GObject *object, + GSimpleAsyncResult *result, + gpointer user_data) { - const gchar *str; + EABContactDisplay *display = user_data; + CamelStreamMem *stream; gchar *html; - EContactPhoto *photo; - - g_string_append_printf ( - buffer, "" - "
", TEXT_IS_RIGHT_TO_LEFT ? - "align=\"right\"" : ""); - photo = e_contact_get (contact, E_CONTACT_PHOTO); - if (!photo) - photo = e_contact_get (contact, E_CONTACT_LOGO); - /* Only handle inlined photos for now */ - if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { - g_string_append (buffer, ""); - } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) { - g_string_append_printf (buffer, "", photo->data.uri); - } - if (photo) - e_contact_photo_free (photo); - - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - g_string_append (buffer, ""); - - g_string_append_printf ( - buffer, "\n", - TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : ""); - - str = e_contact_get_const (contact, E_CONTACT_FILE_AS); - if (!str) - str = e_contact_get_const (contact, E_CONTACT_FULL_NAME); - - if (str) { - html = e_text_to_html (str, 0); - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - g_string_append_printf (buffer, "

%s

", html); - else - g_string_append_printf (buffer, "

%s

", html); - g_free (html); - } - - g_string_append (buffer, "
"); - -} - -static void -render_contact_list_row (GString *buffer, - EDestination *destination, - EABContactDisplay *display) -{ - gchar *evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL); - gboolean list_collapsed = FALSE; - const gchar *listId = e_destination_get_contact_uid (destination), *textrep; - gchar *name = NULL, *email_addr = NULL; - - if (listId) - list_collapsed = GPOINTER_TO_INT (g_hash_table_lookup (display->priv->closed_lists, listId)); - - textrep = e_destination_get_textrep (destination, TRUE); - if (!eab_parse_qp_email (textrep, &name, &email_addr)) - email_addr = g_strdup (textrep); - - g_string_append (buffer, ""); - if (e_destination_is_evolution_list (destination)) { - g_string_append_printf (buffer, - "%s", - e_destination_get_contact_uid (destination), - evolution_imagesdir, - (list_collapsed ? "plus" : "minus"), - name ? name : email_addr); - - if (!list_collapsed) { - const GList *dest, *dests; - g_string_append (buffer, "
"); - - dests = e_destination_list_get_root_dests (destination); - for (dest = dests; dest; dest = dest->next) { - render_contact_list_row (buffer, dest->data, display); - } - - g_string_append (buffer, "
"); - } - - g_string_append (buffer, ""); - - } else { - if (name && *name) { - g_string_append_printf (buffer, "%s <%s>", name, email_addr, email_addr); - } else { - g_string_append_printf (buffer, "%s", email_addr, email_addr); - } - } - - g_string_append (buffer, ""); - - g_free (evolution_imagesdir); - g_free (name); - g_free (email_addr); -} - -static void -render_contact_list_vertical (GString *buffer, - EContact *contact, - EABContactDisplay *display) -{ - EDestination *destination; - const GList *dest, *dests; - - destination = e_destination_new (); - e_destination_set_contact (destination, contact, 0); - dests = e_destination_list_get_root_dests (destination); - - render_title_block (buffer, contact); - - g_string_append_printf (buffer, "
%s", - _("List Members:")); - g_string_append (buffer, ""); - - for (dest = dests; dest; dest = dest->next) { - render_contact_list_row (buffer, dest->data, display); - } - - g_string_append (buffer, "
"); - g_string_append (buffer, "
"); - - g_object_unref (destination); -} - -static void -render_contact_list_horizontal (GString *buffer, - EContact *contact, - EABContactDisplay *display) -{ - EDestination *destination; - const GList *dest, *dests; + GByteArray *ba; - destination = e_destination_new (); - e_destination_set_contact (destination, contact, 0); - dests = e_destination_list_get_root_dests (destination); - - render_title_block (buffer, contact); - - g_string_append_printf (buffer, "" - "
%s
", _("List Members:")); - g_string_append (buffer, ""); - - for (dest = dests; dest; dest = dest->next) - render_contact_list_row (buffer, dest->data, display); - - g_string_append (buffer, "
"); - g_string_append (buffer, "
"); - - g_object_unref (destination); -} - -static void -render_contact_list (GString *buffer, - EContact *contact, - EABContactDisplay *display) - -{ - if (display->priv->orientation == GTK_ORIENTATION_VERTICAL) - render_contact_list_vertical (buffer, contact, display); - else - render_contact_list_horizontal (buffer, contact, display); -} - -static void -render_contact_block (GString *buffer, - EContact *contact) -{ - GString *accum; - GList *email_list, *l, *email_attr_list, *al; - gint email_num = 0; - const gchar *nl; - gchar *nick = NULL; - - accum = g_string_new (""); - nl = ""; - - start_block (buffer, ""); - - email_list = e_contact_get (contact, E_CONTACT_EMAIL); - 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) { - gchar *name = NULL, *mail = NULL; - gchar *attr_str = (gchar *) get_email_location ((EVCardAttribute *) al->data); - - 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%s%s (%s)", - nl, - name ? name : "", - name ? " <" : "", - email_num, - mail, - name ? ">" : "", - attr_str ? attr_str : ""); - email_num++; - nl = "
"; - - g_free (name); - g_free (mail); - } - g_list_foreach (email_list, (GFunc) g_free, NULL); - g_list_foreach (email_attr_list, (GFunc) e_vcard_attribute_free, NULL); - g_list_free (email_list); - g_list_free (email_attr_list); - - if (accum->len) { - - if (TEXT_IS_RIGHT_TO_LEFT) { - g_string_append_printf ( - buffer, "" - "%s " - "" - "%s:" - "" - "", accum->str, _("Email")); - } else { - g_string_append ( - buffer, ""); - g_string_append_printf ( - buffer, "" - "%s: " - "%s", - _("Email"), accum->str); - } - } - - g_string_assign (accum, ""); - nick = e_contact_get (contact, E_CONTACT_NICKNAME); - if (nick && *nick) { - accum_name_value (accum, _("Nickname"), nick, NULL, 0); - if (accum->len > 0) - g_string_append_printf ( - buffer, "%s", accum->str); - } - - g_string_assign (accum, ""); - accum_multival_attribute (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0); - accum_multival_attribute (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0); - accum_multival_attribute (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0); - accum_multival_attribute (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0); - accum_multival_attribute (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0); - accum_multival_attribute (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0); - accum_multival_attribute (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0); - accum_multival_attribute (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0); - - if (accum->len > 0) - g_string_append_printf (buffer, "%s", accum->str); + stream = g_simple_async_result_get_op_res_gpointer (result); + ba = camel_stream_mem_get_byte_array (stream); - end_block (buffer); - - g_string_free (accum, TRUE); - g_free (nick); - -} - -static void -render_work_block (GString *buffer, - EContact *contact) -{ - GString *accum = g_string_new (""); - - accum_attribute (accum, contact, _("Company"), E_CONTACT_ORG, NULL, 0); - accum_attribute (accum, contact, _("Department"), E_CONTACT_ORG_UNIT, NULL, 0); - accum_attribute (accum, contact, _("Profession"), E_CONTACT_ROLE, NULL, 0); - accum_attribute (accum, contact, _("Position"), E_CONTACT_TITLE, NULL, 0); - accum_attribute (accum, contact, _("Manager"), E_CONTACT_MANAGER, NULL, 0); - accum_attribute (accum, contact, _("Assistant"), E_CONTACT_ASSISTANT, NULL, 0); - accum_attribute (accum, contact, _("Video Chat"), E_CONTACT_VIDEO_URL, VIDEOCONF_ICON, E_TEXT_TO_HTML_CONVERT_URLS); - accum_attribute (accum, contact, _("Calendar"), E_CONTACT_CALENDAR_URI, NULL, E_TEXT_TO_HTML_CONVERT_URLS); - accum_attribute (accum, contact, _("Free/Busy"), E_CONTACT_FREEBUSY_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); - accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_BUSINESS, NULL, 0); - accum_attribute (accum, contact, _("Fax"), E_CONTACT_PHONE_BUSINESS_FAX, NULL, 0); - accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK); - - if (accum->len > 0) { - start_block (buffer, _("Work")); - g_string_append_printf (buffer, "%s", accum->str); - end_block (buffer); - } - - g_string_free (accum, TRUE); -} - -static void -render_personal_block (GString *buffer, - EContact *contact) -{ - GString *accum = g_string_new (""); - - accum_attribute (accum, contact, _("Home Page"), E_CONTACT_HOMEPAGE_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); - accum_attribute (accum, contact, _("Web Log"), E_CONTACT_BLOG_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); - - accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_HOME, NULL, 0); - accum_attribute (accum, contact, _("Mobile Phone"), E_CONTACT_PHONE_MOBILE, NULL, 0); - accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_HOME, E_CONTACT_ADDRESS_LABEL_HOME); - accum_time_attribute (accum, contact, _("Birthday"), E_CONTACT_BIRTH_DATE, NULL, 0); - accum_time_attribute (accum, contact, _("Anniversary"), E_CONTACT_ANNIVERSARY, NULL, 0); - accum_attribute (accum, contact, _("Spouse"), E_CONTACT_SPOUSE, NULL, 0); - if (accum->len > 0) { - start_block (buffer, _("Personal")); - g_string_append_printf (buffer, "%s", accum->str); - end_block (buffer); - } - - g_string_free (accum, TRUE); -} - -static void -render_note_block (GString *buffer, - EContact *contact) -{ - const gchar *str; - gchar *html; - - str = e_contact_get_const (contact, E_CONTACT_NOTE); - if (!str || !*str) - return; - - html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_ADDRESSES | E_TEXT_TO_HTML_CONVERT_URLS | E_TEXT_TO_HTML_CONVERT_NL); - - start_block (buffer, _("Note")); - g_string_append_printf (buffer, "%s", html); - end_block (buffer); + html = g_strndup ((gchar *) ba->data, ba->len); + e_web_view_load_string (E_WEB_VIEW (display), html); g_free (html); + g_object_unref (stream); } static void -render_address_map (GString *buffer, - EContact *contact, - gint map_type) -{ -#ifdef WITH_CONTACT_MAPS - if (map_type == E_CONTACT_ADDRESS_WORK) { - g_string_append (buffer, ""); - } else { - g_string_append (buffer, ""); - } -#endif -} - -static void -render_contact_horizontal (GString *buffer, - EContact *contact, - gboolean show_maps) -{ - g_string_append (buffer, ""); - render_title_block (buffer, contact); - g_string_append (buffer, "
"); - - g_string_append (buffer, ""); - render_contact_block (buffer, contact); - render_work_block (buffer, contact); - g_string_append (buffer, ""); - render_personal_block (buffer, contact); - g_string_append (buffer, ""); - g_string_append (buffer, "
"); - if (show_maps) - render_address_map (buffer, contact, E_CONTACT_ADDRESS_WORK); - g_string_append (buffer, "
"); - if (show_maps) - render_address_map (buffer, contact, E_CONTACT_ADDRESS_HOME); - g_string_append (buffer, "
"); - - g_string_append (buffer, ""); - render_note_block (buffer, contact); - g_string_append (buffer, "
"); -} - -static void -render_contact_vertical (GString *buffer, - EContact *contact, - gboolean show_maps) -{ - /* First row: photo & name */ - g_string_append (buffer, ""); - render_title_block (buffer, contact); - g_string_append (buffer, ""); - - /* Second row: addresses etc. */ - g_string_append (buffer, ""); - - /* First column: email, IM */ - g_string_append (buffer, ""); - g_string_append (buffer, ""); - render_contact_block (buffer, contact); - g_string_append (buffer, "
"); - - /* Second column: Work */ - g_string_append (buffer, ""); - render_work_block (buffer, contact); - g_string_append (buffer, "
"); - if (show_maps) - render_address_map (buffer, contact, E_CONTACT_ADDRESS_WORK); - g_string_append (buffer, ""); - - /* Third column: Personal */ - g_string_append (buffer, ""); - render_personal_block (buffer, contact); - g_string_append (buffer, "
"); - if (show_maps) - render_address_map (buffer, contact, E_CONTACT_ADDRESS_HOME); - g_string_append (buffer, ""); - - /* Third row: note */ - g_string_append (buffer, ""); - - g_string_append (buffer, "
\n"); -} - -static void -render_contact (GString *buffer, - EContact *contact, - GtkOrientation orientation, - gboolean show_maps) -{ - if (orientation == GTK_ORIENTATION_VERTICAL) - render_contact_vertical (buffer, contact, show_maps); - else - render_contact_horizontal (buffer, contact, show_maps); -} - -static void -eab_contact_display_render_normal (EABContactDisplay *display, - EContact *contact) -{ - GString *buffer; - - /* XXX The initial buffer size is arbitrary. Tune it. */ - - buffer = g_string_sized_new (4096); - g_string_append (buffer, HTML_HEADER); - g_string_append_printf ( - buffer, "" - "
\n", TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : ""); - - if (contact) { - GtkOrientation orientation; - orientation = display->priv->orientation; - - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - render_contact_list (buffer, contact, display); - else - render_contact (buffer, contact, orientation, display->priv->show_maps); - - } - - g_string_append (buffer, "
\n"); - - e_web_view_load_string (E_WEB_VIEW (display), buffer->str); - - g_string_free (buffer, TRUE); -} - -static void -eab_contact_display_render_compact (EABContactDisplay *display, - EContact *contact) +load_contact (EABContactDisplay *display) { - GString *buffer; - - /* XXX The initial buffer size is arbitrary. Tune it. */ - - buffer = g_string_sized_new (4096); - g_string_append (buffer, HTML_HEADER); - g_string_append (buffer, "\n"); - - if (contact) { - const gchar *str; - gchar *html; - EContactPhoto *photo; - guint bg_frame = 0x000000, bg_body = 0xEEEEEE; - GtkStyle *style; - - style = gtk_widget_get_style (GTK_WIDGET (display)); - if (style) { - gushort r, g, b; - - r = style->black.red >> 8; - g = style->black.green >> 8; - b = style->black.blue >> 8; - bg_frame = ((r << 16) | (g << 8) | b) & 0xffffff; - - #define DARKER(a) (((a) >= 0x22) ? ((a) - 0x22) : 0) - r = DARKER (style->bg[GTK_STATE_NORMAL].red >> 8); - g = DARKER (style->bg[GTK_STATE_NORMAL].green >> 8); - b = DARKER (style->bg[GTK_STATE_NORMAL].blue >> 8); - bg_body = ((r << 16) | (g << 8) | b) & 0xffffff; - #undef DARKER - } - - g_string_append_printf ( - buffer, - "" - "
" - "" - "
" - "" - "
", bg_frame, bg_body); - - photo = e_contact_get (contact, E_CONTACT_PHOTO); - if (!photo) - photo = e_contact_get (contact, E_CONTACT_LOGO); - if (photo) { - gint calced_width = MAX_COMPACT_IMAGE_DIMENSION, calced_height = MAX_COMPACT_IMAGE_DIMENSION; - GdkPixbufLoader *loader = gdk_pixbuf_loader_new (); - GdkPixbuf *pixbuf; - - /* figure out if we need to downscale the - * image here. we don't scale the pixbuf - * itself, just insert width/height tags in - * the html */ - if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { - gdk_pixbuf_loader_write (loader, photo->data.inlined.data, photo->data.inlined.length, NULL); - } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && - g_ascii_strncasecmp (photo->data.uri, "file://", 7) == 0) { - gchar *filename, *contents = NULL; - gsize length; - - filename = g_filename_from_uri (photo->data.uri, NULL, NULL); - if (filename) { - if (g_file_get_contents (filename, &contents, &length, NULL)) { - gdk_pixbuf_loader_write (loader, (const guchar *) contents, length, NULL); - g_free (contents); - } - g_free (filename); - } - } - gdk_pixbuf_loader_close (loader, NULL); - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf) - g_object_ref (pixbuf); - g_object_unref (loader); - if (pixbuf) { - gint max_dimension; - - calced_width = gdk_pixbuf_get_width (pixbuf); - calced_height = gdk_pixbuf_get_height (pixbuf); - - max_dimension = calced_width; - if (max_dimension < calced_height) - max_dimension = calced_height; - - if (max_dimension > MAX_COMPACT_IMAGE_DIMENSION) { - calced_width *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension); - calced_height *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension); - } - g_object_unref (pixbuf); - } - - if (photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) - g_string_append_printf ( - buffer, - "", - calced_width, calced_height, photo->data.uri); - else - g_string_append_printf ( - buffer, - "", - calced_width, calced_height); - - e_contact_photo_free (photo); - } - - g_string_append (buffer, "\n"); - - str = e_contact_get_const (contact, E_CONTACT_FILE_AS); - if (str) { - html = e_text_to_html (str, 0); - g_string_append_printf (buffer, "%s", html); - g_free (html); - } - else { - str = e_contact_get_const (contact, E_CONTACT_FULL_NAME); - if (str) { - html = e_text_to_html (str, 0); - g_string_append_printf (buffer, "%s", html); - g_free (html); - } - } - - g_string_append (buffer, "
"); - - if (e_contact_get (contact, E_CONTACT_IS_LIST)) { - GList *email_list; - GList *l; - - g_string_append (buffer, "
"); - g_string_append_printf (buffer, "%s: ", _("List Members")); - - email_list = e_contact_get (contact, E_CONTACT_EMAIL); - - for (l = email_list; l; l = l->next) { - if (l->data) { - html = e_text_to_html (l->data, 0); - g_string_append_printf (buffer, "%s, ", html); - g_free (html); - } - } - g_string_append (buffer, "
"); - } - else { - gboolean comma = FALSE; - str = e_contact_get_const (contact, E_CONTACT_TITLE); - if (str) { - html = e_text_to_html (str, 0); - g_string_append_printf (buffer, "%s: %s
", _("Job Title"), str); - g_free (html); - } - - #define print_email() { \ - html = eab_parse_qp_email_to_html (str); \ - \ - if (!html) \ - html = e_text_to_html (str, 0); \ - \ - g_string_append_printf (buffer, "%s%s", comma ? ", " : "", html); \ - g_free (html); \ - comma = TRUE; \ - } - - g_string_append_printf (buffer, "%s: ", _("Email")); - str = e_contact_get_const (contact, E_CONTACT_EMAIL_1); - if (str) - print_email (); - - str = e_contact_get_const (contact, E_CONTACT_EMAIL_2); - if (str) - print_email (); - - str = e_contact_get_const (contact, E_CONTACT_EMAIL_3); - if (str) - print_email (); - - g_string_append (buffer, "
"); - - #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); - g_string_append_printf ( - buffer, "%s: %s
", - _("Home page"), html); - g_free (html); - } - - str = e_contact_get_const (contact, E_CONTACT_BLOG_URL); - if (str) { - html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS); - g_string_append_printf ( - buffer, "%s: %s
", - _("Blog"), html); - } - } - - g_string_append (buffer, "
\n"); - } - - g_string_append (buffer, "\n"); - - e_web_view_load_string (E_WEB_VIEW (display), buffer->str); + if (!display->priv->contact) + return; - g_string_free (buffer, TRUE); + eab_contact_formatter_format_contact_async ( + display->priv->formatter, + display->priv->contact, + NULL, + (GAsyncReadyCallback) contact_formatting_finished, + display); } static void @@ -1116,12 +218,6 @@ contact_display_set_property (GObject *object, g_value_get_int (value)); return; - case PROP_ORIENTATION: - eab_contact_display_set_orientation ( - EAB_CONTACT_DISPLAY (object), - g_value_get_int (value)); - return; - case PROP_SHOW_MAPS: eab_contact_display_set_show_maps ( EAB_CONTACT_DISPLAY (object), @@ -1151,12 +247,6 @@ contact_display_get_property (GObject *object, EAB_CONTACT_DISPLAY (object))); return; - case PROP_ORIENTATION: - g_value_set_int ( - value, eab_contact_display_get_orientation ( - EAB_CONTACT_DISPLAY (object))); - return; - case PROP_SHOW_MAPS: g_value_set_boolean ( value, eab_contact_display_get_show_maps ( @@ -1179,84 +269,10 @@ contact_display_dispose (GObject *object) priv->contact = NULL; } - if (priv->closed_lists != NULL) { - g_hash_table_unref (priv->closed_lists); - priv->closed_lists = NULL; - } - /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } -static void -contact_display_url_requested (GtkHTML *html, - const gchar *uri, - GtkHTMLStream *handle) -{ - EABContactDisplay *display; - GtkHTMLClass *class; - gsize length; - - display = EAB_CONTACT_DISPLAY (html); - class = GTK_HTML_CLASS (parent_class); - - /* internal-contact-photo: */ - if (strcmp (uri, "internal-contact-photo:") == 0) { - EContactPhoto *photo; - EContact *contact; - - contact = eab_contact_display_get_contact (display); - photo = e_contact_get (contact, E_CONTACT_PHOTO); - if (photo == NULL) - photo = e_contact_get (contact, E_CONTACT_LOGO); - - if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) - gtk_html_stream_write ( - handle, (gchar *) photo->data.inlined.data, - photo->data.inlined.length); - - gtk_html_end (html, handle, GTK_HTML_STREAM_OK); - - e_contact_photo_free (photo); - - return; - } - - /* evo-icon:<> */ - length = strlen ("evo-icon:"); - if (g_ascii_strncasecmp (uri, "evo-icon:", length) == 0) { - GtkIconTheme *icon_theme; - GtkIconInfo *icon_info; - const gchar *filename; - gchar *icon_uri; - GError *error = NULL; - - icon_theme = gtk_icon_theme_get_default (); - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, uri + length, GTK_ICON_SIZE_MENU, 0); - g_return_if_fail (icon_info != NULL); - - filename = gtk_icon_info_get_filename (icon_info); - icon_uri = g_filename_to_uri (filename, NULL, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - /* Chain up with the URI for the icon file. */ - class->url_requested (html, icon_uri, handle); - - gtk_icon_info_free (icon_info); - g_free (icon_uri); - - return; - } - - /* Chain up to parent's uri_requested() method. */ - class->url_requested (html, uri, handle); -} - static void contact_display_hovering_over_link (EWebView *web_view, const gchar *title, @@ -1309,19 +325,6 @@ contact_display_link_clicked (EWebView *web_view, index = atoi (uri + length); contact_display_emit_send_message (display, index); - return; - } else if (g_str_has_prefix (uri, "##") && g_str_has_suffix (uri, "##")) { - gchar *list_id = g_strndup (uri + 2, strlen (uri) - 4); - - if (g_hash_table_lookup (display->priv->closed_lists, list_id)) { - g_hash_table_remove (display->priv->closed_lists, list_id); - g_free (list_id); - } else { - g_hash_table_insert (display->priv->closed_lists, list_id, GINT_TO_POINTER (TRUE)); - } - - eab_contact_display_render_normal (display, display->priv->contact); - return; } @@ -1341,9 +344,11 @@ handle_map_scroll_event (GtkWidget *widget, return TRUE; } -static void -contact_display_object_requested (GtkHTML *html, - GtkHTMLEmbedded *eb, +static GtkWidget * +contact_display_object_requested (WebKitWebView *web_view, + gchar *mime_type, + gchar *uri, + GHashTable *param, EABContactDisplay *display) { EContact *contact = display->priv->contact; @@ -1351,18 +356,18 @@ contact_display_object_requested (GtkHTML *html, const gchar *contact_uid = e_contact_get_const (contact, E_CONTACT_UID); gchar *full_name; EContactAddress *address; + GtkWidget *map = NULL; - if (g_ascii_strcasecmp (eb->classid, "address-map-work") == 0) { + if (strstr (mime_type, "work") != NULL) { address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK); full_name = g_strconcat (name, " (", _("Work"), ")", NULL); - } else { + } else if (strstr (mime_type, "home") != NULL) { address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME); full_name = g_strconcat (name, " (", _("Home"), ")", NULL); } if (address) { - GtkWidget *map = e_contact_map_new (); - gtk_container_add (GTK_CONTAINER (eb), map); + map = e_contact_map_new (); gtk_widget_set_size_request (map, 250, 250); g_signal_connect ( E_CONTACT_MAP (map), "contact-added", @@ -1378,10 +383,15 @@ contact_display_object_requested (GtkHTML *html, e_contact_map_add_marker ( E_CONTACT_MAP (map), full_name, contact_uid, address, NULL); + + gtk_widget_show_all (map); + + e_contact_address_free (address); } g_free (full_name); - e_contact_address_free (address); + + return map; } #endif @@ -1419,7 +429,6 @@ static void eab_contact_display_class_init (EABContactDisplayClass *class) { GObjectClass *object_class; - GtkHTMLClass *html_class; EWebViewClass *web_view_class; parent_class = g_type_class_peek_parent (class); @@ -1430,9 +439,6 @@ eab_contact_display_class_init (EABContactDisplayClass *class) object_class->get_property = contact_display_get_property; object_class->dispose = contact_display_dispose; - html_class = GTK_HTML_CLASS (class); - html_class->url_requested = contact_display_url_requested; - web_view_class = E_WEB_VIEW_CLASS (class); web_view_class->hovering_over_link = contact_display_hovering_over_link; web_view_class->link_clicked = contact_display_link_clicked; @@ -1461,18 +467,6 @@ eab_contact_display_class_init (EABContactDisplayClass *class) EAB_CONTACT_DISPLAY_RENDER_NORMAL, G_PARAM_READWRITE)); - g_object_class_install_property ( - object_class, - PROP_ORIENTATION, - g_param_spec_int ( - "orientation", - NULL, - NULL, - GTK_ORIENTATION_HORIZONTAL, - GTK_ORIENTATION_VERTICAL, - GTK_ORIENTATION_HORIZONTAL, - G_PARAM_READWRITE)); - g_object_class_install_property ( object_class, PROP_SHOW_MAPS, @@ -1504,18 +498,17 @@ eab_contact_display_init (EABContactDisplay *display) GError *error = NULL; display->priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (display); - display->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; - display->priv->orientation = GTK_ORIENTATION_HORIZONTAL; - display->priv->show_maps = FALSE; - display->priv->closed_lists = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, NULL); + + display->priv->formatter = g_object_new ( + EAB_TYPE_CONTACT_FORMATTER, + "display-mode", EAB_CONTACT_DISPLAY_RENDER_NORMAL, + "render-maps", FALSE, NULL); web_view = E_WEB_VIEW (display); ui_manager = e_web_view_get_ui_manager (web_view); #ifdef WITH_CONTACT_MAPS - g_signal_connect ( - web_view, "object-requested", + g_signal_connect (web_view, "create-plugin-widget", G_CALLBACK (contact_display_object_requested), display); #endif @@ -1554,27 +547,17 @@ void eab_contact_display_set_contact (EABContactDisplay *display, EContact *contact) { - EABContactDisplayMode mode; - g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display)); - mode = eab_contact_display_get_mode (display); - if (contact != NULL) g_object_ref (contact); + if (display->priv->contact != NULL) g_object_unref (display->priv->contact); - display->priv->contact = contact; - switch (mode) { - case EAB_CONTACT_DISPLAY_RENDER_NORMAL: - eab_contact_display_render_normal (display, contact); - break; + display->priv->contact = contact; - case EAB_CONTACT_DISPLAY_RENDER_COMPACT: - eab_contact_display_render_compact (display, contact); - break; - } + load_contact (display); g_object_notify (G_OBJECT (display), "contact"); } @@ -1584,65 +567,27 @@ eab_contact_display_get_mode (EABContactDisplay *display) { g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), 0); - return display->priv->mode; + return eab_contact_formatter_get_display_mode (display->priv->formatter); } void eab_contact_display_set_mode (EABContactDisplay *display, EABContactDisplayMode mode) { - EContact *contact; - g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display)); - display->priv->mode = mode; - contact = eab_contact_display_get_contact (display); + if (eab_contact_formatter_get_display_mode ( + display->priv->formatter) == mode) { - switch (mode) { - case EAB_CONTACT_DISPLAY_RENDER_NORMAL: - eab_contact_display_render_normal (display, contact); - break; - - case EAB_CONTACT_DISPLAY_RENDER_COMPACT: - eab_contact_display_render_compact (display, contact); - break; - } - - g_object_notify (G_OBJECT (display), "mode"); -} - -GtkOrientation -eab_contact_display_get_orientation (EABContactDisplay *display) -{ - g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), 0); - - return display->priv->orientation; -} - -void -eab_contact_display_set_orientation (EABContactDisplay *display, - GtkOrientation orientation) -{ - EABContactDisplayMode mode; - EContact *contact; - - g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display)); - - display->priv->orientation = orientation; - contact = eab_contact_display_get_contact (display); - mode = eab_contact_display_get_mode (display); + return; + }; - switch (mode) { - case EAB_CONTACT_DISPLAY_RENDER_NORMAL: - eab_contact_display_render_normal (display, contact); - break; + eab_contact_formatter_set_display_mode ( + display->priv->formatter, mode); - case EAB_CONTACT_DISPLAY_RENDER_COMPACT: - eab_contact_display_render_compact (display, contact); - break; - } + load_contact (display); - g_object_notify (G_OBJECT (display), "orientation"); + g_object_notify (G_OBJECT (display), "mode"); } gboolean @@ -1650,31 +595,25 @@ eab_contact_display_get_show_maps (EABContactDisplay *display) { g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), FALSE); - return display->priv->show_maps; + return eab_contact_formatter_get_render_maps (display->priv->formatter); } void eab_contact_display_set_show_maps (EABContactDisplay *display, gboolean show_maps) { - EABContactDisplayMode mode; - EContact *contact; - g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display)); - display->priv->show_maps = show_maps; - contact = eab_contact_display_get_contact (display); - mode = eab_contact_display_get_mode (display); - - switch (mode) { - case EAB_CONTACT_DISPLAY_RENDER_NORMAL: - eab_contact_display_render_normal (display, contact); - break; + if (eab_contact_formatter_get_render_maps ( + display->priv->formatter) == show_maps) { - case EAB_CONTACT_DISPLAY_RENDER_COMPACT: - eab_contact_display_render_compact (display, contact); - break; + return; } + eab_contact_formatter_set_render_maps ( + display->priv->formatter, show_maps); + + load_contact (display); + g_object_notify (G_OBJECT (display), "show-maps"); } diff --git a/addressbook/gui/widgets/eab-contact-formatter.c b/addressbook/gui/widgets/eab-contact-formatter.c new file mode 100644 index 0000000000..c0ca4ed524 --- /dev/null +++ b/addressbook/gui/widgets/eab-contact-formatter.c @@ -0,0 +1,1267 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "eab-contact-formatter.h" + +#include "eab-gui-util.h" +#include "e-util/e-util.h" +#include "e-util/e-util-private.h" +#include "e-util/e-html-utils.h" +#include "e-util/e-icon-factory.h" +#include "e-util/e-plugin-ui.h" + +#ifdef WITH_CONTACT_MAPS +#include "widgets/misc/e-contact-map.h" +#endif + +#include +#include + +G_DEFINE_TYPE ( + EABContactFormatter, + eab_contact_formatter, + G_TYPE_OBJECT); + +#define EAB_CONTACT_FORMATTER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterPrivate)) + +#define TEXT_IS_RIGHT_TO_LEFT \ + (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL) + +static gpointer parent_class = NULL; + +enum { + PROP_0, + PROP_DISPLAY_MODE, + PROP_RENDER_MAPS +}; + +struct _EABContactFormatterPrivate { + + EContact *contact; + + EABContactDisplayMode mode; + gboolean render_maps; +}; + +static struct { + const gchar *name; + const gchar *pretty_name; +} +common_location[] = +{ + { "WORK", N_ ("Work") }, + { "HOME", N_ ("Home") }, + { "OTHER", N_ ("Other") } +}; + +#define IMAGE_COL_WIDTH "20" +#define CONTACT_LIST_ICON "stock_contact-list" +#define AIM_ICON "im-aim" +#define GROUPWISE_ICON "im-nov" +#define ICQ_ICON "im-icq" +#define JABBER_ICON "im-jabber" +#define MSN_ICON "im-msn" +#define YAHOO_ICON "im-yahoo" +#define GADUGADU_ICON "im-gadugadu" +#define SKYPE_ICON "stock_people" +#define VIDEOCONF_ICON "stock_video-conferencing" + +#define MAX_COMPACT_IMAGE_DIMENSION 48 + +#define HTML_HEADER "\n\n" \ +"\n\n" \ +"" \ +"\n" \ +"\n" \ +"\n" + +static gchar * +get_icon_uri (const gchar *icon_name) +{ + GtkIconTheme *icon_theme; + GtkIconInfo *icon_info; + const gchar *filename; + gchar *icon_uri; + GError *error = NULL; + + icon_theme = gtk_icon_theme_get_default (); + icon_info = gtk_icon_theme_lookup_icon ( + icon_theme, icon_name, GTK_ICON_SIZE_MENU, 0); + g_return_val_if_fail (icon_info != NULL, NULL); + + filename = gtk_icon_info_get_filename (icon_info); + icon_uri = g_filename_to_uri (filename, NULL, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + gtk_icon_info_free (icon_info); + + return icon_uri; +} + +static void +render_address_link (GString *buffer, + EContact *contact, + gint map_type) +{ + EContactAddress *adr; + GString *link = g_string_new (""); + + adr = e_contact_get (contact, map_type); + if (adr && + (adr->street || adr->locality || adr->region || adr->country)) { + gchar *escaped; + + if (adr->street && *adr->street) + g_string_append_printf (link, "%s, ", adr->street); + + if (adr->locality && *adr->locality) + g_string_append_printf (link, "%s, ", adr->locality); + + if (adr->region && *adr->region) + g_string_append_printf (link, "%s, ", adr->region); + + if (adr->country && *adr->country) + g_string_append_printf (link, "%s", adr->country); + + escaped = g_uri_escape_string (link->str, NULL, TRUE); + g_string_assign (link, escaped); + g_free (escaped); + + g_string_prepend (link, "%s", _("Open map")); + } + + if (adr) + e_contact_address_free (adr); + + g_string_append (buffer, link->str); + g_string_free (link, TRUE); +} + +static void +accum_address (GString *buffer, + EContact *contact, + const gchar *html_label, + EContactField adr_field, + EContactField label_field) +{ + EContactAddress *adr; + const gchar *label; + GString *map_link = g_string_new ("
"); + + render_address_link (map_link, contact, adr_field); + + label = e_contact_get_const (contact, label_field); + if (label) { + gchar *html = e_text_to_html (label, E_TEXT_TO_HTML_CONVERT_NL); + + if (TEXT_IS_RIGHT_TO_LEFT) { + g_string_append_printf ( + buffer, + "" + "%s" + "%s:
%s" + "" + "", + html, html_label, map_link->str); + } else { + g_string_append_printf ( + buffer, + "" + "" + "%s:
%s" + "%s" + "", + html_label, map_link->str, html); + } + + g_free (html); + g_string_free (map_link, TRUE); + return; + } + + adr = e_contact_get (contact, adr_field); + if (adr && + (adr->po || adr->ext || adr->street || adr->locality || + adr->region || adr->code || adr->country)) { + + if (TEXT_IS_RIGHT_TO_LEFT) { + g_string_append_printf ( + buffer, ""); + } else { + g_string_append_printf ( + buffer, + "" + "" + "%s:
%s" + "", + html_label, map_link->str); + } + + if (adr->po && *adr->po) + g_string_append_printf (buffer, "%s
", adr->po); + + if (adr->ext && *adr->ext) + g_string_append_printf (buffer, "%s
", adr->ext); + + if (adr->street && *adr->street) + g_string_append_printf (buffer, "%s
", adr->street); + + if (adr->locality && *adr->locality) + g_string_append_printf (buffer, "%s
", adr->locality); + + if (adr->region && *adr->region) + g_string_append_printf (buffer, "%s
", adr->region); + + if (adr->code && *adr->code) + g_string_append_printf (buffer, "%s
", adr->code); + + if (adr->country && *adr->country) + g_string_append_printf (buffer, "%s
", adr->country); + + if (TEXT_IS_RIGHT_TO_LEFT) { + g_string_append_printf ( + buffer, + "%s" + "" + "", html_label, map_link->str); + } else { + g_string_append_printf (buffer, ""); + } + + } + + if (adr) + e_contact_address_free (adr); + + g_string_free (map_link, TRUE); +} + +static void +render_table_row (GString *buffer, + const gchar *label, + const gchar *str, + const gchar *icon, + guint html_flags) +{ + const gchar *icon_html; + gchar *value; + + if (html_flags) + value = e_text_to_html (str, html_flags); + else + value = (gchar *) str; + + if (icon) { + gchar *icon_uri = get_icon_uri (icon); + icon_html = g_strdup_printf ("", icon_uri); + g_free (icon_uri); + } else { + icon_html = ""; + } + + if (TEXT_IS_RIGHT_TO_LEFT) { + g_string_append_printf ( + buffer, "" + "%s" + ":%s" + "%s" + "", + value, label, icon_html); + } else { + g_string_append_printf ( + buffer, "" + "%s" + "%s:" + "%s" + "", + icon_html, label, value); + } + + if (html_flags) + g_free (value); +} + +static void +accum_attribute (GString *buffer, + EContact *contact, + const gchar *html_label, + EContactField field, + const gchar *icon, + guint html_flags) +{ + const gchar *str; + + str = e_contact_get_const (contact, field); + + if (str != NULL && *str != '\0') + render_table_row (buffer, html_label, str, icon, html_flags); +} + +static void +accum_time_attribute (GString *buffer, + EContact *contact, + const gchar *html_label, + EContactField field, + const gchar *icon, + guint html_flags) +{ + EContactDate *date; + GDate *gdate = NULL; + gchar sdate[100]; + + date = e_contact_get (contact, field); + if (date) { + gdate = g_date_new_dmy ( date->day, + date->month, + date->year ); + g_date_strftime (sdate, 100, "%x", gdate); + g_date_free (gdate); + render_table_row (buffer, html_label, sdate, icon, html_flags); + e_contact_date_free (date); + } +} + +static void +accum_attribute_multival (GString *buffer, + EContact *contact, + const gchar *html_label, + EContactField field, + const gchar *icon, + guint html_flags) +{ + GList *val_list, *l; + GString *val = g_string_new (""); + + val_list = e_contact_get (contact, field); + + for (l = val_list; l; l = l->next) { + if (l != val_list) + g_string_append (val, "
"); + + g_string_append (val, l->data); + } + + if (val->str && *val->str) + render_table_row (buffer, html_label, val->str, icon, html_flags); + + g_string_free (val, TRUE); + g_list_foreach (val_list, (GFunc) g_free, NULL); + g_list_free (val_list); +} + +static const gchar * +get_email_location (EVCardAttribute *attr) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + if (e_vcard_attribute_has_type (attr, common_location[i].name)) + return _(common_location[i].pretty_name); + } + + return _("Other"); +} + +static void +render_title_block (EABContactFormatter *formatter, + GString *buffer) +{ + const gchar *str; + gchar *html; + EContactPhoto *photo; + EContact *contact; + + contact = formatter->priv->contact; + + g_string_append_printf ( + buffer, + "" + "
", TEXT_IS_RIGHT_TO_LEFT ? + "align=\"right\"" : ""); + + photo = e_contact_get (contact, E_CONTACT_PHOTO); + if (!photo) + photo = e_contact_get (contact, E_CONTACT_LOGO); + + if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { + gchar *photo_data; + photo_data = g_base64_encode ( + photo->data.inlined.data, + photo->data.inlined.length); + g_string_append_printf ( + buffer, "", + photo->data.inlined.mime_type, + photo_data); + } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) { + g_string_append_printf ( + buffer, "", photo->data.uri); + } + + if (photo) + e_contact_photo_free (photo); + + if (e_contact_get (contact, E_CONTACT_IS_LIST)) { + gchar *icon = get_icon_uri (CONTACT_LIST_ICON); + g_string_append_printf (buffer, "", icon); + g_free (icon); + } + + g_string_append_printf ( + buffer, + "\n", + TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : ""); + + str = e_contact_get_const (contact, E_CONTACT_FILE_AS); + if (!str) + str = e_contact_get_const (contact, E_CONTACT_FULL_NAME); + + if (str) { + html = e_text_to_html (str, 0); + if (e_contact_get (contact, E_CONTACT_IS_LIST)) { + g_string_append_printf ( + buffer, + "

%s

", + html); + } else { + g_string_append_printf (buffer, "

%s

", html); + } + g_free (html); + } + + g_string_append (buffer, "
"); +} + +static void +render_contact_list_row (EABContactFormatter *formatter, + EDestination *destination, + GString *buffer) +{ + gchar *evolution_imagesdir; + gboolean list_collapsed = FALSE; + const gchar *textrep; + gchar *name = NULL, *email_addr = NULL; + + evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL); + + textrep = e_destination_get_textrep (destination, TRUE); + if (!eab_parse_qp_email (textrep, &name, &email_addr)) + email_addr = g_strdup (textrep); + + g_string_append (buffer, ""); + if (e_destination_is_evolution_list (destination)) { + g_string_append_printf ( + buffer, + "" + "" + "%s", + evolution_imagesdir, + e_destination_get_contact_uid (destination), + name ? name : email_addr); + + if (!list_collapsed) { + const GList *dest, *dests; + g_string_append_printf ( + buffer, + "
", + e_destination_get_contact_uid (destination)); + + dests = e_destination_list_get_root_dests (destination); + for (dest = dests; dest; dest = dest->next) { + render_contact_list_row ( + formatter, dest->data, buffer); + } + + g_string_append (buffer, "
"); + } + + g_string_append (buffer, ""); + + } else { + if (name && *name) { + g_string_append_printf ( + buffer, + "%s <" + "%s>" + "", + name, email_addr, email_addr); + } else { + g_string_append_printf ( + buffer, + "" + "%s" + "", + email_addr, email_addr); + } + } + + g_string_append (buffer, ""); + + g_free (evolution_imagesdir); + g_free (name); + g_free (email_addr); +} + +static void +render_contact_list (EABContactFormatter *formatter, + GString *buffer) +{ + EContact *contact; + EDestination *destination; + const GList *dest, *dests; + + contact = formatter->priv->contact; + + destination = e_destination_new (); + e_destination_set_contact (destination, contact, 0); + dests = e_destination_list_get_root_dests (destination); + + render_title_block (formatter, buffer); + + g_string_append_printf ( + buffer, + "" + "
%s
", _("List Members:")); + + g_string_append (buffer, ""); + + for (dest = dests; dest; dest = dest->next) + render_contact_list_row (formatter, dest->data, buffer); + + g_string_append (buffer, "
"); + g_string_append (buffer, "
"); + + g_object_unref (destination); +} + +static void +render_contact_column (EABContactFormatter *formatter, + GString *buffer) +{ + EContact *contact; + GString *accum, *email; + GList *email_list, *l, *email_attr_list, *al; + gint email_num = 0; + const gchar *nl; + + contact = formatter->priv->contact; + email = g_string_new (""); + nl = ""; + + email_list = e_contact_get (contact, E_CONTACT_EMAIL); + 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) { + gchar *name = NULL, *mail = NULL; + gchar *attr_str = (gchar *) get_email_location ((EVCardAttribute *) al->data); + + if (!eab_parse_qp_email (l->data, &name, &mail)) + mail = e_text_to_html (l->data, 0); + + g_string_append_printf ( + email, + "%s%s%s%s%s " + "(%s)", + nl, + name ? name : "", + name ? " <" : "", + email_num, + mail, + name ? ">" : "", + attr_str ? attr_str : ""); + email_num++; + nl = "
"; + + g_free (name); + g_free (mail); + } + g_list_foreach (email_list, (GFunc) g_free, NULL); + g_list_foreach (email_attr_list, (GFunc) e_vcard_attribute_free, NULL); + g_list_free (email_list); + g_list_free (email_attr_list); + + accum = g_string_new (""); + + if (email->len) + render_table_row (accum, _("Email"), email->str, NULL, 0); + + accum_attribute (accum, contact, _("Nickname"), E_CONTACT_NICKNAME, NULL, 0); + accum_attribute_multival (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0); + accum_attribute_multival (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0); + accum_attribute_multival (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0); + accum_attribute_multival (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0); + accum_attribute_multival (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0); + accum_attribute_multival (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0); + accum_attribute_multival (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0); + accum_attribute_multival (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0); + + if (accum->len) + g_string_append_printf ( + buffer, + "
" + "%s
" + "
", accum->str); + + g_string_free (accum, TRUE); + g_string_free (email, TRUE); +} + +static void +accum_address_map (GString *buffer, + EContact *contact, + gint map_type) +{ + #ifdef WITH_CONTACT_MAPS + + g_string_append (buffer, ""); + + if (map_type == E_CONTACT_ADDRESS_WORK) { + g_string_append (buffer, + ""); + } else { + g_string_append (buffer, + ""); + } + + g_string_append (buffer, ""); + + #endif +} + +static void +render_work_column (EABContactFormatter *formatter, + GString *buffer) +{ + EContact *contact = formatter->priv->contact; + GString *accum = g_string_new (""); + + accum_attribute (accum, contact, _("Company"), E_CONTACT_ORG, NULL, 0); + accum_attribute (accum, contact, _("Department"), E_CONTACT_ORG_UNIT, NULL, 0); + accum_attribute (accum, contact, _("Profession"), E_CONTACT_ROLE, NULL, 0); + accum_attribute (accum, contact, _("Position"), E_CONTACT_TITLE, NULL, 0); + accum_attribute (accum, contact, _("Manager"), E_CONTACT_MANAGER, NULL, 0); + accum_attribute (accum, contact, _("Assistant"), E_CONTACT_ASSISTANT, NULL, 0); + accum_attribute (accum, contact, _("Video Chat"), E_CONTACT_VIDEO_URL, VIDEOCONF_ICON, E_TEXT_TO_HTML_CONVERT_URLS); + accum_attribute (accum, contact, _("Calendar"), E_CONTACT_CALENDAR_URI, NULL, E_TEXT_TO_HTML_CONVERT_URLS); + accum_attribute (accum, contact, _("Free/Busy"), E_CONTACT_FREEBUSY_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); + accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_BUSINESS, NULL, 0); + accum_attribute (accum, contact, _("Fax"), E_CONTACT_PHONE_BUSINESS_FAX, NULL, 0); + accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK); + if (formatter->priv->render_maps) + accum_address_map (accum, contact, E_CONTACT_ADDRESS_WORK); + + if (accum->len > 0) { + g_string_append_printf ( + buffer, + "
" + "

%s

" + "%s
" + "
", _("Work"), accum->str); + } + + g_string_free (accum, TRUE); +} + +static void +render_personal_column (EABContactFormatter *formatter, + GString *buffer) +{ + EContact *contact = formatter->priv->contact; + GString *accum = g_string_new (""); + + accum_attribute (accum, contact, _("Home Page"), E_CONTACT_HOMEPAGE_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); + accum_attribute (accum, contact, _("Web Log"), E_CONTACT_BLOG_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); + accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_HOME, NULL, 0); + accum_attribute (accum, contact, _("Mobile Phone"), E_CONTACT_PHONE_MOBILE, NULL, 0); + accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_HOME, E_CONTACT_ADDRESS_LABEL_HOME); + accum_time_attribute (accum, contact, _("Birthday"), E_CONTACT_BIRTH_DATE, NULL, 0); + accum_time_attribute (accum, contact, _("Anniversary"), E_CONTACT_ANNIVERSARY, NULL, 0); + accum_attribute (accum, contact, _("Spouse"), E_CONTACT_SPOUSE, NULL, 0); + if (formatter->priv->render_maps) + accum_address_map (accum, contact, E_CONTACT_ADDRESS_HOME); + + if (accum->len > 0) { + g_string_append_printf ( + buffer, + "
" + "

%s

" + "%s
" + "
", _("Personal"), accum->str); + } + + g_string_free (accum, TRUE); +} + +static void +render_footer (EABContactFormatter *formatter, + GString *buffer) +{ + EContact *contact; + const gchar *str; + + contact = formatter->priv->contact; + + str = e_contact_get_const (contact, E_CONTACT_NOTE); + if (!str || !*str) + return; + + g_string_append ( + buffer, + "
"); + + render_table_row ( + buffer, _("Note"), + e_contact_get_const (contact, E_CONTACT_NOTE), + NULL, + E_TEXT_TO_HTML_CONVERT_ADDRESSES | + E_TEXT_TO_HTML_CONVERT_URLS | + E_TEXT_TO_HTML_CONVERT_NL); + + g_string_append (buffer, "
"); +} + +static void +render_contact (EABContactFormatter *formatter, + GString *buffer) +{ + render_title_block (formatter, buffer); + + g_string_append (buffer, "
"); + render_contact_column (formatter, buffer); + render_work_column (formatter, buffer); + render_personal_column (formatter, buffer); + g_string_append (buffer, "
"); + + render_footer (formatter, buffer); +} + +static void +render_normal (EABContactFormatter *formatter, + GString *buffer) +{ + g_string_append (buffer, HTML_HEADER); + g_string_append (buffer, ""); + + if (formatter->priv->contact) { + + if (e_contact_get (formatter->priv->contact, E_CONTACT_IS_LIST)) + + render_contact_list ( + formatter, + buffer); + else + render_contact ( + formatter, + buffer); + + } + + g_string_append (buffer, "\n"); +} + +static void +render_compact (EABContactFormatter *formatter, + GString *buffer) +{ + EContact *contact = formatter->priv->contact; + const gchar *str; + gchar *html; + EContactPhoto *photo; + + g_string_append (buffer, HTML_HEADER); + g_string_append (buffer, "\n"); + + if (!contact) { + g_string_append (buffer, ""); + return; + } + + g_string_append_printf ( + buffer, + "
"); + + photo = e_contact_get (contact, E_CONTACT_PHOTO); + + if (!photo) + photo = e_contact_get (contact, E_CONTACT_LOGO); + + if (photo) { + gint calced_width = MAX_COMPACT_IMAGE_DIMENSION, calced_height = MAX_COMPACT_IMAGE_DIMENSION; + GdkPixbufLoader *loader = gdk_pixbuf_loader_new (); + GdkPixbuf *pixbuf; + + /* figure out if we need to downscale the + * image here. we don't scale the pixbuf + * itself, just insert width/height tags in + * the html */ + if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { + gdk_pixbuf_loader_write ( + loader, photo->data.inlined.data, + photo->data.inlined.length, NULL); + } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI && + photo->data.uri && + g_ascii_strncasecmp (photo->data.uri, "file://", 7) == 0) { + gchar *filename, *contents = NULL; + gsize length; + + filename = g_filename_from_uri (photo->data.uri, NULL, NULL); + + if (filename) { + if (g_file_get_contents (filename, &contents, &length, NULL)) { + gdk_pixbuf_loader_write (loader, (const guchar *) contents, length, NULL); + g_free (contents); + } + + g_free (filename); + } + } + + gdk_pixbuf_loader_close (loader, NULL); + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + + if (pixbuf) + g_object_ref (pixbuf); + + g_object_unref (loader); + + if (pixbuf) { + gint max_dimension; + + calced_width = gdk_pixbuf_get_width (pixbuf); + calced_height = gdk_pixbuf_get_height (pixbuf); + + max_dimension = calced_width; + + if (max_dimension < calced_height) + max_dimension = calced_height; + + if (max_dimension > MAX_COMPACT_IMAGE_DIMENSION) { + calced_width *= ( (gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension); + calced_height *= ( (gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension); + } + + g_object_unref (pixbuf); + } + + if (photo->type == E_CONTACT_PHOTO_TYPE_URI && + photo->data.uri && *photo->data.uri) + g_string_append_printf ( + buffer, + "", + calced_width, calced_height, photo->data.uri); + else { + gchar *photo_data; + + photo_data = g_base64_encode ( + photo->data.inlined.data, + photo->data.inlined.length); + g_string_append_printf (buffer, + "", + photo->data.inlined.mime_type, + photo_data, + calced_width, calced_height); + g_free (photo_data); + } + + e_contact_photo_free (photo); + } + + g_string_append (buffer, "\n"); + + str = e_contact_get_const (contact, E_CONTACT_FILE_AS); + + if (str) { + html = e_text_to_html (str, 0); + g_string_append_printf (buffer, "%s", html); + g_free (html); + } else { + str = e_contact_get_const (contact, E_CONTACT_FULL_NAME); + + if (str) { + html = e_text_to_html (str, 0); + g_string_append_printf (buffer, "%s", html); + g_free (html); + } + } + + g_string_append (buffer, "
"); + + if (e_contact_get (contact, E_CONTACT_IS_LIST)) { + GList *email_list; + GList *l; + + g_string_append ( + buffer, + "" + "
"); + g_string_append_printf ( + buffer, + "%s: ", _ ("List Members")); + + email_list = e_contact_get (contact, E_CONTACT_EMAIL); + + for (l = email_list; l; l = l->next) { + if (l->data) { + html = e_text_to_html (l->data, 0); + g_string_append_printf (buffer, "%s, ", html); + g_free (html); + } + } + + g_string_append (buffer, "
"); + + } else { + + gboolean comma = FALSE; + str = e_contact_get_const (contact, E_CONTACT_TITLE); + + if (str) { + html = e_text_to_html (str, 0); + g_string_append_printf (buffer, "%s: %s
", _ ("Job Title"), str); + g_free (html); + } + + #define print_email() { \ + html = eab_parse_qp_email_to_html (str); \ + \ + if (!html) \ + html = e_text_to_html (str, 0); \ + \ + g_string_append_printf (buffer, "%s%s", comma ? ", " : "", html); \ + g_free (html); \ + comma = TRUE; \ + } + + g_string_append_printf (buffer, "%s: ", _ ("Email")); + str = e_contact_get_const (contact, E_CONTACT_EMAIL_1); + + if (str) + print_email (); + + str = e_contact_get_const (contact, E_CONTACT_EMAIL_2); + + if (str) + print_email (); + + str = e_contact_get_const (contact, E_CONTACT_EMAIL_3); + + if (str) + print_email (); + + g_string_append (buffer, "
"); + + #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); + g_string_append_printf ( + buffer, "%s: %s
", + _ ("Home page"), html); + g_free (html); + } + + str = e_contact_get_const (contact, E_CONTACT_BLOG_URL); + + if (str) { + html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS); + g_string_append_printf ( + buffer, "%s: %s
", + _ ("Blog"), html); + } + } + + g_string_append (buffer, "
\n"); + + g_string_append (buffer, "\n"); +} + +static CamelStream * +format_contact (EABContactFormatter *formatter, + GCancellable *cancellable) +{ + GString *buffer; + CamelStream *stream; + + buffer = g_string_new (""); + + if (formatter->priv->mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) { + render_normal (formatter, buffer); + } else { + render_compact (formatter, buffer); + } + + stream = camel_stream_mem_new (); + camel_stream_write_string (stream, buffer->str, cancellable, NULL); + + g_string_free (buffer, TRUE); + + return stream; +} + +static void +do_start_async_formatter (GSimpleAsyncResult *result, + GObject *object, + GCancellable *cancellable) +{ + EABContactFormatter *formatter; + CamelStream *stream; + + formatter = EAB_CONTACT_FORMATTER (object); + + stream = format_contact (formatter, cancellable); + + g_simple_async_result_set_op_res_gpointer (result, stream, NULL); +} + +static void +eab_contact_formatter_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EABContactFormatter *formatter = EAB_CONTACT_FORMATTER (object); + + switch (property_id) { + case PROP_DISPLAY_MODE: + eab_contact_formatter_set_display_mode ( + formatter, g_value_get_int (value)); + return; + case PROP_RENDER_MAPS: + eab_contact_formatter_set_render_maps ( + formatter, g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +eab_contact_formatter_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EABContactFormatter *formatter = EAB_CONTACT_FORMATTER (object); + + switch (property_id) { + case PROP_DISPLAY_MODE: + g_value_set_int (value, + eab_contact_formatter_get_display_mode ( + formatter)); + return; + case PROP_RENDER_MAPS: + g_value_set_boolean (value, + eab_contact_formatter_get_render_maps ( + formatter)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +eab_contact_formatter_finalize (GObject *object) +{ + EABContactFormatter *formatter; + + formatter = EAB_CONTACT_FORMATTER (object); + + if (formatter->priv->contact) { + g_object_unref (formatter->priv->contact); + formatter->priv->contact = NULL; + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +eab_contact_formatter_class_init (EABContactFormatterClass *klass) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (klass); + g_type_class_add_private (klass, sizeof (EABContactFormatterClass)); + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = eab_contact_formatter_finalize; + object_class->set_property = eab_contact_formatter_set_property; + object_class->get_property = eab_contact_formatter_get_property; + + g_object_class_install_property ( + object_class, + PROP_DISPLAY_MODE, + g_param_spec_int ( + "display-mode", + "", + "", + EAB_CONTACT_DISPLAY_RENDER_NORMAL, + EAB_CONTACT_DISPLAY_RENDER_COMPACT, + EAB_CONTACT_DISPLAY_RENDER_NORMAL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_RENDER_MAPS, + g_param_spec_boolean ( + "render-maps", + "", + "", + FALSE, + G_PARAM_READWRITE)); +} + +static void +eab_contact_formatter_init (EABContactFormatter *formatter) +{ + formatter->priv = EAB_CONTACT_FORMATTER_GET_PRIVATE (formatter); + + formatter->priv->contact = NULL; + formatter->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; + formatter->priv->render_maps = FALSE; +} + +void +eab_contact_formatter_set_display_mode (EABContactFormatter *formatter, + EABContactDisplayMode mode) +{ + g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter)); + + if (formatter->priv->mode == mode) + return; + + formatter->priv->mode = mode; + + g_object_notify (G_OBJECT (formatter), "display-mode"); +} + +EABContactDisplayMode +eab_contact_formatter_get_display_mode (EABContactFormatter *formatter) +{ + g_return_val_if_fail (EAB_IS_CONTACT_FORMATTER (formatter), + EAB_CONTACT_DISPLAY_RENDER_NORMAL); + + return formatter->priv->mode; +} + +void +eab_contact_formatter_set_render_maps (EABContactFormatter *formatter, + gboolean render_maps) +{ + g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter)); + + if (formatter->priv->render_maps == render_maps) + return; + + formatter->priv->render_maps = render_maps; + + g_object_notify (G_OBJECT (formatter), "render-maps"); +} + +gboolean +eab_contact_formatter_get_render_maps (EABContactFormatter *formatter) +{ + g_return_val_if_fail (EAB_IS_CONTACT_FORMATTER (formatter), FALSE); + + return formatter->priv->render_maps; +} + +void +eab_contact_formatter_format_contact_sync (EABContactFormatter *formatter, + EContact *contact, + CamelStream *stream, + GCancellable *cancellable) +{ + CamelStream *out; + + g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter)); + g_return_if_fail (E_IS_CONTACT (contact)); + + g_object_ref (contact); + + if (formatter->priv->contact) + g_object_unref (formatter->priv->contact); + + formatter->priv->contact = contact; + + out = format_contact (formatter, cancellable); + + g_seekable_seek (G_SEEKABLE (out), 0, G_SEEK_SET, cancellable, NULL); + camel_stream_write_to_stream (out, stream, cancellable, NULL); + + g_object_unref (out); +} + +void +eab_contact_formatter_format_contact_async (EABContactFormatter *formatter, + EContact *contact, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter)); + g_return_if_fail (E_IS_CONTACT (contact)); + g_return_if_fail (callback != NULL); + + g_object_ref (contact); + if (formatter->priv->contact) + g_object_unref (formatter->priv->contact); + + formatter->priv->contact = contact; + + result = g_simple_async_result_new ( + G_OBJECT (formatter), + callback, user_data, + eab_contact_formatter_format_contact_async); + + g_simple_async_result_run_in_thread ( + result, do_start_async_formatter, + G_PRIORITY_DEFAULT, cancellable); +} diff --git a/addressbook/gui/widgets/eab-contact-formatter.h b/addressbook/gui/widgets/eab-contact-formatter.h new file mode 100644 index 0000000000..4a0e95fd2b --- /dev/null +++ b/addressbook/gui/widgets/eab-contact-formatter.h @@ -0,0 +1,89 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef EAB_CONTACT_FORMATTER_H +#define EAB_CONTACT_FORMATTER_H + +#include +#include + +#include + +/* Standard GObject macros */ +#define EAB_TYPE_CONTACT_FORMATTER \ +(eab_contact_formatter_get_type ()) +#define EAB_CONTACT_FORMATTER(obj) \ +(G_TYPE_CHECK_INSTANCE_CAST \ +((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatter)) +#define EAB_CONTACT_FORMATTER_CLASS(cls) \ +(G_TYPE_CHECK_CLASS_CAST \ +((cls), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterClass)) +#define EAB_IS_CONTACT_FORMATTER(obj) \ +(G_TYPE_CHECK_INSTANCE_TYPE \ +((obj), EAB_TYPE_CONTACT_FORMATTER)) +#define EAB_IS_CONTACT_FORMATTER_CLASS(cls) \ +(G_TYPE_CHECK_CLASS_TYPE \ +((cls), EAB_TYPE_CONTACT_FORMATTER)) +#define EAB_CONTACT_FORMATTER_GET_CLASS(obj) \ +(G_TYPE_ISNTANCE_GET_CLASS \ +((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterClass)) + +G_BEGIN_DECLS + +typedef struct _EABContactFormatter EABContactFormatter; +typedef struct _EABContactFormatterClass EABContactFormatterClass; +typedef struct _EABContactFormatterPrivate EABContactFormatterPrivate; + +struct _EABContactFormatter { + GObject parent; + EABContactFormatterPrivate *priv; +}; + +struct _EABContactFormatterClass { + GObjectClass parent_class; +}; + +GType eab_contact_formatter_get_type (); + +void eab_contact_formatter_set_render_maps + (EABContactFormatter *formatter, + gboolean render_maps); +gboolean eab_contact_formatter_get_render_maps + (EABContactFormatter *formatter); + +void eab_contact_formatter_set_display_mode + (EABContactFormatter *formatter, + EABContactDisplayMode mode); +EABContactDisplayMode + eab_contact_formatter_get_display_mode + (EABContactFormatter *formatter); + +void eab_contact_formatter_format_contact_sync + (EABContactFormatter *formatter, + EContact *contact, + CamelStream *stream, + GCancellable *cancellable); + +void eab_contact_formatter_format_contact_async + (EABContactFormatter *formatter, + EContact *contact, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +G_END_DECLS + +#endif diff --git a/addressbook/importers/Makefile.am b/addressbook/importers/Makefile.am index 2c5f587f5c..3f2f1db38f 100644 --- a/addressbook/importers/Makefile.am +++ b/addressbook/importers/Makefile.am @@ -10,7 +10,7 @@ libevolution_addressbook_importers_la_CPPFLAGS = \ -I$(top_srcdir)/widgets \ -I$(top_builddir)/addressbook \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GNOME_PLATFORM_CFLAGS) libevolution_addressbook_importers_la_SOURCES = \ evolution-ldif-importer.c \ @@ -25,6 +25,7 @@ libevolution_addressbook_importers_la_LIBADD = \ $(top_builddir)/addressbook/util/libeabutil.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GTKHTML_LIBS) + $(GNOME_PLATFORM_LIBS) \ + $(IMPORTERS_LIBS) -include $(top_srcdir)/git.mk -- cgit v1.2.3