diff options
-rw-r--r-- | addressbook/gui/widgets/Makefile.am | 3 | ||||
-rw-r--r-- | addressbook/gui/widgets/eab-contact-display.c | 1189 | ||||
-rw-r--r-- | addressbook/gui/widgets/eab-contact-formatter.c | 1267 | ||||
-rw-r--r-- | addressbook/gui/widgets/eab-contact-formatter.h | 89 | ||||
-rw-r--r-- | addressbook/importers/Makefile.am | 5 | ||||
-rw-r--r-- | calendar/gui/Makefile.am | 1 | ||||
-rw-r--r-- | calendar/gui/e-cal-component-preview.c | 91 | ||||
-rw-r--r-- | composer/e-composer-actions.c | 2 | ||||
-rw-r--r-- | composer/e-composer-activity.c | 10 | ||||
-rw-r--r-- | composer/e-composer-private.c | 2 | ||||
-rw-r--r-- | composer/e-composer-private.h | 2 | ||||
-rw-r--r-- | composer/e-msg-composer.c | 39 | ||||
-rw-r--r-- | composer/e-msg-composer.h | 5 | ||||
-rw-r--r-- | e-util/e-marshal.list | 1 |
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\"> </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 <<a href=\"mailto:%s\">%s</a>></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 ? " <" : "", - email_num, - mail, - name ? ">" : "", - 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> <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 <" + "<a href=\"mailto:%s\">%s</a>>" + "</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 ? " <" : "", + email_num, + mail, + name ? ">" : "", + 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> <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 |