Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-09-15 20:30:02 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-09-15 20:35:25 +0300
commitb8a8059e21d2e28bf79b578d338f518c78a88382 (patch)
treecb98dded2e2a7ac9a3855c5a2e4833de971b853f
parent860e25fe29c3f6732860c23dccb1f4813d4e387e (diff)
Fix for text editor un-indent undo
Same issue as T44381, re-use logic for indent.
-rw-r--r--source/blender/blenkernel/intern/text.c226
1 files changed, 99 insertions, 127 deletions
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 89456763b95..77d6043d6f3 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -1914,9 +1914,13 @@ struct LinkInt {
int value;
};
-/* unindentLines points to a ListBase composed of LinkInt elements, listing the numbers
- * of the lines that should not be indented back. */
-static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask, const int line_index_mask_len)
+/**
+ * UnindentLines points to a #ListBase composed of #LinkInt elements, listing the numbers
+ * of the lines that should not be indented back.
+ */
+static void txt_undo_add_unprefix_op(
+ Text *text, char undo_op,
+ const ListBase *line_index_mask, const int line_index_mask_len)
{
struct LinkInt *idata;
@@ -1929,7 +1933,7 @@ static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask
/* Opening buffer sequence with OP */
text->undo_pos++;
- text->undo_buf[text->undo_pos] = UNDO_UNINDENT;
+ text->undo_buf[text->undo_pos] = undo_op;
text->undo_pos++;
/* Adding number of line numbers to read */
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, line_index_mask_len);
@@ -1944,7 +1948,7 @@ static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask
/* Adding current selection */
txt_undo_store_cursors(text);
/* Closing with OP (same as above) */
- text->undo_buf[text->undo_pos] = UNDO_UNINDENT;
+ text->undo_buf[text->undo_pos] = undo_op;
/* Marking as last undo operation */
text->undo_buf[text->undo_pos + 1] = 0;
}
@@ -2244,7 +2248,6 @@ void txt_do_undo(Text *text)
break;
case UNDO_INDENT:
case UNDO_COMMENT:
- case UNDO_UNCOMMENT:
case UNDO_DUPLICATE:
case UNDO_MOVE_LINES_UP:
case UNDO_MOVE_LINES_DOWN:
@@ -2259,9 +2262,6 @@ void txt_do_undo(Text *text)
else if (op == UNDO_COMMENT) {
txt_uncomment(text);
}
- else if (op == UNDO_UNCOMMENT) {
- txt_comment(text);
- }
else if (op == UNDO_DUPLICATE) {
txt_delete_line(text, text->curl->next);
}
@@ -2275,7 +2275,10 @@ void txt_do_undo(Text *text)
text->undo_pos--;
break;
case UNDO_UNINDENT:
+ case UNDO_UNCOMMENT:
{
+ void (*txt_prefix_fn)(Text *);
+ void (*txt_unprefix_fn)(Text *);
int count;
int i;
/* Get and restore the cursors */
@@ -2284,7 +2287,16 @@ void txt_do_undo(Text *text)
txt_move_to(text, selln, selc, 1);
/* Un-unindent */
- txt_indent(text);
+ if (op == UNDO_UNINDENT) {
+ txt_prefix_fn = txt_indent;
+ txt_unprefix_fn = txt_unindent;
+ }
+ else {
+ txt_prefix_fn = txt_comment;
+ txt_unprefix_fn = txt_uncomment;
+ }
+
+ txt_prefix_fn(text);
/* Get the count */
count = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
@@ -2293,8 +2305,8 @@ void txt_do_undo(Text *text)
for (i = 0; i < count; i++) {
txt_move_to(text, txt_undo_read_uint32(text->undo_buf, &text->undo_pos), 0, 0);
- /* Un-un-unindent */
- txt_unindent(text);
+ /* Un-un-unindent/comment */
+ txt_unprefix_fn(text);
}
/* Restore selection */
txt_move_to(text, curln, curc, 0);
@@ -2823,26 +2835,19 @@ bool txt_replace_char(Text *text, unsigned int add)
return true;
}
-void txt_indent(Text *text)
+/**
+ * Generic prefix operation, use for comment & indent.
+ *
+ * \note caller must handle undo.
+ */
+static void txt_select_prefix(Text *text, const char *add)
{
int len, num, curc_old;
char *tmp;
- const char *add = "\t";
- int indentlen = 1;
-
- /* hardcoded: TXT_TABSIZE = 4 spaces: */
- int spaceslen = TXT_TABSIZE;
+ const int indentlen = strlen(add);
- if (ELEM(NULL, text->curl, text->sell)) {
- return;
- }
-
- /* insert spaces rather than tabs */
- if (text->flags & TXT_TABSTOSPACES) {
- add = tab_to_spaces;
- indentlen = spaceslen;
- }
+ BLI_assert(!ELEM(NULL, text->curl, text->sell));
curc_old = text->curc;
@@ -2886,36 +2891,31 @@ void txt_indent(Text *text)
num--;
}
- if (!undoing) {
- txt_undo_add_op(text, UNDO_INDENT);
- }
+ /* caller must handle undo */
}
-void txt_unindent(Text *text)
+/**
+ * Generic un-prefix operation, use for comment & indent.
+ *
+ * \param r_line_index_mask: List of lines that are already at indent level 0,
+ * to store them later into the undo buffer.
+ *
+ * \note caller must handle undo.
+ */
+static void txt_select_unprefix(
+ Text *text, const char *remove,
+ ListBase *r_line_index_mask, int *r_line_index_mask_len)
{
int num = 0;
- const char *remove = "\t";
- int indentlen = 1;
+ const int indentlen = strlen(remove);
bool unindented_first = false;
-
- /* List of lines that are already at indent level 0, to store them later into the undo buffer */
- ListBase line_index_mask = {NULL, NULL};
- int line_index_mask_len = 0;
- int curl_span_init = 0;
-
- /* hardcoded: TXT_TABSIZE = 4 spaces: */
- int spaceslen = TXT_TABSIZE;
+ int curl_span_init = 0;
- if (ELEM(NULL, text->curl, text->sell)) {
- return;
- }
+ BLI_assert(!ELEM(NULL, text->curl, text->sell));
- /* insert spaces rather than tabs */
- if (text->flags & TXT_TABSTOSPACES) {
- remove = tab_to_spaces;
- indentlen = spaceslen;
- }
+ BLI_listbase_clear(r_line_index_mask);
+ *r_line_index_mask_len = 0;
if (!undoing) {
curl_span_init = txt_get_span(text->lines.first, text->curl);
@@ -2936,8 +2936,8 @@ void txt_unindent(Text *text)
struct LinkInt *idata = MEM_mallocN(sizeof(struct LinkInt), __func__);
idata->value = curl_span_init + num;
BLI_assert(idata->value == txt_get_span(text->lines.first, text->curl));
- BLI_addtail(&line_index_mask, idata);
- line_index_mask_len += 1;
+ BLI_addtail(r_line_index_mask, idata);
+ (*r_line_index_mask_len) += 1;
}
}
@@ -2964,57 +2964,20 @@ void txt_unindent(Text *text)
text->curl = text->curl->prev;
num--;
}
-
- if (!undoing) {
- txt_undo_add_unindent_op(text, &line_index_mask, line_index_mask_len);
- }
- BLI_freelistN(&line_index_mask);
+ /* caller must handle undo */
}
void txt_comment(Text *text)
{
- int len, num;
- char *tmp;
- char add = '#';
+ const char *prefix = "#";
- if (!text->curl) return;
- if (!text->sell) return; // Need to change this need to check if only one line is selected to more than one
+ if (ELEM(NULL, text->curl, text->sell)) {
+ return;
+ }
- num = 0;
- while (true) {
- tmp = MEM_mallocN(text->curl->len + 2, "textline_string");
-
- text->curc = 0;
- if (text->curc) memcpy(tmp, text->curl->line, text->curc);
- tmp[text->curc] = add;
-
- len = text->curl->len - text->curc;
- if (len > 0) memcpy(tmp + text->curc + 1, text->curl->line + text->curc, len);
- tmp[text->curl->len + 1] = 0;
+ txt_select_prefix(text, prefix);
- make_new_line(text->curl, tmp);
-
- text->curc++;
-
- txt_make_dirty(text);
- txt_clean_text(text);
-
- if (text->curl == text->sell) {
- text->selc = text->sell->len;
- break;
- }
- else {
- text->curl = text->curl->next;
- num++;
- }
- }
- text->curc = 0;
- while (num > 0) {
- text->curl = text->curl->prev;
- num--;
- }
-
if (!undoing) {
txt_undo_add_op(text, UNDO_COMMENT);
}
@@ -3022,46 +2985,55 @@ void txt_comment(Text *text)
void txt_uncomment(Text *text)
{
- int num = 0;
- char remove = '#';
+ const char *prefix = "#";
+ ListBase line_index_mask;
+ int line_index_mask_len;
- if (!text->curl) return;
- if (!text->sell) return;
+ if (ELEM(NULL, text->curl, text->sell)) {
+ return;
+ }
- while (true) {
- int i = 0;
-
- if (text->curl->line[i] == remove) {
- while (i < text->curl->len) {
- text->curl->line[i] = text->curl->line[i + 1];
- i++;
- }
- text->curl->len--;
- }
-
-
- txt_make_dirty(text);
- txt_clean_text(text);
-
- if (text->curl == text->sell) {
- text->selc = text->sell->len;
- break;
- }
- else {
- text->curl = text->curl->next;
- num++;
- }
-
+ txt_select_unprefix(text, prefix, &line_index_mask, &line_index_mask_len);
+
+ if (!undoing) {
+ txt_undo_add_unprefix_op(text, UNDO_UNCOMMENT, &line_index_mask, line_index_mask_len);
}
- text->curc = 0;
- while (num > 0) {
- text->curl = text->curl->prev;
- num--;
+
+ BLI_freelistN(&line_index_mask);
+}
+
+void txt_indent(Text *text)
+{
+ const char *prefix = (text->flags & TXT_TABSTOSPACES) ? tab_to_spaces : "\t";
+
+ if (ELEM(NULL, text->curl, text->sell)) {
+ return;
}
+
+ txt_select_prefix(text, prefix);
+
+ if (!undoing) {
+ txt_undo_add_op(text, UNDO_INDENT);
+ }
+}
+
+void txt_unindent(Text *text)
+{
+ const char *prefix = (text->flags & TXT_TABSTOSPACES) ? tab_to_spaces : "\t";
+ ListBase line_index_mask;
+ int line_index_mask_len;
+ if (ELEM(NULL, text->curl, text->sell)) {
+ return;
+ }
+
+ txt_select_unprefix(text, prefix, &line_index_mask, &line_index_mask_len);
+
if (!undoing) {
- txt_undo_add_op(text, UNDO_UNCOMMENT);
+ txt_undo_add_unprefix_op(text, UNDO_UNINDENT, &line_index_mask, line_index_mask_len);
}
+
+ BLI_freelistN(&line_index_mask);
}
void txt_move_lines(struct Text *text, const int direction)