Index: blender/source/blender/blenkernel/BKE_text.h =================================================================== --- blender/source/blender/blenkernel/BKE_text.h (revision 45766) +++ blender/source/blender/blenkernel/BKE_text.h (working copy) @@ -83,7 +83,7 @@ char* txt_sel_to_buf (struct Text *text); void txt_insert_buf (struct Text *text, const char *in_buffer); void txt_print_undo (struct Text *text); -void txt_undo_add_toop (struct Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc); +void txt_undo_add_op (struct Text *text, int op); void txt_do_undo (struct Text *text); void txt_do_redo (struct Text *text); void txt_split_curline (struct Text *text); @@ -116,24 +116,6 @@ /* Undo opcodes */ -/* Simple main cursor movement */ -#define UNDO_CLEFT 001 -#define UNDO_CRIGHT 002 -#define UNDO_CUP 003 -#define UNDO_CDOWN 004 - -/* Simple selection cursor movement */ -#define UNDO_SLEFT 005 -#define UNDO_SRIGHT 006 -#define UNDO_SUP 007 -#define UNDO_SDOWN 010 - -/* Complex movement (opcode is followed - * by 4 character line ID + a 2 character - * position ID and opcode (repeat)) */ -#define UNDO_CTO 011 -#define UNDO_STO 012 - /* Complex editing */ /* 1 - opcode is followed by 1 byte for ascii character and opcode (repeat)) */ /* 2 - opcode is followed by 2 bytes for utf-8 character and opcode (repeat)) */ @@ -162,8 +144,6 @@ #define UNDO_IBLOCK 030 /* Insert block */ /* Misc */ -#define UNDO_SWAP 031 /* Swap cursors */ - #define UNDO_INDENT 032 #define UNDO_UNINDENT 033 #define UNDO_COMMENT 034 Index: blender/source/blender/blenkernel/intern/text.c =================================================================== --- blender/source/blender/blenkernel/intern/text.c (revision 45766) +++ blender/source/blender/blenkernel/intern/text.c (working copy) @@ -105,26 +105,18 @@ * * Undo * -- - * Undo/Redo works by storing - * events in a queue, and a pointer - * to the current position in the - * queue... + * Undo/Redo works by storing events in a queue, and a pointer to the current + * position in the queue... * - * Events are stored using an - * arbitrary op-code system - * to keep track of + * Events are stored using an arbitrary op-code system to keep track of * a) the two cursors (normal and selected) * b) input (visible and control (ie backspace)) * - * input data is stored as its - * ASCII value, the opcodes are - * then selected to not conflict. + * input data is stored as its ASCII value, the opcodes are then selected to + * not conflict. * - * opcodes with data in between are - * written at the beginning and end - * of the data to allow undo and redo - * to simply check the code at the current - * undo position + * opcodes with data in between are written at the beginning and end of the data + * to allow undo and redo to simply check the code at the current undo position * */ @@ -132,8 +124,7 @@ static void txt_pop_first(Text *text); static void txt_pop_last(Text *text); -static void txt_undo_add_op(Text *text, int op); -static void txt_undo_add_block(Text *text, int op, const char *buf); +static void txt_undo_add_blockop(Text *text, int op, const char *buf); static void txt_delete_line(Text *text, TextLine *line); static void txt_delete_sel (Text *text); static void txt_make_dirty (Text *text); @@ -749,23 +740,6 @@ *linep= &text->sell; *charp= &text->selc; } -static void txt_curs_first (Text *text, TextLine **linep, int *charp) -{ - if (text->curl==text->sell) { - *linep= text->curl; - if (text->curcselc) *charp= text->curc; - else *charp= text->selc; - } - else if (txt_get_span(text->lines.first, text->curl)lines.first, text->sell)) { - *linep= text->curl; - *charp= text->curc; - } - else { - *linep= text->sell; - *charp= text->selc; - } -} - /*****************************/ /* Cursor movement functions */ /*****************************/ @@ -807,22 +781,17 @@ { TextLine **linep; int *charp; - /* int old; */ /* UNUSED */ if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - /* old= *charp; */ /* UNUSED */ if ((*linep)->prev) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); *linep= (*linep)->prev; if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len; else *charp= txt_utf8_index_to_offset((*linep)->line, index); - - if (!undoing) - txt_undo_add_op(text, sel?UNDO_SUP:UNDO_CUP); } else { txt_move_bol(text, sel); @@ -835,22 +804,17 @@ { TextLine **linep; int *charp; - /* int old; */ /* UNUSED */ if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - /* old= *charp; */ /* UNUSED */ if ((*linep)->next) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); *linep= (*linep)->next; if (index > txt_utf8_len((*linep)->line)) *charp= (*linep)->len; else *charp= txt_utf8_index_to_offset((*linep)->line, index); - - if (!undoing) - txt_undo_add_op(text, sel?UNDO_SDOWN:UNDO_CDOWN); } else { txt_move_eol(text, sel); @@ -862,7 +826,7 @@ void txt_move_left(Text *text, short sel) { TextLine **linep; - int *charp, oundoing= undoing; + int *charp; int tabsize= 0, i= 0; if (!text) return; @@ -870,8 +834,6 @@ else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - undoing= 1; - if (*charp== 0) { if ((*linep)->prev) { txt_move_up(text, sel); @@ -903,24 +865,19 @@ } } - undoing= oundoing; - if (!undoing) txt_undo_add_op(text, sel?UNDO_SLEFT:UNDO_CLEFT); - if (!sel) txt_pop_sel(text); } void txt_move_right(Text *text, short sel) { TextLine **linep; - int *charp, oundoing= undoing, do_tab= 0, i; + int *charp, do_tab= 0, i; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - undoing= 1; - if (*charp== (*linep)->len) { if ((*linep)->next) { txt_move_down(text, sel); @@ -947,18 +904,14 @@ } else (*charp)+= BLI_str_utf8_size((*linep)->line + *charp); } - - undoing= oundoing; - if (!undoing) txt_undo_add_op(text, sel?UNDO_SRIGHT:UNDO_CRIGHT); if (!sel) txt_pop_sel(text); } void txt_jump_left(Text *text, short sel) { - TextLine **linep, *oldl; - int *charp, oldc, oldflags, i; - unsigned char oldu; + TextLine **linep; + int *charp, oldflags, i; int pos; if (!text) return; @@ -969,11 +922,6 @@ oldflags = text->flags; text->flags &= ~TXT_TABSTOSPACES; - oldl= *linep; - oldc= *charp; - oldu= undoing; - undoing= 1; /* Don't push individual moves to undo stack */ - pos = *charp; BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, &pos, STRCUR_DIR_PREV, @@ -983,16 +931,12 @@ } text->flags = oldflags; - - undoing= oldu; - if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_jump_right(Text *text, short sel) { - TextLine **linep, *oldl; - int *charp, oldc, oldflags, i; - unsigned char oldu; + TextLine **linep; + int *charp, oldflags, i; int pos; if (!text) return; @@ -1003,11 +947,6 @@ oldflags = text->flags; text->flags &= ~TXT_TABSTOSPACES; - oldl= *linep; - oldc= *charp; - oldu= undoing; - undoing= 1; /* Don't push individual moves to undo stack */ - pos = *charp; BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, &pos, STRCUR_DIR_NEXT, @@ -1017,79 +956,68 @@ } text->flags = oldflags; - - undoing= oldu; - if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_bol (Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old= *charp; *charp= 0; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_eol (Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old= *charp; *charp= (*linep)->len; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_bof (Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old= *charp; *linep= text->lines.first; *charp= 0; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_eof (Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old= *charp; *linep= text->lines.last; *charp= (*linep)->len; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_toline (Text *text, unsigned int line, short sel) @@ -1100,16 +1028,14 @@ /* Moves to a certain byte in a line, not a certain utf8-character! */ void txt_move_to (Text *text, unsigned int line, unsigned int ch, short sel) { - TextLine **linep, *oldl; - int *charp, oldc; + TextLine **linep; + int *charp; unsigned int i; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - oldc= *charp; - oldl= *linep; *linep= text->lines.first; for (i=0; ilines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } /****************************/ @@ -1140,8 +1065,6 @@ tmpc= text->curc; text->curc= text->selc; text->selc= tmpc; - - if (!undoing) txt_undo_add_op(text, UNDO_SWAP); } static void txt_pop_first (Text *text) @@ -1151,12 +1074,6 @@ (text->curl==text->sell && text->curc>text->selc)) { txt_curs_swap(text); } - - if (!undoing) txt_undo_add_toop(text, UNDO_STO, - txt_get_span(text->lines.first, text->sell), - text->selc, - txt_get_span(text->lines.first, text->curl), - text->curc); txt_pop_sel(text); } @@ -1167,12 +1084,6 @@ (text->curl==text->sell && text->curcselc)) { txt_curs_swap(text); } - - if (!undoing) txt_undo_add_toop(text, UNDO_STO, - txt_get_span(text->lines.first, text->sell), - text->selc, - txt_get_span(text->lines.first, text->curl), - text->curc); txt_pop_sel(text); } @@ -1192,7 +1103,7 @@ if (!text->curl) return; if (!text->sell) return; - /* Flip so text->curl is before text->sell */ + /* Flip so text->curl is before text->sell */ if (txt_get_span(text->curl, text->sell)<0 || (text->curl==text->sell && text->curc>text->selc)) txt_curs_swap(text); @@ -1220,7 +1131,7 @@ if (!undoing) { buf= txt_sel_to_buf(text); - txt_undo_add_block(text, UNDO_DBLOCK, buf); + txt_undo_add_blockop(text, UNDO_DBLOCK, buf); MEM_freeN(buf); } @@ -1479,10 +1390,11 @@ { TextMarker *marker; - for (marker=text->markers.first; marker; marker= marker->next) + for (marker=text->markers.first; marker; marker= marker->next) { if (marker->lineno>=lineno) { marker->lineno+= count; } + } } void txt_insert_buf(Text *text, const char *in_buffer) @@ -1501,7 +1413,7 @@ buffer= BLI_strdupn(in_buffer, len); len+= txt_extended_ascii_as_utf8(&buffer); - if (!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer); + if (!undoing) txt_undo_add_blockop(text, UNDO_IBLOCK, buffer); u= undoing; undoing= 1; @@ -1583,6 +1495,7 @@ while (i++undo_pos) printf("%d: %d %c\n", i, text->undo_buf[i], text->undo_buf[i]); } +/* Note: this function is outdated and must be updated if needed for future use */ void txt_print_undo(Text *text) { int i= 0; @@ -1599,37 +1512,7 @@ while (i<=text->undo_pos) { op= text->undo_buf[i]; - if (op==UNDO_CLEFT) { - ops= "Cursor left"; - } - else if (op==UNDO_CRIGHT) { - ops= "Cursor right"; - } - else if (op==UNDO_CUP) { - ops= "Cursor up"; - } - else if (op==UNDO_CDOWN) { - ops= "Cursor down"; - } - else if (op==UNDO_SLEFT) { - ops= "Selection left"; - } - else if (op==UNDO_SRIGHT) { - ops= "Selection right"; - } - else if (op==UNDO_SUP) { - ops= "Selection up"; - } - else if (op==UNDO_SDOWN) { - ops= "Selection down"; - } - else if (op==UNDO_STO) { - ops= "Selection "; - } - else if (op==UNDO_CTO) { - ops= "Cursor "; - } - else if (op==UNDO_INSERT_1) { + if (op==UNDO_INSERT_1) { ops= "Insert ascii "; } else if (op==UNDO_INSERT_2) { @@ -1665,9 +1548,6 @@ else if (op==UNDO_DEL_4) { ops= "Delete unicode "; } - else if (op==UNDO_SWAP) { - ops= "Cursor swap"; - } else if (op==UNDO_DBLOCK) { ops= "Delete text block"; } @@ -1721,29 +1601,6 @@ } } } - else if (op==UNDO_STO || op==UNDO_CTO) { - i++; - - charp= text->undo_buf[i]; i++; - charp= charp+(text->undo_buf[i]<<8); i++; - - linep= text->undo_buf[i]; i++; - linep= linep+(text->undo_buf[i]<<8); i++; - linep= linep+(text->undo_buf[i]<<16); i++; - linep= linep+(text->undo_buf[i]<<24); i++; - - printf ("to <%d, %d> ", linep, charp); - - charp= text->undo_buf[i]; i++; - charp= charp+(text->undo_buf[i]<<8); i++; - - linep= text->undo_buf[i]; i++; - linep= linep+(text->undo_buf[i]<<8); i++; - linep= linep+(text->undo_buf[i]<<16); i++; - linep= linep+(text->undo_buf[i]<<24); i++; - - printf ("from <%d, %d>", linep, charp); - } else if (op==UNDO_DBLOCK || op==UNDO_IBLOCK) { i++; @@ -1794,16 +1651,6 @@ } } -static void txt_undo_add_op(Text *text, int op) -{ - if (!max_undo_test(text, 2)) - return; - - text->undo_pos++; - text->undo_buf[text->undo_pos]= op; - text->undo_buf[text->undo_pos+1]= 0; -} - static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value) { undo_buf[*undo_pos]= (value)&0xff; @@ -1824,17 +1671,41 @@ (*undo_pos)++; } -static void txt_undo_add_block(Text *text, int op, const char *buf) +/* store the cur cursor to the undo buffer */ +static void txt_undo_store_cur(Text *text) { + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->curc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->curl)); +} + +/* store the sel cursor to the undo buffer */ +static void txt_undo_store_sel(Text *text) +{ + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->selc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->sell)); +} + +/* store both cursors to the undo buffer */ +static void txt_undo_store_cursors(Text *text) +{ + txt_undo_store_cur(text); + txt_undo_store_sel(text); +} + +/* store an operator along with a block of data */ +static void txt_undo_add_blockop(Text *text, int op, const char *buf) +{ unsigned int length= strlen(buf); - if (!max_undo_test(text, length+11)) + if (!max_undo_test(text, length + 11 + 12)) return; text->undo_pos++; text->undo_buf[text->undo_pos]= op; text->undo_pos++; + txt_undo_store_cursors(text); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length); strncpy(text->undo_buf+text->undo_pos, buf, length); @@ -1846,34 +1717,30 @@ text->undo_buf[text->undo_pos+1]= 0; } -void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc) +/* store a regular operator */ +void txt_undo_add_op(Text *text, int op) { if (!max_undo_test(text, 15)) return; - if (froml==tol && fromc==toc) return; - text->undo_pos++; text->undo_buf[text->undo_pos]= op; text->undo_pos++; - txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc); - txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml); - txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc); - txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol); + txt_undo_store_cursors(text); text->undo_buf[text->undo_pos]= op; - text->undo_buf[text->undo_pos+1]= 0; } +/* store an operator for a single character */ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) { char utf8[BLI_UTF8_MAX]; size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8); - if (!max_undo_test(text, 3 + utf8_size)) + if (!max_undo_test(text, 3 + utf8_size + 12)) return; text->undo_pos++; @@ -1882,6 +1749,8 @@ text->undo_buf[text->undo_pos]= op_start + utf8_size - 1; text->undo_pos++; + txt_undo_store_cur(text); + for (i = 0; i < utf8_size; i++) { text->undo_buf[text->undo_pos]= utf8[i]; text->undo_pos++; @@ -1892,6 +1761,9 @@ else { text->undo_buf[text->undo_pos]= op_start + 3; text->undo_pos++; + + txt_undo_store_cursors(text); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c); text->undo_buf[text->undo_pos]= op_start + 3; } @@ -1917,6 +1789,29 @@ return val; } +/* read the cur cursor from the undo buffer */ +static void txt_undo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc) +{ + *curln = txt_undo_read_uint32(undo_buf, undo_pos); + *curc = txt_undo_read_uint16(undo_buf, undo_pos); +} + +/* read the sel cursor from the undo buffer */ +static void txt_undo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc) +{ + *selln = txt_undo_read_uint32(undo_buf, undo_pos); + *selc = txt_undo_read_uint16(undo_buf, undo_pos); +} + +/* read both cursors from the undo buffer */ +static void txt_undo_read_cursors(const char *undo_buf, int *undo_pos, + unsigned int *curln, unsigned short *curc, + unsigned int *selln, unsigned short *selc) +{ + txt_undo_read_sel(undo_buf, undo_pos, selln, selc); + txt_undo_read_cur(undo_buf, undo_pos, curln, curc); +} + static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) { unsigned int unicode; @@ -1968,6 +1863,29 @@ return val; } +/* redo read cur cursor from the undo buffer */ +static void txt_redo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc) +{ + *curc = txt_redo_read_uint16(undo_buf, undo_pos); + *curln = txt_redo_read_uint32(undo_buf, undo_pos); +} + +/* redo read sel cursor from the undo buffer */ +static void txt_redo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc) +{ + *selc = txt_redo_read_uint16(undo_buf, undo_pos); + *selln = txt_redo_read_uint32(undo_buf, undo_pos); +} + +/* redo read both cursors from the undo buffer */ +static void txt_redo_read_cursors(const char *undo_buf, int *undo_pos, + unsigned int *curln, unsigned short *curc, + unsigned int *selln, unsigned short *selc) +{ + txt_redo_read_cur(undo_buf, undo_pos, curln, curc); + txt_redo_read_sel(undo_buf, undo_pos, selln, selc); +} + static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) { unsigned int unicode; @@ -2005,9 +1923,10 @@ { int op= text->undo_buf[text->undo_pos]; unsigned int linep, i; + unsigned int uchar; + unsigned int curln, selln; + unsigned short curc, selc; unsigned short charp; - TextLine *holdl; - int holdc, holdln; char *buf; if (text->undo_pos<0) { @@ -2019,124 +1938,92 @@ undoing= 1; switch(op) { - case UNDO_CLEFT: - txt_move_right(text, 0); - break; + case UNDO_INSERT_1: + case UNDO_INSERT_2: + case UNDO_INSERT_3: + case UNDO_INSERT_4: + text->undo_pos-= op - UNDO_INSERT_1 + 1; - case UNDO_CRIGHT: - txt_move_left(text, 0); - break; + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - case UNDO_CUP: - txt_move_down(text, 0); - break; + txt_delete_char(text); - case UNDO_CDOWN: - txt_move_up(text, 0); + text->undo_pos--; break; - - case UNDO_SLEFT: - txt_move_right(text, 1); - break; - - case UNDO_SRIGHT: - txt_move_left(text, 1); - break; - - case UNDO_SUP: - txt_move_down(text, 1); - break; - - case UNDO_SDOWN: - txt_move_up(text, 1); - break; - - case UNDO_CTO: - case UNDO_STO: - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - - text->undo_pos--; - text->undo_pos--; - - linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - charp= txt_undo_read_uint16(text->undo_buf, &text->undo_pos); + // JD: check + case UNDO_BS_1: + case UNDO_BS_2: + case UNDO_BS_3: + case UNDO_BS_4: + charp = op - UNDO_BS_1 + 1; + uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp); - if (op==UNDO_CTO) { - txt_move_toline(text, linep, 0); - text->curc= charp; - txt_pop_sel(text); - } - else { - txt_move_toline(text, linep, 1); - text->selc= charp; - } + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - text->undo_pos--; - break; - - case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: - txt_backspace_char(text); - text->undo_pos-= op - UNDO_INSERT_1 + 1; - text->undo_pos--; - break; + txt_add_char(text, uchar); - case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: - charp = op - UNDO_BS_1 + 1; - txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); text->undo_pos--; break; + case UNDO_DEL_1: + case UNDO_DEL_2: + case UNDO_DEL_3: + case UNDO_DEL_4: + charp = op - UNDO_DEL_1 + 1; + uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp); - case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: - charp = op - UNDO_DEL_1 + 1; - txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + txt_add_char(text, uchar); + txt_move_left(text, 0); + text->undo_pos--; break; - - case UNDO_SWAP: - txt_curs_swap(text); - break; - case UNDO_DBLOCK: - linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - - buf= MEM_mallocN(linep+1, "dblock buffer"); - for (i=0; i < linep; i++) { - buf[(linep-1)-i]= text->undo_buf[text->undo_pos]; + /* length of the string in the buffer */ + linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); + + buf = MEM_mallocN(linep+1, "dblock buffer"); + for (i = 0; i < linep; i++) { + buf[(linep-1)-i] = text->undo_buf[text->undo_pos]; text->undo_pos--; } - buf[i]= 0; + buf[i] = 0; - txt_curs_first(text, &holdl, &holdc); - holdln= txt_get_span(text->lines.first, holdl); - - txt_insert_buf(text, buf); - MEM_freeN(buf); - - text->curl= text->lines.first; - while (holdln>0) { - if (text->curl->next) - text->curl= text->curl->next; - - holdln--; - } - text->curc= holdc; - + /* skip over the length that was stored again */ text->undo_pos--; text->undo_pos--; text->undo_pos--; text->undo_pos--; - + + /* Get the cursor positions */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + + /* move cur to location that needs buff inserted */ + txt_move_to(text, curln, curc, 0); + + txt_insert_buf(text, buf); + MEM_freeN(buf); + + /* restore the cursors */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + text->undo_pos--; - break; case UNDO_IBLOCK: - linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - txt_delete_sel(text); + /* length of the string in the buffer */ + linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); /* txt_backspace_char removes utf8-characters, not bytes */ buf= MEM_mallocN(linep+1, "iblock buffer"); @@ -2144,52 +2031,39 @@ buf[(linep-1)-i]= text->undo_buf[text->undo_pos]; text->undo_pos--; } - buf[i]= 0; - linep= txt_utf8_len(buf); + buf[i] = 0; + linep = txt_utf8_len(buf); MEM_freeN(buf); - - while (linep>0) { - txt_backspace_char(text); - linep--; - } - + + /* skip over the length that was stored again */ text->undo_pos--; text->undo_pos--; - text->undo_pos--; text->undo_pos--; + text->undo_pos--; + /* get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + while (linep>0) { + txt_move_right(text, 1); + linep--; + } + + txt_delete_sel(text); + text->undo_pos--; - break; case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: - linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the end line of the selection + /* get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - //charp is the last char selected or text->line->len - - //set the selection for this now - text->selc = charp; - text->sell = text->lines.first; - for (i= 0; i < linep; i++) { - text->sell = text->sell->next; - } - - linep= txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - //first line to be selected - - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - //first postion to be selected - text->curc = charp; - text->curl = text->lines.first; - for (i = 0; i < linep; i++) { - text->curl = text->curl->next; - } - - if (op==UNDO_INDENT) { txt_unindent(text); } @@ -2202,7 +2076,7 @@ else if (op == UNDO_UNCOMMENT) { txt_comment(text); } - + text->undo_pos--; break; default: @@ -2211,19 +2085,6 @@ break; } - - /* next undo step may need evaluating */ - if (text->undo_pos>=0) { - switch (text->undo_buf[text->undo_pos]) { - case UNDO_STO: - txt_do_undo(text); - txt_do_redo(text); /* selections need restoring */ - break; - case UNDO_SWAP: - txt_do_undo(text); /* swaps should appear transparent */ - break; - } - } undoing= 0; } @@ -2231,9 +2092,12 @@ void txt_do_redo(Text *text) { char op; - unsigned int linep, i; + char *buf; + unsigned int linep; unsigned short charp; - char *buf; + unsigned int uchar; + unsigned int curln, selln; + unsigned short curc, selc; text->undo_pos++; op= text->undo_buf[text->undo_pos]; @@ -2246,149 +2110,116 @@ undoing= 1; switch(op) { - case UNDO_CLEFT: - txt_move_left(text, 0); - break; + case UNDO_INSERT_1: + case UNDO_INSERT_2: + case UNDO_INSERT_3: + case UNDO_INSERT_4: + text->undo_pos++; - case UNDO_CRIGHT: - txt_move_right(text, 0); - break; + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - case UNDO_CUP: - txt_move_up(text, 0); - break; + charp = op - UNDO_INSERT_1 + 1; + uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp); - case UNDO_CDOWN: - txt_move_down(text, 0); + txt_add_char(text, uchar); + break; - - case UNDO_SLEFT: - txt_move_left(text, 1); - break; - - case UNDO_SRIGHT: - txt_move_right(text, 1); - break; - - case UNDO_SUP: - txt_move_up(text, 1); - break; - - case UNDO_SDOWN: - txt_move_down(text, 1); - break; - - case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: + case UNDO_BS_1: + case UNDO_BS_2: + case UNDO_BS_3: + case UNDO_BS_4: text->undo_pos++; - charp = op - UNDO_INSERT_1 + 1; - txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp)); - break; - - case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: - text->undo_pos++; + + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + text->undo_pos+= op - UNDO_BS_1 + 1; + + /* move right so we backspace the correct char */ + txt_move_right(text, 0); txt_backspace_char(text); - text->undo_pos+= op - UNDO_BS_1 + 1; + break; - - case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: + case UNDO_DEL_1: + case UNDO_DEL_2: + case UNDO_DEL_3: + case UNDO_DEL_4: text->undo_pos++; - txt_delete_char(text); + + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + text->undo_pos+= op - UNDO_DEL_1 + 1; - break; - - case UNDO_SWAP: - txt_curs_swap(text); - txt_do_redo(text); /* swaps should appear transparent a*/ - break; - case UNDO_CTO: - case UNDO_STO: - text->undo_pos++; - text->undo_pos++; - - text->undo_pos++; - text->undo_pos++; - text->undo_pos++; - text->undo_pos++; - - text->undo_pos++; - - charp= txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); + txt_delete_char(text); - if (op==UNDO_CTO) { - txt_move_toline(text, linep, 0); - text->curc= charp; - txt_pop_sel(text); - } - else { - txt_move_toline(text, linep, 1); - text->selc= charp; - } - break; - case UNDO_DBLOCK: text->undo_pos++; - linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - txt_delete_sel(text); - text->undo_pos+=linep; + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + + /* length of the block */ + linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); + + text->undo_pos += linep; + /* skip over the length that was stored again */ text->undo_pos++; text->undo_pos++; - text->undo_pos++; text->undo_pos++; + text->undo_pos++; + txt_delete_sel(text); + break; - case UNDO_IBLOCK: text->undo_pos++; - linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + /* length of the block */ + linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); buf= MEM_mallocN(linep+1, "iblock buffer"); - memcpy (buf, &text->undo_buf[text->undo_pos], linep); - text->undo_pos+= linep; + memcpy(buf, &text->undo_buf[text->undo_pos], linep); + + text->undo_pos += linep; buf[linep]= 0; txt_insert_buf(text, buf); MEM_freeN(buf); + /* skip over the length that was stored again */ text->undo_pos++; text->undo_pos++; - text->undo_pos++; text->undo_pos++; + text->undo_pos++; + break; - case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: text->undo_pos++; - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - //charp is the first char selected or 0 - linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the first line of the selection - //set the selcetion for this now - text->curc = charp; - text->curl = text->lines.first; - for (i= 0; i < linep; i++) { - text->curl = text->curl->next; - } + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - //last postion to be selected - - linep= txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //Last line to be selected - - text->selc = charp; - text->sell = text->lines.first; - for (i = 0; i < linep; i++) { - text->sell = text->sell->next; - } - if (op==UNDO_INDENT) { txt_indent(text); } @@ -2401,6 +2232,11 @@ else if (op == UNDO_UNCOMMENT) { txt_uncomment(text); } + + /* re-restore the cursors since they got moved when redoing */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + break; default: //XXX error("Undo buffer error - resetting"); @@ -2708,6 +2544,8 @@ txt_delete_sel(text); + if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); + add_len = BLI_str_utf8_from_unicode(add, ch); mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0); if (mrk) { @@ -2734,7 +2572,6 @@ txt_make_dirty(text); txt_clean_text(text); - if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); return 1; } @@ -2795,8 +2632,8 @@ /* Should probably create a new op for this */ if (!undoing) { + txt_undo_add_charop(text, UNDO_INSERT_1, add); txt_undo_add_charop(text, UNDO_DEL_1, del); - txt_undo_add_charop(text, UNDO_INSERT_1, add); } return 1; } @@ -2865,7 +2702,7 @@ if (!undoing) { - txt_undo_add_toop(text, UNDO_INDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_INDENT); } } @@ -2924,7 +2761,7 @@ if (!undoing) { - txt_undo_add_toop(text, UNDO_UNINDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_UNINDENT); } } @@ -2977,7 +2814,7 @@ if (!undoing) { - txt_undo_add_toop(text, UNDO_COMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_COMMENT); } } @@ -3027,7 +2864,7 @@ if (!undoing) { - txt_undo_add_toop(text, UNDO_UNCOMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_UNCOMMENT); } } Index: blender/source/blender/editors/space_text/text_ops.c =================================================================== --- blender/source/blender/editors/space_text/text_ops.c (revision 45766) +++ blender/source/blender/editors/space_text/text_ops.c (working copy) @@ -1589,7 +1589,7 @@ Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, i, j, max, start, end, endj, chop, loop; + int oldc, i, j, max, start, end, endj, chop, loop; char ch; text_update_character_width(st); @@ -1598,7 +1598,6 @@ else linep = &text->curl, charp = &text->curc; oldc = *charp; - oldl = txt_get_span(text->lines.first, *linep); max = wrap_width(st, ar); @@ -1649,7 +1648,6 @@ } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp); } static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel) @@ -1657,7 +1655,7 @@ Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, i, j, max, start, end, endj, chop, loop; + int oldc, i, j, max, start, end, endj, chop, loop; char ch; text_update_character_width(st); @@ -1666,7 +1664,6 @@ else linep = &text->curl, charp = &text->curc; oldc = *charp; - oldl = txt_get_span(text->lines.first, *linep); max = wrap_width(st, ar); @@ -1715,7 +1712,6 @@ } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp); } static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel) @@ -1723,7 +1719,7 @@ Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, offl, offc, col, newl; + int offl, offc, col, newl; text_update_character_width(st); @@ -1731,8 +1727,7 @@ else linep = &text->curl, charp = &text->curc; /* store previous position */ - oldc = *charp; - newl = oldl = txt_get_span(text->lines.first, *linep); + newl = txt_get_span(text->lines.first, *linep); wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); col = text_get_char_pos(st, (*linep)->line, *charp) + offc; @@ -1753,7 +1748,6 @@ } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, newl, *charp); } static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel) @@ -1761,7 +1755,7 @@ Text *text = st->text; TextLine **linep; int *charp; - int oldl, oldc, offl, offc, col, newl, visible_lines; + int offl, offc, col, newl, visible_lines; text_update_character_width(st); @@ -1769,8 +1763,7 @@ else linep = &text->curl, charp = &text->curc; /* store previous position */ - oldc = *charp; - newl = oldl = txt_get_span(text->lines.first, *linep); + newl = txt_get_span(text->lines.first, *linep); wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc); col = text_get_char_pos(st, (*linep)->line, *charp) + offc; @@ -1789,7 +1782,6 @@ } if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, newl, *charp); } /* Moves the cursor vertically by the specified number of lines. @@ -1801,12 +1793,10 @@ static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int sel) { TextLine **linep; - int oldl, oldc, *charp; + int *charp; if (sel) linep = &text->sell, charp = &text->selc; else linep = &text->curl, charp = &text->curc; - oldl = txt_get_span(text->lines.first, *linep); - oldc = *charp; if (st && ar && st->wordwrap) { int rell, relc; @@ -1829,7 +1819,6 @@ if (*charp > (*linep)->len) *charp = (*linep)->len; if (!sel) txt_pop_sel(text); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, *linep), *charp); } static int text_move_cursor(bContext *C, int type, int select) @@ -2621,7 +2610,6 @@ SpaceText *st = CTX_wm_space_text(C); Text *text = st->text; SetSelection *ssel = op->customdata; - int linep2, charp2; char *buffer; if (txt_has_sel(text)) { @@ -2630,12 +2618,6 @@ MEM_freeN(buffer); } - linep2 = txt_get_span(st->text->lines.first, st->text->sell); - charp2 = st->text->selc; - - if (ssel->sell != linep2 || ssel->selc != charp2) - txt_undo_add_toop(st->text, UNDO_STO, ssel->sell, ssel->selc, linep2, charp2); - text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text); @@ -2711,19 +2693,12 @@ static int text_cursor_set_exec(bContext *C, wmOperator *op) { SpaceText *st = CTX_wm_space_text(C); - Text *text = st->text; ARegion *ar = CTX_wm_region(C); int x = RNA_int_get(op->ptr, "x"); int y = RNA_int_get(op->ptr, "y"); - int oldl, oldc; - oldl = txt_get_span(text->lines.first, text->curl); - oldc = text->curc; - text_cursor_set_to_pos(st, ar, x, y, 0); - txt_undo_add_toop(text, UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, text->curl), text->curc); - text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);