ajwillia-ms pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=4aee312774df7446eecc9bcfd15ce98ea568f815

commit 4aee312774df7446eecc9bcfd15ce98ea568f815
Author: YeongJong Lee <[email protected]>
Date:   Thu Feb 2 18:07:02 2017 +0000

    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
---
 src/lib/elementary/elm_code_widget.c      | 19 ++++---
 src/lib/elementary/elm_code_widget.eo     |  3 ++
 src/lib/elementary/elm_code_widget_undo.c | 82 ++++++++++++++++++++++++-------
 3 files changed, 80 insertions(+), 24 deletions(-)

diff --git a/src/lib/elementary/elm_code_widget.c 
b/src/lib/elementary/elm_code_widget.c
index 199d19a..349551b 100644
--- a/src/lib/elementary/elm_code_widget.c
+++ b/src/lib/elementary/elm_code_widget.c
@@ -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);
 }
diff --git a/src/lib/elementary/elm_code_widget.eo 
b/src/lib/elementary/elm_code_widget.eo
index f6bf6f4..49a2ad8 100644
--- a/src/lib/elementary/elm_code_widget.eo
+++ b/src/lib/elementary/elm_code_widget.eo
@@ -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;
diff --git a/src/lib/elementary/elm_code_widget_undo.c 
b/src/lib/elementary/elm_code_widget_undo.c
index ed0b8f2..5da08d1 100644
--- a/src/lib/elementary/elm_code_widget_undo.c
+++ b/src/lib/elementary/elm_code_widget_undo.c
@@ -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);
+   pd->undo_stack_ptr = eina_list_next(pd->undo_stack_ptr);
+}
+
+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
-     pd->undo_stack_ptr = NULL;
+     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);
 }
 

-- 


Reply via email to