fb22106d61fc3787cccec1710a56d19f48e01e44
[modest] / src / widgets / modest-mozembed-msg-view.c
1 /* Copyright (c) 2006, 2007, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <config.h>
31 #include <tny-gtk-text-buffer-stream.h>
32 #include <string.h>
33 #include <regex.h>
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <glib/gi18n.h>
37 #include <tny-list.h>
38 #include <tny-simple-list.h>
39
40 #include <modest-tny-msg.h>
41 #include <modest-text-utils.h>
42 #include <widgets/modest-msg-view.h>
43 #include <widgets/modest-compact-mail-header-view.h>
44 #include <widgets/modest-attachments-view.h>
45 #include <modest-marshal.h>
46 #include <widgets/modest-isearch-view.h>
47 #include <widgets/modest-mozembed-msg-view.h>
48 #include <widgets/modest-mozembed-mime-part-view.h>
49 #include <widgets/modest-scroll-area.h>
50
51
52 /* 'private'/'protected' functions */
53 static void     modest_mozembed_msg_view_class_init   (ModestMozembedMsgViewClass *klass);
54 static void     tny_header_view_init (gpointer g, gpointer iface_data);
55 static void     tny_msg_view_init (gpointer g, gpointer iface_data);
56 static void     tny_mime_part_view_init (gpointer g, gpointer iface_data);
57 static void     modest_mime_part_view_init (gpointer g, gpointer iface_data);
58 static void     modest_zoomable_init (gpointer g, gpointer iface_data);
59 static void     modest_isearch_view_init (gpointer g, gpointer iface_data);
60 static void     modest_msg_view_init (gpointer g, gpointer iface_data);
61 static void     modest_mozembed_msg_view_init         (ModestMozembedMsgView *obj);
62 static void     modest_mozembed_msg_view_finalize     (GObject *obj);
63 static void     modest_mozembed_msg_view_destroy     (GtkObject *obj);
64
65 /* headers signals */
66 static void on_recpt_activated (ModestMailHeaderView *header_view, const gchar *address, ModestMozembedMsgView *msg_view);
67 static void on_attachment_activated (ModestAttachmentsView * att_view, TnyMimePart *mime_part, gpointer userdata);
68
69 /* body view signals */
70 static gboolean on_activate_link (GtkWidget *widget, const gchar *uri, ModestMozembedMsgView *msg_view);
71 static gboolean on_fetch_url (GtkWidget *widget, const gchar *uri, TnyStream *stream,
72                               ModestMozembedMsgView *msg_view);
73 static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestMozembedMsgView *msg_view);
74
75 #if HAVE_DECL_GTK_WIDGET_TAP_AND_HOLD_SETUP
76 static void     on_tap_and_hold (GtkWidget *widget, gpointer userdata); 
77 #endif /*HAVE_DECL_GTK_WIDGET_TAP_AND_HOLD_SETUP*/
78
79 /* TnyMimePartView implementation */
80 static void modest_msg_view_mp_clear (TnyMimePartView *self);
81 static void modest_msg_view_mp_set_part (TnyMimePartView *self, TnyMimePart *part);
82 static void modest_msg_view_mp_set_part_default (TnyMimePartView *self, TnyMimePart *part);
83 static TnyMimePart* modest_msg_view_mp_get_part (TnyMimePartView *self);
84 static TnyMimePart* modest_msg_view_mp_get_part_default (TnyMimePartView *self);
85 /* ModestMimePartView implementation */
86 static gboolean modest_msg_view_mp_is_empty (ModestMimePartView *self);
87 static gboolean modest_msg_view_mp_is_empty_default (ModestMimePartView *self);
88 /* TnyHeaderView implementation */
89 static void modest_msg_view_set_header (TnyHeaderView *self, TnyHeader *header);
90 static void modest_msg_view_set_header_default (TnyHeaderView *self, TnyHeader *header);
91 static void modest_msg_view_clear_header (TnyHeaderView *self);
92 static void modest_msg_view_clear_header_default (TnyHeaderView *self);
93 /* TnyMsgView implementation */
94 static TnyMsg *modest_msg_view_get_msg (TnyMsgView *self);
95 static TnyMsg *modest_msg_view_get_msg_default (TnyMsgView *self);
96 static void modest_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg);
97 static void modest_msg_view_set_msg_default (TnyMsgView *self, TnyMsg *msg);
98 static void modest_msg_view_clear (TnyMsgView *self);
99 static void modest_msg_view_clear_default (TnyMsgView *self);
100 static void modest_msg_view_set_unavailable (TnyMsgView *self);
101 static void modest_msg_view_set_unavailable_default (TnyMsgView *self);
102 static TnyMimePartView *modest_msg_view_create_mime_part_view_for (TnyMsgView *self, TnyMimePart *part);
103 static TnyMimePartView *modest_msg_view_create_mime_part_view_for_default (TnyMsgView *self, TnyMimePart *part);
104 static TnyMsgView *modest_msg_view_create_new_inline_viewer (TnyMsgView *self);
105 static TnyMsgView *modest_msg_view_create_new_inline_viewer_default (TnyMsgView *self);
106 /* ModestZoomable implementation */
107 static gdouble modest_msg_view_get_zoom (ModestZoomable *self);
108 static void modest_msg_view_set_zoom (ModestZoomable *self, gdouble value);
109 static gboolean modest_msg_view_zoom_minus (ModestZoomable *self);
110 static gboolean modest_msg_view_zoom_plus (ModestZoomable *self);
111 static gdouble modest_msg_view_get_zoom_default (ModestZoomable *self);
112 static void modest_msg_view_set_zoom_default (ModestZoomable *self, gdouble value);
113 static gboolean modest_msg_view_zoom_minus_default (ModestZoomable *self);
114 static gboolean modest_msg_view_zoom_plus_default (ModestZoomable *self);
115 /* ModestISearchView implementation */
116 static gboolean modest_msg_view_search (ModestISearchView *self, const gchar *string);
117 static gboolean modest_msg_view_search_default (ModestISearchView *self, const gchar *string);
118 static gboolean modest_msg_view_search_next (ModestISearchView *self);
119 static gboolean modest_msg_view_search_next_default (ModestISearchView *self);
120 /* ModestMsgView implementation */
121 static void modest_mozembed_msg_view_set_msg_with_other_body (ModestMsgView *self, TnyMsg *msg, TnyMimePart *part);
122 static GtkAdjustment *modest_mozembed_msg_view_get_vadjustment (ModestMsgView *self);
123 static GtkAdjustment *modest_mozembed_msg_view_get_hadjustment (ModestMsgView *self);
124 static void modest_mozembed_msg_view_set_vadjustment (ModestMsgView *self, GtkAdjustment *vadj);
125 static void modest_mozembed_msg_view_set_hadjustment (ModestMsgView *self, GtkAdjustment *hadj);
126 static void modest_mozembed_msg_view_set_shadow_type (ModestMsgView *self, GtkShadowType type);
127 static GtkShadowType modest_mozembed_msg_view_get_shadow_type (ModestMsgView *self);
128 static TnyHeaderFlags modest_mozembed_msg_view_get_priority (ModestMsgView *self);
129 static void modest_mozembed_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags);
130 static TnyList *modest_mozembed_msg_view_get_selected_attachments (ModestMsgView *self);
131 static TnyList *modest_mozembed_msg_view_get_attachments (ModestMsgView *self);
132 static void modest_mozembed_msg_view_grab_focus (ModestMsgView *self);
133 static void modest_mozembed_msg_view_remove_attachment (ModestMsgView *view, TnyMimePart *attachment);
134 static void modest_mozembed_msg_view_request_fetch_images (ModestMsgView *view);
135 static gboolean modest_mozembed_msg_view_has_blocked_external_images (ModestMsgView *view);
136 static void modest_mozembed_msg_view_set_msg_with_other_body_default (ModestMsgView *self, TnyMsg *msg, TnyMimePart *part);
137 static GtkAdjustment *modest_mozembed_msg_view_get_vadjustment_default (ModestMsgView *self);
138 static GtkAdjustment *modest_mozembed_msg_view_get_hadjustment_default (ModestMsgView *self);
139 static void modest_mozembed_msg_view_set_vadjustment_default (ModestMsgView *self, GtkAdjustment *vadj);
140 static void modest_mozembed_msg_view_set_hadjustment_default (ModestMsgView *self, GtkAdjustment *hadj);
141 static void modest_mozembed_msg_view_set_shadow_type_default (ModestMsgView *self, GtkShadowType type);
142 static GtkShadowType modest_mozembed_msg_view_get_shadow_type_default (ModestMsgView *self);
143 static TnyHeaderFlags modest_mozembed_msg_view_get_priority_default (ModestMsgView *self);
144 static void modest_mozembed_msg_view_set_priority_default (ModestMsgView *self, TnyHeaderFlags flags);
145 static TnyList *modest_mozembed_msg_view_get_selected_attachments_default (ModestMsgView *self);
146 static TnyList *modest_mozembed_msg_view_get_attachments_default (ModestMsgView *self);
147 static void modest_mozembed_msg_view_grab_focus_default (ModestMsgView *self);
148 static void modest_mozembed_msg_view_remove_attachment_default (ModestMsgView *view, TnyMimePart *attachment);
149 static gboolean modest_mozembed_msg_view_has_blocked_external_images_default (ModestMsgView *view);
150 static void modest_mozembed_msg_view_request_fetch_images_default (ModestMsgView *view);
151
152 /* internal api */
153 static void     set_header     (ModestMozembedMsgView *self, TnyHeader *header);
154 static TnyMsg   *get_message   (ModestMozembedMsgView *self);
155 static void     set_message    (ModestMozembedMsgView *self, TnyMsg *msg, TnyMimePart *other_body);
156 static gboolean is_empty       (ModestMozembedMsgView *self); 
157 static void     set_zoom       (ModestMozembedMsgView *self, gdouble zoom);
158 static gdouble  get_zoom       (ModestMozembedMsgView *self);
159 static gboolean search         (ModestMozembedMsgView *self, const gchar *search);
160 static gboolean search_next    (ModestMozembedMsgView *self);
161 static GtkAdjustment *get_vadjustment (ModestMozembedMsgView *self);
162 static GtkAdjustment *get_hadjustment (ModestMozembedMsgView *self);
163 static void set_vadjustment (ModestMozembedMsgView *self, GtkAdjustment *vadj);
164 static void set_hadjustment (ModestMozembedMsgView *self, GtkAdjustment *hadj);
165 static void set_shadow_type (ModestMozembedMsgView *self, GtkShadowType type);
166 static GtkShadowType get_shadow_type (ModestMozembedMsgView *self);
167 static TnyHeaderFlags get_priority (ModestMozembedMsgView *self);
168 static void set_priority (ModestMozembedMsgView *self, TnyHeaderFlags flags);
169 static TnyList *get_selected_attachments (ModestMozembedMsgView *self);
170 static TnyList *get_attachments (ModestMozembedMsgView *self);
171 static void grab_focus (ModestMozembedMsgView *self);
172 static void remove_attachment (ModestMozembedMsgView *view, TnyMimePart *attachment);
173 static void request_fetch_images (ModestMozembedMsgView *view);
174 static gboolean has_blocked_external_images (ModestMozembedMsgView *view);
175
176 typedef struct _ModestMozembedMsgViewPrivate ModestMozembedMsgViewPrivate;
177 struct _ModestMozembedMsgViewPrivate {
178         GtkWidget   *body_view;
179         GtkWidget   *mail_header_view;
180         GtkWidget   *attachments_view;
181
182         TnyMsg      *msg;
183
184         /* embedded elements */
185         GtkWidget   *headers_box;
186         GtkWidget   *attachments_box;
187
188         /* zoom */
189         gdouble current_zoom;
190
191         /* link click management */
192         gchar *last_url;
193
194 };
195
196 #define MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
197                                                                                   MODEST_TYPE_MOZEMBED_MSG_VIEW, \
198                                                                                   ModestMozembedMsgViewPrivate))
199
200 /* globals */
201 static GtkContainerClass *parent_class = NULL;
202
203 GType
204 modest_mozembed_msg_view_get_type (void)
205 {
206         static GType my_type = 0;
207         if (!my_type) {
208                 static const GTypeInfo my_info = {
209                         sizeof(ModestMozembedMsgViewClass),
210                         NULL,           /* base init */
211                         NULL,           /* base finalize */
212                         (GClassInitFunc) modest_mozembed_msg_view_class_init,
213                         NULL,           /* class finalize */
214                         NULL,           /* class data */
215                         sizeof(ModestMozembedMsgView),
216                         1,              /* n_preallocs */
217                         (GInstanceInitFunc) modest_mozembed_msg_view_init,
218                         NULL
219                 };
220                 static const GInterfaceInfo tny_msg_view_info = 
221                 {
222                   (GInterfaceInitFunc) tny_msg_view_init, /* interface_init */
223                   NULL,         /* interface_finalize */
224                   NULL          /* interface_data */
225                 };
226
227                 static const GInterfaceInfo tny_mime_part_view_info = 
228                 {
229                   (GInterfaceInitFunc) tny_mime_part_view_init, /* interface_init */
230                   NULL,         /* interface_finalize */
231                   NULL          /* interface_data */
232                 };
233
234                 static const GInterfaceInfo tny_header_view_info = 
235                 {
236                   (GInterfaceInitFunc) tny_header_view_init, /* interface_init */
237                   NULL,         /* interface_finalize */
238                   NULL          /* interface_data */
239                 };
240
241                 static const GInterfaceInfo modest_mime_part_view_info = 
242                 {
243                   (GInterfaceInitFunc) modest_mime_part_view_init, /* interface_init */
244                   NULL,         /* interface_finalize */
245                   NULL          /* interface_data */
246                 };
247
248                 static const GInterfaceInfo modest_zoomable_info = 
249                 {
250                   (GInterfaceInitFunc) modest_zoomable_init, /* interface_init */
251                   NULL,         /* interface_finalize */
252                   NULL          /* interface_data */
253                 };
254
255                 static const GInterfaceInfo modest_isearch_view_info = 
256                 {
257                   (GInterfaceInitFunc) modest_isearch_view_init, /* interface_init */
258                   NULL,         /* interface_finalize */
259                   NULL          /* interface_data */
260                 };
261
262                 static const GInterfaceInfo modest_msg_view_info = 
263                 {
264                   (GInterfaceInitFunc) modest_msg_view_init, /* interface_init */
265                   NULL,         /* interface_finalize */
266                   NULL          /* interface_data */
267                 };
268
269                 my_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW,
270                                                   "ModestMozembedMsgView",
271                                                   &my_info, 0);
272
273                 g_type_add_interface_static (my_type, TNY_TYPE_HEADER_VIEW, 
274                         &tny_header_view_info);
275
276                 g_type_add_interface_static (my_type, TNY_TYPE_MIME_PART_VIEW, 
277                         &tny_mime_part_view_info);
278
279                 g_type_add_interface_static (my_type, MODEST_TYPE_MIME_PART_VIEW, 
280                         &modest_mime_part_view_info);
281
282                 g_type_add_interface_static (my_type, TNY_TYPE_MSG_VIEW, 
283                         &tny_msg_view_info);
284
285                 g_type_add_interface_static (my_type, MODEST_TYPE_ZOOMABLE, 
286                         &modest_zoomable_info);
287
288                 g_type_add_interface_static (my_type, MODEST_TYPE_ISEARCH_VIEW, 
289                         &modest_isearch_view_info);
290
291                 g_type_add_interface_static (my_type, MODEST_TYPE_MSG_VIEW, 
292                         &modest_msg_view_info);
293         }
294         return my_type;
295 }
296
297 static void
298 modest_mozembed_msg_view_class_init (ModestMozembedMsgViewClass *klass)
299 {
300         GObjectClass *gobject_class;
301         GtkWidgetClass *widget_class;
302         GtkObjectClass *gtkobject_class;
303         GtkContainerClass *container_class;
304         gobject_class = (GObjectClass*) klass;
305         widget_class = (GtkWidgetClass *) klass;
306         gtkobject_class = (GtkObjectClass *) klass;
307         container_class = (GtkContainerClass *) klass;
308
309         parent_class            = g_type_class_peek_parent (klass);
310         gobject_class->finalize = modest_mozembed_msg_view_finalize;
311         gtkobject_class->destroy = modest_mozembed_msg_view_destroy;
312
313         klass->set_header_func = modest_msg_view_set_header_default;
314         klass->clear_header_func = modest_msg_view_clear_header_default;
315         klass->set_scroll_adjustments = NULL;
316         klass->get_part_func = modest_msg_view_mp_get_part_default;
317         klass->set_part_func = modest_msg_view_mp_set_part_default;
318         klass->is_empty_func = modest_msg_view_mp_is_empty_default;
319         klass->get_msg_func = modest_msg_view_get_msg_default;
320         klass->set_msg_func = modest_msg_view_set_msg_default;
321         klass->set_unavailable_func = modest_msg_view_set_unavailable_default;
322         klass->clear_func = modest_msg_view_clear_default;
323         klass->create_mime_part_view_for_func = modest_msg_view_create_mime_part_view_for_default;
324         klass->create_new_inline_viewer_func = modest_msg_view_create_new_inline_viewer_default;
325         klass->get_zoom_func = modest_msg_view_get_zoom_default;
326         klass->set_zoom_func = modest_msg_view_set_zoom_default;
327         klass->zoom_minus_func = modest_msg_view_zoom_minus_default;
328         klass->zoom_plus_func = modest_msg_view_zoom_plus_default;
329         klass->search_func = modest_msg_view_search_default;
330         klass->search_next_func = modest_msg_view_search_next_default;
331         klass->set_msg_with_other_body_func = modest_mozembed_msg_view_set_msg_with_other_body_default;
332         klass->get_vadjustment_func = modest_mozembed_msg_view_get_vadjustment_default;
333         klass->get_hadjustment_func = modest_mozembed_msg_view_get_hadjustment_default;
334         klass->set_vadjustment_func = modest_mozembed_msg_view_set_vadjustment_default;
335         klass->set_hadjustment_func = modest_mozembed_msg_view_set_hadjustment_default;
336         klass->get_shadow_type_func = modest_mozembed_msg_view_get_shadow_type_default;
337         klass->set_shadow_type_func = modest_mozembed_msg_view_set_shadow_type_default;
338         klass->get_priority_func = modest_mozembed_msg_view_get_priority_default;
339         klass->set_priority_func = modest_mozembed_msg_view_set_priority_default;
340         klass->get_selected_attachments_func = modest_mozembed_msg_view_get_selected_attachments_default;
341         klass->get_attachments_func = modest_mozembed_msg_view_get_attachments_default;
342         klass->grab_focus_func = modest_mozembed_msg_view_grab_focus_default;
343         klass->remove_attachment_func = modest_mozembed_msg_view_remove_attachment_default;
344         klass->request_fetch_images_func = modest_mozembed_msg_view_request_fetch_images_default;
345         klass->has_blocked_external_images_func = modest_mozembed_msg_view_has_blocked_external_images_default;
346
347         g_type_class_add_private (gobject_class, sizeof(ModestMozembedMsgViewPrivate));
348
349 }
350
351 static void
352 modest_mozembed_msg_view_init (ModestMozembedMsgView *obj)
353 {
354         ModestMozembedMsgViewPrivate *priv;
355         GtkWidget *separator;
356         GtkWidget *main_vbox;
357         GtkWidget *scroll_area;
358         GtkWidget *body_box;
359
360         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE(obj);
361
362         priv->current_zoom = 1.0;
363
364         priv->body_view                 = GTK_WIDGET (g_object_new (MODEST_TYPE_MOZEMBED_MIME_PART_VIEW, NULL));
365         priv->mail_header_view        = GTK_WIDGET(modest_compact_mail_header_view_new (TRUE));
366         gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
367         priv->attachments_view        = GTK_WIDGET(modest_attachments_view_new (NULL));
368
369         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (obj), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
370         gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (obj), NULL);
371         gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (obj), NULL);
372
373         priv->msg                     = NULL;
374
375         priv->headers_box = gtk_vbox_new (0, FALSE);
376
377         if (priv->mail_header_view)
378                 gtk_box_pack_start (GTK_BOX(priv->headers_box), priv->mail_header_view, FALSE, FALSE, 0);
379         
380         if (priv->attachments_view) {
381 #ifndef MODEST_TOOLKIT_HILDON2
382                 gchar *att_label = g_strconcat (_("mcen_me_viewer_attachments"), ":", NULL);
383 #else
384                 gchar *att_label = g_strconcat (_("mail_va_attachment"), ":", NULL);
385 #endif
386
387                 priv->attachments_box = (GtkWidget *)
388                         modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view),
389                                                                    att_label,
390                                                                    priv->attachments_view,
391                                                                    FALSE, FALSE);
392                 gtk_widget_hide_all (priv->attachments_box);
393                 g_free (att_label);
394         }
395
396         separator = gtk_hseparator_new ();
397         gtk_box_pack_start (GTK_BOX(priv->headers_box), separator, FALSE, FALSE, 0);
398
399         body_box = gtk_vbox_new (FALSE, 0);
400
401         main_vbox = gtk_vbox_new (FALSE, 0);
402         gtk_box_pack_start (GTK_BOX (main_vbox), priv->headers_box, FALSE, FALSE, 0);
403         gtk_box_pack_start (GTK_BOX (main_vbox), body_box, TRUE, TRUE, 0);
404
405         if (priv->body_view) {
406                 /* gtk_widget_set_size_request (priv->body_view, 610, 1000); */
407                 /* scroll_area = modest_scroll_area_new (GTK_WIDGET (obj), priv->body_view); */
408                 /* gtk_container_add (GTK_CONTAINER (body_box), scroll_area); */
409
410                 /* gtk_container_add (GTK_CONTAINER (body_box), priv->body_view); */
411                 /* scroll_area = NULL; */
412
413                 scroll_area = gtk_scrolled_window_new (NULL, NULL);
414                 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_area), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
415                 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll_area), priv->body_view);
416                 gtk_box_pack_start (GTK_BOX (body_box), scroll_area, TRUE, TRUE, 0);
417                 gtk_widget_show_all (body_box);
418
419 #if HAVE_DECL_GTK_WIDGET_TAP_AND_HOLD_SETUP
420                 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->body_view), NULL, NULL, 0);
421                 g_signal_connect (G_OBJECT (priv->body_view), "tap-and-hold", G_CALLBACK (on_tap_and_hold), obj);
422 #endif
423         }
424
425         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (obj), main_vbox);
426         
427
428         g_signal_connect (G_OBJECT(priv->body_view), "activate_link",
429                                        G_CALLBACK(on_activate_link), obj);
430         g_signal_connect (G_OBJECT(priv->body_view), "fetch_url",
431                                        G_CALLBACK(on_fetch_url), obj);
432         g_signal_connect (G_OBJECT(priv->body_view), "link_hover",
433                                        G_CALLBACK(on_link_hover), obj);
434
435         g_signal_connect (G_OBJECT (priv->mail_header_view), "recpt-activated", 
436                           G_CALLBACK (on_recpt_activated), obj);
437
438         g_signal_connect (G_OBJECT (priv->attachments_view), "activate",
439                           G_CALLBACK (on_attachment_activated), obj);
440
441 }
442         
443
444 static void
445 modest_mozembed_msg_view_finalize (GObject *obj)
446 {       
447         ModestMozembedMsgViewPrivate *priv;
448         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (obj);
449
450         if (priv->msg) {
451                 g_object_unref (G_OBJECT(priv->msg));
452                 priv->msg = NULL;
453         }
454         
455         priv->body_view = NULL;
456         priv->attachments_view = NULL;
457
458         G_OBJECT_CLASS(parent_class)->finalize (obj);           
459 }
460
461 static void
462 modest_mozembed_msg_view_destroy (GtkObject *obj)
463 {       
464         GTK_OBJECT_CLASS(parent_class)->destroy (obj);          
465 }
466
467 /* INTERNAL METHODS */
468
469 static GtkAdjustment *
470 get_vadjustment (ModestMozembedMsgView *self)
471 {
472         return gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
473         
474 }
475
476 static GtkAdjustment *
477 get_hadjustment (ModestMozembedMsgView *self)
478 {
479         return gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (self));
480 }
481
482 static void
483 set_hadjustment (ModestMozembedMsgView *self, GtkAdjustment *hadj)
484 {
485         gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (self), hadj);
486 }
487
488 static void
489 set_vadjustment (ModestMozembedMsgView *self, GtkAdjustment *vadj)
490 {
491         gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (self), vadj);
492 }
493
494 static void
495 set_shadow_type (ModestMozembedMsgView *self,
496                  GtkShadowType shadow_type)
497 {
498         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self), shadow_type);
499 }
500
501 static GtkShadowType
502 get_shadow_type (ModestMozembedMsgView *self)
503 {
504         return gtk_scrolled_window_get_shadow_type (GTK_SCROLLED_WINDOW (self));
505 }
506
507 GtkWidget*
508 modest_mozembed_msg_view_new (TnyMsg *msg)
509 {
510         GObject *obj;
511         ModestMozembedMsgView* self;
512         
513         obj  = G_OBJECT(g_object_new(MODEST_TYPE_MOZEMBED_MSG_VIEW, NULL));
514         self = MODEST_MOZEMBED_MSG_VIEW(obj);
515         tny_msg_view_set_msg (TNY_MSG_VIEW (self), msg);
516
517         return GTK_WIDGET(self);
518 }
519
520 #if HAVE_DECL_GTK_WIDGET_TAP_AND_HOLD_SETUP
521 static void
522 on_tap_and_hold (GtkWidget *widget,
523                  gpointer data)
524 {
525         ModestMozembedMsgView *self = (ModestMozembedMsgView *) data;
526         ModestMozembedMsgViewPrivate *priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
527
528         g_signal_emit_by_name (G_OBJECT (self), "link-contextual", priv->last_url);
529 }
530 #endif
531
532 static void
533 on_recpt_activated (ModestMailHeaderView *header_view, 
534                     const gchar *address,
535                     ModestMozembedMsgView *self)
536 {
537         g_signal_emit_by_name (G_OBJECT (self), "recpt-activated", address);
538 }
539
540 static void
541 on_attachment_activated (ModestAttachmentsView * att_view, TnyMimePart *mime_part, gpointer self)
542 {
543
544         g_signal_emit_by_name (G_OBJECT(self), "attachment_clicked", mime_part);
545 }
546
547
548 static void
549 request_fetch_images (ModestMozembedMsgView *self)
550 {
551         ModestMozembedMsgViewPrivate *priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
552         TnyMimePart *part;
553
554         /* The message could have not been downloaded yet */
555         if (priv->msg) {
556                 modest_mime_part_view_set_view_images (MODEST_MIME_PART_VIEW (priv->body_view), TRUE);
557                 part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (priv->body_view));
558                 if (part) {
559                         tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (priv->body_view), part);
560                         g_object_unref (part);
561                 }
562                 tny_msg_set_allow_external_images (TNY_MSG (priv->msg), TRUE);
563         }
564 }
565
566 static gboolean
567 has_blocked_external_images (ModestMozembedMsgView *self)
568 {
569         ModestMozembedMsgViewPrivate *priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
570
571         return modest_mime_part_view_has_external_images (MODEST_MIME_PART_VIEW (priv->body_view));
572 }
573
574 static gboolean
575 on_activate_link (GtkWidget *widget, const gchar *uri, ModestMozembedMsgView *self)
576 {
577         gboolean result;
578         g_return_val_if_fail (self, FALSE);
579         
580         g_signal_emit_by_name (G_OBJECT(self), "activate-link", uri, &result);
581
582         return result;
583 }
584
585
586 static gboolean
587 on_link_hover (GtkWidget *widget, const gchar *uri, ModestMozembedMsgView *self)
588 {
589         ModestMozembedMsgViewPrivate *priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
590         gboolean result;
591
592         g_free (priv->last_url);
593         priv->last_url = g_strdup (uri);
594
595         g_signal_emit_by_name (G_OBJECT(self), "link-hover", uri, &result);
596
597         return result;
598 }
599
600
601
602 static TnyMimePart *
603 find_cid_image (TnyMsg *msg, const gchar *cid)
604 {
605         TnyMimePart *part = NULL;
606         TnyList *parts;
607         TnyIterator *iter;
608         
609         g_return_val_if_fail (msg, NULL);
610         g_return_val_if_fail (cid, NULL);
611         
612         parts  = TNY_LIST (tny_simple_list_new());
613
614         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); 
615         iter   = tny_list_create_iterator (parts);
616         
617         while (!tny_iterator_is_done(iter)) {
618                 const gchar *part_cid;
619
620                 part = TNY_MIME_PART(tny_iterator_get_current(iter));
621                 part_cid = tny_mime_part_get_content_id (part);
622
623                 if (part_cid && strcmp (cid, part_cid) == 0)
624                         break;
625
626                 if (tny_mime_part_content_type_is (part, "multipart/related")) {
627                         TnyList *related_parts = TNY_LIST (tny_simple_list_new ());
628                         TnyIterator *related_iter = NULL;
629                         TnyMimePart *related_part = NULL;
630
631                         tny_mime_part_get_parts (part, related_parts);
632                         related_iter = tny_list_create_iterator (related_parts);
633
634                         while (!tny_iterator_is_done (related_iter)) {
635                                 related_part = TNY_MIME_PART (tny_iterator_get_current (related_iter));
636                                 part_cid = tny_mime_part_get_content_id (related_part);
637                                 if (part_cid && strcmp (cid, part_cid) == 0) {
638                                         break;
639                                 }
640                                 g_object_unref (related_part);
641                                 related_part = NULL;
642                                 tny_iterator_next (related_iter);
643                         }
644
645                         g_object_unref (related_iter);
646                         g_object_unref (related_parts);
647                         if (related_part != NULL) {
648                                 g_object_unref (part);
649                                 part = related_part;
650                                 break;
651                         }
652                 }
653
654                 g_object_unref (G_OBJECT(part));
655         
656                 part = NULL;
657                 tny_iterator_next (iter);
658         }
659         
660         g_object_unref (G_OBJECT(iter));        
661         g_object_unref (G_OBJECT(parts));
662         
663         return part;
664 }
665
666
667 static gboolean
668 on_fetch_url (GtkWidget *widget, const gchar *uri,
669               TnyStream *stream, ModestMozembedMsgView *self)
670 {
671         ModestMozembedMsgViewPrivate *priv;
672         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
673         gboolean result = FALSE;
674         
675         if (g_str_has_prefix (uri, "cid:")) {
676                 /* +4 ==> skip "cid:" */
677                 TnyMimePart *part = find_cid_image (priv->msg, uri + 4);
678                 if (!part) {
679                         g_printerr ("modest: '%s' not found\n", uri + 4);
680                         result = FALSE;
681                 } else {
682                         tny_mime_part_decode_to_stream ((TnyMimePart*)part,
683                                                         stream, NULL);
684                         g_object_unref (G_OBJECT(part));
685                         result = TRUE;
686                 }
687         } else {
688                 return TRUE;
689         }
690
691         return result;
692 }
693
694 static void
695 set_message (ModestMozembedMsgView *self, TnyMsg *msg, TnyMimePart *other_body)
696 {
697         TnyMimePart *body;
698         ModestMozembedMsgViewPrivate *priv;
699         TnyHeader *header;
700         
701         g_return_if_fail (self);
702         
703         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE(self);
704         gtk_widget_set_no_show_all (priv->mail_header_view, FALSE);
705
706         if (msg != priv->msg) {
707                 if (priv->msg)
708                         g_object_unref (G_OBJECT(priv->msg));
709                 if (msg)
710                         g_object_ref   (G_OBJECT(msg));
711                 priv->msg = msg;
712         }
713         
714         if (!msg) {
715                 tny_header_view_clear (TNY_HEADER_VIEW (priv->mail_header_view));
716                 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL);
717                 gtk_widget_hide_all (priv->mail_header_view);
718                 gtk_widget_hide_all (priv->attachments_box);
719                 gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
720                 tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view));
721                 return;
722         }
723
724         header = tny_msg_get_header (msg);
725         tny_header_view_set_header (TNY_HEADER_VIEW (priv->mail_header_view), header);
726         g_object_unref (header);
727
728         modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW(priv->attachments_view),
729                                              other_body?NULL:msg);
730         
731         if (other_body) {
732                 body = other_body;
733                 g_object_ref (body);
734         } else {
735                 body = modest_tny_msg_find_body_part (msg, TRUE);
736         }
737
738         if (body) {
739                 tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (priv->body_view), body);
740
741                 if(modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view))) {
742                         gtk_widget_show_all (priv->attachments_box);
743                 } else {
744                         gtk_widget_hide_all (priv->attachments_box);
745                 }
746
747         } else 
748                 tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view));
749
750         gtk_widget_show (priv->body_view);
751         gtk_widget_set_no_show_all (priv->attachments_box, TRUE);
752         gtk_widget_show_all (priv->mail_header_view);
753         gtk_widget_set_no_show_all (priv->attachments_box, FALSE);
754         gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
755
756 }
757
758 static void
759 set_header (ModestMozembedMsgView *self, TnyHeader *header)
760 {
761         ModestMozembedMsgViewPrivate *priv;
762         
763         g_return_if_fail (self);
764
765         if (header == NULL)
766                 set_message (self, NULL, NULL);
767         
768         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE(self);
769         gtk_widget_set_no_show_all (priv->mail_header_view, FALSE);
770
771         if (priv->msg)
772                 g_object_unref (G_OBJECT(priv->msg));
773         priv->msg = NULL;
774         
775         tny_header_view_set_header (TNY_HEADER_VIEW (priv->mail_header_view), header);
776         modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL);
777         gtk_widget_show_all (priv->mail_header_view);
778         gtk_widget_hide_all (priv->attachments_box);
779         gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
780         tny_mime_part_view_clear (TNY_MIME_PART_VIEW (priv->body_view));
781 }
782
783
784 static TnyMsg*
785 get_message (ModestMozembedMsgView *self)
786 {
787         TnyMsg *msg;
788
789         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), NULL);
790
791         msg = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE(self)->msg;
792
793         if (msg)
794                 g_object_ref (msg);
795         
796         return msg;
797 }
798
799 static gboolean 
800 is_empty (ModestMozembedMsgView *self)
801 {
802         ModestMozembedMsgViewPrivate *priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
803
804         return modest_mime_part_view_is_empty (MODEST_MIME_PART_VIEW (priv->body_view));
805 }
806
807 static void
808 set_zoom (ModestMozembedMsgView *self, gdouble zoom)
809 {
810         ModestMozembedMsgViewPrivate *priv;
811
812         g_return_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self));
813         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
814
815         modest_zoomable_set_zoom (MODEST_ZOOMABLE(priv->body_view), zoom);
816
817         gtk_widget_queue_resize (priv->body_view);
818 }
819
820 static gdouble
821 get_zoom (ModestMozembedMsgView *self)
822 {
823         ModestMozembedMsgViewPrivate *priv;
824
825         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), 1.0);
826         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
827
828         return modest_zoomable_get_zoom (MODEST_ZOOMABLE (priv->body_view));
829 }
830
831 static TnyHeaderFlags
832 get_priority (ModestMozembedMsgView *self)
833 {
834         ModestMozembedMsgViewPrivate *priv;
835
836         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), 0);
837
838         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
839
840         return modest_mail_header_view_get_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view));
841 }
842
843 static void
844 set_priority (ModestMozembedMsgView *self, TnyHeaderFlags flags)
845 {
846         ModestMozembedMsgViewPrivate *priv;
847
848         g_return_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self));
849         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
850
851         modest_mail_header_view_set_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), flags);
852 }
853
854 /* INCREMENTAL SEARCH IMPLEMENTATION */
855
856 static gboolean 
857 search (ModestMozembedMsgView *self, const gchar *search)
858 {
859         ModestMozembedMsgViewPrivate *priv;
860         gboolean result;
861
862         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), FALSE);
863
864         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
865         result = modest_isearch_view_search (MODEST_ISEARCH_VIEW (priv->body_view),
866                                              search);
867
868         return result;
869 }
870
871 static gboolean
872 search_next (ModestMozembedMsgView *self)
873 {
874         ModestMozembedMsgViewPrivate *priv;
875         gboolean result;
876
877         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), FALSE);
878
879         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
880         result = modest_isearch_view_search_next (MODEST_ISEARCH_VIEW (priv->body_view));
881
882         return result;
883 }
884
885 static TnyList *
886 get_selected_attachments (ModestMozembedMsgView *self)
887 {
888         ModestMozembedMsgViewPrivate *priv;
889
890         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), NULL);
891         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
892
893         return modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
894         
895 }
896
897 static TnyList *
898 get_attachments (ModestMozembedMsgView *self)
899 {
900         ModestMozembedMsgViewPrivate *priv;
901
902         g_return_val_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self), NULL);
903         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
904
905         return modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
906         
907 }
908
909 static void
910 grab_focus (ModestMozembedMsgView *self)
911 {
912         ModestMozembedMsgViewPrivate *priv = NULL;
913
914         g_return_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self));
915         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
916
917         gtk_widget_grab_focus (priv->body_view);
918 }
919
920 static void
921 remove_attachment (ModestMozembedMsgView *self, TnyMimePart *attachment)
922 {
923         ModestMozembedMsgViewPrivate *priv;
924
925         g_return_if_fail (MODEST_IS_MOZEMBED_MSG_VIEW (self));
926         g_return_if_fail (TNY_IS_MIME_PART (attachment));
927         priv = MODEST_MOZEMBED_MSG_VIEW_GET_PRIVATE (self);
928
929         modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
930                                                    attachment);
931         
932 }
933
934 /* TNY HEADER VIEW IMPLEMENTATION */
935
936 static void
937 tny_header_view_init (gpointer g, gpointer iface_data)
938 {
939         TnyHeaderViewIface *klass = (TnyHeaderViewIface *)g;
940
941         klass->set_header = modest_msg_view_set_header;
942         klass->clear = modest_msg_view_clear_header;
943
944         return;
945 }
946
947 static void
948 modest_msg_view_set_header (TnyHeaderView *self, TnyHeader *header)
949 {
950         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_header_func (self, header);
951 }
952
953
954 static void
955 modest_msg_view_set_header_default (TnyHeaderView *self, TnyHeader *header)
956 {
957         set_header (MODEST_MOZEMBED_MSG_VIEW (self), header);
958 }
959
960 static void
961 modest_msg_view_clear_header (TnyHeaderView *self)
962 {
963         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->clear_header_func (self);
964 }
965
966
967 static void
968 modest_msg_view_clear_header_default (TnyHeaderView *self)
969 {
970         set_message (MODEST_MOZEMBED_MSG_VIEW (self), NULL, NULL);
971 }
972
973 /* TNY MSG IMPLEMENTATION */
974
975 static void
976 tny_msg_view_init (gpointer g, gpointer iface_data)
977 {
978         TnyMsgViewIface *klass = (TnyMsgViewIface *)g;
979
980         klass->get_msg = modest_msg_view_get_msg;
981         klass->set_msg = modest_msg_view_set_msg;
982         klass->set_unavailable = modest_msg_view_set_unavailable;
983         klass->clear = modest_msg_view_clear;
984         klass->create_mime_part_view_for = modest_msg_view_create_mime_part_view_for;
985         klass->create_new_inline_viewer = modest_msg_view_create_new_inline_viewer;
986
987         return;
988 }
989
990 static TnyMsg *
991 modest_msg_view_get_msg (TnyMsgView *self)
992 {
993         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_msg_func (self);
994 }
995
996 static TnyMsg *
997 modest_msg_view_get_msg_default (TnyMsgView *self)
998 {
999         return TNY_MSG (tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (self)));
1000 }
1001
1002 static void
1003 modest_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg)
1004 {
1005         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_msg_func (self, msg);
1006 }
1007
1008 static void 
1009 modest_msg_view_set_msg_default (TnyMsgView *self, TnyMsg *msg)
1010 {
1011
1012         tny_mime_part_view_set_part (TNY_MIME_PART_VIEW (self), TNY_MIME_PART (msg));
1013
1014         return;
1015 }
1016
1017 static void
1018 modest_msg_view_set_unavailable (TnyMsgView *self)
1019 {
1020         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_unavailable_func (self);
1021 }
1022
1023 static void
1024 modest_msg_view_set_unavailable_default (TnyMsgView *self)
1025 {
1026         tny_msg_view_clear (self);
1027
1028         return;
1029 }
1030
1031 static void
1032 modest_msg_view_clear (TnyMsgView *self)
1033 {
1034         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->clear_func (self);
1035 }
1036
1037 static void
1038 modest_msg_view_clear_default (TnyMsgView *self)
1039 {
1040         set_message (MODEST_MOZEMBED_MSG_VIEW (self), NULL, NULL);
1041 }
1042
1043 static TnyMimePartView*
1044 modest_msg_view_create_mime_part_view_for (TnyMsgView *self, TnyMimePart *part)
1045 {
1046         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->create_mime_part_view_for_func (self, part);
1047 }
1048
1049 static TnyMimePartView*
1050 modest_msg_view_create_mime_part_view_for_default (TnyMsgView *self, TnyMimePart *part)
1051 {
1052         g_warning ("modest_msg_view_create_mime_part_view_for_default is not implemented");
1053         return NULL;
1054 }
1055
1056 static TnyMsgView*
1057 modest_msg_view_create_new_inline_viewer (TnyMsgView *self)
1058 {
1059         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->create_new_inline_viewer_func (self);
1060 }
1061
1062 static TnyMsgView*
1063 modest_msg_view_create_new_inline_viewer_default (TnyMsgView *self)
1064 {
1065         g_warning ("modest_msg_view_create_new_inline_viewer_default is not implemented");
1066
1067         return NULL;
1068 }
1069
1070 /* TNY MIME PART IMPLEMENTATION */
1071
1072 static void
1073 tny_mime_part_view_init (gpointer g, gpointer iface_data)
1074 {
1075         TnyMimePartViewIface *klass = (TnyMimePartViewIface *)g;
1076
1077         klass->get_part = modest_msg_view_mp_get_part;
1078         klass->set_part = modest_msg_view_mp_set_part;
1079         klass->clear = modest_msg_view_mp_clear;
1080
1081         return;
1082 }
1083
1084 static TnyMimePart* 
1085 modest_msg_view_mp_get_part (TnyMimePartView *self)
1086 {
1087         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_part_func (self);
1088 }
1089
1090
1091 static TnyMimePart* 
1092 modest_msg_view_mp_get_part_default (TnyMimePartView *self)
1093 {
1094         return TNY_MIME_PART (get_message (MODEST_MOZEMBED_MSG_VIEW (self)));
1095 }
1096
1097 static void
1098 modest_msg_view_mp_set_part (TnyMimePartView *self,
1099                              TnyMimePart *part)
1100 {
1101         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_part_func (self, part);
1102 }
1103
1104 static void
1105 modest_msg_view_mp_set_part_default (TnyMimePartView *self,
1106                                      TnyMimePart *part)
1107 {
1108         g_return_if_fail ((part == NULL) || TNY_IS_MSG (part));
1109
1110         set_message (MODEST_MOZEMBED_MSG_VIEW (self), TNY_MSG (part), NULL);
1111 }
1112
1113 static void
1114 modest_msg_view_mp_clear (TnyMimePartView *self)
1115 {
1116         tny_msg_view_clear (TNY_MSG_VIEW (self));
1117 }
1118
1119 /* MODEST MIME PART VIEW IMPLEMENTATION */
1120
1121 static void
1122 modest_mime_part_view_init (gpointer g, gpointer iface_data)
1123 {
1124         ModestMimePartViewIface *klass = (ModestMimePartViewIface *)g;
1125
1126         klass->is_empty_func = modest_msg_view_mp_is_empty;
1127
1128         return;
1129 }
1130
1131 static gboolean
1132 modest_msg_view_mp_is_empty (ModestMimePartView *self)
1133 {
1134         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->is_empty_func (self);
1135 }
1136
1137 static gboolean
1138 modest_msg_view_mp_is_empty_default (ModestMimePartView *self)
1139 {
1140         return is_empty (MODEST_MOZEMBED_MSG_VIEW (self));
1141 }
1142
1143 /* MODEST ZOOMABLE IMPLEMENTATION */
1144 static void
1145 modest_zoomable_init (gpointer g, gpointer iface_data)
1146 {
1147         ModestZoomableIface *klass = (ModestZoomableIface *)g;
1148
1149         klass->get_zoom_func = modest_msg_view_get_zoom;
1150         klass->set_zoom_func = modest_msg_view_set_zoom;
1151         klass->zoom_minus_func = modest_msg_view_zoom_minus;
1152         klass->zoom_plus_func = modest_msg_view_zoom_plus;
1153
1154         return;
1155 }
1156
1157 static gdouble
1158 modest_msg_view_get_zoom (ModestZoomable *self)
1159 {
1160         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_zoom_func (self);
1161 }
1162
1163 static gdouble
1164 modest_msg_view_get_zoom_default (ModestZoomable *self)
1165 {
1166         return get_zoom (MODEST_MOZEMBED_MSG_VIEW (self));
1167 }
1168
1169 static void
1170 modest_msg_view_set_zoom (ModestZoomable *self, gdouble value)
1171 {
1172         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_zoom_func (self, value);
1173 }
1174
1175 static void
1176 modest_msg_view_set_zoom_default (ModestZoomable *self, gdouble value)
1177 {
1178         set_zoom (MODEST_MOZEMBED_MSG_VIEW (self), value);
1179 }
1180
1181 static gboolean
1182 modest_msg_view_zoom_minus (ModestZoomable *self)
1183 {
1184         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->zoom_minus_func (self);
1185 }
1186
1187 static gboolean
1188 modest_msg_view_zoom_minus_default (ModestZoomable *self)
1189 {
1190         /* operation not supported in ModestMsgView */
1191         return FALSE;
1192 }
1193
1194 static gboolean
1195 modest_msg_view_zoom_plus (ModestZoomable *self)
1196 {
1197         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->zoom_plus_func (self);
1198 }
1199
1200 static gboolean
1201 modest_msg_view_zoom_plus_default (ModestZoomable *self)
1202 {
1203         /* operation not supported in ModestMsgView */
1204         return FALSE;
1205 }
1206
1207 /* MODEST ISEARCH VIEW IMPLEMENTATION */
1208 static void
1209 modest_isearch_view_init (gpointer g, gpointer iface_data)
1210 {
1211         ModestISearchViewIface *klass = (ModestISearchViewIface *)g;
1212
1213         klass->search_func = modest_msg_view_search;
1214         klass->search_next_func = modest_msg_view_search_next;
1215
1216         return;
1217 }
1218
1219 static gboolean
1220 modest_msg_view_search (ModestISearchView *self, const gchar *string)
1221 {
1222         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->search_func (self, string);
1223 }
1224
1225 static gboolean
1226 modest_msg_view_search_default (ModestISearchView *self, const gchar *string)
1227 {
1228         return search (MODEST_MOZEMBED_MSG_VIEW (self), string);
1229 }
1230
1231 static gboolean
1232 modest_msg_view_search_next (ModestISearchView *self)
1233 {
1234         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->search_next_func (self);
1235 }
1236
1237 static gboolean
1238 modest_msg_view_search_next_default (ModestISearchView *self)
1239 {
1240         return search_next (MODEST_MOZEMBED_MSG_VIEW (self));
1241 }
1242
1243 /* MODEST MSG VIEW IMPLEMENTATION */
1244 static void
1245 modest_msg_view_init (gpointer g, gpointer iface_data)
1246 {
1247         ModestMsgViewIface *klass = (ModestMsgViewIface *)g;
1248
1249         klass->set_msg_with_other_body_func = modest_mozembed_msg_view_set_msg_with_other_body;
1250         klass->get_vadjustment_func = modest_mozembed_msg_view_get_vadjustment;
1251         klass->get_hadjustment_func = modest_mozembed_msg_view_get_hadjustment;
1252         klass->set_vadjustment_func = modest_mozembed_msg_view_set_vadjustment;
1253         klass->set_hadjustment_func = modest_mozembed_msg_view_set_hadjustment;
1254         klass->set_shadow_type_func = modest_mozembed_msg_view_set_shadow_type;
1255         klass->get_shadow_type_func = modest_mozembed_msg_view_get_shadow_type;
1256         klass->get_priority_func = modest_mozembed_msg_view_get_priority;
1257         klass->set_priority_func = modest_mozembed_msg_view_set_priority;
1258         klass->get_selected_attachments_func = modest_mozembed_msg_view_get_selected_attachments;
1259         klass->get_attachments_func = modest_mozembed_msg_view_get_attachments;
1260         klass->grab_focus_func = modest_mozembed_msg_view_grab_focus;
1261         klass->remove_attachment_func = modest_mozembed_msg_view_remove_attachment;
1262         klass->request_fetch_images_func = modest_mozembed_msg_view_request_fetch_images;
1263         klass->has_blocked_external_images_func = modest_mozembed_msg_view_has_blocked_external_images;
1264
1265         return;
1266 }
1267
1268 static void
1269 modest_mozembed_msg_view_set_msg_with_other_body (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body)
1270 {
1271         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_msg_with_other_body_func (self, msg, other_body);
1272 }
1273
1274 static void
1275 modest_mozembed_msg_view_set_msg_with_other_body_default (ModestMsgView *self, TnyMsg *msg, TnyMimePart *other_body)
1276 {
1277         set_message (MODEST_MOZEMBED_MSG_VIWE (self), msg, other_body);
1278 }
1279
1280 static GtkAdjustment*
1281 modest_mozembed_msg_view_get_vadjustment (ModestMsgView *self)
1282 {
1283         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_vadjustment_func (self);
1284 }
1285
1286 static GtkAdjustment*
1287 modest_mozembed_msg_view_get_vadjustment_default (ModestMsgView *self)
1288 {
1289         return get_vadjustment (MODEST_MOZEMBED_MSG_VIEW (self));
1290 }
1291
1292 static GtkAdjustment*
1293 modest_mozembed_msg_view_get_hadjustment (ModestMsgView *self)
1294 {
1295         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_hadjustment_func (self);
1296 }
1297
1298 static GtkAdjustment*
1299 modest_mozembed_msg_view_get_hadjustment_default (ModestMsgView *self)
1300 {
1301         return get_hadjustment (MODEST_MOZEMBED_MSG_VIEW (self));
1302 }
1303
1304 static void
1305 modest_mozembed_msg_view_set_vadjustment (ModestMsgView *self, GtkAdjustment *adj)
1306 {
1307         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_vadjustment_func (self, adj);
1308 }
1309
1310 static void
1311 modest_mozembed_msg_view_set_vadjustment_default (ModestMsgView *self, GtkAdjustment *adj)
1312 {
1313         set_vadjustment (MODEST_MOZEMBED_MSG_VIEW (self), adj);
1314 }
1315
1316 static void
1317 modest_mozembed_msg_view_set_hadjustment (ModestMsgView *self, GtkAdjustment *adj)
1318 {
1319         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_hadjustment_func (self, adj);
1320 }
1321
1322 static void
1323 modest_mozembed_msg_view_set_hadjustment_default (ModestMsgView *self, GtkAdjustment *adj)
1324 {
1325         set_hadjustment (MODEST_MOZEMBED_MSG_VIEW (self), adj);
1326 }
1327
1328 static void
1329 modest_mozembed_msg_view_set_shadow_type (ModestMsgView *self, GtkShadowType type)
1330 {
1331         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_shadow_type_func (self, type);
1332 }
1333
1334 static void
1335 modest_mozembed_msg_view_set_shadow_type_default (ModestMsgView *self, GtkShadowType type)
1336 {
1337         set_shadow_type (MODEST_MOZEMBED_MSG_VIEW (self), type);
1338 }
1339
1340 static GtkShadowType
1341 modest_mozembed_msg_view_get_shadow_type (ModestMsgView *self)
1342 {
1343         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_shadow_type_func (self);
1344 }
1345
1346 static GtkShadowType
1347 modest_mozembed_msg_view_get_shadow_type_default (ModestMsgView *self)
1348 {
1349         return get_shadow_type (MODEST_MOZEMBED_MSG_VIEW (self));
1350 }
1351
1352 static void
1353 modest_mozembed_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags)
1354 {
1355         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->set_priority_func (self, flags);
1356 }
1357
1358 static void
1359 modest_mozembed_msg_view_set_priority_default (ModestMsgView *self, TnyHeaderFlags flags)
1360 {
1361         set_priority (MODEST_MOZEMBED_MSG_VIEW (self), flags);
1362 }
1363
1364 static TnyHeaderFlags
1365 modest_mozembed_msg_view_get_priority (ModestMsgView *self)
1366 {
1367         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_priority_func (self);
1368 }
1369
1370 static TnyHeaderFlags
1371 modest_mozembed_msg_view_get_priority_default (ModestMsgView *self)
1372 {
1373         return get_priority (MODEST_MOZEMBED_MSG_VIEW (self));
1374 }
1375
1376 static TnyList*
1377 modest_mozembed_msg_view_get_selected_attachments (ModestMsgView *self)
1378 {
1379         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_selected_attachments_func (self);
1380 }
1381
1382 static TnyList*
1383 modest_mozembed_msg_view_get_selected_attachments_default (ModestMsgView *self)
1384 {
1385         return get_selected_attachments (MODEST_MOZEMBED_MSG_VIEW (self));
1386 }
1387
1388 static TnyList*
1389 modest_mozembed_msg_view_get_attachments (ModestMsgView *self)
1390 {
1391         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->get_attachments_func (self);
1392 }
1393
1394 static TnyList*
1395 modest_mozembed_msg_view_get_attachments_default (ModestMsgView *self)
1396 {
1397         return get_attachments (MODEST_MOZEMBED_MSG_VIEW (self));
1398 }
1399
1400 static void
1401 modest_mozembed_msg_view_grab_focus (ModestMsgView *self)
1402 {
1403         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->grab_focus_func (self);
1404 }
1405
1406 static void
1407 modest_mozembed_msg_view_grab_focus_default (ModestMsgView *self)
1408 {
1409         grab_focus (MODEST_MOZEMBED_MSG_VIEW (self));
1410 }
1411
1412 static void
1413 modest_mozembed_msg_view_remove_attachment (ModestMsgView *self, TnyMimePart *attachment)
1414 {
1415         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->remove_attachment_func (self, attachment);
1416 }
1417
1418 static void
1419 modest_mozembed_msg_view_remove_attachment_default (ModestMsgView *self, TnyMimePart *attachment)
1420 {
1421         remove_attachment (MODEST_MOZEMBED_MSG_VIEW (self), attachment);
1422 }
1423
1424 static void
1425 modest_mozembed_msg_view_request_fetch_images (ModestMsgView *self)
1426 {
1427         MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->request_fetch_images_func (self);
1428 }
1429
1430 static void
1431 modest_mozembed_msg_view_request_fetch_images_default (ModestMsgView *self)
1432 {
1433         request_fetch_images (MODEST_MOZEMBED_MSG_VIEW (self));
1434 }
1435
1436 static gboolean
1437 modest_mozembed_msg_view_has_blocked_external_images (ModestMsgView *self)
1438 {
1439         return MODEST_MOZEMBED_MSG_VIEW_GET_CLASS (self)->has_blocked_external_images_func (self);
1440 }
1441
1442 static gboolean
1443 modest_mozembed_msg_view_has_blocked_external_images_default (ModestMsgView *self)
1444 {
1445         return has_blocked_external_images (MODEST_MOZEMBED_MSG_VIEW (self));
1446 }