Browse Source

Fix so undoing complex operations in TextEdit will restore selections.

Sofox 1 year ago
parent
commit
4b82cacc21
2 changed files with 64 additions and 2 deletions
  1. 10 2
      scene/gui/text_edit.cpp
  2. 54 0
      tests/scene/test_text_edit.h

+ 10 - 2
scene/gui/text_edit.cpp

@@ -7690,7 +7690,11 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r
 	op.version = ++version;
 	op.chain_forward = false;
 	op.chain_backward = false;
-	op.start_carets = carets;
+	if (next_operation_is_complex) {
+		op.start_carets = current_op.start_carets;
+	} else {
+		op.start_carets = carets;
+	}
 	op.end_carets = carets;
 
 	// See if it should just be set as current op.
@@ -7745,7 +7749,11 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
 	op.version = ++version;
 	op.chain_forward = false;
 	op.chain_backward = false;
-	op.start_carets = carets;
+	if (next_operation_is_complex) {
+		op.start_carets = current_op.start_carets;
+	} else {
+		op.start_carets = carets;
+	}
 	op.end_carets = carets;
 
 	// See if it should just be set as current op.

+ 54 - 0
tests/scene/test_text_edit.h

@@ -3186,6 +3186,60 @@ TEST_CASE("[SceneTree][TextEdit] versioning") {
 	CHECK(text_edit->get_version() == 3); // Should this be cleared?
 	CHECK(text_edit->get_saved_version() == 0);
 
+	SUBCASE("[TextEdit] versioning selection") {
+		text_edit->set_text("Godot Engine\nWaiting for Godot\nTest Text for multi carat\nLine 4 Text");
+		text_edit->set_multiple_carets_enabled(true);
+
+		text_edit->remove_secondary_carets();
+		text_edit->deselect();
+		text_edit->set_caret_line(0);
+		text_edit->set_caret_column(0);
+
+		CHECK(text_edit->get_caret_count() == 1);
+
+		Array caret_index;
+		caret_index.push_back(0);
+
+		for (int i = 1; i < 4; i++) {
+			caret_index.push_back(text_edit->add_caret(i, 0));
+			CHECK((int)caret_index.back() >= 0);
+		}
+
+		CHECK(text_edit->get_caret_count() == 4);
+
+		for (int i = 0; i < 4; i++) {
+			text_edit->select(i, 0, i, 5, caret_index[i]);
+		}
+
+		CHECK(text_edit->get_caret_count() == 4);
+		for (int i = 0; i < 4; i++) {
+			CHECK(text_edit->has_selection(caret_index[i]));
+			CHECK(text_edit->get_selection_from_line(caret_index[i]) == i);
+			CHECK(text_edit->get_selection_from_column(caret_index[i]) == 0);
+			CHECK(text_edit->get_selection_to_line(caret_index[i]) == i);
+			CHECK(text_edit->get_selection_to_column(caret_index[i]) == 5);
+		}
+		text_edit->begin_complex_operation();
+		text_edit->deselect();
+		text_edit->set_text("New Line Text");
+		text_edit->select(0, 0, 0, 7, 0);
+		text_edit->end_complex_operation();
+
+		CHECK(text_edit->get_caret_count() == 1);
+		CHECK(text_edit->get_selected_text(0) == "New Lin");
+
+		text_edit->undo();
+
+		CHECK(text_edit->get_caret_count() == 4);
+		for (int i = 0; i < 4; i++) {
+			CHECK(text_edit->has_selection(caret_index[i]));
+			CHECK(text_edit->get_selection_from_line(caret_index[i]) == i);
+			CHECK(text_edit->get_selection_from_column(caret_index[i]) == 0);
+			CHECK(text_edit->get_selection_to_line(caret_index[i]) == i);
+			CHECK(text_edit->get_selection_to_column(caret_index[i]) == 5);
+		}
+	}
+
 	memdelete(text_edit);
 }