From 4b82cacc219266cdb16c59f037766e1fc8d25d47 Mon Sep 17 00:00:00 2001 From: Sofox Date: Wed, 13 Dec 2023 13:38:20 +0000 Subject: [PATCH] Fix so undoing complex operations in TextEdit will restore selections. --- scene/gui/text_edit.cpp | 12 ++++++-- tests/scene/test_text_edit.h | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 308250c592e1..cd1450b8798b 100644 --- a/scene/gui/text_edit.cpp +++ b/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. diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index e81578a8628f..8f603c698daf 100644 --- a/tests/scene/test_text_edit.h +++ b/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); }