[evolution/webkit: 171/177] vcard-inline plugin: render preview as HTML in <iframe> rather then WebKitWebView widget



commit 33c3bc9f5d05ff632a8f9b12afec7afb3f899518
Author: Dan VrÃtil <dvratil redhat com>
Date:   Fri Feb 24 13:33:38 2012 +0100

    vcard-inline plugin: render preview as HTML in <iframe> rather then WebKitWebView widget
    
    The vcard-inline plugin used to render the vcard preview as the
    EABContactDisplay and embed it into the EMailDisplay. Since
    EABContactDisplay is actually a WebKitWebView, it didn't
    work much well.
    
    This commit changes the vcard-inline plugin so that it renders
    as an <iframe> and renders the preview within the <iframe> using
    the new EABContactFormatter.

 plugins/vcard-inline/vcard-inline.c |  346 ++++++++++++++++++++++-------------
 1 files changed, 216 insertions(+), 130 deletions(-)
---
diff --git a/plugins/vcard-inline/vcard-inline.c b/plugins/vcard-inline/vcard-inline.c
index 9cad663..16a797a 100644
--- a/plugins/vcard-inline/vcard-inline.c
+++ b/plugins/vcard-inline/vcard-inline.c
@@ -28,10 +28,11 @@
 #include <libedataserverui/e-source-selector-dialog.h>
 
 #include "addressbook/gui/merging/eab-contact-merging.h"
-#include "addressbook/gui/widgets/eab-contact-display.h"
+#include "addressbook/gui/widgets/eab-contact-formatter.h"
 #include "addressbook/util/eab-book-util.h"
 #include "mail/em-format-hook.h"
 #include "mail/em-format-html.h"
+#include "mail/e-mail-display.h"
 
 #define d(x)
 
@@ -44,9 +45,12 @@ struct _VCardInlinePURI {
 	ESourceList *source_list;
 	GtkWidget *contact_display;
 	GtkWidget *message_label;
-};
 
-static gint org_gnome_vcard_inline_classid;
+	EABContactFormatter *formatter;
+	WebKitDOMElement *iframe;
+	WebKitDOMElement *toggle_button;
+	WebKitDOMElement *save_button;
+};
 
 /* Forward Declarations */
 void org_gnome_vcard_inline_format (gpointer ep, EMFormatHookTarget *target);
@@ -83,6 +87,26 @@ org_gnome_vcard_inline_pobject_free (EMFormatPURI *object)
 		g_object_unref (vcard_object->message_label);
 		vcard_object->message_label = NULL;
 	}
+
+	if (vcard_object->formatter != NULL) {
+		g_object_unref (vcard_object->formatter);
+		vcard_object->formatter = NULL;
+	}
+
+	if (vcard_object->iframe != NULL) {
+		g_object_unref (vcard_object->iframe);
+		vcard_object->iframe = NULL;
+	}
+
+	if (vcard_object->toggle_button != NULL) {
+		g_object_unref (vcard_object->toggle_button);
+		vcard_object->toggle_button = NULL;
+	}
+
+	if (vcard_object->save_button != NULL) {
+		g_object_unref (vcard_object->save_button);
+		vcard_object->save_button = NULL;
+	}
 }
 
 static void
@@ -156,7 +180,9 @@ org_gnome_vcard_inline_client_loaded_cb (ESource *source,
 }
 
 static void
-org_gnome_vcard_inline_save_cb (VCardInlinePURI *vcard_object)
+org_gnome_vcard_inline_save_cb (WebKitDOMEventTarget *button,
+				WebKitDOMEvent *event,
+				VCardInlinePURI *vcard_object)
 {
 	ESource *source;
 	GSList *contact_list;
@@ -191,145 +217,198 @@ org_gnome_vcard_inline_save_cb (VCardInlinePURI *vcard_object)
 }
 
 static void
-org_gnome_vcard_inline_toggle_cb (VCardInlinePURI *vcard_object,
-                                  GtkButton *button)
+org_gnome_vcard_inline_toggle_cb (WebKitDOMEventTarget *button,
+				  WebKitDOMEvent *event,
+				  EMFormatPURI *puri)
 {
-	EABContactDisplay *contact_display;
+	VCardInlinePURI *vcard_object;
 	EABContactDisplayMode mode;
-	const gchar *label;
+	gchar *uri;
 
-	contact_display = EAB_CONTACT_DISPLAY (vcard_object->contact_display);
-	mode = eab_contact_display_get_mode (contact_display);
+	vcard_object = (VCardInlinePURI *) puri;
 
-	/* Toggle between "full" and "compact" modes. */
+	mode = eab_contact_formatter_get_display_mode (vcard_object->formatter);
 	if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
 		mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
-		label = _("Show Full vCard");
+
+		webkit_dom_html_element_set_inner_text(
+			WEBKIT_DOM_HTML_ELEMENT (button),
+			_("Show Full vCard"), NULL);
+
 	} else {
 		mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
-		label = _("Show Compact vCard");
+
+		webkit_dom_html_element_set_inner_text (
+			WEBKIT_DOM_HTML_ELEMENT (button),
+			_("Show Compact vCard"), NULL);
 	}
 
-	eab_contact_display_set_mode (contact_display, mode);
-	gtk_button_set_label (button, label);
+	eab_contact_formatter_set_display_mode (vcard_object->formatter, mode);
+
+	uri = em_format_build_mail_uri (
+		puri->emf->folder, puri->emf->message_uid,
+		"part_id", G_TYPE_STRING, puri->uri,
+		"mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, NULL);
+
+	webkit_dom_html_iframe_element_set_src (
+		WEBKIT_DOM_HTML_IFRAME_ELEMENT (vcard_object->iframe), uri);
+
+	g_free (uri);
 }
 
-static GtkWidget*
-org_gnome_vcard_inline_embed (EMFormat *emf,
-                              EMFormatPURI *object,
-                              GCancellable *cancellable)
+static void
+org_gnome_vcard_inline_bind_dom (EMailDisplay *display,
+				 EMFormatPURI *puri)
 {
+	WebKitDOMDocument *document;
+	WebKitDOMElement *attachment;
+	WebKitDOMNodeList *list;
+	WebKitDOMElement *iframe, *toggle_button, *save_button;
 	VCardInlinePURI *vcard_object;
-	GtkWidget *button_box;
-	GtkWidget *container;
-	GtkWidget *widget;
-	GtkWidget *layout;
-	EContact *contact;
-	guint length;
 
-	vcard_object = (VCardInlinePURI *) object;
-	length = g_slist_length (vcard_object->contact_list);
-
-	if (vcard_object->contact_list != NULL)
-		contact = E_CONTACT (vcard_object->contact_list->data);
-	else
-		contact = NULL;
-
-	layout = gtk_vbox_new (FALSE, 0);
-	gtk_widget_show (layout);
-
-	container = layout;
-
-	widget = gtk_hbutton_box_new ();
-	gtk_button_box_set_layout (
-		GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
-	gtk_box_set_spacing (GTK_BOX (widget), 12);
-	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
-	gtk_widget_show (widget);
-
-	button_box = widget;
-
-	widget = eab_contact_display_new ();
-	eab_contact_display_set_contact (
-		EAB_CONTACT_DISPLAY (widget), contact);
-	eab_contact_display_set_mode (
-		EAB_CONTACT_DISPLAY (widget),
-		EAB_CONTACT_DISPLAY_RENDER_COMPACT);
-	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
-	vcard_object->contact_display = g_object_ref (widget);
-	gtk_widget_show (widget);
-
-	widget = gtk_label_new (NULL);
-	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
-	vcard_object->message_label = g_object_ref (widget);
-
-	if (length == 2) {
-		const gchar *text;
-
-		text = _("There is one other contact.");
-		gtk_label_set_text (GTK_LABEL (widget), text);
-		gtk_widget_show (widget);
-
-	} else if (length > 2) {
-		gchar *text;
-
-		/* Translators: This will always be two or more. */
-		text = g_strdup_printf (ngettext (
-			"There is %d other contact.",
-			"There are %d other contacts.",
-			length - 1), length - 1);
-		gtk_label_set_text (GTK_LABEL (widget), text);
-		gtk_widget_show (widget);
-		g_free (text);
-
-	} else
-		gtk_widget_hide (widget);
-
-	container = button_box;
-
-	widget = gtk_button_new_with_label (_("Show Full vCard"));
-	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
-	gtk_widget_show (widget);
-
-	g_signal_connect_swapped (
-		widget, "clicked",
-		G_CALLBACK (org_gnome_vcard_inline_toggle_cb),
-		vcard_object);
-
-	widget = gtk_button_new_with_label (_("Save in Address Book"));
-	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
-
-	/* This depends on having a source list. */
-	if (vcard_object->source_list != NULL)
-		gtk_widget_show (widget);
-	else
-		gtk_widget_hide (widget);
-
-	g_signal_connect_swapped (
-		widget, "clicked",
-		G_CALLBACK (org_gnome_vcard_inline_save_cb),
-		vcard_object);
-
-	return layout;
+	vcard_object = (VCardInlinePURI *) puri;
+	document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
+	attachment = webkit_dom_document_get_element_by_id (document, puri->uri);
+	if (!attachment)
+		return;
+
+	/* IFRAME */
+	list = webkit_dom_element_get_elements_by_tag_name (attachment, "iframe");
+	if (webkit_dom_node_list_get_length (list) != 1)
+		return;
+	iframe = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0));
+	if (vcard_object->iframe)
+		g_object_unref (vcard_object->iframe);
+	vcard_object->iframe = g_object_ref (iframe);
+
+	/* TOGGLE DISPLAY MODE BUTTON */
+	list = webkit_dom_element_get_elements_by_class_name(
+		attachment, "org-gnome-vcard-inline-display-mode-button");
+	if (webkit_dom_node_list_get_length (list) != 1)
+		return;
+	toggle_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0));
+	if (vcard_object->toggle_button)
+		g_object_unref (vcard_object->toggle_button);
+	vcard_object->toggle_button = g_object_ref (toggle_button);
+
+	/* SAVE TO ADDRESSBOOK BUTTON */
+	list = webkit_dom_element_get_elements_by_class_name (
+		attachment, "org-gnome-vcard-inline-save-button");
+	if (webkit_dom_node_list_get_length (list) != 1)
+		return;
+	save_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0));
+	if (vcard_object->save_button)
+		g_object_unref (vcard_object->save_button);
+	vcard_object->save_button = g_object_ref (save_button);
+
+
+	webkit_dom_event_target_add_event_listener (
+		WEBKIT_DOM_EVENT_TARGET (toggle_button),
+		"click", G_CALLBACK (org_gnome_vcard_inline_toggle_cb),
+		FALSE, puri);
+
+	webkit_dom_event_target_add_event_listener (
+		WEBKIT_DOM_EVENT_TARGET (save_button),
+		"click", G_CALLBACK (org_gnome_vcard_inline_save_cb),
+		FALSE, puri);
 }
 
 static void
-write_vcard_inline_display (EMFormat *emf,
-			    EMFormatPURI *puri,
-			    CamelStream *stream,
-			    EMFormatWriterInfo *info,
-			    GCancellable *cancellable)
+org_gnome_vcard_inline_write (EMFormat *emf,
+			      EMFormatPURI *puri,
+			      CamelStream *stream,
+			      EMFormatWriterInfo *info,
+			      GCancellable *cancellable)
 {
-	gchar *str;
+	VCardInlinePURI *vpuri;
 
-	str = g_strdup_printf (
-		"<object type=\"application/x-org-gnome-vcard-display\" "
-		"height=\"100\" width=\"100%%\" "
-		"data=\"%s\" id=\"%s\"></object>", puri->uri, puri->uri);
+	vpuri = (VCardInlinePURI *) puri;
 
-	camel_stream_write_string (stream, str, cancellable, NULL);
+	if (info->mode == EM_FORMAT_WRITE_MODE_RAW)  {
 
-	g_free (str);
+		EContact *contact;
+
+		if (vpuri->contact_list != NULL)
+			contact = E_CONTACT (vpuri->contact_list->data);
+		else
+			contact = NULL;
+
+		eab_contact_formatter_format_contact_sync (
+			vpuri->formatter, contact, stream, cancellable);
+
+	} else {
+		gchar *str, *uri;
+		gint length;
+		const gchar *label = NULL;
+		EABContactDisplayMode mode;
+		const gchar *info = NULL;
+
+		length = g_slist_length (vpuri->contact_list);
+		if (length < 1)
+			return;
+
+		uri = em_format_build_mail_uri (
+			emf->folder, emf->message_uid,
+			"part_id", G_TYPE_STRING, puri->uri,
+			"mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, NULL);
+
+		mode = eab_contact_formatter_get_display_mode (vpuri->formatter);
+		if (mode == EAB_CONTACT_DISPLAY_RENDER_COMPACT) {
+			mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+			label =_("Show Full vCard");
+		} else {
+			mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
+			label = _("Show Compact vCard");
+		}
+
+		str = g_strdup_printf (
+			"<div id=\"%s\">"
+			"<button type=\"button\" "
+				"name=\"set-display-mode\" "
+				"class=\"org-gnome-vcard-inline-display-mode-button\" "
+				"value=\"%d\">%s</button>"
+			"<button type=\"button\" "
+				"name=\"save-to-addressbook\" "
+				"class=\"org-gnome-vcard-inline-save-button\" "
+				"value=\"%s\">%s</button><br/>"
+			"<iframe width=\"100%%\" height=\"auto\" frameborder=\"0\""
+				"src=\"%s\" name=\"%s\"></iframe>"
+			"</div>",
+			 puri->uri,
+			 mode, label,
+			 puri->uri, _("Save To Addressbook"),
+			 uri, puri->uri);
+
+		camel_stream_write_string (stream, str, cancellable, NULL);
+
+		g_free (str);
+
+		if (length == 2) {
+
+			info = _("There is one other contact.");
+
+		} else if (length > 2) {
+
+			/* Translators: This will always be two or more. */
+			info = g_strdup_printf (ngettext (
+				"There is %d other contact.",
+				"There are %d other contacts.",
+				length - 1), length - 1);
+		}
+
+		if (info) {
+
+			str = g_strdup_printf (
+				"<div class=\"attachment-info\">%s</div>",
+				info);
+
+			camel_stream_write_string (stream, str, cancellable, NULL);
+
+			g_free (str);
+		}
+
+		g_free (uri);
+	}
 }
 
 void
@@ -337,24 +416,31 @@ org_gnome_vcard_inline_format (gpointer ep,
                                EMFormatHookTarget *target)
 {
 	VCardInlinePURI *vcard_object;
-	gchar *classid;
+	gint len;
 
-	classid = g_strdup_printf (
-		"org-gnome-vcard-inline-display-%d",
-		org_gnome_vcard_inline_classid++);
+	len = target->part_id->len;
+	g_string_append (target->part_id, ".org-gnome-vcard-inline-display");
 
 	vcard_object = (VCardInlinePURI *) em_format_puri_new (
-			target->format, sizeof(VCardInlinePURI), target->part, classid);
-	vcard_object->puri.widget_func = org_gnome_vcard_inline_embed;
-	vcard_object->puri.write_func = write_vcard_inline_display;
+			target->format, sizeof(VCardInlinePURI),
+			target->part, target->part_id->str);
+	vcard_object->puri.mime_type = g_strdup("text/html");
+	vcard_object->puri.write_func = org_gnome_vcard_inline_write;
+	vcard_object->puri.bind_func = org_gnome_vcard_inline_bind_dom;
 	vcard_object->puri.free = org_gnome_vcard_inline_pobject_free;
+	vcard_object->puri.is_attachment = true;
+	vcard_object->formatter
+		= g_object_new (
+			EAB_TYPE_CONTACT_FORMATTER,
+			"display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+			"render-maps", FALSE, NULL);
 
 	em_format_add_puri (target->format, (EMFormatPURI *) vcard_object);
 
 	g_object_ref (target->part);
-	org_gnome_vcard_inline_decode (vcard_object, target->part);
 
+	org_gnome_vcard_inline_decode (vcard_object, target->part);
 	e_book_client_get_sources (&vcard_object->source_list, NULL);
 
-	g_free (classid);
+	g_string_truncate (target->part_id, len);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]