2005-12-06 [colin] 1.9.100cvs70
authorColin Leroy <colin@colino.net>
Tue, 6 Dec 2005 18:07:14 +0000 (18:07 +0000)
committerColin Leroy <colin@colino.net>
Tue, 6 Dec 2005 18:07:14 +0000 (18:07 +0000)
* 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
PATCHSETS
configure.ac
src/compose.c
src/quote_fmt_parse.y
src/undo.c
src/undo.h

index ba10324..4229946 100644 (file)
--- 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
index c869dfa..a572ccf 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( 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
index 16d2145..9713383 100644 (file)
@@ -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=
 
index f9d5442..c84c75b 100644 (file)
@@ -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);
 
index b148377..cb21fc6 100644 (file)
@@ -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)
index 960a914..cd74686 100644 (file)
@@ -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);
index eafa66a..ff1547e 100644 (file)
@@ -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__ */