[Bf-blender-cvs] [b8a8059] master: Fix for text editor un-indent undo

Campbell Barton noreply at git.blender.org
Tue Sep 15 19:52:54 CEST 2015


Commit: b8a8059e21d2e28bf79b578d338f518c78a88382
Author: Campbell Barton
Date:   Wed Sep 16 03:30:02 2015 +1000
Branches: master
https://developer.blender.org/rBb8a8059e21d2e28bf79b578d338f518c78a88382

Fix for text editor un-indent undo

Same issue as T44381, re-use logic for indent.

===================================================================

M	source/blender/blenkernel/intern/text.c

===================================================================

diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 8945676..77d6043 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)




More information about the Bf-blender-cvs mailing list