|
@@ -161,13 +161,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
|
|
|
} break;
|
|
|
|
|
|
- case (KEY_Z): { // Simple One level undo
|
|
|
-
|
|
|
+ case (KEY_Z): { // undo / redo
|
|
|
if (editable) {
|
|
|
-
|
|
|
- undo();
|
|
|
+ if (k->get_shift()) {
|
|
|
+ redo();
|
|
|
+ } else {
|
|
|
+ undo();
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
} break;
|
|
|
|
|
|
case (KEY_U): { // Delete from start to cursor
|
|
@@ -175,7 +176,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
if (editable) {
|
|
|
|
|
|
selection_clear();
|
|
|
- undo_text = text;
|
|
|
text = text.substr(cursor_pos, text.length() - cursor_pos);
|
|
|
|
|
|
Ref<Font> font = get_font("font");
|
|
@@ -205,7 +205,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
if (editable) {
|
|
|
|
|
|
selection_clear();
|
|
|
- undo_text = text;
|
|
|
text = text.substr(0, cursor_pos);
|
|
|
_text_changed();
|
|
|
}
|
|
@@ -245,7 +244,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
break;
|
|
|
|
|
|
if (selection.enabled) {
|
|
|
- undo_text = text;
|
|
|
selection_delete();
|
|
|
break;
|
|
|
}
|
|
@@ -276,7 +274,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
set_cursor_position(cc);
|
|
|
|
|
|
} else {
|
|
|
- undo_text = text;
|
|
|
delete_char();
|
|
|
}
|
|
|
|
|
@@ -382,7 +379,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
}
|
|
|
|
|
|
if (selection.enabled) {
|
|
|
- undo_text = text;
|
|
|
selection_delete();
|
|
|
break;
|
|
|
}
|
|
@@ -417,7 +413,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
|
|
delete_text(cursor_pos, cc);
|
|
|
|
|
|
} else {
|
|
|
- undo_text = text;
|
|
|
set_cursor_position(cursor_pos + 1);
|
|
|
delete_char();
|
|
|
}
|
|
@@ -778,7 +773,6 @@ void LineEdit::copy_text() {
|
|
|
void LineEdit::cut_text() {
|
|
|
|
|
|
if (selection.enabled) {
|
|
|
- undo_text = text;
|
|
|
OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
|
|
|
selection_delete();
|
|
|
}
|
|
@@ -798,23 +792,33 @@ void LineEdit::paste_text() {
|
|
|
}
|
|
|
|
|
|
void LineEdit::undo() {
|
|
|
-
|
|
|
- int old_cursor_pos = cursor_pos;
|
|
|
- text = undo_text;
|
|
|
-
|
|
|
- Ref<Font> font = get_font("font");
|
|
|
-
|
|
|
- cached_width = 0;
|
|
|
- for (int i = 0; i < text.length(); i++)
|
|
|
- cached_width += font->get_char_size(text[i]).width;
|
|
|
-
|
|
|
- if (old_cursor_pos > text.length()) {
|
|
|
- set_cursor_position(text.length());
|
|
|
- } else {
|
|
|
- set_cursor_position(old_cursor_pos);
|
|
|
+ if (undo_stack_pos == NULL) {
|
|
|
+ if (undo_stack.size() <= 1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ undo_stack_pos = undo_stack.back();
|
|
|
+ } else if (undo_stack_pos == undo_stack.front()) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ undo_stack_pos = undo_stack_pos->prev();
|
|
|
+ TextOperation op = undo_stack_pos->get();
|
|
|
+ text = op.text;
|
|
|
+ set_cursor_position(op.cursor_pos);
|
|
|
+ _emit_text_change();
|
|
|
+}
|
|
|
|
|
|
- _text_changed();
|
|
|
+void LineEdit::redo() {
|
|
|
+ if (undo_stack_pos == NULL) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (undo_stack_pos == undo_stack.back()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ undo_stack_pos = undo_stack_pos->next();
|
|
|
+ TextOperation op = undo_stack_pos->get();
|
|
|
+ text = op.text;
|
|
|
+ set_cursor_position(op.cursor_pos);
|
|
|
+ _emit_text_change();
|
|
|
}
|
|
|
|
|
|
void LineEdit::shift_selection_check_pre(bool p_shift) {
|
|
@@ -947,8 +951,6 @@ void LineEdit::delete_char() {
|
|
|
|
|
|
void LineEdit::delete_text(int p_from_column, int p_to_column) {
|
|
|
|
|
|
- undo_text = text;
|
|
|
-
|
|
|
if (text.size() > 0) {
|
|
|
Ref<Font> font = get_font("font");
|
|
|
if (font != NULL) {
|
|
@@ -1086,8 +1088,6 @@ void LineEdit::append_at_cursor(String p_text) {
|
|
|
|
|
|
if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) {
|
|
|
|
|
|
- undo_text = text;
|
|
|
-
|
|
|
Ref<Font> font = get_font("font");
|
|
|
if (font != NULL) {
|
|
|
for (int i = 0; i < p_text.length(); i++)
|
|
@@ -1105,6 +1105,7 @@ void LineEdit::append_at_cursor(String p_text) {
|
|
|
|
|
|
void LineEdit::clear_internal() {
|
|
|
|
|
|
+ _clear_undo_stack();
|
|
|
cached_width = 0;
|
|
|
cursor_pos = 0;
|
|
|
window_pos = 0;
|
|
@@ -1275,6 +1276,11 @@ void LineEdit::menu_option(int p_option) {
|
|
|
undo();
|
|
|
}
|
|
|
} break;
|
|
|
+ case MENU_REDO: {
|
|
|
+ if (editable) {
|
|
|
+ redo();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1312,10 +1318,43 @@ void LineEdit::_text_changed() {
|
|
|
if (expand_to_text_length)
|
|
|
minimum_size_changed();
|
|
|
|
|
|
+ _emit_text_change();
|
|
|
+ _clear_redo();
|
|
|
+}
|
|
|
+
|
|
|
+void LineEdit::_emit_text_change() {
|
|
|
emit_signal("text_changed", text);
|
|
|
_change_notify("text");
|
|
|
}
|
|
|
|
|
|
+void LineEdit::_clear_redo() {
|
|
|
+ _create_undo_state();
|
|
|
+ if (undo_stack_pos == NULL) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ undo_stack_pos = undo_stack_pos->next();
|
|
|
+ while (undo_stack_pos) {
|
|
|
+ List<TextOperation>::Element *elem = undo_stack_pos;
|
|
|
+ undo_stack_pos = undo_stack_pos->next();
|
|
|
+ undo_stack.erase(elem);
|
|
|
+ }
|
|
|
+ _create_undo_state();
|
|
|
+}
|
|
|
+
|
|
|
+void LineEdit::_clear_undo_stack() {
|
|
|
+ undo_stack.clear();
|
|
|
+ undo_stack_pos = NULL;
|
|
|
+ _create_undo_state();
|
|
|
+}
|
|
|
+
|
|
|
+void LineEdit::_create_undo_state() {
|
|
|
+ TextOperation op;
|
|
|
+ op.text = text;
|
|
|
+ op.cursor_pos = cursor_pos;
|
|
|
+ undo_stack.push_back(op);
|
|
|
+}
|
|
|
+
|
|
|
void LineEdit::_bind_methods() {
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &LineEdit::_toggle_draw_caret);
|
|
@@ -1369,6 +1408,7 @@ void LineEdit::_bind_methods() {
|
|
|
BIND_ENUM_CONSTANT(MENU_CLEAR);
|
|
|
BIND_ENUM_CONSTANT(MENU_SELECT_ALL);
|
|
|
BIND_ENUM_CONSTANT(MENU_UNDO);
|
|
|
+ BIND_ENUM_CONSTANT(MENU_REDO);
|
|
|
BIND_ENUM_CONSTANT(MENU_MAX);
|
|
|
|
|
|
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
|
|
@@ -1388,6 +1428,8 @@ void LineEdit::_bind_methods() {
|
|
|
|
|
|
LineEdit::LineEdit() {
|
|
|
|
|
|
+ undo_stack_pos = NULL;
|
|
|
+ _create_undo_state();
|
|
|
align = ALIGN_LEFT;
|
|
|
cached_width = 0;
|
|
|
cursor_pos = 0;
|
|
@@ -1421,6 +1463,7 @@ LineEdit::LineEdit() {
|
|
|
menu->add_item(TTR("Clear"), MENU_CLEAR);
|
|
|
menu->add_separator();
|
|
|
menu->add_item(TTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
|
|
|
+ menu->add_item(TTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
|
|
|
menu->connect("id_pressed", this, "menu_option");
|
|
|
expand_to_text_length = false;
|
|
|
}
|