1
0
Fork 0
This commit is contained in:
Alexander Nadeau 2025-02-28 01:36:01 +01:00 committed by GitHub
commit 730d867e75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 91 additions and 2 deletions

View File

@ -539,6 +539,12 @@
[b]Note:[/b] The Y position corresponds to the bottom side of the line. Use [method get_rect_at_line_column] to get the top side position.
</description>
</method>
<method name="get_prev_version" qualifiers="const">
<return type="int" />
<description>
Returns the version number of the undo/redo state that will be applied if an undo is performed.
</description>
</method>
<method name="get_rect_at_line_column" qualifiers="const">
<return type="Rect2i" />
<param index="0" name="line" type="int" />
@ -548,6 +554,12 @@
[b]Note:[/b] The Y position of the returned rect corresponds to the top side of the line, unlike [method get_pos_at_line_column] which returns the bottom side.
</description>
</method>
<method name="get_redo_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of available "redo" actions in the undo/redo history.
</description>
</method>
<method name="get_saved_version" qualifiers="const">
<return type="int" />
<description>
@ -668,6 +680,12 @@
Returns the total number of lines in the text. This includes wrapped lines and excludes folded lines. If [member wrap_mode] is set to [constant LINE_WRAPPING_NONE] and no lines are folded (see [method CodeEdit.is_line_folded]) then this is equivalent to [method get_line_count]. See [method get_visible_line_count_in_range] for a limited range of lines.
</description>
</method>
<method name="get_undo_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of available "undo" actions in the undo/redo history.
</description>
</method>
<method name="get_v_scroll_bar" qualifiers="const">
<return type="VScrollBar" />
<description>
@ -677,7 +695,7 @@
<method name="get_version" qualifiers="const">
<return type="int" />
<description>
Returns the current version of the [TextEdit]. The version is a count of recorded operations by the undo/redo history.
Returns the current version of the [TextEdit]. Different undo/redo history states have different, increasing version numbers.
</description>
</method>
<method name="get_visible_line_count" qualifiers="const">
@ -1430,6 +1448,13 @@
When text is added [param from_line] will be less than [param to_line]. On a remove [param to_line] will be less than [param from_line].
</description>
</signal>
<signal name="operation_done">
<param index="0" name="from_line" type="int" />
<param index="1" name="to_line" type="int" />
<description>
Emitted when the text changes and a new undo operation has been created for the change.
</description>
</signal>
<signal name="text_changed">
<description>
Emitted when the text changes.

View File

@ -4117,10 +4117,24 @@ void TextEdit::end_complex_operation() {
undo_stack.back()->get().end_carets = carets;
if (undo_stack.back()->get().chain_forward) {
undo_stack.back()->get().chain_forward = false;
emit_signal(SNAME("operation_done"), undo_stack.back()->get().from_line, undo_stack.back()->get().to_line);
return;
}
undo_stack.back()->get().chain_backward = true;
int min_line = undo_stack.back()->get().from_line;
int max_line = undo_stack.back()->get().to_line;
List<TextOperation>::Element *op = undo_stack.back();
op->get().chain_backward = true;
while (op) {
min_line = MIN(min_line, op->get().from_line);
max_line = MIN(max_line, op->get().to_line);
if (op->get().chain_forward) {
break;
}
op = op->prev();
}
emit_signal(SNAME("operation_done"), min_line, max_line);
}
bool TextEdit::has_undo() const {
@ -4135,6 +4149,41 @@ bool TextEdit::has_redo() const {
return undo_stack_pos != nullptr;
}
int TextEdit::get_undo_count() const {
if (undo_stack_pos == nullptr) {
int pending = current_op.type == TextOperation::TYPE_NONE ? 0 : 1;
return undo_stack.size() + pending;
}
return undo_stack.size() - undo_stack_idx;
}
int TextEdit::get_redo_count() const {
return undo_stack_idx;
}
int TextEdit::get_prev_version() const {
if (undo_stack.is_empty()) {
return -1;
}
if (current_op.type != TextOperation::TYPE_NONE) {
return current_op.prev_version;
}
const List<TextOperation>::Element *pos = undo_stack_pos;
if (pos == nullptr) {
pos = undo_stack.back();
} else {
pos = pos->prev();
}
if (pos == nullptr) {
return -1;
}
if (pos->get().chain_backward) {
while (pos && !pos->get().chain_forward) {
pos = pos->prev();
}
}
return pos ? pos->get().prev_version : -5;
}
void TextEdit::undo() {
if (!editable) {
return;
@ -4151,11 +4200,13 @@ void TextEdit::undo() {
}
undo_stack_pos = undo_stack.back();
undo_stack_idx = 1;
} else if (undo_stack_pos == undo_stack.front()) {
return; // At the bottom of the undo stack.
} else {
undo_stack_pos = undo_stack_pos->prev();
undo_stack_idx += 1;
}
deselect();
@ -4169,6 +4220,7 @@ void TextEdit::undo() {
while (true) {
ERR_BREAK(!undo_stack_pos->prev());
undo_stack_pos = undo_stack_pos->prev();
undo_stack_idx += 1;
op = undo_stack_pos->get();
_do_text_op(op, true);
current_op.version = op.prev_version;
@ -4224,6 +4276,7 @@ void TextEdit::redo() {
while (true) {
ERR_BREAK(!undo_stack_pos->next());
undo_stack_pos = undo_stack_pos->next();
undo_stack_idx -= 1;
op = undo_stack_pos->get();
_do_text_op(op, false);
current_op.version = op.version;
@ -4246,6 +4299,7 @@ void TextEdit::redo() {
carets = undo_stack_pos->get().end_carets;
undo_stack_pos = undo_stack_pos->next();
undo_stack_idx -= 1;
_unhide_carets();
@ -4260,6 +4314,7 @@ void TextEdit::clear_undo_history() {
saved_version = 0;
current_op.type = TextOperation::TYPE_NONE;
undo_stack_pos = nullptr;
undo_stack_idx = 0;
undo_stack.clear();
}
@ -6662,6 +6717,9 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_undo"), &TextEdit::has_undo);
ClassDB::bind_method(D_METHOD("has_redo"), &TextEdit::has_redo);
ClassDB::bind_method(D_METHOD("get_undo_count"), &TextEdit::get_undo_count);
ClassDB::bind_method(D_METHOD("get_redo_count"), &TextEdit::get_redo_count);
ClassDB::bind_method(D_METHOD("get_prev_version"), &TextEdit::get_prev_version);
ClassDB::bind_method(D_METHOD("undo"), &TextEdit::undo);
ClassDB::bind_method(D_METHOD("redo"), &TextEdit::redo);
ClassDB::bind_method(D_METHOD("clear_undo_history"), &TextEdit::clear_undo_history);
@ -7013,6 +7071,7 @@ void TextEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("text_set"));
ADD_SIGNAL(MethodInfo("text_changed"));
ADD_SIGNAL(MethodInfo("lines_edited_from", PropertyInfo(Variant::INT, "from_line"), PropertyInfo(Variant::INT, "to_line")));
ADD_SIGNAL(MethodInfo("operation_done", PropertyInfo(Variant::INT, "from_line"), PropertyInfo(Variant::INT, "to_line")));
/* Caret. */
ADD_SIGNAL(MethodInfo("caret_changed"));
@ -7543,6 +7602,7 @@ void TextEdit::_clear_redo() {
undo_stack_pos = undo_stack_pos->next();
undo_stack.erase(elem);
}
undo_stack_idx = 0;
}
/* Search */

View File

@ -372,6 +372,7 @@ private:
TextOperation current_op;
List<TextOperation> undo_stack;
List<TextOperation>::Element *undo_stack_pos = nullptr;
size_t undo_stack_idx = 0; // number of elements away from top undo_stack_pos is
Timer *idle_detect = nullptr;
@ -844,6 +845,9 @@ public:
bool has_undo() const;
bool has_redo() const;
int get_undo_count() const;
int get_redo_count() const;
int get_prev_version() const;
void undo();
void redo();
void clear_undo_history();