forked from enlightenment/efl
elm_code: add support for redo
Summary: now, elm_code support redo. shortcut is <Ctrl> + <y> Test Plan: 1. elementary_test - Code Editor 2. Check that undo and redo are work correctly. Reviewers: ajwillia.ms Reviewed By: ajwillia.ms Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4642
This commit is contained in:
parent
1b53925b4c
commit
4aee312774
|
@ -1249,7 +1249,7 @@ _elm_code_widget_change_selection_add(Evas_Object *widget)
|
|||
|
||||
change = _elm_code_widget_change_create(selection->start_col,
|
||||
selection->start_line,
|
||||
selection->end_col + 1,
|
||||
selection->end_col,
|
||||
selection->end_line,
|
||||
selection_text,
|
||||
strlen(selection_text),
|
||||
|
@ -1360,8 +1360,8 @@ _elm_code_widget_newline(Elm_Code_Widget *widget)
|
|||
Elm_Code *code;
|
||||
Elm_Code_Line *line;
|
||||
Elm_Code_Widget_Change_Info *change;
|
||||
unsigned int row, col, position, oldlen, width, indent;
|
||||
char *oldtext, *leading;
|
||||
unsigned int row, col, position, oldlen, width, indent, textlen;
|
||||
char *oldtext, *leading, *text;
|
||||
|
||||
_elm_code_widget_change_selection_add(widget);
|
||||
elm_code_widget_selection_delete(widget);
|
||||
|
@ -1394,9 +1394,14 @@ _elm_code_widget_newline(Elm_Code_Widget *widget)
|
|||
efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL);
|
||||
free(leading);
|
||||
|
||||
change = _elm_code_widget_change_create(width + 1, row, indent - 1, row + 1, "\n", 1, EINA_TRUE);
|
||||
textlen = strlen(leading) + 2;
|
||||
text = malloc(sizeof(char) * textlen);
|
||||
snprintf(text, textlen, "\n%s", leading);
|
||||
|
||||
change = _elm_code_widget_change_create(width + 1, row, indent - 1, row + 1, text, strlen(text), EINA_TRUE);
|
||||
_elm_code_widget_undo_change_add(widget, change);
|
||||
_elm_code_widget_change_free(change);
|
||||
free(text);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1479,7 +1484,7 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget)
|
|||
|
||||
efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL);
|
||||
|
||||
change = _elm_code_widget_change_create(start_col, row, end_col, row, text, char_width, EINA_FALSE);
|
||||
change = _elm_code_widget_change_create(start_col, row, end_col - 1, row, text, char_width, EINA_FALSE);
|
||||
_elm_code_widget_undo_change_add(widget, change);
|
||||
_elm_code_widget_change_free(change);
|
||||
}
|
||||
|
@ -1524,7 +1529,7 @@ _elm_code_widget_delete(Elm_Code_Widget *widget)
|
|||
elm_obj_code_widget_cursor_position_set(widget, row, start_col);
|
||||
efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL);
|
||||
|
||||
change = _elm_code_widget_change_create(start_col, row, col, row, text, char_width, EINA_FALSE);
|
||||
change = _elm_code_widget_change_create(start_col, row, col - 1, row, text, char_width, EINA_FALSE);
|
||||
_elm_code_widget_undo_change_add(widget, change);
|
||||
_elm_code_widget_change_free(change);
|
||||
}
|
||||
|
@ -1545,6 +1550,8 @@ _elm_code_widget_control_key_down_cb(Elm_Code_Widget *widget, const char *key)
|
|||
elm_code_widget_selection_paste(widget);
|
||||
else if (!strcmp("x", key))
|
||||
elm_code_widget_selection_cut(widget);
|
||||
else if (!strcmp("y", key))
|
||||
elm_code_widget_redo(widget);
|
||||
else if (!strcmp("z", key))
|
||||
elm_code_widget_undo(widget);
|
||||
}
|
||||
|
|
|
@ -275,6 +275,9 @@ class Elm.Code_Widget (Elm.Layout, Elm.Interface.Atspi.Text)
|
|||
undo {
|
||||
[[Undo last action]]
|
||||
}
|
||||
redo {
|
||||
[[Redo last action]]
|
||||
}
|
||||
}
|
||||
implements {
|
||||
class.constructor;
|
||||
|
|
|
@ -6,6 +6,25 @@
|
|||
|
||||
#include "elm_code_widget_private.h"
|
||||
|
||||
static void
|
||||
_elm_code_widget_undo_prev_clear(Evas_Object *widget)
|
||||
{
|
||||
Elm_Code_Widget_Data *pd;
|
||||
Elm_Code_Widget_Change_Info *info;
|
||||
Eina_List *list;
|
||||
|
||||
pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
|
||||
if (!pd->undo_stack_ptr)
|
||||
return;
|
||||
|
||||
for (list = eina_list_prev(pd->undo_stack_ptr); list; list = eina_list_prev(list))
|
||||
{
|
||||
info = eina_list_data_get(list);
|
||||
free(info->content);
|
||||
free(info);
|
||||
}
|
||||
}
|
||||
|
||||
Elm_Code_Widget_Change_Info *
|
||||
_elm_code_widget_undo_info_copy(Elm_Code_Widget_Change_Info *info)
|
||||
{
|
||||
|
@ -13,8 +32,7 @@ _elm_code_widget_undo_info_copy(Elm_Code_Widget_Change_Info *info)
|
|||
|
||||
copy = calloc(1, sizeof(*info));
|
||||
memcpy(copy, info, sizeof(*info));
|
||||
copy->content = malloc(sizeof(char) * (info->length + 1));
|
||||
strncpy(copy->content, info->content, info->length);
|
||||
copy->content = strndup(info->content, info->length);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
@ -29,6 +47,8 @@ _elm_code_widget_undo_change_add(Evas_Object *widget,
|
|||
info_copy = _elm_code_widget_undo_info_copy(info);
|
||||
pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
|
||||
|
||||
_elm_code_widget_undo_prev_clear(widget);
|
||||
|
||||
pd->undo_stack_ptr = eina_list_prepend(pd->undo_stack_ptr, info_copy);
|
||||
pd->undo_stack = pd->undo_stack_ptr;
|
||||
}
|
||||
|
@ -38,8 +58,9 @@ _elm_code_widget_undo_change(Evas_Object *widget,
|
|||
Elm_Code_Widget_Change_Info *info)
|
||||
{
|
||||
Elm_Code_Widget_Data *pd;
|
||||
unsigned int textlen, position, row, col;
|
||||
unsigned int textlen, position, row, col, newrow, remainlen;
|
||||
short nllen;
|
||||
char *content;
|
||||
Elm_Code_Line *line;
|
||||
pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
|
||||
|
||||
|
@ -51,37 +72,40 @@ _elm_code_widget_undo_change(Evas_Object *widget,
|
|||
}
|
||||
else
|
||||
{
|
||||
newrow = info->start_line;
|
||||
content = info->content;
|
||||
remainlen = info->length;
|
||||
elm_code_widget_selection_clear(widget);
|
||||
elm_code_widget_cursor_position_set(widget, info->start_line, info->start_col);
|
||||
unsigned int newrow = info->start_line;
|
||||
elm_code_widget_cursor_position_set(widget, info->start_line,
|
||||
info->start_col);
|
||||
while (newrow <= info->end_line)
|
||||
{
|
||||
line = elm_code_file_line_get(pd->code->file, newrow);
|
||||
if (newrow != info->end_line)
|
||||
{
|
||||
textlen = info->length;
|
||||
textlen = elm_code_text_newlinenpos(info->content, info->length, &nllen);
|
||||
info->length -= textlen + nllen;
|
||||
textlen = remainlen;
|
||||
textlen = elm_code_text_newlinenpos(content, remainlen,
|
||||
&nllen);
|
||||
remainlen -= textlen + nllen;
|
||||
_elm_code_widget_text_at_cursor_insert_no_undo(widget,
|
||||
info->content,
|
||||
content,
|
||||
textlen);
|
||||
elm_obj_code_widget_cursor_position_get(widget, &row, &col);
|
||||
position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
|
||||
elm_code_line_split_at(line, position);
|
||||
elm_code_widget_cursor_position_set(widget, newrow + 1, 1);
|
||||
info->content += textlen + nllen;
|
||||
content += textlen + nllen;
|
||||
}
|
||||
else
|
||||
{
|
||||
_elm_code_widget_text_at_cursor_insert_no_undo(widget,
|
||||
info->content,
|
||||
info->length);
|
||||
content,
|
||||
strlen(content));
|
||||
}
|
||||
newrow++;
|
||||
}
|
||||
if (info->end_col < 1)
|
||||
info->end_col = 1;
|
||||
elm_code_widget_cursor_position_set(widget, info->end_line, info->end_col);
|
||||
elm_code_widget_cursor_position_set(widget, info->end_line,
|
||||
info->end_col + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,9 +120,31 @@ _elm_code_widget_undo(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd)
|
|||
info = eina_list_data_get(pd->undo_stack_ptr);
|
||||
_elm_code_widget_undo_change(obj, info);
|
||||
|
||||
if (eina_list_next(pd->undo_stack_ptr))
|
||||
pd->undo_stack_ptr = eina_list_next(pd->undo_stack_ptr);
|
||||
else
|
||||
pd->undo_stack_ptr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_code_widget_redo(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd)
|
||||
{
|
||||
Elm_Code_Widget_Change_Info *info, *redo_info;
|
||||
Eina_List *redo_ptr;
|
||||
|
||||
if (pd->undo_stack_ptr)
|
||||
redo_ptr = eina_list_prev(pd->undo_stack_ptr);
|
||||
else
|
||||
redo_ptr = eina_list_last(pd->undo_stack);
|
||||
|
||||
if (!redo_ptr)
|
||||
return;
|
||||
|
||||
info = eina_list_data_get(redo_ptr);
|
||||
redo_info = _elm_code_widget_undo_info_copy(info);
|
||||
redo_info->insert = redo_info->insert ? EINA_FALSE : EINA_TRUE;
|
||||
_elm_code_widget_undo_change(obj, redo_info);
|
||||
|
||||
pd->undo_stack_ptr = redo_ptr;
|
||||
|
||||
free(redo_info->content);
|
||||
free(redo_info);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue