aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2010-05-19 04:47:29 +0800
committerMilan Crha <mcrha@redhat.com>2010-05-19 04:47:29 +0800
commitef7690c3845e3c1cebcf3caba7f7667a10e7123d (patch)
treeab4a5bfa25bc5e25e0fed851c25226ce1930ec52 /widgets/misc
parent0f92771be57383e5d6e7d0f3e05743d192066eb3 (diff)
downloadgsoc2013-evolution-ef7690c3845e3c1cebcf3caba7f7667a10e7123d.tar.gz
gsoc2013-evolution-ef7690c3845e3c1cebcf3caba7f7667a10e7123d.tar.zst
gsoc2013-evolution-ef7690c3845e3c1cebcf3caba7f7667a10e7123d.zip
Bug #499320 - Preview before import from command line
Diffstat (limited to 'widgets/misc')
-rw-r--r--widgets/misc/Makefile.am2
-rw-r--r--widgets/misc/e-import-assistant.c105
-rw-r--r--widgets/misc/e-web-view-preview.c481
-rw-r--r--widgets/misc/e-web-view-preview.h101
4 files changed, 674 insertions, 15 deletions
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index 9a33f48b32..6373ceb58b 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -71,6 +71,7 @@ widgetsinclude_HEADERS = \
e-signature-tree-view.h \
e-url-entry.h \
e-web-view.h \
+ e-web-view-preview.h \
ea-calendar-cell.h \
ea-calendar-item.h \
ea-cell-table.h \
@@ -147,6 +148,7 @@ libemiscwidgets_la_SOURCES = \
e-signature-tree-view.c \
e-url-entry.c \
e-web-view.c \
+ e-web-view-preview.c \
ea-calendar-cell.c \
ea-calendar-item.c \
ea-cell-table.c \
diff --git a/widgets/misc/e-import-assistant.c b/widgets/misc/e-import-assistant.c
index 30d41385f4..3ca06dcda8 100644
--- a/widgets/misc/e-import-assistant.c
+++ b/widgets/misc/e-import-assistant.c
@@ -71,8 +71,12 @@ struct _ImportProgressPage {
};
struct _ImportSimplePage {
+ GtkWidget *actionlabel;
+ GtkWidget *filetypetable;
GtkWidget *filetype;
- GtkWidget *control; /* importer's destination widget in an alignment */
+ GtkWidget *control; /* importer's destination or preview widget in an alignment */
+ gboolean has_preview; /* TRUE when 'control' holds a preview widget,
+ otherwise holds destination widget */
EImportTargetURI *target;
EImportImporter *importer;
@@ -427,7 +431,6 @@ import_assistant_simple_page_init (EImportAssistant *import_assistant)
GtkWidget *widget;
GtkCellRenderer *cell;
GtkListStore *store;
- const gchar *text;
gint row = 0;
page = gtk_vbox_new (FALSE, 6);
@@ -436,12 +439,11 @@ import_assistant_simple_page_init (EImportAssistant *import_assistant)
container = page;
- text = _("Select what type of file you want to import from the list.");
-
- widget = gtk_label_new (text);
+ widget = gtk_label_new ("");
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
gtk_widget_show (widget);
+ import_assistant->priv->simple_page.actionlabel = widget;
widget = gtk_table_new (2, 1, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (widget), 2);
@@ -449,6 +451,7 @@ import_assistant_simple_page_init (EImportAssistant *import_assistant)
gtk_container_set_border_width (GTK_CONTAINER (widget), 8);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
gtk_widget_show (widget);
+ import_assistant->priv->simple_page.filetypetable = widget;
container = widget;
@@ -743,7 +746,7 @@ prepare_progress_page (GtkAssistant *assistant,
g_object_get (G_OBJECT (assistant), "is-simple", &is_simple, NULL);
- intelligent_import = gtk_toggle_button_get_active (
+ intelligent_import = is_simple ? FALSE : gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (priv->type_page.intelligent));
if (is_simple) {
@@ -797,9 +800,15 @@ simple_filetype_changed_cb (GtkComboBox *combo_box, GtkAssistant *assistant)
if (page->control)
gtk_widget_destroy (page->control);
+ page->has_preview = FALSE;
+
+ control = e_import_get_preview_widget (priv->import, (EImportTarget *) page->target, page->importer);
+ if (control) {
+ page->has_preview = TRUE;
+ gtk_widget_set_size_request (control, 320, 240);
+ } else
+ control = create_importer_control (priv->import, (EImportTarget *)page->target, page->importer);
- control = create_importer_control (
- priv->import, (EImportTarget *)page->target, page->importer);
page->control = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
gtk_widget_show (page->control);
gtk_container_add (GTK_CONTAINER (page->control), control);
@@ -847,8 +856,6 @@ prepare_simple_page (GtkAssistant *assistant, GtkWidget *vbox)
-1);
}
- g_slist_free (importers);
-
gtk_combo_box_set_active (GTK_COMBO_BOX (page->filetype), 0);
g_object_set_data (G_OBJECT (page->filetype), "page-vbox", vbox);
@@ -857,6 +864,56 @@ prepare_simple_page (GtkAssistant *assistant, GtkWidget *vbox)
g_signal_connect (
page->filetype, "changed",
G_CALLBACK (simple_filetype_changed_cb), assistant);
+
+ if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1) {
+ gchar *title;
+
+ /* only one importer found, make it even simpler */
+ gtk_label_set_text (GTK_LABEL (page->actionlabel),
+ page->has_preview ?
+ _("Preview data to be imported") :
+ _("Choose the destination for this import"));
+
+ gtk_widget_hide (page->filetypetable);
+
+ title = g_strconcat (_("Import Data"), " - ", ((EImportImporter *)importers->data)->name, NULL);
+ gtk_assistant_set_page_title (assistant, vbox, title);
+ g_free (title);
+ } else {
+ /* multiple importers found, be able to choose from them */
+ gtk_label_set_text (GTK_LABEL (page->actionlabel), _("Select what type of file you want to import from the list."));
+
+ gtk_widget_show (page->filetypetable);
+
+ gtk_assistant_set_page_title (assistant, vbox, _("Import Data"));
+ }
+
+ g_slist_free (importers);
+}
+
+static gboolean
+prepare_simple_destination_page (GtkAssistant *assistant,
+ GtkWidget *vbox)
+{
+ EImportAssistantPrivate *priv;
+ ImportDestinationPage *page;
+ ImportSimplePage *simple_page;
+
+ priv = E_IMPORT_ASSISTANT_GET_PRIVATE (assistant);
+ page = &priv->destination_page;
+ simple_page = &priv->simple_page;
+
+ if (page->control)
+ gtk_container_remove (GTK_CONTAINER (vbox), page->control);
+
+ page->control = create_importer_control (
+ priv->import, (EImportTarget *)
+ simple_page->target, simple_page->importer);
+
+ gtk_box_pack_start (GTK_BOX (vbox), page->control, TRUE, TRUE, 0);
+ gtk_assistant_set_page_complete (assistant, vbox, TRUE);
+
+ return FALSE;
}
static gint
@@ -864,6 +921,16 @@ forward_cb (gint current_page,
EImportAssistant *import_assistant)
{
GtkToggleButton *toggle_button;
+ gboolean is_simple = FALSE;
+
+ g_object_get (G_OBJECT (import_assistant), "is-simple", &is_simple, NULL);
+
+ if (is_simple) {
+ if (!import_assistant->priv->simple_page.has_preview)
+ current_page++;
+
+ return current_page + 1;
+ }
toggle_button = GTK_TOGGLE_BUTTON (
import_assistant->priv->type_page.intelligent);
@@ -1076,6 +1143,8 @@ import_assistant_prepare (GtkAssistant *assistant,
if (page_no == 0) {
prepare_simple_page (assistant, page);
} else if (page_no == 1) {
+ prepare_simple_destination_page (assistant, page);
+ } else if (page_no == 2) {
prepare_progress_page (assistant, page);
}
@@ -1193,6 +1262,14 @@ import_assistant_construct (EImportAssistant *import_assistant)
gtk_assistant_append_page (assistant, page);
gtk_assistant_set_page_header_image (assistant, page, pixbuf);
+ gtk_assistant_set_page_title (assistant, page, _("Import Data"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
+
+ /* File destination page - when with preview*/
+ page = import_assistant_destination_page_init (import_assistant);
+
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, pixbuf);
gtk_assistant_set_page_title (assistant, page, _("Import Location"));
gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
} else {
@@ -1272,11 +1349,9 @@ import_assistant_construct (EImportAssistant *import_assistant)
gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_PROGRESS);
gtk_assistant_set_page_complete (assistant, page, TRUE);
- if (!import_assistant->priv->is_simple) {
- gtk_assistant_set_forward_page_func (
- assistant, (GtkAssistantPageFunc)
- forward_cb, import_assistant, NULL);
- }
+ gtk_assistant_set_forward_page_func (
+ assistant, (GtkAssistantPageFunc)
+ forward_cb, import_assistant, NULL);
g_object_unref (pixbuf);
diff --git a/widgets/misc/e-web-view-preview.c b/widgets/misc/e-web-view-preview.c
new file mode 100644
index 0000000000..e268779827
--- /dev/null
+++ b/widgets/misc/e-web-view-preview.c
@@ -0,0 +1,481 @@
+/*
+ * e-web-view-preview.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-web-view-preview.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+
+#define E_WEB_VIEW_PREVIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreviewPrivate))
+
+struct _EWebViewPreviewPrivate {
+ gboolean escape_values;
+ GString *updating_content; /* is NULL when not between begin_update/end_update */
+};
+
+enum {
+ PROP_0,
+ PROP_TREE_VIEW,
+ PROP_PREVIEW_WIDGET,
+ PROP_ESCAPE_VALUES
+};
+
+G_DEFINE_TYPE (EWebViewPreview, e_web_view_preview, GTK_TYPE_VPANED);
+
+static void
+web_view_preview_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ESCAPE_VALUES:
+ e_web_view_preview_set_escape_values (
+ E_WEB_VIEW_PREVIEW (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+web_view_preview_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TREE_VIEW:
+ g_value_set_object (
+ value, e_web_view_preview_get_tree_view (
+ E_WEB_VIEW_PREVIEW (object)));
+ return;
+
+ case PROP_PREVIEW_WIDGET:
+ g_value_set_object (
+ value, e_web_view_preview_get_preview (
+ E_WEB_VIEW_PREVIEW (object)));
+ return;
+
+ case PROP_ESCAPE_VALUES:
+ g_value_set_boolean (
+ value, e_web_view_preview_get_escape_values (
+ E_WEB_VIEW_PREVIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+web_view_preview_dispose (GObject *object)
+{
+ EWebViewPreviewPrivate *priv;
+
+ priv = E_WEB_VIEW_PREVIEW_GET_PRIVATE (object);
+
+ if (priv->updating_content != NULL) {
+ g_string_free (priv->updating_content, TRUE);
+ priv->updating_content = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_web_view_preview_parent_class)->dispose (object);
+}
+
+static void
+e_web_view_preview_class_init (EWebViewPreviewClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EWebViewPreviewPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = web_view_preview_set_property;
+ object_class->get_property = web_view_preview_get_property;
+ object_class->dispose = web_view_preview_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TREE_VIEW,
+ g_param_spec_object (
+ "tree-view",
+ "Tree View",
+ NULL,
+ GTK_TYPE_TREE_VIEW,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREVIEW_WIDGET,
+ g_param_spec_object (
+ "preview-widget",
+ "Preview Widget",
+ NULL,
+ GTK_TYPE_WIDGET,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ESCAPE_VALUES,
+ g_param_spec_boolean (
+ "escape-values",
+ "Whether escaping values automatically, when inserting",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+}
+
+static GtkWidget *
+in_scrolled_window (GtkWidget *widget)
+{
+ GtkWidget *sw;
+
+ g_return_val_if_fail (widget != NULL, NULL);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (sw), widget);
+
+ gtk_widget_show (widget);
+ gtk_widget_show (sw);
+
+ return sw;
+}
+
+static void
+e_web_view_preview_init (EWebViewPreview *preview)
+{
+ GtkWidget *tree_view_sw, *web_view_sw;
+ EWebViewPreviewPrivate *priv;
+
+ priv = E_WEB_VIEW_PREVIEW_GET_PRIVATE (preview);
+ preview->priv = priv;
+ priv->escape_values = TRUE;
+
+ tree_view_sw = in_scrolled_window (gtk_tree_view_new ());
+ web_view_sw = in_scrolled_window (e_web_view_new ());
+
+ gtk_widget_hide (tree_view_sw);
+ gtk_widget_show (web_view_sw);
+
+ gtk_paned_pack1 (GTK_PANED (preview), tree_view_sw, FALSE, TRUE);
+ gtk_paned_pack2 (GTK_PANED (preview), web_view_sw, TRUE, TRUE);
+
+ /* rawly 3 lines of a text plus a little bit more */
+ if (gtk_paned_get_position (GTK_PANED (preview)) < 85)
+ gtk_paned_set_position (GTK_PANED (preview), 85);
+}
+
+GtkWidget *
+e_web_view_preview_new (void)
+{
+ return g_object_new (E_TYPE_WEB_VIEW_PREVIEW, NULL);
+}
+
+GtkTreeView *
+e_web_view_preview_get_tree_view (EWebViewPreview *preview)
+{
+ g_return_val_if_fail (preview != NULL, NULL);
+ g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), NULL);
+
+ return GTK_TREE_VIEW (gtk_bin_get_child (GTK_BIN (gtk_paned_get_child1 (GTK_PANED (preview)))));
+}
+
+GtkWidget *
+e_web_view_preview_get_preview (EWebViewPreview *preview)
+{
+ g_return_val_if_fail (preview != NULL, NULL);
+ g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), NULL);
+
+ return gtk_bin_get_child (GTK_BIN (gtk_paned_get_child2 (GTK_PANED (preview))));
+}
+
+void
+e_web_view_preview_set_preview (EWebViewPreview *preview, GtkWidget *preview_widget)
+{
+ GtkWidget *old_child;
+
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview_widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (preview_widget));
+
+ old_child = gtk_bin_get_child (GTK_BIN (gtk_paned_get_child2 (GTK_PANED (preview))));
+ if (old_child) {
+ g_return_if_fail (old_child != preview_widget);
+ gtk_widget_destroy (old_child);
+ }
+
+ gtk_container_add (GTK_CONTAINER (gtk_paned_get_child2 (GTK_PANED (preview))), preview_widget);
+}
+
+void
+e_web_view_preview_show_tree_view (EWebViewPreview *preview)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+
+ gtk_widget_show (gtk_paned_get_child1 (GTK_PANED (preview)));
+}
+
+void
+e_web_view_preview_hide_tree_view(EWebViewPreview *preview)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+
+ gtk_widget_hide (gtk_paned_get_child1 (GTK_PANED (preview)));
+}
+
+void
+e_web_view_preview_set_escape_values (EWebViewPreview *preview, gboolean escape)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+
+ preview->priv->escape_values = escape;
+}
+
+gboolean
+e_web_view_preview_get_escape_values (EWebViewPreview *preview)
+{
+ g_return_val_if_fail (preview != NULL, FALSE);
+ g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), FALSE);
+ g_return_val_if_fail (preview->priv != NULL, FALSE);
+
+ return preview->priv->escape_values;
+}
+
+void
+e_web_view_preview_begin_update (EWebViewPreview *preview)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+
+ if (preview->priv->updating_content) {
+ g_warning ("%s: Previous content update isn't finished with e_web_view_preview_end_update()", G_STRFUNC);
+ g_string_free (preview->priv->updating_content, TRUE);
+ }
+
+ preview->priv->updating_content = g_string_new ("<TABLE width=\"100%\" border=\"0\" cols=\"2\">");
+}
+
+void
+e_web_view_preview_end_update (EWebViewPreview *preview)
+{
+ GtkWidget *web_view;
+
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+
+ g_string_append (preview->priv->updating_content, "</TABLE>");
+
+ web_view = e_web_view_preview_get_preview (preview);
+ if (E_IS_WEB_VIEW (web_view))
+ e_web_view_load_string (E_WEB_VIEW (web_view), preview->priv->updating_content->str);
+
+ g_string_free (preview->priv->updating_content, TRUE);
+ preview->priv->updating_content = NULL;
+}
+
+static gchar *
+replace_string (const gchar *text, const gchar *find, const gchar *replace)
+{
+ const gchar *p, *next;
+ GString *str;
+ gint find_len;
+
+ g_return_val_if_fail (text != NULL, NULL);
+ g_return_val_if_fail (find != NULL, NULL);
+ g_return_val_if_fail (*find, NULL);
+
+ find_len = strlen (find);
+ str = g_string_new ("");
+
+ p = text;
+ while (next = strstr (p, find), next) {
+ if (p + 1 < next)
+ g_string_append_len (str, p, next - p);
+
+ if (replace && *replace)
+ g_string_append (str, replace);
+
+ p = next + find_len;
+ }
+
+ g_string_append (str, p);
+
+ return g_string_free (str, FALSE);
+}
+
+static gchar *
+web_view_preview_escape_text (EWebViewPreview *preview, const gchar *text)
+{
+ gchar *utf8_valid, *res, *end;
+
+ if (!e_web_view_preview_get_escape_values (preview))
+ return NULL;
+
+ g_return_val_if_fail (text != NULL, NULL);
+
+ if (g_utf8_validate (text, -1, NULL)) {
+ res = g_markup_escape_text (text, -1);
+ } else {
+ utf8_valid = g_strdup (text);
+ while (end = NULL, !g_utf8_validate (utf8_valid, -1, (const gchar **) &end) && end && *end)
+ *end = '?';
+
+ res = g_markup_escape_text (utf8_valid, -1);
+
+ g_free (utf8_valid);
+ }
+
+ if (res && strchr (res, '\n')) {
+ /* replace line breaks with <BR> */
+ if (strchr (res, '\r')) {
+ end = replace_string (res, "\r", "");
+ g_free (res);
+ res = end;
+ }
+
+ end = replace_string (res, "\n", "<BR>");
+ g_free (res);
+ res = end;
+ }
+
+ return res;
+}
+
+void
+e_web_view_preview_add_header (EWebViewPreview *preview, gint index, const gchar *header)
+{
+ gchar *escaped;
+
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+ g_return_if_fail (header != NULL);
+
+ if (index < 1)
+ index = 1;
+ else if (index > 6)
+ index = 6;
+
+ escaped = web_view_preview_escape_text (preview, header);
+ if (escaped)
+ header = escaped;
+
+ g_string_append_printf (preview->priv->updating_content, "<TR><TD colspan=2><H%d>%s</H%d></TD></TR>", index, header, index);
+
+ g_free (escaped);
+}
+
+void
+e_web_view_preview_add_text (EWebViewPreview *preview, const gchar *text)
+{
+ gchar *escaped;
+
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+ g_return_if_fail (text != NULL);
+
+ escaped = web_view_preview_escape_text (preview, text);
+ if (escaped)
+ text = escaped;
+
+ g_string_append_printf (preview->priv->updating_content, "<TR><TD colspan=2><FONT size=\"3\">%s</FONT></TD></TR>", text);
+
+ g_free (escaped);
+}
+
+void
+e_web_view_preview_add_raw_html (EWebViewPreview *preview, const gchar *raw_html)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+ g_return_if_fail (raw_html != NULL);
+
+ g_string_append_printf (preview->priv->updating_content, "<TR><TD colspan=2>%s</TD></TR>", raw_html);
+}
+
+void
+e_web_view_preview_add_separator (EWebViewPreview *preview)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+
+ g_string_append (preview->priv->updating_content, "<TR><TD colspan=2><HR></TD></TR>");
+}
+
+void
+e_web_view_preview_add_empty_line (EWebViewPreview *preview)
+{
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+
+ g_string_append (preview->priv->updating_content, "<TR><TD colspan=2>&nbsp;</TD></TR>");
+}
+
+/* section can be NULL, but value cannot */
+void
+e_web_view_preview_add_section (EWebViewPreview *preview, const gchar *section, const gchar *value)
+{
+ gchar *escaped_section = NULL, *escaped_value;
+
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
+ g_return_if_fail (preview->priv != NULL);
+ g_return_if_fail (preview->priv->updating_content != NULL);
+ g_return_if_fail (value != NULL);
+
+ if (section) {
+ escaped_section = web_view_preview_escape_text (preview, section);
+ if (escaped_section)
+ section = escaped_section;
+ }
+
+ escaped_value = web_view_preview_escape_text (preview, value);
+ if (escaped_value)
+ value = escaped_value;
+
+ g_string_append_printf (preview->priv->updating_content, "<TR><TD width=\"10%%\" valign=\"top\" nowrap><FONT size=\"3\"><B>%s</B></FONT></TD><TD width=\"90%%\"><FONT size=\"3\">%s</FONT></TD></TR>", section ? section : "", value);
+
+ g_free (escaped_section);
+ g_free (escaped_value);
+}
diff --git a/widgets/misc/e-web-view-preview.h b/widgets/misc/e-web-view-preview.h
new file mode 100644
index 0000000000..319f67ec82
--- /dev/null
+++ b/widgets/misc/e-web-view-preview.h
@@ -0,0 +1,101 @@
+/*
+ * e-web-view-preview.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* This is intended to serve as a common widget for previews before import.
+ * It contains a GtkTreeView at the top and an EWebView at the bottom.
+ * The tree view is not shown initially, it should be forced with
+ * e_web_view_preview_show_tree_view().
+ *
+ * The internal default EWebView can be accessed by e_web_view_preview_get_preview()
+ * and it should be updated for each change of the selected item in the tree
+ * view, when it's shown.
+ *
+ * Updating an EWebView content through helper functions of an EWebViewPreview
+ * begins with call of e_web_view_preview_begin_update(), which starts an empty
+ * page construction, which is finished by e_web_view_preview_end_update(),
+ * and the content of the EWebView is updated.
+ */
+
+#ifndef E_WEB_VIEW_PREVIEW_H
+#define E_WEB_VIEW_PREVIEW_H
+
+#include <misc/e-web-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEB_VIEW_PREVIEW \
+ (e_web_view_preview_get_type ())
+#define E_WEB_VIEW_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreview))
+#define E_WEB_VIEW_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreviewClass))
+#define E_IS_WEB_VIEW_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_WEB_VIEW_PREVIEW))
+#define E_IS_WEB_VIEW_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_WEB_VIEW_PREVIEW))
+#define E_WEB_VIEW_PREVIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_WEB_VIEW_PREVIEW, EWebViewPreviewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EWebViewPreview EWebViewPreview;
+typedef struct _EWebViewPreviewClass EWebViewPreviewClass;
+typedef struct _EWebViewPreviewPrivate EWebViewPreviewPrivate;
+
+struct _EWebViewPreview {
+ GtkVPaned parent;
+ EWebViewPreviewPrivate *priv;
+};
+
+struct _EWebViewPreviewClass {
+ GtkVPanedClass parent_class;
+};
+
+GType e_web_view_preview_get_type (void);
+GtkWidget * e_web_view_preview_new (void);
+
+GtkTreeView * e_web_view_preview_get_tree_view(EWebViewPreview *preview);
+GtkWidget * e_web_view_preview_get_preview (EWebViewPreview *preview);
+void e_web_view_preview_set_preview (EWebViewPreview *preview, GtkWidget *preview_widget);
+
+void e_web_view_preview_show_tree_view(EWebViewPreview *preview);
+void e_web_view_preview_hide_tree_view(EWebViewPreview *preview);
+
+void e_web_view_preview_set_escape_values(EWebViewPreview *preview, gboolean escape);
+gboolean e_web_view_preview_get_escape_values(EWebViewPreview *preview);
+
+void e_web_view_preview_begin_update (EWebViewPreview *preview);
+void e_web_view_preview_end_update (EWebViewPreview *preview);
+
+void e_web_view_preview_add_header (EWebViewPreview *preview, gint index, const gchar *header);
+void e_web_view_preview_add_text (EWebViewPreview *preview, const gchar *text);
+void e_web_view_preview_add_raw_html (EWebViewPreview *preview, const gchar *raw_html);
+void e_web_view_preview_add_separator(EWebViewPreview *preview);
+void e_web_view_preview_add_empty_line(EWebViewPreview *preview);
+void e_web_view_preview_add_section (EWebViewPreview *preview, const gchar *section, const gchar *value);
+
+G_END_DECLS
+
+#endif /* E_WEB_VIEW_PREVIEW_H */