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