aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/gui/widgets/Makefile.am3
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c1189
-rw-r--r--addressbook/gui/widgets/eab-contact-formatter.c1267
-rw-r--r--addressbook/gui/widgets/eab-contact-formatter.h89
-rw-r--r--addressbook/importers/Makefile.am5
-rw-r--r--calendar/gui/Makefile.am1
-rw-r--r--calendar/gui/e-cal-component-preview.c91
-rw-r--r--composer/e-composer-actions.c2
-rw-r--r--composer/e-composer-activity.c10
-rw-r--r--composer/e-composer-private.c2
-rw-r--r--composer/e-composer-private.h2
-rw-r--r--composer/e-msg-composer.c39
-rw-r--r--composer/e-msg-composer.h5
-rw-r--r--e-util/e-marshal.list1
14 files changed, 1497 insertions, 1209 deletions
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 <string.h>
#include <glib/gi18n.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
-#include <gtkhtml/gtkhtml-embedded.h>
#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 "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
- "<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n</head>\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 =
"<ui>"
" <popup name='context'>"
@@ -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, "<a href=\"http://maps.google.com?q=");
- g_string_append_printf (link, "\">%s</a>", _("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 ("<br>");
-
- 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, "<tr><td align=\"right\" valign=\"top\" nowrap>%s</td><td valign=\"top\" width=\"100\" align=\"right\" nowrap><font color=" HEADER_COLOR ">%s:</font>%s</td><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td></tr>", html, html_label, map_link->str);
- else
- g_string_append_printf (buffer, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td><td valign=\"top\" width=\"100\" nowrap><font color=" HEADER_COLOR ">%s:</font>%s</td><td valign=\"top\" nowrap>%s</td></tr>", 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, "<tr><td align=\"right\" valign=\"top\" nowrap>");
- else
- g_string_append_printf (buffer, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td><td valign=\"top\" width=\"100\"><font color=" HEADER_COLOR ">%s:</font>%s</td><td valign=\"top\" nowrap>", html_label, map_link->str);
-
- if (adr->po && *adr->po) g_string_append_printf (buffer, "%s<br>", adr->po);
- if (adr->ext && *adr->ext) g_string_append_printf (buffer, "%s<br>", adr->ext);
- if (adr->street && *adr->street) g_string_append_printf (buffer, "%s<br>", adr->street);
- if (adr->locality && *adr->locality) g_string_append_printf (buffer, "%s<br>", adr->locality);
- if (adr->region && *adr->region) g_string_append_printf (buffer, "%s<br>", adr->region);
- if (adr->code && *adr->code) g_string_append_printf (buffer, "%s<br>", adr->code);
- if (adr->country && *adr->country) g_string_append_printf (buffer, "%s<br>", adr->country);
-
- if (TEXT_IS_RIGHT_TO_LEFT)
- g_string_append_printf (buffer, "</td><td valign=\"top\" width=\"100\" align=\"right\"><font color=" HEADER_COLOR ">%s:</font>%s</td><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td></tr>", html_label, map_link->str);
- else
- g_string_append_printf (buffer, "</td></tr>");
- }
- 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, "<tr>"
- "<td valign=\"top\" align=\"right\">%s</td> "
- "<td align=\"right\" valign=\"top\" width=\"100\" nowrap>"
- "<font color=" HEADER_COLOR ">%s:</font></td>",
- value, label);
- g_string_append_printf (
- buffer, "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">");
- if (icon != NULL)
- g_string_append_printf (
- buffer, "<img width=\"16\" height=\"16\" "
- "src=\"evo-icon:%s\"></td></tr>", icon);
- else
- g_string_append_printf (buffer, "</td></tr>");
- } else {
- g_string_append_printf (
- buffer, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">");
- if (icon != NULL)
- g_string_append_printf (
- buffer, "<img width=\"16\" height=\"16\" "
- "src=\"evo-icon:%s\">", icon);
- g_string_append_printf (
- buffer, "</td><td valign=\"top\" width=\"100\" nowrap>"
- "<font color=" HEADER_COLOR ">%s:</font>"
- "</td> <td valign=\"top\">%s</td></tr>",
- 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, "<tr><td height=\"20\" colspan=\"3\">"
- "<font color=" HEADER_COLOR "><b>%s</b>"
- "</font></td></tr>", label);
-}
-
-static void
-end_block (GString *buffer)
-{
- g_string_append (buffer, "<tr><td height=\"20\">&nbsp;</td></tr>");
-}
-
-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, "<table border=\"0\"><tr>"
- "<td %s valign=\"middle\">", 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, "<img border=\"1\" src=\"internal-contact-photo:\">");
- } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) {
- g_string_append_printf (buffer, "<img border=\"1\" src=\"%s\">", photo->data.uri);
- }
- if (photo)
- e_contact_photo_free (photo);
-
- if (e_contact_get (contact, E_CONTACT_IS_LIST))
- g_string_append (buffer, "<img src=\"evo-icon:" CONTACT_LIST_ICON "\">");
-
- g_string_append_printf (
- buffer, "</td><td width=\"20\"></td><td %s valign=\"top\">\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, "<h2><a href=\"internal-mailto:0\">%s</a></h2>", html);
- else
- g_string_append_printf (buffer, "<h2>%s</h2>", html);
- g_free (html);
- }
-
- g_string_append (buffer, "</td></tr></table>");
-
-}
-
-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, "<tr>");
- if (e_destination_is_evolution_list (destination)) {
- g_string_append_printf (buffer,
- "<td width=" IMAGE_COL_WIDTH " valign=\"top\"><a href=\"##%s##\"><img src=\"%s/%s.png\"></a></td><td width=\"100%%\">%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, "<br><table cellspacing=\"1\">");
-
- 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, "</table>");
- }
-
- g_string_append (buffer, "</td>");
-
- } else {
- if (name && *name) {
- g_string_append_printf (buffer, "<td colspan=\"2\">%s &lt<a href=\"mailto:%s\">%s</a>&gt;</td>", name, email_addr, email_addr);
- } else {
- g_string_append_printf (buffer, "<td colspan=\"2\"><a href=\"mailto:%s\">%s</a></td>", email_addr, email_addr);
- }
- }
-
- g_string_append (buffer, "</tr>");
-
- 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, "<table border=\"0\"><tr><td valign=\"top\"><font color=" HEADER_COLOR ">%s</font></td><td>",
- _("List Members:"));
- g_string_append (buffer, "<table border=\"0\" cellspacing=\"1\">");
-
- for (dest = dests; dest; dest = dest->next) {
- render_contact_list_row (buffer, dest->data, display);
- }
-
- g_string_append (buffer, "</table>");
- g_string_append (buffer, "</td></tr></table>");
-
- 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, "<table border=\"0\"><tr><td colspan=\"2\" valign=\"top\"><font color=" HEADER_COLOR ">%s</font></td></tr>"
- "<tr><td with=" IMAGE_COL_WIDTH "></td><td>", _("List Members:"));
- g_string_append (buffer, "<table border=\"0\" cellspacing=\"1\">");
-
- for (dest = dests; dest; dest = dest->next)
- render_contact_list_row (buffer, dest->data, display);
-
- g_string_append (buffer, "</table>");
- g_string_append (buffer, "</td></tr></table>");
-
- 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<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++;
- nl = "<br>";
-
- 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, "<tr>"
- "<td valign=\"top\" align=\"right\">%s</td> "
- "<td valign=\"top\" align=\"right\" width=\"100\" nowrap>"
- "<font color=" HEADER_COLOR ">%s:</font>"
- "</td><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">"
- "</td></tr>", accum->str, _("Email"));
- } else {
- g_string_append (
- buffer, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">");
- g_string_append_printf (
- buffer, "</td><td valign=\"top\" width=\"100\" nowrap>"
- "<font color=" HEADER_COLOR ">%s:</font></td> "
- "<td valign=\"top\" nowrap>%s</td></tr>",
- _("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, "<tr><td>%s</td></tr>", 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, "<object classid=\"address-map-work\"></object>");
- } else {
- g_string_append (buffer, "<object classid=\"address-map-home\"></object>");
- }
-#endif
-}
-
-static void
-render_contact_horizontal (GString *buffer,
- EContact *contact,
- gboolean show_maps)
-{
- g_string_append (buffer, "<table border=\"0\">");
- render_title_block (buffer, contact);
- g_string_append (buffer, "</table>");
-
- g_string_append (buffer, "<table border=\"0\">");
- render_contact_block (buffer, contact);
- render_work_block (buffer, contact);
- g_string_append (buffer, "<tr><td></td><td colspan=\"2\">");
- if (show_maps)
- render_address_map (buffer, contact, E_CONTACT_ADDRESS_WORK);
- g_string_append (buffer, "<br></td></tr>");
- render_personal_block (buffer, contact);
- g_string_append (buffer, "<tr><td></td><td colspan=\"2\">");
- if (show_maps)
- render_address_map (buffer, contact, E_CONTACT_ADDRESS_HOME);
- g_string_append (buffer, "<br></td></tr>");
- g_string_append (buffer, "</table>");
-
- g_string_append (buffer, "<table border=\"0\">");
- render_note_block (buffer, contact);
- g_string_append (buffer, "</table>");
-}
-
-static void
-render_contact_vertical (GString *buffer,
- EContact *contact,
- gboolean show_maps)
-{
- /* First row: photo & name */
- g_string_append (buffer, "<tr><td colspan=\"3\">");
- render_title_block (buffer, contact);
- g_string_append (buffer, "</td></tr>");
-
- /* Second row: addresses etc. */
- g_string_append (buffer, "<tr>");
-
- /* First column: email, IM */
- g_string_append (buffer, "<td valign=\"top\">");
- g_string_append (buffer, "<table border=\"0\">");
- render_contact_block (buffer, contact);
- g_string_append (buffer, "</table></td>");
-
- /* Second column: Work */
- g_string_append (buffer, "<td width=\"30\"></td><td valign=\"top\"><table border=\"0\">");
- render_work_block (buffer, contact);
- g_string_append (buffer, "</table>");
- if (show_maps)
- render_address_map (buffer, contact, E_CONTACT_ADDRESS_WORK);
- g_string_append (buffer, "</td>");
-
- /* Third column: Personal */
- g_string_append (buffer, "<td width=\"30\"></td><td valign=\"top\"><table border=\"0\">");
- render_personal_block (buffer, contact);
- g_string_append (buffer, "</table>");
- if (show_maps)
- render_address_map (buffer, contact, E_CONTACT_ADDRESS_HOME);
- g_string_append (buffer, "</td>");
-
- /* Third row: note */
- g_string_append (buffer, "<tr><td colspan=\"3\"><table border=\"0\"");
- render_note_block (buffer, contact);
- g_string_append (buffer, "</table></td></tr>");
-
- g_string_append (buffer, "</table>\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, "<body><table><tr>"
- "<td %s>\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, "</td></tr></table></body></html>\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, "<body>\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,
- "<table width=\"100%%\" cellpadding=1 cellspacing=0 bgcolor=\"#%06X\">"
- "<tr><td valign=\"top\">"
- "<table width=\"100%%\" cellpadding=0 cellspacing=0 bgcolor=\"#%06X\">"
- "<tr><td valign=\"top\">"
- "<table>"
- "<tr><td valign=\"top\">", 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,
- "<img width=\"%d\" height=\"%d\" src=\"%s\">",
- calced_width, calced_height, photo->data.uri);
- else
- g_string_append_printf (
- buffer,
- "<img width=\"%d\" height=\"%d\" src=\"internal-contact-photo:\">",
- calced_width, calced_height);
-
- e_contact_photo_free (photo);
- }
-
- g_string_append (buffer, "</td><td valign=\"top\">\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, "<b>%s</b>", 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, "<b>%s</b>", html);
- g_free (html);
- }
- }
-
- g_string_append (buffer, "<hr>");
-
- if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
- GList *email_list;
- GList *l;
-
- g_string_append (buffer, "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td valign=\"top\">");
- g_string_append_printf (buffer, "<b>%s:</b>&nbsp;<td>", _("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, "</td></tr></table>");
- }
- 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, "<b>%s:</b> %s<br>", _("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, "<b>%s:</b> ", _("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, "<br>");
-
- #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, "<b>%s:</b> %s<br>",
- _("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, "<b>%s:</b> %s<br>",
- _("Blog"), html);
- }
- }
-
- g_string_append (buffer, "</td></tr></table></td></tr></table></td></tr></table>\n");
- }
-
- g_string_append (buffer, "</body></html>\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,85 +269,11 @@ 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:<<themed-icon-name>> */
- 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,
const gchar *uri)
@@ -1310,19 +326,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;
}
/* Chain up to parent's link_clicked() method. */
@@ -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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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 <string.h>
+#include <glib/gi18n.h>
+
+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 "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
+"<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n" \
+"<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\">" \
+"<style type=\"text/css\">\n" \
+" div#header { width:100%; clear: both; }\n" \
+" div#columns { width: 100%; clear: both; }\n" \
+" div#footer { width: 100%; clear: both; }\n" \
+" div.column { width: auto; float: left; margin-right: 15px; }\n" \
+" img#contact-photo { float: left; }\n" \
+" div#contact-name { float: left; margin-left: 20px; }\n" \
+"</style>\n" \
+"<script type=\"text/javascript\">\n" \
+"function collapse_list (obj, listId) {\n" \
+" var l = document.getElementById (listId);\n" \
+" if (l.style.display == \"none\") {\n" \
+" l.style.display = \"block\"; obj.src = obj.src.substr (0, obj.src.lastIndexOf (\"/\")) + \"/minus.png\";\n" \
+" } else {\n" \
+" l.style.display = \"none\"; obj.src = obj.src.substr (0, obj.src.lastIndexOf (\"/\")) + \"/plus.png\";\n" \
+" }\n" \
+"}\n" \
+"</script>\n" \
+"</head>\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, "<a href=\"http://maps.google.com?q=");
+ g_string_append_printf (link, "\">%s</a>", _("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 ("<br>");
+
+ 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,
+ "<tr>"
+ "<td align=\"right\" valign=\"top\" nowrap>%s</td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "</tr>",
+ html, html_label, map_link->str);
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" nowrap>%s</td>"
+ "</tr>",
+ 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, "<tr><td align=\"right\" valign=\"top\" nowrap>");
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" nowrap>",
+ html_label, map_link->str);
+ }
+
+ if (adr->po && *adr->po)
+ g_string_append_printf (buffer, "%s<br>", adr->po);
+
+ if (adr->ext && *adr->ext)
+ g_string_append_printf (buffer, "%s<br>", adr->ext);
+
+ if (adr->street && *adr->street)
+ g_string_append_printf (buffer, "%s<br>", adr->street);
+
+ if (adr->locality && *adr->locality)
+ g_string_append_printf (buffer, "%s<br>", adr->locality);
+
+ if (adr->region && *adr->region)
+ g_string_append_printf (buffer, "%s<br>", adr->region);
+
+ if (adr->code && *adr->code)
+ g_string_append_printf (buffer, "%s<br>", adr->code);
+
+ if (adr->country && *adr->country)
+ g_string_append_printf (buffer, "%s<br>", adr->country);
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer,
+ "</td><th%s:<br>%s</th>"
+ "<td width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "</tr>", html_label, map_link->str);
+ } else {
+ g_string_append_printf (buffer, "</td></tr>");
+ }
+
+ }
+
+ 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 ("<img src=\"%s\" width=\"16\" height=\"16\" />", icon_uri);
+ g_free (icon_uri);
+ } else {
+ icon_html = "";
+ }
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer, "<tr>"
+ "<td valign=\"top\" align=\"right\">%s</td>"
+ "<th align=\"right\" valign=\"top\" width=\"100\" nowrap>:%s</th>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+ "</tr>",
+ value, label, icon_html);
+ } else {
+ g_string_append_printf (
+ buffer, "<tr>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+ "<th valign=\"top\" width=\"100\" nowrap>%s:</th>"
+ "<td valign=\"top\">%s</td>"
+ "</tr>",
+ 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, "<br>");
+
+ 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,
+ "<table border=\"0\"><tr>"
+ "<td %s valign=\"middle\">", 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, "<img border=\"1\" src=\"data:%s;base64,%s\">",
+ 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, "<img border=\"1\" src=\"%s\">", 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, "<img src=\"%s\">", icon);
+ g_free (icon);
+ }
+
+ g_string_append_printf (
+ buffer,
+ "</td><td width=\"20\"></td><td %s valign=\"top\">\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,
+ "<h2><a href=\"internal-mailto:0\">%s</a></h2>",
+ html);
+ } else {
+ g_string_append_printf (buffer, "<h2>%s</h2>", html);
+ }
+ g_free (html);
+ }
+
+ g_string_append (buffer, "</td></tr></table>");
+}
+
+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, "<tr>");
+ if (e_destination_is_evolution_list (destination)) {
+ g_string_append_printf (
+ buffer,
+ "<td width=" IMAGE_COL_WIDTH " valign=\"top\">"
+ "<img src=\"%s/minus.png\" "
+ "onClick=\"collapse_list(this, %s);\" "
+ "class=\"navigable\">"
+ "</td><td width=\"100%%\">%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,
+ "<br><table cellspacing=\"1\" id=\"%s\">",
+ 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, "</table>");
+ }
+
+ g_string_append (buffer, "</td>");
+
+ } else {
+ if (name && *name) {
+ g_string_append_printf (
+ buffer,
+ "<td colspan=\"2\">%s &lt"
+ "<a href=\"mailto:%s\">%s</a>&gt;"
+ "</td>",
+ name, email_addr, email_addr);
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<td colspan=\"2\">"
+ "<a href=\"mailto:%s\">%s</a>"
+ "</td>",
+ email_addr, email_addr);
+ }
+ }
+
+ g_string_append (buffer, "</tr>");
+
+ 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,
+ "<table border=\"0\"><tr><th colspan=\"2\">%s</th></tr>"
+ "<tr><td with=" IMAGE_COL_WIDTH "></td><td>", _("List Members:"));
+
+ g_string_append (buffer, "<table border=\"0\" cellspacing=\"1\">");
+
+ for (dest = dests; dest; dest = dest->next)
+ render_contact_list_row (formatter, dest->data, buffer);
+
+ g_string_append (buffer, "</table>");
+ g_string_append (buffer, "</td></tr></table>");
+
+ 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<a href=\"internal-mailto:%d\">%s</a>%s "
+ "<span class=\"header\">(%s)</span>",
+ nl,
+ name ? name : "",
+ name ? " &lt;" : "",
+ email_num,
+ mail,
+ name ? "&gt;" : "",
+ attr_str ? attr_str : "");
+ email_num++;
+ nl = "<br>";
+
+ 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,
+ "<div class=\"column\" id=\"contact-internet\">"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", 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, "<tr><td colspan=\"3\">");
+
+ if (map_type == E_CONTACT_ADDRESS_WORK) {
+ g_string_append (buffer,
+ "<object type=\"application/x-work-map-widget\" "
+ "width=\"250\" height=\"250\"></object>");
+ } else {
+ g_string_append (buffer,
+ "<object type=\"application/x-home-map-widget\" "
+ "width=\"250\" height=\"250\"></object>");
+ }
+
+ g_string_append (buffer, "</td></tr>");
+
+ #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,
+ "<div class=\"column\" id=\"contact-work\">"
+ "<h3>%s</h3>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("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,
+ "<div class=\"column\" id=\"contact-personal\">"
+ "<h3>%s</h3>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("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,
+ "<div id=\"footer\"><table border=\"0\" cellspacing=\"5\">");
+
+ 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, "</table></div>");
+}
+
+static void
+render_contact (EABContactFormatter *formatter,
+ GString *buffer)
+{
+ render_title_block (formatter, buffer);
+
+ g_string_append (buffer, "<div id=\"columns\">");
+ render_contact_column (formatter, buffer);
+ render_work_column (formatter, buffer);
+ render_personal_column (formatter, buffer);
+ g_string_append (buffer, "</div>");
+
+ render_footer (formatter, buffer);
+}
+
+static void
+render_normal (EABContactFormatter *formatter,
+ GString *buffer)
+{
+ g_string_append (buffer, HTML_HEADER);
+ g_string_append (buffer, "<body>");
+
+ 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, "</body></html>\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, "<body>\n");
+
+ if (!contact) {
+ g_string_append (buffer, "</body></html>");
+ return;
+ }
+
+ g_string_append_printf (
+ buffer,
+ "<table><tr><td valign=\"top\">");
+
+ 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,
+ "<img width=\"%d\" height=\"%d\" src=\"%s\">",
+ 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,
+ "<img border=\"1\" src=\"data:%s;base64,%s\" "
+ "width=\"%d\" height=\"%d\">",
+ photo->data.inlined.mime_type,
+ photo_data,
+ calced_width, calced_height);
+ g_free (photo_data);
+ }
+
+ e_contact_photo_free (photo);
+ }
+
+ g_string_append (buffer, "</td><td width=\"5\"></td><td valign=\"top\">\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, "<b>%s</b>", 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, "<b>%s</b>", html);
+ g_free (html);
+ }
+ }
+
+ g_string_append (buffer, "<hr>");
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ GList *email_list;
+ GList *l;
+
+ g_string_append (
+ buffer,
+ "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
+ "<tr><td valign=\"top\">");
+ g_string_append_printf (
+ buffer,
+ "<b>%s:</b>&nbsp;<td>", _ ("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, "</td></tr></table>");
+
+ } 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, "<b>%s:</b> %s<br>", _ ("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, "<b>%s:</b> ", _ ("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, "<br>");
+
+ #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, "<b>%s:</b> %s<br>",
+ _ ("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, "<b>%s:</b> %s<br>",
+ _ ("Blog"), html);
+ }
+ }
+
+ g_string_append (buffer, "</td></tr></table>\n");
+
+ g_string_append (buffer, "</body></html>\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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EAB_CONTACT_FORMATTER_H
+#define EAB_CONTACT_FORMATTER_H
+
+#include <libebook/e-contact.h>
+#include <addressbook/gui/widgets/eab-contact-display.h>
+
+#include <camel/camel.h>
+
+/* 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
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index f280d3abdf..75991807df 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -66,6 +66,7 @@ libevolution_calendar_la_CPPFLAGS = \
-DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
-DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
-DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DEVOLUTION_PRIVDATADIR=\""${privdatadir}"\" \
-DPREFIX=\""$(prefix)"\" \
$(EVOLUTION_DATA_SERVER_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS) \
diff --git a/calendar/gui/e-cal-component-preview.c b/calendar/gui/e-cal-component-preview.c
index ce8cdeee2d..c96a9e0790 100644
--- a/calendar/gui/e-cal-component-preview.c
+++ b/calendar/gui/e-cal-component-preview.c
@@ -56,6 +56,14 @@ struct _ECalComponentPreviewPrivate {
gint comp_sequence;
};
+#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
+ "<head>\n<meta name=\"generator\" content=\"Evolution Calendar Component\">\n" \
+ "<link type=\"text/css\" rel=\"stylesheet\" href=\"file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\">\n" \
+ "<style>\n" \
+ ".description { font-family: monospace; font-size: 1em; }\n" \
+ "</style>\n" \
+ "</head>"
+
static void
clear_comp_info (ECalComponentPreview *preview)
{
@@ -191,20 +199,21 @@ cal_component_preview_write_html (GString *buffer,
/* write document header */
e_cal_component_get_summary (comp, &text);
+ g_string_append (buffer, HTML_HEADER);
+ g_string_append (buffer, "<body>");
+
if (text.value)
- g_string_append_printf (
- buffer, "<HTML><BODY><H1>%s</H1>",
- text.value);
+ g_string_append_printf (buffer, "<h2>%s</h2>", text.value);
else
- g_string_append_printf (
- buffer, "<HTML><BODY><H1><I>%s</I></H1>",
- _("Untitled"));
+ g_string_append_printf (buffer, "<h2><i>%s</i></h2>",_("Untitled"));
+
+ g_string_append (buffer, "<table border=\"0\" cellspacing=\"5\">");
/* write icons for the categories */
string = g_string_new (NULL);
e_cal_component_get_categories_list (comp, &list);
if (list != NULL)
- g_string_append_printf (buffer, "<H3>%s ", _("Categories:"));
+ g_string_append_printf (buffer, "<tr><th>%s</th><td>", _("Categories:"));
for (iter = list; iter != NULL; iter = iter->next) {
const gchar *category = iter->data;
const gchar *icon_file;
@@ -215,7 +224,7 @@ cal_component_preview_write_html (GString *buffer,
uri = g_filename_to_uri (icon_file, NULL, NULL);
g_string_append_printf (
- buffer, "<IMG ALT=\"%s\" SRC=\"%s\">",
+ buffer, "<img alt=\"%s\" src=\"%s\">",
category, uri);
g_free (uri);
} else {
@@ -227,22 +236,14 @@ cal_component_preview_write_html (GString *buffer,
if (string->len > 0)
g_string_append_printf (buffer, "%s", string->str);
if (list != NULL)
- g_string_append (buffer, "</H3>");
+ g_string_append (buffer, "</td></tr>");
e_cal_component_free_categories_list (list);
g_string_free (string, TRUE);
- /* Start table */
- g_string_append (
- buffer, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">"
- "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"15%%\">"
- "</TD></TR>");
-
/* write location */
e_cal_component_get_location (comp, &location);
if (location)
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" "
- "WIDTH=\"15%%\"><B>%s</B></TD><TD>%s</TD></TR>",
+ g_string_append_printf (buffer, "<tr><th>%s</th><td>%s</td></tr>",
_("Summary:"), text.value);
/* write start date */
@@ -250,11 +251,8 @@ cal_component_preview_write_html (GString *buffer,
if (dt.value != NULL) {
str = timet_to_str_with_zone (
&dt, client, default_zone, use_24_hour_format);
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD><TD>%s</TD></TR>",
+ g_string_append_printf (buffer, "<tr><th>%s</th><td>%s</td></tr>",
_("Start Date:"), str);
-
g_free (str);
}
e_cal_component_free_datetime (&dt);
@@ -264,11 +262,8 @@ cal_component_preview_write_html (GString *buffer,
if (dt.value != NULL) {
str = timet_to_str_with_zone (
&dt, client, default_zone, use_24_hour_format);
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD><TD>%s</TD></TR>",
- _("Start Date:"), str);
-
+ g_string_append_printf (buffer,"<tr><th>%s</th><td>%s</td></tr>",
+ _("End Date:"), str);
g_free (str);
}
e_cal_component_free_datetime (&dt);
@@ -278,11 +273,8 @@ cal_component_preview_write_html (GString *buffer,
if (dt.value != NULL) {
str = timet_to_str_with_zone (
&dt, client, default_zone, use_24_hour_format);
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD><TD>%s</TD></TR>",
+ g_string_append_printf (buffer, "<tr><th>%s</th><td>%s</td></tr>",
_("Due Date:"), str);
-
g_free (str);
}
e_cal_component_free_datetime (&dt);
@@ -292,9 +284,8 @@ cal_component_preview_write_html (GString *buffer,
icalprop = icalcomponent_get_first_property (
icalcomp, ICAL_STATUS_PROPERTY);
if (icalprop != NULL) {
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD>", _("Status:"));
+ g_string_append_printf (buffer, "<tr><th>%s</th>",
+ _("Status:"));
e_cal_component_get_status (comp, &status);
switch (status) {
case ICAL_STATUS_INPROCESS :
@@ -312,16 +303,15 @@ cal_component_preview_write_html (GString *buffer,
break;
}
- g_string_append_printf (buffer, "<TD>%s</TD></TR>", str);
+ g_string_append_printf (buffer, "<td>%s</td></tr>", str);
g_free (str);
}
/* write priority */
e_cal_component_get_priority (comp, &priority_value);
if (priority_value && *priority_value != 0) {
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD>", _("Priority:"));
+ g_string_append_printf (buffer, "<tr><th>%s</th>",
+ _("Priority:"));
if (*priority_value <= 4)
str = g_strdup (_("High"));
else if (*priority_value == 5)
@@ -329,7 +319,7 @@ cal_component_preview_write_html (GString *buffer,
else
str = g_strdup (_("Low"));
- g_string_append_printf (buffer, "<TD>%s</TD></TR>", str);
+ g_string_append_printf (buffer, "<td>%s</td></tr>", str);
g_free (str);
}
@@ -338,17 +328,16 @@ cal_component_preview_write_html (GString *buffer,
e_cal_component_free_priority (priority_value);
/* write description and URL */
- g_string_append (buffer, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>");
+ g_string_append (buffer, "<tr><td colspan=\"2\"><hr></td></tr>");
e_cal_component_get_description_list (comp, &list);
if (list) {
GSList *node;
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD>", _("Description:"));
+ g_string_append_printf (buffer, "<tr><th>%s</th>",
+ _("Description:"));
- g_string_append (buffer, "<TD><TT>");
+ g_string_append (buffer, "<td class=\"description\">");
for (node = list; node != NULL; node = node->next) {
gchar *html;
@@ -367,7 +356,7 @@ cal_component_preview_write_html (GString *buffer,
g_free (html);
}
- g_string_append (buffer, "</TT></TD></TR>");
+ g_string_append (buffer, "</td></tr>");
e_cal_component_free_text_list (list);
}
@@ -375,18 +364,14 @@ cal_component_preview_write_html (GString *buffer,
/* URL */
e_cal_component_get_url (comp, (const gchar **) &str);
if (str) {
- g_string_append_printf (
- buffer, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\">"
- "<B>%s</B></TD>", _("Web Page:"));
- g_string_append_printf (
- buffer, "<TD><A HREF=\"%s\">%s</A></TD></TR>",
- str, str);
+ g_string_append_printf (buffer, "<tr><th>%s</th><td><a href=\"%s\">%s</a></td></tr>",
+ _("Web Page:"), str, str);
}
- g_string_append (buffer, "</TABLE>");
+ g_string_append (buffer, "</table>");
/* close document */
- g_string_append (buffer, "</BODY></HTML>");
+ g_string_append (buffer, "</body></html>");
}
static void
diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c
index 11ad9cdabd..966866b830 100644
--- a/composer/e-composer-actions.c
+++ b/composer/e-composer-actions.c
@@ -462,7 +462,7 @@ e_composer_actions_init (EMsgComposer *composer)
GtkActionGroup *action_group;
GtkUIManager *ui_manager;
GtkhtmlEditor *editor;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
gboolean visible;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
diff --git a/composer/e-composer-activity.c b/composer/e-composer-activity.c
index 603a271580..a74e5cdce7 100644
--- a/composer/e-composer-activity.c
+++ b/composer/e-composer-activity.c
@@ -46,14 +46,14 @@ composer_activity_lock_interface (EComposerActivity *activity)
{
GtkActionGroup *action_group;
EMsgComposer *composer;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
gboolean editable;
composer = e_composer_activity_get_composer (activity);
web_view = e_msg_composer_get_web_view (composer);
- editable = e_web_view_get_editable (web_view);
- e_web_view_set_editable (web_view, FALSE);
+ editable = e_web_view_gtkhtml_get_editable (web_view);
+ e_web_view_gtkhtml_set_editable (web_view, FALSE);
activity->priv->saved_editable = editable;
action_group = composer->priv->async_actions;
@@ -65,14 +65,14 @@ composer_activity_unlock_interface (EComposerActivity *activity)
{
GtkActionGroup *action_group;
EMsgComposer *composer;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
gboolean editable;
composer = e_composer_activity_get_composer (activity);
editable = activity->priv->saved_editable;
web_view = e_msg_composer_get_web_view (composer);
- e_web_view_set_editable (web_view, editable);
+ e_web_view_gtkhtml_set_editable (web_view, editable);
action_group = composer->priv->async_actions;
gtk_action_group_set_sensitive (action_group, TRUE);
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index 3441c6b566..477aae4296 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -129,7 +129,7 @@ e_composer_private_constructed (EMsgComposer *composer)
EFocusTracker *focus_tracker;
EShell *shell;
EShellSettings *shell_settings;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
GtkhtmlEditor *editor;
GtkUIManager *ui_manager;
GtkAction *action;
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index a727cf6841..990c5b64bc 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -51,7 +51,7 @@
#include "widgets/misc/e-picture-gallery.h"
#include "widgets/misc/e-preferences-window.h"
#include "widgets/misc/e-signature-combo-box.h"
-#include "widgets/misc/e-web-view.h"
+#include "widgets/misc/e-web-view-gtkhtml.h"
#include "shell/e-shell.h"
#ifdef HAVE_XFREE
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 8da99128e1..25553295aa 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -193,19 +193,20 @@ emcu_part_to_html (CamelMimePart *part,
camel_stream_mem_set_byte_array (mem, buf);
emfq = em_format_quote_new (NULL, (CamelStream *) mem, EM_FORMAT_QUOTE_KEEP_SIG);
- ((EMFormat *) emfq)->composer = TRUE;
+ em_format_set_composer ((EMFormat *) emfq, TRUE);
if (source) {
/* Copy over things we can, other things are internal.
* XXX Perhaps need different api than 'clone'. */
- if (source->default_charset)
+ if (em_format_get_default_charset (source))
em_format_set_default_charset (
- (EMFormat *) emfq, source->default_charset);
- if (source->charset)
- em_format_set_default_charset (
- (EMFormat *) emfq, source->charset);
+ (EMFormat *) emfq, em_format_get_default_charset (source));
+ if (em_format_get_charset (source))
+ em_format_set_charset (
+ (EMFormat *) emfq, em_format_get_charset (source));
}
- em_format_part (
- EM_FORMAT (emfq), CAMEL_STREAM (mem), part, cancellable);
+
+ em_format_format_text (EM_FORMAT (emfq),
+ CAMEL_STREAM (mem), CAMEL_DATA_WRAPPER (part), cancellable);
g_object_unref (emfq);
camel_stream_write((CamelStream *) mem, "", 1, cancellable, NULL);
@@ -1691,7 +1692,7 @@ msg_composer_paste_clipboard_targets_cb (GtkClipboard *clipboard,
}
static void
-msg_composer_paste_clipboard_cb (EWebView *web_view,
+msg_composer_paste_clipboard_cb (EWebViewGtkHTML *web_view,
EMsgComposer *composer)
{
GtkClipboard *clipboard;
@@ -1721,7 +1722,7 @@ msg_composer_realize_gtkhtml_cb (GtkWidget *widget,
/* When redirecting a message, the message body is not
* editable and therefore cannot be a drag destination. */
- if (!e_web_view_get_editable (E_WEB_VIEW (widget)))
+ if (!e_web_view_gtkhtml_get_editable (E_WEB_VIEW_GTKHTML (widget)))
return;
view = e_msg_composer_get_attachment_view (composer);
@@ -1969,7 +1970,7 @@ msg_composer_constructed (GObject *object)
EAttachmentView *view;
EAttachmentStore *store;
EComposerHeaderTable *table;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
GtkUIManager *ui_manager;
GtkToggleAction *action;
const gchar *id;
@@ -2179,7 +2180,7 @@ msg_composer_key_press_event (GtkWidget *widget,
EMsgComposer *composer = E_MSG_COMPOSER (widget);
GtkWidget *input_widget;
GtkhtmlEditor *editor;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
editor = GTKHTML_EDITOR (widget);
composer = E_MSG_COMPOSER (widget);
@@ -2558,7 +2559,7 @@ e_msg_composer_new (EShell *shell)
return g_object_new (
E_TYPE_MSG_COMPOSER,
- "html", e_web_view_new (), "shell", shell, NULL);
+ "html", e_web_view_gtkhtml_new (), "shell", shell, NULL);
}
EFocusTracker *
@@ -3389,7 +3390,7 @@ e_msg_composer_new_redirect (EShell *shell,
{
EMsgComposer *composer;
EComposerHeaderTable *table;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
const gchar *subject;
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
@@ -3408,7 +3409,7 @@ e_msg_composer_new_redirect (EShell *shell,
e_composer_header_table_set_subject (table, subject);
web_view = e_msg_composer_get_web_view (composer);
- e_web_view_set_editable (web_view, FALSE);
+ e_web_view_gtkhtml_set_editable (web_view, FALSE);
return composer;
}
@@ -3464,7 +3465,7 @@ e_msg_composer_get_shell (EMsgComposer *composer)
*
* Returns: the #EWebView
**/
-EWebView *
+EWebViewGtkHTML *
e_msg_composer_get_web_view (EMsgComposer *composer)
{
GtkHTML *html;
@@ -3477,7 +3478,7 @@ e_msg_composer_get_web_view (EMsgComposer *composer)
editor = GTKHTML_EDITOR (composer);
html = gtkhtml_editor_get_html (editor);
- return E_WEB_VIEW (html);
+ return E_WEB_VIEW_GTKHTML (html);
}
static void
@@ -4152,7 +4153,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
{
EMsgComposerPrivate *p = composer->priv;
EComposerHeaderTable *table;
- EWebView *web_view;
+ EWebViewGtkHTML *web_view;
gchar *buff;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
@@ -4168,7 +4169,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (composer), FALSE);
web_view = e_msg_composer_get_web_view (composer);
- e_web_view_set_editable (web_view, FALSE);
+ e_web_view_gtkhtml_set_editable (web_view, FALSE);
g_free (p->mime_body);
p->mime_body = g_strdup (body);
diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h
index 258d260e3f..aa63b0e894 100644
--- a/composer/e-msg-composer.h
+++ b/composer/e-msg-composer.h
@@ -30,7 +30,7 @@
#include <gtkhtml-editor.h>
#include <misc/e-attachment-view.h>
#include <misc/e-focus-tracker.h>
-#include <misc/e-web-view.h>
+#include <misc/e-web-view-gtkhtml.h>
#include <shell/e-shell.h>
#include <composer/e-composer-header-table.h>
@@ -100,7 +100,8 @@ EFocusTracker * e_msg_composer_get_focus_tracker
(EMsgComposer *composer);
CamelSession * e_msg_composer_get_session (EMsgComposer *composer);
EShell * e_msg_composer_get_shell (EMsgComposer *composer);
-EWebView * e_msg_composer_get_web_view (EMsgComposer *composer);
+EWebViewGtkHTML *
+ e_msg_composer_get_web_view (EMsgComposer *composer);
void e_msg_composer_send (EMsgComposer *composer);
void e_msg_composer_save_to_drafts (EMsgComposer *composer);
diff --git a/e-util/e-marshal.list b/e-util/e-marshal.list
index bf15633ab8..62be8aa74a 100644
--- a/e-util/e-marshal.list
+++ b/e-util/e-marshal.list
@@ -39,6 +39,7 @@ NONE:INT,POINTER,INT,OBJECT,INT,INT,BOXED,UINT,UINT
NONE:INT,POINTER,INT,OBJECT,UINT
NONE:LONG,LONG
NONE:OBJECT,BOOLEAN
+NONE:OBJECT,INT
NONE:OBJECT,DOUBLE,DOUBLE,BOOLEAN
NONE:OBJECT,OBJECT
NONE:OBJECT,STRING