source: trunk/third/yelp/src/yelp-html-gtkhtml2.c @ 18397

Revision 18397, 8.7 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18396, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2001-2002 Mikael Hallendal <micke@codefactory.se>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Mikael Hallendal <micke@codefactory.se>
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <libgnomevfs/gnome-vfs.h>
28#include <libgnomevfs/gnome-vfs-mime-utils.h>
29#include <libgnome/gnome-i18n.h>
30#include <libgtkhtml/gtkhtml.h>
31
32#include <string.h>
33#include <stdio.h>
34
35#include "yelp-util.h"
36#include "yelp-marshal.h"
37#include "yelp-error.h"
38#include "yelp-uri.h"
39#include "yelp-html.h"
40
41#define d(x)
42
43struct _YelpHtmlPriv {
44        HtmlView     *view;
45
46        HtmlDocument *doc;
47        YelpURI      *base_uri;
48};
49
50
51static void      html_init               (YelpHtml           *html);
52static void      html_class_init         (YelpHtmlClass      *klass);
53
54static void      html_url_requested_cb   (HtmlDocument       *doc,
55                                          const gchar        *uri,
56                                          HtmlStream         *stream,
57                                          gpointer            data);
58static void      html_cancel_stream      (HtmlStream         *stream,
59                                          gpointer            user_data,
60                                          gpointer            cancel_data);
61
62static void      html_link_clicked_cb    (HtmlDocument       *doc,
63                                          const gchar        *url,
64                                          YelpHtml           *html);
65static void      html_title_changed_cb   (HtmlDocument       *doc,
66                                          const gchar        *new_title,
67                                          YelpHtml           *html);
68
69
70#define BUFFER_SIZE 16384
71
72enum {
73        URI_SELECTED,
74        TITLE_CHANGED,
75        LAST_SIGNAL
76};
77
78static gint        signals[LAST_SIGNAL] = { 0 };
79
80GType
81yelp_html_get_type (void)
82{
83        static GType view_type = 0;
84
85        if (!view_type)
86        {
87                static const GTypeInfo view_info =
88                        {
89                                sizeof (YelpHtmlClass),
90                                NULL,
91                                NULL,
92                                (GClassInitFunc) html_class_init,
93                                NULL,
94                                NULL,
95                                sizeof (YelpHtml),
96                                0,
97                                (GInstanceInitFunc) html_init,
98                        };
99               
100                view_type = g_type_register_static (G_TYPE_OBJECT,
101                                                    "YelpHtml",
102                                                    &view_info, 0);
103        }
104       
105        return view_type;
106}
107
108static void
109html_init (YelpHtml *html)
110{
111        YelpHtmlPriv *priv;
112
113        priv = g_new0 (YelpHtmlPriv, 1);
114
115        priv->view        = HTML_VIEW (html_view_new ());
116        priv->doc         = html_document_new ();
117        priv->base_uri    = NULL;
118
119        html_view_set_document (HTML_VIEW (priv->view), priv->doc);
120       
121        g_signal_connect (G_OBJECT (priv->doc), "link_clicked",
122                          G_CALLBACK (html_link_clicked_cb), html);
123       
124        g_signal_connect (G_OBJECT (priv->doc), "request_url",
125                          G_CALLBACK (html_url_requested_cb), html);
126
127        g_signal_connect (G_OBJECT (priv->doc), "title_changed",
128                          G_CALLBACK (html_title_changed_cb), html);
129
130        html->priv = priv;
131}
132
133static void
134html_class_init (YelpHtmlClass *klass)
135{
136        signals[URI_SELECTED] =
137                g_signal_new ("uri_selected",
138                              G_TYPE_FROM_CLASS (klass),
139                              G_SIGNAL_RUN_LAST,
140                              G_STRUCT_OFFSET (YelpHtmlClass,
141                                               uri_selected),
142                              NULL, NULL,
143                              yelp_marshal_VOID__POINTER_BOOLEAN,
144                              G_TYPE_NONE,
145                              2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
146
147        signals[TITLE_CHANGED] =
148                g_signal_new ("title_changed",
149                              G_TYPE_FROM_CLASS (klass),
150                              G_SIGNAL_RUN_LAST,
151                              G_STRUCT_OFFSET (YelpHtmlClass,
152                                               title_changed),
153                              NULL, NULL,
154                              yelp_marshal_VOID__STRING,
155                              G_TYPE_NONE,
156                              1, G_TYPE_STRING);
157}
158
159static void
160html_url_requested_cb (HtmlDocument *doc,
161                       const gchar  *url,
162                       HtmlStream   *stream,
163                       gpointer      data)
164{
165        YelpHtmlPriv     *priv;
166        YelpHtml         *html;
167        GnomeVFSHandle   *handle;
168        GnomeVFSResult    result;
169        gchar             buffer[BUFFER_SIZE];
170        GnomeVFSFileSize  read_len;
171        gchar            *absolute_url;
172       
173        html = YELP_HTML (data);
174        priv = html->priv;
175       
176        html_stream_set_cancel_func (stream, html_cancel_stream, html);
177
178        d(g_print ("URL REQUESTED: %s\n", url));
179
180        absolute_url = yelp_util_resolve_relative_url (yelp_uri_get_path (priv->base_uri), url);
181       
182        result = gnome_vfs_open (&handle, absolute_url, GNOME_VFS_OPEN_READ);
183
184        if (result != GNOME_VFS_OK) {
185                g_warning ("Failed to open: %s", absolute_url);
186                g_free (absolute_url);
187
188                return;
189        }
190
191        g_free (absolute_url);
192
193        while (gnome_vfs_read (handle, buffer, BUFFER_SIZE, &read_len) ==
194               GNOME_VFS_OK) {
195                html_stream_write (stream, buffer, read_len);
196        }
197
198        gnome_vfs_close (handle);
199}
200
201static void
202html_cancel_stream (HtmlStream *stream,
203                    gpointer    user_data,
204                    gpointer    cancel_data)
205{
206        d(g_print ("CANCEL!!\n"));
207
208        /* Not sure what to do here */
209}
210
211static void
212html_link_clicked_cb (HtmlDocument *doc, const gchar *url, YelpHtml *html)
213{
214        YelpHtmlPriv *priv;
215        gboolean      handled;
216        YelpURI      *uri;
217
218        g_return_if_fail (HTML_IS_DOCUMENT (doc));
219        g_return_if_fail (url != NULL);
220        g_return_if_fail (YELP_IS_HTML (html));
221
222        priv    = html->priv;
223        handled = FALSE;
224
225        d(g_print ("Link clicked: %s\n", url));
226
227        uri = yelp_uri_get_relative (priv->base_uri, url);
228
229        d(g_print ("That would be: %s\n", yelp_uri_to_string (uri)));
230       
231        /* If this is a relative reference. Shortcut reload. */
232        if (yelp_uri_equal_path (uri, priv->base_uri) &&
233            yelp_uri_get_section (uri)) {
234                if (yelp_uri_get_type (uri) == YELP_URI_TYPE_HTML ||
235                    yelp_uri_get_type (uri) == YELP_URI_TYPE_MAN) {
236                        html_view_jump_to_anchor (HTML_VIEW (html->priv->view),
237                                                  yelp_uri_get_section (uri));
238                        handled = TRUE;
239                }
240        }
241
242        g_signal_emit (html, signals[URI_SELECTED], 0, uri, handled);
243
244        yelp_uri_unref (uri);
245}
246
247static void
248html_title_changed_cb (HtmlDocument *doc,
249                       const gchar  *new_title,
250                       YelpHtml     *html)
251{
252        g_return_if_fail (HTML_IS_DOCUMENT (doc));
253        g_return_if_fail (new_title != NULL);
254       
255        g_signal_emit (html, signals[TITLE_CHANGED], 0, new_title);
256}
257
258YelpHtml *
259yelp_html_new (void)
260{
261        YelpHtml *html;
262       
263        d(puts(G_GNUC_FUNCTION));
264
265        html = g_object_new (YELP_TYPE_HTML, NULL);
266       
267        yelp_html_clear (html);
268       
269        {
270                gchar *text = "<html><body></body></html>";
271
272                yelp_html_write (html, text, -1);
273        }
274       
275        yelp_html_close (html);
276
277        return html;
278}
279
280void
281yelp_html_set_base_uri (YelpHtml *html, YelpURI *uri)
282{
283        YelpHtmlPriv *priv;
284       
285        g_return_if_fail (YELP_IS_HTML (html));
286
287        priv = html->priv;
288
289        if (priv->base_uri) {
290                yelp_uri_unref (priv->base_uri);
291        }
292
293        priv->base_uri = yelp_uri_ref (uri);
294}
295
296void
297yelp_html_clear (YelpHtml *html)
298{
299        YelpHtmlPriv *priv;
300       
301        g_return_if_fail (YELP_IS_HTML (html));
302
303        priv = html->priv;
304
305        html_document_clear (priv->doc);
306        html_document_open_stream (priv->doc, "text/html");
307        html_stream_set_cancel_func (priv->doc->current_stream,
308                                     html_cancel_stream,
309                                     html);
310}
311
312void
313yelp_html_write (YelpHtml *html, const gchar *data, gint len)
314{
315        YelpHtmlPriv *priv;
316       
317        g_return_if_fail (YELP_IS_HTML (html));
318       
319        priv = html->priv;
320       
321        if (len == -1) {
322                len = strlen (data);
323        }
324       
325        if (len <= 0) {
326                return;
327        }
328       
329        html_document_write_stream (priv->doc, data, len);
330}
331
332void
333yelp_html_printf (YelpHtml *html, char *format, ...)
334{
335        va_list  args;
336        gchar   *string;
337       
338        g_return_if_fail (format != NULL);
339       
340        va_start (args, format);
341        string = g_strdup_vprintf (format, args);
342        va_end (args);
343       
344        yelp_html_write (html, string, -1);
345       
346        g_free (string);
347}
348
349void
350yelp_html_close (YelpHtml *html)
351{
352        YelpHtmlPriv *priv;
353       
354        g_return_if_fail (YELP_IS_HTML (html));
355       
356        priv = html->priv;
357       
358        html_document_close_stream (priv->doc);
359
360        gtk_adjustment_set_value (gtk_layout_get_vadjustment (GTK_LAYOUT (priv->view)),
361                                  0);
362}
363
364GtkWidget *
365yelp_html_get_widget (YelpHtml *html)
366{
367        g_return_val_if_fail (YELP_IS_HTML (html), NULL);
368       
369        return GTK_WIDGET (html->priv->view);
370}
Note: See TracBrowser for help on using the repository browser.