[evolution/webkit] Port Itip formatter to HTML



commit 274c752319755f2aeec0338c6d535e135325fccb
Author: Dan VrÃtil <dvratil redhat com>
Date:   Mon Mar 26 22:48:33 2012 +0200

    Port Itip formatter to HTML

 data/webview.css                        |   47 +-
 mail/e-mail-request.c                   |  132 ++-
 plugins/itip-formatter/Makefile.am      |    1 +
 plugins/itip-formatter/itip-formatter.c | 1253 ++++++++++--------
 plugins/itip-formatter/itip-view.c      | 2169 ++++++++++++++++++-------------
 plugins/itip-formatter/itip-view.h      |  277 +++--
 6 files changed, 2285 insertions(+), 1594 deletions(-)
---
diff --git a/data/webview.css b/data/webview.css
index 687d06c..9ff8220 100644
--- a/data/webview.css
+++ b/data/webview.css
@@ -39,7 +39,7 @@ img.navigable {
 }
 
 .attachments {
-  backgound: #FFF;
+  background: #FFF;
   border: 1px solid silver;
   margin: 10px 10px 10px 10px;
   border-left: 0;
@@ -100,3 +100,48 @@ object { /* GtkWidgets */
 .attachments-list th {
   font-weight: bold;
 }
+
+/******* ITIP *********/
+.itip.icon {
+  float: left;
+  margin-right: 5px;
+}
+
+.itip.content {
+  float: left;
+  max-width: 90%;
+}
+
+.itip.description {
+  margin: 5px;
+}
+
+.itip tr {
+  vertical-align: middle;
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+
+.itip th {
+  color: #000;
+  vertical-align: middle;
+}
+
+#table_row_summary td {
+  font-weight: bold;
+}
+
+#table_row_buttons button {
+  line-height: 28px;
+  min-width: 150px;
+  white-space: nowrap;
+}
+
+#table_row_buttons img {
+  margin-right: 5px;
+  vertical-align: middle;
+}
+
+#text_row_buttons td {
+  text-align: center;
+}
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index ceb0a6c..d380ae2 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -427,6 +427,113 @@ cleanup:
 }
 
 static void
+handle_stock_request (GSimpleAsyncResult *res,
+                      GObject *object,
+                      GCancellable *cancellable)
+{
+        EMailRequest *request;
+        SoupURI *uri;
+        GtkIconTheme *icon_theme;
+        GtkIconInfo *icon_info;
+        const gchar *file;
+        gchar *a_size;
+        gssize size;
+        gchar *buffer;
+        gsize buff_len;
+        GtkStyleContext *context;
+        GtkWidgetPath *path;
+        GtkIconSet *set;
+
+        request = E_MAIL_REQUEST (object);
+        uri = soup_request_get_uri (SOUP_REQUEST (object));
+
+        if (request->priv->uri_query) {
+                a_size = g_hash_table_lookup (request->priv->uri_query, "size");
+        } else {
+                a_size = NULL;
+        }
+
+        if (!a_size) {
+                size = GTK_ICON_SIZE_BUTTON;
+        } else {
+                size = atoi(a_size);
+        }
+
+        /* Try style context first */
+        context = gtk_style_context_new ();
+        path = gtk_widget_path_new ();
+        gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
+        gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
+        gtk_style_context_set_path (context, path);
+
+        set = gtk_style_context_lookup_icon_set (context, uri->host);
+        if (!set) {
+                /* Fallback to icon theme */
+                icon_theme = gtk_icon_theme_get_default ();
+                icon_info = gtk_icon_theme_lookup_icon (
+                                icon_theme, uri->host, size,
+                                GTK_ICON_LOOKUP_USE_BUILTIN);
+                if (!icon_info) {
+                        gtk_widget_path_free (path);
+                        g_object_unref (context);
+                        return;
+                }
+
+                file = gtk_icon_info_get_filename (icon_info);
+                buffer = NULL;
+                if (file) {
+                        if (g_file_get_contents (file, &buffer, &buff_len, NULL)) {
+
+                                request->priv->mime_type =
+                                        g_content_type_guess (file, NULL, 0, NULL);
+                                request->priv->content_length = buff_len;
+                        }
+
+                } else {
+                        GdkPixbuf *pixbuf;
+
+                        pixbuf = gtk_icon_info_get_builtin_pixbuf (icon_info);
+                        if (pixbuf) {
+                                gdk_pixbuf_save_to_buffer (
+                                        pixbuf, &buffer,
+                                        &buff_len, "png", NULL, NULL);
+
+                                request->priv->mime_type = g_strdup("image/png");
+                                request->priv->content_length = buff_len;
+
+                                g_object_unref (pixbuf);
+                        }
+                }
+
+                gtk_icon_info_free (icon_info);
+
+        } else {
+                GdkPixbuf *pixbuf;
+
+                pixbuf = gtk_icon_set_render_icon_pixbuf (set, context, size);
+                                gdk_pixbuf_save_to_buffer (
+                                        pixbuf, &buffer,
+                                        &buff_len, "png", NULL, NULL);
+
+                request->priv->mime_type = g_strdup("image/png");
+                request->priv->content_length = buff_len;
+
+                g_object_unref (pixbuf);
+        }
+
+        if (buffer) {
+                GInputStream *stream;
+                stream = g_memory_input_stream_new_from_data (
+                                buffer, buff_len, (GDestroyNotify) g_free);
+                g_simple_async_result_set_op_res_gpointer (res, stream, NULL);
+        }
+
+        gtk_widget_path_free (path);
+        g_object_unref (context);
+
+}
+
+static void
 e_mail_request_init (EMailRequest *request)
 {
 	request->priv = G_TYPE_INSTANCE_GET_PRIVATE (
@@ -476,7 +583,8 @@ mail_request_check_uri(SoupRequest *request,
 	return ((strcmp (uri->scheme, "mail") == 0) ||
 		(strcmp (uri->scheme, "evo-file") == 0) ||
                 (strcmp (uri->scheme, "evo-http") == 0) ||
-                (strcmp (uri->scheme, "evo-https") == 0));
+                (strcmp (uri->scheme, "evo-https") == 0) ||
+                (strcmp (uri->scheme, "gtk-stock") == 0));
 }
 
 static void
@@ -510,12 +618,13 @@ mail_request_send_async (SoupRequest *request,
                 return;
         }
 
-        if (!uri->query) {
-                g_warning ("No query in URI %s", soup_uri_to_string (uri, FALSE));
-                g_return_if_fail (uri->query);
+        if (uri->query) {
+                emr->priv->uri_query = soup_form_decode (uri->query);
+        } else {
+                emr->priv->uri_query = NULL;
         }
 
-        emr->priv->uri_query = soup_form_decode (uri->query);
+
 
         formatters = g_object_get_data (G_OBJECT (session), "formatters");
                                         g_return_if_fail (formatters != NULL);
@@ -561,6 +670,17 @@ mail_request_send_async (SoupRequest *request,
                                 user_data, mail_request_send_async);
                 g_simple_async_result_run_in_thread (result, handle_http_request,
                                 G_PRIORITY_DEFAULT, cancellable);
+
+                return;
+
+        } else if ((g_strcmp0 (uri->scheme, "gtk-stock") == 0)) {
+
+                result = g_simple_async_result_new (G_OBJECT (request), callback,
+                                user_data, mail_request_send_async);
+                g_simple_async_result_run_in_thread (result, handle_stock_request,
+                                G_PRIORITY_DEFAULT, cancellable);
+
+                return;
         }
 }
 
@@ -632,7 +752,7 @@ mail_request_get_content_type (SoupRequest *request)
         return emr->priv->ret_mime_type;
 }
 
-static const char *data_schemes[] = { "mail", "evo-file", "evo-http", "evo-https", NULL };
+static const char *data_schemes[] = { "mail", "evo-file", "evo-http", "evo-https", "gtk-stock", NULL };
 
 static void
 e_mail_request_class_init (EMailRequestClass *class)
diff --git a/plugins/itip-formatter/Makefile.am b/plugins/itip-formatter/Makefile.am
index cabd075..1e6f759 100644
--- a/plugins/itip-formatter/Makefile.am
+++ b/plugins/itip-formatter/Makefile.am
@@ -7,6 +7,7 @@ liborg_gnome_itip_formatter_la_CPPFLAGS =		\
 	$(AM_CPPFLAGS)					\
 	-I$(top_srcdir)					\
 	-I$(top_srcdir)/widgets				\
+	-DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\"	\
 	$(EVOLUTION_DATA_SERVER_CFLAGS)			\
 	$(GNOME_PLATFORM_CFLAGS)
 
diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c
index 0293727..a5f00ec 100644
--- a/plugins/itip-formatter/itip-formatter.c
+++ b/plugins/itip-formatter/itip-formatter.c
@@ -57,12 +57,11 @@
 
 #include "itip-view.h"
 
-#define CLASSID "mail://itip."
 #define CONF_KEY_DELETE "delete-processed"
 
 #define d(x)
 
-struct _itip_puri {
+struct _ItipPURI {
 	EMFormatPURI puri;
 
 	const EMFormatHandler *handle;
@@ -71,7 +70,6 @@ struct _itip_puri {
 	CamelMimePart *part;
 
 	gchar *uid;
-	GtkWidget *view;
 
 	ESourceList *source_lists[E_CAL_CLIENT_SOURCE_TYPE_LAST];
 	GHashTable *clients[E_CAL_CLIENT_SOURCE_TYPE_LAST];
@@ -145,12 +143,15 @@ struct _itip_puri {
 	GHashTable *real_comps; /* ESource's UID -> ECalComponent stored on the server */
 };
 
+typedef struct _ItipPURI ItipPURI;
+
 void format_itip (EPlugin *ep, EMFormatHookTarget *target);
 GtkWidget *itip_formatter_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data);
 gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 
 typedef struct {
-	struct _itip_puri *puri;
+	ItipPURI *puri;
+        ItipView *view;
 	GCancellable *cancellable;
 	gboolean keep_alarm_check;
 	GHashTable *conflicts;
@@ -244,7 +245,7 @@ find_attendee_if_sentby (icalcomponent *ical_comp,
 }
 
 static void
-find_to_address (struct _itip_puri *pitip,
+find_to_address (ItipPURI *pitip,
                  icalcomponent *ical_comp,
                  icalparameter_partstat *status)
 {
@@ -368,7 +369,7 @@ find_to_address (struct _itip_puri *pitip,
 }
 
 static void
-find_from_address (struct _itip_puri *pitip,
+find_from_address (ItipPURI *pitip,
                    icalcomponent *ical_comp)
 {
 	EIterator *it;
@@ -432,7 +433,7 @@ find_from_address (struct _itip_puri *pitip,
 }
 
 static ECalComponent *
-get_real_item (struct _itip_puri *pitip)
+get_real_item (ItipPURI *pitip)
 {
 	ECalComponent *comp = NULL;
 	ESource *source;
@@ -449,7 +450,7 @@ get_real_item (struct _itip_puri *pitip)
 }
 
 static void
-adjust_item (struct _itip_puri *pitip,
+adjust_item (ItipPURI *pitip,
              ECalComponent *comp)
 {
 	ECalComponent *real_comp;
@@ -477,14 +478,15 @@ adjust_item (struct _itip_puri *pitip,
 }
 
 static void
-set_buttons_sensitive (struct _itip_puri *pitip)
+set_buttons_sensitive (ItipPURI *pitip,
+                       ItipView *view)
 {
 	gboolean read_only = TRUE;
 
 	if (pitip->current_client)
 		read_only = e_client_is_readonly (E_CLIENT (pitip->current_client));
 
-	itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), pitip->current_client != NULL && !read_only);
+	itip_view_set_buttons_sensitive (view, pitip->current_client != NULL && !read_only);
 }
 
 static void
@@ -513,7 +515,8 @@ cal_opened_cb (GObject *source_object,
                gpointer user_data)
 {
 	ESource *source = E_SOURCE (source_object);
-	struct _itip_puri *pitip = user_data;
+        ItipView *view = user_data;
+	ItipPURI *pitip = itip_view_get_puri (view);
 	ECalClientSourceType source_type;
 	EClient *client = NULL;
 	ECalClient *cal_client;
@@ -531,8 +534,7 @@ cal_opened_cb (GObject *source_object,
 
 	} else if (error != NULL) {
 		g_warn_if_fail (client == NULL);
-		add_failed_to_load_msg (
-			ITIP_VIEW (pitip->view), source, error);
+		add_failed_to_load_msg (view, source, error);
 		g_error_free (error);
 		return;
 	}
@@ -554,8 +556,7 @@ cal_opened_cb (GObject *source_object,
 		icalcomp = e_cal_component_get_icalcomponent (pitip->comp);
 
 		show_recur_check = check_is_instance (icalcomp);
-		itip_view_set_show_recur_check (
-			ITIP_VIEW (pitip->view), show_recur_check);
+		itip_view_set_show_recur_check (view, show_recur_check);
 	}
 
 	if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) {
@@ -564,19 +565,18 @@ cal_opened_cb (GObject *source_object,
 		needs_decline = e_client_check_capability (
 			E_CLIENT (client),
 			CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING);
-		itip_view_set_needs_decline (
-			ITIP_VIEW (pitip->view), needs_decline);
-		itip_view_set_mode (
-			ITIP_VIEW (pitip->view), ITIP_VIEW_MODE_PUBLISH);
+		itip_view_set_needs_decline (view, needs_decline);
+		itip_view_set_mode (view, ITIP_VIEW_MODE_PUBLISH);
 	}
 
 	pitip->current_client = cal_client;
 
-	set_buttons_sensitive (pitip);
+	set_buttons_sensitive (pitip, view);
 }
 
 static void
-start_calendar_server (struct _itip_puri *pitip,
+start_calendar_server (ItipPURI *pitip,
+                       ItipView *view,
                        ESource *source,
                        ECalClientSourceType type,
                        GAsyncReadyCallback func,
@@ -590,10 +590,10 @@ start_calendar_server (struct _itip_puri *pitip,
 	if (client) {
 		pitip->current_client = client;
 
-		itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->progress_info_id);
+		itip_view_remove_lower_info_item (view, pitip->progress_info_id);
 		pitip->progress_info_id = 0;
 
-		set_buttons_sensitive (pitip);
+		set_buttons_sensitive (pitip, view);
 
 		return;
 	}
@@ -608,20 +608,21 @@ start_calendar_server (struct _itip_puri *pitip,
 }
 
 static void
-start_calendar_server_by_uid (struct _itip_puri *pitip,
+start_calendar_server_by_uid (ItipPURI *pitip,
+                              ItipView *view,
                               const gchar *uid,
                               ECalClientSourceType type)
 {
 	gint i;
 
-	itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE);
+	itip_view_set_buttons_sensitive (view, FALSE);
 
 	for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) {
 		ESource *source;
 
 		source = e_source_list_peek_source_by_uid (pitip->source_lists[i], uid);
 		if (source) {
-			start_calendar_server (pitip, source, type, cal_opened_cb, pitip);
+			start_calendar_server (pitip, view, source, type, cal_opened_cb, view);
 			break;
 		}
 	}
@@ -632,25 +633,27 @@ source_selected_cb (ItipView *view,
                     ESource *source,
                     gpointer data)
 {
-	struct _itip_puri *pitip = data;
+	ItipPURI *pitip = data;
 
-	itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE);
+	itip_view_set_buttons_sensitive (view, FALSE);
 
 	g_return_if_fail (source != NULL);
 
-	start_calendar_server (pitip, source, pitip->type, cal_opened_cb, pitip);
+	start_calendar_server (pitip, view, source, pitip->type, cal_opened_cb, view);
 }
 
 static void
 find_cal_update_ui (FormatItipFindData *fd,
                     ECalClient *cal_client)
 {
-	struct _itip_puri *pitip;
+	ItipPURI *pitip;
+        ItipView *view;
 	ESource *source;
 
 	g_return_if_fail (fd != NULL);
 
 	pitip = fd->puri;
+        view = fd->view;
 
 	/* UI part gone */
 	if (g_cancellable_is_cancelled (fd->cancellable))
@@ -659,13 +662,13 @@ find_cal_update_ui (FormatItipFindData *fd,
 	source = cal_client ? e_client_get_source (E_CLIENT (cal_client)) : NULL;
 
 	if (cal_client && g_hash_table_lookup (fd->conflicts, cal_client)) {
-		itip_view_add_upper_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
+		itip_view_add_upper_info_item_printf (view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
 						      _("An appointment in the calendar '%s' conflicts with this meeting"), e_source_peek_name (source));
 	}
 
 	/* search for a master object if the detached object doesn't exist in the calendar */
 	if (pitip->current_client && pitip->current_client == cal_client) {
-		itip_view_set_show_keep_alarm_check (ITIP_VIEW (pitip->view), fd->keep_alarm_check);
+		itip_view_set_show_keep_alarm_check (view, fd->keep_alarm_check);
 
 		pitip->current_client = cal_client;
 
@@ -679,35 +682,35 @@ find_cal_update_ui (FormatItipFindData *fd,
 		/* We clear everything because we don't really care
 		 * about any other info/warnings now we found an
 		 * existing versions */
-		itip_view_clear_lower_info_items (ITIP_VIEW (pitip->view));
+		itip_view_clear_lower_info_items (view);
 		pitip->progress_info_id = 0;
 
 		/* FIXME Check read only state of calendar? */
-		itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO,
-						      _("Found the appointment in the calendar '%s'"), e_source_peek_name (source));
+		itip_view_add_lower_info_item_printf (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                        _("Found the appointment in the calendar '%s'"), e_source_peek_name (source));
 
-		set_buttons_sensitive (pitip);
+		set_buttons_sensitive (pitip, view);
 	} else if (!pitip->current_client)
-		itip_view_set_show_keep_alarm_check (ITIP_VIEW (pitip->view), FALSE);
+		itip_view_set_show_keep_alarm_check (view, FALSE);
 
 	if (pitip->current_client && pitip->current_client == cal_client) {
 		if (e_cal_client_check_recurrences_no_master (pitip->current_client)) {
 			icalcomponent *icalcomp = e_cal_component_get_icalcomponent (pitip->comp);
 
 			if (check_is_instance (icalcomp))
-				itip_view_set_show_recur_check (ITIP_VIEW (pitip->view), TRUE);
+				itip_view_set_show_recur_check (view, TRUE);
 			else
-				itip_view_set_show_recur_check (ITIP_VIEW (pitip->view), FALSE);
+				itip_view_set_show_recur_check (view, FALSE);
 		}
 
 		if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) {
 			/* TODO The static capability should be made generic to convey that the calendar contains unaccepted items */
 			if (e_client_check_capability (E_CLIENT (pitip->current_client), CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING))
-				itip_view_set_needs_decline (ITIP_VIEW (pitip->view), TRUE);
+				itip_view_set_needs_decline (view, TRUE);
 			else
-				itip_view_set_needs_decline (ITIP_VIEW (pitip->view), FALSE);
+				itip_view_set_needs_decline (view, FALSE);
 
-			itip_view_set_mode (ITIP_VIEW (pitip->view), ITIP_VIEW_MODE_PUBLISH);
+			itip_view_set_mode (view, ITIP_VIEW_MODE_PUBLISH);
 		}
 	}
 }
@@ -722,9 +725,10 @@ decrease_find_data (FormatItipFindData *fd)
 
 	if (fd->count == 0 && !g_cancellable_is_cancelled (fd->cancellable)) {
 		gboolean rsvp_enabled = FALSE;
-		struct _itip_puri *pitip = fd->puri;
+		ItipPURI *pitip = fd->puri;
+                ItipView *view = fd->view;
 
-		itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->progress_info_id);
+		itip_view_remove_lower_info_item (view, pitip->progress_info_id);
 		pitip->progress_info_id = 0;
 
 		/*
@@ -733,15 +737,15 @@ decrease_find_data (FormatItipFindData *fd)
  *               * invitiations (REQUEST), but not replies (REPLY).
 		 * Replies only make sense for events with an organizer.
 		 */
-		if ((!pitip->current_client || !e_cal_client_check_save_schedules (pitip->current_client)) &&
+	        if ((!pitip->current_client || !e_cal_client_check_save_schedules (pitip->current_client)) &&
 		    (pitip->method == ICAL_METHOD_PUBLISH || pitip->method ==  ICAL_METHOD_REQUEST) &&
 		    pitip->has_organizer) {
 			rsvp_enabled = TRUE;
 		}
-		itip_view_set_show_rsvp (ITIP_VIEW (pitip->view), rsvp_enabled);
+		itip_view_set_show_rsvp_check (view, rsvp_enabled);
 
 		/* default is chosen in extract_itip_data() based on content of the VEVENT */
-		itip_view_set_rsvp (ITIP_VIEW (pitip->view), !pitip->no_reply_wanted);
+		itip_view_set_rsvp (view, !pitip->no_reply_wanted);
 
 		if ((pitip->method == ICAL_METHOD_PUBLISH || pitip->method ==  ICAL_METHOD_REQUEST)
 		    && !pitip->current_client) {
@@ -787,32 +791,35 @@ decrease_find_data (FormatItipFindData *fd)
 			if (!source)
 				source = e_source_list_peek_source_any (pitip->source_lists[pitip->type]);
 
-			itip_view_set_source_list (ITIP_VIEW (pitip->view), pitip->source_lists[pitip->type]);
+			itip_view_set_source_list (view, pitip->source_lists[pitip->type]);
 			g_signal_connect (
-				pitip->view, "source_selected",
+				view, "source_selected",
 				G_CALLBACK (source_selected_cb), pitip);
 
 			if (source) {
-				itip_view_set_source (ITIP_VIEW (pitip->view), source);
+				itip_view_set_source (view, source);
 
 				/* FIXME Shouldn't the buttons be sensitized here? */
 			} else {
-				itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to find any calendars"));
-				itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE);
+				itip_view_add_lower_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to find any calendars"));
+				itip_view_set_buttons_sensitive (view, FALSE);
 			}
 		} else if (!pitip->current_client) {
 			switch (pitip->type) {
 			case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-				itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
-								      _("Unable to find this meeting in any calendar"));
+				itip_view_add_lower_info_item_printf (
+                                        view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
+					_("Unable to find this meeting in any calendar"));
 				break;
 			case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-				itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
-								      _("Unable to find this task in any task list"));
+				itip_view_add_lower_info_item_printf (
+                                        view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
+					_("Unable to find this task in any task list"));
 				break;
 			case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-				itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
-								      _("Unable to find this memo in any memo list"));
+				itip_view_add_lower_info_item_printf (
+                                        view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
+					_("Unable to find this memo in any memo list"));
 				break;
 			default:
 				g_assert_not_reached ();
@@ -826,6 +833,8 @@ decrease_find_data (FormatItipFindData *fd)
 		g_object_unref (fd->cancellable);
 		g_free (fd->uid);
 		g_free (fd->rid);
+                if (fd->sexp)
+                        g_free (fd->sexp);
 		g_free (fd);
 	}
 }
@@ -980,7 +989,8 @@ find_cal_opened_cb (GObject *source_object,
 {
 	ESource *source = E_SOURCE (source_object);
 	FormatItipFindData *fd = user_data;
-	struct _itip_puri *pitip = fd->puri;
+	ItipPURI *pitip = fd->puri;
+        ItipView *view = fd->view;
 	ECalClientSourceType source_type;
 	EClient *client = NULL;
 	ECalClient *cal_client;
@@ -1009,8 +1019,7 @@ find_cal_opened_cb (GObject *source_object,
 		 * to find the item, this won't be cleared but the
 		 * selector might be shown */
 		g_warn_if_fail (client == NULL);
-		add_failed_to_load_msg (
-			ITIP_VIEW (pitip->view), source, error);
+		add_failed_to_load_msg (view, source, error);
 		decrease_find_data (fd);
 		g_error_free (error);
 		return;
@@ -1051,7 +1060,8 @@ find_cal_opened_cb (GObject *source_object,
 }
 
 static void
-find_server (struct _itip_puri *pitip,
+find_server (ItipPURI *pitip,
+             ItipView *view,
              ECalComponent *comp)
 {
 	FormatItipFindData *fd = NULL;
@@ -1074,7 +1084,7 @@ find_server (struct _itip_puri *pitip,
 	uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
 	camel_url_free (url);
 
-	itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE);
+	itip_view_set_buttons_sensitive (view, FALSE);
 
 	groups = e_source_list_peek_groups (pitip->source_lists[pitip->type]);
 	for (l = groups; l; l = l->next) {
@@ -1113,11 +1123,13 @@ find_server (struct _itip_puri *pitip,
 	if (current_source) {
 		l = sources_conflict;
 
-		pitip->progress_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
-				_("Opening the calendar. Please wait..."));
+		pitip->progress_info_id = itip_view_add_lower_info_item (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
+			_("Opening the calendar. Please wait..."));
 	} else {
-		pitip->progress_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
-				_("Searching for an existing version of this appointment"));
+		pitip->progress_info_id = itip_view_add_lower_info_item (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
+			_("Searching for an existing version of this appointment"));
 
 		l = all_sources;
 	}
@@ -1130,6 +1142,7 @@ find_server (struct _itip_puri *pitip,
 
 			fd = g_new0 (FormatItipFindData, 1);
 			fd->puri = pitip;
+                        fd->view = view;
 			fd->cancellable = g_object_ref (pitip->cancellable);
 			fd->conflicts = g_hash_table_new (g_direct_hash, g_direct_equal);
 			fd->uid = g_strdup (uid);
@@ -1152,9 +1165,9 @@ find_server (struct _itip_puri *pitip,
 		d(printf ("Increasing itip formatter search count to %d\n", fd->count));
 
 		if (current_source == source)
-			start_calendar_server (pitip, source, pitip->type, find_cal_opened_cb, fd);
+			start_calendar_server (pitip, view, source, pitip->type, find_cal_opened_cb, fd);
 		else
-			start_calendar_server (pitip, source, pitip->type, find_cal_opened_cb, fd);
+			start_calendar_server (pitip, view, source, pitip->type, find_cal_opened_cb, fd);
 
 	}
 
@@ -1347,32 +1360,36 @@ get_uri_for_part (CamelMimePart *mime_part)
 }
 
 static void
-update_item_progress_info (struct _itip_puri *pitip,
+update_item_progress_info (ItipPURI *pitip,
+                           ItipView *view,
                            const gchar *message)
 {
 	if (pitip->update_item_progress_info_id) {
-		itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->update_item_progress_info_id);
+		itip_view_remove_lower_info_item (view, pitip->update_item_progress_info_id);
 		pitip->update_item_progress_info_id = 0;
 
 		if (!message)
-			itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), TRUE);
+			itip_view_set_buttons_sensitive (view, TRUE);
 	}
 
 	if (pitip->update_item_error_info_id) {
-		itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->update_item_error_info_id);
+		itip_view_remove_lower_info_item (view, pitip->update_item_error_info_id);
 		pitip->update_item_error_info_id = 0;
 	}
 
 	if (message) {
-		itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE);
-		pitip->update_item_progress_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view),
-			ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
-			message);
+		itip_view_set_buttons_sensitive (view, FALSE);
+		pitip->update_item_progress_info_id =
+		        itip_view_add_lower_info_item (
+                                view,
+			        ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
+			        message);
 	}
 }
 
 static void
-finish_message_delete_with_rsvp (struct _itip_puri *pitip,
+finish_message_delete_with_rsvp (ItipPURI *pitip,
+                                 ItipView *view,
                                  ECalClient *client)
 {
 	gboolean save_schedules = e_cal_client_check_save_schedules (client);
@@ -1380,7 +1397,7 @@ finish_message_delete_with_rsvp (struct _itip_puri *pitip,
 	if (!save_schedules && pitip->delete_message && pitip->folder)
 		camel_folder_delete_message (pitip->folder, pitip->uid);
 
-	if (itip_view_get_rsvp (ITIP_VIEW (pitip->view))) {
+	if (itip_view_get_rsvp (view)) {
 		ECalComponent *comp = NULL;
 		icalcomponent *ical_comp;
 		icalproperty *prop;
@@ -1433,7 +1450,7 @@ finish_message_delete_with_rsvp (struct _itip_puri *pitip,
 		g_slist_free (list);
 
 		/* Add a comment if there user set one */
-		comment = itip_view_get_rsvp_comment (ITIP_VIEW (pitip->view));
+		comment = itip_view_get_rsvp_comment (view);
 		if (comment) {
 			GSList comments;
 			ECalComponentText text;
@@ -1460,7 +1477,7 @@ finish_message_delete_with_rsvp (struct _itip_puri *pitip,
 		g_object_unref (comp);
 	}
 
-	update_item_progress_info (pitip, NULL);
+	update_item_progress_info (pitip, view, NULL);
 }
 
 static void
@@ -1470,44 +1487,51 @@ receive_objects_ready_cb (GObject *ecalclient,
 {
 	ECalClient *client = E_CAL_CLIENT (ecalclient);
 	ESource *source = e_client_get_source (E_CLIENT (client));
-	struct _itip_puri *pitip = user_data;
+        ItipView *view = user_data;
+	ItipPURI *pitip = itip_view_get_puri (view);
 	gboolean save_schedules;
 	GError *error = NULL;
 
 	if (!e_cal_client_receive_objects_finish (client, result, &error)) {
 		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
 		    !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) {
-			update_item_progress_info (pitip, NULL);
-			pitip->update_item_error_info_id = itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO,
-						      _("Unable to send item to calendar '%s'.  %s"),
-						      e_source_peek_name (source), error ? error->message : _("Unknown error"));
+			update_item_progress_info (pitip, view, NULL);
+			pitip->update_item_error_info_id =
+			        itip_view_add_lower_info_item_printf (
+                                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                                        _("Unable to send item to calendar '%s'.  %s"),
+					e_source_peek_name (source), error ? error->message : _("Unknown error"));
 		}
 		g_clear_error (&error);
 		return;
 	}
 
-	itip_view_set_source_list (ITIP_VIEW (pitip->view), NULL);
+	itip_view_set_source_list (view, NULL);
 
-	itip_view_clear_lower_info_items (ITIP_VIEW (pitip->view));
+	itip_view_clear_lower_info_items (view);
 
 	switch (pitip->update_item_response) {
 	case ITIP_VIEW_RESPONSE_ACCEPT:
-		itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO,
-						      _("Sent to calendar '%s' as accepted"), e_source_peek_name (source));
+		itip_view_add_lower_info_item_printf (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+			_("Sent to calendar '%s' as accepted"), e_source_peek_name (source));
 		break;
 	case ITIP_VIEW_RESPONSE_TENTATIVE:
-		itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO,
-						      _("Sent to calendar '%s' as tentative"), e_source_peek_name (source));
+		itip_view_add_lower_info_item_printf (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+			_("Sent to calendar '%s' as tentative"), e_source_peek_name (source));
 		break;
 	case ITIP_VIEW_RESPONSE_DECLINE:
 		/* FIXME some calendars just might not save it at all, is this accurate? */
-		itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO,
-						      _("Sent to calendar '%s' as declined"), e_source_peek_name (source));
+		itip_view_add_lower_info_item_printf (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+			_("Sent to calendar '%s' as declined"), e_source_peek_name (source));
 		break;
 	case ITIP_VIEW_RESPONSE_CANCEL:
 		/* FIXME some calendars just might not save it at all, is this accurate? */
-		itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO,
-						      _("Sent to calendar '%s' as canceled"), e_source_peek_name (source));
+		itip_view_add_lower_info_item_printf (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                        _("Sent to calendar '%s' as canceled"), e_source_peek_name (source));
 		break;
 	default:
 		g_assert_not_reached ();
@@ -1526,7 +1550,7 @@ receive_objects_ready_cb (GObject *ecalclient,
 		if (mi) {
 			changes = camel_folder_change_info_new ();
 
-			if (itip_view_get_recur_check_state (ITIP_VIEW (pitip->view))) {
+			if (itip_view_get_recur_check_state (view)) {
 				/* Recurring appointment and "apply-to-all" is selected */
 				tag = camel_message_info_user_tag (mi, "recurrence-key");
 				if (tag) {
@@ -1563,11 +1587,12 @@ receive_objects_ready_cb (GObject *ecalclient,
 		}
 	}
 
-	finish_message_delete_with_rsvp (pitip, client);
+	finish_message_delete_with_rsvp (pitip, view, client);
 }
 
 static void
-update_item (struct _itip_puri *pitip,
+update_item (ItipPURI *pitip,
+             ItipView *view,
              ItipViewResponse response)
 {
 	struct icaltimetype stamp;
@@ -1576,7 +1601,7 @@ update_item (struct _itip_puri *pitip,
 	ECalComponent *clone_comp;
 	gchar *str;
 
-	update_item_progress_info (pitip, _("Saving changes to the calendar. Please wait..."));
+	update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait..."));
 
 	/* Set X-MICROSOFT-CDO-REPLYTIME to record the time at which
 	 * the user accepted/declined the request. (Outlook ignores
@@ -1598,7 +1623,7 @@ update_item (struct _itip_puri *pitip,
 	icalcomponent_add_component (pitip->top_level, clone);
 	icalcomponent_set_method (pitip->top_level, pitip->method);
 
-	if (!itip_view_get_inherit_alarm_check_state (ITIP_VIEW (pitip->view))) {
+	if (!itip_view_get_inherit_alarm_check_state (view)) {
 		icalcomponent *alarm_comp;
 		icalcompiter alarm_iter;
 
@@ -1613,13 +1638,13 @@ update_item (struct _itip_puri *pitip,
 
 	clone_comp = e_cal_component_new ();
 	if (!e_cal_component_set_icalcomponent (clone_comp, clone)) {
-		update_item_progress_info (pitip, NULL);
-		pitip->update_item_error_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view),
+		update_item_progress_info (pitip, view, NULL);
+		pitip->update_item_error_info_id = itip_view_add_lower_info_item (view,
 			ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to parse item"));
 		goto cleanup;
 	}
 
-	if (itip_view_get_keep_alarm_check_state (ITIP_VIEW (pitip->view))) {
+	if (itip_view_get_keep_alarm_check_state (view)) {
 		ECalComponent *real_comp;
 		GList *alarms, *l;
 		ECalComponentAlarm *alarm;
@@ -1702,7 +1727,12 @@ update_item (struct _itip_puri *pitip,
 
 	pitip->update_item_response = response;
 
-	e_cal_client_receive_objects (pitip->current_client, pitip->top_level, pitip->cancellable, receive_objects_ready_cb, pitip);
+	e_cal_client_receive_objects (
+                pitip->current_client,
+                pitip->top_level,
+                pitip->cancellable,
+                receive_objects_ready_cb,
+                view);
 
  cleanup:
 	icalcomponent_remove_component (pitip->top_level, clone);
@@ -1789,7 +1819,8 @@ send_comp_to_attendee (ECalComponentItipMethod method,
 }
 
 static void
-remove_delegate (struct _itip_puri *pitip,
+remove_delegate (ItipPURI *pitip,
+                 ItipView *view,
                  const gchar *delegate,
                  const gchar *delegator,
                  ECalComponent *comp)
@@ -1798,13 +1829,21 @@ remove_delegate (struct _itip_puri *pitip,
 	gchar *comment = g_strdup_printf (_("Organizer has removed the delegate %s "), itip_strip_mailto (delegate));
 
 	/* send cancellation notice to delegate */
-	status = send_comp_to_attendee (E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp, delegate, pitip->current_client, comment);
+	status = send_comp_to_attendee (
+                E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp,
+                delegate, pitip->current_client, comment);
 	if (status)
-		send_comp_to_attendee (E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp, delegator, pitip->current_client, comment);
+		send_comp_to_attendee (
+                        E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp,
+                         delegator, pitip->current_client, comment);
 	if (status) {
-		itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Sent a cancelation notice to the delegate"));
+		itip_view_add_lower_info_item (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                        _("Sent a cancelation notice to the delegate"));
 	} else
-		itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Could not send the cancelation notice to the delegate"));
+		itip_view_add_lower_info_item (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                        _("Could not send the cancelation notice to the delegate"));
 
 	g_free (comment);
 
@@ -1837,7 +1876,8 @@ modify_object_cb (GObject *ecalclient,
                   gpointer user_data)
 {
 	ECalClient *client = E_CAL_CLIENT (ecalclient);
-	struct _itip_puri *pitip = user_data;
+        ItipView *view = user_data;
+	ItipPURI *pitip = itip_view_get_puri (view);
 	GError *error = NULL;
 
 	if (!e_cal_client_modify_object_finish (client, result, &error)) {
@@ -1847,21 +1887,25 @@ modify_object_cb (GObject *ecalclient,
 			return;
 		}
 
-		update_item_progress_info (pitip, NULL);
-		pitip->update_item_error_info_id = itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view),
-			ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
-			_("Unable to update attendee. %s"), error ? error->message : _("Unknown error"));
+		update_item_progress_info (pitip, view, NULL);
+		pitip->update_item_error_info_id =
+		        itip_view_add_lower_info_item_printf (
+                                view,
+			        ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
+			        _("Unable to update attendee. %s"),
+                                error ? error->message : _("Unknown error"));
 
 		g_clear_error (&error);
 	} else {
-		update_item_progress_info (pitip, NULL);
-		itip_view_add_lower_info_item (ITIP_VIEW (pitip->view),
+		update_item_progress_info (pitip, view, NULL);
+		itip_view_add_lower_info_item (view,
 			ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Attendee status updated"));
 	}
 }
 
 static void
-update_attendee_status_icalcomp (struct _itip_puri *pitip,
+update_attendee_status_icalcomp (ItipPURI *pitip,
+                                 ItipView *view,
                                  icalcomponent *icalcomp)
 {
 	ECalComponent *comp;
@@ -1876,7 +1920,9 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 	if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
 		icalcomponent_free (icalcomp);
 
-		itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("The meeting is invalid and cannot be updated"));
+		itip_view_add_lower_info_item (
+                        view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
+                        _("The meeting is invalid and cannot be updated"));
 	} else {
 		icalcomponent *org_icalcomp;
 		const gchar *delegate;
@@ -1887,12 +1933,13 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 		if (attendees != NULL) {
 			ECalComponentAttendee *a = attendees->data;
 			icalproperty *prop, *del_prop;
+                        EShell *shell = e_shell_get_default ();
 
 			prop = find_attendee (icalcomp, itip_strip_mailto (a->value));
 			if ((a->status == ICAL_PARTSTAT_DELEGATED) && (del_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->delto))) && !(find_attendee (icalcomp, itip_strip_mailto (a->delto)))) {
 				gint response;
 				delegate = icalproperty_get_attendee (del_prop);
-				response = e_alert_run_dialog_for_args (GTK_WINDOW (gtk_widget_get_toplevel (pitip->view)),
+				response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell),
 									"org.gnome.itip-formatter:add-delegate",
 									itip_strip_mailto (a->value),
 									itip_strip_mailto (delegate), NULL);
@@ -1900,7 +1947,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 					icalcomponent_add_property (icalcomp, icalproperty_new_clone (del_prop));
 					e_cal_component_rescan (comp);
 				} else if (response == GTK_RESPONSE_NO) {
-					remove_delegate (pitip, delegate, itip_strip_mailto (a->value), comp);
+					remove_delegate (pitip, view, delegate, itip_strip_mailto (a->value), comp);
 					goto cleanup;
 				} else {
 					goto cleanup;
@@ -1911,7 +1958,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 				gint response;
 
 				if (a->delfrom && *a->delfrom) {
-					response = e_alert_run_dialog_for_args (GTK_WINDOW (gtk_widget_get_toplevel (pitip->view)),
+					response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell),
 										"org.gnome.itip-formatter:add-delegate",
 										itip_strip_mailto (a->delfrom),
 										itip_strip_mailto (a->value), NULL);
@@ -1922,6 +1969,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 						e_cal_component_rescan (comp);
 					} else if (response == GTK_RESPONSE_NO) {
 						remove_delegate (pitip,
+                                                                 view,
 								 itip_strip_mailto (a->value),
 								 itip_strip_mailto (a->delfrom),
 								 comp);
@@ -1931,7 +1979,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 					}
 				}
 
-				response = e_alert_run_dialog_for_args (GTK_WINDOW (gtk_widget_get_toplevel (pitip->view)),
+				response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell),
 									"org.gnome.itip-formatter:add-unknown-attendee", NULL);
 
 				if (response == GTK_RESPONSE_YES) {
@@ -1941,8 +1989,9 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 					goto cleanup;
 				}
 			} else if (a->status == ICAL_PARTSTAT_NONE || a->status == ICAL_PARTSTAT_X) {
-				itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
-							       _("Attendee status could not be updated because the status is invalid"));
+				itip_view_add_lower_info_item (
+                                        view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
+					_("Attendee status could not be updated because the status is invalid"));
 				goto cleanup;
 			} else {
 				if (a->status == ICAL_PARTSTAT_DELEGATED) {
@@ -1964,14 +2013,19 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip,
 
 	update_x (pitip->comp, comp);
 
-	if (itip_view_get_update (ITIP_VIEW (pitip->view))) {
+	if (itip_view_get_update (view)) {
 		e_cal_component_commit_sequence (comp);
 		itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_client, NULL, NULL, NULL, TRUE, FALSE);
 	}
 
-	update_item_progress_info (pitip, _("Saving changes to the calendar. Please wait..."));
+	update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait..."));
 
-	e_cal_client_modify_object (pitip->current_client, icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL, pitip->cancellable, modify_object_cb, pitip);
+	e_cal_client_modify_object (
+                pitip->current_client,
+                icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL,
+                pitip->cancellable,
+                modify_object_cb,
+                view);
 
  cleanup:
 	g_object_unref (comp);
@@ -1983,7 +2037,8 @@ update_attendee_status_get_object_without_rid_cb (GObject *ecalclient,
                                                   gpointer user_data)
 {
 	ECalClient *client = E_CAL_CLIENT (ecalclient);
-	struct _itip_puri *pitip = user_data;
+        ItipView *view = user_data;
+	ItipPURI *pitip = itip_view_get_puri (view);
 	icalcomponent *icalcomp = NULL;
 	GError *error = NULL;
 
@@ -1996,14 +2051,15 @@ update_attendee_status_get_object_without_rid_cb (GObject *ecalclient,
 
 		g_clear_error (&error);
 
-		update_item_progress_info (pitip, NULL);
-		pitip->update_item_error_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view),
+		update_item_progress_info (pitip, view, NULL);
+		pitip->update_item_error_info_id = itip_view_add_lower_info_item (
+                        view,
 			ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
 			_("Attendee status can not be updated because the item no longer exists"));
 		return;
 	}
 
-	update_attendee_status_icalcomp (pitip, icalcomp);
+	update_attendee_status_icalcomp (pitip, view, icalcomp);
 }
 
 static void
@@ -2012,7 +2068,8 @@ update_attendee_status_get_object_with_rid_cb (GObject *ecalclient,
                                                gpointer user_data)
 {
 	ECalClient *client = E_CAL_CLIENT (ecalclient);
-	struct _itip_puri *pitip = user_data;
+        ItipView *view = user_data;
+	ItipPURI *pitip = itip_view_get_puri (view);
 	icalcomponent *icalcomp = NULL;
 	GError *error = NULL;
 
@@ -2034,24 +2091,32 @@ update_attendee_status_get_object_with_rid_cb (GObject *ecalclient,
 		if (!rid || !*rid) {
 			g_free (rid);
 
-			update_item_progress_info (pitip, NULL);
-			pitip->update_item_error_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view),
+			update_item_progress_info (pitip, view, NULL);
+			pitip->update_item_error_info_id = itip_view_add_lower_info_item (
+                                view,
 				ITIP_VIEW_INFO_ITEM_TYPE_WARNING,
 				_("Attendee status can not be updated because the item no longer exists"));
 			return;
 		}
 
-		e_cal_client_get_object (pitip->current_client, uid, NULL, pitip->cancellable, update_attendee_status_get_object_without_rid_cb, pitip);
+		e_cal_client_get_object (
+                        pitip->current_client,
+                        uid,
+                        NULL,
+                        pitip->cancellable,
+                        update_attendee_status_get_object_without_rid_cb,
+                        view);
 
 		g_free (rid);
 		return;
 	}
 
-	update_attendee_status_icalcomp (pitip, icalcomp);
+	update_attendee_status_icalcomp (pitip, view, icalcomp);
 }
 
 static void
-update_attendee_status (struct _itip_puri *pitip)
+update_attendee_status (ItipPURI *pitip,
+                        ItipView *view)
 {
 	const gchar *uid = NULL;
 	gchar *rid;
@@ -2060,16 +2125,22 @@ update_attendee_status (struct _itip_puri *pitip)
 	e_cal_component_get_uid (pitip->comp, &uid);
 	rid = e_cal_component_get_recurid_as_string (pitip->comp);
 
-	update_item_progress_info (pitip, _("Saving changes to the calendar. Please wait..."));
+	update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait..."));
 
 	/* search for a master object if the detached object doesn't exist in the calendar */
-	e_cal_client_get_object (pitip->current_client, uid, rid, pitip->cancellable, update_attendee_status_get_object_with_rid_cb, pitip);
+	e_cal_client_get_object (
+                pitip->current_client,
+                uid, rid,
+                pitip->cancellable,
+                update_attendee_status_get_object_with_rid_cb,
+                view);
 
 	g_free (rid);
 }
 
 static void
-send_item (struct _itip_puri *pitip)
+send_item (ItipPURI *pitip,
+           ItipView *view)
 {
 	ECalComponent *comp;
 
@@ -2081,13 +2152,19 @@ send_item (struct _itip_puri *pitip)
 
 		switch (pitip->type) {
 		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-			itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Meeting information sent"));
+			itip_view_add_lower_info_item (
+                                view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                                _("Meeting information sent"));
 			break;
 		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-			itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Task information sent"));
+			itip_view_add_lower_info_item (
+                                view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                                _("Task information sent"));
 			break;
 		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-			itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Memo information sent"));
+			itip_view_add_lower_info_item (
+                                view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
+                                _("Memo information sent"));
 			break;
 		default:
 			g_assert_not_reached ();
@@ -2096,13 +2173,19 @@ send_item (struct _itip_puri *pitip)
 	} else {
 		switch (pitip->type) {
 		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-			itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to send meeting information, the meeting does not exist"));
+			itip_view_add_lower_info_item (
+			        view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
+                                _("Unable to send meeting information, the meeting does not exist"));
 			break;
 		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-			itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to send task information, the task does not exist"));
+			itip_view_add_lower_info_item (
+                                view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
+                                _("Unable to send task information, the task does not exist"));
 			break;
 		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-			itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to send memo information, the memo does not exist"));
+			itip_view_add_lower_info_item (
+                                view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
+                                _("Unable to send memo information, the memo does not exist"));
 			break;
 		default:
 			g_assert_not_reached ();
@@ -2153,8 +2236,7 @@ attachment_load_finish (EAttachment *attachment,
 }
 
 static void
-save_vcalendar_cb (GtkWidget *button,
-                   struct _itip_puri *pitip)
+save_vcalendar_cb (ItipPURI *pitip)
 {
 	EAttachment *attachment;
 	EShell *shell;
@@ -2185,39 +2267,29 @@ save_vcalendar_cb (GtkWidget *button,
 		attachment_load_finish, file);
 }
 
-static GtkWidget *
-set_itip_error (struct _itip_puri *pitip,
-				GtkWidget *container,
-				const gchar *primary,
-				const gchar *secondary)
+static void
+set_itip_error (ItipView *view,
+                const gchar *primary,
+		const gchar *secondary,
+                gboolean save_btn)
 {
-	GtkWidget *vbox, *label;
-	gchar *message;
-
-	vbox = gtk_vbox_new (FALSE, 12);
-	gtk_widget_show (vbox);
-
-	message = g_strdup_printf ("<b>%s</b>", primary);
-	label = gtk_label_new (NULL);
-	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-	gtk_label_set_markup (GTK_LABEL (label), message);
-	g_free (message);
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+        gchar *error;
 
-	label = gtk_label_new (secondary);
-	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+        error = g_strdup_printf (
+                "<div class=\"error\">"
+                "<p><b>%s</b></p>"
+                "<p>%s</p>",
+                primary, secondary);
 
-	gtk_container_add (GTK_CONTAINER (container), vbox);
+        itip_view_set_error (view, error, save_btn);
 
-	return vbox;
+        g_free (error);
 }
 
-static GtkWidget*
-extract_itip_data (struct _itip_puri *pitip,
-				   gboolean *have_alarms)
+static gboolean
+extract_itip_data (ItipPURI *pitip,
+                   ItipView *view,
+                   gboolean *have_alarms)
 {
 	EShell *shell;
 	EShellSettings *shell_settings;
@@ -2229,35 +2301,34 @@ extract_itip_data (struct _itip_puri *pitip,
 	icalcompiter alarm_iter;
 	ECalComponent *comp;
 	gboolean use_default_reminder;
-	GtkWidget *container;
 
 	shell = e_shell_get_default ();
 	shell_settings = e_shell_get_shell_settings (shell);
 
-	container = gtk_vbox_new (FALSE, 5);
-
 	if (!pitip->vcalendar) {
-		set_itip_error (pitip, container,
-				_("The calendar attached is not valid"),
-				_("The message claims to contain a calendar, but the calendar is not a valid iCalendar."));
+		set_itip_error (view,
+                        _("The calendar attached is not valid"),
+			_("The message claims to contain a calendar, but the calendar is not a valid iCalendar."),
+                        FALSE);
 
-		return container;
+		return FALSE;
 	}
 
 	pitip->top_level = e_cal_util_new_top_level ();
 
 	pitip->main_comp = icalparser_parse_string (pitip->vcalendar);
 	if (pitip->main_comp == NULL || !is_icalcomp_valid (pitip->main_comp)) {
-		set_itip_error (pitip, container,
-				_("The calendar attached is not valid"),
-				_("The message claims to contain a calendar, but the calendar is not a valid iCalendar."));
+		set_itip_error (view,
+                        _("The calendar attached is not valid"),
+			_("The message claims to contain a calendar, but the calendar is not a valid iCalendar."),
+                        FALSE);
 
 		if (pitip->main_comp) {
 			icalcomponent_free (pitip->main_comp);
 			pitip->main_comp = NULL;
 		}
 
-		return container;
+		return FALSE;
 	}
 
 	prop = icalcomponent_get_first_property (pitip->main_comp, ICAL_METHOD_PROPERTY);
@@ -2289,11 +2360,12 @@ extract_itip_data (struct _itip_puri *pitip,
 	}
 
 	if (pitip->ical_comp == NULL) {
-		set_itip_error (pitip, container,
-				_("The item in the calendar is not valid"),
-				_("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"));
+		set_itip_error (view,
+                        _("The item in the calendar is not valid"),
+			_("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"),
+                        FALSE);
 
-		return container;
+		return FALSE;
 	}
 
 	switch (icalcomponent_isa (pitip->ical_comp)) {
@@ -2317,10 +2389,12 @@ extract_itip_data (struct _itip_puri *pitip,
 		pitip->type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
 		break;
 	default:
-		set_itip_error (pitip, container,
-				_("The item in the calendar is not valid"),
-				_("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"));
-		return container;
+		set_itip_error (view,
+                        _("The item in the calendar is not valid"),
+			_("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"),
+                        FALSE);
+
+		return FALSE;
 	}
 
 	pitip->total = icalcomponent_count_components (pitip->main_comp, ICAL_VEVENT_COMPONENT);
@@ -2329,26 +2403,12 @@ extract_itip_data (struct _itip_puri *pitip,
 	pitip->total += icalcomponent_count_components (pitip->main_comp, ICAL_VJOURNAL_COMPONENT);
 
 	if (pitip->total > 1) {
-		GtkWidget *save, *vbox, *hbox;
-
-		vbox = set_itip_error (pitip, container,
-				_("The calendar attached contains multiple items"),
-				_("To process all of these items, the file should be saved and the calendar imported"));
-
-		g_return_val_if_fail (vbox != NULL, FALSE);
 
-		hbox = gtk_hbox_new (FALSE, 0);
+		set_itip_error (view,
+                        _("The calendar attached contains multiple items"),
+			_("To process all of these items, the file should be saved and the calendar imported"),
+                        TRUE);
 
-		save = gtk_button_new_from_stock (GTK_STOCK_SAVE);
-		gtk_container_set_border_width (GTK_CONTAINER (save), 10);
-		gtk_box_pack_start (GTK_BOX (hbox), save, FALSE, FALSE, 0);
-
-		gtk_widget_show_all (hbox);
-		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-		g_signal_connect (
-			save, "clicked",
-			G_CALLBACK (save_vcalendar_cb), pitip);
 	} if (pitip->total > 0) {
 		pitip->current = 1;
 	} else {
@@ -2427,11 +2487,12 @@ extract_itip_data (struct _itip_puri *pitip,
 		g_object_unref (pitip->comp);
 		pitip->comp = NULL;
 
-		set_itip_error (pitip, container,
-				_("The item in the calendar is not valid"),
-				_("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"));
+		set_itip_error (view,
+                        _("The item in the calendar is not valid"),
+			_("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"),
+                        FALSE);
 
-		return container;
+		return FALSE;
 	};
 
 	/* Add default reminder if the config says so */
@@ -2482,9 +2543,7 @@ extract_itip_data (struct _itip_puri *pitip,
 	find_from_address (pitip, pitip->ical_comp);
 	find_to_address (pitip, pitip->ical_comp, NULL);
 
-	gtk_widget_destroy (container);
-
-	return NULL;
+	return TRUE;
 }
 
 struct _opencal_msg {
@@ -2528,7 +2587,7 @@ static MailMsgInfo open_calendar_info = {
 static gboolean
 idle_open_cb (gpointer data)
 {
-	struct _itip_puri *pitip = data;
+	ItipPURI *pitip = data;
 	struct _opencal_msg *m;
 	gchar *start, *end;
 
@@ -2545,18 +2604,23 @@ idle_open_cb (gpointer data)
 }
 
 static void
-view_response_cb (GtkWidget *widget,
+view_response_cb (ItipView *view,
                   ItipViewResponse response,
                   gpointer data)
 {
-	struct _itip_puri *pitip = data;
+	ItipPURI *pitip = data;
 	gboolean status = FALSE;
 	icalproperty *prop;
 	ECalComponentTransparency trans;
 
+        if (response == ITIP_VIEW_RESPONSE_SAVE) {
+                save_vcalendar_cb (pitip);
+                return;
+        }
+
 	pitip->can_delete_invitation_from_cache = FALSE;
 	if (pitip->method == ICAL_METHOD_PUBLISH || pitip->method ==  ICAL_METHOD_REQUEST) {
-		if (itip_view_get_free_time_check_state (ITIP_VIEW (pitip->view)))
+		if (itip_view_get_free_time_check_state (view))
 			e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
 		else
 			e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
@@ -2572,7 +2636,7 @@ view_response_cb (GtkWidget *widget,
 
 	/* check if it is a  recur instance (no master object) and
 	 * add a property */
-	if (itip_view_get_recur_check_state (ITIP_VIEW (pitip->view))) {
+	if (itip_view_get_recur_check_state (view)) {
 		prop = icalproperty_new_x ("All");
 		icalproperty_set_x_name (prop, "X-GW-RECUR-INSTANCES-MOD-TYPE");
 		icalcomponent_add_property (pitip->ical_comp, prop);
@@ -2588,7 +2652,7 @@ view_response_cb (GtkWidget *widget,
 			if (status) {
 				e_cal_component_rescan (pitip->comp);
 				pitip->can_delete_invitation_from_cache = TRUE;
-				update_item (pitip, response);
+				update_item (pitip, view, response);
 			}
 			break;
 		case ITIP_VIEW_RESPONSE_TENTATIVE:
@@ -2597,7 +2661,7 @@ view_response_cb (GtkWidget *widget,
 			if (status) {
 				e_cal_component_rescan (pitip->comp);
 				pitip->can_delete_invitation_from_cache = TRUE;
-				update_item (pitip, response);
+				update_item (pitip, view, response);
 			}
 			break;
 		case ITIP_VIEW_RESPONSE_DECLINE:
@@ -2614,17 +2678,17 @@ view_response_cb (GtkWidget *widget,
 			if (status) {
 				e_cal_component_rescan (pitip->comp);
 				pitip->can_delete_invitation_from_cache = TRUE;
-				update_item (pitip, response);
+				update_item (pitip, view, response);
 			}
 			break;
 		case ITIP_VIEW_RESPONSE_UPDATE:
-			update_attendee_status (pitip);
+			update_attendee_status (pitip, view);
 			break;
 		case ITIP_VIEW_RESPONSE_CANCEL:
-			update_item (pitip, response);
+			update_item (pitip, view, response);
 			break;
 		case ITIP_VIEW_RESPONSE_REFRESH:
-			send_item (pitip);
+			send_item (pitip, view);
 			break;
 		case ITIP_VIEW_RESPONSE_OPEN:
 			g_idle_add (idle_open_cb, pitip);
@@ -2698,337 +2762,335 @@ in_proper_folder (CamelFolder *folder)
 	return res;
 }
 
-static GtkWidget*
-create_itip_widget (EMFormat *emf,
-                    EMFormatPURI *puri,
-                    GCancellable *cancellable)
+static void
+init_itip_view (ItipPURI *info,
+                ItipView *view,
+                GString *buffer)
 {
-	EShell *shell;
-	EShellSettings *shell_settings;
-	struct _itip_puri *info;
-	ECalComponentText text;
-	ECalComponentOrganizer organizer;
-	ECalComponentDateTime datetime;
-	icaltimezone *from_zone, *to_zone;
-	GString *gstring = NULL;
-	GSList *list, *l;
-	icalcomponent *icalcomp;
-	const gchar *string, *org;
-	gint i;
-	gboolean response_enabled;
-	gboolean have_alarms = FALSE;
-	GtkWidget *err_widget;
-	EMFormatHTML *efh = (EMFormatHTML *) emf;
-
-	shell = e_shell_get_default ();
-	shell_settings = e_shell_get_shell_settings (shell);
-
-	info = (struct _itip_puri *) puri;
-
-	/* Accounts */
-	info->accounts = e_get_account_list ();
-
-	/* Source Lists and open ecal clients */
-	for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) {
-		if (!e_cal_client_get_sources (&info->source_lists[i], i, NULL))
-			/* FIXME More error handling? */
-			info->source_lists[i] = NULL;
-
-		/* Initialize the ecal hashes */
-		info->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-	}
-
-	/* FIXME Handle multiple VEVENTS with the same UID, ie detached instances */
-	if ((err_widget = extract_itip_data (info, &have_alarms)) != NULL)
-		return err_widget;
-
-	info->view = itip_view_new ();
-	gtk_widget_show (info->view);
-
-	response_enabled = in_proper_folder (((EMFormat *) efh)->folder);
-
-	if (!response_enabled) {
-		itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_HIDE_ALL);
-	} else {
-		itip_view_set_show_inherit_alarm_check (ITIP_VIEW (info->view), have_alarms && (info->method == ICAL_METHOD_PUBLISH || info->method ==  ICAL_METHOD_REQUEST));
-
-		switch (info->method) {
-		case ICAL_METHOD_PUBLISH:
-		case ICAL_METHOD_REQUEST:
-			/*
-			 * Treat meeting request (sent by organizer directly) and
-			 * published evend (forwarded by organizer or attendee) alike:
-			 * if the event has an organizer, then it can be replied to and
-			 * we show the "accept/tentative/decline" choice.
-			 * Otherwise only show "accept".
-			 */
-			itip_view_set_mode (ITIP_VIEW (info->view),
-					    info->has_organizer ?
-					    ITIP_VIEW_MODE_REQUEST :
-					    ITIP_VIEW_MODE_PUBLISH);
-			break;
-		case ICAL_METHOD_REPLY:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REPLY);
-			break;
-		case ICAL_METHOD_ADD:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_ADD);
-			break;
-		case ICAL_METHOD_CANCEL:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_CANCEL);
-			break;
-		case ICAL_METHOD_REFRESH:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REFRESH);
-			break;
-		case ICAL_METHOD_COUNTER:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_COUNTER);
-			break;
-		case ICAL_METHOD_DECLINECOUNTER:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_DECLINECOUNTER);
-			break;
-		case ICAL_METHOD_X :
-			/* Handle appointment requests from Microsoft Live. This is
-			 * a best-at-hand-now handling. Must be revisited when we have
-			 * better access to the source of such meetings */
-			info->method = ICAL_METHOD_REQUEST;
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REQUEST);
-			break;
-		default:
-			return NULL;
-		}
-	}
-
-	itip_view_set_item_type (ITIP_VIEW (info->view), info->type);
-
-	if (response_enabled) {
-		switch (info->method) {
-		case ICAL_METHOD_REQUEST:
-			/* FIXME What about the name? */
-			itip_view_set_delegator (ITIP_VIEW (info->view), info->delegator_name ? info->delegator_name : info->delegator_address);
-		case ICAL_METHOD_PUBLISH:
-		case ICAL_METHOD_ADD:
-		case ICAL_METHOD_CANCEL:
-		case ICAL_METHOD_DECLINECOUNTER:
-			itip_view_set_show_update (ITIP_VIEW (info->view), FALSE);
-
-			/* An organizer sent this */
-			e_cal_component_get_organizer (info->comp, &organizer);
-			org = organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value);
-
-			itip_view_set_organizer (ITIP_VIEW (info->view), org);
-			if (organizer.sentby)
-				itip_view_set_organizer_sentby (ITIP_VIEW (info->view), itip_strip_mailto (organizer.sentby));
-
-			if (info->my_address) {
-				if (!(organizer.value && !g_ascii_strcasecmp (itip_strip_mailto (organizer.value), info->my_address))
-				&& !(organizer.sentby && !g_ascii_strcasecmp (itip_strip_mailto (organizer.sentby), info->my_address))
-				&& (info->to_address && g_ascii_strcasecmp (info->to_address, info->my_address)))
-					itip_view_set_proxy (ITIP_VIEW (info->view), info->to_name ? info->to_name : info->to_address);
-			}
-			break;
-		case ICAL_METHOD_REPLY:
-		case ICAL_METHOD_REFRESH:
-		case ICAL_METHOD_COUNTER:
-			itip_view_set_show_update (ITIP_VIEW (info->view), TRUE);
-
-			/* An attendee sent this */
-			e_cal_component_get_attendee_list (info->comp, &list);
-			if (list != NULL) {
-				ECalComponentAttendee *attendee;
-
-				attendee = list->data;
-
-				itip_view_set_attendee (ITIP_VIEW (info->view), attendee->cn ? attendee->cn : itip_strip_mailto (attendee->value));
-
-				if (attendee->sentby)
-					itip_view_set_attendee_sentby (ITIP_VIEW (info->view), itip_strip_mailto (attendee->sentby));
-
-				if (info->my_address) {
-					if (!(attendee->value && !g_ascii_strcasecmp (itip_strip_mailto (attendee->value), info->my_address))
-					&& !(attendee->sentby && !g_ascii_strcasecmp (itip_strip_mailto (attendee->sentby), info->my_address))
-					&& (info->from_address && g_ascii_strcasecmp (info->from_address, info->my_address)))
-						itip_view_set_proxy (ITIP_VIEW (info->view), info->from_name ? info->from_name : info->from_address);
-				}
-
-				e_cal_component_free_attendee_list (list);
-			}
-			break;
-		default:
-			g_assert_not_reached ();
-			break;
-		}
-	}
-
-	e_cal_component_get_summary (info->comp, &text);
-	itip_view_set_summary (ITIP_VIEW (info->view), text.value ? text.value : C_("cal-itip", "None"));
-
-	e_cal_component_get_location (info->comp, &string);
-	itip_view_set_location (ITIP_VIEW (info->view), string);
-
-	/* Status really only applies for REPLY */
-	if (response_enabled && info->method == ICAL_METHOD_REPLY) {
-		e_cal_component_get_attendee_list (info->comp, &list);
-		if (list != NULL) {
-			ECalComponentAttendee *a = list->data;
-
-			switch (a->status) {
-			case ICAL_PARTSTAT_ACCEPTED:
-				itip_view_set_status (ITIP_VIEW (info->view), _("Accepted"));
-				break;
-			case ICAL_PARTSTAT_TENTATIVE:
-				itip_view_set_status (ITIP_VIEW (info->view), _("Tentatively Accepted"));
-				break;
-			case ICAL_PARTSTAT_DECLINED:
-				itip_view_set_status (ITIP_VIEW (info->view), _("Declined"));
-				break;
-			case ICAL_PARTSTAT_DELEGATED:
-				itip_view_set_status (ITIP_VIEW (info->view), _("Delegated"));
-				break;
-			default:
-				itip_view_set_status (ITIP_VIEW (info->view), _("Unknown"));
-			}
-		}
-		e_cal_component_free_attendee_list (list);
-	}
-
-	if (info->method == ICAL_METHOD_REPLY
-	    || info->method == ICAL_METHOD_COUNTER
-	    || info->method == ICAL_METHOD_DECLINECOUNTER) {
-		/* FIXME Check spec to see if multiple comments are actually valid */
-		/* Comments for iTIP are limited to one per object */
-		e_cal_component_get_comment_list (info->comp, &list);
-		if (list) {
-			ECalComponentText *text = list->data;
-
-			if (text->value)
-				itip_view_set_comment (ITIP_VIEW (info->view), text->value);
-		}
-		e_cal_component_free_text_list (list);
-	}
-
-	e_cal_component_get_description_list (info->comp, &list);
-	for (l = list; l; l = l->next) {
-		ECalComponentText *text = l->data;
-
-		if (!gstring && text->value)
-			gstring = g_string_new (text->value);
-		else if (text->value)
-			g_string_append_printf (gstring, "\n\n%s", text->value);
-	}
-	e_cal_component_free_text_list (list);
-
-	if (gstring) {
-		itip_view_set_description (ITIP_VIEW (info->view), gstring->str);
-		g_string_free (gstring, TRUE);
-	}
-
-	to_zone = e_shell_settings_get_pointer (shell_settings, "cal-timezone");
-
-	e_cal_component_get_dtstart (info->comp, &datetime);
-	info->start_time = 0;
-	if (datetime.value) {
-		struct tm start_tm;
-
-		/* If the timezone is not in the component, guess the local time */
-		/* Should we guess if the timezone is an olsen name somehow? */
-		if (datetime.value->is_utc)
-			from_zone = icaltimezone_get_utc_timezone ();
-		else if (!datetime.value->is_utc && datetime.tzid)
-			from_zone = icalcomponent_get_timezone (info->top_level, datetime.tzid);
-		else
-			from_zone = NULL;
-
-		start_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone);
-
-		itip_view_set_start (ITIP_VIEW (info->view), &start_tm, datetime.value->is_date);
-		info->start_time = icaltime_as_timet_with_zone (*datetime.value, from_zone);
-	}
-
-	icalcomp = e_cal_component_get_icalcomponent (info->comp);
-
-	/* Set the recurrence id */
-	if (check_is_instance (icalcomp) && datetime.value) {
-		ECalComponentRange *recur_id;
-		struct icaltimetype icaltime = icaltime_convert_to_zone (*datetime.value, to_zone);
-
-		recur_id = g_new0 (ECalComponentRange, 1);
-		recur_id->type = E_CAL_COMPONENT_RANGE_SINGLE;
-		recur_id->datetime.value = &icaltime;
-		recur_id->datetime.tzid = icaltimezone_get_tzid (to_zone);
-		e_cal_component_set_recurid (info->comp, recur_id);
-		g_free (recur_id); /* it's ok to call g_free here */
-	}
-	e_cal_component_free_datetime (&datetime);
-
-	e_cal_component_get_dtend (info->comp, &datetime);
-	info->end_time = 0;
-	if (datetime.value) {
-		struct tm end_tm;
-
-		/* If the timezone is not in the component, guess the local time */
-		/* Should we guess if the timezone is an olsen name somehow? */
-		if (datetime.value->is_utc)
-			from_zone = icaltimezone_get_utc_timezone ();
-		else if (!datetime.value->is_utc && datetime.tzid)
-			from_zone = icalcomponent_get_timezone (info->top_level, datetime.tzid);
-		else
-			from_zone = NULL;
-
-		if (datetime.value->is_date) {
-			/* RFC says the DTEND is not inclusive, thus subtract one day
-			 * if we have a date */
-
-			icaltime_adjust (datetime.value, -1, 0, 0, 0);
-		}
-
-		end_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone);
-
-		itip_view_set_end (ITIP_VIEW (info->view), &end_tm, datetime.value->is_date);
-		info->end_time = icaltime_as_timet_with_zone (*datetime.value, from_zone);
-	}
-	e_cal_component_free_datetime (&datetime);
-
-	/* Recurrence info */
-	/* FIXME Better recurring description */
-	if (e_cal_component_has_recurrences (info->comp)) {
-		/* FIXME Tell the user we don't support recurring tasks */
-		switch (info->type) {
-		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-			itip_view_add_upper_info_item (ITIP_VIEW (info->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This meeting recurs"));
-			break;
-		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-			itip_view_add_upper_info_item (ITIP_VIEW (info->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This task recurs"));
-			break;
-		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-			itip_view_add_upper_info_item (ITIP_VIEW (info->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This memo recurs"));
-			break;
-		default:
-			g_assert_not_reached ();
-			break;
-		}
-	}
-
-	if (response_enabled) {
-		g_signal_connect (
-			info->view, "response",
-			G_CALLBACK (view_response_cb), info);
-
-		itip_view_set_show_free_time_check (ITIP_VIEW (info->view), info->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS && (info->method == ICAL_METHOD_PUBLISH || info->method ==  ICAL_METHOD_REQUEST));
-
-		if (info->calendar_uid) {
-			start_calendar_server_by_uid (info, info->calendar_uid, info->type);
-		} else {
-			find_server (info, info->comp);
-			set_buttons_sensitive (info);
-		}
-	}
-
-	return info->view;
+        EShell *shell;
+        EShellSettings *shell_settings;
+        ECalComponentText text;
+        ECalComponentOrganizer organizer;
+        ECalComponentDateTime datetime;
+        icaltimezone *from_zone, *to_zone;
+        GString *gstring = NULL;
+        GSList *list, *l;
+        icalcomponent *icalcomp;
+        const gchar *string, *org;
+        gint i;
+        gboolean response_enabled;
+        gboolean have_alarms = FALSE;
+        EMFormat *emf = info->puri.emf;
+
+        shell = e_shell_get_default ();
+        shell_settings = e_shell_get_shell_settings (shell);
+
+        /* Reset current client before initializing view */
+        info->current_client = NULL;
+
+        /* Accounts */
+        info->accounts = e_get_account_list ();
+
+        /* Source Lists and open ecal clients */
+        for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) {
+                if (!e_cal_client_get_sources (&info->source_lists[i], i, NULL))
+                        /* FIXME More error handling? */
+                        info->source_lists[i] = NULL;
+
+                /* Initialize the ecal hashes */
+                info->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+        }
+
+        /* FIXME Handle multiple VEVENTS with the same UID, ie detached instances */
+        if (!extract_itip_data (info, view, &have_alarms))
+                return;
+
+        response_enabled = in_proper_folder (emf->folder);
+
+        if (!response_enabled) {
+                itip_view_set_mode (view, ITIP_VIEW_MODE_HIDE_ALL);
+        } else {
+                itip_view_set_show_inherit_alarm_check (
+                        view,
+                        have_alarms && (info->method == ICAL_METHOD_PUBLISH || info->method ==  ICAL_METHOD_REQUEST));
+
+                switch (info->method) {
+                        case ICAL_METHOD_PUBLISH:
+                        case ICAL_METHOD_REQUEST:
+                                /*
+                                 * Treat meeting request (sent by organizer directly) and
+                                 * published evend (forwarded by organizer or attendee) alike:
+                                 * if the event has an organizer, then it can be replied to and
+                                 * we show the "accept/tentative/decline" choice.
+                                 * Otherwise only show "accept".
+                                 */
+                                itip_view_set_mode (view,
+                                                    info->has_organizer ?
+                                                    ITIP_VIEW_MODE_REQUEST :
+                                                    ITIP_VIEW_MODE_PUBLISH);
+                                break;
+                        case ICAL_METHOD_REPLY:
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_REPLY);
+                                break;
+                        case ICAL_METHOD_ADD:
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_ADD);
+                                break;
+                        case ICAL_METHOD_CANCEL:
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_CANCEL);
+                                break;
+                        case ICAL_METHOD_REFRESH:
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_REFRESH);
+                                break;
+                        case ICAL_METHOD_COUNTER:
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_COUNTER);
+                                break;
+                        case ICAL_METHOD_DECLINECOUNTER:
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_DECLINECOUNTER);
+                                break;
+                        case ICAL_METHOD_X :
+                                /* Handle appointment requests from Microsoft Live. This is
+                                 * a best-at-hand-now handling. Must be revisited when we have
+                                 * better access to the source of such meetings */
+                                info->method = ICAL_METHOD_REQUEST;
+                                itip_view_set_mode (view, ITIP_VIEW_MODE_REQUEST);
+                                break;
+                        default:
+                                return;
+                }
+        }
+
+        itip_view_set_item_type (view, info->type);
+
+        if (response_enabled) {
+                switch (info->method) {
+                        case ICAL_METHOD_REQUEST:
+                                /* FIXME What about the name? */
+                                itip_view_set_delegator (view, info->delegator_name ? info->delegator_name : info->delegator_address);
+                        case ICAL_METHOD_PUBLISH:
+                        case ICAL_METHOD_ADD:
+                        case ICAL_METHOD_CANCEL:
+                        case ICAL_METHOD_DECLINECOUNTER:
+                                itip_view_set_show_update_check (view, FALSE);
+
+                                /* An organizer sent this */
+                                e_cal_component_get_organizer (info->comp, &organizer);
+                                org = organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value);
+
+                                itip_view_set_organizer (view, org);
+                                if (organizer.sentby)
+                                        itip_view_set_organizer_sentby (
+                                                view, itip_strip_mailto (organizer.sentby));
+
+                                        if (info->my_address) {
+                                                if (!(organizer.value && !g_ascii_strcasecmp (itip_strip_mailto (organizer.value), info->my_address))
+                                                        && !(organizer.sentby && !g_ascii_strcasecmp (itip_strip_mailto (organizer.sentby), info->my_address))
+                                                        && (info->to_address && g_ascii_strcasecmp (info->to_address, info->my_address)))
+                                                        itip_view_set_proxy (view, info->to_name ? info->to_name : info->to_address);
+                                        }
+                                        break;
+                        case ICAL_METHOD_REPLY:
+                        case ICAL_METHOD_REFRESH:
+                        case ICAL_METHOD_COUNTER:
+                                itip_view_set_show_update_check (view, TRUE);
+
+                                /* An attendee sent this */
+                                e_cal_component_get_attendee_list (info->comp, &list);
+                                if (list != NULL) {
+                                        ECalComponentAttendee *attendee;
+
+                                        attendee = list->data;
+
+                                        itip_view_set_attendee (view, attendee->cn ? attendee->cn : itip_strip_mailto (attendee->value));
+
+                                        if (attendee->sentby)
+                                                itip_view_set_attendee_sentby (view, itip_strip_mailto (attendee->sentby));
+
+                                        if (info->my_address) {
+                                                if (!(attendee->value && !g_ascii_strcasecmp (itip_strip_mailto (attendee->value), info->my_address))
+                                                        && !(attendee->sentby && !g_ascii_strcasecmp (itip_strip_mailto (attendee->sentby), info->my_address))
+                                                        && (info->from_address && g_ascii_strcasecmp (info->from_address, info->my_address)))
+                                                        itip_view_set_proxy (view, info->from_name ? info->from_name : info->from_address);
+                                        }
+
+                                        e_cal_component_free_attendee_list (list);
+                                }
+                                break;
+                        default:
+                                g_assert_not_reached ();
+                                break;
+                }
+        }
+
+        e_cal_component_get_summary (info->comp, &text);
+        itip_view_set_summary (view, text.value ? text.value : C_("cal-itip", "None"));
+
+        e_cal_component_get_location (info->comp, &string);
+        itip_view_set_location (view, string);
+
+        /* Status really only applies for REPLY */
+        if (response_enabled && info->method == ICAL_METHOD_REPLY) {
+                e_cal_component_get_attendee_list (info->comp, &list);
+                if (list != NULL) {
+                        ECalComponentAttendee *a = list->data;
+
+                        switch (a->status) {
+                                case ICAL_PARTSTAT_ACCEPTED:
+                                        itip_view_set_status (view, _("Accepted"));
+                                        break;
+                                case ICAL_PARTSTAT_TENTATIVE:
+                                        itip_view_set_status (view, _("Tentatively Accepted"));
+                                        break;
+                                case ICAL_PARTSTAT_DECLINED:
+                                        itip_view_set_status (view, _("Declined"));
+                                        break;
+                                case ICAL_PARTSTAT_DELEGATED:
+                                        itip_view_set_status (view, _("Delegated"));
+                                        break;
+                                default:
+                                        itip_view_set_status (view, _("Unknown"));
+                        }
+                }
+                e_cal_component_free_attendee_list (list);
+        }
+
+        if (info->method == ICAL_METHOD_REPLY
+                || info->method == ICAL_METHOD_COUNTER
+                || info->method == ICAL_METHOD_DECLINECOUNTER) {
+                /* FIXME Check spec to see if multiple comments are actually valid */
+                /* Comments for iTIP are limited to one per object */
+                e_cal_component_get_comment_list (info->comp, &list);
+                if (list) {
+                        ECalComponentText *text = list->data;
+
+                        if (text->value)
+                                itip_view_set_comment (view, text->value);
+                }
+                e_cal_component_free_text_list (list);
+        }
+
+        e_cal_component_get_description_list (info->comp, &list);
+        for (l = list; l; l = l->next) {
+                ECalComponentText *text = l->data;
+
+                if (!gstring && text->value)
+                        gstring = g_string_new (text->value);
+                else if (text->value)
+                        g_string_append_printf (gstring, "\n\n%s", text->value);
+        }
+
+        e_cal_component_free_text_list (list);
+
+        if (gstring) {
+                itip_view_set_description (view, gstring->str);
+                g_string_free (gstring, TRUE);
+        }
+
+        to_zone = e_shell_settings_get_pointer (shell_settings, "cal-timezone");
+
+        e_cal_component_get_dtstart (info->comp, &datetime);
+        info->start_time = 0;
+        if (datetime.value) {
+                struct tm start_tm;
+
+                /* If the timezone is not in the component, guess the local time */
+                /* Should we guess if the timezone is an olsen name somehow? */
+                if (datetime.value->is_utc)
+                        from_zone = icaltimezone_get_utc_timezone ();
+                else if (!datetime.value->is_utc && datetime.tzid)
+                        from_zone = icalcomponent_get_timezone (info->top_level, datetime.tzid);
+                else
+                        from_zone = NULL;
+
+                start_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone);
+
+                itip_view_set_start (view, &start_tm, datetime.value->is_date);
+                info->start_time = icaltime_as_timet_with_zone (*datetime.value, from_zone);
+        }
+
+        icalcomp = e_cal_component_get_icalcomponent (info->comp);
+
+        /* Set the recurrence id */
+        if (check_is_instance (icalcomp) && datetime.value) {
+                ECalComponentRange *recur_id;
+                struct icaltimetype icaltime = icaltime_convert_to_zone (*datetime.value, to_zone);
+
+                recur_id = g_new0 (ECalComponentRange, 1);
+                recur_id->type = E_CAL_COMPONENT_RANGE_SINGLE;
+                recur_id->datetime.value = &icaltime;
+                recur_id->datetime.tzid = icaltimezone_get_tzid (to_zone);
+                e_cal_component_set_recurid (info->comp, recur_id);
+                g_free (recur_id); /* it's ok to call g_free here */
+        }
+        e_cal_component_free_datetime (&datetime);
+
+        e_cal_component_get_dtend (info->comp, &datetime);
+        info->end_time = 0;
+        if (datetime.value) {
+                struct tm end_tm;
+
+                /* If the timezone is not in the component, guess the local time */
+                /* Should we guess if the timezone is an olsen name somehow? */
+                if (datetime.value->is_utc)
+                        from_zone = icaltimezone_get_utc_timezone ();
+                else if (!datetime.value->is_utc && datetime.tzid)
+                        from_zone = icalcomponent_get_timezone (info->top_level, datetime.tzid);
+                else
+                        from_zone = NULL;
+
+                if (datetime.value->is_date) {
+                        /* RFC says the DTEND is not inclusive, thus subtract one day
+                         * if we have a date */
+
+                        icaltime_adjust (datetime.value, -1, 0, 0, 0);
+                }
+
+                end_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone);
+
+                itip_view_set_end (view, &end_tm, datetime.value->is_date);
+                info->end_time = icaltime_as_timet_with_zone (*datetime.value, from_zone);
+        }
+        e_cal_component_free_datetime (&datetime);
+
+        /* Recurrence info */
+        /* FIXME Better recurring description */
+        if (e_cal_component_has_recurrences (info->comp)) {
+                /* FIXME Tell the user we don't support recurring tasks */
+                switch (info->type) {
+                        case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
+                                itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This meeting recurs"));
+                                break;
+                        case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
+                                itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This task recurs"));
+                                break;
+                        case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
+                                itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This memo recurs"));
+                                break;
+                        default:
+                                g_assert_not_reached ();
+                                break;
+                }
+        }
+
+        if (response_enabled) {
+                g_signal_connect (
+                        view, "response",
+                        G_CALLBACK (view_response_cb), info);
+
+                itip_view_set_show_free_time_check (view, info->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS && (info->method == ICAL_METHOD_PUBLISH || info->method ==  ICAL_METHOD_REQUEST));
+
+                if (info->calendar_uid) {
+                        start_calendar_server_by_uid (info, view, info->calendar_uid, info->type);
+                } else {
+                        find_server (info, view, info->comp);
+                        set_buttons_sensitive (info, view);
+                }
+        }
 }
 
 static void
 puri_free (EMFormatPURI *puri)
 {
-	struct _itip_puri *pitip = (struct _itip_puri *) puri;
+	ItipPURI *pitip = (ItipPURI *) puri;
 	gint i;
 
 	g_cancellable_cancel (pitip->cancellable);
@@ -3084,31 +3146,75 @@ puri_free (EMFormatPURI *puri)
 }
 
 static void
-write_itip_object (EMFormat *emf,
-		   EMFormatPURI *puri,
-		   CamelStream *stream,
-		   EMFormatWriterInfo *info,
-		   GCancellable *cancellable)
+write_itip_view (EMFormat *emf,
+                 EMFormatPURI *puri,
+                 CamelStream *stream,
+                 EMFormatWriterInfo *info,
+                 GCancellable *cancellable)
 {
-	gchar *str;
+        GString *buffer;
 
-	str = g_strdup_printf (
-		"<object type=\"application/x-itip-widget\" "
-		"height=\"100\" width=\"100%%\" "
-		"data=\"%s\" id=\"%s\"></object>", puri->uri, puri->uri);
+        if (info->mode == EM_FORMAT_WRITE_MODE_RAW) {
+                buffer = g_string_sized_new (2048);
 
-	camel_stream_write_string (stream, str, cancellable, NULL);
+                itip_view_write (buffer);
 
-	g_free (str);
+        } else {
+                gchar *uri;
+
+                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);
+
+                buffer = g_string_sized_new (256);
+                g_string_append_printf (buffer,
+                        "<div class=\"part-container\" "
+                             "style=\"border: none; background: none;\">"
+                        "<iframe width=\"100%%\" height=\"auto\""
+                        " frameborder=\"0\" src=\"%s\" name=\"%s\" id=\"%s\"></iframe>"
+                        "</div>",
+                        uri, puri->uri, puri->uri);
+
+                g_free (uri);
+        }
+
+        camel_stream_write_string (stream, buffer->str, cancellable, NULL);
+
+        g_string_free (buffer, TRUE);
 }
 
+static void
+bind_itip_view (WebKitDOMElement *element,
+                EMFormatPURI *puri)
+{
+        if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
+                GString *buffer = g_string_new ("");
+                WebKitDOMDocument *document;
+                ItipView *view;
+
+                document = webkit_dom_html_iframe_element_get_content_document (
+                                WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+
+                view = itip_view_new ((ItipPURI *) puri);
+                g_object_set_data_full (G_OBJECT (element), "view", view,
+                                        (GDestroyNotify) g_object_unref);
+
+                itip_view_create_dom_bindings (view,
+                        webkit_dom_document_get_document_element (document));
+
+                init_itip_view ((ItipPURI *) puri, view, buffer);
+                g_string_free (buffer, TRUE);
+        }
+}
 
 void
 format_itip (EPlugin *ep,
              EMFormatHookTarget *target)
 {
 	GSettings *settings;
-	struct _itip_puri *puri;
+	ItipPURI *puri;
 	CamelDataWrapper *content;
 	CamelStream *stream;
 	GByteArray *byte_array;
@@ -3124,11 +3230,14 @@ format_itip (EPlugin *ep,
 
 	settings = g_settings_new ("org.gnome.evolution.plugin.itip");
 
-	puri = (struct _itip_puri *) em_format_puri_new (target->format, sizeof (struct _itip_puri), target->part, target->part_id->str);
-	puri->puri.write_func = write_itip_object;
-        puri->puri.widget_func = create_itip_widget;
+	puri = (ItipPURI *) em_format_puri_new (
+                target->format, sizeof (ItipPURI),
+                target->part, target->part_id->str);
+	puri->puri.write_func = write_itip_view;
+        puri->puri.bind_func = bind_itip_view;
 	puri->puri.free = puri_free;
 	puri->puri.is_attachment = FALSE;
+        puri->puri.mime_type = g_strdup ("text/html");
 	puri->delete_message = g_settings_get_boolean (settings, CONF_KEY_DELETE);
 	puri->has_organizer = FALSE;
 	puri->no_reply_wanted = FALSE;
diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c
index 35b08b2..b436c12 100644
--- a/plugins/itip-formatter/itip-view.c
+++ b/plugins/itip-formatter/itip-view.c
@@ -39,13 +39,19 @@
 #include <calendar/gui/itip-utils.h>
 #include "itip-view.h"
 
+#include <shell/e-shell-window.h>
+
+#include <webkit/webkit.h>
+
+#define d(x) x
+
 #define MEETING_ICON "stock_new-meeting"
 
 #define ITIP_VIEW_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), ITIP_TYPE_VIEW, ItipViewPrivate))
 
-G_DEFINE_TYPE (ItipView, itip_view, GTK_TYPE_HBOX)
+G_DEFINE_TYPE (ItipView, itip_view, G_TYPE_OBJECT)
 
 typedef struct  {
 	ItipViewInfoItemType type;
@@ -58,7 +64,6 @@ struct _ItipViewPrivate {
 	ItipViewMode mode;
 	ECalClientSourceType type;
 
-	GtkWidget *sender_label;
 	gchar *organizer;
 	gchar *organizer_sentby;
 	gchar *delegator;
@@ -66,70 +71,79 @@ struct _ItipViewPrivate {
 	gchar *attendee_sentby;
 	gchar *proxy;
 
-	GtkWidget *summary_label;
 	gchar *summary;
 
-	GtkWidget *location_header;
-	GtkWidget *location_label;
 	gchar *location;
-
-	GtkWidget *status_header;
-	GtkWidget *status_label;
-	gchar *status;
-
-	GtkWidget *comment_header;
-	GtkWidget *comment_label;
+        gchar *status;
 	gchar *comment;
 
-	GtkWidget *start_header;
-	GtkWidget *start_label;
 	struct tm *start_tm;
-	gboolean start_tm_is_date;
+	gint start_tm_is_date : 1;
 
-	GtkWidget *end_header;
-	GtkWidget *end_label;
 	struct tm *end_tm;
-	gboolean end_tm_is_date;
+	gint end_tm_is_date : 1;
 
-	GtkWidget *upper_info_box;
 	GSList *upper_info_items;
-
-	GtkWidget *lower_info_box;
 	GSList *lower_info_items;
 
 	guint next_info_item_id;
 
-	GtkWidget *description_label;
 	gchar *description;
 
-	GtkWidget *selector_box;
-	GtkWidget *escb;
-	GtkWidget *escb_header;
 	ESourceList *source_list;
 
-	GtkWidget *rsvp_box;
-	GtkWidget *rsvp_check;
-	GtkWidget *rsvp_comment_header;
-	GtkWidget *rsvp_comment_text;
-	gboolean rsvp_show;
+	gint buttons_sensitive : 1;
 
-	GtkWidget *recur_box;
-	GtkWidget *recur_check;
+        gboolean is_recur_set;
 
-	GtkWidget *update_box;
-	GtkWidget *update_check;
-	gboolean update_show;
+	gint needs_decline : 1;
 
-	GtkWidget *options_box;
-	GtkWidget *free_time_check;
-	GtkWidget *keep_alarm_check;
-	GtkWidget *inherit_alarm_check;
+        WebKitDOMDocument *dom_document;
+        ItipPURI *puri;
+};
 
-	GtkWidget *button_box;
-	gboolean buttons_sensitive;
 
-	gboolean needs_decline;
-};
+#define TEXT_ROW_SENDER "text_row_sender"
+#define TABLE_ROW_SUMMARY "table_row_summary"
+#define TABLE_ROW_LOCATION "table_row_location"
+#define TABLE_ROW_START_DATE "table_row_start_time"
+#define TABLE_ROW_END_DATE "table_row_end_time"
+#define TABLE_ROW_STATUS "table_row_status"
+#define TABLE_ROW_COMMENT "table_row_comment"
+#define TABLE_ROW_DESCRIPTION "table_row_description"
+#define TABLE_ROW_RSVP_COMMENT "table_row_rsvp_comment"
+#define TABLE_ROW_ESCB "table_row_escb"
+#define TABLE_ROW_BUTTONS "table_row_buttons"
+
+#define TABLE_BUTTONS "table_buttons"
+
+#define SELECT_ESOURCE "select_esource"
+#define TEXTAREA_RSVP_COMMENT "textarea_rsvp_comment"
+
+#define CHECKBOX_RSVP "checkbox_rsvp"
+#define CHECKBOX_RECUR "checkbox_recur"
+#define CHECKBOX_UPDATE "checkbox_update"
+#define CHECKBOX_FREE_TIME "checkbox_free_time"
+#define CHECKBOX_KEEP_ALARM "checkbox_keep_alarm"
+#define CHECKBOX_INHERIT_ALARM "checkbox_inherit_alarm"
+
+#define BUTTON_OPEN_CALENDAR "button_open_calendar"
+#define BUTTON_DECLINE "button_decline"
+#define BUTTON_DECLINE_ALL "button_decline_all"
+#define BUTTON_ACCEPT "button_accept"
+#define BUTTON_ACCEPT_ALL "button_accept_all"
+#define BUTTON_TENTATIVE "button_tentative"
+#define BUTTON_TENTATIVE_ALL "button_tentative_all"
+#define BUTTON_SEND_INFORMATION "button_send_information"
+#define BUTTON_UPDATE "button_update"
+#define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status"
+#define BUTTON_SAVE "button_save"
+
+#define TABLE_UPPER_ITIP_INFO "table_upper_itip_info"
+#define TABLE_LOWER_ITIP_INFO "table_lower_itip_info"
+
+#define DIV_ITIP_CONTENT "div_itip_content"
+#define DIV_ITIP_ERROR "div_itip_error"
 
 /* Signal IDs */
 enum {
@@ -140,6 +154,7 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+
 static void
 format_date_and_time_x (struct tm *date_tm,
                         struct tm *current_tm,
@@ -353,7 +368,7 @@ dupe_first_bold (const gchar *format,
 	return res;
 }
 
-static void
+static gchar*
 set_calendar_sender_text (ItipView *view)
 {
 	ItipViewPrivate *priv;
@@ -434,14 +449,12 @@ set_calendar_sender_text (ItipView *view)
 	if (sender && on_behalf_of)
 		sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
 
-	gtk_label_set_text (GTK_LABEL (priv->sender_label), sender);
-	gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE);
-
 	g_free (on_behalf_of);
-	g_free (sender);
+
+        return sender;
 }
 
-static void
+static gchar*
 set_tasklist_sender_text (ItipView *view)
 {
 	ItipViewPrivate *priv;
@@ -522,14 +535,12 @@ set_tasklist_sender_text (ItipView *view)
 	if (sender && on_behalf_of)
 		sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
 
-	gtk_label_set_text (GTK_LABEL (priv->sender_label), sender);
-	gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE);
+        g_free (on_behalf_of);
 
-	g_free (on_behalf_of);
-	g_free (sender);
+        return sender;
 }
 
-static void
+static gchar*
 set_journal_sender_text (ItipView *view)
 {
 	ItipViewPrivate *priv;
@@ -574,109 +585,56 @@ set_journal_sender_text (ItipView *view)
 	if (sender && on_behalf_of)
 		sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
 
-	gtk_label_set_text (GTK_LABEL (priv->sender_label), sender);
-	gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE);
-
 	g_free (on_behalf_of);
-	g_free (sender);
+
+        return sender;
 }
 
 static void
 set_sender_text (ItipView *view)
 {
 	ItipViewPrivate *priv;
+        gchar *sender = NULL;
 
 	priv = view->priv;
 
 	switch (priv->type) {
 	case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-		set_calendar_sender_text (view);
+		sender = set_calendar_sender_text (view);
 		break;
 	case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-		set_tasklist_sender_text (view);
+		sender = set_tasklist_sender_text (view);
 		break;
 	case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-		set_journal_sender_text (view);
+		sender = set_journal_sender_text (view);
 		break;
 	default:
+                sender = NULL;
 		break;
 	}
-}
-
-static void
-set_summary_text (ItipView *view)
-{
-	ItipViewPrivate *priv;
-	gchar *summary = NULL;
-
-	priv = view->priv;
-
-	summary = g_markup_printf_escaped ("<b>%s</b>", priv->summary);
-
-	gtk_label_set_text (GTK_LABEL (priv->summary_label), summary);
-	gtk_label_set_use_markup (GTK_LABEL (priv->summary_label), TRUE);
-
-	g_free (summary);
-}
-
-static void
-set_location_text (ItipView *view)
-{
-	ItipViewPrivate *priv;
-
-	priv = view->priv;
-
-	gtk_label_set_text (GTK_LABEL (priv->location_label), priv->location);
-
-	priv->location ? gtk_widget_show (priv->location_header) : gtk_widget_hide (priv->location_header);
-	priv->location ? gtk_widget_show (priv->location_label) : gtk_widget_hide (priv->location_label);
-}
-
-static void
-set_status_text (ItipView *view)
-{
-	ItipViewPrivate *priv;
-
-	priv = view->priv;
-
-	gtk_label_set_text (GTK_LABEL (priv->status_label), priv->status);
-
-	priv->status ? gtk_widget_show (priv->status_header) : gtk_widget_hide (priv->status_header);
-	priv->status ? gtk_widget_show (priv->status_label) : gtk_widget_hide (priv->status_label);
-}
-
-static void
-set_comment_text (ItipView *view)
-{
-	ItipViewPrivate *priv;
-
-	priv = view->priv;
-
-	gtk_label_set_text (GTK_LABEL (priv->comment_label), priv->comment);
-
-	priv->comment ? gtk_widget_show (priv->comment_header) : gtk_widget_hide (priv->comment_header);
-	priv->comment ? gtk_widget_show (priv->comment_label) : gtk_widget_hide (priv->comment_label);
-}
 
-static void
-set_description_text (ItipView *view)
-{
-	ItipViewPrivate *priv;
+	if (sender) {
+                WebKitDOMElement *div;
 
-	priv = view->priv;
-
-	gtk_label_set_text (GTK_LABEL (priv->description_label), priv->description);
+                div = webkit_dom_document_get_element_by_id (
+                        view->priv->dom_document, TEXT_ROW_SENDER);
+                webkit_dom_html_element_set_inner_html (
+                        WEBKIT_DOM_HTML_ELEMENT (div), sender, NULL);
 
-	priv->description ? gtk_widget_show (priv->description_label) : gtk_widget_hide (priv->description_label);
+                g_free (sender);
+        }
 }
 
 static void
 update_start_end_times (ItipView *view)
 {
 	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *col;
 	gchar buffer[256];
 	time_t now;
 	struct tm *now_tm;
+        const gchar *start_header, *end_header;
+        gchar *start_label, *end_label;
 
 	priv = view->priv;
 
@@ -688,219 +646,99 @@ update_start_end_times (ItipView *view)
 	    && is_same (tm_mday) && is_same (tm_mon) && is_same (tm_year)) {
 		/* it's an all day event in one particular day */
 		format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256);
-		gtk_label_set_text (GTK_LABEL (priv->start_label), buffer);
-		gtk_label_set_text (GTK_LABEL (priv->start_header), _("All day:"));
-
-		gtk_widget_show (priv->start_header);
-		gtk_widget_show (priv->start_label);
-		gtk_widget_hide (priv->end_header);
-		gtk_widget_hide (priv->end_label);
+                start_label = g_strdup (buffer);
+                start_header = _("All day:");
+                end_header = NULL;
+                end_label = NULL;
 	} else {
 		if (priv->start_tm) {
 			format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256);
-			gtk_label_set_text (GTK_LABEL (priv->start_label), buffer);
-			gtk_label_set_text (GTK_LABEL (priv->start_header), priv->start_tm_is_date ? _("Start day:") : _("Start time:"));
-			gtk_widget_show (priv->start_header);
-			gtk_widget_show (priv->start_label);
+                        start_header = priv->start_tm_is_date ? _("Start day:") : _("Start time:");
+                        start_label = g_strdup (buffer);
 		} else {
-			gtk_label_set_text (GTK_LABEL (priv->start_label), NULL);
-			gtk_widget_hide (priv->start_header);
-			gtk_widget_hide (priv->start_label);
+                        start_header = NULL;
+                        start_label = NULL;
 		}
 
 		if (priv->end_tm) {
 			format_date_and_time_x (priv->end_tm, now_tm, FALSE, TRUE, FALSE, priv->end_tm_is_date, buffer, 256);
-			gtk_label_set_text (GTK_LABEL (priv->end_label), buffer);
-			gtk_label_set_text (GTK_LABEL (priv->end_header), priv->end_tm_is_date ? _("End day:") : _("End time:"));
-			gtk_widget_show (priv->end_header);
-			gtk_widget_show (priv->end_label);
+                        end_header = priv->end_tm_is_date ? _("End day:") : _("End time:");
+                        end_label = g_strdup (buffer);
 		} else {
-			gtk_label_set_text (GTK_LABEL (priv->end_label), NULL);
-			gtk_widget_hide (priv->end_header);
-			gtk_widget_hide (priv->end_label);
+                        end_header = NULL;
+                        end_label = NULL;
 		}
-	}
-
+        }
 	#undef is_same
-}
 
-static void
-set_info_items (GtkWidget *info_box,
-                GSList *info_items)
-{
-	GSList *l;
+        row = webkit_dom_document_get_element_by_id (
+                priv->dom_document, TABLE_ROW_START_DATE);
+	if (start_header && start_label) {
+                webkit_dom_html_element_set_hidden (
+                        WEBKIT_DOM_HTML_ELEMENT (row), FALSE);
 
-	gtk_container_foreach (GTK_CONTAINER (info_box), (GtkCallback) gtk_widget_destroy, NULL);
+                col = webkit_dom_element_get_first_element_child (row);
+                webkit_dom_html_element_set_inner_html (
+                        WEBKIT_DOM_HTML_ELEMENT (col), start_header, NULL);
 
-	for (l = info_items; l; l = l->next) {
-		ItipViewInfoItem *item = l->data;
-		GtkWidget *hbox, *image, *label;
-
-		hbox = gtk_hbox_new (FALSE, 0);
-
-		switch (item->type) {
-		case ITIP_VIEW_INFO_ITEM_TYPE_INFO:
-			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_SMALL_TOOLBAR);
-			break;
-		case ITIP_VIEW_INFO_ITEM_TYPE_WARNING:
-			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
-			break;
-		case ITIP_VIEW_INFO_ITEM_TYPE_ERROR:
-			image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_SMALL_TOOLBAR);
-			break;
-		case ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS:
-			image = gtk_spinner_new ();
-			gtk_spinner_start (GTK_SPINNER (image));
-			break;
-		case ITIP_VIEW_INFO_ITEM_TYPE_NONE:
-		default:
-			image = NULL;
-		}
-
-		if (image) {
-			gtk_widget_show (image);
-			gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 6);
-		}
+                col = webkit_dom_element_get_last_element_child (row);
+                webkit_dom_html_element_set_inner_html (
+                        WEBKIT_DOM_HTML_ELEMENT (col), start_label, NULL);
 
-		label = gtk_label_new (item->message);
-		gtk_label_set_selectable (GTK_LABEL (label), TRUE);
-		gtk_widget_show (label);
-		gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6);
+                g_free (start_label);
+        } else {
+                webkit_dom_html_element_set_hidden (
+                        WEBKIT_DOM_HTML_ELEMENT (row), TRUE);
+        }
 
-		gtk_widget_show (hbox);
-		gtk_box_pack_start (GTK_BOX (info_box), hbox, FALSE, FALSE, 6);
-	}
-}
-
-static void
-set_upper_info_items (ItipView *view)
-{
-	ItipViewPrivate *priv;
-
-	priv = view->priv;
-
-	set_info_items (priv->upper_info_box, priv->upper_info_items);
-}
+        row = webkit_dom_document_get_element_by_id (
+                priv->dom_document, TABLE_ROW_END_DATE);
+        if (end_header && end_label) {
+                webkit_dom_html_element_set_hidden (
+                        WEBKIT_DOM_HTML_ELEMENT (row), FALSE);
 
-static void
-set_lower_info_items (ItipView *view)
-{
-	ItipViewPrivate *priv;
+                col = webkit_dom_element_get_first_element_child (row);
+                webkit_dom_html_element_set_inner_html (
+                        WEBKIT_DOM_HTML_ELEMENT (col), end_header, NULL);
 
-	priv = view->priv;
+                col = webkit_dom_element_get_last_element_child (row);
+                webkit_dom_html_element_set_inner_html (
+                        WEBKIT_DOM_HTML_ELEMENT (col), end_label, NULL);
 
-	set_info_items (priv->lower_info_box, priv->lower_info_items);
+                g_free (end_label);
+        } else {
+                webkit_dom_html_element_set_hidden (
+                        WEBKIT_DOM_HTML_ELEMENT (row), TRUE);
+        }
 }
 
-#define DATA_RESPONSE_KEY "ItipView::button_response"
-
 static void
-button_clicked_cb (GtkWidget *widget,
+button_clicked_cb (WebKitDOMElement *element,
+                   WebKitDOMEvent *event,
                    gpointer data)
 {
 	ItipViewResponse response;
+        gchar *responseStr;
 
-	response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), DATA_RESPONSE_KEY));
-
-	g_signal_emit (G_OBJECT (data), signals[RESPONSE], 0, response);
-}
-
-static void
-set_one_button (ItipView *view,
-                const gchar *label,
-                const gchar *stock_id,
-                ItipViewResponse response)
-{
-	ItipViewPrivate *priv;
-	GtkWidget *button;
-	GtkWidget *image;
-	gpointer data;
-
-	priv = view->priv;
-
-	button = gtk_button_new_with_mnemonic (label);
-	image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
-	gtk_button_set_image (GTK_BUTTON (button), image);
-
-	data = GINT_TO_POINTER (response);
-	g_object_set_data (G_OBJECT (button), DATA_RESPONSE_KEY, data);
-
-	gtk_widget_show (button);
-	gtk_container_add (GTK_CONTAINER (priv->button_box), button);
-
-	g_signal_connect (
-		button, "clicked", G_CALLBACK (button_clicked_cb), view);
-}
-
-static void
-set_buttons (ItipView *view)
-{
-	ItipViewPrivate *priv;
-	gboolean is_recur_set = FALSE;
-
-	priv = view->priv;
-
-	is_recur_set = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->recur_check));
-	gtk_container_foreach (GTK_CONTAINER (priv->button_box), (GtkCallback) gtk_widget_destroy, NULL);
-
-	if (priv->mode == ITIP_VIEW_MODE_HIDE_ALL)
-		return;
+        responseStr = webkit_dom_html_button_element_get_value (
+                WEBKIT_DOM_HTML_BUTTON_ELEMENT (element));
 
-	/* Everything gets the open button */
-	set_one_button (view, _("_Open Calendar"), GTK_STOCK_JUMP_TO, ITIP_VIEW_RESPONSE_OPEN);
+        response = atoi(responseStr);
 
-	switch (priv->mode) {
-	case ITIP_VIEW_MODE_PUBLISH:
-		/* FIXME Is this really the right button? */
-		if (priv->needs_decline)
-			set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
-		set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
-		break;
-	case ITIP_VIEW_MODE_REQUEST:
-		set_one_button (view, is_recur_set ? _("_Decline all") : _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
-		set_one_button (view, is_recur_set ? _("_Tentative all") : _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE);
-		set_one_button (view, is_recur_set ? _("A_ccept all") : _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
-		break;
-	case ITIP_VIEW_MODE_ADD:
-		if (priv->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) {
-			set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
-			set_one_button (view, _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE);
-		}
-		set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
-		break;
-	case ITIP_VIEW_MODE_REFRESH:
-		/* FIXME Is this really the right button? */
-		set_one_button (view, _("_Send Information"), GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_REFRESH);
-		break;
-	case ITIP_VIEW_MODE_REPLY:
-		/* FIXME Is this really the right button? */
-		set_one_button (view, _("_Update Attendee Status"), GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_UPDATE);
-		break;
-	case ITIP_VIEW_MODE_CANCEL:
-		set_one_button (view, _("_Update"), GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_CANCEL);
-		break;
-	case ITIP_VIEW_MODE_COUNTER:
-		set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
-		set_one_button (view, _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE);
-		set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
-		break;
-	case ITIP_VIEW_MODE_DECLINECOUNTER:
-		set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
-		set_one_button (view, _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE);
-		set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
-		break;
-	default:
-		break;
-	}
+        //d(printf("Clicked btton %d\n", response));
+	g_signal_emit (G_OBJECT (data), signals[RESPONSE], 0, response);
 }
 
 static void
 itip_view_finalize (GObject *object)
 {
 	ItipViewPrivate *priv;
+        GSList *iter;
 
 	priv = ITIP_VIEW_GET_PRIVATE (object);
 
+        d(printf("Itip view finalized!\n"));
+
 	g_free (priv->organizer);
 	g_free (priv->organizer_sentby);
 	g_free (priv->delegator);
@@ -915,8 +753,19 @@ itip_view_finalize (GObject *object)
 	g_free (priv->end_tm);
 	g_free (priv->description);
 
-	itip_view_clear_upper_info_items (ITIP_VIEW (object));
-	itip_view_clear_lower_info_items (ITIP_VIEW (object));
+        for (iter = priv->lower_info_items; iter; iter = iter->next) {
+                ItipViewInfoItem *item = iter->data;
+                g_free (item->message);
+                g_free (item);
+        }
+        g_slist_free (priv->lower_info_items);
+
+        for (iter = priv->upper_info_items; iter; iter = iter->next) {
+                ItipViewInfoItem *item = iter->data;
+                g_free (item->message);
+                g_free (item);
+        }
+        g_slist_free (priv->upper_info_items);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (itip_view_parent_class)->finalize (object);
@@ -952,31 +801,31 @@ itip_view_class_init (ItipViewClass *class)
 }
 
 static void
-rsvp_toggled_cb (GtkWidget *widget,
+rsvp_toggled_cb (WebKitDOMHTMLInputElement *input,
+                 WebKitDOMEvent *event,
                  gpointer data)
 {
+        WebKitDOMElement *el;
+
 	ItipView *view = data;
-	ItipViewPrivate *priv;
 	gboolean rsvp;
 
-	priv = view->priv;
-
-	rsvp = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->rsvp_check));
+	rsvp = webkit_dom_html_input_element_get_checked (input);
 
-	gtk_widget_set_sensitive (priv->rsvp_comment_header, rsvp);
-	gtk_widget_set_sensitive (priv->rsvp_comment_text, rsvp);
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
+        webkit_dom_html_text_area_element_set_disabled (
+                WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp);
 }
 
 static void
-recur_toggled_cb (GtkWidget *widget,
+recur_toggled_cb (WebKitDOMHTMLInputElement *input,
+                  WebKitDOMEvent *event,
                   gpointer data)
 {
 	ItipView *view = data;
-	ItipViewPrivate *priv;
 
-	priv = view->priv;
-
-	itip_view_set_mode (view, priv->mode);
+	itip_view_set_mode (view, view->priv->mode);
 }
 
 /*
@@ -984,290 +833,592 @@ recur_toggled_cb (GtkWidget *widget,
   check1 was changed, so make the second available based on state of the first check.
 */
 static void
-alarm_check_toggled_cb (GtkWidget *check1,
-                        GtkWidget *check2)
+alarm_check_toggled_cb (WebKitDOMHTMLInputElement *check1,
+                        WebKitDOMEvent *event,
+                        ItipView *view)
 {
-	g_return_if_fail (check1 != NULL);
-	g_return_if_fail (check2 != NULL);
+        WebKitDOMElement *check2;
+        gchar *id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (check1));
+
+        if (g_strcmp0 (id, CHECKBOX_INHERIT_ALARM)) {
+                check2 = webkit_dom_document_get_element_by_id (
+                        view->priv->dom_document, CHECKBOX_KEEP_ALARM);
+        } else {
+                check2 = webkit_dom_document_get_element_by_id (
+                        view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
+        }
+
+        g_free (id);
 
-	gtk_widget_set_sensitive (check2, !(gtk_widget_get_visible (check1) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check1))));
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (check2),
+                (webkit_dom_html_element_get_hidden (
+                                WEBKIT_DOM_HTML_ELEMENT (check1)) &&
+                        webkit_dom_html_input_element_get_checked (check1)));
 }
 
 static void
-itip_view_init (ItipView *view)
+source_changed_cb (WebKitDOMElement *select,
+                   WebKitDOMEvent *event,
+                   ItipView *view)
+{
+        ESource *source;
+
+        source = itip_view_get_source (view);
+
+        d(printf("Source changed to '%s'\n", e_source_peek_name (source)));
+        g_signal_emit (view, signals[SOURCE_SELECTED], 0, source);
+}
+
+static void
+append_checkbox_table_row (GString *buffer,
+                           const gchar *name,
+                           const gchar *label)
+{
+        g_string_append_printf (
+                buffer,
+                "<tr id=\"table_row_%s\" hidden=\"\"><td colspan=\"2\">"
+                "<input type=\"checkbox\" name=\"%s\" id=\"%s\" value=\"%s\" >"
+                "<label for=\"%s\">%s</label>"
+                "</td></tr>\n",
+                name, name, name, name, name, label);
+}
+
+static void
+append_text_table_row (GString *buffer,
+                       const gchar *id,
+                       const gchar *label)
+{
+        if (label && *label) {
+
+                g_string_append_printf (buffer,
+                        "<tr id=\"%s\" hidden=\"\"><th>%s</th><td></td></tr>\n",
+                        id, label);
+
+        } else {
+
+                g_string_append_printf (
+                        buffer,
+                        "<tr id=\"%s\" hidden=\"\"><td colspan=\"2\"></td></tr>\n",
+                        id);
+
+        }
+}
+
+static void
+append_info_item_row (ItipView *view,
+                      const gchar *table_id,
+                      ItipViewInfoItem *item)
+{
+        WebKitDOMElement *table;
+        WebKitDOMHTMLElement *row, *cell;
+        const gchar *icon_name;
+        gchar *id;
+
+        table = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, table_id);
+        row = webkit_dom_html_table_element_insert_row (
+                WEBKIT_DOM_HTML_TABLE_ELEMENT (table), -1, NULL);
+
+        id = g_strdup_printf ("%s_row_%d", table_id, item->id);
+        webkit_dom_html_element_set_id (row, id);
+        g_free (id);
+
+        switch (item->type) {
+                case ITIP_VIEW_INFO_ITEM_TYPE_INFO:
+                        icon_name = GTK_STOCK_DIALOG_INFO;
+                        break;
+                case ITIP_VIEW_INFO_ITEM_TYPE_WARNING:
+                        icon_name = GTK_STOCK_DIALOG_WARNING;
+                        break;
+                case ITIP_VIEW_INFO_ITEM_TYPE_ERROR:
+                        icon_name = GTK_STOCK_DIALOG_ERROR;
+                        break;
+                case ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS:
+                        icon_name = "evolution-spinner"; /* FIXME WEBKIT */
+                        break;
+                case ITIP_VIEW_INFO_ITEM_TYPE_NONE:
+                        default:
+                        icon_name = NULL;
+        }
+
+        cell = webkit_dom_html_table_row_element_insert_cell (
+                (WebKitDOMHTMLTableRowElement *) row, -1, NULL);
+
+        if (icon_name) {
+                WebKitDOMElement *image;
+                gchar *icon_uri;
+
+                image = webkit_dom_document_create_element (
+                        view->priv->dom_document, "IMG", NULL);
+
+                icon_uri = g_strdup_printf ("gtk-stock://%s", icon_name);
+                webkit_dom_html_image_element_set_src (
+                        WEBKIT_DOM_HTML_IMAGE_ELEMENT (image), icon_uri);
+                g_free (icon_uri);
+
+                webkit_dom_node_append_child (
+                        WEBKIT_DOM_NODE (cell),
+                        WEBKIT_DOM_NODE (image),
+                        NULL);
+        }
+
+        cell = webkit_dom_html_table_row_element_insert_cell (
+                (WebKitDOMHTMLTableRowElement *) row, -1, NULL);
+
+        webkit_dom_html_element_set_inner_html (cell, item->message, NULL);
+
+        d(printf("Added row %s_row_%d ('%s')\n", table_id, item->id, item->message));
+}
+
+static void
+remove_info_item_row (ItipView *view,
+                      const gchar *table_id,
+                      guint id)
+{
+        WebKitDOMElement *row;
+        gchar *row_id;
+
+        row_id = g_strdup_printf ("%s_row_%d", table_id, id);
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, row_id);
+        g_free (row_id);
+
+        webkit_dom_node_remove_child (
+                webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row)),
+                WEBKIT_DOM_NODE (row),
+                NULL);
+
+        d(printf("Removed row %s_row_%d\n", table_id, id));
+}
+
+
+static void
+buttons_table_write_button (GString *buffer,
+                            const gchar *name,
+                            const gchar *label,
+                            const gchar *icon,
+                            ItipViewResponse response)
 {
-	GtkWidget *icon, *vbox, *hbox, *separator, *table, *label;
-	GtkWidget *scrolled_window;
-
-	view->priv = ITIP_VIEW_GET_PRIVATE (view);
-
-	view->priv->mode = ITIP_VIEW_MODE_NONE;
-
-	gtk_box_set_spacing (GTK_BOX (view), 12);
-
-	/* The meeting icon */
-	icon = gtk_image_new_from_icon_name (
-		MEETING_ICON, GTK_ICON_SIZE_LARGE_TOOLBAR);
-	gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0);
-	gtk_widget_show (icon);
-
-	gtk_box_pack_start (GTK_BOX (view), icon, FALSE, FALSE, 0);
-
-	/* The RHS */
-	vbox = gtk_vbox_new (FALSE, 12);
-	gtk_widget_show (vbox);
-	gtk_box_pack_start (GTK_BOX (view), vbox, FALSE, FALSE, 0);
-
-	/* The first section listing the sender */
-	/* FIXME What to do if the send and organizer do not match */
-	view->priv->sender_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->sender_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->sender_label), 0, 0.5);
-	gtk_widget_show (view->priv->sender_label);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->sender_label, FALSE, FALSE, 0);
-
-	separator = gtk_hseparator_new ();
-	gtk_widget_show (separator);
-	gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
-
-	/* A table with information on the meeting and any extra info/warnings */
-	table = gtk_table_new (4, 2, FALSE);
-	gtk_table_set_row_spacings (GTK_TABLE (table), 6);
-	gtk_table_set_col_spacings (GTK_TABLE (table), 6);
-	gtk_widget_show (table);
-	gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
-
-	/* Summary */
-	view->priv->summary_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->summary_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->summary_label), 0, 0.5);
-	gtk_label_set_line_wrap_mode (GTK_LABEL (view->priv->summary_label), PANGO_WRAP_WORD);
-	gtk_label_set_line_wrap (GTK_LABEL (view->priv->summary_label), TRUE);
-	gtk_widget_show (view->priv->summary_label);
-	gtk_table_attach (GTK_TABLE (table), view->priv->summary_label, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
-
-	/* Location */
-	view->priv->location_header = gtk_label_new (_("Location:"));
-	view->priv->location_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->location_header), TRUE);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->location_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->location_header), 0, 0.5);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->location_label), 0, 0.5);
-	gtk_table_attach (GTK_TABLE (table), view->priv->location_header, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
-	gtk_table_attach (GTK_TABLE (table), view->priv->location_label, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
-
-	/* Start time */
-	view->priv->start_header = gtk_label_new (_("Start time:"));
-	view->priv->start_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->start_header), TRUE);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->start_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->start_header), 0, 0.5);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->start_label), 0, 0.5);
-	gtk_widget_show (view->priv->start_header);
-	gtk_table_attach (GTK_TABLE (table), view->priv->start_header, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
-	gtk_table_attach (GTK_TABLE (table), view->priv->start_label, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
-
-	/* End time */
-	view->priv->end_header = gtk_label_new (_("End time:"));
-	view->priv->end_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->end_header), TRUE);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->end_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->end_header), 0, 0.5);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->end_label), 0, 0.5);
-	gtk_table_attach (GTK_TABLE (table), view->priv->end_header, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
-	gtk_table_attach (GTK_TABLE (table), view->priv->end_label, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 0, 0);
-
-	/* Status */
-	view->priv->status_header = gtk_label_new (_("Status:"));
-	view->priv->status_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->status_header), TRUE);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->status_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->status_header), 0, 0.5);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->status_label), 0, 0.5);
-	gtk_table_attach (GTK_TABLE (table), view->priv->status_header, 0, 1, 4, 5, GTK_FILL, 0, 0, 0);
-	gtk_table_attach (GTK_TABLE (table), view->priv->status_label, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0);
-
-	/* Comment */
-	view->priv->comment_header = gtk_label_new (_("Comment:"));
-	view->priv->comment_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->comment_header), TRUE);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->comment_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->comment_header), 0, 0.5);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->comment_label), 0, 0.5);
-	gtk_table_attach (GTK_TABLE (table), view->priv->comment_header, 0, 1, 5, 6, GTK_FILL, 0, 0, 0);
-	gtk_table_attach (GTK_TABLE (table), view->priv->comment_label, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+        g_string_append_printf (
+                buffer,
+                "<td><button type=\"button\" name=\"%s\" value=\"%d\" id=\"%s\" hidden>"
+                "<div><img src=\"gtk-stock://%s?size=%d\"> <span>%s</span></div>"
+                "</button></td>\n",
+                name, response, name, icon, GTK_ICON_SIZE_BUTTON, label);
+}
+
+static void
+append_buttons_table (GString *buffer)
+{
+        g_string_append (buffer,
+                         "<table class=\"itip buttons\" border=\"0\" "
+                                "id=\"" TABLE_BUTTONS "\" cellspacing=\"6\" "
+                                "cellpadding=\"0\" >"
+                         "<tr id=\"" TABLE_ROW_BUTTONS "\">");
+
+        /* Everything gets the open button */
+        buttons_table_write_button (
+                buffer, BUTTON_OPEN_CALENDAR, _("Open Calendar"),
+                GTK_STOCK_JUMP_TO, ITIP_VIEW_RESPONSE_OPEN);
+        buttons_table_write_button (
+                buffer, BUTTON_DECLINE_ALL, _("Decline all"),
+                GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
+        buttons_table_write_button (
+                buffer, BUTTON_DECLINE, _("Decline"),
+                GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE);
+        buttons_table_write_button (
+                buffer, BUTTON_TENTATIVE_ALL, _("Tentative all"),
+                GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE);
+        buttons_table_write_button (
+                buffer, BUTTON_TENTATIVE, _("Tentative"),
+                GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE);
+        buttons_table_write_button (
+                buffer, BUTTON_ACCEPT_ALL, _("Accept all"),
+                GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
+        buttons_table_write_button (
+                buffer, BUTTON_ACCEPT, _("Accept"),
+                GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT);
+        buttons_table_write_button (
+                buffer, BUTTON_SEND_INFORMATION, _("Send Information"),
+                GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_REFRESH);
+        buttons_table_write_button (
+                buffer, BUTTON_UPDATE_ATTENDEE_STATUS, _("Update Attendee Status"),
+                GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_UPDATE);
+        buttons_table_write_button (
+                buffer, BUTTON_UPDATE,  _("Update"),
+                GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_CANCEL);
+
+        g_string_append (buffer, "</tr></table>");
+}
+
+void
+itip_view_write (GString *buffer)
+{
+        g_string_append (buffer,
+                "<html>\n"
+                "<head>\n"
+                "<title>ITIP</title>\n"
+                "<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\" />\n"
+                "</head>\n"
+                "<body>\n");
+
+        g_string_append_printf (buffer,
+                "<img src=\"gtk-stock://%s?size=%d\" class=\"itip icon\" />\n",
+                        MEETING_ICON, GTK_ICON_SIZE_BUTTON);
+
+        g_string_append (buffer,
+                "<div class=\"itip content\" id=\"" DIV_ITIP_CONTENT "\">\n");
+
+        /* The first section listing the sender */
+        /* FIXME What to do if the send and organizer do not match */
+        g_string_append (buffer,
+                "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\"></div>\n");
+
+        g_string_append (buffer, "<hr>\n");
+
+        /* Elementary event information */
+        g_string_append (buffer,
+                "<table class=\"itip table\" border=\"0\" "
+                       "cellspacing=\"5\" cellpadding=\"0\">\n");
+
+        append_text_table_row (buffer, TABLE_ROW_SUMMARY, NULL);
+        append_text_table_row (buffer, TABLE_ROW_LOCATION, _("Location:"));
+        append_text_table_row (buffer, TABLE_ROW_START_DATE, _("Start time:"));
+        append_text_table_row (buffer, TABLE_ROW_END_DATE, _("End time:"));
+        append_text_table_row (buffer, TABLE_ROW_STATUS, _("Status:"));
+        append_text_table_row (buffer, TABLE_ROW_COMMENT, _("Comment:"));
+
+        g_string_append (buffer, "</table>\n");
 
 	/* Upper Info items */
-	view->priv->upper_info_box = gtk_vbox_new (FALSE, 12);
-	gtk_widget_show (view->priv->upper_info_box);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->upper_info_box, FALSE, FALSE, 0);
+        g_string_append (buffer,
+                "<table class=\"itip info\" id=\"" TABLE_UPPER_ITIP_INFO "\" border=\"0\" "
+                       "cellspacing=\"5\" cellpadding=\"0\">");
 
-	/* Description */
-	view->priv->description_label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (view->priv->description_label), TRUE);
-	gtk_label_set_line_wrap (GTK_LABEL (view->priv->description_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->description_label), 0, 0.5);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->description_label, FALSE, FALSE, 0);
+        /* Description */
+        g_string_append (buffer,
+                "<div id=\"" TABLE_ROW_DESCRIPTION "\" class=\"itip description\" hidden=\"\"></div>\n");
 
-	separator = gtk_hseparator_new ();
-	gtk_widget_show (separator);
-	gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
+	g_string_append (buffer, "<hr>\n");
 
 	/* Lower Info items */
-	view->priv->lower_info_box = gtk_vbox_new (FALSE, 12);
-	gtk_widget_show (view->priv->lower_info_box);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->lower_info_box, FALSE, FALSE, 0);
+        g_string_append (buffer,
+                "<table class=\"itip info\" id=\"" TABLE_LOWER_ITIP_INFO "\" border=\"0\" "
+                       "cellspacing=\"5\" cellpadding=\"0\">");
 
-	/* Selector area */
-	view->priv->selector_box = gtk_hbox_new (FALSE, 12);
-	gtk_widget_show (view->priv->selector_box);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->selector_box, FALSE, FALSE, 0);
 
-	/* RSVP area */
-	view->priv->rsvp_box = gtk_vbox_new (FALSE, 12);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->rsvp_box, FALSE, FALSE, 0);
-
-	view->priv->rsvp_check = gtk_check_button_new_with_mnemonic (_("Send _reply to sender"));
-	gtk_widget_show (view->priv->rsvp_check);
-	gtk_box_pack_start (GTK_BOX (view->priv->rsvp_box), view->priv->rsvp_check, FALSE, FALSE, 0);
-
-	g_signal_connect (
-		view->priv->rsvp_check, "toggled",
-		G_CALLBACK (rsvp_toggled_cb), view);
-
-	hbox = gtk_hbox_new (FALSE, 12);
-	gtk_widget_show (hbox);
-	gtk_box_pack_start (GTK_BOX (view->priv->rsvp_box), hbox, FALSE, FALSE, 0);
-
-	label = gtk_label_new (NULL);
-	gtk_label_set_selectable (GTK_LABEL (label), TRUE);
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
-	view->priv->rsvp_comment_header = gtk_label_new (_("Comment:"));
-	gtk_label_set_selectable (GTK_LABEL (view->priv->rsvp_comment_header), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (view->priv->rsvp_comment_header), 0.0, 0.0);
-	gtk_widget_set_sensitive (view->priv->rsvp_comment_header, FALSE);
-	gtk_widget_show (view->priv->rsvp_comment_header);
-	gtk_box_pack_start (GTK_BOX (hbox), view->priv->rsvp_comment_header, FALSE, FALSE, 0);
-
-	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-	gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), 120);
-	gtk_widget_show (scrolled_window);
-	gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0);
-
-	view->priv->rsvp_comment_text = gtk_text_view_new ();
-	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->priv->rsvp_comment_text), GTK_WRAP_WORD_CHAR);
-	gtk_widget_set_sensitive (view->priv->rsvp_comment_text, FALSE);
-	gtk_widget_show (view->priv->rsvp_comment_text);
-	gtk_container_add (GTK_CONTAINER (scrolled_window), view->priv->rsvp_comment_text);
+        g_string_append (buffer,
+                "<table class=\"itip table\" border=\"0\" "
+                       "cellspacing=\"5\" cellpadding=\"0\">\n");
+
+        g_string_append (buffer,
+                "<tr id=\"" TABLE_ROW_ESCB "\" hidden=\"\""">"
+                "<th></th>"
+                "<td><select name=\"" SELECT_ESOURCE "\" id=\"" SELECT_ESOURCE "\"></select></td>"
+                "</tr>\n");
 
 	/* RSVP area */
-	view->priv->update_box = gtk_vbox_new (FALSE, 12);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->update_box, FALSE, FALSE, 0);
+        append_checkbox_table_row (buffer, CHECKBOX_RSVP, _("Send reply to sender"));
 
-	view->priv->update_check = gtk_check_button_new_with_mnemonic (_("Send _updates to attendees"));
-	gtk_widget_show (view->priv->update_check);
-	gtk_box_pack_start (GTK_BOX (view->priv->update_box), view->priv->update_check, FALSE, FALSE, 0);
+        /* Comments */
+        g_string_append_printf (buffer,
+                "<tr id=\"" TABLE_ROW_RSVP_COMMENT "\" hidden=\"\">"
+                "<th>%s</th>"
+                "<td><textarea name=\"" TEXTAREA_RSVP_COMMENT "\" "
+                              "id=\"" TEXTAREA_RSVP_COMMENT "\" "
+                              "rows=\"3\" cols=\"40\" disabled=\"\">"
+                "</textarea></td>\n"
+                "</tr>\n",
+                _("Comment:"));
 
-	/* The recurrence check button */
-	view->priv->recur_box = gtk_vbox_new (FALSE, 12);
-	gtk_widget_show (view->priv->recur_box);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->recur_box, FALSE, FALSE, 0);
+        /* Updates */
+        append_checkbox_table_row (buffer, CHECKBOX_UPDATE, _("Send updates to attendees"));
 
-	view->priv->recur_check = gtk_check_button_new_with_mnemonic (_("_Apply to all instances"));
-	gtk_box_pack_start (GTK_BOX (view->priv->recur_box), view->priv->recur_check, FALSE, FALSE, 0);
+        /* The recurrence check button */
+        append_checkbox_table_row (buffer, CHECKBOX_RECUR, _("Apply to all instances"));
+        append_checkbox_table_row (buffer, CHECKBOX_FREE_TIME, _("Show time as free"));
+        append_checkbox_table_row (buffer, CHECKBOX_KEEP_ALARM, _("Preserve my reminder"));
+        append_checkbox_table_row (buffer, CHECKBOX_INHERIT_ALARM, _("Inherit reminder"));
 
-	g_signal_connect (
-		view->priv->recur_check, "toggled",
-		G_CALLBACK (recur_toggled_cb), view);
+        g_string_append (buffer, "</table>\n");
 
-	view->priv->options_box = gtk_vbox_new (FALSE, 2);
-	gtk_widget_show (view->priv->options_box);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->options_box, FALSE, FALSE, 0);
+        /* Buttons table */
+        append_buttons_table (buffer);
 
-	view->priv->free_time_check = gtk_check_button_new_with_mnemonic (_("Show time as _free"));
-	gtk_box_pack_start (GTK_BOX (view->priv->options_box), view->priv->free_time_check, FALSE, FALSE, 0);
+        /* <div class="itip content" > */
+        g_string_append (buffer, "</div>\n");
 
-	view->priv->keep_alarm_check = gtk_check_button_new_with_mnemonic (_("_Preserve my reminder"));
-	/* default value is to keep user's alarms */
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->keep_alarm_check), TRUE);
-	gtk_box_pack_start (GTK_BOX (view->priv->options_box), view->priv->keep_alarm_check, FALSE, FALSE, 0);
+        g_string_append (buffer, "<div class=\"itip error\" id=\"" DIV_ITIP_ERROR "\"></div>");
 
-	/* To Translators: This is a check box to inherit a reminder. */
-	view->priv->inherit_alarm_check = gtk_check_button_new_with_mnemonic (_("_Inherit reminder"));
-	gtk_box_pack_start (GTK_BOX (view->priv->options_box), view->priv->inherit_alarm_check, FALSE, FALSE, 0);
+        g_string_append (buffer, "</body></html>");
+}
+
+void
+itip_view_create_dom_bindings (ItipView *view,
+                               WebKitDOMElement *element)
+{
+        WebKitDOMElement *el;
+        WebKitDOMDocument *doc;
+
+        doc = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
+        view->priv->dom_document = doc;
+
+        el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RECUR);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (recur_toggled_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RSVP);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (rsvp_toggled_cb), FALSE, view);
+        }
+
+
+        el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_INHERIT_ALARM);
+        if (el) {
+                webkit_dom_event_target_add_event_listener(
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (alarm_check_toggled_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_KEEP_ALARM);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (alarm_check_toggled_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_OPEN_CALENDAR);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT_ALL);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE_ALL);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE_ALL);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE_ATTENDEE_STATUS);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, BUTTON_SEND_INFORMATION);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+
+        el = webkit_dom_document_get_element_by_id (doc, SELECT_ESOURCE);
+        if (el) {
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "change",
+                        G_CALLBACK (source_changed_cb), FALSE, view);
+        }
+}
+
+
+static void
+itip_view_init (ItipView *view)
+{
+        view->priv = ITIP_VIEW_GET_PRIVATE (view);
+}
 
-	g_signal_connect (
-		view->priv->keep_alarm_check, "toggled",
-		G_CALLBACK (alarm_check_toggled_cb),
-		view->priv->inherit_alarm_check);
-	g_signal_connect (
-		view->priv->inherit_alarm_check, "toggled",
-		G_CALLBACK (alarm_check_toggled_cb),
-		view->priv->keep_alarm_check);
+ItipView *
+itip_view_new (ItipPURI *puri)
+{
+        ItipView *view;
 
-	/* The buttons for actions */
-	view->priv->button_box = gtk_hbutton_box_new ();
-	gtk_button_box_set_layout (GTK_BUTTON_BOX (view->priv->button_box), GTK_BUTTONBOX_START);
-	gtk_box_set_spacing (GTK_BOX (view->priv->button_box), 12);
-	gtk_widget_show (view->priv->button_box);
-	gtk_box_pack_start (GTK_BOX (vbox), view->priv->button_box, FALSE, FALSE, 0);
+        view = ITIP_VIEW (g_object_new (ITIP_TYPE_VIEW, NULL));
+        view->priv->puri = puri;
 
-	view->priv->buttons_sensitive = TRUE;
+        return view;
 }
 
-GtkWidget *
-itip_view_new (void)
+ItipPURI*
+itip_view_get_puri (ItipView *view)
 {
-	 ItipView *itip_view = g_object_new (ITIP_TYPE_VIEW, "homogeneous", FALSE, "spacing", 6, NULL);
+        g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	 return GTK_WIDGET (itip_view);
+        return view->priv->puri;
 }
 
+
+static void
+show_button (ItipView *view,
+             const gchar *id)
+{
+        WebKitDOMElement *button;
+
+        button = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, id);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (button), FALSE);
+}
+
+
 void
 itip_view_set_mode (ItipView *view,
                     ItipViewMode mode)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *cell;
+        WebKitDOMElement *button;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	priv->mode = mode;
+	view->priv->mode = mode;
 
 	set_sender_text (view);
-	set_buttons (view);
+
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_BUTTONS);
+        cell = webkit_dom_element_get_first_element_child (row);
+        do {
+                button = webkit_dom_element_get_first_element_child (cell);
+                webkit_dom_html_element_set_hidden (
+                        WEBKIT_DOM_HTML_ELEMENT (button), TRUE);
+        } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL);
+
+        view->priv->is_recur_set = itip_view_get_recur_check_state (view);
+
+        /* Always visible */
+        show_button (view, BUTTON_OPEN_CALENDAR);
+
+        switch (mode) {
+        case ITIP_VIEW_MODE_PUBLISH:
+                if (view->priv->needs_decline) {
+                        show_button (view, BUTTON_DECLINE);
+                }
+                show_button (view, BUTTON_ACCEPT);
+                break;
+        case ITIP_VIEW_MODE_REQUEST:
+                show_button (view, view->priv->is_recur_set ? BUTTON_DECLINE_ALL : BUTTON_DECLINE);
+                show_button (view, view->priv->is_recur_set ? BUTTON_TENTATIVE_ALL : BUTTON_TENTATIVE);
+                show_button (view, view->priv->is_recur_set ? BUTTON_ACCEPT_ALL : BUTTON_ACCEPT);
+                break;
+        case ITIP_VIEW_MODE_ADD:
+                if (view->priv->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) {
+                        show_button(view, BUTTON_DECLINE);
+                        show_button(view, BUTTON_TENTATIVE);
+                }
+                show_button (view, BUTTON_ACCEPT);
+                break;
+        case ITIP_VIEW_MODE_REFRESH:
+                show_button (view, BUTTON_SEND_INFORMATION);
+                break;
+        case ITIP_VIEW_MODE_REPLY:
+                show_button (view, BUTTON_UPDATE_ATTENDEE_STATUS);
+                break;
+        case ITIP_VIEW_MODE_CANCEL:
+                show_button (view, BUTTON_UPDATE);
+                break;
+        case ITIP_VIEW_MODE_COUNTER:
+        case ITIP_VIEW_MODE_DECLINECOUNTER:
+                show_button (view, BUTTON_DECLINE);
+                show_button (view, BUTTON_TENTATIVE);
+                show_button (view, BUTTON_ACCEPT);
+                break;
+        default:
+                break;
+        }
 }
 
 ItipViewMode
 itip_view_get_mode (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, ITIP_VIEW_MODE_NONE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE);
 
-	priv = view->priv;
-
-	return priv->mode;
+	return view->priv->mode;
 }
 
 void
 itip_view_set_item_type (ItipView *view,
                          ECalClientSourceType type)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *cell;
+        const gchar *header;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+	view->priv->type = type;
+
+
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_ESCB);
+        cell = webkit_dom_element_get_first_element_child (row);
+
+        switch (view->priv->type) {
+                case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
+                        header = _("Calendar:");
+                        break;
+                case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
+                        header = _("Tasks:");
+                        break;
+                case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
+                        header = _("Memos:");
+                        break;
+                default:
+                        header = NULL;
+                        break;
+        }
+
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (cell), header ? header : "", NULL);
 
-	priv->type = type;
 
 	set_sender_text (view);
 }
@@ -1275,31 +1426,21 @@ itip_view_set_item_type (ItipView *view,
 ECalClientSourceType
 itip_view_get_item_type (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, ITIP_VIEW_MODE_NONE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE);
 
-	priv = view->priv;
-
-	return priv->type;
+	return view->priv->type;
 }
 
 void
 itip_view_set_organizer (ItipView *view,
                          const gchar *organizer)
 {
-	ItipViewPrivate *priv;
-
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	if (priv->organizer)
-		g_free (priv->organizer);
+	if (view->priv->organizer)
+		g_free (view->priv->organizer);
 
-	priv->organizer = e_utf8_ensure_valid (organizer);
+	view->priv->organizer = e_utf8_ensure_valid (organizer);
 
 	set_sender_text (view);
 }
@@ -1307,31 +1448,21 @@ itip_view_set_organizer (ItipView *view,
 const gchar *
 itip_view_get_organizer (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->organizer;
+	return view->priv->organizer;
 }
 
 void
 itip_view_set_organizer_sentby (ItipView *view,
                                 const gchar *sentby)
 {
-	ItipViewPrivate *priv;
+        g_return_if_fail (ITIP_IS_VIEW (view));
 
-	g_return_if_fail (view != NULL);
-	g_return_if_fail (ITIP_IS_VIEW (view));
-
-	priv = view->priv;
+	if (view->priv->organizer_sentby)
+		g_free (view->priv->organizer_sentby);
 
-	if (priv->organizer_sentby)
-		g_free (priv->organizer_sentby);
-
-	priv->organizer_sentby = e_utf8_ensure_valid (sentby);
+	view->priv->organizer_sentby = e_utf8_ensure_valid (sentby);
 
 	set_sender_text (view);
 }
@@ -1339,31 +1470,21 @@ itip_view_set_organizer_sentby (ItipView *view,
 const gchar *
 itip_view_get_organizer_sentby (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->organizer_sentby;
+	return view->priv->organizer_sentby;
 }
 
 void
 itip_view_set_attendee (ItipView *view,
                         const gchar *attendee)
 {
-	ItipViewPrivate *priv;
-
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	if (priv->attendee)
-		g_free (priv->attendee);
+	if (view->priv->attendee)
+		g_free (view->priv->attendee);
 
-	priv->attendee = e_utf8_ensure_valid (attendee);
+	view->priv->attendee = e_utf8_ensure_valid (attendee);
 
 	set_sender_text (view);
 }
@@ -1371,31 +1492,21 @@ itip_view_set_attendee (ItipView *view,
 const gchar *
 itip_view_get_attendee (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->attendee;
+	return view->priv->attendee;
 }
 
 void
 itip_view_set_attendee_sentby (ItipView *view,
                                const gchar *sentby)
 {
-	ItipViewPrivate *priv;
-
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	if (priv->attendee_sentby)
-		g_free (priv->attendee_sentby);
+	if (view->priv->attendee_sentby)
+		g_free (view->priv->attendee_sentby);
 
-	priv->attendee_sentby = e_utf8_ensure_valid (sentby);
+	view->priv->attendee_sentby = e_utf8_ensure_valid (sentby);
 
 	set_sender_text (view);
 }
@@ -1403,31 +1514,21 @@ itip_view_set_attendee_sentby (ItipView *view,
 const gchar *
 itip_view_get_attendee_sentby (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
-	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
+        g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->attendee_sentby;
+	return view->priv->attendee_sentby;
 }
 
 void
 itip_view_set_proxy (ItipView *view,
                      const gchar *proxy)
 {
-	ItipViewPrivate *priv;
-
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	if (priv->proxy)
-		g_free (priv->proxy);
+	if (view->priv->proxy)
+		g_free (view->priv->proxy);
 
-	priv->proxy = e_utf8_ensure_valid (proxy);
+	view->priv->proxy = e_utf8_ensure_valid (proxy);
 
 	set_sender_text (view);
 }
@@ -1435,31 +1536,21 @@ itip_view_set_proxy (ItipView *view,
 const gchar *
 itip_view_get_proxy (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->proxy;
+	return view->priv->proxy;
 }
 
 void
 itip_view_set_delegator (ItipView *view,
                          const gchar *delegator)
 {
-	ItipViewPrivate *priv;
-
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	if (priv->delegator)
-		g_free (priv->delegator);
+	if (view->priv->delegator)
+		g_free (view->priv->delegator);
 
-	priv->delegator = e_utf8_ensure_valid (delegator);
+	view->priv->delegator = e_utf8_ensure_valid (delegator);
 
 	set_sender_text (view);
 }
@@ -1467,174 +1558,173 @@ itip_view_set_delegator (ItipView *view,
 const gchar *
 itip_view_get_delegator (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->delegator;
+	return view->priv->delegator;
 }
 
 void
 itip_view_set_summary (ItipView *view,
                        const gchar *summary)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *col;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+        if (view->priv->summary)
+		g_free (view->priv->summary);
 
-	if (priv->summary)
-		g_free (priv->summary);
+	view->priv->summary = summary ? g_strstrip (e_utf8_ensure_valid (summary)) : NULL;
 
-	priv->summary = summary ? g_strstrip (e_utf8_ensure_valid (summary)) : NULL;
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_SUMMARY);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->summary == NULL));
 
-	set_summary_text (view);
+        col = webkit_dom_element_get_last_element_child (row);
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (col),
+                view->priv->summary ? view->priv->summary : "",
+                NULL);
 }
 
 const gchar *
 itip_view_get_summary (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->summary;
+	return view->priv->summary;
 }
 
 void
 itip_view_set_location (ItipView *view,
                         const gchar *location)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *col;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+	if (view->priv->location)
+		g_free (view->priv->location);
 
-	if (priv->location)
-		g_free (priv->location);
+	view->priv->location = location ? g_strstrip (e_utf8_ensure_valid (location)) : NULL;
 
-	priv->location = location ? g_strstrip (e_utf8_ensure_valid (location)) : NULL;
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_LOCATION);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->location == NULL));
 
-	set_location_text (view);
+        col = webkit_dom_element_get_last_element_child (row);
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (col),
+                view->priv->location ? view->priv->location : "",
+                NULL);
 }
 
 const gchar *
 itip_view_get_location (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->location;
+	return view->priv->location;
 }
 
 void
 itip_view_set_status (ItipView *view,
                       const gchar *status)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *col;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+	if (view->priv->status)
+		g_free (view->priv->status);
 
-	if (priv->status)
-		g_free (priv->status);
+	view->priv->status = status ? g_strstrip (e_utf8_ensure_valid (status)) : NULL;
 
-	priv->status = status ? g_strstrip (e_utf8_ensure_valid (status)) : NULL;
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_STATUS);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->status == NULL));
 
-	set_status_text (view);
+        col = webkit_dom_element_get_last_element_child (row);
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (col),
+                view->priv->status ? view->priv->status : "",
+                NULL);
 }
 
 const gchar *
 itip_view_get_status (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->status;
+	return view->priv->status;
 }
 
 void
 itip_view_set_comment (ItipView *view,
                        const gchar *comment)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *row, *col;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+	if (view->priv->comment)
+		g_free (view->priv->comment);
 
-	if (priv->comment)
-		g_free (priv->comment);
+	view->priv->comment = comment ? g_strstrip (e_utf8_ensure_valid (comment)) : NULL;
 
-	priv->comment = comment ? g_strstrip (e_utf8_ensure_valid (comment)) : NULL;
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_COMMENT);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->comment == NULL));
 
-	set_comment_text (view);
+        col = webkit_dom_element_get_last_element_child (row);
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (col),
+                view->priv->comment ? view->priv->comment : "",
+                NULL);
 }
 
 const gchar *
 itip_view_get_comment (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->comment;
+	return view->priv->comment;
 }
 
 void
 itip_view_set_description (ItipView *view,
                            const gchar *description)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *div;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+	if (view->priv->description)
+		g_free (view->priv->description);
 
-	if (priv->description)
-		g_free (priv->description);
+	view->priv->description = description ? g_strstrip (e_utf8_ensure_valid (description)) : NULL;
 
-	priv->description = description ? g_strstrip (e_utf8_ensure_valid (description)) : NULL;
+        div = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_DESCRIPTION);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (div), (view->priv->description == NULL));
 
-	set_description_text (view);
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (div),
+                view->priv->description ? view->priv->description : "",
+                NULL);
 }
 
 const gchar *
 itip_view_get_description (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->description;
+	return view->priv->description;
 }
 
 void
@@ -1644,7 +1734,6 @@ itip_view_set_start (ItipView *view,
 {
 	ItipViewPrivate *priv;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
@@ -1668,17 +1757,12 @@ const struct tm *
 itip_view_get_start (ItipView *view,
                      gboolean *is_date)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
 	if (is_date)
-		*is_date = priv->start_tm_is_date;
+		*is_date = view->priv->start_tm_is_date;
 
-	return priv->start_tm;
+	return view->priv->start_tm;
 }
 
 void
@@ -1688,8 +1772,7 @@ itip_view_set_end (ItipView *view,
 {
 	ItipViewPrivate *priv;
 
-	g_return_if_fail (view != NULL);
-	g_return_if_fail (ITIP_IS_VIEW (view));
+        g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
 
@@ -1712,17 +1795,12 @@ const struct tm *
 itip_view_get_end (ItipView *view,
                    gboolean *is_date)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
 	if (is_date)
-		*is_date = priv->end_tm_is_date;
+		*is_date = view->priv->end_tm_is_date;
 
-	return priv->end_tm;
+	return view->priv->end_tm;
 }
 
 guint
@@ -1733,7 +1811,6 @@ itip_view_add_upper_info_item (ItipView *view,
 	ItipViewPrivate *priv;
 	ItipViewInfoItem *item;
 
-	g_return_val_if_fail (view != NULL, 0);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), 0);
 
 	priv = view->priv;
@@ -1746,7 +1823,7 @@ itip_view_add_upper_info_item (ItipView *view,
 
 	priv->upper_info_items = g_slist_append (priv->upper_info_items, item);
 
-	set_upper_info_items (view);
+        append_info_item_row (view, TABLE_UPPER_ITIP_INFO, item);
 
 	return item->id;
 }
@@ -1761,8 +1838,7 @@ itip_view_add_upper_info_item_printf (ItipView *view,
 	gchar *message;
 	guint id;
 
-	g_return_val_if_fail (view != NULL, 0);
-	g_return_val_if_fail (ITIP_IS_VIEW (view), 0);
+        g_return_val_if_fail (ITIP_IS_VIEW (view), 0);
 
 	va_start (args, format);
 	message = g_strdup_vprintf (format, args);
@@ -1781,7 +1857,6 @@ itip_view_remove_upper_info_item (ItipView *view,
 	ItipViewPrivate *priv;
 	GSList *l;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
@@ -1792,10 +1867,10 @@ itip_view_remove_upper_info_item (ItipView *view,
 		if (item->id == id) {
 			priv->upper_info_items = g_slist_remove (priv->upper_info_items, item);
 
-			g_free (item->message);
+                        g_free (item->message);
 			g_free (item);
 
-			set_upper_info_items (view);
+                        remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, id);
 
 			return;
 		}
@@ -1808,19 +1883,18 @@ itip_view_clear_upper_info_items (ItipView *view)
 	ItipViewPrivate *priv;
 	GSList *l;
 
-	g_return_if_fail (view != NULL);
-	g_return_if_fail (ITIP_IS_VIEW (view));
+        g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
 
-	gtk_container_foreach (GTK_CONTAINER (priv->upper_info_box), (GtkCallback) gtk_widget_destroy, NULL);
-
 	for (l = priv->upper_info_items; l; l = l->next) {
 		ItipViewInfoItem *item = l->data;
 
+                remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, item->id);
+
 		g_free (item->message);
 		g_free (item);
-	}
+        }
 
 	g_slist_free (priv->upper_info_items);
 	priv->upper_info_items = NULL;
@@ -1834,7 +1908,6 @@ itip_view_add_lower_info_item (ItipView *view,
 	ItipViewPrivate *priv;
 	ItipViewInfoItem *item;
 
-	g_return_val_if_fail (view != NULL, 0);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), 0);
 
 	priv = view->priv;
@@ -1847,7 +1920,7 @@ itip_view_add_lower_info_item (ItipView *view,
 
 	priv->lower_info_items = g_slist_append (priv->lower_info_items, item);
 
-	set_lower_info_items (view);
+        append_info_item_row (view, TABLE_LOWER_ITIP_INFO, item);
 
 	return item->id;
 }
@@ -1862,7 +1935,6 @@ itip_view_add_lower_info_item_printf (ItipView *view,
 	gchar *message;
 	guint id;
 
-	g_return_val_if_fail (view != NULL, 0);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), 0);
 
 	va_start (args, format);
@@ -1882,7 +1954,6 @@ itip_view_remove_lower_info_item (ItipView *view,
 	ItipViewPrivate *priv;
 	GSList *l;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
@@ -1896,7 +1967,7 @@ itip_view_remove_lower_info_item (ItipView *view,
 			g_free (item->message);
 			g_free (item);
 
-			set_lower_info_items (view);
+                        remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, id);
 
 			return;
 		}
@@ -1909,16 +1980,15 @@ itip_view_clear_lower_info_items (ItipView *view)
 	ItipViewPrivate *priv;
 	GSList *l;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
 
-	gtk_container_foreach (GTK_CONTAINER (priv->lower_info_box), (GtkCallback) gtk_widget_destroy, NULL);
-
 	for (l = priv->lower_info_items; l; l = l->next) {
 		ItipViewInfoItem *item = l->data;
 
+                remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, item->id);
+
 		g_free (item->message);
 		g_free (item);
 	}
@@ -1928,14 +1998,73 @@ itip_view_clear_lower_info_items (ItipView *view)
 }
 
 static void
-source_changed_cb (ESourceComboBox *escb,
-                   ItipView *view)
-{
-	ESource *source;
-
-	source = e_source_combo_box_get_active (escb);
-
-	g_signal_emit (view, signals[SOURCE_SELECTED], 0, source);
+source_list_changed_cb (ESourceList *source_list,
+                        ItipView *view)
+{
+        GSList *groups, *iter;
+        WebKitDOMElement *select;
+
+        d(printf("Assigning a new source list!\n"));
+
+        select = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, SELECT_ESOURCE);
+
+        while (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (select))) {
+                webkit_dom_node_remove_child (
+                        WEBKIT_DOM_NODE (select),
+                        webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (select)),
+                        NULL);
+        }
+
+        groups = e_source_list_peek_groups (source_list);
+        for (iter = groups; iter; iter = iter->next) {
+
+                ESourceGroup *group = iter->data;
+                GSList *sources, *iter2;
+                WebKitDOMElement *optgroup;
+
+                sources = e_source_group_peek_sources (group);
+                if (sources == NULL)
+                        continue;
+
+                optgroup = webkit_dom_document_create_element (
+                        view->priv->dom_document, "OPTGROUP", NULL);
+                webkit_dom_html_opt_group_element_set_label(
+                        WEBKIT_DOM_HTML_OPT_GROUP_ELEMENT (optgroup),
+                        e_source_group_peek_name (group));
+
+                webkit_dom_node_append_child (
+                        WEBKIT_DOM_NODE (select),
+                        WEBKIT_DOM_NODE (optgroup),
+                        NULL);
+
+                for (iter2 = sources; iter2; iter2 = iter2->next) {
+
+                        WebKitDOMElement *option;
+                        ESource *source = iter2->data;
+
+                        option = webkit_dom_document_create_element (
+                                view->priv->dom_document, "OPTION", NULL);
+                        webkit_dom_html_option_element_set_value (
+                                WEBKIT_DOM_HTML_OPTION_ELEMENT (option),
+                                e_source_peek_uid (source));
+                        webkit_dom_html_option_element_set_label (
+                                WEBKIT_DOM_HTML_OPTION_ELEMENT (option),
+                                e_source_peek_name (source));
+                        webkit_dom_html_element_set_inner_html (
+                                WEBKIT_DOM_HTML_ELEMENT (option),
+                                e_source_peek_name (source), NULL);
+                        webkit_dom_html_element_set_class_name (
+                                WEBKIT_DOM_HTML_ELEMENT (option), "calendar");
+
+                        webkit_dom_node_append_child (
+                                WEBKIT_DOM_NODE (optgroup),
+                                WEBKIT_DOM_NODE (option),
+                                NULL);
+                }
+        }
+
+        source_changed_cb (select, NULL, view);
 }
 
 void
@@ -1944,7 +2073,6 @@ itip_view_set_source_list (ItipView *view,
 {
 	ItipViewPrivate *priv;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
 	priv = view->priv;
@@ -1952,380 +2080,595 @@ itip_view_set_source_list (ItipView *view,
 	if (priv->source_list)
 		g_object_unref (priv->source_list);
 
-	if (priv->escb)
-		gtk_widget_destroy (priv->escb);
-
 	if (!source_list) {
-		if (priv->escb_header)
-			gtk_widget_destroy (priv->escb_header);
-
 		priv->source_list = NULL;
-		priv->escb = NULL;
-		priv->escb_header = NULL;
-
 		return;
 	}
 
 	priv->source_list = g_object_ref (source_list);
 
-	priv->escb = e_source_combo_box_new (source_list);
-	gtk_widget_show (priv->escb);
-	g_signal_connect (
-		priv->escb, "changed",
-		G_CALLBACK (source_changed_cb), view);
-
-	if (!priv->escb_header) {
-		if (priv->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS)
-			priv->escb_header = gtk_label_new_with_mnemonic (_("_Calendar:"));
-		else if (priv->type == E_CAL_CLIENT_SOURCE_TYPE_TASKS)
-			priv->escb_header = gtk_label_new_with_mnemonic (_("_Tasks:"));
-		else if (priv->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS)
-			priv->escb_header = gtk_label_new_with_mnemonic (_("_Memos:"));
-
-		gtk_label_set_selectable (GTK_LABEL (priv->escb_header), TRUE);
-		gtk_label_set_mnemonic_widget (GTK_LABEL (priv->escb_header), priv->escb);
-		gtk_widget_show (priv->escb_header);
-	}
+        source_list_changed_cb (source_list, view);
 
-	gtk_box_pack_start (GTK_BOX (priv->selector_box), priv->escb_header, FALSE, TRUE, 6);
-	gtk_box_pack_start (GTK_BOX (priv->selector_box), priv->escb, FALSE, TRUE, 0);
+        g_signal_connect (source_list, "changed",
+                G_CALLBACK (source_list_changed_cb), view);
 }
 
 ESourceList *
 itip_view_get_source_list (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
-
-	return priv->source_list;
+	return view->priv->source_list;
 }
 
 void
 itip_view_set_source (ItipView *view,
                       ESource *source)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *select;
+        WebKitDOMElement *row;
+        gulong i, len;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+        d(printf("Settings default source '%s'\n", e_source_peek_name (source)));
+
+        row = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_ESCB);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (row), (source == NULL));
+        if (source == NULL)
+                return;
 
-	if (!priv->escb)
-		return;
 
-	e_source_combo_box_set_active (
-		E_SOURCE_COMBO_BOX (priv->escb), source);
+        select = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, SELECT_ESOURCE);
+
+        /* <select> does not emit 'change' event when already selected <option>
+         * is re-selected, but we need to notify itip formatter, so that it would
+         * make all the buttons sensitive */
+        if (source == itip_view_get_source (view)) {
+                source_changed_cb (select, NULL, view);
+        }
+
+        if (webkit_dom_html_select_element_get_disabled (
+                        WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) {
+                webkit_dom_html_select_element_set_disabled (
+                        WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE);
+        }
+
+        len = webkit_dom_html_select_element_get_length (
+                WEBKIT_DOM_HTML_SELECT_ELEMENT (select));
+        for (i = 0; i < len; i++) {
+
+                WebKitDOMNode *node;
+                WebKitDOMHTMLOptionElement *option;
+                gchar *value;
+
+                node = webkit_dom_html_select_element_item (
+                        WEBKIT_DOM_HTML_SELECT_ELEMENT (select), i);
+                option = WEBKIT_DOM_HTML_OPTION_ELEMENT (node);
+
+                value = webkit_dom_html_option_element_get_value (option);
+                if (g_strcmp0 (value, e_source_peek_uid (source)) == 0) {
+                        webkit_dom_html_option_element_set_selected (
+                                option, TRUE);
+
+                        g_free (value);
+                        break;
+                }
+
+                g_free (value);
+        }
 }
 
 ESource *
 itip_view_get_source (ItipView *view)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *select;
+        gchar *uid;
+        ESource *source;
+        gboolean disable = FALSE;
 
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
+        select = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, SELECT_ESOURCE);
+        if (webkit_dom_html_select_element_get_disabled (
+                        WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) {
+                webkit_dom_html_select_element_set_disabled (
+                WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE);
+                disable = TRUE;
+        }
 
-	if (!priv->escb)
-		return NULL;
+        uid = webkit_dom_html_select_element_get_value (
+                WEBKIT_DOM_HTML_SELECT_ELEMENT (select));
 
-	return e_source_combo_box_get_active (
-		E_SOURCE_COMBO_BOX (priv->escb));
+        source = e_source_list_peek_source_by_uid (
+                view->priv->source_list, uid);
+        g_free (uid);
+
+        if (disable) {
+                webkit_dom_html_select_element_set_disabled (
+                        WEBKIT_DOM_HTML_SELECT_ELEMENT (select), TRUE);
+        }
+
+        return source;
 }
 
 void
 itip_view_set_rsvp (ItipView *view,
                     gboolean rsvp)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->rsvp_check), rsvp);
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RSVP);
+        webkit_dom_html_input_element_set_checked (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), rsvp);
 
-	gtk_widget_set_sensitive (priv->rsvp_comment_header, rsvp);
-	gtk_widget_set_sensitive (priv->rsvp_comment_text, rsvp);
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
+        webkit_dom_html_text_area_element_set_disabled (
+                WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp);
 }
 
 gboolean
 itip_view_get_rsvp (ItipView *view)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el;
 
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	priv = view->priv;
-
-	return priv->rsvp_show && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->rsvp_check));
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_UPDATE);
+        return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
 }
 
 void
-itip_view_set_show_rsvp (ItipView *view,
-                         gboolean rsvp)
+itip_view_set_show_rsvp_check (ItipView *view,
+                               gboolean show)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *label;
+        WebKitDOMElement *el;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, "table_row_" CHECKBOX_RSVP);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
 
-	priv->rsvp_show = rsvp;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RSVP);
+        label = webkit_dom_element_get_next_element_sibling (el);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
 
-	priv->rsvp_show ? gtk_widget_show (priv->rsvp_box) : gtk_widget_hide (priv->rsvp_box);
+
+        if (!show) {
+                webkit_dom_html_input_element_set_checked (
+                        WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+        }
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_RSVP_COMMENT);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
 }
 
 gboolean
-itip_view_get_show_rsvp (ItipView *view)
+itip_view_get_show_rsvp_check (ItipView *view)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el;
 
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	priv = view->priv;
-
-	return priv->rsvp_show;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RSVP);
+        return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el));
 }
 
 void
 itip_view_set_update (ItipView *view,
                       gboolean update)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_UPDATE);
 
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->update_check), update);
+        webkit_dom_html_input_element_set_checked (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), update);
 }
 
 gboolean
 itip_view_get_update (ItipView *view)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el;
 
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	priv = view->priv;
-
-	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->update_check));
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_UPDATE);
+	return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
 }
 
 void
-itip_view_set_show_update (ItipView *view,
-                           gboolean update)
+itip_view_set_show_update_check (ItipView *view,
+                                 gboolean show)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *label;
+        WebKitDOMElement *el;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, "table_row_" CHECKBOX_UPDATE);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
 
-	priv->update_show = update;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_UPDATE);
+        label = webkit_dom_element_get_next_element_sibling (el);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
 
-	priv->update_show ? gtk_widget_show (priv->update_box) : gtk_widget_hide (priv->update_box);
+        if (!show) {
+                webkit_dom_html_input_element_set_checked (
+                        WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+        }
 }
 
 gboolean
-itip_view_get_show_update (ItipView *view)
+itip_view_get_show_update_check (ItipView *view)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el;
 
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	priv = view->priv;
-
-	return priv->update_show;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_UPDATE);
+	return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el));
 }
 
 void
 itip_view_set_rsvp_comment (ItipView *view,
                             const gchar *comment)
 {
-	ItipViewPrivate *priv;
-	GtkTextBuffer *text_buffer;
+        WebKitDOMElement *el;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
+        webkit_dom_html_element_set_hidden(
+                WEBKIT_DOM_HTML_ELEMENT (el), (comment == NULL));
 
-	text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->rsvp_comment_text));
-	gtk_text_buffer_set_text (text_buffer, comment, -1);
+        if (comment) {
+                webkit_dom_html_text_area_element_set_value (
+                        WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), comment);
+        }
 }
 
 gchar *
 itip_view_get_rsvp_comment (ItipView *view)
 {
-	ItipViewPrivate *priv;
-	GtkTextBuffer *text_buffer;
-	GtkTextIter start, end;
+        WebKitDOMElement *el;
 
-	g_return_val_if_fail (view != NULL, NULL);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-	priv = view->priv;
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
 
-	text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->rsvp_comment_text));
-	gtk_text_buffer_get_bounds (text_buffer, &start, &end);
+        if (webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el))) {
+                return NULL;
+        }
 
-	return gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE);
+        return webkit_dom_html_text_area_element_get_value (
+                WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el));
 }
 
 void
 itip_view_set_needs_decline (ItipView *view,
                              gboolean needs_decline)
 {
-	ItipViewPrivate *priv;
-
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	priv->needs_decline = needs_decline;
+	view->priv->needs_decline = needs_decline;
 }
 
 void
 itip_view_set_buttons_sensitive (ItipView *view,
                                  gboolean sensitive)
 {
-	ItipViewPrivate *priv;
+        WebKitDOMElement *el, *cell;
 
-	g_return_if_fail (view != NULL);
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	priv = view->priv;
-
-	priv->buttons_sensitive = sensitive;
-
-	gtk_widget_set_sensitive (priv->button_box, priv->buttons_sensitive);
-	gtk_widget_set_sensitive (priv->update_box, priv->buttons_sensitive);
-	gtk_widget_set_sensitive (priv->recur_box, priv->buttons_sensitive);
-	gtk_widget_set_sensitive (priv->options_box, priv->buttons_sensitive);
-	gtk_widget_set_sensitive (priv->selector_box, priv->buttons_sensitive);
-	gtk_widget_set_sensitive (priv->rsvp_box, priv->buttons_sensitive);
+        d(printf("Settings buttons %s\n", sensitive ? "sensitive" : "insensitive"));
+
+	view->priv->buttons_sensitive = sensitive;
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_UPDATE);
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RECUR);
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_FREE_TIME);
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_KEEP_ALARM);
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RSVP);
+        webkit_dom_html_input_element_set_disabled (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
+        webkit_dom_html_text_area_element_set_disabled (
+                WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !sensitive);
+
+	el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, SELECT_ESOURCE);
+        webkit_dom_html_select_element_set_disabled(
+                WEBKIT_DOM_HTML_SELECT_ELEMENT (el), !sensitive);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, TABLE_ROW_BUTTONS);
+        cell = webkit_dom_element_get_first_element_child (el);
+        do {
+                WebKitDOMElement *btn;
+                btn = webkit_dom_element_get_first_element_child (cell);
+                if (!webkit_dom_html_element_get_hidden (
+                        WEBKIT_DOM_HTML_ELEMENT (btn))) {
+                        webkit_dom_html_button_element_set_disabled (
+                                WEBKIT_DOM_HTML_BUTTON_ELEMENT (btn), !sensitive);
+                }
+        } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL);
 }
 
 gboolean
 itip_view_get_buttons_sensitive (ItipView *view)
 {
-	ItipViewPrivate *priv;
-
-	g_return_val_if_fail (view != NULL, FALSE);
 	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	priv = view->priv;
-
-	return priv->buttons_sensitive;
+	return view->priv->buttons_sensitive;
 }
 
 gboolean
 itip_view_get_recur_check_state (ItipView *view)
 {
-	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->recur_check));
+        WebKitDOMElement *el;
+
+        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RECUR);
+        return webkit_dom_html_input_element_get_checked (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
 }
 
 void
 itip_view_set_show_recur_check (ItipView *view,
                                 gboolean show)
 {
-	g_return_if_fail (view != NULL);
+        WebKitDOMElement *label;
+        WebKitDOMElement *el;
+
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	if (show)
-		gtk_widget_show (view->priv->recur_check);
-	else {
-		gtk_widget_hide (view->priv->recur_check);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->recur_check), FALSE);
-	}
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, "table_row_" CHECKBOX_RECUR);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_RECUR);
+        label = webkit_dom_element_get_next_element_sibling (el);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
+
+        if (!show) {
+                webkit_dom_html_input_element_set_checked (
+                        WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+        }
+
+        /* and update state of the second check */
+        alarm_check_toggled_cb (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
+                NULL, view);
 }
 
 void
 itip_view_set_show_free_time_check (ItipView *view,
                                     gboolean show)
 {
-	g_return_if_fail (view != NULL);
+        WebKitDOMElement *label;
+        WebKitDOMElement *el;
+
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	if (show)
-		gtk_widget_show (view->priv->free_time_check);
-	else {
-		gtk_widget_hide (view->priv->free_time_check);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->free_time_check), FALSE);
-	}
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, "table_row_" CHECKBOX_FREE_TIME);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_FREE_TIME);
+        label = webkit_dom_element_get_next_element_sibling (el);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
+
+        if (!show) {
+                webkit_dom_html_input_element_set_checked (
+                        WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+        }
+
+        /* and update state of the second check */
+        alarm_check_toggled_cb (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
+                NULL, view);
 }
 
 gboolean
 itip_view_get_free_time_check_state (ItipView *view)
 {
-	g_return_val_if_fail (view != NULL, FALSE);
+        WebKitDOMElement *el;
+
+	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->free_time_check));
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_FREE_TIME);
+        return webkit_dom_html_input_element_get_checked (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
 }
 
 void
 itip_view_set_show_keep_alarm_check (ItipView *view,
                                      gboolean show)
 {
-	g_return_if_fail (view != NULL);
+        WebKitDOMElement *label;
+        WebKitDOMElement *el;
+
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	if (show)
-		gtk_widget_show (view->priv->keep_alarm_check);
-	else
-		gtk_widget_hide (view->priv->keep_alarm_check);
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, "table_row_" CHECKBOX_KEEP_ALARM);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
 
-	/* and update state of the second check */
-	alarm_check_toggled_cb (view->priv->keep_alarm_check, view->priv->inherit_alarm_check);
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_KEEP_ALARM);
+        label = webkit_dom_element_get_next_element_sibling (el);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
+
+        if (!show) {
+                webkit_dom_html_input_element_set_checked (
+                        WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+        }
+
+        /* and update state of the second check */
+        alarm_check_toggled_cb (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
+                NULL, view);
 }
 
 gboolean
 itip_view_get_keep_alarm_check_state (ItipView *view)
 {
-	g_return_val_if_fail (view != NULL, FALSE);
+        WebKitDOMElement *el;
+
+	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->keep_alarm_check));
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_KEEP_ALARM);
+        return webkit_dom_html_input_element_get_checked (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
 }
 
 void
 itip_view_set_show_inherit_alarm_check (ItipView *view,
                                         gboolean show)
 {
-	g_return_if_fail (view != NULL);
+        WebKitDOMElement *label;
+        WebKitDOMElement *el;
+
 	g_return_if_fail (ITIP_IS_VIEW (view));
 
-	if (show)
-		gtk_widget_show (view->priv->inherit_alarm_check);
-	else {
-		gtk_widget_hide (view->priv->inherit_alarm_check);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->inherit_alarm_check), FALSE);
-	}
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, "table_row_" CHECKBOX_INHERIT_ALARM);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
+        label = webkit_dom_element_get_next_element_sibling (el);
+        webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
+
+        if (!show) {
+                webkit_dom_html_input_element_set_checked (
+                        WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+        }
 
 	/* and update state of the second check */
-	alarm_check_toggled_cb (view->priv->inherit_alarm_check, view->priv->keep_alarm_check);
+	alarm_check_toggled_cb (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
+                NULL, view);
 }
 
 gboolean
 itip_view_get_inherit_alarm_check_state (ItipView *view)
 {
-	g_return_val_if_fail (view != NULL, FALSE);
+        WebKitDOMElement *el;
+
+	g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-	return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->inherit_alarm_check));
+        el = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
+	return webkit_dom_html_input_element_get_checked (
+                WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
 }
+
+void
+itip_view_set_error (ItipView *view,
+                     const gchar *error_html,
+                     gboolean show_save_btn)
+{
+        WebKitDOMElement *content, *error;
+        GString *str;
+
+        g_return_if_fail (ITIP_IS_VIEW (view));
+        g_return_if_fail (error_html);
+
+        content = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, DIV_ITIP_CONTENT);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (content), TRUE);
+
+        error = webkit_dom_document_get_element_by_id (
+                view->priv->dom_document, DIV_ITIP_ERROR);
+        webkit_dom_html_element_set_hidden (
+                WEBKIT_DOM_HTML_ELEMENT (error), FALSE);
+
+        str = g_string_new (error_html);
+
+        if (show_save_btn) {
+                g_string_append (str,
+                        "<table border=\"0\" width=\"100%\">"
+                        "<tr width=\"100%\" id=\"" TABLE_ROW_BUTTONS "\">");
+
+                buttons_table_write_button (
+                        str, BUTTON_SAVE, _("Save"),
+                        GTK_STOCK_SAVE, ITIP_VIEW_RESPONSE_SAVE);
+
+                g_string_append (str, "</tr></table>");
+        }
+
+        webkit_dom_html_element_set_inner_html (
+                WEBKIT_DOM_HTML_ELEMENT (error), str->str, NULL);
+
+        g_string_free (str, TRUE);
+
+        if (show_save_btn) {
+                WebKitDOMElement *el;
+
+                show_button (view, BUTTON_SAVE);
+
+                el = webkit_dom_document_get_element_by_id (
+                        view->priv->dom_document, BUTTON_SAVE);
+                webkit_dom_event_target_add_event_listener (
+                        WEBKIT_DOM_EVENT_TARGET (el), "click",
+                        G_CALLBACK (button_clicked_cb), FALSE, view);
+        }
+}
+
diff --git a/plugins/itip-formatter/itip-view.h b/plugins/itip-formatter/itip-view.h
index 538306c..0821da6 100644
--- a/plugins/itip-formatter/itip-view.h
+++ b/plugins/itip-formatter/itip-view.h
@@ -29,6 +29,7 @@
 #include <gtk/gtk.h>
 #include <libedataserver/e-source-list.h>
 #include <libecal/e-cal-client.h>
+#include <webkit/webkitdom.h>
 
 G_BEGIN_DECLS
 
@@ -42,6 +43,7 @@ G_BEGIN_DECLS
 typedef struct _ItipView        ItipView;
 typedef struct _ItipViewPrivate ItipViewPrivate;
 typedef struct _ItipViewClass   ItipViewClass;
+typedef struct _ItipPURI        ItipPURI;
 
 typedef enum {
 	ITIP_VIEW_MODE_NONE,
@@ -64,7 +66,8 @@ typedef enum {
 	ITIP_VIEW_RESPONSE_UPDATE,
 	ITIP_VIEW_RESPONSE_CANCEL,
 	ITIP_VIEW_RESPONSE_REFRESH,
-	ITIP_VIEW_RESPONSE_OPEN
+	ITIP_VIEW_RESPONSE_OPEN,
+	ITIP_VIEW_RESPONSE_SAVE
 } ItipViewResponse;
 
 typedef enum {
@@ -76,115 +79,185 @@ typedef enum {
 } ItipViewInfoItemType;
 
 struct _ItipView {
-	GtkHBox parent_instance;
+	GObject parent_instance;
 
 	ItipViewPrivate *priv;
-
-	GtkWidget *action_vbox;
 };
 
 struct _ItipViewClass {
-	GtkHBoxClass parent_class;
-
-	void (* source_selected) (ItipView *view, ESource *selected_source);
-	void (* response) (ItipView *view, gint response);
-};
-
-GType      itip_view_get_type (void);
-GtkWidget *itip_view_new      (void);
-
-void itip_view_set_mode (ItipView *view, ItipViewMode mode);
-ItipViewMode itip_view_get_mode (ItipView *view);
-
-void itip_view_set_item_type (ItipView *view, ECalClientSourceType type);
-ECalClientSourceType itip_view_get_item_type (ItipView *view);
-
-void itip_view_set_organizer (ItipView *view, const gchar *organizer);
-const gchar *itip_view_get_organizer (ItipView *view);
-
-void itip_view_set_organizer_sentby (ItipView *view, const gchar *sentby);
-const gchar *itip_view_get_organizer_sentby (ItipView *view);
-
-void itip_view_set_attendee (ItipView *view, const gchar *attendee);
-const gchar *itip_view_get_attendee (ItipView *view);
-
-void itip_view_set_attendee_sentby (ItipView *view, const gchar *sentby);
-const gchar *itip_view_get_attendee_sentby (ItipView *view);
-
-void itip_view_set_delegator (ItipView *view, const gchar *delegator);
-const gchar *itip_view_get_delegator (ItipView *view);
-
-void itip_view_set_proxy (ItipView *view, const gchar *proxy);
-const gchar *itip_view_get_proxy (ItipView *view);
-
-void itip_view_set_summary (ItipView *view, const gchar *summary);
-const gchar *itip_view_get_summary (ItipView *view);
-
-void itip_view_set_location (ItipView *view, const gchar *location);
-const gchar *itip_view_get_location (ItipView *view);
-
-void itip_view_set_status (ItipView *view, const gchar *status);
-const gchar *itip_view_get_status (ItipView *view);
-
-void itip_view_set_comment (ItipView *view, const gchar *comment);
-const gchar *itip_view_get_comment (ItipView *view);
+	GObjectClass parent_class;
 
-void itip_view_set_description (ItipView *view, const gchar *description);
-const gchar *itip_view_get_description (ItipView *view);
+	void    (* source_selected)             (ItipView *view,
+                                                 ESource *selected_source);
 
-void itip_view_set_start (ItipView *view, struct tm *start, gboolean is_date);
-const struct tm *itip_view_get_start (ItipView *view, gboolean *is_date);
-
-void itip_view_set_end (ItipView *view, struct tm *end, gboolean is_date);
-const struct tm *itip_view_get_end (ItipView *view, gboolean *is_date);
-
-guint itip_view_add_upper_info_item (ItipView *view, ItipViewInfoItemType type, const gchar *message);
-guint itip_view_add_upper_info_item_printf (ItipView *view, ItipViewInfoItemType, const gchar *format, ...) G_GNUC_PRINTF (3, 4);
-void itip_view_remove_upper_info_item (ItipView *view, guint id);
-void itip_view_clear_upper_info_items (ItipView *view);
-
-guint itip_view_add_lower_info_item (ItipView *view, ItipViewInfoItemType type, const gchar *message);
-guint itip_view_add_lower_info_item_printf (ItipView *view, ItipViewInfoItemType type, const gchar *format, ...) G_GNUC_PRINTF (3, 4);
-void itip_view_remove_lower_info_item (ItipView *view, guint id);
-void itip_view_clear_lower_info_items (ItipView *view);
-
-void itip_view_set_source_list (ItipView *view, ESourceList *source_list);
-ESourceList *itip_view_get_source_list (ItipView *view);
-
-void itip_view_set_source (ItipView *view, ESource *source);
-ESource *itip_view_get_source (ItipView *view);
-
-void itip_view_set_rsvp (ItipView *view, gboolean rsvp);
-gboolean itip_view_get_rsvp (ItipView *view);
-
-void itip_view_set_show_rsvp (ItipView *view, gboolean rsvp);
-gboolean itip_view_get_show_rsvp (ItipView *view);
-
-void itip_view_set_update (ItipView *view, gboolean update);
-gboolean itip_view_get_update (ItipView *view);
-
-void itip_view_set_show_update (ItipView *view, gboolean update);
-gboolean itip_view_get_show_update (ItipView *view);
-
-void itip_view_set_rsvp_comment (ItipView *view, const gchar *comment);
-gchar *itip_view_get_rsvp_comment (ItipView *view);
-
-void itip_view_set_buttons_sensitive (ItipView *view, gboolean sensitive);
-gboolean itip_view_get_buttons_sensitive (ItipView *view);
-
-void itip_view_set_show_recur_check (ItipView *view, gboolean show);
-gboolean itip_view_get_recur_check_state (ItipView *view);
-
-void itip_view_set_needs_decline (ItipView *view, gboolean needs_decline);
-
-void itip_view_set_show_free_time_check (ItipView *view, gboolean show);
-gboolean itip_view_get_free_time_check_state (ItipView *view);
-
-void itip_view_set_show_keep_alarm_check (ItipView *view, gboolean show);
-gboolean itip_view_get_keep_alarm_check_state (ItipView *view);
+	void    (* response)                    (ItipView *view,
+                                                 gint response);
+};
 
-void itip_view_set_show_inherit_alarm_check (ItipView *view, gboolean show);
-gboolean itip_view_get_inherit_alarm_check_state (ItipView *view);
+GType           itip_view_get_type              (void);
+
+ItipView*       itip_view_new                   (ItipPURI *puri);
+
+void            itip_view_write                 (GString *buffer);
+
+void            itip_view_create_dom_bindings   (ItipView *view,
+                                                 WebKitDOMElement *element);
+
+ItipPURI*       itip_view_get_puri              (ItipView *view);
+
+void            itip_view_set_mode              (ItipView *view,
+                                                 ItipViewMode mode);
+ItipViewMode    itip_view_get_mode              (ItipView *view);
+
+void            itip_view_set_item_type         (ItipView *view,
+                                                 ECalClientSourceType type);
+ECalClientSourceType
+                itip_view_get_item_type         (ItipView *view);
+
+void            itip_view_set_organizer         (ItipView *view,
+                                                 const gchar *organizer);
+const gchar*    itip_view_get_organizer         (ItipView *view);
+
+void            itip_view_set_organizer_sentby  (ItipView *view,
+                                                 const gchar *sentby);
+const gchar*    itip_view_get_organizer_sentby  (ItipView *view);
+
+void            itip_view_set_attendee          (ItipView *view,
+                                                 const gchar *attendee);
+const gchar*    itip_view_get_attendee          (ItipView *view);
+
+void            itip_view_set_attendee_sentby   (ItipView *view,
+                                                 const gchar *sentby);
+const gchar*    itip_view_get_attendee_sentby   (ItipView *view);
+
+void            itip_view_set_delegator         (ItipView *view,
+                                                 const gchar *delegator);
+const gchar*    itip_view_get_delegator         (ItipView *view);
+
+void            itip_view_set_proxy             (ItipView *view,
+                                                 const gchar *proxy);
+const gchar*    itip_view_get_proxy             (ItipView *view);
+
+void            itip_view_set_summary           (ItipView *view,
+                                                 const gchar *summary);
+const gchar*    itip_view_get_summary           (ItipView *view);
+
+void            itip_view_set_location          (ItipView *view,
+                                                 const gchar *location);
+const gchar*    itip_view_get_location          (ItipView *view);
+
+void            itip_view_set_status            (ItipView *view,
+                                                 const gchar *status);
+const gchar*    itip_view_get_status            (ItipView *view);
+
+void            itip_view_set_comment           (ItipView *view,
+                                                 const gchar *comment);
+const gchar*    itip_view_get_comment           (ItipView *view);
+
+void            itip_view_set_description       (ItipView *view,
+                                                 const gchar *description);
+const gchar*    itip_view_get_description       (ItipView *view);
+
+void            itip_view_set_start             (ItipView *view,
+                                                 struct tm *start,
+                                                 gboolean is_date);
+const struct tm*
+                itip_view_get_start             (ItipView *view,
+                                                 gboolean *is_date);
+
+void            itip_view_set_end               (ItipView *view,
+                                                 struct tm *end,
+                                                 gboolean is_date);
+const struct tm*
+                itip_view_get_end               (ItipView *view,
+                                                 gboolean *is_date);
+
+guint           itip_view_add_upper_info_item   (ItipView *view,
+                                                 ItipViewInfoItemType type,
+                                                 const gchar *message);
+guint           itip_view_add_upper_info_item_printf
+                                                (ItipView *view,
+                                                 ItipViewInfoItemType,
+                                                 const gchar *format, ...) G_GNUC_PRINTF (3, 4);
+void            itip_view_remove_upper_info_item
+                                                (ItipView *view,
+                                                 guint id);
+void            itip_view_clear_upper_info_items
+                                                (ItipView *view);
+
+guint           itip_view_add_lower_info_item   (ItipView *view,
+                                                 ItipViewInfoItemType type,
+                                                 const gchar *message);
+guint           itip_view_add_lower_info_item_printf
+                                                (ItipView *view,
+                                                 ItipViewInfoItemType type,
+                                                 const gchar *format, ...) G_GNUC_PRINTF (3, 4);
+void            itip_view_remove_lower_info_item
+                                                (ItipView *view,
+                                                 guint id);
+void            itip_view_clear_lower_info_items
+                                                (ItipView *view);
+
+void            itip_view_set_source_list       (ItipView *view,
+                                                 ESourceList *source_list);
+ESourceList*    itip_view_get_source_list       (ItipView *view);
+
+void            itip_view_set_source            (ItipView *view,
+                                                 ESource *source);
+ESource*        itip_view_get_source            (ItipView *view);
+
+void            itip_view_set_rsvp              (ItipView *view,
+                                                 gboolean rsvp);
+gboolean        itip_view_get_rsvp              (ItipView *view);
+
+void            itip_view_set_show_rsvp_check   (ItipView *view,
+                                                 gboolean show);
+gboolean        itip_view_get_show_rsvp_check   (ItipView *view);
+
+void            itip_view_set_update            (ItipView *view,
+                                                 gboolean update);
+gboolean        itip_view_get_update            (ItipView *view);
+
+void            itip_view_set_show_update_check (ItipView *view,
+                                                 gboolean show);
+gboolean        itip_view_get_show_update_check (ItipView *view);
+
+void            itip_view_set_rsvp_comment      (ItipView *view,
+                                                 const gchar *comment);
+gchar*          itip_view_get_rsvp_comment      (ItipView *view);
+
+void            itip_view_set_buttons_sensitive (ItipView *view,
+                                                 gboolean sensitive);
+gboolean        itip_view_get_buttons_sensitive (ItipView *view);
+
+void            itip_view_set_show_recur_check  (ItipView *view,
+                                                 gboolean show);
+gboolean        itip_view_get_recur_check_state (ItipView *view);
+
+void            itip_view_set_needs_decline     (ItipView *view,
+                                                 gboolean needs_decline);
+
+void            itip_view_set_show_free_time_check
+                                                (ItipView *view,
+                                                 gboolean show);
+gboolean        itip_view_get_free_time_check_state
+                                                (ItipView *view);
+
+void            itip_view_set_show_keep_alarm_check
+                                                (ItipView *view,
+                                                 gboolean show);
+gboolean        itip_view_get_keep_alarm_check_state
+                                                (ItipView *view);
+
+void            itip_view_set_show_inherit_alarm_check
+                                                (ItipView *view,
+                                                 gboolean show);
+gboolean        itip_view_get_inherit_alarm_check_state
+                                                (ItipView *view);
+
+void            itip_view_set_error             (ItipView *view,
+                                                 const gchar *error_html,
+                                                 gboolean show_save_btn);
 
 G_END_DECLS
 



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