From f01b90c66d8e39e31efdd85cc401934ada17bade Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Fri, 4 Dec 2009 18:49:45 +0100 Subject: [PATCH] Webkit based mime part and msg view implementation. --- src/Makefile.am | 2 + src/modest-tny-platform-factory.c | 8 +- src/widgets/Makefile.am | 19 +- src/widgets/modest-tny-stream-webkit.c | 362 +++++++ src/widgets/modest-tny-stream-webkit.h | 107 ++ src/widgets/modest-webkit-mime-part-view.c | 858 +++++++++++++++ src/widgets/modest-webkit-mime-part-view.h | 110 ++ src/widgets/modest-webkit-msg-view.c | 1575 ++++++++++++++++++++++++++++ src/widgets/modest-webkit-msg-view.h | 131 +++ 9 files changed, 3158 insertions(+), 14 deletions(-) create mode 100644 src/widgets/modest-tny-stream-webkit.c create mode 100644 src/widgets/modest-tny-stream-webkit.h create mode 100644 src/widgets/modest-webkit-mime-part-view.c create mode 100644 src/widgets/modest-webkit-mime-part-view.h create mode 100644 src/widgets/modest-webkit-msg-view.c create mode 100644 src/widgets/modest-webkit-msg-view.h diff --git a/src/Makefile.am b/src/Makefile.am index 8ab21ca..542a9db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,6 +15,7 @@ INCLUDES=\ $(MODEST_LIBCONIC_CFLAGS) \ $(MODEST_HILDON_NOTIFY_CFLAGS) \ $(MODEST_MOZEMBED_CFLAGS) \ + $(MODEST_WEBKIT_CFLAGS) \ -fPIC \ -I$(MODEST_TOOLKIT_DIR) \ -DPREFIX=\"@prefix@\" \ @@ -171,6 +172,7 @@ libmodest_la_LIBADD = \ $(MAEMO_LAUNCHER_LIBS) \ $(MODEST_GSTUFF_LIBS) \ $(MODEST_MOZEMBED_LIBS) \ + $(MODEST_WEBKIT_LIBS) \ $(MODEST_PLATFORM_LIBS) \ $(MODEST_TOOLKIT_LIBS) \ $(MODEST_HILDON_HELP_LIBS) \ diff --git a/src/modest-tny-platform-factory.c b/src/modest-tny-platform-factory.c index 84290ef..62f8eef 100644 --- a/src/modest-tny-platform-factory.c +++ b/src/modest-tny-platform-factory.c @@ -39,8 +39,8 @@ #include "modest-tny-platform-factory.h" #include "modest-tny-account-store.h" -#ifdef MODEST_USE_MOZEMBED -#include +#ifdef MODEST_USE_WEBKIT +#include #else #include #endif @@ -198,8 +198,8 @@ static TnyMsgView* modest_tny_platform_factory_new_msg_view (TnyPlatformFactory *self) { /* Here we'll select one of the implementations available */ -#ifdef MODEST_USE_MOZEMBED - return g_object_new (MODEST_TYPE_MOZEMBED_MSG_VIEW, NULL); +#ifdef MODEST_USE_WEBKIT + return g_object_new (MODEST_TYPE_WEBKIT_MSG_VIEW, NULL); #else return g_object_new (MODEST_TYPE_GTKHTML_MSG_VIEW, NULL); #endif diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am index 20b4b9a..e297c00 100644 --- a/src/widgets/Makefile.am +++ b/src/widgets/Makefile.am @@ -8,6 +8,7 @@ INCLUDES=\ $(MODEST_TOOLKIT_CFLAGS) \ $(MODEST_PLUGIN_DEFINES) \ $(MODEST_HILDON_HELP_CFLAGS) \ + $(MODEST_WEBKIT_CFLAGS) \ $(MODEST_MOZEMBED_CFLAGS) \ $(MODEST_WPEDITOR_CFLAGS) \ $(MODEST_LIBCONIC_CFLAGS) \ @@ -171,6 +172,7 @@ libmodest_widgets_la_include_HEADERS = $(libmodest_widgets_public_headers) LDADD = \ $(MODEST_GSTUFF_LIBS) \ $(MODEST_MOZEMBED_LIBS) \ + $(MODEST_WEBKIT_LIBS) \ $(MODEST_WPEDITOR_LIBS) \ $(MODEST_PLATFORM_LIBS) \ $(MODEST_LIBCONIC_LIBS) \ @@ -178,17 +180,14 @@ LDADD = \ $(MODEST_CALENDAR_WIDGETS_LIBS) if MODEST_USE_WEBKIT -# libmodest_widgets_la_SOURCES += \ -# modest-webkit-mime-part-view.c \ -# modest-webkit-mime-part-view.h \ -# modest-webkit-msg-view.c \ -# modest-webkit-msg-view.h +libmodest_widgets_la_SOURCES += \ + modest-webkit-mime-part-view.c \ + modest-webkit-mime-part-view.h \ + modest-webkit-msg-view.c \ + modest-webkit-msg-view.h \ + modest-tny-stream-webkit.c \ + modest-tny-stream-webkit.h -LDADD += \ - $(MODEST_WEBKIT_LIBS) - -INCLUDES += \ - $(MODEST_WEBKIT_CFLAGS) endif UI_FILES=\ diff --git a/src/widgets/modest-tny-stream-webkit.c b/src/widgets/modest-tny-stream-webkit.c new file mode 100644 index 0000000..1495fd0 --- /dev/null +++ b/src/widgets/modest-tny-stream-webkit.c @@ -0,0 +1,362 @@ +/* Copyright (c) 2009, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* modest-tny-stream-webkit.c */ + +#include "modest-tny-stream-webkit.h" +#include "modest-webkit-mime-part-view.h" +#include + +/* 'private'/'protected' functions */ +static void modest_tny_stream_webkit_class_init (ModestTnyStreamWebkitClass *klass); +static void modest_tny_stream_webkit_init (ModestTnyStreamWebkit *obj); +static void modest_tny_stream_webkit_finalize (GObject *obj); + +static void modest_tny_stream_gtkhml_iface_init (gpointer g_iface, gpointer iface_data); + +static void stop_streams (ModestWebkitMimePartView *view, gpointer userdata); + +/* list my signals */ +enum { + /* MY_SIGNAL_1, */ + /* MY_SIGNAL_2, */ + LAST_SIGNAL +}; + +typedef struct _ModestTnyStreamWebkitPrivate ModestTnyStreamWebkitPrivate; +struct _ModestTnyStreamWebkitPrivate { + GString *buffer; + GtkWidget *webview; + + gchar *mime_type; + gchar *encoding; + + guint stop_streams_id; + + gssize max_size; + gssize current_size; +}; +#define MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_TNY_STREAM_WEBKIT, \ + ModestTnyStreamWebkitPrivate)) +/* globals */ +static GObjectClass *parent_class = NULL; + +/* uncomment the following if you have defined any signals */ +/* static guint signals[LAST_SIGNAL] = {0}; */ + +GType +modest_tny_stream_webkit_get_type (void) +{ + static GType my_type = 0; + if (!my_type) { + static const GTypeInfo my_info = { + sizeof(ModestTnyStreamWebkitClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc) modest_tny_stream_webkit_class_init, + NULL, /* class finalize */ + NULL, /* class data */ + sizeof(ModestTnyStreamWebkit), + 1, /* n_preallocs */ + (GInstanceInitFunc) modest_tny_stream_webkit_init, + NULL + }; + + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) modest_tny_stream_gtkhml_iface_init, + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + my_type = g_type_register_static (G_TYPE_OBJECT, + "ModestTnyStreamWebkit", + &my_info, 0); + + g_type_add_interface_static (my_type, TNY_TYPE_STREAM, + &iface_info); + + } + return my_type; +} + +static void +modest_tny_stream_webkit_class_init (ModestTnyStreamWebkitClass *klass) +{ + GObjectClass *gobject_class; + gobject_class = (GObjectClass*) klass; + + parent_class = g_type_class_peek_parent (klass); + gobject_class->finalize = modest_tny_stream_webkit_finalize; + + g_type_class_add_private (gobject_class, sizeof(ModestTnyStreamWebkitPrivate)); +} + +static void +modest_tny_stream_webkit_init (ModestTnyStreamWebkit *obj) +{ + ModestTnyStreamWebkitPrivate *priv; + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(obj); + + priv->buffer = NULL; + priv->webview = NULL; + priv->stop_streams_id = 0; + + priv->max_size = 0; + priv->current_size = 0; + + priv->mime_type = NULL; + priv->encoding = NULL; +} + +static void +modest_tny_stream_webkit_finalize (GObject *obj) +{ + ModestTnyStreamWebkitPrivate *priv; + + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(obj); + if (priv->buffer) + g_string_free (priv->buffer, TRUE); + + g_free (priv->mime_type); + g_free (priv->encoding); + + if (priv->stop_streams_id > 0) { + g_signal_handler_disconnect (G_OBJECT (priv->webview), priv->stop_streams_id); + priv->stop_streams_id = 0; + } + + if (priv->webview) { + g_object_unref (priv->webview); + priv->webview = NULL; + } +} + +GObject* +modest_tny_stream_webkit_new (WebKitWebView *webview, const gchar *mime_type, const gchar *encoding) +{ + GObject *obj; + ModestTnyStreamWebkitPrivate *priv; + + obj = G_OBJECT(g_object_new(MODEST_TYPE_TNY_STREAM_WEBKIT, NULL)); + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(obj); + + g_return_val_if_fail (webview, NULL); + + priv->buffer = g_string_new (""); + + priv->webview = g_object_ref (webview); + priv->mime_type = g_strdup (mime_type); + priv->encoding = g_strdup (encoding); + + priv->stop_streams_id = g_signal_connect (G_OBJECT (webview), "stop-streams", + G_CALLBACK (stop_streams), obj); + priv->current_size = 0; + + return obj; +} + + +/* the rest are interface functions */ + + +static ssize_t +webkit_read (TnyStream *self, char *buffer, size_t n) +{ + return -1; /* we cannot read */ +} + + +static ssize_t +webkit_write (TnyStream *self, const char *buffer, size_t n) +{ + ModestTnyStreamWebkitPrivate *priv; + + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(self); + + if (!priv->buffer) { + g_print ("modest: cannot write to closed stream\n"); + return 0; + } + + if (n == 0 || !buffer) + return 0; + + if (!priv->webview || !GTK_WIDGET_VISIBLE (priv->webview)) + return -1; + + if (priv->max_size > 0) { + + /* We only use the maximum size for write method, and even we + * ignore and fake as we would do a successfull read */ + if (priv->current_size >= priv->max_size) + return n; + + if (priv->current_size + n > priv->max_size) + n = priv->max_size - priv->current_size; + } + + if (!g_main_context_is_owner (NULL)) + gdk_threads_enter (); + + priv->buffer = g_string_append_len (priv->buffer, buffer, n); + + if (!g_main_context_is_owner (NULL)) + gdk_threads_leave (); + priv->current_size += n; + + return n; /* hmmm */ +} + + +static gint +webkit_flush (TnyStream *self) +{ + return 0; +} + + +static gint +webkit_close (TnyStream *self) +{ + ModestTnyStreamWebkitPrivate *priv; + g_return_val_if_fail (self, 0); + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(self); + + if (priv->stop_streams_id > 0) { + g_signal_handler_disconnect (G_OBJECT (priv->webview), priv->stop_streams_id); + priv->stop_streams_id = 0; + } + if (priv->webview) { + webkit_web_view_load_string (WEBKIT_WEB_VIEW (priv->webview), priv->buffer->str, priv->mime_type, priv->encoding, NULL); + + g_object_unref (priv->webview); + priv->webview = NULL; + } + if (priv->buffer) + g_string_free (priv->buffer, TRUE); + priv->buffer = NULL; + + return 0; +} + + +static gboolean +webkit_is_eos (TnyStream *self) +{ + return TRUE; +} + + + +static gint +webkit_reset (TnyStream *self) +{ + return 0; +} + + +static ssize_t +webkit_write_to_stream (TnyStream *self, TnyStream *output) +{ + return 0; +} + +static void +stop_streams (ModestWebkitMimePartView *view, gpointer userdata) +{ + ModestTnyStreamWebkit *self = (ModestTnyStreamWebkit *) userdata; + ModestTnyStreamWebkitPrivate *priv; + + g_return_if_fail (self); + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE(self); + + if (priv->webview && priv->stop_streams_id > 0) { + g_signal_handler_disconnect (G_OBJECT (priv->webview), priv->stop_streams_id); + priv->stop_streams_id = 0; + } + + if (priv->webview) { + g_object_unref (priv->webview); + priv->webview = NULL; + } +} + +void +modest_tny_stream_webkit_set_max_size (ModestTnyStreamWebkit *stream, + gssize max_size) +{ + ModestTnyStreamWebkitPrivate *priv; + + g_return_if_fail (MODEST_IS_TNY_STREAM_WEBKIT (stream)); + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE (stream); + + priv->max_size = max_size; +} + +gssize +modest_tny_stream_webkit_get_max_size (ModestTnyStreamWebkit *stream) +{ + ModestTnyStreamWebkitPrivate *priv; + + g_return_val_if_fail (MODEST_IS_TNY_STREAM_WEBKIT (stream), 0); + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE (stream); + + return priv->max_size; +} + +gboolean +modest_tny_stream_webkit_limit_reached (ModestTnyStreamWebkit *self) +{ + ModestTnyStreamWebkitPrivate *priv; + + g_return_val_if_fail (MODEST_IS_TNY_STREAM_WEBKIT (self), 0); + priv = MODEST_TNY_STREAM_WEBKIT_GET_PRIVATE (self); + + return (priv->max_size > 0) && (priv->current_size >= priv->max_size); +} + +static void +modest_tny_stream_gtkhml_iface_init (gpointer g_iface, gpointer iface_data) +{ + TnyStreamIface *klass; + + g_return_if_fail (g_iface); + + klass = (TnyStreamIface*) g_iface; + + klass->read = webkit_read; + klass->write = webkit_write; + klass->flush = webkit_flush; + klass->close = webkit_close; + klass->is_eos = webkit_is_eos; + klass->reset = webkit_reset; + klass->write_to_stream = webkit_write_to_stream; +} diff --git a/src/widgets/modest-tny-stream-webkit.h b/src/widgets/modest-tny-stream-webkit.h new file mode 100644 index 0000000..23da9b7 --- /dev/null +++ b/src/widgets/modest-tny-stream-webkit.h @@ -0,0 +1,107 @@ +/* Copyright (c) 2009, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* modest-tny-stream-webkit.h */ + +#ifndef __MODEST_TNY_STREAM_WEBKIT_H__ +#define __MODEST_TNY_STREAM_WEBKIT_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/* convenience macros */ +#define MODEST_TYPE_TNY_STREAM_WEBKIT (modest_tny_stream_webkit_get_type()) +#define MODEST_TNY_STREAM_WEBKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_TNY_STREAM_WEBKIT,ModestTnyStreamWebkit)) +#define MODEST_TNY_STREAM_WEBKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_TNY_STREAM_WEBKIT,ModestTnyStreamWebkitClass)) +#define MODEST_IS_TNY_STREAM_WEBKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_TNY_STREAM_WEBKIT)) +#define MODEST_IS_TNY_STREAM_WEBKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_TNY_STREAM_WEBKIT)) +#define MODEST_TNY_STREAM_WEBKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_TNY_STREAM_WEBKIT,ModestTnyStreamWebkitClass)) + +typedef struct _ModestTnyStreamWebkit ModestTnyStreamWebkit; +typedef struct _ModestTnyStreamWebkitClass ModestTnyStreamWebkitClass; + +struct _ModestTnyStreamWebkit { + GObject parent; +}; + +struct _ModestTnyStreamWebkitClass { + GObjectClass parent_class; +}; + +GType modest_tny_stream_webkit_get_type (void) G_GNUC_CONST; + + +/** + * modest_tny_stream_webkit_new: + * @stream: a #WebkitStream + * + * creates a new #ModestTnyStreamWebkit + * + * Returns: a new #ModestTnyStreamWebkit + **/ +GObject* modest_tny_stream_webkit_new (WebKitWebView *webview, + const gchar *mime_type, const gchar *encoding); + +/** + * modest_tny_stream_webkit_set_max_size: + * @stream: a #ModestTnyStreamWebkit + * @max_size: a #gssize + * + * set @max_size as the maximum size @stream will process + */ +void modest_tny_stream_webkit_set_max_size (ModestTnyStreamWebkit *stream, gssize max_size); + +/** + * modest_tny_stream_webkit_get_max_size: + * @stream: a #ModestTnyStreamWebkit + * + * obtain the maximum size @stream will process + * + * Returns: a #gssize (or 0 if unlimited) + */ +gssize modest_tny_stream_webkit_get_max_size (ModestTnyStreamWebkit *stream); + +/** + * modest_tny_stream_webkit_limit_reached: + * @self: a #ModestTnyStreamWebkit + * + * tells if on processing the stream, the max size limit has been hit. + * + * Returns: %TRUE if limit is reached, %FALSE otherwise. + */ +gboolean modest_tny_stream_webkit_limit_reached (ModestTnyStreamWebkit *self); + +G_END_DECLS + +#endif /* __MODEST_TNY_STREAM_WEBKIT_H__ */ + diff --git a/src/widgets/modest-webkit-mime-part-view.c b/src/widgets/modest-webkit-mime-part-view.c new file mode 100644 index 0000000..51de7ea --- /dev/null +++ b/src/widgets/modest-webkit-mime-part-view.c @@ -0,0 +1,858 @@ +/* Copyright (c) 2006, 2007, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "modest-tny-mime-part.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* gobject structure methods */ +static void modest_webkit_mime_part_view_class_init (ModestWebkitMimePartViewClass *klass); +static void tny_mime_part_view_init (gpointer g, gpointer iface_data); +static void modest_mime_part_view_init (gpointer g, gpointer iface_data); +static void modest_zoomable_init (gpointer g, gpointer iface_data); +static void modest_isearch_view_init (gpointer g, gpointer iface_data); +static void modest_webkit_mime_part_view_init (ModestWebkitMimePartView *self); +static void modest_webkit_mime_part_view_finalize (GObject *self); +static void modest_webkit_mime_part_view_dispose (GObject *self); + +/* Webkit signal handlers */ +static void on_notify_style (GObject *obj, GParamSpec *spec, gpointer userdata); +static gboolean update_style (ModestWebkitMimePartView *self); +/* TnyMimePartView implementation */ +static void modest_webkit_mime_part_view_clear (TnyMimePartView *self); +static void modest_webkit_mime_part_view_clear_default (TnyMimePartView *self); +static void modest_webkit_mime_part_view_set_part (TnyMimePartView *self, TnyMimePart *part); +static void modest_webkit_mime_part_view_set_part_default (TnyMimePartView *self, TnyMimePart *part); +static TnyMimePart* modest_webkit_mime_part_view_get_part (TnyMimePartView *self); +static TnyMimePart* modest_webkit_mime_part_view_get_part_default (TnyMimePartView *self); +/* ModestMimePartView implementation */ +static gboolean modest_webkit_mime_part_view_is_empty (ModestMimePartView *self); +static gboolean modest_webkit_mime_part_view_is_empty_default (ModestMimePartView *self); +static gboolean modest_webkit_mime_part_view_get_view_images (ModestMimePartView *self); +static gboolean modest_webkit_mime_part_view_get_view_images_default (ModestMimePartView *self); +static void modest_webkit_mime_part_view_set_view_images (ModestMimePartView *self, gboolean view_images); +static void modest_webkit_mime_part_view_set_view_images_default (ModestMimePartView *self, gboolean view_images); +static gboolean modest_webkit_mime_part_view_has_external_images (ModestMimePartView *self); +static gboolean modest_webkit_mime_part_view_has_external_images_default (ModestMimePartView *self); +/* ModestZoomable implementation */ +static gdouble modest_webkit_mime_part_view_get_zoom (ModestZoomable *self); +static void modest_webkit_mime_part_view_set_zoom (ModestZoomable *self, gdouble value); +static gboolean modest_webkit_mime_part_view_zoom_minus (ModestZoomable *self); +static gboolean modest_webkit_mime_part_view_zoom_plus (ModestZoomable *self); +static gdouble modest_webkit_mime_part_view_get_zoom_default (ModestZoomable *self); +static void modest_webkit_mime_part_view_set_zoom_default (ModestZoomable *self, gdouble value); +static gboolean modest_webkit_mime_part_view_zoom_minus_default (ModestZoomable *self); +static gboolean modest_webkit_mime_part_view_zoom_plus_default (ModestZoomable *self); +/* ModestISearchView implementation */ +static gboolean modest_webkit_mime_part_view_search (ModestISearchView *self, const gchar *string); +static gboolean modest_webkit_mime_part_view_search_next (ModestISearchView *self); +static gboolean modest_webkit_mime_part_view_get_selection_area (ModestISearchView *self, gint *x, gint *y, + gint *width, gint *height); +static gboolean modest_webkit_mime_part_view_search_default (ModestISearchView *self, const gchar *string); +static gboolean modest_webkit_mime_part_view_search_next_default (ModestISearchView *self); +static gboolean modest_webkit_mime_part_view_get_selection_area_default (ModestISearchView *self, gint *x, gint *y, + gint *width, gint *height); + + +/* internal api */ +static TnyMimePart *get_part (ModestWebkitMimePartView *self); +static void set_html_part (ModestWebkitMimePartView *self, TnyMimePart *part, const gchar *encoding); +static void set_text_part (ModestWebkitMimePartView *self, TnyMimePart *part); +static void set_empty_part (ModestWebkitMimePartView *self); +static void set_part (ModestWebkitMimePartView *self, TnyMimePart *part); +static gboolean is_empty (ModestWebkitMimePartView *self); +static gboolean get_view_images (ModestWebkitMimePartView *self); +static void set_view_images (ModestWebkitMimePartView *self, gboolean view_images); +static gboolean has_external_images (ModestWebkitMimePartView *self); +static void set_zoom (ModestWebkitMimePartView *self, gdouble zoom); +static gdouble get_zoom (ModestWebkitMimePartView *self); +static gboolean search (ModestWebkitMimePartView *self, const gchar *string); +static gboolean search_next (ModestWebkitMimePartView *self); +static gboolean get_selection_area (ModestWebkitMimePartView *self, gint *x, gint *y, + gint *width, gint *height); + +typedef struct _ModestWebkitMimePartViewPrivate ModestWebkitMimePartViewPrivate; +struct _ModestWebkitMimePartViewPrivate { + TnyMimePart *part; + gdouble current_zoom; + gboolean view_images; + gboolean has_external_images; + GSList *sighandlers; +}; + +#define MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_WEBKIT_MIME_PART_VIEW, \ + ModestWebkitMimePartViewPrivate)) + +enum { + STOP_STREAMS_SIGNAL, + LIMIT_ERROR_SIGNAL, + LAST_SIGNAL +}; + +static WebKitWebViewClass *parent_class = NULL; + +static guint signals[LAST_SIGNAL] = {0}; + +GtkWidget * +modest_webkit_mime_part_view_new () +{ + return g_object_new (MODEST_TYPE_WEBKIT_MIME_PART_VIEW, NULL); +} + +/* GOBJECT IMPLEMENTATION */ +GType +modest_webkit_mime_part_view_get_type (void) +{ + static GType my_type = 0; + if (!my_type) { + static const GTypeInfo my_info = { + sizeof(ModestWebkitMimePartViewClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc) modest_webkit_mime_part_view_class_init, + NULL, /* class finalize */ + NULL, /* class data */ + sizeof(ModestWebkitMimePartView), + 1, /* n_preallocs */ + (GInstanceInitFunc) modest_webkit_mime_part_view_init, + NULL + }; + + static const GInterfaceInfo tny_mime_part_view_info = + { + (GInterfaceInitFunc) tny_mime_part_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_mime_part_view_info = + { + (GInterfaceInitFunc) modest_mime_part_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_zoomable_info = + { + (GInterfaceInitFunc) modest_zoomable_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_isearch_view_info = + { + (GInterfaceInitFunc) modest_isearch_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + my_type = g_type_register_static (WEBKIT_TYPE_WEB_VIEW, + "ModestWebkitMimePartView", + &my_info, 0); + + g_type_add_interface_static (my_type, TNY_TYPE_MIME_PART_VIEW, + &tny_mime_part_view_info); + + g_type_add_interface_static (my_type, MODEST_TYPE_MIME_PART_VIEW, + &modest_mime_part_view_info); + + g_type_add_interface_static (my_type, MODEST_TYPE_ZOOMABLE, + &modest_zoomable_info); + g_type_add_interface_static (my_type, MODEST_TYPE_ISEARCH_VIEW, + &modest_isearch_view_info); + } + return my_type; +} + +static void +modest_webkit_mime_part_view_class_init (ModestWebkitMimePartViewClass *klass) +{ + GObjectClass *gobject_class; + GtkBindingSet *binding_set; + + gobject_class = (GObjectClass*) klass; + + parent_class = g_type_class_peek_parent (klass); + gobject_class->dispose = modest_webkit_mime_part_view_dispose; + gobject_class->finalize = modest_webkit_mime_part_view_finalize; + + klass->get_part_func = modest_webkit_mime_part_view_get_part_default; + klass->set_part_func = modest_webkit_mime_part_view_set_part_default; + klass->clear_func = modest_webkit_mime_part_view_clear_default; + klass->is_empty_func = modest_webkit_mime_part_view_is_empty_default; + klass->get_view_images_func = modest_webkit_mime_part_view_get_view_images_default; + klass->set_view_images_func = modest_webkit_mime_part_view_set_view_images_default; + klass->has_external_images_func = modest_webkit_mime_part_view_has_external_images_default; + klass->get_zoom_func = modest_webkit_mime_part_view_get_zoom_default; + klass->set_zoom_func = modest_webkit_mime_part_view_set_zoom_default; + klass->zoom_minus_func = modest_webkit_mime_part_view_zoom_minus_default; + klass->zoom_plus_func = modest_webkit_mime_part_view_zoom_plus_default; + klass->search_func = modest_webkit_mime_part_view_search_default; + klass->search_next_func = modest_webkit_mime_part_view_search_next_default; + klass->get_selection_area_func = modest_webkit_mime_part_view_get_selection_area_default; + + binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_skip (binding_set, GDK_Down, 0); + gtk_binding_entry_skip (binding_set, GDK_Up, 0); + gtk_binding_entry_skip (binding_set, GDK_KP_Up, 0); + gtk_binding_entry_skip (binding_set, GDK_KP_Down, 0); + gtk_binding_entry_skip (binding_set, GDK_Page_Down, 0); + gtk_binding_entry_skip (binding_set, GDK_Page_Up, 0); + gtk_binding_entry_skip (binding_set, GDK_KP_Page_Up, 0); + gtk_binding_entry_skip (binding_set, GDK_KP_Page_Down, 0); + gtk_binding_entry_skip (binding_set, GDK_Home, 0); + gtk_binding_entry_skip (binding_set, GDK_End, 0); + gtk_binding_entry_skip (binding_set, GDK_KP_Home, 0); + gtk_binding_entry_skip (binding_set, GDK_KP_End, 0); + + g_type_class_add_private (gobject_class, sizeof(ModestWebkitMimePartViewPrivate)); + + signals[STOP_STREAMS_SIGNAL] = + g_signal_new ("stop-streams", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestWebkitMimePartViewClass,stop_streams), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[LIMIT_ERROR_SIGNAL] = + g_signal_new ("limit-error", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestWebkitMimePartViewClass,limit_error), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + +static void +modest_webkit_mime_part_view_init (ModestWebkitMimePartView *self) +{ + ModestWebkitMimePartViewPrivate *priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (self); + GdkColor base; + GdkColor text; + + gdk_color_parse ("#fff", &base); + gdk_color_parse ("#000", &text); + gtk_widget_modify_base (GTK_WIDGET (self), GTK_STATE_NORMAL, &base); + gtk_widget_modify_text (GTK_WIDGET (self), GTK_STATE_NORMAL, &text); + + priv->sighandlers = NULL; + + priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, + G_OBJECT(self), "notify::style", + G_CALLBACK (on_notify_style), (gpointer) self); + + priv->part = NULL; + priv->current_zoom = 1.0; + priv->view_images = FALSE; + priv->has_external_images = FALSE; +} + +static void +modest_webkit_mime_part_view_finalize (GObject *obj) +{ + ModestWebkitMimePartViewPrivate *priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (obj); + + modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers); + priv->sighandlers = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +static void +modest_webkit_mime_part_view_dispose (GObject *obj) +{ + ModestWebkitMimePartViewPrivate *priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (obj); + + g_signal_emit (G_OBJECT (obj), signals[STOP_STREAMS_SIGNAL], 0); + + if (priv->part) { + g_object_unref (priv->part); + priv->part = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (obj); +} + +/* WEBKIT SIGNALS HANDLERS */ + +static void +on_notify_style (GObject *obj, GParamSpec *spec, gpointer userdata) +{ + if (strcmp ("style", spec->name) == 0) { + g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc) update_style, + g_object_ref (obj), g_object_unref); + gtk_widget_queue_draw (GTK_WIDGET (obj)); + } +} + +gboolean +same_color (GdkColor *a, GdkColor *b) +{ + return ((a->red == b->red) && + (a->green == b->green) && + (a->blue == b->blue)); +} + +static gboolean +update_style (ModestWebkitMimePartView *self) +{ + GdkColor base; + GdkColor text; + GtkRcStyle *rc_style; + + gdk_threads_enter (); + + if (GTK_WIDGET_VISIBLE (self)) { + rc_style = gtk_widget_get_modifier_style (GTK_WIDGET (self)); + + gdk_color_parse ("#fff", &base); + gdk_color_parse ("#000", &text); + + if (!same_color (&(rc_style->base[GTK_STATE_NORMAL]), &base) && + !same_color (&(rc_style->text[GTK_STATE_NORMAL]), &text)) { + + rc_style->base[GTK_STATE_NORMAL] = base; + rc_style->text[GTK_STATE_NORMAL] = text; + gtk_widget_modify_style (GTK_WIDGET (self), rc_style); + } + } + + gdk_threads_leave (); + + return FALSE; +} + + +/* INTERNAL API */ +static void +decode_to_stream_cb (TnyMimePart *self, + gboolean cancelled, + TnyStream *stream, + GError *err, + gpointer user_data) +{ + ModestWebkitMimePartView *view = (ModestWebkitMimePartView *) user_data; + + if (MODEST_IS_STREAM_TEXT_TO_HTML (stream)) { + if (tny_stream_write (stream, "\n", 1) == -1) { + g_warning ("failed to write CR in %s", __FUNCTION__); + } + if (modest_stream_text_to_html_limit_reached (MODEST_STREAM_TEXT_TO_HTML (stream))) { + g_signal_emit (G_OBJECT (view), signals[LIMIT_ERROR_SIGNAL], 0); + } + tny_stream_reset (stream); + } else { + if (modest_tny_stream_webkit_limit_reached (MODEST_TNY_STREAM_WEBKIT (stream))) { + g_signal_emit (G_OBJECT (view), signals[LIMIT_ERROR_SIGNAL], 0); + } + } + tny_stream_close (stream); +} + +static void +set_html_part (ModestWebkitMimePartView *self, TnyMimePart *part, const gchar *encoding) +{ + TnyStream *tny_stream; + + g_return_if_fail (self); + g_return_if_fail (part); + + g_signal_emit (G_OBJECT (self), signals[STOP_STREAMS_SIGNAL], 0); + + tny_stream = TNY_STREAM(modest_tny_stream_webkit_new (WEBKIT_WEB_VIEW (self), "text/html", encoding)); + modest_tny_stream_webkit_set_max_size (MODEST_TNY_STREAM_WEBKIT (tny_stream), 128*1024); + tny_stream_reset (tny_stream); + + tny_mime_part_decode_to_stream_async (TNY_MIME_PART (part), + tny_stream, decode_to_stream_cb, + NULL, self); + g_object_unref (tny_stream); +} + +static void +set_text_part (ModestWebkitMimePartView *self, TnyMimePart *part) +{ + TnyStream* text_to_html_stream, *tny_stream; + + g_return_if_fail (self); + g_return_if_fail (part); + + g_signal_emit (G_OBJECT (self), signals[STOP_STREAMS_SIGNAL], 0); + + tny_stream = TNY_STREAM(modest_tny_stream_webkit_new (WEBKIT_WEB_VIEW (self), "text/html", "utf-8")); + modest_tny_stream_webkit_set_max_size (MODEST_TNY_STREAM_WEBKIT (tny_stream), 128*1024); + text_to_html_stream = TNY_STREAM (modest_stream_text_to_html_new (tny_stream)); + modest_stream_text_to_html_set_linkify_limit (MODEST_STREAM_TEXT_TO_HTML (text_to_html_stream), + 64*1024); + modest_stream_text_to_html_set_full_limit (MODEST_STREAM_TEXT_TO_HTML (text_to_html_stream), + 128*1024); + modest_stream_text_to_html_set_line_limit (MODEST_STREAM_TEXT_TO_HTML (text_to_html_stream), + 1024); + + tny_mime_part_decode_to_stream_async (TNY_MIME_PART (part), + text_to_html_stream, decode_to_stream_cb, + NULL, self); + + g_object_unref (G_OBJECT(text_to_html_stream)); + g_object_unref (G_OBJECT(tny_stream)); +} + +static void +set_empty_part (ModestWebkitMimePartView *self) +{ + g_return_if_fail (self); + + g_signal_emit (G_OBJECT (self), signals[STOP_STREAMS_SIGNAL], 0); + webkit_web_view_load_string (WEBKIT_WEB_VIEW (self), "", "text/plain", "utf-8", NULL); +} + +static void +set_part (ModestWebkitMimePartView *self, TnyMimePart *part) +{ + ModestWebkitMimePartViewPrivate *priv; + gchar *header_content_type, *header_content_type_lower; + const gchar *tmp; + gchar *charset = NULL; + + g_return_if_fail (self); + + priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE(self); + priv->has_external_images = FALSE; + + if (part != priv->part) { + if (priv->part) + g_object_unref (G_OBJECT(priv->part)); + if (part) + g_object_ref (G_OBJECT(part)); + priv->part = part; + } + + if (!part) { + set_empty_part (self); + return; + } + + header_content_type = modest_tny_mime_part_get_header_value (part, "Content-Type"); + if (header_content_type) { + header_content_type = g_strstrip (header_content_type); + header_content_type_lower = g_ascii_strdown (header_content_type, -1); + } else { + header_content_type_lower = NULL; + } + + if (header_content_type_lower) { + tmp = strstr (header_content_type_lower, "charset="); + if (tmp) { + const gchar *tmp2; + tmp = tmp + strlen ("charset="); + + tmp2 = strstr (tmp, ";"); + if (tmp2) { + charset = g_strndup (tmp, tmp2-tmp); + } else { + charset = g_strdup (tmp); + } + } + } + + if (tny_mime_part_content_type_is (part, "text/html")) { + set_html_part (self, part, charset); + } else { + if (tny_mime_part_content_type_is (part, "message/rfc822")) { + if (header_content_type) { + if (g_str_has_prefix (header_content_type_lower, "text/html")) + set_html_part (self, part, charset); + else + set_text_part (self, part); + + } else { + set_text_part (self, part); + } + } else { + set_text_part (self, part); + } + } + g_free (header_content_type_lower); + g_free (header_content_type); + +} + +static TnyMimePart* +get_part (ModestWebkitMimePartView *self) +{ + TnyMimePart *part; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MIME_PART_VIEW (self), NULL); + + part = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE(self)->part; + + if (part) + g_object_ref (part); + + return part; +} + +static gboolean +is_empty (ModestWebkitMimePartView *self) +{ + return FALSE; +} + +static gboolean +get_view_images (ModestWebkitMimePartView *self) +{ + ModestWebkitMimePartViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MIME_PART_VIEW (self), FALSE); + + priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (self); + return priv->view_images; +} + +static void +set_view_images (ModestWebkitMimePartView *self, gboolean view_images) +{ + ModestWebkitMimePartViewPrivate *priv; + + g_return_if_fail (MODEST_IS_WEBKIT_MIME_PART_VIEW (self)); + + priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (self); + priv->view_images = view_images; +} + +static gboolean +has_external_images (ModestWebkitMimePartView *self) +{ + ModestWebkitMimePartViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MIME_PART_VIEW (self), FALSE); + + priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (self); + return priv->has_external_images; +} + +static void +set_zoom (ModestWebkitMimePartView *self, gdouble zoom) +{ + ModestWebkitMimePartViewPrivate *priv; + + g_return_if_fail (MODEST_IS_WEBKIT_MIME_PART_VIEW (self)); + + priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (self); + priv->current_zoom = zoom; + + gtk_widget_queue_resize (GTK_WIDGET (self)); +} + +static gdouble +get_zoom (ModestWebkitMimePartView *self) +{ + ModestWebkitMimePartViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MIME_PART_VIEW (self), 1.0); + + priv = MODEST_WEBKIT_MIME_PART_VIEW_GET_PRIVATE (self); + + return priv->current_zoom; +} + +static gboolean +search (ModestWebkitMimePartView *self, + const gchar *string) +{ + return FALSE; +} + +static gboolean +search_next (ModestWebkitMimePartView *self) +{ + return FALSE; +} + +static gboolean +get_selection_area (ModestWebkitMimePartView *self, + gint *x, gint *y, + gint *width, gint *height) +{ + return FALSE; +} + + +/* TNY MIME PART IMPLEMENTATION */ + +static void +tny_mime_part_view_init (gpointer g, gpointer iface_data) +{ + TnyMimePartViewIface *klass = (TnyMimePartViewIface *)g; + + klass->get_part = modest_webkit_mime_part_view_get_part; + klass->set_part = modest_webkit_mime_part_view_set_part; + klass->clear = modest_webkit_mime_part_view_clear; + + return; +} + +static TnyMimePart* +modest_webkit_mime_part_view_get_part (TnyMimePartView *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->get_part_func (self); +} + + +static TnyMimePart* +modest_webkit_mime_part_view_get_part_default (TnyMimePartView *self) +{ + return TNY_MIME_PART (get_part (MODEST_WEBKIT_MIME_PART_VIEW (self))); +} + +static void +modest_webkit_mime_part_view_set_part (TnyMimePartView *self, + TnyMimePart *part) +{ + MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->set_part_func (self, part); +} + +static void +modest_webkit_mime_part_view_set_part_default (TnyMimePartView *self, + TnyMimePart *part) +{ + g_return_if_fail ((part == NULL) || TNY_IS_MIME_PART (part)); + + set_part (MODEST_WEBKIT_MIME_PART_VIEW (self), part); +} + +static void +modest_webkit_mime_part_view_clear (TnyMimePartView *self) +{ + MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->clear_func (self); +} + +static void +modest_webkit_mime_part_view_clear_default (TnyMimePartView *self) +{ + set_part (MODEST_WEBKIT_MIME_PART_VIEW (self), NULL); +} + +/* MODEST MIME PART VIEW IMPLEMENTATION */ + +static void +modest_mime_part_view_init (gpointer g, gpointer iface_data) +{ + ModestMimePartViewIface *klass = (ModestMimePartViewIface *)g; + + klass->is_empty_func = modest_webkit_mime_part_view_is_empty; + klass->get_view_images_func = modest_webkit_mime_part_view_get_view_images; + klass->set_view_images_func = modest_webkit_mime_part_view_set_view_images; + klass->has_external_images_func = modest_webkit_mime_part_view_has_external_images; + + return; +} + +static gboolean +modest_webkit_mime_part_view_is_empty (ModestMimePartView *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->is_empty_func (self); +} + +static gboolean +modest_webkit_mime_part_view_get_view_images (ModestMimePartView *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->get_view_images_func (self); +} + +static void +modest_webkit_mime_part_view_set_view_images (ModestMimePartView *self, gboolean view_images) +{ + MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->set_view_images_func (self, view_images); +} + +static gboolean +modest_webkit_mime_part_view_has_external_images (ModestMimePartView *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->has_external_images_func (self); +} + +static gboolean +modest_webkit_mime_part_view_is_empty_default (ModestMimePartView *self) +{ + return is_empty (MODEST_WEBKIT_MIME_PART_VIEW (self)); +} + +static gboolean +modest_webkit_mime_part_view_get_view_images_default (ModestMimePartView *self) +{ + return get_view_images (MODEST_WEBKIT_MIME_PART_VIEW (self)); +} + +static void +modest_webkit_mime_part_view_set_view_images_default (ModestMimePartView *self, gboolean view_images) +{ + set_view_images (MODEST_WEBKIT_MIME_PART_VIEW (self), view_images); +} + +static gboolean +modest_webkit_mime_part_view_has_external_images_default (ModestMimePartView *self) +{ + return has_external_images (MODEST_WEBKIT_MIME_PART_VIEW (self)); +} + + +/* MODEST ZOOMABLE IMPLEMENTATION */ +static void +modest_zoomable_init (gpointer g, gpointer iface_data) +{ + ModestZoomableIface *klass = (ModestZoomableIface *)g; + + klass->get_zoom_func = modest_webkit_mime_part_view_get_zoom; + klass->set_zoom_func = modest_webkit_mime_part_view_set_zoom; + klass->zoom_minus_func = modest_webkit_mime_part_view_zoom_minus; + klass->zoom_plus_func = modest_webkit_mime_part_view_zoom_plus; + + return; +} + +static gdouble +modest_webkit_mime_part_view_get_zoom (ModestZoomable *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->get_zoom_func (self); +} + +static gdouble +modest_webkit_mime_part_view_get_zoom_default (ModestZoomable *self) +{ + return get_zoom (MODEST_WEBKIT_MIME_PART_VIEW (self)); +} + +static void +modest_webkit_mime_part_view_set_zoom (ModestZoomable *self, gdouble value) +{ + MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->set_zoom_func (self, value); +} + +static void +modest_webkit_mime_part_view_set_zoom_default (ModestZoomable *self, gdouble value) +{ + set_zoom (MODEST_WEBKIT_MIME_PART_VIEW (self), value); +} + +static gboolean +modest_webkit_mime_part_view_zoom_minus (ModestZoomable *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->zoom_minus_func (self); +} + +static gboolean +modest_webkit_mime_part_view_zoom_minus_default (ModestZoomable *self) +{ + /* operation not supported in ModestWebkitMimePartView */ + return FALSE; +} + +static gboolean +modest_webkit_mime_part_view_zoom_plus (ModestZoomable *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->zoom_plus_func (self); +} + +static gboolean +modest_webkit_mime_part_view_zoom_plus_default (ModestZoomable *self) +{ + /* operation not supported in ModestWebkitMimePartView */ + return FALSE; +} + +/* ISEARCH VIEW IMPLEMENTATION */ +static void +modest_isearch_view_init (gpointer g, gpointer iface_data) +{ + ModestISearchViewIface *klass = (ModestISearchViewIface *)g; + + klass->search_func = modest_webkit_mime_part_view_search; + klass->search_next_func = modest_webkit_mime_part_view_search_next; + klass->get_selection_area_func = modest_webkit_mime_part_view_get_selection_area; + + return; +} + +static gboolean +modest_webkit_mime_part_view_search (ModestISearchView *self, const gchar *string) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->search_func (self, string); +} + +static gboolean +modest_webkit_mime_part_view_search_default (ModestISearchView *self, const gchar *string) +{ + return search (MODEST_WEBKIT_MIME_PART_VIEW (self), string); +} + +static gboolean +modest_webkit_mime_part_view_search_next(ModestISearchView *self) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->search_next_func (self); +} + +static gboolean +modest_webkit_mime_part_view_search_next_default (ModestISearchView *self) +{ + return search_next (MODEST_WEBKIT_MIME_PART_VIEW (self)); +} + +static gboolean +modest_webkit_mime_part_view_get_selection_area (ModestISearchView *self, gint *x, gint *y, + gint *width, gint *height) +{ + return MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS (self)->get_selection_area_func (self, x, y, width, height); +} + +static gboolean +modest_webkit_mime_part_view_get_selection_area_default (ModestISearchView *self, gint *x, gint *y, + gint *width, gint *height) +{ + return get_selection_area (MODEST_WEBKIT_MIME_PART_VIEW (self), x, y, width, height); +} diff --git a/src/widgets/modest-webkit-mime-part-view.h b/src/widgets/modest-webkit-mime-part-view.h new file mode 100644 index 0000000..36e0883 --- /dev/null +++ b/src/widgets/modest-webkit-mime-part-view.h @@ -0,0 +1,110 @@ +/* Copyright (c) 2009, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MODEST_WEBKIT_MIME_PART_VIEW_H__ +#define __MODEST_WEBKIT_MIME_PART_VIEW_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* convenience macros */ +#define MODEST_TYPE_WEBKIT_MIME_PART_VIEW (modest_webkit_mime_part_view_get_type()) +#define MODEST_WEBKIT_MIME_PART_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_WEBKIT_MIME_PART_VIEW,ModestWebkitMimePartView)) +#define MODEST_WEBKIT_MIME_PART_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_WEBKIT_MIME_PART_VIEW,ModestWebkitMimePartViewClass)) +#define MODEST_IS_WEBKIT_MIME_PART_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_WEBKIT_MIME_PART_VIEW)) +#define MODEST_IS_WEBKIT_MIME_PART_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_WEBKIT_MIME_PART_VIEW)) +#define MODEST_WEBKIT_MIME_PART_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_WEBKIT_MIME_PART_VIEW,ModestWebkitMimePartViewClass)) + +typedef struct _ModestWebkitMimePartView ModestWebkitMimePartView; +typedef struct _ModestWebkitMimePartViewClass ModestWebkitMimePartViewClass; + +struct _ModestWebkitMimePartView { + WebKitWebView parent; +}; + +struct _ModestWebkitMimePartViewClass { + WebKitWebViewClass parent_class; + + /* TnyMimePartView interface methods */ + TnyMimePart* (*get_part_func) (TnyMimePartView *self); + void (*set_part_func) (TnyMimePartView *self, TnyMimePart *part); + void (*clear_func) (TnyMimePartView *self); + /* ModestMimePartView interface methods */ + gboolean (*is_empty_func) (ModestMimePartView *self); + gboolean (*get_view_images_func) (ModestMimePartView *self); + void (*set_view_images_func) (ModestMimePartView *self, gboolean view_images); + gboolean (*has_external_images_func) (ModestMimePartView *self); + /* ModestZoomable interface methods */ + gdouble (*get_zoom_func) (ModestZoomable *self); + void (*set_zoom_func) (ModestZoomable *self, gdouble value); + gboolean (*zoom_minus_func) (ModestZoomable *self); + gboolean (*zoom_plus_func) (ModestZoomable *self); + /* ModestISearchView interface methods */ + gboolean (*search_func) (ModestISearchView *self, const gchar *string); + gboolean (*search_next_func) (ModestISearchView *self); + gboolean (*get_selection_area_func) (ModestISearchView *self, gint *x, gint *y, gint *width, gint *height); + + /* signals */ + void (*stop_streams) (ModestWebkitMimePartView *self); + void (*limit_error) (ModestWebkitMimePartView *self); +}; + + +/** + * + * modest_webkit_mime_part_view_get_type + * + * get the GType for the this class + * + * Returns: the GType for this class + */ +GType modest_webkit_mime_part_view_get_type (void) G_GNUC_CONST; + +/** + * modest_webkit_mime_part_view_new: + * + * create a new #ModestWebkitMimePartView instance, implementing + * interfaces #TnyMimePartView, #ModestMimePartView, #ModestZoomable + * and #ModestISearchView. + * + * Returns: a #ModestWebkitMimePartView + */ +GtkWidget *modest_webkit_mime_part_view_new (void); + +G_END_DECLS + +#endif /* __MODEST_GTK_HTML_MIME_PART_VIEW_H__ */ diff --git a/src/widgets/modest-webkit-msg-view.c b/src/widgets/modest-webkit-msg-view.c new file mode 100644 index 0000000..5a630ef --- /dev/null +++ b/src/widgets/modest-webkit-msg-view.c @@ -0,0 +1,1575 @@ +/* Copyright (c) 2006, 2007, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef MODEST_TOOLKIT_HILDON2 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* 'private'/'protected' functions */ +static void modest_webkit_msg_view_class_init (ModestWebkitMsgViewClass *klass); +static void tny_header_view_init (gpointer g, gpointer iface_data); +static void tny_msg_view_init (gpointer g, gpointer iface_data); +static void tny_mime_part_view_init (gpointer g, gpointer iface_data); +static void modest_mime_part_view_init (gpointer g, gpointer iface_data); +static void modest_zoomable_init (gpointer g, gpointer iface_data); +static void modest_isearch_view_init (gpointer g, gpointer iface_data); +static void modest_msg_view_init (gpointer g, gpointer iface_data); +static void modest_webkit_msg_view_init (ModestWebkitMsgView *obj); +static void modest_webkit_msg_view_finalize (GObject *obj); +static void modest_webkit_msg_view_destroy (GtkObject *obj); + +/* headers signals */ +static void on_recpt_activated (ModestMailHeaderView *header_view, const gchar *address, ModestWebkitMsgView *msg_view); +static void on_show_details (ModestMailHeaderView *header_view, ModestWebkitMsgView *msg_view); +static void on_attachment_activated (ModestAttachmentsView * att_view, TnyMimePart *mime_part, gpointer userdata); + +/* body view signals */ +static gboolean on_activate_link (GtkWidget *widget, const gchar *uri, ModestWebkitMsgView *msg_view); +static gboolean on_fetch_url (GtkWidget *widget, const gchar *uri, TnyStream *stream, + ModestWebkitMsgView *msg_view); +static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestWebkitMsgView *msg_view); +static void on_limit_error (GtkWidget *widget, ModestWebkitMsgView *msg_view); + +/* TnyMimePartView implementation */ +static void modest_msg_view_mp_clear (TnyMimePartView *self); +static void modest_msg_view_mp_set_part (TnyMimePartView *self, TnyMimePart *part); +static void modest_msg_view_mp_set_part_default (TnyMimePartView *self, TnyMimePart *part); +static TnyMimePart* modest_msg_view_mp_get_part (TnyMimePartView *self); +static TnyMimePart* modest_msg_view_mp_get_part_default (TnyMimePartView *self); +/* ModestMimePartView implementation */ +static gboolean modest_msg_view_mp_is_empty (ModestMimePartView *self); +static gboolean modest_msg_view_mp_is_empty_default (ModestMimePartView *self); +/* TnyHeaderView implementation */ +static void modest_msg_view_set_header (TnyHeaderView *self, TnyHeader *header); +static void modest_msg_view_set_header_default (TnyHeaderView *self, TnyHeader *header); +static void modest_msg_view_clear_header (TnyHeaderView *self); +static void modest_msg_view_clear_header_default (TnyHeaderView *self); +/* TnyMsgView implementation */ +static TnyMsg *modest_msg_view_get_msg (TnyMsgView *self); +static TnyMsg *modest_msg_view_get_msg_default (TnyMsgView *self); +static void modest_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg); +static void modest_msg_view_set_msg_default (TnyMsgView *self, TnyMsg *msg); +static void modest_msg_view_clear (TnyMsgView *self); +static void modest_msg_view_clear_default (TnyMsgView *self); +static void modest_msg_view_set_unavailable (TnyMsgView *self); +static void modest_msg_view_set_unavailable_default (TnyMsgView *self); +static TnyMimePartView *modest_msg_view_create_mime_part_view_for (TnyMsgView *self, TnyMimePart *part); +static TnyMimePartView *modest_msg_view_create_mime_part_view_for_default (TnyMsgView *self, TnyMimePart *part); +static TnyMsgView *modest_msg_view_create_new_inline_viewer (TnyMsgView *self); +static TnyMsgView *modest_msg_view_create_new_inline_viewer_default (TnyMsgView *self); +/* ModestZoomable implementation */ +static gdouble modest_msg_view_get_zoom (ModestZoomable *self); +static void modest_msg_view_set_zoom (ModestZoomable *self, gdouble value); +static gboolean modest_msg_view_zoom_minus (ModestZoomable *self); +static gboolean modest_msg_view_zoom_plus (ModestZoomable *self); +static gdouble modest_msg_view_get_zoom_default (ModestZoomable *self); +static void modest_msg_view_set_zoom_default (ModestZoomable *self, gdouble value); +static gboolean modest_msg_view_zoom_minus_default (ModestZoomable *self); +static gboolean modest_msg_view_zoom_plus_default (ModestZoomable *self); +/* ModestISearchView implementation */ +static gboolean modest_msg_view_search (ModestISearchView *self, const gchar *string); +static gboolean modest_msg_view_search_default (ModestISearchView *self, const gchar *string); +static gboolean modest_msg_view_search_next (ModestISearchView *self); +static gboolean modest_msg_view_search_next_default (ModestISearchView *self); +/* ModestMsgView implementation */ +static void modest_webkit_msg_view_set_msg_with_other_body (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body); +static GtkAdjustment *modest_webkit_msg_view_get_vadjustment (ModestMsgView *self); +static GtkAdjustment *modest_webkit_msg_view_get_hadjustment (ModestMsgView *self); +static void modest_webkit_msg_view_set_vadjustment (ModestMsgView *self, GtkAdjustment *vadj); +static void modest_webkit_msg_view_set_hadjustment (ModestMsgView *self, GtkAdjustment *hadj); +static void modest_webkit_msg_view_set_shadow_type (ModestMsgView *self, GtkShadowType type); +static GtkShadowType modest_webkit_msg_view_get_shadow_type (ModestMsgView *self); +static TnyHeaderFlags modest_webkit_msg_view_get_priority (ModestMsgView *self); +static void modest_webkit_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags); +static TnyList *modest_webkit_msg_view_get_selected_attachments (ModestMsgView *self); +static TnyList *modest_webkit_msg_view_get_attachments (ModestMsgView *self); +static void modest_webkit_msg_view_grab_focus (ModestMsgView *self); +static void modest_webkit_msg_view_remove_attachment (ModestMsgView *view, TnyMimePart *attachment); +static void modest_webkit_msg_view_request_fetch_images (ModestMsgView *view); +static void modest_webkit_msg_view_set_branding (ModestMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); +static gboolean modest_webkit_msg_view_has_blocked_external_images (ModestMsgView *view); +static void modest_webkit_msg_view_set_msg_with_other_body_default (ModestMsgView *view, TnyMsg *msg, TnyMimePart *part); +static GtkAdjustment *modest_webkit_msg_view_get_vadjustment_default (ModestMsgView *self); +static GtkAdjustment *modest_webkit_msg_view_get_hadjustment_default (ModestMsgView *self); +static void modest_webkit_msg_view_set_vadjustment_default (ModestMsgView *self, GtkAdjustment *vadj); +static void modest_webkit_msg_view_set_hadjustment_default (ModestMsgView *self, GtkAdjustment *hadj); +static void modest_webkit_msg_view_set_shadow_type_default (ModestMsgView *self, GtkShadowType type); +static GtkShadowType modest_webkit_msg_view_get_shadow_type_default (ModestMsgView *self); +static TnyHeaderFlags modest_webkit_msg_view_get_priority_default (ModestMsgView *self); +static void modest_webkit_msg_view_set_priority_default (ModestMsgView *self, TnyHeaderFlags flags); +static TnyList *modest_webkit_msg_view_get_selected_attachments_default (ModestMsgView *self); +static TnyList *modest_webkit_msg_view_get_attachments_default (ModestMsgView *self); +static void modest_webkit_msg_view_grab_focus_default (ModestMsgView *self); +static void modest_webkit_msg_view_remove_attachment_default (ModestMsgView *view, TnyMimePart *attachment); +static gboolean modest_webkit_msg_view_has_blocked_external_images_default (ModestMsgView *view); +static void modest_webkit_msg_view_request_fetch_images_default (ModestMsgView *view); +static void modest_webkit_msg_view_set_branding_default (ModestMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); + +/* internal api */ +static void set_header (ModestWebkitMsgView *self, TnyHeader *header); +static TnyMsg *get_message (ModestWebkitMsgView *self); +static void set_message (ModestWebkitMsgView *self, TnyMsg *tny_msg, TnyMimePart *other_body); +static gboolean is_empty (ModestWebkitMsgView *self); +static void set_zoom (ModestWebkitMsgView *self, gdouble zoom); +static gdouble get_zoom (ModestWebkitMsgView *self); +static gboolean search (ModestWebkitMsgView *self, const gchar *search); +static gboolean search_next (ModestWebkitMsgView *self); +static GtkAdjustment *get_vadjustment (ModestWebkitMsgView *self); +static GtkAdjustment *get_hadjustment (ModestWebkitMsgView *self); +static void set_vadjustment (ModestWebkitMsgView *self, GtkAdjustment *vadj); +static void set_hadjustment (ModestWebkitMsgView *self, GtkAdjustment *hadj); +static void set_shadow_type (ModestWebkitMsgView *self, GtkShadowType type); +static GtkShadowType get_shadow_type (ModestWebkitMsgView *self); +static TnyHeaderFlags get_priority (ModestWebkitMsgView *self); +static void set_priority (ModestWebkitMsgView *self, TnyHeaderFlags flags); +static TnyList *get_selected_attachments (ModestWebkitMsgView *self); +static TnyList *get_attachments (ModestWebkitMsgView *self); +static void grab_focus (ModestWebkitMsgView *self); +static void remove_attachment (ModestWebkitMsgView *view, TnyMimePart *attachment); +static void request_fetch_images (ModestWebkitMsgView *view); +static void set_branding (ModestWebkitMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); +static gboolean has_blocked_external_images (ModestWebkitMsgView *view); + +typedef struct _ModestWebkitMsgViewPrivate ModestWebkitMsgViewPrivate; +struct _ModestWebkitMsgViewPrivate { + GtkWidget *body_view; + GtkWidget *mail_header_view; + GtkWidget *attachments_view; + + TnyMsg *msg; + + /* embedded elements */ + GtkWidget *headers_box; + GtkWidget *attachments_box; + + GtkWidget *priority_box; + GtkWidget *priority_icon; + + /* zoom */ + gdouble current_zoom; + + /* link click management */ + gchar *last_url; +}; + +#define MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_WEBKIT_MSG_VIEW, \ + ModestWebkitMsgViewPrivate)) + +/* globals */ +static GtkContainerClass *parent_class = NULL; + +GType +modest_webkit_msg_view_get_type (void) +{ + static GType my_type = 0; + if (!my_type) { + static const GTypeInfo my_info = { + sizeof(ModestWebkitMsgViewClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc) modest_webkit_msg_view_class_init, + NULL, /* class finalize */ + NULL, /* class data */ + sizeof(ModestWebkitMsgView), + 1, /* n_preallocs */ + (GInstanceInitFunc) modest_webkit_msg_view_init, + NULL + }; + static const GInterfaceInfo tny_msg_view_info = + { + (GInterfaceInitFunc) tny_msg_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo tny_mime_part_view_info = + { + (GInterfaceInitFunc) tny_mime_part_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo tny_header_view_info = + { + (GInterfaceInitFunc) tny_header_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_mime_part_view_info = + { + (GInterfaceInitFunc) modest_mime_part_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_zoomable_info = + { + (GInterfaceInitFunc) modest_zoomable_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_isearch_view_info = + { + (GInterfaceInitFunc) modest_isearch_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + static const GInterfaceInfo modest_msg_view_info = + { + (GInterfaceInitFunc) modest_msg_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + my_type = g_type_register_static (GTK_TYPE_VIEWPORT, + "ModestWebkitMsgView", + &my_info, 0); + + g_type_add_interface_static (my_type, TNY_TYPE_HEADER_VIEW, + &tny_header_view_info); + + g_type_add_interface_static (my_type, TNY_TYPE_MIME_PART_VIEW, + &tny_mime_part_view_info); + + g_type_add_interface_static (my_type, MODEST_TYPE_MIME_PART_VIEW, + &modest_mime_part_view_info); + + g_type_add_interface_static (my_type, TNY_TYPE_MSG_VIEW, + &tny_msg_view_info); + + g_type_add_interface_static (my_type, MODEST_TYPE_ZOOMABLE, + &modest_zoomable_info); + + g_type_add_interface_static (my_type, MODEST_TYPE_ISEARCH_VIEW, + &modest_isearch_view_info); + + g_type_add_interface_static (my_type, MODEST_TYPE_MSG_VIEW, + &modest_msg_view_info); + } + return my_type; +} + +static void +modest_webkit_msg_view_class_init (ModestWebkitMsgViewClass *klass) +{ + GObjectClass *gobject_class; + GtkWidgetClass *widget_class; + GtkObjectClass *gtkobject_class; + GtkContainerClass *container_class; + gobject_class = (GObjectClass*) klass; + widget_class = (GtkWidgetClass *) klass; + gtkobject_class = (GtkObjectClass *) klass; + container_class = (GtkContainerClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + gobject_class->finalize = modest_webkit_msg_view_finalize; + gtkobject_class->destroy = modest_webkit_msg_view_destroy; + + klass->set_header_func = modest_msg_view_set_header_default; + klass->clear_header_func = modest_msg_view_clear_header_default; + klass->get_part_func = modest_msg_view_mp_get_part_default; + klass->set_part_func = modest_msg_view_mp_set_part_default; + klass->is_empty_func = modest_msg_view_mp_is_empty_default; + klass->get_msg_func = modest_msg_view_get_msg_default; + klass->set_msg_func = modest_msg_view_set_msg_default; + klass->set_unavailable_func = modest_msg_view_set_unavailable_default; + klass->clear_func = modest_msg_view_clear_default; + klass->create_mime_part_view_for_func = modest_msg_view_create_mime_part_view_for_default; + klass->create_new_inline_viewer_func = modest_msg_view_create_new_inline_viewer_default; + klass->get_zoom_func = modest_msg_view_get_zoom_default; + klass->set_zoom_func = modest_msg_view_set_zoom_default; + klass->zoom_minus_func = modest_msg_view_zoom_minus_default; + klass->zoom_plus_func = modest_msg_view_zoom_plus_default; + klass->search_func = modest_msg_view_search_default; + klass->search_next_func = modest_msg_view_search_next_default; + klass->set_msg_with_other_body_func = modest_webkit_msg_view_set_msg_with_other_body_default; + klass->get_vadjustment_func = modest_webkit_msg_view_get_vadjustment_default; + klass->get_hadjustment_func = modest_webkit_msg_view_get_hadjustment_default; + klass->set_vadjustment_func = modest_webkit_msg_view_set_vadjustment_default; + klass->set_hadjustment_func = modest_webkit_msg_view_set_hadjustment_default; + klass->get_shadow_type_func = modest_webkit_msg_view_get_shadow_type_default; + klass->set_shadow_type_func = modest_webkit_msg_view_set_shadow_type_default; + klass->get_priority_func = modest_webkit_msg_view_get_priority_default; + klass->set_priority_func = modest_webkit_msg_view_set_priority_default; + klass->get_selected_attachments_func = modest_webkit_msg_view_get_selected_attachments_default; + klass->get_attachments_func = modest_webkit_msg_view_get_attachments_default; + klass->grab_focus_func = modest_webkit_msg_view_grab_focus_default; + klass->remove_attachment_func = modest_webkit_msg_view_remove_attachment_default; + klass->request_fetch_images_func = modest_webkit_msg_view_request_fetch_images_default; + klass->set_branding_func = modest_webkit_msg_view_set_branding_default; + klass->has_blocked_external_images_func = modest_webkit_msg_view_has_blocked_external_images_default; + + g_type_class_add_private (gobject_class, sizeof(ModestWebkitMsgViewPrivate)); + +} + +static void +modest_webkit_msg_view_init (ModestWebkitMsgView *obj) +{ + ModestWebkitMsgViewPrivate *priv; + GtkWidget *vbox; + + GTK_WIDGET_UNSET_FLAGS (obj, GTK_NO_WINDOW); + gtk_widget_set_redraw_on_allocate (GTK_WIDGET (obj), TRUE); + gtk_container_set_reallocate_redraws (GTK_CONTAINER (obj), TRUE); + gtk_container_set_resize_mode (GTK_CONTAINER (obj), GTK_RESIZE_QUEUE); + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE(obj); + + vbox = gtk_vbox_new (FALSE, 0); + + priv->current_zoom = 1.0; + + priv->msg = NULL; + + priv->body_view = GTK_WIDGET (g_object_new (MODEST_TYPE_WEBKIT_MIME_PART_VIEW, NULL)); + priv->mail_header_view = GTK_WIDGET (modest_compact_mail_header_view_new ()); + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); + priv->attachments_view = GTK_WIDGET(modest_attachments_view_new (NULL)); + +#ifdef MODEST_TOOLKIT_HILDON2 + modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), + MODEST_ATTACHMENTS_VIEW_STYLE_LINKS); +#else + modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), + MODEST_ATTACHMENTS_VIEW_STYLE_SELECTABLE); +#endif + + g_signal_connect (G_OBJECT(priv->body_view), "activate_link", + G_CALLBACK(on_activate_link), obj); + g_signal_connect (G_OBJECT(priv->body_view), "fetch_url", + G_CALLBACK(on_fetch_url), obj); + g_signal_connect (G_OBJECT(priv->body_view), "link_hover", + G_CALLBACK(on_link_hover), obj); + g_signal_connect (G_OBJECT(priv->body_view), "limit_error", + G_CALLBACK(on_limit_error), obj); + + g_signal_connect (G_OBJECT (priv->mail_header_view), "recpt-activated", + G_CALLBACK (on_recpt_activated), obj); + g_signal_connect (G_OBJECT (priv->mail_header_view), "show-details", + G_CALLBACK (on_show_details), obj); + + g_signal_connect (G_OBJECT (priv->attachments_view), "activate", + G_CALLBACK (on_attachment_activated), obj); + + priv->headers_box = gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT); + gtk_box_pack_start (GTK_BOX (vbox), priv->headers_box, FALSE, FALSE, 0); + + if (priv->mail_header_view) + gtk_box_pack_start (GTK_BOX(priv->headers_box), priv->mail_header_view, FALSE, FALSE, 0); + + priv->priority_icon = gtk_image_new (); + gtk_misc_set_alignment (GTK_MISC (priv->priority_icon), 0.0, 0.5); + if (priv->priority_icon) { + priv->priority_box = (GtkWidget *) + modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), + _("mcen_me_editor_message_priority"), + priv->priority_icon, + FALSE, FALSE); + + gtk_widget_hide_all (priv->priority_box); + } + if (priv->attachments_view) { + gchar *att_label = g_strconcat (_("mail_va_attachment"), ":", NULL); + + priv->attachments_box = (GtkWidget *) + modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), + att_label, + priv->attachments_view, + FALSE, FALSE); + gtk_widget_hide_all (priv->attachments_box); + g_free (att_label); + } + + + if (priv->body_view) { + gtk_box_pack_start (GTK_BOX (vbox), priv->body_view, TRUE, TRUE, 0); + } + + gtk_container_add (GTK_CONTAINER (obj), vbox); + +} + + +static void +modest_webkit_msg_view_finalize (GObject *obj) +{ + ModestWebkitMsgViewPrivate *priv; + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (obj); + + if (priv->msg) { + g_object_unref (G_OBJECT(priv->msg)); + priv->msg = NULL; + } + + priv->body_view = NULL; + priv->attachments_view = NULL; + + G_OBJECT_CLASS(parent_class)->finalize (obj); +} + +static void +modest_webkit_msg_view_destroy (GtkObject *obj) +{ + + GTK_OBJECT_CLASS(parent_class)->destroy (obj); +} + +static GtkAdjustment * +get_vadjustment (ModestWebkitMsgView *self) +{ + return gtk_viewport_get_vadjustment (GTK_VIEWPORT (self)); +} + +static GtkAdjustment * +get_hadjustment (ModestWebkitMsgView *self) +{ + return gtk_viewport_get_hadjustment (GTK_VIEWPORT (self)); +} + +static void +set_hadjustment (ModestWebkitMsgView *self, GtkAdjustment *hadj) +{ + gtk_viewport_set_hadjustment (GTK_VIEWPORT (self), hadj); +} + +static void +set_vadjustment (ModestWebkitMsgView *self, GtkAdjustment *vadj) +{ + gtk_viewport_set_vadjustment (GTK_VIEWPORT (self), vadj); +} + +static void +set_shadow_type (ModestWebkitMsgView *self, + GtkShadowType shadow_type) +{ + gtk_viewport_set_shadow_type (GTK_VIEWPORT (self), shadow_type); +} + +static GtkShadowType +get_shadow_type (ModestWebkitMsgView *self) +{ + return gtk_viewport_get_shadow_type (GTK_VIEWPORT (self)); +} + +/* INTERNAL METHODS */ +GtkWidget* +modest_msg_view_new (TnyMsg *msg) +{ + GObject *obj; + ModestWebkitMsgView* self; + + obj = G_OBJECT(g_object_new(MODEST_TYPE_WEBKIT_MSG_VIEW, NULL)); + self = MODEST_WEBKIT_MSG_VIEW(obj); + tny_msg_view_set_msg (TNY_MSG_VIEW (self), msg); + + return GTK_WIDGET(self); +} + + +static void +on_recpt_activated (ModestMailHeaderView *header_view, + const gchar *address, + ModestWebkitMsgView *self) +{ + g_signal_emit_by_name (G_OBJECT (self), "recpt-activated", address); +} + +static void +on_show_details (ModestMailHeaderView *header_view, + ModestWebkitMsgView *self) +{ + g_signal_emit_by_name (G_OBJECT (self), "show-details"); +} + +static void +on_attachment_activated (ModestAttachmentsView * att_view, TnyMimePart *mime_part, gpointer self) +{ + + g_signal_emit_by_name (G_OBJECT(self), "attachment_clicked", mime_part); +} + +static void +request_fetch_images (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + TnyMimePart *part; + + /* The message could have not been downloaded yet */ + if (priv->msg) { + modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), TRUE); + part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (priv->body_view)); + if (part) { + tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (priv->body_view), part); + g_object_unref (part); + } + tny_msg_set_allow_external_images (TNY_MSG (priv->msg), TRUE); + } +} + +static void +set_branding (ModestWebkitMsgView *self, const gchar *brand_name, const GdkPixbuf *brand_icon) +{ + ModestWebkitMsgViewPrivate *priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + modest_mail_header_view_set_branding (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), brand_name, brand_icon); +} + +static gboolean +has_blocked_external_images (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + return (modest_mime_part_view_has_external_images (MODEST_MIME_PART_VIEW (priv->body_view)) && + !modest_mime_part_view_get_view_images (MODEST_MIME_PART_VIEW (priv->body_view))); +} + +static gboolean +on_activate_link (GtkWidget *widget, const gchar *uri, ModestWebkitMsgView *self) +{ + gboolean result; + g_return_val_if_fail (self, FALSE); + + g_signal_emit_by_name (G_OBJECT(self), "activate-link", uri, &result); + + return result; +} + + +static gboolean +on_link_hover (GtkWidget *widget, const gchar *uri, ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + gboolean result; + + g_free (priv->last_url); + priv->last_url = g_strdup (uri); + + g_signal_emit_by_name (G_OBJECT(self), "link-hover", uri, &result); + + return result; +} + +static void +on_limit_error (GtkWidget *widget, ModestWebkitMsgView *msg_view) +{ + g_signal_emit_by_name (G_OBJECT (msg_view), "limit-error"); +} + + +static TnyMimePart * +find_cid_image (TnyMsg *msg, const gchar *cid) +{ + TnyMimePart *part = NULL; + TnyList *parts; + TnyIterator *iter; + + g_return_val_if_fail (msg, NULL); + g_return_val_if_fail (cid, NULL); + + parts = TNY_LIST (tny_simple_list_new()); + + tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); + iter = tny_list_create_iterator (parts); + + while (!tny_iterator_is_done(iter)) { + const gchar *part_cid; + + part = TNY_MIME_PART(tny_iterator_get_current(iter)); + part_cid = tny_mime_part_get_content_id (part); + + /* if there is no content id, try the content location; + * this is what Outlook seems to use when it converts + * it's internal richtext to html + */ + if (!part_cid) + part_cid = tny_mime_part_get_content_location (part); + + if (part_cid && strcmp (cid, part_cid) == 0) + break; + + if (tny_mime_part_content_type_is (part, "multipart/related")) { + TnyList *related_parts = TNY_LIST (tny_simple_list_new ()); + TnyIterator *related_iter = NULL; + TnyMimePart *related_part = NULL; + + tny_mime_part_get_parts (part, related_parts); + related_iter = tny_list_create_iterator (related_parts); + + while (!tny_iterator_is_done (related_iter)) { + related_part = TNY_MIME_PART (tny_iterator_get_current (related_iter)); + part_cid = tny_mime_part_get_content_id (related_part); + if (part_cid && strcmp (cid, part_cid) == 0) { + break; + } + g_object_unref (related_part); + related_part = NULL; + tny_iterator_next (related_iter); + } + + g_object_unref (related_iter); + g_object_unref (related_parts); + if (related_part != NULL) { + g_object_unref (part); + part = related_part; + break; + } + } + + g_object_unref (G_OBJECT(part)); + + part = NULL; + tny_iterator_next (iter); + } + + g_object_unref (G_OBJECT(iter)); + g_object_unref (G_OBJECT(parts)); + + return part; +} + + +static gboolean +on_fetch_url (GtkWidget *widget, const gchar *uri, + TnyStream *stream, ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv; + const gchar* my_uri; + TnyMimePart *part = NULL; + + + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + /* + * we search for either something starting with cid:, or something + * with no prefix at all; this latter case occurs when sending mails + * with MS Outlook in rich-text mode, and 'attach-as-object + */ + if (g_str_has_prefix (uri, "cid:")) + my_uri = uri + 4; /* +4 ==> skip "cid:" */ + else + my_uri = uri; + + /* now try to find the embedded image */ + part = find_cid_image (priv->msg, my_uri); + + if (!part) { + if (g_str_has_prefix (uri, "http:")) { + if (modest_mime_part_view_get_view_images (MODEST_MIME_PART_VIEW (priv->body_view))) { + gboolean result = FALSE; + g_signal_emit_by_name (self, "fetch-image", uri, stream, &result); + return result; + } else { + /* we return immediately to get a "image not found" icon */ + tny_stream_close (stream); + return TRUE; + } + } else { + return FALSE; + } + } + + tny_mime_part_decode_to_stream ((TnyMimePart*)part, stream, NULL); + tny_stream_close (stream); + g_object_unref (G_OBJECT(part)); + return TRUE; +} + +static void +set_message (ModestWebkitMsgView *self, TnyMsg *msg, TnyMimePart *other_body) +{ + TnyMimePart *body; + ModestWebkitMsgViewPrivate *priv; + TnyHeader *header; + + g_return_if_fail (self); + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE(self); + modest_mail_header_view_set_loading (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), FALSE); + gtk_widget_set_no_show_all (priv->mail_header_view, FALSE); + modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), FALSE); + + if (msg != priv->msg) { + if (priv->msg) + g_object_unref (G_OBJECT(priv->msg)); + if (msg) + g_object_ref (G_OBJECT(msg)); + priv->msg = msg; + } + + if (!msg) { + tny_header_view_clear (TNY_HEADER_VIEW (priv->mail_header_view)); + modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL); + gtk_widget_hide_all (priv->mail_header_view); + gtk_widget_hide_all (priv->attachments_box); +#ifdef MODEST_TOOKIT_HILDON2 + gtk_widget_hide_all (priv->priority_box); +#endif + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); + tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view)); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); + + gtk_widget_queue_resize (GTK_WIDGET(self)); + gtk_widget_queue_draw (GTK_WIDGET(self)); + return; + } + + header = tny_msg_get_header (msg); + tny_header_view_set_header (TNY_HEADER_VIEW (priv->mail_header_view), header); + g_object_unref (header); + + modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), + other_body?NULL:msg); + + modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), tny_msg_get_allow_external_images (msg)); + + if (other_body) { + body = other_body; + g_object_ref (body); + } else { + body = modest_tny_msg_find_body_part (msg, TRUE); + } + if (body) { + ModestAttachmentsView *widget; + + tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (priv->body_view), body); + g_object_unref (body); + widget = MODEST_ATTACHMENTS_VIEW (priv->attachments_view); + + if (modest_attachments_view_has_attachments (widget)) { + GtkLabel *label; + GList *children = NULL; + gchar *text = NULL; + /* Ugly but... */ + children = gtk_container_get_children (GTK_CONTAINER (priv->attachments_box)); + label = GTK_LABEL (children->data); + gtk_widget_show_all (priv->attachments_box); + if (modest_attachments_view_get_num_attachments (widget) > 1) { + text = _("mail_va_attachments"); + } else { + text = _("mail_va_attachment"); + } + gtk_label_set_text (label, text); + } else { + gtk_widget_hide_all (priv->attachments_box); + } + + } else { + tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view)); + } + + /* Refresh priority */ + set_priority (self, tny_header_get_flags (header)); + + gtk_widget_show (priv->body_view); + gtk_widget_set_no_show_all (priv->priority_box, TRUE); + gtk_widget_set_no_show_all (priv->attachments_box, TRUE); + gtk_widget_show_all (priv->mail_header_view); + gtk_widget_set_no_show_all (priv->attachments_box, FALSE); + gtk_widget_set_no_show_all (priv->priority_box, FALSE); + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); + + gtk_widget_queue_resize (GTK_WIDGET(self)); + gtk_widget_queue_draw (GTK_WIDGET(self)); + +} + +static void +set_header (ModestWebkitMsgView *self, TnyHeader *header) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_if_fail (self); + + if (header == NULL) { + set_message (self, NULL, NULL); + return; + } + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE(self); + modest_mail_header_view_set_loading (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), TRUE); + gtk_widget_set_no_show_all (priv->mail_header_view, FALSE); + modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), FALSE); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + gtk_widget_queue_resize (GTK_WIDGET (priv->body_view)); + + if (priv->msg) { + g_object_unref (G_OBJECT(priv->msg)); + } + priv->msg = NULL; + + tny_header_view_set_header (TNY_HEADER_VIEW (priv->mail_header_view), header); + modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL); + gtk_widget_show_all (priv->mail_header_view); + gtk_widget_hide_all (priv->attachments_box); + gtk_widget_hide_all (priv->priority_box); + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); + tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view)); + gtk_widget_queue_resize (GTK_WIDGET(self)); + gtk_widget_queue_draw (GTK_WIDGET(self)); +} + + +static TnyMsg* +get_message (ModestWebkitMsgView *self) +{ + TnyMsg *msg; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), NULL); + + msg = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE(self)->msg; + + if (msg) + g_object_ref (msg); + + return msg; +} + +static gboolean +is_empty (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + return modest_mime_part_view_is_empty (MODEST_MIME_PART_VIEW (priv->body_view)); +} + +static void +set_zoom (ModestWebkitMsgView *self, gdouble zoom) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self)); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + modest_zoomable_set_zoom (MODEST_ZOOMABLE(priv->body_view), zoom); + + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), 1, 1); + gtk_widget_set_size_request (GTK_WIDGET (priv->body_view), -1, -1); + + gtk_widget_queue_resize (priv->body_view); +} + +static gdouble +get_zoom (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), 1.0); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + return modest_zoomable_get_zoom (MODEST_ZOOMABLE (priv->body_view)); +} + +static TnyHeaderFlags +get_priority (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), 0); + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + return modest_mail_header_view_get_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view)); +} + +static void +set_priority (ModestWebkitMsgView *self, TnyHeaderFlags flags) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self)); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + modest_mail_header_view_set_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), flags); + + gboolean show_priority = FALSE; + TnyHeaderFlags priority_flags; + + priority_flags = flags & TNY_HEADER_FLAG_PRIORITY_MASK; + if (priority_flags == TNY_HEADER_FLAG_HIGH_PRIORITY) { + show_priority = TRUE; + gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), MODEST_HEADER_ICON_HIGH, GTK_ICON_SIZE_MENU); + } else if (priority_flags == TNY_HEADER_FLAG_LOW_PRIORITY) { + show_priority = TRUE; + gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), MODEST_HEADER_ICON_LOW, GTK_ICON_SIZE_MENU); + } + + if (show_priority && MODEST_IS_COMPACT_MAIL_HEADER_VIEW (priv->mail_header_view)) { + gtk_widget_show_all (priv->priority_box); + } else { + gtk_widget_hide_all (priv->priority_box); + } + +} + +/* INCREMENTAL SEARCH IMPLEMENTATION */ + +static gboolean +search (ModestWebkitMsgView *self, const gchar *search) +{ + ModestWebkitMsgViewPrivate *priv; + gboolean result; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), FALSE); + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + result = modest_isearch_view_search (MODEST_ISEARCH_VIEW (priv->body_view), + search); + + return result; +} + +static gboolean +search_next (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv; + gboolean result; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), FALSE); + + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + result = modest_isearch_view_search_next (MODEST_ISEARCH_VIEW (priv->body_view)); + + return result; +} + +static TnyList * +get_selected_attachments (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), NULL); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + return modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)); + +} + +static TnyList * +get_attachments (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self), NULL); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + return modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)); + +} + +static void +grab_focus (ModestWebkitMsgView *self) +{ + ModestWebkitMsgViewPrivate *priv = NULL; + + g_return_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self)); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + gtk_widget_grab_focus (priv->body_view); +} + +static void +remove_attachment (ModestWebkitMsgView *self, TnyMimePart *attachment) +{ + ModestWebkitMsgViewPrivate *priv; + + g_return_if_fail (MODEST_IS_WEBKIT_MSG_VIEW (self)); + g_return_if_fail (TNY_IS_MIME_PART (attachment)); + priv = MODEST_WEBKIT_MSG_VIEW_GET_PRIVATE (self); + + modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), + attachment); + +} + +/* TNY HEADER VIEW IMPLEMENTATION */ + +static void +tny_header_view_init (gpointer g, gpointer iface_data) +{ + TnyHeaderViewIface *klass = (TnyHeaderViewIface *)g; + + klass->set_header = modest_msg_view_set_header; + klass->clear = modest_msg_view_clear_header; + + return; +} + +static void +modest_msg_view_set_header (TnyHeaderView *self, TnyHeader *header) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_header_func (self, header); +} + + +static void +modest_msg_view_set_header_default (TnyHeaderView *self, TnyHeader *header) +{ + set_header (MODEST_WEBKIT_MSG_VIEW (self), header); +} + +static void +modest_msg_view_clear_header (TnyHeaderView *self) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->clear_header_func (self); +} + + +static void +modest_msg_view_clear_header_default (TnyHeaderView *self) +{ + set_message (MODEST_WEBKIT_MSG_VIEW (self), NULL, NULL); +} + +/* TNY MSG IMPLEMENTATION */ + +static void +tny_msg_view_init (gpointer g, gpointer iface_data) +{ + TnyMsgViewIface *klass = (TnyMsgViewIface *)g; + + klass->get_msg = modest_msg_view_get_msg; + klass->set_msg = modest_msg_view_set_msg; + klass->set_unavailable = modest_msg_view_set_unavailable; + klass->clear = modest_msg_view_clear; + klass->create_mime_part_view_for = modest_msg_view_create_mime_part_view_for; + klass->create_new_inline_viewer = modest_msg_view_create_new_inline_viewer; + + return; +} + +static TnyMsg * +modest_msg_view_get_msg (TnyMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_msg_func (self); +} + +static TnyMsg * +modest_msg_view_get_msg_default (TnyMsgView *self) +{ + return TNY_MSG (tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (self))); +} + +static void +modest_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_msg_func (self, msg); +} + +static void +modest_msg_view_set_msg_default (TnyMsgView *self, TnyMsg *msg) +{ + + tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (self), TNY_MIME_PART (msg)); + + return; +} + +static void +modest_msg_view_set_unavailable (TnyMsgView *self) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_unavailable_func (self); +} + +static void +modest_msg_view_set_unavailable_default (TnyMsgView *self) +{ + tny_msg_view_clear (self); + + return; +} + +static void +modest_msg_view_clear (TnyMsgView *self) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->clear_func (self); +} + +static void +modest_msg_view_clear_default (TnyMsgView *self) +{ + set_message (MODEST_WEBKIT_MSG_VIEW (self), NULL, NULL); +} + +static TnyMimePartView* +modest_msg_view_create_mime_part_view_for (TnyMsgView *self, TnyMimePart *part) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->create_mime_part_view_for_func (self, part); +} + +static TnyMimePartView* +modest_msg_view_create_mime_part_view_for_default (TnyMsgView *self, TnyMimePart *part) +{ + g_warning ("modest_msg_view_create_mime_part_view_for_default is not implemented"); + return NULL; +} + +static TnyMsgView* +modest_msg_view_create_new_inline_viewer (TnyMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->create_new_inline_viewer_func (self); +} + +static TnyMsgView* +modest_msg_view_create_new_inline_viewer_default (TnyMsgView *self) +{ + g_warning ("modest_msg_view_create_new_inline_viewer_default is not implemented"); + + return NULL; +} + +/* TNY MIME PART IMPLEMENTATION */ + +static void +tny_mime_part_view_init (gpointer g, gpointer iface_data) +{ + TnyMimePartViewIface *klass = (TnyMimePartViewIface *)g; + + klass->get_part = modest_msg_view_mp_get_part; + klass->set_part = modest_msg_view_mp_set_part; + klass->clear = modest_msg_view_mp_clear; + + return; +} + +static TnyMimePart* +modest_msg_view_mp_get_part (TnyMimePartView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_part_func (self); +} + + +static TnyMimePart* +modest_msg_view_mp_get_part_default (TnyMimePartView *self) +{ + return TNY_MIME_PART (get_message (MODEST_WEBKIT_MSG_VIEW (self))); +} + +static void +modest_msg_view_mp_set_part (TnyMimePartView *self, + TnyMimePart *part) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_part_func (self, part); +} + +static void +modest_msg_view_mp_set_part_default (TnyMimePartView *self, + TnyMimePart *part) +{ + g_return_if_fail ((part == NULL) || TNY_IS_MSG (part)); + + set_message (MODEST_WEBKIT_MSG_VIEW (self), TNY_MSG (part), NULL); +} + +static void +modest_msg_view_mp_clear (TnyMimePartView *self) +{ + tny_msg_view_clear (TNY_MSG_VIEW (self)); +} + +/* MODEST MIME PART VIEW IMPLEMENTATION */ + +static void +modest_mime_part_view_init (gpointer g, gpointer iface_data) +{ + ModestMimePartViewIface *klass = (ModestMimePartViewIface *)g; + + klass->is_empty_func = modest_msg_view_mp_is_empty; + + return; +} + +static gboolean +modest_msg_view_mp_is_empty (ModestMimePartView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->is_empty_func (self); +} + +static gboolean +modest_msg_view_mp_is_empty_default (ModestMimePartView *self) +{ + return is_empty (MODEST_WEBKIT_MSG_VIEW (self)); +} + +/* MODEST ZOOMABLE IMPLEMENTATION */ +static void +modest_zoomable_init (gpointer g, gpointer iface_data) +{ + ModestZoomableIface *klass = (ModestZoomableIface *)g; + + klass->get_zoom_func = modest_msg_view_get_zoom; + klass->set_zoom_func = modest_msg_view_set_zoom; + klass->zoom_minus_func = modest_msg_view_zoom_minus; + klass->zoom_plus_func = modest_msg_view_zoom_plus; + + return; +} + +static gdouble +modest_msg_view_get_zoom (ModestZoomable *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_zoom_func (self); +} + +static gdouble +modest_msg_view_get_zoom_default (ModestZoomable *self) +{ + return get_zoom (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static void +modest_msg_view_set_zoom (ModestZoomable *self, gdouble value) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_zoom_func (self, value); +} + +static void +modest_msg_view_set_zoom_default (ModestZoomable *self, gdouble value) +{ + set_zoom (MODEST_WEBKIT_MSG_VIEW (self), value); +} + +static gboolean +modest_msg_view_zoom_minus (ModestZoomable *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->zoom_minus_func (self); +} + +static gboolean +modest_msg_view_zoom_minus_default (ModestZoomable *self) +{ + /* operation not supported in ModestMsgView */ + return FALSE; +} + +static gboolean +modest_msg_view_zoom_plus (ModestZoomable *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->zoom_plus_func (self); +} + +static gboolean +modest_msg_view_zoom_plus_default (ModestZoomable *self) +{ + /* operation not supported in ModestMsgView */ + return FALSE; +} + +/* MODEST ISEARCH VIEW IMPLEMENTATION */ +static void +modest_isearch_view_init (gpointer g, gpointer iface_data) +{ + ModestISearchViewIface *klass = (ModestISearchViewIface *)g; + + klass->search_func = modest_msg_view_search; + klass->search_next_func = modest_msg_view_search_next; + + return; +} + +static gboolean +modest_msg_view_search (ModestISearchView *self, const gchar *string) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->search_func (self, string); +} + +static gboolean +modest_msg_view_search_default (ModestISearchView *self, const gchar *string) +{ + return search (MODEST_WEBKIT_MSG_VIEW (self), string); +} + +static gboolean +modest_msg_view_search_next (ModestISearchView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->search_next_func (self); +} + +static gboolean +modest_msg_view_search_next_default (ModestISearchView *self) +{ + return search_next (MODEST_WEBKIT_MSG_VIEW (self)); +} + +/* MODEST MSG VIEW IMPLEMENTATION */ +static void +modest_msg_view_init (gpointer g, gpointer iface_data) +{ + ModestMsgViewIface *klass = (ModestMsgViewIface *)g; + + klass->set_msg_with_other_body_func = modest_webkit_msg_view_set_msg_with_other_body; + klass->get_vadjustment_func = modest_webkit_msg_view_get_vadjustment; + klass->get_hadjustment_func = modest_webkit_msg_view_get_hadjustment; + klass->set_vadjustment_func = modest_webkit_msg_view_set_vadjustment; + klass->set_hadjustment_func = modest_webkit_msg_view_set_hadjustment; + klass->set_shadow_type_func = modest_webkit_msg_view_set_shadow_type; + klass->get_shadow_type_func = modest_webkit_msg_view_get_shadow_type; + klass->get_priority_func = modest_webkit_msg_view_get_priority; + klass->set_priority_func = modest_webkit_msg_view_set_priority; + klass->get_selected_attachments_func = modest_webkit_msg_view_get_selected_attachments; + klass->get_attachments_func = modest_webkit_msg_view_get_attachments; + klass->grab_focus_func = modest_webkit_msg_view_grab_focus; + klass->remove_attachment_func = modest_webkit_msg_view_remove_attachment; + klass->request_fetch_images_func = modest_webkit_msg_view_request_fetch_images; + klass->set_branding_func = modest_webkit_msg_view_set_branding; + klass->has_blocked_external_images_func = modest_webkit_msg_view_has_blocked_external_images; + + return; +} + +static void +modest_webkit_msg_view_set_msg_with_other_body (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_msg_with_other_body_func (self, msg, other_body); +} + +static void +modest_webkit_msg_view_set_msg_with_other_body_default (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body) +{ + set_message (MODEST_WEBKIT_MSG_VIEW (self), msg, other_body); +} + +static GtkAdjustment* +modest_webkit_msg_view_get_vadjustment (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_vadjustment_func (self); +} + +static GtkAdjustment* +modest_webkit_msg_view_get_vadjustment_default (ModestMsgView *self) +{ + return get_vadjustment (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static GtkAdjustment* +modest_webkit_msg_view_get_hadjustment (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_hadjustment_func (self); +} + +static GtkAdjustment* +modest_webkit_msg_view_get_hadjustment_default (ModestMsgView *self) +{ + return get_hadjustment (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static void +modest_webkit_msg_view_set_vadjustment (ModestMsgView *self, GtkAdjustment *adj) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_vadjustment_func (self, adj); +} + +static void +modest_webkit_msg_view_set_vadjustment_default (ModestMsgView *self, GtkAdjustment *adj) +{ + set_vadjustment (MODEST_WEBKIT_MSG_VIEW (self), adj); +} + +static void +modest_webkit_msg_view_set_hadjustment (ModestMsgView *self, GtkAdjustment *adj) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_hadjustment_func (self, adj); +} + +static void +modest_webkit_msg_view_set_hadjustment_default (ModestMsgView *self, GtkAdjustment *adj) +{ + set_hadjustment (MODEST_WEBKIT_MSG_VIEW (self), adj); +} + +static void +modest_webkit_msg_view_set_shadow_type (ModestMsgView *self, GtkShadowType type) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_shadow_type_func (self, type); +} + +static void +modest_webkit_msg_view_set_shadow_type_default (ModestMsgView *self, GtkShadowType type) +{ + set_shadow_type (MODEST_WEBKIT_MSG_VIEW (self), type); +} + +static GtkShadowType +modest_webkit_msg_view_get_shadow_type (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_shadow_type_func (self); +} + +static GtkShadowType +modest_webkit_msg_view_get_shadow_type_default (ModestMsgView *self) +{ + return get_shadow_type (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static void +modest_webkit_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_priority_func (self, flags); +} + +static void +modest_webkit_msg_view_set_priority_default (ModestMsgView *self, TnyHeaderFlags flags) +{ + set_priority (MODEST_WEBKIT_MSG_VIEW (self), flags); +} + +static TnyHeaderFlags +modest_webkit_msg_view_get_priority (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_priority_func (self); +} + +static TnyHeaderFlags +modest_webkit_msg_view_get_priority_default (ModestMsgView *self) +{ + return get_priority (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static TnyList* +modest_webkit_msg_view_get_selected_attachments (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_selected_attachments_func (self); +} + +static TnyList* +modest_webkit_msg_view_get_selected_attachments_default (ModestMsgView *self) +{ + return get_selected_attachments (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static TnyList* +modest_webkit_msg_view_get_attachments (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->get_attachments_func (self); +} + +static TnyList* +modest_webkit_msg_view_get_attachments_default (ModestMsgView *self) +{ + return get_attachments (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static void +modest_webkit_msg_view_grab_focus (ModestMsgView *self) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->grab_focus_func (self); +} + +static void +modest_webkit_msg_view_grab_focus_default (ModestMsgView *self) +{ + grab_focus (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static void +modest_webkit_msg_view_remove_attachment (ModestMsgView *self, TnyMimePart *attachment) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->remove_attachment_func (self, attachment); +} + +static void +modest_webkit_msg_view_remove_attachment_default (ModestMsgView *self, TnyMimePart *attachment) +{ + remove_attachment (MODEST_WEBKIT_MSG_VIEW (self), attachment); +} + +static void +modest_webkit_msg_view_request_fetch_images (ModestMsgView *self) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->request_fetch_images_func (self); +} + +static void +modest_webkit_msg_view_request_fetch_images_default (ModestMsgView *self) +{ + request_fetch_images (MODEST_WEBKIT_MSG_VIEW (self)); +} + +static void +modest_webkit_msg_view_set_branding (ModestMsgView *self, const gchar *brand_name, const GdkPixbuf *brand_icon) +{ + MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->set_branding_func (self, brand_name, brand_icon); +} + +static void +modest_webkit_msg_view_set_branding_default (ModestMsgView *self, const gchar *brand_name, const GdkPixbuf *brand_icon) +{ + set_branding (MODEST_WEBKIT_MSG_VIEW (self), brand_name, brand_icon); +} + +static gboolean +modest_webkit_msg_view_has_blocked_external_images (ModestMsgView *self) +{ + return MODEST_WEBKIT_MSG_VIEW_GET_CLASS (self)->has_blocked_external_images_func (self); +} + +static gboolean +modest_webkit_msg_view_has_blocked_external_images_default (ModestMsgView *self) +{ + return has_blocked_external_images (MODEST_WEBKIT_MSG_VIEW (self)); +} diff --git a/src/widgets/modest-webkit-msg-view.h b/src/widgets/modest-webkit-msg-view.h new file mode 100644 index 0000000..4664b24 --- /dev/null +++ b/src/widgets/modest-webkit-msg-view.h @@ -0,0 +1,131 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MODEST_WEBKIT_MSG_VIEW_H__ +#define __MODEST_WEBKIT_MSG_VIEW_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* convenience macros */ +#define MODEST_TYPE_WEBKIT_MSG_VIEW (modest_webkit_msg_view_get_type()) +#define MODEST_WEBKIT_MSG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_WEBKIT_MSG_VIEW,ModestWebkitMsgView)) +#define MODEST_WEBKIT_MSG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_WEBKIT_MSG_VIEW,ModestWebkitMsgViewClass)) +#define MODEST_IS_WEBKIT_MSG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_WEBKIT_MSG_VIEW)) +#define MODEST_IS_WEBKIT_MSG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_WEBKIT_MSG_VIEW)) +#define MODEST_WEBKIT_MSG_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_WEBKIT_MSG_VIEW,ModestWebkitMsgViewClass)) + +typedef struct _ModestWebkitMsgView ModestWebkitMsgView; +typedef struct _ModestWebkitMsgViewClass ModestWebkitMsgViewClass; + +struct _ModestWebkitMsgView { + GtkViewport parent; +}; + +struct _ModestWebkitMsgViewClass { + GtkViewportClass parent_class; + + /* TnyHeaderView interface */ + void (*set_header_func) (TnyHeaderView *self, TnyHeader *header); + void (*clear_header_func) (TnyHeaderView *self); + /* TnyMimePartView interface */ + TnyMimePart* (*get_part_func) (TnyMimePartView *self); + void (*set_part_func) (TnyMimePartView *self, TnyMimePart *part); + /* ModestMimePartView interface methods */ + gboolean (*is_empty_func) (ModestMimePartView *self); + /* TnyMsgView interface */ + TnyMsg* (*get_msg_func) (TnyMsgView *self); + void (*set_msg_func) (TnyMsgView *self, TnyMsg *msg); + void (*set_unavailable_func) (TnyMsgView *self); + void (*clear_func) (TnyMsgView *self); + TnyMimePartView* (*create_mime_part_view_for_func) (TnyMsgView *self, TnyMimePart *part); + TnyMsgView* (*create_new_inline_viewer_func) (TnyMsgView *self); + /* ModestZoomable interface */ + gdouble (*get_zoom_func) (ModestZoomable *self); + void (*set_zoom_func) (ModestZoomable *self, gdouble value); + gboolean (*zoom_minus_func) (ModestZoomable *self); + gboolean (*zoom_plus_func) (ModestZoomable *self); + /* ModestISearchView interface methods */ + gboolean (*search_func) (ModestISearchView *self, const gchar *string); + gboolean (*search_next_func) (ModestISearchView *self); + /* ModestMsgView interface methods */ + void (*set_msg_with_other_body_func) (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body); + GtkAdjustment* (*get_vadjustment_func) (ModestMsgView *self); + GtkAdjustment* (*get_hadjustment_func) (ModestMsgView *self); + void (*set_vadjustment_func) (ModestMsgView *self, GtkAdjustment *vadj); + void (*set_hadjustment_func) (ModestMsgView *self, GtkAdjustment *vadj); + void (*set_shadow_type_func) (ModestMsgView *self, GtkShadowType type); + GtkShadowType (*get_shadow_type_func) (ModestMsgView *self); + TnyHeaderFlags (*get_priority_func) (ModestMsgView *self); + void (*set_priority_func) (ModestMsgView *self, TnyHeaderFlags flags); + TnyList * (*get_selected_attachments_func) (ModestMsgView *self); + TnyList * (*get_attachments_func) (ModestMsgView *self); + void (*grab_focus_func) (ModestMsgView *self); + void (*remove_attachment_func) (ModestMsgView *view, TnyMimePart *attachment); + void (*request_fetch_images_func) (ModestMsgView *view); + void (*set_branding_func) (ModestMsgView *view, const gchar *brand_name, const GdkPixbuf *brand_icon); + gboolean (*has_blocked_external_images_func) (ModestMsgView *view); + + void (*set_scroll_adjustments) (ModestWebkitMsgView *msg_view, GtkAdjustment *hadj, GtkAdjustment *vadj); +}; + + +/** + * modest_webkit_msg_view_get_type: + * + * get the GType for the this class + * + * Returns: the GType for this class + */ +GType modest_webkit_msg_view_get_type (void) G_GNUC_CONST; + + +/** + * modest_webkit_msg_view_new + * @tny_msg: a TnyMsg instance, or NULL + * + * create a new ModestWebkitMsgView widget, + * and display the @tny_msg e-mail message in it. If @tny_msg is NULL, + * then a blank page will be displayed + * + * Returns: a new ModestWebkitMsgView widget, or NULL if there's an error + */ +GtkWidget* modest_webkit_msg_view_new (TnyMsg *tny_msg); + +G_END_DECLS + +#endif /* __MODEST_WEBKIT_MSG_VIEW_H__ */ -- 1.7.9.5