2006-10-16 [colin] 2.5.5cvs8
[claws.git] / src / textview.c
index 28fca07ddc8787a8e2d2aae5558f631db5745021..3a3ce795e7cdeae23018b5d00eb8601c871535f7 100644 (file)
 #include "inputdialog.h"
 #include "timing.h"
 
-struct _ClickableText
-{
-       gchar *uri;
-
-       gchar *filename;
-
-       gpointer data;
-
-       guint start;
-       guint end;
-       
-       gboolean is_quote;
-       gint quote_level;
-       gboolean q_expanded;
-       gchar *fg_color;
-};
-
 gint previousquotelevel = -1;
 
 static GdkColor quote_colors[3] = {
@@ -151,7 +134,8 @@ static void textview_show_html              (TextView       *textview,
 
 static void textview_write_line                (TextView       *textview,
                                         const gchar    *str,
-                                        CodeConverter  *conv);
+                                        CodeConverter  *conv,
+                                        gboolean        do_quote_folding);
 static void textview_write_link                (TextView       *textview,
                                         const gchar    *str,
                                         const gchar    *uri,
@@ -226,7 +210,6 @@ static void save_file_cb                    (TextView       *textview,
 static void open_image_cb                      (TextView       *textview,
                                                 guint           action,
                                                 void           *data);
-static void textview_show_icon(TextView *textview, const gchar *stock_id);
 
 static GtkItemFactoryEntry textview_link_popup_entries[] = 
 {
@@ -602,27 +585,6 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
        END_TIMING();
 }
 
-#define TEXT_INSERT(str) \
-       gtk_text_buffer_insert_with_tags_by_name \
-                               (buffer, &iter, str, -1,\
-                                "header", NULL)
-
-#define TEXT_INSERT_LINK(str, fname, udata) {                          \
-       ClickableText *uri;                                                     \
-       uri = g_new0(ClickableText, 1);                                 \
-       uri->uri = g_strdup("");                                        \
-       uri->start = gtk_text_iter_get_offset(&iter);                   \
-       gtk_text_buffer_insert_with_tags_by_name                        \
-                               (buffer, &iter, str, -1,                \
-                                "link", "header_title", "header",      \
-                                NULL);                                 \
-       uri->end = gtk_text_iter_get_offset(&iter);                     \
-       uri->filename = fname?g_strdup(fname):NULL;                     \
-       uri->data = udata;                                              \
-       textview->uri_list =                                            \
-               g_slist_prepend(textview->uri_list, uri);               \
-}
-
 static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
 {
        GtkTextView *text;
@@ -640,7 +602,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
        buffer = gtk_text_view_get_buffer(text);
        charcount = gtk_text_buffer_get_char_count(buffer);
        gtk_text_buffer_get_end_iter(buffer, &iter);
-
+       
        if (textview->stop_loading) {
                return;
        }
@@ -649,6 +611,8 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
                return;
        }
 
+       previousquotelevel = -1;
+
        if ((mimeinfo->type == MIMETYPE_MESSAGE) && !g_ascii_strcasecmp(mimeinfo->subtype, "rfc822")) {
                FILE *fp;
 
@@ -684,7 +648,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
        || (mimeinfo->disposition == DISPOSITIONTYPE_INLINE && 
            mimeinfo->type != MIMETYPE_TEXT)) {
                gtk_text_buffer_insert(buffer, &iter, "\n", 1);
-               TEXT_INSERT_LINK(buf, "sc://select_attachment", mimeinfo);
+               TEXTVIEW_INSERT_LINK(buf, "sc://select_attachment", mimeinfo);
                gtk_text_buffer_insert(buffer, &iter, " \n", -1);
                if (mimeinfo->type == MIMETYPE_IMAGE  &&
                    prefs_common.inline_img ) {
@@ -844,13 +808,13 @@ void textview_show_error(TextView *textview)
        buffer = gtk_text_view_get_buffer(text);
        gtk_text_buffer_get_start_iter(buffer, &iter);
 
-       TEXT_INSERT(_("\n"
+       TEXTVIEW_INSERT(_("\n"
                      "  This message can't be displayed.\n"
                      "  This is probably due to a network error.\n"
                      "\n"
                      "  Use "));
-       TEXT_INSERT_LINK(_("'View Log'"), "sc://view_log", NULL);
-       TEXT_INSERT(_(" in the Tools menu for more information."));
+       TEXTVIEW_INSERT_LINK(_("'View Log'"), "sc://view_log", NULL);
+       TEXTVIEW_INSERT(_(" in the Tools menu for more information."));
        textview_show_icon(textview, GTK_STOCK_DIALOG_ERROR);
 
 }
@@ -870,30 +834,27 @@ void textview_show_mime_part(TextView *textview, MimeInfo *partinfo)
        buffer = gtk_text_view_get_buffer(text);
        gtk_text_buffer_get_start_iter(buffer, &iter);
 
-       TEXT_INSERT("\n");
-       TEXT_INSERT(_("  The following can be performed on this part by\n"));
-       TEXT_INSERT(_("  right-clicking the icon or list item:\n"));
-
-       TEXT_INSERT(_("     - To save, select "));
-       TEXT_INSERT_LINK(_("'Save as...'"), "sc://save_as", NULL);
-       TEXT_INSERT(_(" (Shortcut key: 'y')\n"));
-       TEXT_INSERT(_("     - To display as text, select "));
-       TEXT_INSERT_LINK(_("'Display as text'"), "sc://display_as_text", NULL);
-       TEXT_INSERT(_(" (Shortcut key: 't')\n"));
-       TEXT_INSERT(_("     - To open with an external program, select "));
-       TEXT_INSERT_LINK(_("'Open'"), "sc://open", NULL);
-       TEXT_INSERT(_(" (Shortcut key: 'l')\n"));
-       TEXT_INSERT(_("       (alternately double-click, or click the middle "));
-       TEXT_INSERT(_("mouse button)\n"));
-       TEXT_INSERT(_("     - Or use "));
-       TEXT_INSERT_LINK(_("'Open with...'"), "sc://open_with", NULL);
-       TEXT_INSERT(_(" (Shortcut key: 'o')\n"));
+       TEXTVIEW_INSERT("\n");
+       TEXTVIEW_INSERT(_("  The following can be performed on this part by\n"));
+       TEXTVIEW_INSERT(_("  right-clicking the icon or list item:\n"));
+
+       TEXTVIEW_INSERT(_("     - To save, select "));
+       TEXTVIEW_INSERT_LINK(_("'Save as...'"), "sc://save_as", NULL);
+       TEXTVIEW_INSERT(_(" (Shortcut key: 'y')\n"));
+       TEXTVIEW_INSERT(_("     - To display as text, select "));
+       TEXTVIEW_INSERT_LINK(_("'Display as text'"), "sc://display_as_text", NULL);
+       TEXTVIEW_INSERT(_(" (Shortcut key: 't')\n"));
+       TEXTVIEW_INSERT(_("     - To open with an external program, select "));
+       TEXTVIEW_INSERT_LINK(_("'Open'"), "sc://open", NULL);
+       TEXTVIEW_INSERT(_(" (Shortcut key: 'l')\n"));
+       TEXTVIEW_INSERT(_("       (alternately double-click, or click the middle "));
+       TEXTVIEW_INSERT(_("mouse button)\n"));
+       TEXTVIEW_INSERT(_("     - Or use "));
+       TEXTVIEW_INSERT_LINK(_("'Open with...'"), "sc://open_with", NULL);
+       TEXTVIEW_INSERT(_(" (Shortcut key: 'o')\n"));
        textview_show_icon(textview, GTK_STOCK_DIALOG_INFO);
 }
 
-#undef TEXT_INSERT
-#undef TEXT_INSERT_LINK
-
 static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
 {
        FILE *tmpfp;
@@ -958,14 +919,14 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
                if (pipe(pfd) < 0) {
                        g_snprintf(buf, sizeof(buf),
                                "pipe failed for textview\n\n%s\n", strerror(errno));
-                       textview_write_line(textview, buf, conv);
+                       textview_write_line(textview, buf, conv, TRUE);
                        goto textview_default;
                }
                pid = fork();
                if (pid < 0) {
                        g_snprintf(buf, sizeof(buf),
                                "fork failed for textview\n\n%s\n", strerror(errno));
-                       textview_write_line(textview, buf, conv);
+                       textview_write_line(textview, buf, conv, TRUE);
                        close(pfd[0]);
                        close(pfd[1]);
                        goto textview_default;
@@ -988,7 +949,7 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
                close(pfd[1]);
                tmpfp = fdopen(pfd[0], "rb");
                while (fgets(buf, sizeof(buf), tmpfp)) {
-                       textview_write_line(textview, buf, conv);
+                       textview_write_line(textview, buf, conv, TRUE);
                        
                        lines++;
                        if (lines % 500 == 0)
@@ -1013,7 +974,7 @@ textview_default:
                debug_print("Viewing text content of type: %s (length: %d)\n", mimeinfo->subtype, mimeinfo->length);
                while ((ftell(tmpfp) < mimeinfo->offset + mimeinfo->length) &&
                       (fgets(buf, sizeof(buf), tmpfp) != NULL)) {
-                       textview_write_line(textview, buf, conv);
+                       textview_write_line(textview, buf, conv, TRUE);
                        lines++;
                        if (lines % 500 == 0)
                                GTK_EVENTS_FLUSH();
@@ -1076,7 +1037,7 @@ static void textview_show_html(TextView *textview, FILE *fp,
                        if (str != NULL)
                                textview_write_link(textview, str, parser->href, NULL);
                } else
-                       textview_write_line(textview, str, NULL);
+                       textview_write_line(textview, str, NULL, FALSE);
                lines++;
                if (lines % 500 == 0)
                        GTK_EVENTS_FLUSH();
@@ -1084,7 +1045,7 @@ static void textview_show_html(TextView *textview, FILE *fp,
                        return;
                }
        }
-       textview_write_line(textview, "\n", NULL);
+       textview_write_line(textview, "\n", NULL, FALSE);
        sc_html_parser_destroy(parser);
 }
 
@@ -1099,7 +1060,7 @@ static void textview_show_ertf(TextView *textview, FILE *fp,
        g_return_if_fail(parser != NULL);
 
        while ((str = ertf_parse(parser)) != NULL) {
-               textview_write_line(textview, str, NULL);
+               textview_write_line(textview, str, NULL, FALSE);
                lines++;
                if (lines % 500 == 0)
                        GTK_EVENTS_FLUSH();
@@ -1385,7 +1346,7 @@ static void textview_make_clickable_parts_later(TextView *textview,
 #undef ADD_TXT_POS
 
 static void textview_write_line(TextView *textview, const gchar *str,
-                               CodeConverter *conv)
+                               CodeConverter *conv, gboolean do_quote_folding)
 {
        GtkTextView *text;
        GtkTextBuffer *buffer;
@@ -1438,7 +1399,15 @@ static void textview_write_line(TextView *textview, const gchar *str,
                textview->is_in_signature = TRUE;
        }
 
-       if (real_quotelevel > -1) {
+       if (real_quotelevel > -1 && do_quote_folding) {
+               if (!g_utf8_validate(buf, -1, NULL)) {
+                       gchar *utf8buf = NULL;
+                       utf8buf = g_malloc(BUFFSIZE);
+                       conv_localetodisp(utf8buf, BUFFSIZE, buf);
+                       strncpy2(buf, utf8buf, BUFFSIZE-1);
+                       g_free(utf8buf);
+               }
+do_quote:
                if ( previousquotelevel != real_quotelevel ) {
                        ClickableText *uri;
                        uri = g_new0(ClickableText, 1);
@@ -1463,8 +1432,14 @@ static void textview_write_line(TextView *textview, const gchar *str,
                } else {
                        GSList *last = textview->uri_list;
                        ClickableText *lasturi = (ClickableText *)last->data;
-                       gint e_len = strlen(lasturi->data);
-                       gint n_len = strlen(buf);
+                       gint e_len = 0, n_len = 0;
+                       
+                       if (lasturi->is_quote == FALSE) {
+                               previousquotelevel = -1;
+                               goto do_quote;
+                       }
+                       e_len = lasturi->data ? strlen(lasturi->data):0;
+                       n_len = strlen(buf);
                        lasturi->data = g_realloc((gchar *)lasturi->data, e_len + n_len + 1);
                        strcpy((gchar *)lasturi->data + e_len, buf);
                        *((gchar *)lasturi->data + e_len + n_len) = '\0';
@@ -1796,7 +1771,7 @@ bail:
        textview->image = NULL; 
 }
 
-static void textview_show_icon(TextView *textview, const gchar *stock_id)
+void textview_show_icon(TextView *textview, const gchar *stock_id)
 {
        GtkTextView *text = GTK_TEXT_VIEW(textview->text);
        int x = 0;