activate links in html mail
authorPaul Mangan <paul@claws-mail.org>
Mon, 29 Oct 2001 15:42:21 +0000 (15:42 +0000)
committerPaul Mangan <paul@claws-mail.org>
Mon, 29 Oct 2001 15:42:21 +0000 (15:42 +0000)
AUTHORS
ChangeLog.claws
configure.in
src/html.c
src/textview.c

diff --git a/AUTHORS b/AUTHORS
index 4a170c6..caa86b3 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -86,3 +86,4 @@ contributors (beside the above; based on Changelog)
        Ravemax
        Jens Jahnke
        Thierry Godefroy
+       Matthieu Dazy
index 83f5002..fbc5472 100644 (file)
@@ -1,10 +1,16 @@
+2001-10-29 [paul]      0.6.4claws15
+
+       * src/html.c, src/textview.c
+               activate links in html mail and fix clickable parts
+               Submitted by Matthieu Dazy <dazy@t-surf.com>
+
 2001-10-29 [paul]
 
        * po/de.po, po/es.po, po/pt_BR/po
                updated translations, submitted by Jens Oberender,
                Ricardo Mones Lastra, and Fabio Junior Beneditto
 
-2001-10-29 [darko]
+2001-10-29 [darko]     0.6.4claws14
 
        * src/compose.c
                fix wrapping for good
@@ -14,7 +20,7 @@
        * src/compose.c
                undo previous change as it broke the smart wrapping
 
-2001-10-29 [darko]
+2001-10-29 [darko]     0.6.4claws13
 
        * src/compose.c
                fix infinite loop when long URL is quoted
index 426c7de..75697f6 100644 (file)
@@ -8,7 +8,7 @@ MINOR_VERSION=6
 MICRO_VERSION=4
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=claws14
+EXTRA_VERSION=claws15
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl
index 4507559..b02ed9f 100644 (file)
@@ -522,6 +522,7 @@ static HTMLState html_parse_tag(HTMLParser *parser)
 {
        gchar buf[HTMLBUFSIZE];
        gchar *p;
+       static gboolean is_in_href = FALSE;
 
        html_get_parenthesis(parser, buf, sizeof(buf));
 
@@ -541,6 +542,30 @@ static HTMLState html_parse_tag(HTMLParser *parser)
                parser->space = FALSE;
                html_append_char(parser, '\n');
                parser->state = HTML_BR;
+       } else if (!strcmp(buf, "a")) {
+               /* look for tokens separated by space or = */
+               char* href_token = strtok(++p, " =");
+               parser->state = HTML_NORMAL;
+               while (href_token != NULL) {
+                       /* look for href */
+                       if (!strcmp(href_token, "href")) {
+                               /* the next token is the url, between double
+                                * quotes */
+                               char* url = strtok(NULL, "\"");
+                               html_append_str(parser, url, strlen(url));
+                               html_append_char(parser, ' ');
+                               /* start enforcing html link */
+                               parser->state = HTML_HREF;
+                               is_in_href = TRUE;
+                               break;
+                       }
+                       /* or get next token */
+                       href_token = strtok(NULL, " =");
+               }
+       } else if (!strcmp(buf, "/a")) {
+               /* stop enforcing html link */
+               parser->state = HTML_NORMAL;
+               is_in_href = FALSE;
        } else if (!strcmp(buf, "p")) {
                parser->space = FALSE;
                if (!parser->empty_line) {
@@ -590,6 +615,12 @@ static HTMLState html_parse_tag(HTMLParser *parser)
                }
                parser->state = HTML_NORMAL;
        }
+       
+       if (is_in_href == TRUE) {
+               /* when inside a link, everything will be written as
+                * clickable (see textview_show_thml in textview.c) */
+               parser->state = HTML_HREF;
+       }
 
        return parser->state;
 }
index 130e4fb..f0e7f42 100644 (file)
@@ -103,6 +103,10 @@ static void textview_show_html             (TextView       *textview,
 static void textview_write_line                (TextView       *textview,
                                         const gchar    *str,
                                         CodeConverter  *conv);
+static void textview_write_link         (TextView      *textview,
+                                         const gchar    *url,
+                                        const gchar    *str,
+                                        CodeConverter  *conv);
 static GPtrArray *textview_scan_header (TextView       *textview,
                                         FILE           *fp);
 static void textview_show_header       (TextView       *textview,
@@ -420,12 +424,30 @@ static void textview_show_html(TextView *textview, FILE *fp,
 {
        HTMLParser *parser;
        gchar *str;
+       gchar* url = NULL;
 
        parser = html_parser_new(fp, conv);
        g_return_if_fail(parser != NULL);
 
        while ((str = html_parse(parser)) != NULL) {
-               textview_write_line(textview, str, NULL);
+               if (parser->state == HTML_HREF) {
+                       /* first time : get and copy the URL */
+                       if (url == NULL) {
+                               url = strdup(strtok(str, " "));
+                               /* the URL may (or not) be followed by the
+                                * referenced text */
+                               str = strtok(NULL, "");
+                       }
+                       if (str != NULL) {
+                               textview_write_link(textview, url, str, NULL);
+                       }
+               } else {
+                       if (url != NULL) {
+                               free(url);
+                               url = NULL;
+                       }
+                       textview_write_line(textview, str, NULL);
+               }
        }
        html_parser_destroy(parser);
 }
@@ -739,6 +761,41 @@ static void textview_make_clickable_parts(TextView *textview,
 
 #undef ADD_TXT_POS
 
+/* This function writes str as a double-clickable link with the given url. */ 
+static void textview_write_link(TextView *textview, const gchar *url,
+                                const gchar *str, CodeConverter *conv)
+{
+    GdkColor *link_color = NULL;
+    RemoteURI* uri;
+    GtkText *text = GTK_TEXT(textview->text);
+    gchar buf[BUFFSIZE];
+
+    /* this part is taken from textview_write_line. Right now the only place
+     * that calls this function passes NULL for conv, but you never know. */
+    if (!conv)
+           strncpy2(buf, str, sizeof(buf));
+    else if (conv_convert(conv, buf, sizeof(buf), str) < 0) {
+                   gtk_text_insert(text, textview->msgfont,
+                           prefs_common.enable_color
+                           ? &error_color : NULL, NULL,
+                           "*** Warning: code conversion failed ***\n",
+                           -1);
+           return;
+    }
+
+    /* this part is based on the code in make_clickable_parts */
+    if (prefs_common.enable_color) {
+       link_color = &uri_color;
+    }
+    uri = g_new(RemoteURI, 1);
+    uri->uri = g_strdup(url);
+    uri->start = gtk_text_get_point(text);
+    gtk_text_insert(text, textview->msgfont, link_color, NULL, buf,
+                   strlen(buf));
+    uri->end = gtk_text_get_point(text);
+    textview->uri_list = g_slist_append(textview->uri_list, uri);
+}
+
 static void textview_write_line(TextView *textview, const gchar *str,
                                CodeConverter *conv)
 {
@@ -1360,6 +1417,13 @@ static void textview_button_pressed(GtkWidget *widget, GdkEventButton *event,
             || event->button == 2 || event->button == 3)) {
                GSList *cur;
 
+               /* double click seems to set the cursor after the current
+                * word. The cursor position needs fixing, otherwise the
+                * last word of a clickable zone will not work */
+               if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
+                       textview->cur_pos--;
+               }
+
                for (cur = textview->uri_list; cur != NULL; cur = cur->next) {
                        RemoteURI *uri = (RemoteURI *)cur->data;