root/trunk/libtinymailui-gtkhtml/tny-gtk-html-mime-part-view.c

Revision 3666 (checked in by jdapena, 6 months ago)

* Use GOnce registering all types in tinymail to make

registering thread-safe.

Line 
1 /* libtinymailui-webkit - The Tiny Mail UI library for Webkit
2  * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org>
3  *
4  * This component was developed based on Modest's ModestGtkHtmlMimePartView
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with self library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22  
23 #include <config.h>
24 #include <glib/gi18n-lib.h>
25
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32
33 #include <string.h>
34 #include <gtk/gtk.h>
35
36 #include <tny-gtk-html-mime-part-view.h>
37 #include <tny-gtk-html-stream.h>
38
39 static GObjectClass *parent_class = NULL;
40
41 typedef struct _TnyGtkHtmlMimePartViewPriv TnyGtkHtmlMimePartViewPriv;
42
43 struct _TnyGtkHtmlMimePartViewPriv {
44         TnyMimePart *part;
45         TnyStatusCallback status_callback;
46         gpointer status_user_data;
47 };
48
49 #define TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE(o) \
50         (G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_GTK_HTML_MIME_PART_VIEW, TnyGtkHtmlMimePartViewPriv))
51
52
53 static TnyMimePart*
54 tny_gtk_html_mime_part_view_get_part (TnyMimePartView *self)
55 {
56         TnyGtkHtmlMimePartViewPriv *priv = TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE (self);
57         return (priv->part)?TNY_MIME_PART (g_object_ref (priv->part)):NULL;
58 }
59
60
61 typedef struct {
62         TnyGtkHtmlMimePartView *self;
63         GtkHTMLStream *gtkhtml_stream;
64         TnyStream *tny_stream;
65 } SomeData;
66
67
68 static void
69 on_status (GObject *self, TnyStatus *status, gpointer user_data)
70 {
71         SomeData *info = (SomeData *) user_data;
72         TnyGtkHtmlMimePartViewPriv *priv = TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE (info->self);
73         if (priv->status_callback)
74                 priv->status_callback (self, status, priv->status_user_data);
75 }
76
77 static void
78 on_set_stream_finished (TnyMimePart *self, gboolean cancelled, TnyStream *stream, GError *err, gpointer user_data)
79 {
80         SomeData *info = (SomeData *) user_data;
81
82         g_object_unref (info->tny_stream);
83         gtk_html_stream_destroy (info->gtkhtml_stream);
84         g_object_unref (info->self);
85
86         g_slice_free (SomeData, user_data);
87 }
88
89 static void
90 set_html_part (TnyGtkHtmlMimePartView *self, TnyMimePart *part)
91 {
92         SomeData *info = g_slice_new (SomeData);
93
94         info->self = (TnyGtkHtmlMimePartView *) g_object_ref (self);
95         info->gtkhtml_stream = gtk_html_begin(GTK_HTML(self));
96         info->tny_stream = TNY_STREAM (tny_gtk_html_stream_new (info->gtkhtml_stream));
97         tny_stream_reset (info->tny_stream);
98
99         tny_mime_part_decode_to_stream_async ((TnyMimePart*)part, info->tny_stream,
100                         on_set_stream_finished, on_status, info);
101
102         return;
103 }
104
105
106 /**
107  * tny_gtk_html_mime_part_view_set_part:
108  * @self: a #TnyWebkitMimePartView instance
109  * @part: a #TnyMimePart instance
110  *
111  * This is non-public API documentation
112  *
113  * The implementation simply decodes the part to a stream that is implemented in
114  * such a way that it will forward the stream to the GtkWebkit stream API.
115  **/
116 static void
117 tny_gtk_html_mime_part_view_set_part (TnyMimePartView *self, TnyMimePart *part)
118 {
119         TnyGtkHtmlMimePartViewPriv *priv = TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE (self);
120
121         if (priv->part)
122                 g_object_unref (priv->part);
123
124         if (part) {
125                 set_html_part (TNY_GTK_HTML_MIME_PART_VIEW (self), part);
126                 priv->part = (TnyMimePart *) g_object_ref (part);
127         }
128
129         return;
130 }
131
132 static void
133 tny_gtk_html_mime_part_view_clear (TnyMimePartView *self)
134 {
135         return;
136 }
137
138
139
140
141 #if 0
142 typedef struct {
143         gpointer buffer;
144         GtkHTML *html;
145         GtkHTMLStream *stream;
146         gboolean html_finalized;
147 } ImageFetcherInfo;
148
149 static void
150 html_finalized_notify (ImageFetcherInfo *ifinfo,
151                        GObject *destroyed)
152 {
153         ifinfo->html_finalized = TRUE;
154 }
155
156 static void
157 image_fetcher_close (GnomeVFSAsyncHandle *handle,
158                      GnomeVFSResult result,
159                      gpointer data)
160 {
161 }
162
163 static void
164 image_fetcher_read (GnomeVFSAsyncHandle *handle,
165                     GnomeVFSResult result,
166                     gpointer buffer,
167                     GnomeVFSFileSize bytes_requested,
168                     GnomeVFSFileSize bytes_read,
169                     ImageFetcherInfo *ifinfo)
170 {
171
172         if (ifinfo->html_finalized || result != GNOME_VFS_OK) {
173                 gnome_vfs_async_close (handle, (GnomeVFSAsyncCloseCallback) image_fetcher_close, (gpointer) NULL);
174                 if (!ifinfo->html_finalized) {
175                         gtk_html_stream_close (ifinfo->stream, GTK_HTML_STREAM_OK);
176                         g_object_weak_unref ((GObject *) ifinfo->html, (GWeakNotify) html_finalized_notify, (gpointer) ifinfo);
177                 }
178                 g_slice_free1 (128, ifinfo->buffer);
179                 g_slice_free (ImageFetcherInfo, ifinfo);
180                 return;
181         }
182         gtk_html_stream_write (ifinfo->stream, buffer, bytes_read);
183         gnome_vfs_async_read (handle, ifinfo->buffer, 128,
184                               (GnomeVFSAsyncReadCallback)image_fetcher_read, ifinfo);
185         return;
186 }
187
188 static void
189 image_fetcher_open (GnomeVFSAsyncHandle *handle,
190                     GnomeVFSResult result,
191                     ImageFetcherInfo *ifinfo)
192 {
193         if (!ifinfo->html_finalized && result == GNOME_VFS_OK) {
194                 ifinfo->buffer = g_slice_alloc (128);
195                 gnome_vfs_async_read (handle, ifinfo->buffer, 128,
196                                       (GnomeVFSAsyncReadCallback) image_fetcher_read, ifinfo);
197         } else {
198                 if (!ifinfo->html_finalized) {
199                         gtk_html_stream_close (ifinfo->stream, GTK_HTML_STREAM_OK);
200                         g_object_weak_unref ((GObject *) ifinfo->html, (GWeakNotify) html_finalized_notify, (gpointer) ifinfo);
201                 }
202                 g_slice_free (ImageFetcherInfo, ifinfo);
203         }
204 }
205
206 #endif
207
208 static gboolean
209 on_url_requested (GtkWidget *widget, const gchar *uri, GtkHTMLStream *stream, TnyMimePartView *self)
210 {
211         gboolean result;
212         TnyStream *tny_stream;
213
214 #if 0
215         if (g_str_has_prefix (uri, "http:") && TRUE /* TODO: make optional */) {
216                 GnomeVFSAsyncHandle *handle;
217                 ImageFetcherInfo *ifinfo;
218
219                 ifinfo = g_slice_new (ImageFetcherInfo);
220                 ifinfo->html_finalized = FALSE;
221                 ifinfo->html = (GtkHTML *) self;
222                 ifinfo->buffer = NULL;
223                 ifinfo->stream = stream;
224                 g_object_weak_ref ((GObject *) self, (GWeakNotify) html_finalized_notify, (gpointer) ifinfo);
225                 gnome_vfs_async_open (&handle, uri, GNOME_VFS_OPEN_READ,
226                                       GNOME_VFS_PRIORITY_DEFAULT,
227                                       (GnomeVFSAsyncOpenCallback) image_fetcher_open, ifinfo);
228                 return FALSE;
229         }
230 #endif
231
232         tny_stream = TNY_STREAM (tny_gtk_html_stream_new (stream));
233         g_signal_emit_by_name (self, "fetch-url", uri, tny_stream, &result);
234         gtk_html_stream_close (stream, result?GTK_HTML_STREAM_OK:GTK_HTML_STREAM_ERROR);
235         g_object_unref (tny_stream);
236         return result;
237 }
238
239
240
241 /**
242  * tny_gtk_html_mime_part_view_new:
243  *
244  * Create a #TnyMimePartView that can display HTML mime parts
245  *
246  * Return value: a new #TnyMimePartView instance implemented for Gtk+
247  **/
248 TnyMimePartView*
249 tny_gtk_html_mime_part_view_new (TnyStatusCallback status_callback, gpointer status_user_data)
250 {
251         TnyGtkHtmlMimePartView *self = g_object_new (TNY_TYPE_GTK_HTML_MIME_PART_VIEW, NULL);
252         TnyGtkHtmlMimePartViewPriv *priv = TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE (self);
253
254         priv->status_callback = status_callback;
255         priv->status_user_data = status_user_data;
256
257         return TNY_MIME_PART_VIEW (self);
258 }
259
260
261
262 static void
263 tny_gtk_html_mime_part_view_instance_init (GTypeInstance *instance, gpointer g_class)
264 {
265         TnyGtkHtmlMimePartView *self  = (TnyGtkHtmlMimePartView*) instance;
266         TnyGtkHtmlMimePartViewPriv *priv = TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE (self);
267
268         gtk_html_set_editable (GTK_HTML(self), FALSE);
269         gtk_html_allow_selection (GTK_HTML(self), TRUE);
270         gtk_html_set_caret_mode (GTK_HTML(self), FALSE);
271         gtk_html_set_blocking (GTK_HTML(self), FALSE);
272         gtk_html_set_images_blocking (GTK_HTML(self), FALSE);
273
274         g_signal_connect (G_OBJECT(self), "url_requested",
275                         G_CALLBACK(on_url_requested), self);
276
277         priv->part = NULL;
278
279         return;
280 }
281
282 static void
283 tny_gtk_html_mime_part_view_finalize (GObject *object)
284 {
285         TnyGtkHtmlMimePartView *self = (TnyGtkHtmlMimePartView *)object;       
286         TnyGtkHtmlMimePartViewPriv *priv = TNY_GTK_HTML_MIME_PART_VIEW_GET_PRIVATE (self);
287         if (priv->part)
288                 g_object_unref (priv->part);
289         (*parent_class->finalize) (object);
290         return;
291 }
292
293 static void
294 tny_mime_part_view_init (gpointer g, gpointer iface_data)
295 {
296         TnyMimePartViewIface *klass = (TnyMimePartViewIface *)g;
297
298         klass->get_part= tny_gtk_html_mime_part_view_get_part;
299         klass->set_part= tny_gtk_html_mime_part_view_set_part;
300         klass->clear= tny_gtk_html_mime_part_view_clear;
301
302         return;
303 }
304
305 static void
306 tny_gtk_html_mime_part_view_class_init (TnyGtkHtmlMimePartViewClass *class)
307 {
308         GObjectClass *object_class;
309
310         parent_class = g_type_class_peek_parent (class);
311         object_class = (GObjectClass*) class;
312
313         object_class->finalize = tny_gtk_html_mime_part_view_finalize;
314
315         g_type_class_add_private (object_class, sizeof (TnyGtkHtmlMimePartViewPriv));
316
317         return;
318 }
319
320 static gpointer
321 tny_gtk_html_mime_part_view_register_type (gpointer notused)
322 {
323         GType type = 0;
324
325         static const GTypeInfo info =
326                 {
327                   sizeof (TnyGtkHtmlMimePartViewClass),
328                   NULL,   /* base_init */
329                   NULL,   /* base_finalize */
330                   (GClassInitFunc) tny_gtk_html_mime_part_view_class_init,   /* class_init */
331                   NULL,   /* class_finalize */
332                   NULL,   /* class_data */
333                   sizeof (TnyGtkHtmlMimePartView),
334                   0,      /* n_preallocs */
335                   tny_gtk_html_mime_part_view_instance_init,    /* instance_init */
336                   NULL
337                 };
338
339         static const GInterfaceInfo tny_mime_part_view_info =
340                 {
341                   (GInterfaceInitFunc) tny_mime_part_view_init, /* interface_init */
342                   NULL,         /* interface_finalize */
343                   NULL          /* interface_data */
344                 };
345
346         type = g_type_register_static (GTK_TYPE_HTML,
347                                        "TnyGtkHtmlMimePartView",
348                                        &info, 0);
349
350         g_type_add_interface_static (type, TNY_TYPE_MIME_PART_VIEW,
351                                      &tny_mime_part_view_info);
352
353         return GUINT_TO_POINTER (type);
354 }
355
356 GType
357 tny_gtk_html_mime_part_view_get_type (void)
358 {
359         static GOnce once = G_ONCE_INIT;
360         g_once (&once, tny_gtk_html_mime_part_view_register_type, NULL);
361         return GPOINTER_TO_UINT (once.retval);
362 }
Note: See TracBrowser for help on using the browser.