[evolution/webkit: 4/105] Port EABContactDisplay to JavaScript and CSS
- From: Dan VrÃtil <dvratil src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit: 4/105] Port EABContactDisplay to JavaScript and CSS
- Date: Mon, 9 Jan 2012 08:40:05 +0000 (UTC)
commit d68acdb35b728c063fa30719bda641600b0264f9
Author: Dan VrÃtil <dvratil redhat com>
Date: Mon Jul 11 15:39:37 2011 +0200
Port EABContactDisplay to JavaScript and CSS
- replace table layout by floating <div>s; this makes it possible to use one
common HTML code for both vertical and horizontal contact preview
- use JavaScript for collapsing/expanding subcontact lists instead of
generating whole new HTML code and re-rendering the preview page
- TODO: the maps widgets are not yet ported, this is blocked by
WebKit bug #63451
addressbook/gui/widgets/Makefile.am | 1 +
addressbook/gui/widgets/eab-contact-display.c | 653 +++++++------------------
mail/em-format-html.c | 185 +++++++-
modules/addressbook/e-book-shell-content.c | 9 -
widgets/misc/e-web-view.c | 2 +-
5 files changed, 373 insertions(+), 477 deletions(-)
---
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index 546a218..e78d5b6 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_DATADIR=\"${datadir}\" \
-I$(top_srcdir) \
-I$(top_srcdir)/filter \
-I$(top_srcdir)/widgets \
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index 76e9e11..95ba3f0 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -46,17 +46,13 @@
struct _EABContactDisplayPrivate {
EContact *contact;
EABContactDisplayMode mode;
- GtkOrientation orientation;
gboolean show_maps;
-
- GHashTable *closed_lists; /* see render_contact_list_ * */
};
enum {
PROP_0,
PROP_CONTACT,
PROP_MODE,
- PROP_ORIENTATION,
PROP_SHOW_MAPS
};
@@ -76,9 +72,6 @@ common_location[] =
{ "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"
@@ -88,12 +81,40 @@ common_location[] =
#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 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" \
+ "<style type=\"text/css\" rel=\"Stylesheet\" ref=\"file://" EVOLUTION_DATADIR "/evo_style.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" \
+ " h2 { color: " HEADER_COLOR "; }\n" \
+ " table th { color: " HEADER_COLOR "; text-align: left; }\n" \
+ " .type { color: " HEADER_COLOR "; }\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 const gchar *ui =
"<ui>"
" <popup name='context'>"
@@ -109,6 +130,33 @@ static const gchar *ui =
static gpointer parent_class;
static guint signals[LAST_SIGNAL];
+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
contact_display_emit_send_message (EABContactDisplay *display,
gint email_num)
@@ -277,48 +325,49 @@ accum_address (GString *buffer,
}
static void
-accum_name_value (GString *buffer,
+render_table_row (GString *buffer,
const gchar *label,
const gchar *str,
const gchar *icon,
guint html_flags)
{
- gchar *value = e_text_to_html (str, 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> "
- "<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,
- "<object width=\"16\" height=\"16\" "
- "type=\"image/x-themed-icon\" "
- "data=\"%s\"/></td></tr>", icon);
- else
- g_string_append_printf (buffer, "</td></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 "\">");
- if (icon != NULL)
- g_string_append_printf (
- buffer,
- "<object width=\"16\" height=\"16\" "
- "type=\"image/x-themed-icon\" "
- "data=\"%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);
+ 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);
}
- g_free (value);
+ if (html_flags)
+ g_free (value);
}
static void
@@ -334,7 +383,7 @@ accum_attribute (GString *buffer,
str = e_contact_get_const (contact, field);
if (str != NULL && *str != '\0')
- accum_name_value (buffer, html_label, str, icon, html_flags);
+ render_table_row (buffer, html_label, str, icon, html_flags);
}
static void
@@ -356,13 +405,13 @@ accum_time_attribute (GString *buffer,
date->year );
g_date_strftime (sdate, 100, "%x", gdate);
g_date_free (gdate);
- accum_name_value (buffer, html_label, sdate, icon, html_flags);
+ render_table_row (buffer, html_label, sdate, icon, html_flags);
e_contact_date_free (date);
}
}
static void
-accum_multival_attribute (GString *buffer,
+accum_attribute_multival (GString *buffer,
EContact *contact,
const gchar *html_label,
EContactField field,
@@ -370,34 +419,23 @@ accum_multival_attribute (GString *buffer,
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;
+ GString *val = g_string_new ("");
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);
+ if (l != val_list)
+ g_string_append (val, "<br>");
+
+ g_string_append (val, l->data);
}
- 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);
-}
+ if (val->str && *val->str)
+ render_table_row (buffer, html_label, val->str, icon, html_flags);
-static void
-end_block (GString *buffer)
-{
- g_string_append (buffer, "<tr><td height=\"20\"> </td></tr>");
+ g_string_free (val, TRUE);
+ g_list_foreach (val_list, (GFunc) g_free, NULL);
+ g_list_free (val_list);
}
static const gchar *
@@ -430,10 +468,10 @@ render_title_block (GString *buffer,
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,
- "<object border=\"1\" "
- "type=\"image/x-contact-photo\"/>");
+ gchar *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);
}
@@ -441,12 +479,12 @@ render_title_block (GString *buffer,
if (photo)
e_contact_photo_free (photo);
- if (e_contact_get (contact, E_CONTACT_IS_LIST))
- g_string_append (
- buffer,
- "<object width=\"16\" height=\"16\" "
- "type=\"image/x-themed-icon\" "
- "data=\"" CONTACT_LIST_ICON "\"/>");
+ 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\"" : "");
@@ -475,12 +513,9 @@ render_contact_list_row (GString *buffer,
{
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;
+ const gchar *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);
@@ -488,15 +523,15 @@ render_contact_list_row (GString *buffer,
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),
+ "<td width=" IMAGE_COL_WIDTH " valign=\"top\"><img src=\"%s/minus.png\" onClick=\"collapse_list(this, %s);\"></td><td width=\"100%%\">%s",
evolution_imagesdir,
- (list_collapsed ? "plus" : "minus"),
+ e_destination_get_contact_uid (destination),
name ? name : email_addr);
if (!list_collapsed) {
const GList *dest, *dests;
- g_string_append (buffer, "<br><table cellspacing=\"1\">");
+ 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) {
@@ -524,37 +559,9 @@ render_contact_list_row (GString *buffer,
}
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)
+render_contact_list (GString *buffer,
+ EContact *contact,
+ EABContactDisplay *display)
{
EDestination *destination;
const GList *dest, *dests;
@@ -579,32 +586,17 @@ render_contact_list_horizontal (GString *buffer,
}
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)
+render_contact_column (GString *buffer,
+ EContact *contact)
{
- GString *accum;
+ GString *accum, *email;
GList *email_list, *l, *email_attr_list, *al;
gint email_num = 0;
const gchar *nl;
- gchar *nick = NULL;
- accum = g_string_new ("");
+ email = 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);
@@ -615,7 +607,7 @@ render_contact_block (GString *buffer,
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>",
+ g_string_append_printf (email, "%s%s%s<a href=\"internal-mailto:%d\">%s</a>%s <span class=\"type\">(%s)</span>",
nl,
name ? name : "",
name ? " <" : "",
@@ -634,59 +626,34 @@ render_contact_block (GString *buffer,
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);
- }
+ accum = g_string_new ("");
- 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 (email->len)
+ render_table_row (accum, _("Email"), email->str, NULL, 0);
- if (accum->len > 0)
- g_string_append_printf (buffer, "%s", accum->str);
+ 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);
- end_block (buffer);
+ 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_free (nick);
-
+ g_string_free (email, TRUE);
}
static void
-render_work_block (GString *buffer,
- EContact *contact)
+render_work_column (GString *buffer,
+ EContact *contact)
{
GString *accum = g_string_new ("");
@@ -704,17 +671,19 @@ render_work_block (GString *buffer,
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_append_printf (buffer,
+ "<div class=\"column\" id=\"contact-work\">"
+ "<h2>%s</h2>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("Work"), accum->str);
}
g_string_free (accum, TRUE);
}
static void
-render_personal_block (GString *buffer,
- EContact *contact)
+render_personal_column (GString *buffer,
+ EContact *contact)
{
GString *accum = g_string_new ("");
@@ -727,33 +696,34 @@ render_personal_block (GString *buffer,
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_append_printf (buffer,
+ "<div class=\"column\" id=\"contact-personal\">"
+ "<h2>%s</h2>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("Personal"), accum->str);
}
g_string_free (accum, TRUE);
}
static void
-render_note_block (GString *buffer,
- EContact *contact)
+render_footer (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);
-
- g_free (html);
+ 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
@@ -763,94 +733,27 @@ render_address_map (GString *buffer,
{
#ifdef WITH_CONTACT_MAPS
if (map_type == E_CONTACT_ADDRESS_WORK) {
- g_string_append (buffer, "<object classid=\"address-map-work\"></object>");
+ g_string_append (buffer, "<object type=\"application/x-map-widget\" data=\"work\"></object>");
} else {
- g_string_append (buffer, "<object classid=\"address-map-home\"></object>");
+ g_string_append (buffer, "<object type=\"application/x-map-widget\" data=\"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)
+render_contact (GString *buffer,
+ EContact *contact,
+ EABContactDisplay *display)
{
- /* 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, "<div id=\"columns\">");
+ render_contact_column (buffer, contact);
+ render_work_column (buffer, contact);
+ render_personal_column (buffer, contact);
+ g_string_append (buffer, "</div>");
- 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);
+ render_footer (buffer, contact);
}
static void
@@ -863,22 +766,16 @@ eab_contact_display_render_normal (EABContactDisplay *display,
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\"" : "");
+ g_string_append (buffer, "<body>");
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);
-
+ render_contact (buffer, contact, display);
}
- g_string_append (buffer, "</td></tr></table></body></html>\n");
+ g_string_append (buffer, "</body></html>\n");
e_web_view_load_string (E_WEB_VIEW (display), buffer->str);
@@ -889,8 +786,11 @@ static void
eab_contact_display_render_compact (EABContactDisplay *display,
EContact *contact)
{
+#warning FIXME: eab_contact_display_render_compact is not WebKit-ready
+
GString *buffer;
+
/* XXX The initial buffer size is arbitrary. Tune it. */
buffer = g_string_sized_new (4096);
@@ -1116,12 +1016,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 +1045,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,86 +1067,10 @@ contact_display_dispose (GObject *object)
priv->contact = NULL;
}
- if (priv->closed_lists != NULL) {
- g_hash_table_unref (priv->closed_lists);
- priv->closed_lists = NULL;
- }
-
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
-#if 0 /* WEBKIT */
-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);
-}
-#endif
-
static GtkWidget *
contact_display_create_plugin_widget (EWebView *web_view,
const gchar *mime_type,
@@ -1266,34 +1078,9 @@ contact_display_create_plugin_widget (EWebView *web_view,
GHashTable *param)
{
EWebViewClass *web_view_class;
- EABContactDisplay *display;
-
- display = EAB_CONTACT_DISPLAY (web_view);
-
- if (g_strcmp0 (mime_type, "image/x-contact-photo") == 0) {
- EContactPhoto *photo;
- EContact *contact;
- GdkPixbuf *pixbuf;
- GdkPixbufLoader *loader;
- GtkWidget *widget = NULL;
- 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);
+#warning FIXME: contact_display_create_plugin_widget is not WebKit-ready
- loader = gdk_pixbuf_loader_new ();
- gdk_pixbuf_loader_write (
- loader, photo->data.inlined.data,
- photo->data.inlined.length, NULL);
- gdk_pixbuf_loader_close (loader, NULL);
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
- if (pixbuf != NULL)
- widget = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (loader);
-
- return widget;
- }
/* Chain up to parent's create_plugin_widget() method. */
web_view_class = E_WEB_VIEW_CLASS (parent_class);
@@ -1353,19 +1140,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. */
@@ -1384,6 +1158,7 @@ handle_map_scroll_event (GtkWidget *widget,
return TRUE;
}
+#if 0
static void
contact_display_object_requested (GtkHTML *html,
GtkHTMLEmbedded *eb,
@@ -1422,6 +1197,7 @@ contact_display_object_requested (GtkHTML *html,
e_contact_address_free (address);
}
#endif
+#endif
static void
contact_display_update_actions (EWebView *web_view)
@@ -1457,9 +1233,6 @@ static void
eab_contact_display_class_init (EABContactDisplayClass *class)
{
GObjectClass *object_class;
-#if 0 /* WEBKIT */
- GtkHTMLClass *html_class;
-#endif
EWebViewClass *web_view_class;
parent_class = g_type_class_peek_parent (class);
@@ -1470,11 +1243,6 @@ eab_contact_display_class_init (EABContactDisplayClass *class)
object_class->get_property = contact_display_get_property;
object_class->dispose = contact_display_dispose;
-#if 0 /* WEBKIT */
- html_class = GTK_HTML_CLASS (class);
- html_class->url_requested = contact_display_url_requested;
-#endif
-
web_view_class = E_WEB_VIEW_CLASS (class);
web_view_class->create_plugin_widget = contact_display_create_plugin_widget;
web_view_class->hovering_over_link = contact_display_hovering_over_link;
@@ -1504,18 +1272,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,
@@ -1549,18 +1305,17 @@ eab_contact_display_init (EABContactDisplay *display)
display->priv = G_TYPE_INSTANCE_GET_PRIVATE (
display, EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayPrivate);
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);
web_view = E_WEB_VIEW (display);
ui_manager = e_web_view_get_ui_manager (web_view);
#ifdef WITH_CONTACT_MAPS
+#if 0
g_signal_connect (web_view, "object-requested",
G_CALLBACK (contact_display_object_requested), display);
#endif
+#endif
action_group = gtk_action_group_new ("internal-mailto");
gtk_action_group_set_translation_domain (action_group, domain);
@@ -1680,40 +1435,6 @@ eab_contact_display_set_mode (EABContactDisplay *display,
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);
-
- 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), "orientation");
-}
-
gboolean
eab_contact_display_get_show_maps (EABContactDisplay *display)
{
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 01b8b43..7c57d07 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1534,7 +1534,190 @@ em_format_html_job_queue (EMFormatHTML *emfh,
/* ********************************************************************** */
-#if 0 /* WEBKIT */
+static void
+emfh_getpuri (struct _EMFormatHTMLJob *job,
+ GCancellable *cancellable)
+{
+ d(printf(" running getpuri task\n"));
+ if (!g_cancellable_is_cancelled (cancellable))
+ job->u.puri->func (
+ EM_FORMAT (job->format), job->stream,
+ job->u.puri, cancellable);
+}
+
+static void
+emfh_gethttp (struct _EMFormatHTMLJob *job,
+ GCancellable *cancellable)
+{
+ CamelStream *cistream = NULL, *costream = NULL, *instream = NULL;
+ CamelURL *url;
+ CamelContentType *content_type;
+ CamelHttpStream *tmp_stream;
+ gssize n, total = 0, pc_complete = 0, nread = 0;
+ gchar buffer[1500];
+ const gchar *length;
+
+ if (g_cancellable_is_cancelled (cancellable)
+ || (url = camel_url_new (job->u.uri, NULL)) == NULL)
+ goto badurl;
+
+ d(printf(" running load uri task: %s\n", job->u.uri));
+
+ if (emfh_http_cache)
+ instream = cistream = camel_data_cache_get (emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
+
+ if (instream == NULL) {
+ EMailImageLoadingPolicy policy;
+ gchar *proxy;
+
+ policy = em_format_html_get_image_loading_policy (job->format);
+
+ if (!(job->format->priv->load_images_now
+ || policy == E_MAIL_IMAGE_LOADING_POLICY_ALWAYS
+ || (policy == E_MAIL_IMAGE_LOADING_POLICY_SOMETIMES
+ && em_utils_in_addressbook ((CamelInternetAddress *) camel_mime_message_get_from (job->format->parent.message), FALSE)))) {
+ /* TODO: Ideally we would put the http requests into another queue and only send them out
+ if the user selects 'load images', when they do. The problem is how to maintain this
+ state with multiple renderings, and how to adjust the thread dispatch/setup routine to handle it */
+ camel_url_free (url);
+ goto done;
+ }
+
+ instream = camel_http_stream_new (CAMEL_HTTP_METHOD_GET, ((EMFormat *) job->format)->session, url);
+ camel_http_stream_set_user_agent((CamelHttpStream *)instream, "CamelHttpStream/1.0 Evolution/" VERSION);
+ proxy = em_utils_get_proxy_uri (job->u.uri);
+ if (proxy) {
+ camel_http_stream_set_proxy ((CamelHttpStream *) instream, proxy);
+ g_free (proxy);
+ }
+ camel_operation_push_message (
+ cancellable, _("Retrieving '%s'"), job->u.uri);
+ tmp_stream = (CamelHttpStream *) instream;
+ content_type = camel_http_stream_get_content_type (tmp_stream);
+ length = camel_header_raw_find(&tmp_stream->headers, "Content-Length", NULL);
+ d(printf(" Content-Length: %s\n", length));
+ if (length != NULL)
+ total = atoi (length);
+ camel_content_type_unref (content_type);
+ } else
+ camel_operation_push_message (
+ cancellable, _("Retrieving '%s'"), job->u.uri);
+
+ camel_url_free (url);
+
+ if (instream == NULL)
+ goto done;
+
+ if (emfh_http_cache != NULL && cistream == NULL)
+ costream = camel_data_cache_add (emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
+
+ do {
+ if (camel_operation_cancel_check (CAMEL_OPERATION (cancellable))) {
+ n = -1;
+ break;
+ }
+ /* FIXME: progress reporting in percentage, can we get the length always? do we care? */
+ n = camel_stream_read (instream, buffer, sizeof (buffer), cancellable, NULL);
+ if (n > 0) {
+ nread += n;
+ /* If we didn't get a valid Content-Length header, do not try to calculate percentage */
+ if (total != 0) {
+ pc_complete = ((nread * 100) / total);
+ camel_operation_progress (cancellable, pc_complete);
+ }
+ d(printf(" read %d bytes\n", n));
+ if (costream && camel_stream_write (costream, buffer, n, cancellable, NULL) == -1) {
+ n = -1;
+ break;
+ }
+
+ camel_stream_write (job->stream, buffer, n, cancellable, NULL);
+ }
+ } while (n>0);
+
+ /* indicates success */
+ if (n == 0)
+ camel_stream_close (job->stream, cancellable, NULL);
+
+ if (costream) {
+ /* do not store broken files in a cache */
+ if (n != 0)
+ camel_data_cache_remove (emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
+ g_object_unref (costream);
+ }
+
+ g_object_unref (instream);
+done:
+ camel_operation_pop_message (cancellable);
+badurl:
+ g_free (job->u.uri);
+}
+
+/* ********************************************************************** */
+
+static void
+efh_url_requested (GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMFormatHTML *efh)
+{
+ EMFormatPURI *puri;
+ struct _EMFormatHTMLJob *job = NULL;
+
+ d(printf("url requested, html = %p, url '%s'\n", html, url));
+
+ puri = em_format_find_visible_puri ((EMFormat *) efh, url);
+ if (puri) {
+ CamelDataWrapper *dw = camel_medium_get_content ((CamelMedium *) puri->part);
+ CamelContentType *ct = dw?dw->mime_type:NULL;
+
+ /* GtkHTML only handles text and images.
+ application/octet-stream parts are the only ones
+ which are snooped for other content. So only try
+ to pass these to it - any other types are badly
+ formed or intentionally malicious emails. They
+ will still show as attachments anyway */
+
+ if (ct && (camel_content_type_is(ct, "text", "*")
+ || camel_content_type_is(ct, "image", "*")
+ || camel_content_type_is(ct, "application", "octet-stream"))) {
+ puri->use_count++;
+
+ d(printf(" adding puri job\n"));
+ job = em_format_html_job_new (efh, emfh_getpuri, puri);
+ } else {
+ d(printf(" part is unknown type '%s', not using\n", ct?camel_content_type_format(ct):"<unset>"));
+ gtk_html_stream_close (handle, GTK_HTML_STREAM_ERROR);
+ }
+ } else if (g_ascii_strncasecmp(url, "http:", 5) == 0 || g_ascii_strncasecmp(url, "https:", 6) == 0) {
+ d(printf(" adding job, get %s\n", url));
+ job = em_format_html_job_new (efh, emfh_gethttp, g_strdup (url));
+ } else if (g_str_has_prefix (url, "file://")) {
+ gchar *data = NULL;
+ gsize length = 0;
+ gboolean status;
+ gchar *path;
+
+ path = g_filename_from_uri (url, NULL, NULL);
+ g_return_if_fail (path != NULL);
+
+ status = g_file_get_contents (path, &data, &length, NULL);
+ if (status)
+ gtk_html_stream_write (handle, data, length);
+
+ gtk_html_stream_close (handle, status ? GTK_HTML_STREAM_OK : GTK_HTML_STREAM_ERROR);
+ g_free (data);
+ g_free (path);
+ } else {
+ d(printf("HTML Includes reference to unknown uri '%s'\n", url));
+ gtk_html_stream_close (handle, GTK_HTML_STREAM_ERROR);
+ }
+
+ if (job) {
+ job->stream = em_html_stream_new (html, handle);
+ em_format_html_job_queue (efh, job);
+ }
+
+ g_signal_stop_emission_by_name (html, "url-requested");
+}
+
static gboolean
efh_object_requested (GtkHTML *html,
GtkHTMLEmbedded *eb,
diff --git a/modules/addressbook/e-book-shell-content.c b/modules/addressbook/e-book-shell-content.c
index 0183512..f3457e8 100644
--- a/modules/addressbook/e-book-shell-content.c
+++ b/modules/addressbook/e-book-shell-content.c
@@ -286,20 +286,11 @@ book_shell_content_constructed (GObject *object)
EAB_CONTACT_DISPLAY (widget),
EAB_CONTACT_DISPLAY_RENDER_NORMAL);
- eab_contact_display_set_orientation (
- EAB_CONTACT_DISPLAY (widget),
- priv->orientation);
-
eab_contact_display_set_show_maps (
EAB_CONTACT_DISPLAY (widget),
priv->preview_show_maps);
g_object_bind_property (
- object, "orientation",
- widget, "orientation",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
object, "preview-show-maps",
widget, "show-maps",
G_BINDING_SYNC_CREATE);
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 6333173..1944570 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -1063,7 +1063,7 @@ web_view_load_string (EWebView *web_view,
webkit_web_view_load_string (
WEBKIT_WEB_VIEW (web_view),
- string, "text/html", "UTF-8", NULL);
+ string, "text/html", "UTF-8", "file://");
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]