#include "timing.h"
#include "tags.h"
#include "manage_window.h"
+#include "folder_item_prefs.h"
static GdkColor quote_colors[3] = {
{(gulong)0, (gushort)0, (gushort)0, (gushort)0},
GtkTextBuffer *buffer;
GtkTextIter iter;
const gchar *name;
- gchar *content_type;
+ gchar *content_type, *shortcut;
+ GtkUIManager *ui_manager;
if (!partinfo) return;
+ if (textview->messageview->window != NULL)
+ ui_manager = textview->messageview->ui_manager;
+ else
+ ui_manager = textview->messageview->mainwin->ui_manager;
+
textview_set_font(textview, NULL);
textview_clear(textview);
TEXTVIEW_INSERT(_(" - To save, select "));
TEXTVIEW_INSERT_LINK(_("'Save as...'"), "sc://save_as", NULL);
#ifndef GENERIC_UMPC
- TEXTVIEW_INSERT(_(" (Shortcut key: 'y')"));
+ TEXTVIEW_INSERT(_(" (Shortcut key: '"));
+ shortcut = cm_menu_item_get_shortcut(ui_manager, "Menu/File/SavePartAs");
+ TEXTVIEW_INSERT(shortcut);
+ g_free(shortcut);
+ TEXTVIEW_INSERT("')");
#endif
TEXTVIEW_INSERT("\n");
TEXTVIEW_INSERT_LINK(_("'Display as text'"), "sc://display_as_text", NULL);
#ifndef GENERIC_UMPC
- TEXTVIEW_INSERT(_(" (Shortcut key: 't')"));
+ TEXTVIEW_INSERT(_(" (Shortcut key: '"));
+ shortcut = cm_menu_item_get_shortcut(ui_manager, "Menu/View/Part/AsText");
+ TEXTVIEW_INSERT(shortcut);
+ g_free(shortcut);
+ TEXTVIEW_INSERT("')");
#endif
TEXTVIEW_INSERT("\n");
TEXTVIEW_INSERT_LINK(_("'Open'"), "sc://open", NULL);
#ifndef GENERIC_UMPC
- TEXTVIEW_INSERT(_(" (Shortcut key: 'l')\n"));
+ TEXTVIEW_INSERT(_(" (Shortcut key: '"));
+ shortcut = cm_menu_item_get_shortcut(ui_manager, "Menu/View/Part/Open");
+ TEXTVIEW_INSERT(shortcut);
+ g_free(shortcut);
+ TEXTVIEW_INSERT("')\n");
TEXTVIEW_INSERT(_(" (alternately double-click, or click the middle "));
TEXTVIEW_INSERT(_("mouse button)\n"));
#ifndef G_OS_WIN32
TEXTVIEW_INSERT(_(" - Or use "));
TEXTVIEW_INSERT_LINK(_("'Open with...'"), "sc://open_with", NULL);
- TEXTVIEW_INSERT(_(" (Shortcut key: 'o')"));
+ TEXTVIEW_INSERT(_(" (Shortcut key: '"));
+ shortcut = cm_menu_item_get_shortcut(ui_manager, "Menu/View/Part/OpenWith");
+ TEXTVIEW_INSERT(shortcut);
+ g_free(shortcut);
+ TEXTVIEW_INSERT("')");
#endif
#endif
TEXTVIEW_INSERT("\n");
GtkTextView *text = GTK_TEXT_VIEW(textview->text);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
GtkTextIter iter;
- gchar *mybuf = g_strdup(linebuf);
+ gint mybuf_len = strlen(linebuf);
+ gchar *mybuf = g_strndup(linebuf, mybuf_len);
/* parse table - in order of priority */
struct table {
/* token search function */
gchar *(*search) (const gchar *haystack,
+ gint haystack_len,
const gchar *needle);
/* part parsing function */
gboolean (*parse) (const gchar *start,
};
static struct table parser[] = {
- {"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},
- {"gopher://",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}
+ {"http://", strncasestr, get_uri_part, make_uri_string},
+ {"https://", strncasestr, get_uri_part, make_uri_string},
+ {"ftp://", strncasestr, get_uri_part, make_uri_string},
+ {"sftp://", strncasestr, get_uri_part, make_uri_string},
+ {"gopher://",strncasestr, get_uri_part, make_uri_string},
+ {"www.", strncasestr, get_uri_part, make_http_string},
+ {"mailto:", strncasestr, get_uri_part, make_uri_string},
+ {"@", strncasestr, get_email_part, make_email_string}
};
const gint PARSE_ELEMS = sizeof parser / sizeof parser[0];
if (!g_utf8_validate(linebuf, -1, NULL)) {
g_free(mybuf);
- mybuf = g_malloc(strlen(linebuf)*2 +1);
- conv_localetodisp(mybuf, strlen(linebuf)*2 +1, linebuf);
+ mybuf = g_malloc(mybuf_len*2 +1);
+ conv_localetodisp(mybuf, mybuf_len*2 +1, linebuf);
+ mybuf_len = strlen(mybuf);
}
gtk_text_buffer_get_end_iter(buffer, &iter);
/* parse for clickable parts, and build a list of begin and end positions */
- for (walk = mybuf, n = 0;;) {
- gint last_index = PARSE_ELEMS;
- gchar *scanpos = NULL;
-
- /* FIXME: this looks phony. scanning for anything in the parse table */
- for (n = 0; n < PARSE_ELEMS; n++) {
- gchar *tmp;
-
- tmp = parser[n].search(walk, parser[n].needle);
- if (tmp) {
- if (scanpos == NULL || tmp < scanpos) {
- scanpos = tmp;
- last_index = n;
- }
- }
- }
-
- if (scanpos) {
- /* check if URI can be parsed */
- if (parser[last_index].parse(walk, scanpos, &bp, &ep, hdr)
- && (size_t) (ep - bp - 1) > strlen(parser[last_index].needle)) {
- ADD_TXT_POS(bp, ep, last_index);
+ for (n = 0; n < PARSE_ELEMS; n++) {
+ gint len = mybuf_len;
+ gint needle_len = strlen(parser[n].needle);
+ for (walk = mybuf;;) {
+ gchar *scanpos = parser[n].search(walk, len, parser[n].needle);
+ if (scanpos) {
+ /* check if URI can be parsed */
+ if (parser[n].parse(walk, scanpos, &bp, &ep, hdr)
+ && (size_t) (ep - bp - 1) > needle_len) {
+ ADD_TXT_POS(bp, ep, n);
+ len -= ep - walk;
walk = ep;
+ } else {
+ len -= (scanpos + needle_len) - walk;
+ walk = scanpos + needle_len;
+ }
} else
- walk = scanpos +
- strlen(parser[last_index].needle);
- } else
- break;
+ break;
+ }
}
/* colorize this line */
if (head.next) {
const gchar *normal_text = mybuf;
+ struct txtpos *previous = NULL;
/* insert URIs */
for (last = head.next; last != NULL;
normal_text = last->ep, last = last->next) {
ClickableText *uri;
+
+ if (previous != NULL
+ && previous->bp < last->bp
+ && previous->ep == last->ep)
+ continue;
+
uri = g_new0(ClickableText, 1);
if (last->bp - normal_text > 0)
gtk_text_buffer_insert_with_tags_by_name
uri->filename = NULL;
textview->uri_list =
g_slist_prepend(textview->uri_list, uri);
+ previous = last;
}
if (*normal_text)
GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
GtkTextIter start_iter, end_iter;
gchar *mybuf;
+ gint mybuf_len;
gint offset = 0;
/* parse table - in order of priority */
struct table {
/* token search function */
gchar *(*search) (const gchar *haystack,
+ gint haystack_len,
const gchar *needle);
/* part parsing function */
gboolean (*parse) (const gchar *start,
};
static struct table parser[] = {
- {"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}
+ {"http://", strncasestr, get_uri_part, make_uri_string},
+ {"https://", strncasestr, get_uri_part, make_uri_string},
+ {"ftp://", strncasestr, get_uri_part, make_uri_string},
+ {"sftp://", strncasestr, get_uri_part, make_uri_string},
+ {"www.", strncasestr, get_uri_part, make_http_string},
+ {"mailto:", strncasestr, get_uri_part, make_uri_string},
+ {"@", strncasestr, get_email_part, make_email_string}
};
const gint PARSE_ELEMS = sizeof parser / sizeof parser[0];
offset = gtk_text_iter_get_offset(&start_iter);
/* parse for clickable parts, and build a list of begin and end positions */
- for (walk = mybuf, n = 0;;) {
- gint last_index = PARSE_ELEMS;
- gchar *scanpos = NULL;
-
- /* FIXME: this looks phony. scanning for anything in the parse table */
- for (n = 0; n < PARSE_ELEMS; n++) {
- gchar *tmp;
-
- tmp = parser[n].search(walk, parser[n].needle);
- if (tmp) {
- if (scanpos == NULL || tmp < scanpos) {
- scanpos = tmp;
- last_index = n;
- }
- }
- }
-
- if (scanpos) {
- /* check if URI can be parsed */
- if (parser[last_index].parse(walk, scanpos, &bp, &ep, FALSE)
- && (size_t) (ep - bp - 1) > strlen(parser[last_index].needle)) {
- ADD_TXT_POS_LATER(bp, ep, last_index);
+ mybuf_len = strlen(mybuf);
+ for (n = 0; n < PARSE_ELEMS; n++) {
+ gint len = mybuf_len;
+ gint needle_len = strlen(parser[n].needle);
+ for (walk = mybuf;;) {
+ gchar *scanpos = parser[n].search(walk, len, parser[n].needle);
+ if (scanpos) {
+ /* check if URI can be parsed */
+ if (parser[n].parse(walk, scanpos, &bp, &ep, FALSE)
+ && (size_t) (ep - bp - 1) > needle_len) {
+ ADD_TXT_POS_LATER(bp, ep, n);
+ len -= ep - walk;
walk = ep;
+ } else {
+ len -= (scanpos + needle_len) - walk;
+ walk = scanpos + needle_len;
+ }
} else
- walk = scanpos +
- strlen(parser[last_index].needle);
- } else
- break;
+ break;
+ }
}
/* colorize this line */
if (head.next) {
+ struct txtpos *previous = NULL;
/* insert URIs */
for (last = head.next; last != NULL; last = last->next) {
ClickableText *uri;
gint start_offset, end_offset;
gchar *tmp_str;
gchar old_char;
+
+ if (previous != NULL
+ && previous->bp < last->bp
+ && previous->ep == last->ep)
+ continue;
+
uri = g_new0(ClickableText, 1);
uri->uri = parser[last->pti].build_uri(last->bp,
last->ep);
uri->filename = NULL;
textview->uri_list =
g_slist_prepend(textview->uri_list, uri);
+ previous = last;
}
}
uri = g_new0(ClickableText, 1);
uri->uri = g_strdup("");
uri->data = g_strdup(buf);
+ uri->data_len = strlen(uri->data);
uri->start = gtk_text_iter_get_offset(&iter);
uri->is_quote = TRUE;
uri->quote_level = real_quotelevel;
textview->prev_quote_level = -1;
goto do_quote;
}
- e_len = lasturi->data ? strlen(lasturi->data):0;
+ e_len = lasturi->data ? lasturi->data_len: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';
+ lasturi->data_len += n_len;
}
}
} else {
void textview_write_link(TextView *textview, const gchar *str,
const gchar *uri, CodeConverter *conv)
{
- GdkColor *link_color = NULL;
GtkTextView *text;
GtkTextBuffer *buffer;
GtkTextIter iter;
if (bufp > buf)
gtk_text_buffer_insert(buffer, &iter, buf, bufp - buf);
- if (prefs_common.enable_color) {
- link_color = &uri_color;
- }
r_uri = g_new0(ClickableText, 1);
r_uri->uri = g_strdup(uri);
r_uri->start = gtk_text_iter_get_offset(&iter);
if (summaryview)
summary_pass_key_press_event(summaryview, event);
break;
- case GDK_KEY_y:
- case GDK_KEY_t:
- case GDK_KEY_l:
- case GDK_KEY_o:
- case GDK_KEY_c:
- case GDK_KEY_a:
- if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) == 0) {
- KEY_PRESS_EVENT_STOP();
- mimeview_pass_key_press_event(messageview->mimeview,
- event);
- break;
- }
- /* possible fall through */
default:
window = gtk_widget_get_window(messageview->mainwin->window);
if (summaryview &&