nikawhite pushed a commit to branch master.

http://git.enlightenment.org/tools/enventor.git/commit/?id=6aea530622577b3686a7066a1d99422d2f713681

commit 6aea530622577b3686a7066a1d99422d2f713681
Author: Mykyta Biliavskyi <m.biliavs...@samsung.com>
Date:   Thu Dec 10 10:53:12 2015 +0900

    Text settings: Add analysis typed text for redoundo feature.
    
    Added cases:
        Analyse auto indention for new lines. It mean, that redo/undo
                line creation will finished by one step.
        Analyse input symbols speed. In case when user writes somethenigi
                and takes a short delay (by default 0.8sec)
                between written symbols - redo/undo action will use this delay
                as point to create new node in redo/undo queue.
        Analyse input symbols on a "words". Ongoing alphabetic symbols
                between nonalphabetic symbols known as
                "word". Redo/undo action will use for a step a whole "word".
    
    In text setting added addition toggle named "Smart undo/redo".
    By default this feature is disabled.
    
    Todo: make this feature work with auto intendation.
    
    Prortotype here: https://phab.enlightenment.org/D1288
---
 src/bin/config_data.c      | 18 +++++++++++
 src/bin/main.c             |  1 +
 src/bin/text_setting.c     | 15 +++++++++-
 src/include/config_data.h  |  2 ++
 src/include/text_setting.h |  2 ++
 src/lib/edc_editor.c       | 16 ++++++++++
 src/lib/enventor_object.eo |  9 ++++++
 src/lib/enventor_private.h |  3 ++
 src/lib/enventor_smart.c   | 13 ++++++++
 src/lib/redoundo.c         | 74 +++++++++++++++++++++++++++++++++++++++++++++-
 10 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/src/bin/config_data.c b/src/bin/config_data.c
index 3205b27..15327a9 100644
--- a/src/bin/config_data.c
+++ b/src/bin/config_data.c
@@ -38,6 +38,7 @@ typedef struct config_s
    Eina_Bool console;
    Eina_Bool auto_complete;
    Eina_Bool view_size_configurable;
+   Eina_Bool smart_undo_redo;
 } config_data;
 
 static config_data *g_cd = NULL;
@@ -178,6 +179,7 @@ config_load(void)
         cd->auto_complete = EINA_TRUE;
         cd->view_size_configurable = EINA_FALSE;
         cd->version = ENVENTOR_CONFIG_VERSION;
+        cd->smart_undo_redo = EINA_FALSE;
      }
 
    g_cd = cd;
@@ -282,6 +284,8 @@ eddc_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd_base, config_data,
                                  "view_size_configurable",
                                  view_size_configurable, EET_T_UCHAR);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd_base, config_data, "smart_undo_redo",
+                                    smart_undo_redo, EET_T_UCHAR);
 }
 
 void
@@ -732,6 +736,20 @@ config_font_scale_get(void)
    return cd->font_scale;
 }
 
+Eina_Bool
+config_smart_undo_redo_get(void)
+{
+   config_data *cd = g_cd;
+   return cd->smart_undo_redo;
+}
+
+void
+config_smart_undo_redo_set(Eina_Bool smart_undo_redo)
+{
+   config_data *cd = g_cd;
+   cd->smart_undo_redo = smart_undo_redo;
+}
+
 void
 config_auto_complete_set(Eina_Bool auto_complete)
 {
diff --git a/src/bin/main.c b/src/bin/main.c
index 3e05691..be0ed0e 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -56,6 +56,7 @@ enventor_common_setup(Evas_Object *enventor)
    enventor_object_live_view_scale_set(enventor, config_view_scale_get());
    enventor_object_auto_indent_set(enventor, config_auto_indent_get());
    enventor_object_auto_complete_set(enventor, config_auto_complete_get());
+   enventor_object_smart_undo_redo_set(enventor, config_smart_undo_redo_get());
 
    Eina_List *list = eina_list_append(NULL, config_output_path_get());
    enventor_object_path_set(enventor, ENVENTOR_PATH_TYPE_EDJ, list);
diff --git a/src/bin/text_setting.c b/src/bin/text_setting.c
index 111916a..9292b13 100644
--- a/src/bin/text_setting.c
+++ b/src/bin/text_setting.c
@@ -864,6 +864,11 @@ text_setting_layout_create(Evas_Object *parent)
                                                 config_auto_complete_get());
    elm_box_pack_end(box, toggle_autocomp);
 
+   //Toggle (Smart Undo/Redo)
+   Evas_Object *toggle_smart_undo_redo = toggle_create(box, _("Smart 
Undo/Redo"),
+                                                config_smart_undo_redo_get());
+   elm_box_pack_end(box, toggle_smart_undo_redo);
+
    //Font Name and Style (Box)
    box = elm_box_add(layout);
    elm_box_horizontal_set(box, EINA_TRUE);
@@ -953,7 +958,7 @@ text_setting_layout_create(Evas_Object *parent)
    tsd->toggle_linenum = toggle_linenum;
    tsd->toggle_indent = toggle_indent;
    tsd->toggle_autocomp = toggle_autocomp;
-
+   tsd->toggle_smart_undo_redo = toggle_smart_undo_redo;
    return layout;
 }
 
@@ -999,6 +1004,7 @@ text_setting_config_set(void)
    config_linenumber_set(elm_check_state_get(tsd->toggle_linenum));
    config_auto_indent_set(elm_check_state_get(tsd->toggle_indent));
    config_auto_complete_set(elm_check_state_get(tsd->toggle_autocomp));
+   
config_smart_undo_redo_set(elm_check_state_get(tsd->toggle_smart_undo_redo));
 }
 
 static void
@@ -1059,6 +1065,13 @@ text_setting_auto_complete_set(Eina_Bool enabled)
 }
 
 void
+text_setting_smart_undo_redo_set(Eina_Bool enabled)
+{
+   text_setting_data *tsd = g_tsd;
+   elm_check_state_set(tsd->toggle_smart_undo_redo, enabled);
+}
+
+void
 text_setting_init(void)
 {
    text_setting_data *tsd = g_tsd;
diff --git a/src/include/config_data.h b/src/include/config_data.h
index 4b5771d..a1296da 100644
--- a/src/include/config_data.h
+++ b/src/include/config_data.h
@@ -58,3 +58,5 @@ double config_editor_size_get(void);
 void config_console_set(Eina_Bool enabled);
 void config_win_size_get(Evas_Coord *w, Evas_Coord *h);
 void config_win_size_set(Evas_Coord w, Evas_Coord h);
+void config_smart_undo_redo_set(Eina_Bool smart_undo_redo);
+Eina_Bool config_smart_undo_redo_get(void);
diff --git a/src/include/text_setting.h b/src/include/text_setting.h
index 5e37be2..55a1306 100644
--- a/src/include/text_setting.h
+++ b/src/include/text_setting.h
@@ -15,6 +15,7 @@ struct text_setting_s
    Evas_Object *toggle_linenum;
    Evas_Object *toggle_indent;
    Evas_Object *toggle_autocomp;
+   Evas_Object *toggle_smart_undo_redo;
 
    color_keyword *color_keyword_list;
    char *syntax_template_format;
@@ -37,5 +38,6 @@ void text_setting_font_scale_set(double font_scale);
 void text_setting_linenumber_set(Eina_Bool enabled);
 void text_setting_auto_indent_set(Eina_Bool enabled);
 void text_setting_auto_complete_set(Eina_Bool enabled);
+void text_setting_smart_undo_redo_set(Eina_Bool enabled);
 void text_setting_term(void);
 void text_setting_init(void);
diff --git a/src/lib/edc_editor.c b/src/lib/edc_editor.c
index 66cfb33..bea9119 100644
--- a/src/lib/edc_editor.c
+++ b/src/lib/edc_editor.c
@@ -60,6 +60,7 @@ struct editor_s
    Eina_Bool part_highlight : 1;
    Eina_Bool ctxpopup_enabled : 1;
    Eina_Bool on_save : 1;
+   Eina_Bool smart_undo_redo : 1;
 };
 
 /*****************************************************************************/
@@ -1184,6 +1185,7 @@ edit_init(Evas_Object *enventor)
    ed->auto_indent = EINA_TRUE;
    ed->part_highlight = EINA_TRUE;
    ed->ctxpopup_enabled = EINA_TRUE;
+   ed->smart_undo_redo = EINA_FALSE;
    ed->cur_line = -1;
    ed->select_pos = -1;
    ed->font_scale = 1;
@@ -1433,6 +1435,20 @@ edit_disabled_set(edit_data *ed, Eina_Bool disabled)
 }
 
 void
+edit_smart_undo_redo_set(edit_data *ed, Eina_Bool smart_undo_redo)
+{
+   smart_undo_redo = !!smart_undo_redo;
+   ed->smart_undo_redo = smart_undo_redo;
+   redoundo_smart_set(ed->rd, smart_undo_redo);
+}
+
+Eina_Bool
+edit_smart_undo_redo_get(edit_data *ed)
+{
+   return ed->smart_undo_redo;
+}
+
+void
 edit_auto_indent_set(edit_data *ed, Eina_Bool auto_indent)
 {
    auto_indent = !!auto_indent;
diff --git a/src/lib/enventor_object.eo b/src/lib/enventor_object.eo
index a837f0e..7b3fb46 100644
--- a/src/lib/enventor_object.eo
+++ b/src/lib/enventor_object.eo
@@ -91,6 +91,15 @@ class Enventor.Object (Elm.Widget, Efl.File) {
             linenumber: bool;
          }
       }
+      @property smart_undo_redo {
+         set {
+         }
+         get {
+         }
+         values {
+            smart_undo_redo: bool;
+         }
+      }
       path_set {
          return: Eina_Bool;
          params {
diff --git a/src/lib/enventor_private.h b/src/lib/enventor_private.h
index 8347dc7..3e2adc6 100644
--- a/src/lib/enventor_private.h
+++ b/src/lib/enventor_private.h
@@ -195,6 +195,7 @@ void redoundo_entry_region_push(redoundo_data *rd, int 
cursor_pos, int cursor_po
 int redoundo_undo(redoundo_data *rd, Eina_Bool *changed);
 int redoundo_redo(redoundo_data *rd, Eina_Bool *changed);
 void redoundo_n_diff_cancel(redoundo_data *rd, unsigned int n);
+void redoundo_smart_set(redoundo_data *rd, Eina_Bool status);
 
 
 /* edj_viewer */
@@ -271,6 +272,8 @@ Eina_Bool edit_part_highlight_get(edit_data *ed);
 void edit_ctxpopup_enabled_set(edit_data *ed, Eina_Bool enabled);
 Eina_Bool edit_ctxpopup_enabled_get(edit_data *ed);
 Eina_Bool edit_ctxpopup_visible_get(edit_data *ed);
+void edit_smart_undo_redo_set(edit_data *ed, Eina_Bool smart_undo_redo);
+Eina_Bool edit_smart_undo_redo_get(edit_data *ed);
 void edit_ctxpopup_dismiss(edit_data *ed);
 Eina_Bool edit_load(edit_data *ed, const char *edc_path);
 void edit_selection_clear(edit_data *ed);
diff --git a/src/lib/enventor_smart.c b/src/lib/enventor_smart.c
index 8d64804..e99fab0 100644
--- a/src/lib/enventor_smart.c
+++ b/src/lib/enventor_smart.c
@@ -310,6 +310,19 @@ _enventor_object_linenumber_get(Eo *obj EINA_UNUSED, 
Enventor_Object_Data *pd)
 }
 
 EOLIAN static void
+_enventor_object_smart_undo_redo_set(Eo *obj EINA_UNUSED, Enventor_Object_Data 
*pd,
+                                     Eina_Bool smart_undo_redo)
+{
+   edit_smart_undo_redo_set(pd->ed, smart_undo_redo);
+}
+
+EOLIAN static Eina_Bool
+_enventor_object_smart_undo_redo_get(Eo *obj EINA_UNUSED, Enventor_Object_Data 
*pd)
+{
+   return edit_smart_undo_redo_get(pd->ed);
+}
+
+EOLIAN static void
 _enventor_object_auto_indent_set(Eo *obj EINA_UNUSED, Enventor_Object_Data *pd,
                                  Eina_Bool auto_indent)
 {
diff --git a/src/lib/redoundo.c b/src/lib/redoundo.c
index 819d951..01d7106 100644
--- a/src/lib/redoundo.c
+++ b/src/lib/redoundo.c
@@ -6,6 +6,7 @@
 #include "enventor_private.h"
 
 #define DEFAULT_QUEUE_SIZE 200
+#define INPUT_SPEED 0.8 //how much time need to input one symbol with speed 
75sym/min
 
 typedef struct diff_s
 {
@@ -26,11 +27,72 @@ struct redoundo_s
    diff_data *last_diff;
    unsigned int queue_max;        //Maximum queuing data count 0: unlimited
    Eina_Bool internal_change : 1; //Entry change by redoundo
+   struct {
+      Eina_Bool enable;
+      Ecore_Timer *timer;
+      Eina_Bool continues_input;
+      double input_delay;
+   } smart;
 };
 
 /*****************************************************************************/
 /* Internal method implementation                                            */
 /*****************************************************************************/
+Eina_Bool
+_input_timer_cb(void *data)
+{
+   redoundo_data *rd = (redoundo_data *)data;
+   if (!rd->smart.continues_input) return ECORE_CALLBACK_CANCEL;
+   rd->smart.continues_input = EINA_FALSE;
+   ecore_timer_del(rd->smart.timer);
+   rd->smart.timer = NULL;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static diff_data *
+smart_analyser(redoundo_data *rd, diff_data *diff)
+{
+   if (!rd->smart.enable) return diff;
+
+   if (rd->smart.timer)
+     {
+        ecore_timer_del(rd->smart.timer);
+        rd->smart.timer = NULL;
+     }
+
+   if ((!diff) || (diff->length > 1) || (!rd->last_diff)) return diff;
+
+   /*  Autoindent. Here need  edit_data pointer,
+   *  for check status of autoindent feature.
+   *
+   *  if (edit_auto_indent_get(edit_obj_get))
+   *   {
+   *     if (strstr(diff->text, "<br/>")) diff->relative = EINA_TRUE;
+   *       else diff->relative = EINA_FALSE;
+   *    }
+   */
+
+   // Analyse speed of text input and words separates
+   if ((rd->smart.continues_input) && (!diff->relative) &&
+       (isalpha(diff->text[0])) && (isalpha(rd->last_diff->text[0])))
+     {
+        diff_data *tmp = diff;
+        const char *text;
+        diff = rd->last_diff;
+        diff->length += tmp->length;
+        text = eina_stringshare_printf("%s%s", diff->text, tmp->text);
+        eina_stringshare_replace(&diff->text, text);
+        eina_stringshare_del(text);
+        rd->last_diff = eina_list_data_get(eina_list_prev(rd->current_node));
+        rd->queue = eina_list_remove_list(rd->queue, rd->current_node);
+        eina_stringshare_del(tmp->text);
+        free(tmp);
+     }
+
+   rd->smart.continues_input = EINA_TRUE;
+   rd->smart.timer = ecore_timer_add(rd->smart.input_delay, _input_timer_cb, 
rd);
+   return diff;
+}
 
 static void
 untracked_diff_free(redoundo_data *rd)
@@ -104,7 +166,7 @@ entry_changed_user_cb(void *data, Evas_Object *obj 
EINA_UNUSED,
         diff->length = abs(length);
         diff->action = EINA_FALSE;
      }
-   diff->relative = EINA_FALSE;
+   diff = smart_analyser(rd, diff);
 
    untracked_diff_free(rd);
    rd->queue = eina_list_append(rd->queue, diff);
@@ -319,6 +381,8 @@ redoundo_init(Evas_Object *entry)
    rd->textblock = elm_entry_textblock_get(entry);
    rd->cursor = evas_object_textblock_cursor_new(rd->textblock);
    rd->queue_max = DEFAULT_QUEUE_SIZE;
+   rd->smart.enable = EINA_FALSE;
+   rd->smart.input_delay = INPUT_SPEED;
 
    //FIXME: Why signal callback? not smart callback?
    elm_object_signal_callback_add(entry, "entry,changed,user", "*",
@@ -337,6 +401,7 @@ redoundo_clear(redoundo_data *rd)
         free(data);
      }
    rd->internal_change = EINA_FALSE;
+   ecore_timer_del(rd->smart.timer);
 }
 
 void
@@ -395,3 +460,10 @@ redoundo_n_diff_cancel(redoundo_data *rd, unsigned int n)
    rd->last_diff = (diff_data *)eina_list_data_get(rd->current_node);
    untracked_diff_free(rd);
 }
+
+void
+redoundo_smart_set(redoundo_data *rd, Eina_Bool status)
+{
+   if (!rd) return;
+   rd->smart.enable = status;
+}

-- 


Reply via email to