2006-07-06 [paul] 2.3.1cvs62
[claws.git] / src / textview.c
index 3354b350ef48caf965f257e49bcf662c9587e61c..9b81b69332f2bc39f43589f6e35cd3bf42796a7e 100644 (file)
@@ -34,6 +34,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
+#include <sys/wait.h>
 #if HAVE_LIBCOMPFACE
 #  include <compface.h>
 #endif
@@ -69,6 +70,8 @@ struct _RemoteURI
 
        gchar *filename;
 
+       gpointer data;
+
        guint start;
        guint end;
 };
@@ -556,6 +559,27 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
                textview_write_body(textview, mimeinfo);
 }
 
+#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) {                          \
+       RemoteURI *uri;                                                 \
+       uri = g_new(RemoteURI, 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_append(textview->uri_list, uri);                \
+}
+
 static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
 {
        GtkTextView *text;
@@ -608,7 +632,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
        if (mimeinfo->disposition == DISPOSITIONTYPE_ATTACHMENT
        || (mimeinfo->disposition == DISPOSITIONTYPE_INLINE && 
            mimeinfo->type != MIMETYPE_TEXT)) {
-               gtk_text_buffer_insert(buffer, &iter, buf, -1);
+               TEXT_INSERT_LINK(buf, "sc://select_attachment", mimeinfo);
                if (mimeinfo->type == MIMETYPE_IMAGE  &&
                    prefs_common.inline_img ) {
                        GdkPixbuf *pixbuf;
@@ -652,6 +676,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
 
                        uri_str = g_filename_to_uri(filename, NULL, NULL);
                        if (uri_str) {
+                               gtk_text_buffer_insert(buffer, &iter, " ", -1);
                                uri = g_new(RemoteURI, 1);
                                uri->uri = uri_str;
                                uri->start = gtk_text_iter_get_offset(&iter);
@@ -748,26 +773,6 @@ static void textview_add_parts(TextView *textview, MimeInfo *mimeinfo)
         recursive_add_parts(textview, mimeinfo->node);
 }
 
-#define TEXT_INSERT(str) \
-       gtk_text_buffer_insert_with_tags_by_name \
-                               (buffer, &iter, str, -1,\
-                                "header", NULL)
-
-#define TEXT_INSERT_LINK(str, fname) {                                         \
-       RemoteURI *uri;                                                 \
-       uri = g_new(RemoteURI, 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 = g_strdup(fname);                                \
-       textview->uri_list =                                            \
-               g_slist_append(textview->uri_list, uri);                \
-}
-
 void textview_show_error(TextView *textview)
 {
        GtkTextView *text;
@@ -786,7 +791,7 @@ void textview_show_error(TextView *textview)
                      "  This is probably due to a network error.\n"
                      "\n"
                      "  Use "));
-       TEXT_INSERT_LINK(_("'View Log'"), "sc://view_log");
+       TEXT_INSERT_LINK(_("'View Log'"), "sc://view_log", NULL);
        TEXT_INSERT(_(" in the Tools menu for more information."));
        textview_show_icon(textview, GTK_STOCK_DIALOG_ERROR);
 
@@ -812,18 +817,18 @@ void textview_show_mime_part(TextView *textview, MimeInfo *partinfo)
        TEXT_INSERT(_("  right-clicking the icon or list item:\n"));
 
        TEXT_INSERT(_("     - To save, select "));
-       TEXT_INSERT_LINK(_("'Save as...'"), "sc://save_as");
+       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");
+       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");
+       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");
+       TEXT_INSERT_LINK(_("'Open with...'"), "sc://open_with", NULL);
        TEXT_INSERT(_(" (Shortcut key: 'o')\n"));
        textview_show_icon(textview, GTK_STOCK_DIALOG_INFO);
 }
@@ -836,7 +841,7 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
        FILE *tmpfp;
        gchar buf[BUFFSIZE];
        CodeConverter *conv;
-       const gchar *charset;
+       const gchar *charset, *p, *cmd;
        
        if (textview->messageview->forced_charset)
                charset = textview->messageview->forced_charset;
@@ -876,7 +881,53 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
                        g_unlink(filename);
                }
                g_free(filename);
+       } else if ( g_ascii_strcasecmp(mimeinfo->subtype, "plain") &&
+                  (cmd = prefs_common.mime_textviewer) && *cmd &&
+                  (p = strchr(cmd, '%')) && *(p + 1) == 's') {
+               int pid, pfd[2];
+               const gchar *fname;
+
+               fname  = procmime_get_tmp_file_name(mimeinfo);
+               if (procmime_get_part(fname, mimeinfo)) goto textview_default;
+
+               g_snprintf(buf, sizeof(buf), cmd, fname);
+               debug_print("Viewing text content of type: %s (length: %d) "
+                       "using %s\n", mimeinfo->subtype, mimeinfo->length, buf);
+
+               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);
+                       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);
+                       close(pfd[0]);
+                       close(pfd[1]);
+                       goto textview_default;
+               }
+               if (pid == 0) { /* child */
+                       gchar **argv;
+                       argv = strsplit_with_quote(buf, " ", 0);
+                       close(1);
+                       close(pfd[0]);
+                       dup(pfd[1]);
+                       execvp(argv[0], argv);
+                       close(pfd[1]);
+                       exit(255);
+               }
+               close(pfd[1]);
+               tmpfp = fdopen(pfd[0], "rb");
+               while (fgets(buf, sizeof(buf), tmpfp))
+                       textview_write_line(textview, buf, conv);
+               fclose(tmpfp);
+               waitpid(pid, pfd, 0);
+               unlink(fname);
        } else {
+textview_default:
                tmpfp = g_fopen(mimeinfo->data.filename, "rb");
                fseek(tmpfp, mimeinfo->offset, SEEK_SET);
                debug_print("Viewing text content of type: %s (length: %d)\n", mimeinfo->subtype, mimeinfo->length);
@@ -987,6 +1038,7 @@ static void textview_make_clickable_parts(TextView *textview,
                {"http://",  strcasestr, get_uri_part,   make_uri_string},
                {"https://", strcasestr, get_uri_part,   make_uri_string},
                {"ftp://",   strcasestr, get_uri_part,   make_uri_string},
+               {"sftp://",  strcasestr, get_uri_part,   make_uri_string},
                {"www.",     strcasestr, get_uri_part,   make_http_string},
                {"mailto:",  strcasestr, get_uri_part,   make_uri_string},
                {"@",        strcasestr, get_email_part, make_email_string}
@@ -2042,11 +2094,14 @@ static gboolean textview_uri_button_pressed(GtkTextTag *tag, GObject *obj,
        if ((event->type == GDK_BUTTON_PRESS && bevent->button == 1) ||
                bevent->button == 2 || bevent->button == 3) {
                if (uri->filename && !g_ascii_strncasecmp(uri->filename, "sc://", 5)) {
-                       if (bevent->button == 1) {
-                               MimeView *mimeview = 
-                                       (textview->messageview)?
-                                               textview->messageview->mimeview:NULL;
-                               mimeview_handle_cmd(mimeview, uri->filename);
+                       MimeView *mimeview = 
+                               (textview->messageview)?
+                                       textview->messageview->mimeview:NULL;
+                       if (mimeview && bevent->button == 1) {
+                               mimeview_handle_cmd(mimeview, uri->filename, uri->data);
+                       } else if (mimeview && bevent->button == 2 && 
+                               !g_ascii_strcasecmp(uri->filename, "sc://select_attachment")) {
+                               mimeview_handle_cmd(mimeview, "sc://open_attachment", uri->data);
                        }
                        return TRUE;
                } else if (!g_ascii_strncasecmp(uri->uri, "mailto:", 7)) {
@@ -2146,12 +2201,16 @@ static gboolean textview_uri_security_check(TextView *textview, RemoteURI *uri)
                gchar *msg;
                AlertValue aval;
 
-               msg = g_strdup_printf(_("The real URL (%s) is different from\n"
-                                       "the apparent URL (%s).\n"
-                                       "\n"
-                                       "Open it anyway?"),
-                                     uri->uri, visible_str);
-               aval = alertpanel_full(_("Fake URL warning"), msg,
+               msg = g_markup_printf_escaped(_("The real URL is different from "
+                                               "the displayed URL.\n"
+                                               "\n"
+                                               "<b>Displayed URL:</b> %s\n"
+                                               "\n"
+                                               "<b>Real URL:</b> %s\n"
+                                               "\n"
+                                               "Open it anyway?"),
+                                              visible_str,uri->uri);
+               aval = alertpanel_full(_("Phishing attempt warning"), msg,
                                       GTK_STOCK_CANCEL, _("_Open URL"), NULL, FALSE,
                                       NULL, ALERT_WARNING, G_ALERTDEFAULT);
                g_free(msg);