#include <ctype.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
+#include <sys/wait.h>
#if HAVE_LIBCOMPFACE
# include <compface.h>
#endif
gchar *filename;
+ gpointer data;
+
guint start;
guint end;
};
textview_create_tags(GTK_TEXT_VIEW(textview->text), textview);
}
-#define CHANGE_TAG_COLOR(tagname, colorfg, colorbg) { \
+#if GTK_CHECK_VERSION(2, 8, 0)
+ #define CHANGE_TAG_COLOR(tagname, colorfg, colorbg) { \
tag = gtk_text_tag_table_lookup(tags, tagname); \
- if (tag && colorbg) \
+ if (tag) \
g_object_set(G_OBJECT(tag), "foreground-gdk", colorfg, "paragraph-background-gdk", colorbg, NULL); \
- else if (tag) \
+ }
+#else
+ #define CHANGE_TAG_COLOR(tagname, colorfg, colorbg) { \
+ tag = gtk_text_tag_table_lookup(tags, tagname); \
+ if (tag) \
g_object_set(G_OBJECT(tag), "foreground-gdk", colorfg, NULL); \
-}
+ }
+#endif
static void textview_update_message_colors(TextView *textview)
{
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;
if (name == NULL)
name = procmime_mimeinfo_get_parameter(mimeinfo, "name");
if (name != NULL)
- g_snprintf(buf, sizeof(buf), "\n[%s %s (%d bytes)]\n",
+ g_snprintf(buf, sizeof(buf), "\n[%s %s (%d bytes)]",
name, content_type, mimeinfo->length);
else
- g_snprintf(buf, sizeof(buf), "\n[%s (%d bytes)]\n",
+ g_snprintf(buf, sizeof(buf), "\n[%s (%d bytes)]",
content_type, mimeinfo->length);
g_free(content_type);
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);
+ gtk_text_buffer_insert(buffer, &iter, " \n", -1);
if (mimeinfo->type == MIMETYPE_IMAGE &&
prefs_common.inline_img ) {
GdkPixbuf *pixbuf;
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;
" 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);
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);
}
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;
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);
/* ALF - the sylpheed html parser returns an empty string,
* if still inside an <a>, but already parsed past HREF */
str = strtok(str, " ");
- if (str) {
+ if (str) {
+ while (str && *str && g_ascii_isspace(*str))
+ str++;
parser->href = g_strdup(str);
/* the URL may (or not) be followed by the
* referenced text */
{"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}
if (!uri)
return;
+ while (uri && *uri && g_ascii_isspace(*uri))
+ uri++;
+
text = GTK_TEXT_VIEW(textview->text);
buffer = gtk_text_view_get_buffer(text);
gtk_text_buffer_get_end_iter(buffer, &iter);
textview->uri_list = g_slist_append(textview->uri_list, r_uri);
}
+static void textview_set_cursor(GdkWindow *window, GdkCursor *cursor)
+{
+ if (GDK_IS_WINDOW(window))
+ gdk_window_set_cursor(window, cursor);
+}
void textview_clear(TextView *textview)
{
GtkTextView *text = GTK_TEXT_VIEW(textview->text);
textview->image = NULL;
if (textview->messageview->mainwin->cursor_count == 0) {
- gdk_window_set_cursor(window, text_cursor);
+ textview_set_cursor(window, text_cursor);
} else {
- gdk_window_set_cursor(window, watch_cursor);
+ textview_set_cursor(window, watch_cursor);
}
}
procheader_headername_equal(header->name, "From") ||
procheader_headername_equal(header->name, "To") ||
procheader_headername_equal(header->name, "Cc") ||
- procheader_headername_equal(header->name, "Bcc");
+ procheader_headername_equal(header->name, "Bcc") ||
+ procheader_headername_equal(header->name, "Reply-To") ||
+ procheader_headername_equal(header->name, "Sender");
textview_make_clickable_parts(textview, "header",
"link", header->body,
hdr);
GdkWindow *window = gtk_text_view_get_window(
GTK_TEXT_VIEW(textview->text),
GTK_TEXT_WINDOW_TEXT);
- gdk_window_set_cursor(window, watch_cursor);
+ textview_set_cursor(window, watch_cursor);
}
void textview_cursor_normal(TextView *textview)
GdkWindow *window = gtk_text_view_get_window(
GTK_TEXT_VIEW(textview->text),
GTK_TEXT_WINDOW_TEXT);
- gdk_window_set_cursor(window, text_cursor);
+ textview_set_cursor(window, text_cursor);
}
static void textview_uri_update(TextView *textview, gint x, gint y)
window = gtk_text_view_get_window(GTK_TEXT_VIEW(textview->text),
GTK_TEXT_WINDOW_TEXT);
if (textview->messageview->mainwin->cursor_count == 0) {
- gdk_window_set_cursor(window, uri ? hand_cursor : text_cursor);
+ textview_set_cursor(window, uri ? hand_cursor : text_cursor);
} else {
- gdk_window_set_cursor(window, watch_cursor);
+ textview_set_cursor(window, watch_cursor);
}
TEXTVIEW_STATUSBAR_POP(textview);
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, NULL, uri->data);
+ } else if (mimeview && bevent->button == 2 &&
+ !g_ascii_strcasecmp(uri->filename, "sc://select_attachment")) {
+ mimeview_handle_cmd(mimeview, "sc://open_attachment", NULL, uri->data);
+ } else if (mimeview && bevent->button == 3 &&
+ !g_ascii_strcasecmp(uri->filename, "sc://select_attachment")) {
+ mimeview_handle_cmd(mimeview, "sc://menu_attachment", bevent, uri->data);
+ }
return TRUE;
} else if (!g_ascii_strncasecmp(uri->uri, "mailto:", 7)) {
if (bevent->button == 3) {
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);