From e0329942aaba1570d01467fe1f8d7829dcee1c46 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Tue, 6 Dec 2005 18:07:14 +0000 Subject: [PATCH] 2005-12-06 [colin] 1.9.100cvs70 * src/compose.c * src/quote_fmt_parse.y * src/undo.c * src/undo.h Allow %X to position cursor at 0 (no %X = before signature) Fix paste as quotation putting the cursor at 0 Fix undo offsets when pasting Insert the quote_fmt at once instead of line by line Fix [Edited] when starting to reply/forward --- ChangeLog | 14 ++++++ PATCHSETS | 1 + configure.ac | 2 +- src/compose.c | 102 +++++++++++++++++++++--------------------- src/quote_fmt_parse.y | 4 +- src/undo.c | 42 ++++++++++++++++- src/undo.h | 4 +- 7 files changed, 112 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba1032484..422994626 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-12-06 [colin] 1.9.100cvs70 + + * src/compose.c + * src/quote_fmt_parse.y + * src/undo.c + * src/undo.h + Allow %X to position cursor at 0 + (no %X = before signature) + Fix paste as quotation putting the cursor at 0 + Fix undo offsets when pasting + Insert the quote_fmt at once instead of line + by line + Fix [Edited] when starting to reply/forward + 2005-12-06 [paul] 1.9.100cvs69 * src/plugins/clamav/clamav_plugin_gtk.c diff --git a/PATCHSETS b/PATCHSETS index c869dfa67..a572ccfab 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -1053,3 +1053,4 @@ ( cvs diff -u -r 1.382.2.200 -r 1.382.2.201 src/compose.c; cvs diff -u -r 1.50.2.15 -r 1.50.2.16 src/compose.h; ) > 1.9.100cvs67.patchset ( cvs diff -u -r 1.53.2.14 -r 1.53.2.15 po/POTFILES.in; ) > 1.9.100cvs68.patchset ( cvs diff -u -r 1.9.2.14 -r 1.9.2.15 src/plugins/clamav/clamav_plugin_gtk.c; cvs diff -u -r 1.23.2.16 -r 1.23.2.17 src/plugins/spamassassin/spamassassin_gtk.c; ) > 1.9.100cvs69.patchset +( cvs diff -u -r 1.382.2.201 -r 1.382.2.202 src/compose.c; cvs diff -u -r 1.22.2.16 -r 1.22.2.17 src/quote_fmt_parse.y; cvs diff -u -r 1.13.2.4 -r 1.13.2.5 src/undo.c; cvs diff -u -r 1.5.14.3 -r 1.5.14.4 src/undo.h; ) > 1.9.100cvs70.patchset diff --git a/configure.ac b/configure.ac index 16d2145e1..9713383cd 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=100 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=69 +EXTRA_VERSION=70 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/compose.c b/src/compose.c index f9d5442e9..c84c75baf 100644 --- a/src/compose.c +++ b/src/compose.c @@ -215,7 +215,8 @@ static gchar *compose_quote_fmt (Compose *compose, MsgInfo *msginfo, const gchar *fmt, const gchar *qmark, - const gchar *body); + const gchar *body, + gboolean rewrap); static void compose_reply_set_entry (Compose *compose, MsgInfo *msginfo, @@ -926,6 +927,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI if (prefs_common.auto_exteditor) compose_exec_ext_editor(compose); + compose->modified = FALSE; compose_set_title(compose); return compose; } @@ -1198,7 +1200,7 @@ static Compose *compose_generic_reply(MsgInfo *msginfo, gboolean quote, compose_quote_fmt(compose, compose->replyinfo, prefs_common.quotefmt, - qmark, body); + qmark, body, FALSE); } if (procmime_msginfo_is_encrypted(compose->replyinfo)) { compose_force_encryption(compose, account, FALSE); @@ -1216,6 +1218,7 @@ static Compose *compose_generic_reply(MsgInfo *msginfo, gboolean quote, if (prefs_common.auto_exteditor) compose_exec_ext_editor(compose); + compose->modified = FALSE; compose_set_title(compose); return compose; } @@ -1269,7 +1272,8 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo, textview = GTK_TEXT_VIEW(compose->text); textbuf = gtk_text_view_get_buffer(textview); compose_create_tags(textview, compose); - + + undo_block(compose->undostruct); if (as_attach) { gchar *msgfile; @@ -1297,7 +1301,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo, compose_quote_fmt(compose, full_msginfo, prefs_common.fw_quotefmt, - qmark, body); + qmark, body, FALSE); compose_attach_parts(compose, msginfo); procmsg_msginfo_free(full_msginfo); @@ -1326,6 +1330,9 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo, g_free(folderidentifier); } + undo_unblock(compose->undostruct); + + compose->modified = FALSE; compose_set_title(compose); return compose; } @@ -1369,7 +1376,8 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list) textview = GTK_TEXT_VIEW(compose->text); textbuf = gtk_text_view_get_buffer(textview); compose_create_tags(textview, compose); - + + undo_block(compose->undostruct); for (msginfo = msginfo_list; msginfo != NULL; msginfo = msginfo->next) { msgfile = procmsg_get_message_file_path((MsgInfo *)msginfo->data); if (!is_file_exist(msgfile)) @@ -1409,7 +1417,8 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list) gtk_text_buffer_place_cursor(textbuf, &iter); gtk_widget_grab_focus(compose->header_last->entry); - + undo_unblock(compose->undostruct); + compose->modified = FALSE; compose_set_title(compose); return compose; } @@ -1622,6 +1631,7 @@ void compose_reedit(MsgInfo *msginfo) if (prefs_common.auto_exteditor) compose_exec_ext_editor(compose); + compose->modified = FALSE; compose_set_title(compose); } @@ -1673,7 +1683,7 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo) msginfo->subject); gtk_editable_set_editable(GTK_EDITABLE(compose->subject_entry), FALSE); - compose_quote_fmt(compose, msginfo, "%M", NULL, NULL); + compose_quote_fmt(compose, msginfo, "%M", NULL, NULL, FALSE); gtk_text_view_set_editable(GTK_TEXT_VIEW(compose->text), FALSE); compose_colorize_signature(compose); @@ -1701,6 +1711,7 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo) gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, FALSE); gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, FALSE); + compose->modified = FALSE; compose_set_title(compose); return compose; } @@ -2096,19 +2107,18 @@ static gchar *compose_parse_references(const gchar *ref, const gchar *msgid) static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo, const gchar *fmt, const gchar *qmark, - const gchar *body) + const gchar *body, gboolean rewrap) { static MsgInfo dummyinfo; gchar *quote_str = NULL; gchar *buf; - gchar *p, *lastp; - gint len; gboolean prev_autowrap; const gchar *trimmed_body = body; - gint cursor_pos = 0; + gint cursor_pos = -1; GtkTextView *text = GTK_TEXT_VIEW(compose->text); GtkTextBuffer *buffer = gtk_text_view_get_buffer(text); GtkTextIter iter; + GtkTextMark *mark; if (!msginfo) msginfo = &dummyinfo; @@ -2151,43 +2161,36 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo, g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_inserted), compose); - for (p = buf; *p != '\0'; ) { - GtkTextMark *mark; - - mark = gtk_text_buffer_get_insert(buffer); - gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); - - lastp = strchr(p, '\n'); - len = lastp ? lastp - p + 1 : -1; - if (g_utf8_validate(p, -1, NULL)) { - gtk_text_buffer_insert(buffer, &iter, p, len); - } else { - gchar *tmpin = g_strdup(p); - gchar *tmpout = NULL; - tmpin[len] = '\0'; - tmpout = conv_codeset_strdup - (tmpin, conv_get_locale_charset_str(), - CS_INTERNAL); - gtk_text_buffer_insert(buffer, &iter, tmpout, -1); - g_free(tmpin); + mark = gtk_text_buffer_get_insert(buffer); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); + if (g_utf8_validate(buf, -1, NULL)) { + gtk_text_buffer_insert(buffer, &iter, buf, -1); + } else { + gchar *tmpout = NULL; + tmpout = conv_codeset_strdup + (buf, conv_get_locale_charset_str(), + CS_INTERNAL); + if (!tmpout || !g_utf8_validate(tmpout, -1, NULL)) { g_free(tmpout); + tmpout = g_malloc(strlen(buf)*2+1); + conv_localetodisp(tmpout, strlen(buf)*2+1, buf); } - - if (lastp) - p = lastp + 1; - else - break; + gtk_text_buffer_insert(buffer, &iter, tmpout, -1); + g_free(tmpout); } cursor_pos = quote_fmt_get_cursor_pos(); + compose->set_cursor_pos = cursor_pos; + if (cursor_pos == -1) { + cursor_pos = 0; + } gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_get_iter_at_offset(buffer, &iter, cursor_pos); gtk_text_buffer_place_cursor(buffer, &iter); - compose->set_cursor_pos = cursor_pos; compose->autowrap = prev_autowrap; - if (compose->autowrap) + if (compose->autowrap && rewrap) compose_wrap_all(compose); g_signal_handlers_unblock_by_func(G_OBJECT(buffer), @@ -2529,7 +2532,7 @@ static void compose_insert_sig(Compose *compose, gboolean replace) /* put the cursor where it should be * either where the quote_fmt says, either before the signature */ - if (compose->set_cursor_pos <= 0) + if (compose->set_cursor_pos < 0) gtk_text_buffer_get_iter_at_offset(buffer, &iter, cur_pos); else gtk_text_buffer_get_iter_at_offset(buffer, &iter, @@ -3231,9 +3234,7 @@ static void compose_beautify_paragraph(Compose *compose, GtkTextIter *par_iter, compose->autowrap = FALSE; buffer = gtk_text_view_get_buffer(text); - - undo_block(compose->undostruct); - + undo_wrapping(compose->undostruct, TRUE); if (par_iter) { iter = *par_iter; } else { @@ -3445,8 +3446,7 @@ colorize: if (par_iter) *par_iter = iter; - - undo_unblock(compose->undostruct); + undo_wrapping(compose->undostruct, FALSE); compose->autowrap = prev_autowrap; } @@ -3463,13 +3463,10 @@ static void compose_wrap_all_full(Compose *compose, gboolean force) buffer = gtk_text_view_get_buffer(text); - undo_block(compose->undostruct); - gtk_text_buffer_get_start_iter(buffer, &iter); while (!gtk_text_iter_is_end(&iter)) compose_beautify_paragraph(compose, &iter, force); - undo_unblock(compose->undostruct); } static void compose_set_title(Compose *compose) @@ -6008,7 +6005,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl, if ((compose->replyinfo == NULL) && (compose->fwdinfo == NULL)) { parsed_str = compose_quote_fmt(compose, NULL, tmpl->value, - NULL, NULL); + NULL, NULL, FALSE); } else { if (prefs_common.quotemark && *prefs_common.quotemark) qmark = prefs_common.quotemark; @@ -6017,10 +6014,10 @@ static void compose_template_apply(Compose *compose, Template *tmpl, if (compose->replyinfo != NULL) parsed_str = compose_quote_fmt(compose, compose->replyinfo, - tmpl->value, qmark, NULL); + tmpl->value, qmark, NULL, FALSE); else if (compose->fwdinfo != NULL) parsed_str = compose_quote_fmt(compose, compose->fwdinfo, - tmpl->value, qmark, NULL); + tmpl->value, qmark, NULL, FALSE); else parsed_str = NULL; } @@ -6035,10 +6032,12 @@ static void compose_template_apply(Compose *compose, Template *tmpl, if (parsed_str) { cursor_pos = quote_fmt_get_cursor_pos(); + compose->set_cursor_pos = cursor_pos; + if (cursor_pos == -1) + cursor_pos = 0; gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_get_iter_at_offset(buffer, &iter, cursor_pos); gtk_text_buffer_place_cursor(buffer, &iter); - compose->set_cursor_pos = cursor_pos; } if (parsed_str) @@ -8040,12 +8039,13 @@ static void text_inserted(GtkTextBuffer *buffer, GtkTextIter *iter, mark = gtk_text_buffer_create_mark(buffer, NULL, iter, FALSE); gtk_text_buffer_place_cursor(buffer, iter); - compose_quote_fmt(compose, NULL, "%Q", qmark, new_text); + compose_quote_fmt(compose, NULL, "%Q", qmark, new_text, TRUE); g_free(new_text); g_object_set_data(G_OBJECT(compose->text), "paste_as_quotation", GINT_TO_POINTER(paste_as_quotation - 1)); gtk_text_buffer_get_iter_at_mark(buffer, iter, mark); + gtk_text_buffer_place_cursor(buffer, iter); } else gtk_text_buffer_insert(buffer, iter, text, len); diff --git a/src/quote_fmt_parse.y b/src/quote_fmt_parse.y index b148377e6..cb21fc6d8 100644 --- a/src/quote_fmt_parse.y +++ b/src/quote_fmt_parse.y @@ -53,7 +53,7 @@ static const gchar *quote_str = NULL; static const gchar *body = NULL; static gint error = 0; -static gint cursor_pos = 0; +static gint cursor_pos = -1; extern int quote_fmt_firsttime; @@ -133,7 +133,7 @@ void quote_fmt_init(MsgInfo *info, const gchar *my_quote_str, * force LEX initialization */ quote_fmt_firsttime = 1; - cursor_pos = 0; + cursor_pos = -1; } void quote_fmterror(char *str) diff --git a/src/undo.c b/src/undo.c index 960a9147e..cd7468630 100644 --- a/src/undo.c +++ b/src/undo.c @@ -537,18 +537,39 @@ void undo_unblock(UndoMain *undostruct) undostruct); } +void undo_wrapping(UndoMain *undostruct, gboolean wrap) +{ + debug_print("undo wrapping now %d\n", wrap); + undostruct->wrap = wrap; +} + void undo_insert_text_cb(GtkTextBuffer *textbuf, GtkTextIter *iter, gchar *new_text, gint new_text_length, UndoMain *undostruct) { gchar *text_to_insert; gint pos; - if (prefs_common.undolevels <= 0) return; pos = gtk_text_iter_get_offset(iter); - + if (undostruct->wrap && undostruct->undo) { + UndoInfo *last_undo = undostruct->undo->data; + if (last_undo && last_undo->action == UNDO_ACTION_INSERT + && last_undo->start_pos < pos && last_undo->end_pos > pos) { + GtkTextIter start,end; + last_undo->end_pos += g_utf8_strlen(new_text, -1); + gtk_text_buffer_get_iter_at_offset(textbuf, &start, last_undo->start_pos); + gtk_text_buffer_get_iter_at_offset(textbuf, &end, last_undo->end_pos); + g_free(last_undo->text); + last_undo->text = gtk_text_buffer_get_text(textbuf, &start, &end, FALSE); + debug_print("add:undo upd %d-%d\n", last_undo->start_pos, last_undo->end_pos); + return; + } else debug_print("add:last: %d, %d-%d (%d)\n", last_undo->action, + last_undo->start_pos, last_undo->end_pos, pos); + + } Xstrndup_a(text_to_insert, new_text, new_text_length, return); + debug_print("add:undo add %d-%ld\n", pos, pos + g_utf8_strlen(text_to_insert, -1)); undo_add(text_to_insert, pos, pos + g_utf8_strlen(text_to_insert, -1), UNDO_ACTION_INSERT, undostruct); } @@ -567,6 +588,23 @@ void undo_delete_text_cb(GtkTextBuffer *textbuf, GtkTextIter *start, start_pos = gtk_text_iter_get_offset(start); end_pos = gtk_text_iter_get_offset(end); + if (undostruct->wrap && undostruct->undo) { + UndoInfo *last_undo = undostruct->undo->data; + if (last_undo && last_undo->action == UNDO_ACTION_INSERT + && last_undo->start_pos < start_pos && last_undo->end_pos > end_pos) { + GtkTextIter start,end; + last_undo->end_pos -= g_utf8_strlen(text_to_delete, -1); + gtk_text_buffer_get_iter_at_offset(textbuf, &start, last_undo->start_pos); + gtk_text_buffer_get_iter_at_offset(textbuf, &end, last_undo->end_pos); + g_free(last_undo->text); + last_undo->text = gtk_text_buffer_get_text(textbuf, &start, &end, FALSE); + debug_print("del:undo upd %d-%d\n", last_undo->start_pos, last_undo->end_pos); + return; + } else debug_print("del:last: %d, %d-%d (%d)\n", last_undo->action, + last_undo->start_pos, last_undo->end_pos, start_pos); + + } + debug_print("del:undo add %d-%d\n", start_pos, end_pos); undo_add(text_to_delete, start_pos, end_pos, UNDO_ACTION_DELETE, undostruct); g_free(text_to_delete); diff --git a/src/undo.h b/src/undo.h index eafa66a85..ff1547e87 100644 --- a/src/undo.h +++ b/src/undo.h @@ -63,6 +63,7 @@ struct _UndoMain gboolean redo_state : 1; gint paste; + gint wrap; }; UndoMain *undo_init (GtkWidget *text); @@ -76,5 +77,6 @@ void undo_undo (UndoMain *undostruct); void undo_redo (UndoMain *undostruct); void undo_block (UndoMain *undostruct); void undo_unblock (UndoMain *undostruct); - +void undo_wrapping (UndoMain *undostruct, + gboolean wrap); #endif /* __UNDO_H__ */ -- 2.25.1