* src/messageview.c
* src/summaryview.c
* src/textview.c
* src/textview.h
Make loading of huge mails (lots of text and/or
images) cancellable, so the GUI doesn't block
+2006-09-04 [colin] 2.4.0cvs143
+
+ * src/messageview.c
+ * src/summaryview.c
+ * src/textview.c
+ * src/textview.h
+ Make loading of huge mails (lots of text and/or
+ images) cancellable, so the GUI doesn't block
+
2006-09-04 [colin] 2.4.0cvs142
* src/plugins/trayicon/trayicon.c
2006-09-04 [colin] 2.4.0cvs142
* src/plugins/trayicon/trayicon.c
( cvs diff -u -r 1.59.2.41 -r 1.59.2.42 src/prefs_filtering.c; ) > 2.4.0cvs140.patchset
( cvs diff -u -r 1.1.2.9 -r 1.1.2.10 src/gtk/icon_legend.c; ) > 2.4.0cvs141.patchset
( cvs diff -u -r 1.14.2.37 -r 1.14.2.38 src/plugins/trayicon/trayicon.c; ) > 2.4.0cvs142.patchset
( cvs diff -u -r 1.59.2.41 -r 1.59.2.42 src/prefs_filtering.c; ) > 2.4.0cvs140.patchset
( cvs diff -u -r 1.1.2.9 -r 1.1.2.10 src/gtk/icon_legend.c; ) > 2.4.0cvs141.patchset
( cvs diff -u -r 1.14.2.37 -r 1.14.2.38 src/plugins/trayicon/trayicon.c; ) > 2.4.0cvs142.patchset
+( cvs diff -u -r 1.94.2.102 -r 1.94.2.103 src/messageview.c; cvs diff -u -r 1.395.2.242 -r 1.395.2.243 src/summaryview.c; cvs diff -u -r 1.96.2.144 -r 1.96.2.145 src/textview.c; cvs diff -u -r 1.12.2.12 -r 1.12.2.13 src/textview.h; ) > 2.4.0cvs143.patchset
MICRO_VERSION=0
INTERFACE_AGE=0
BINARY_AGE=0
MICRO_VERSION=0
INTERFACE_AGE=0
BINARY_AGE=0
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
}
headerview_show(messageview->headerview, messageview->msginfo);
}
headerview_show(messageview->headerview, messageview->msginfo);
+ messageview_set_position(messageview, 0);
+
textview_set_all_headers(messageview->mimeview->textview,
messageview->all_headers);
textview_set_all_headers(messageview->mimeview->textview,
messageview->all_headers);
- messageview_set_position(messageview, 0);
-
main_create_mailing_list_menu(messageview->mainwin, messageview->msginfo);
if (messageview->msginfo->extradata
main_create_mailing_list_menu(messageview->mainwin, messageview->msginfo);
if (messageview->msginfo->extradata
}
if (messageview->updating) {
}
if (messageview->updating) {
- debug_print("uh oh, better not touch that now\n");
+ debug_print("uh oh, better not touch that now (fetching)\n");
+ messageview->deferred_destroy = TRUE;
+ gtk_widget_hide(messageview->window);
+ return;
+ }
+
+ if (messageview->mimeview->textview
+ && messageview->mimeview->textview->loading) {
+ debug_print("uh oh, better not touch that now (loading text)\n");
messageview->deferred_destroy = TRUE;
messageview->deferred_destroy = TRUE;
+ messageview->mimeview->textview->stop_loading = TRUE;
gtk_widget_hide(messageview->window);
return;
}
gtk_widget_hide(messageview->window);
return;
}
main_window_cursor_normal(summaryview->mainwin);
return FALSE;
}
main_window_cursor_normal(summaryview->mainwin);
return FALSE;
}
gboolean summary_show(SummaryView *summaryview, FolderItem *item)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
gboolean summary_show(SummaryView *summaryview, FolderItem *item)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
summary_status_show(summaryview);
}
summary_status_show(summaryview);
}
+typedef struct _PostponedSelectData
+{
+ GtkCTree *ctree;
+ GtkCTreeNode *row;
+ gint column;
+ SummaryView *summaryview;
+} PostponedSelectData;
+
+static gboolean summary_select_retry(void *data)
+{
+ PostponedSelectData *psdata = (PostponedSelectData *)data;
+ debug_print("trying again\n");
+ summary_selected(psdata->ctree, psdata->row,
+ psdata->column, psdata->summaryview);
+ g_free(psdata);
+ return FALSE;
+}
+
static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
gint column, SummaryView *summaryview)
{
MsgInfo *msginfo;
gboolean marked_unread = FALSE;
static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
gint column, SummaryView *summaryview)
{
MsgInfo *msginfo;
gboolean marked_unread = FALSE;
+ if (summary_is_locked(summaryview)
+ && !GTK_SCTREE(ctree)->selecting_range
+ && summaryview->messageview->mimeview
+ && summaryview->messageview->mimeview->type == MIMEVIEW_TEXT
+ && summaryview->messageview->mimeview->textview->loading) {
+ PostponedSelectData *data = g_new0(PostponedSelectData, 1);
+ summaryview->messageview->mimeview->textview->stop_loading = TRUE;
+
+ data->ctree = ctree;
+ data->row = row;
+ data->column = column;
+ data->summaryview = summaryview;
+ debug_print("postponing open of message till end of load\n");
+ g_timeout_add(100, summary_select_retry, data);
+ return;
+ }
if (summary_is_locked(summaryview)
|| GTK_SCTREE(ctree)->selecting_range) {
return;
if (summary_is_locked(summaryview)
|| GTK_SCTREE(ctree)->selecting_range) {
return;
void textview_show_message(TextView *textview, MimeInfo *mimeinfo,
const gchar *file)
{
void textview_show_message(TextView *textview, MimeInfo *mimeinfo,
const gchar *file)
{
+ textview->loading = TRUE;
+ textview->stop_loading = FALSE;
+
textview_clear(textview);
textview_add_parts(textview, mimeinfo);
textview_set_position(textview, 0);
textview_clear(textview);
textview_add_parts(textview, mimeinfo);
textview_set_position(textview, 0);
+
+ textview->loading = FALSE;
+ textview->stop_loading = FALSE;
}
void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
}
void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
if ((mimeinfo->type == MIMETYPE_MULTIPART) ||
((mimeinfo->type == MIMETYPE_MESSAGE) && !g_ascii_strcasecmp(mimeinfo->subtype, "rfc822"))) {
if ((mimeinfo->type == MIMETYPE_MULTIPART) ||
((mimeinfo->type == MIMETYPE_MESSAGE) && !g_ascii_strcasecmp(mimeinfo->subtype, "rfc822"))) {
+ textview->loading = TRUE;
+ textview->stop_loading = FALSE;
+
textview_clear(textview);
textview_add_parts(textview, mimeinfo);
textview_clear(textview);
textview_add_parts(textview, mimeinfo);
+
+ textview->loading = FALSE;
+ textview->stop_loading = FALSE;
+ textview->loading = TRUE;
+ textview->stop_loading = FALSE;
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0)
perror("fseek");
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0)
perror("fseek");
textview_add_parts(textview, mimeinfo);
else
textview_write_body(textview, mimeinfo);
textview_add_parts(textview, mimeinfo);
else
textview_write_body(textview, mimeinfo);
+
+ textview->loading = FALSE;
+ textview->stop_loading = FALSE;
charcount = gtk_text_buffer_get_char_count(buffer);
gtk_text_buffer_get_end_iter(buffer, &iter);
charcount = gtk_text_buffer_get_char_count(buffer);
gtk_text_buffer_get_end_iter(buffer, &iter);
+ if (textview->stop_loading) {
+ return;
+ }
if (mimeinfo->type == MIMETYPE_MULTIPART) {
END_TIMING();
return;
if (mimeinfo->type == MIMETYPE_MULTIPART) {
END_TIMING();
return;
ClickableText *uri;
gchar *uri_str;
START_TIMING("inserting image");
ClickableText *uri;
gchar *uri_str;
START_TIMING("inserting image");
filename = procmime_get_tmp_file_name(mimeinfo);
if (procmime_get_part(filename, mimeinfo) < 0) {
filename = procmime_get_tmp_file_name(mimeinfo);
if (procmime_get_part(filename, mimeinfo) < 0) {
g_object_unref(pixbuf);
g_free(filename);
END_TIMING();
g_object_unref(pixbuf);
g_free(filename);
END_TIMING();
}
} else if (mimeinfo->type == MIMETYPE_TEXT) {
if (prefs_common.display_header && (charcount > 0))
}
} else if (mimeinfo->type == MIMETYPE_TEXT) {
if (prefs_common.display_header && (charcount > 0))
CodeConverter *conv;
const gchar *charset, *p, *cmd;
GSList *cur;
CodeConverter *conv;
const gchar *charset, *p, *cmd;
GSList *cur;
if (textview->messageview->forced_charset)
charset = textview->messageview->forced_charset;
if (textview->messageview->forced_charset)
charset = textview->messageview->forced_charset;
}
close(pfd[1]);
tmpfp = fdopen(pfd[0], "rb");
}
close(pfd[1]);
tmpfp = fdopen(pfd[0], "rb");
- while (fgets(buf, sizeof(buf), tmpfp))
+ while (fgets(buf, sizeof(buf), tmpfp)) {
textview_write_line(textview, buf, conv);
textview_write_line(textview, buf, conv);
+
+ lines++;
+ if (lines % 500 == 0)
+ GTK_EVENTS_FLUSH();
+ if (textview->stop_loading) {
+ fclose(tmpfp);
+ waitpid(pid, pfd, 0);
+ unlink(fname);
+ return;
+ }
+ }
+
fclose(tmpfp);
waitpid(pid, pfd, 0);
unlink(fname);
} else {
textview_default:
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);
while ((ftell(tmpfp) < mimeinfo->offset + mimeinfo->length) &&
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);
while ((ftell(tmpfp) < mimeinfo->offset + mimeinfo->length) &&
- (fgets(buf, sizeof(buf), tmpfp) != NULL))
+ (fgets(buf, sizeof(buf), tmpfp) != NULL)) {
textview_write_line(textview, buf, conv);
textview_write_line(textview, buf, conv);
+ lines++;
+ if (lines % 500 == 0)
+ GTK_EVENTS_FLUSH();
+ if (textview->stop_loading) {
+ fclose(tmpfp);
+ return;
+ }
+ }
fclose(tmpfp);
}
conv_code_converter_destroy(conv);
procmime_force_encoding(0);
fclose(tmpfp);
}
conv_code_converter_destroy(conv);
procmime_force_encoding(0);
for (cur = textview->uri_list; cur; cur = cur->next) {
ClickableText *uri = (ClickableText *)cur->data;
if (!uri->is_quote)
for (cur = textview->uri_list; cur; cur = cur->next) {
ClickableText *uri = (ClickableText *)cur->data;
if (!uri->is_quote)
if (!prefs_common.hide_quotes ||
uri->quote_level+1 < prefs_common.hide_quotes) {
textview_toggle_quote(textview, uri, TRUE);
if (!prefs_common.hide_quotes ||
uri->quote_level+1 < prefs_common.hide_quotes) {
textview_toggle_quote(textview, uri, TRUE);
+ lines++;
+ if (lines % 500 == 0)
+ GTK_EVENTS_FLUSH();
+ if (textview->stop_loading) {
+ return;
+ }
{
SC_HTMLParser *parser;
gchar *str;
{
SC_HTMLParser *parser;
gchar *str;
parser = sc_html_parser_new(fp, conv);
g_return_if_fail(parser != NULL);
parser = sc_html_parser_new(fp, conv);
g_return_if_fail(parser != NULL);
textview_write_link(textview, str, parser->href, NULL);
} else
textview_write_line(textview, str, NULL);
textview_write_link(textview, str, parser->href, NULL);
} else
textview_write_line(textview, str, NULL);
+ lines++;
+ if (lines % 500 == 0)
+ GTK_EVENTS_FLUSH();
+ if (textview->stop_loading) {
+ return;
+ }
}
textview_write_line(textview, "\n", NULL);
sc_html_parser_destroy(parser);
}
textview_write_line(textview, "\n", NULL);
sc_html_parser_destroy(parser);
{
ERTFParser *parser;
gchar *str;
{
ERTFParser *parser;
gchar *str;
parser = ertf_parser_new(fp, conv);
g_return_if_fail(parser != NULL);
while ((str = ertf_parse(parser)) != NULL) {
textview_write_line(textview, str, NULL);
parser = ertf_parser_new(fp, conv);
g_return_if_fail(parser != NULL);
while ((str = ertf_parse(parser)) != NULL) {
textview_write_line(textview, str, NULL);
+ lines++;
+ if (lines % 500 == 0)
+ GTK_EVENTS_FLUSH();
+ if (textview->stop_loading) {
+ return;
+ }
}
ertf_parser_destroy(parser);
}
ertf_parser_destroy(parser);
GdkEventMotion *event,
TextView *textview)
{
GdkEventMotion *event,
TextView *textview)
{
+ if (textview->loading)
+ return FALSE;
textview_uri_update(textview, event->x, event->y);
gdk_window_get_pointer(widget->window, NULL, NULL, NULL);
textview_uri_update(textview, event->x, event->y);
gdk_window_get_pointer(widget->window, NULL, NULL, NULL);
GdkEventCrossing *event,
TextView *textview)
{
GdkEventCrossing *event,
TextView *textview)
{
+ if (textview->loading)
+ return FALSE;
textview_uri_update(textview, -1, -1);
return FALSE;
textview_uri_update(textview, -1, -1);
return FALSE;
gint wx, wy;
GdkWindow *window;
gint wx, wy;
GdkWindow *window;
+ if (textview->loading)
+ return FALSE;
+
window = gtk_text_view_get_window(GTK_TEXT_VIEW(widget),
GTK_TEXT_WINDOW_TEXT);
window = gtk_text_view_get_window(GTK_TEXT_VIEW(widget),
GTK_TEXT_WINDOW_TEXT);
GtkTextIter uri_hover_start_iter;
GtkTextIter uri_hover_end_iter;
GtkWidget *image;
GtkTextIter uri_hover_start_iter;
GtkTextIter uri_hover_end_iter;
GtkWidget *image;
+ gboolean loading;
+ gboolean stop_loading;
};
TextView *textview_create (void);
};
TextView *textview_create (void);