summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Williams <andy@andywilliams.me>2016-02-21 23:46:10 +0000
committerAndy Williams <andy@andywilliams.me>2016-02-21 23:46:10 +0000
commitb61b460c997a5850e5c3b9d524a9b11864d6b19f (patch)
tree336ab51c287d1a1850775d8dfbd3608d31344385
parent9b491f8efac18f4e0d9fba9d6b9e4fef8bb6da28 (diff)
downloadefl-b61b460c997a5850e5c3b9d524a9b11864d6b19f.tar.gz
[editor] add delete and backspace undo hooks
-rw-r--r--legacy/elm_code/src/lib/widget/elm_code_widget.c40
-rw-r--r--legacy/elm_code/src/lib/widget/elm_code_widget.eo9
-rw-r--r--legacy/elm_code/src/lib/widget/elm_code_widget_private.h6
-rw-r--r--legacy/elm_code/src/lib/widget/elm_code_widget_selection.c85
-rw-r--r--legacy/elm_code/src/lib/widget/elm_code_widget_text.c81
-rw-r--r--legacy/elm_code/src/lib/widget/elm_code_widget_undo.c27
-rw-r--r--legacy/elm_code/src/tests/widget/elm_code_test_widget_undo.c46
7 files changed, 201 insertions, 93 deletions
diff --git a/legacy/elm_code/src/lib/widget/elm_code_widget.c b/legacy/elm_code/src/lib/widget/elm_code_widget.c
index fe78a82d83..203c1d1be4 100644
--- a/legacy/elm_code/src/lib/widget/elm_code_widget.c
+++ b/legacy/elm_code/src/lib/widget/elm_code_widget.c
@@ -988,14 +988,14 @@ _elm_code_widget_delete_selection(Elm_Code_Widget *widget)
}
static Elm_Code_Widget_Change_Info *
-_elm_code_widget_change_create_insert(unsigned int start_col, unsigned int start_line,
- unsigned int end_col, unsigned int end_line,
- const char *text, unsigned int length)
+_elm_code_widget_change_create(unsigned int start_col, unsigned int start_line,
+ unsigned int end_col, unsigned int end_line,
+ const char *text, unsigned int length, Eina_Bool insert)
{
Elm_Code_Widget_Change_Info *info;
info = calloc(1, sizeof(*info));
- info->insert = EINA_TRUE;
+ info->insert = insert;
info->start_col = start_col;
info->start_line = start_line;
@@ -1003,7 +1003,8 @@ _elm_code_widget_change_create_insert(unsigned int start_col, unsigned int start
info->end_line = end_line;
info->content = malloc((length + 1) * sizeof(char));
- strncpy((char *)info->content, text, length + 1);
+ strncpy(info->content, text, length);
+ info->content[length] = '\0';
info->length = length;
return info;
@@ -1045,7 +1046,7 @@ _elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, const char *text
elm_obj_code_widget_cursor_position_set(col + col_width, row),
eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL));
- change = _elm_code_widget_change_create_insert(col, row, col + col_width - 1, row, text, length);
+ change = _elm_code_widget_change_create(col, row, col + col_width - 1, row, text, length, EINA_TRUE);
_elm_code_widget_undo_change_add(widget, change);
_elm_code_widget_change_free(change);
}
@@ -1054,7 +1055,6 @@ static void
_elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget)
{
Elm_Code_Widget_Data *pd;
- Elm_Code_Widget_Change_Info *change;
unsigned int col, row, rem;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
@@ -1113,7 +1113,7 @@ _elm_code_widget_newline(Elm_Code_Widget *widget)
elm_obj_code_widget_cursor_position_set(indent, row + 1),
eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL));
- change = _elm_code_widget_change_create_insert(width + 1, row, indent - 1, row + 1, "\n", 1);
+ change = _elm_code_widget_change_create(width + 1, row, indent - 1, row + 1, "\n", 1, EINA_TRUE);
_elm_code_widget_undo_change_add(widget, change);
_elm_code_widget_change_free(change);
}
@@ -1149,15 +1149,17 @@ _elm_code_widget_backspaceline(Elm_Code_Widget *widget, Eina_Bool nextline)
eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL));
}
-static void
+void
_elm_code_widget_backspace(Elm_Code_Widget *widget)
{
Elm_Code *code;
Elm_Code_Line *line;
+ Elm_Code_Widget_Change_Info *change;
unsigned int row, col, position, start_col, char_width;
+ const char *text;
if (_elm_code_widget_delete_selection(widget))
- return;
+ return; // TODO fire the change and log it
eo_do(widget,
code = elm_obj_code_widget_code_get(),
@@ -1179,23 +1181,29 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget)
elm_code_widget_line_text_position_for_column_get(widget, line, col - 1));
char_width = position - elm_code_widget_line_text_position_for_column_get(widget, line, start_col);
+ text = elm_code_widget_text_between_positions_get(widget, start_col, row, start_col, row);
elm_code_line_text_remove(line, position - char_width, char_width);
eo_do(widget,
elm_obj_code_widget_cursor_position_set(start_col, row));
-// TODO construct and pass a change object
eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL));
+
+ change = _elm_code_widget_change_create(start_col, row, col, row, text, char_width, EINA_FALSE);
+ _elm_code_widget_undo_change_add(widget, change);
+ _elm_code_widget_change_free(change);
}
-static void
+void
_elm_code_widget_delete(Elm_Code_Widget *widget)
{
Elm_Code *code;
Elm_Code_Line *line;
+ Elm_Code_Widget_Change_Info *change;
unsigned int row, col, position, char_width, start_col;
+ const char *text;
if (_elm_code_widget_delete_selection(widget))
- return;
+ return; // TODO fire the change and log it
eo_do(widget,
code = elm_obj_code_widget_code_get(),
@@ -1214,11 +1222,15 @@ _elm_code_widget_delete(Elm_Code_Widget *widget)
char_width = elm_code_widget_line_text_position_for_column_get(widget, line, col + 1) - position;
start_col = elm_code_widget_line_text_column_width_to_position(widget, line, position);
+ text = elm_code_widget_text_between_positions_get(widget, start_col, row, start_col, row);
elm_code_line_text_remove(line, position, char_width?char_width:1);
eo_do(widget,
elm_obj_code_widget_cursor_position_set(start_col, row),
-// TODO construct and pass a change object
eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL));
+
+ change = _elm_code_widget_change_create(start_col, row, col, row, text, char_width, EINA_FALSE);
+ _elm_code_widget_undo_change_add(widget, change);
+ _elm_code_widget_change_free(change);
}
static void
diff --git a/legacy/elm_code/src/lib/widget/elm_code_widget.eo b/legacy/elm_code/src/lib/widget/elm_code_widget.eo
index e07459a5b7..ace043a764 100644
--- a/legacy/elm_code/src/lib/widget/elm_code_widget.eo
+++ b/legacy/elm_code/src/lib/widget/elm_code_widget.eo
@@ -175,6 +175,15 @@ class Elm.Code_Widget (Elm.Layout, Elm.Interface_Atspi_Text)
text_line_number_width_get {
return: int; [[the column width required to represent the number of lines in the widget.]]
}
+ text_between_positions_get {
+ params {
+ start_col: uint; [[the widget column of the first character to get]]
+ start_line: uint; [[the line of the first character to get]]
+ end_col: uint; [[the widget column of the last character to get]]
+ end_line: uint; [[the line of the last character to get]]
+ }
+ return: char *; [[the text content between start and end positions]]
+ }
line_text_column_width_to_position {
params {
diff --git a/legacy/elm_code/src/lib/widget/elm_code_widget_private.h b/legacy/elm_code/src/lib/widget/elm_code_widget_private.h
index fab43c257a..b4e19007b0 100644
--- a/legacy/elm_code/src/lib/widget/elm_code_widget_private.h
+++ b/legacy/elm_code/src/lib/widget/elm_code_widget_private.h
@@ -35,7 +35,7 @@ typedef struct
typedef struct
{
- const char *content;
+ char *content;
unsigned int length;
unsigned int start_line, start_col, end_line, end_col;
@@ -48,6 +48,10 @@ void _elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, const char
void _elm_code_widget_newline(Elm_Code_Widget *widget);
+void _elm_code_widget_backspace(Elm_Code_Widget *widget);
+
+void _elm_code_widget_delete(Elm_Code_Widget *widget);
+
void _elm_code_widget_tooltip_text_set(Evas_Object *widget, const char *text);
void _elm_code_widget_tooltip_add(Evas_Object *widget);
diff --git a/legacy/elm_code/src/lib/widget/elm_code_widget_selection.c b/legacy/elm_code/src/lib/widget/elm_code_widget_selection.c
index 9a558ecc6b..d4d214241b 100644
--- a/legacy/elm_code/src/lib/widget/elm_code_widget_selection.c
+++ b/legacy/elm_code/src/lib/widget/elm_code_widget_selection.c
@@ -317,91 +317,26 @@ elm_code_widget_selection_select_word(Evas_Object *widget, unsigned int line, un
elm_code_widget_line_text_column_width_to_position(widget, lineobj, pos));
}
-static char *
-_elm_code_widget_selection_text_single_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd)
-{
- Elm_Code_Line *line;
- unsigned int start, end;
- Elm_Code_Widget_Selection_Data *selection;
-
- selection = elm_code_widget_selection_normalized_get(widget);
- line = elm_code_file_line_get(pd->code->file, selection->start_line);
- start = elm_code_widget_line_text_position_for_column_get(widget, line, selection->start_col);
- end = elm_code_widget_line_text_position_for_column_get(widget, line, selection->end_col + 1);
- free(selection);
-
- return elm_code_line_text_substr(line, start, end - start);
-}
-
-static char *
-_elm_code_widget_selection_text_multi_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd)
-{
- Elm_Code_Line *line;
- char *first, *last, *ret, *ptr;
- const char *newline;
- short newline_len;
- int ret_len;
- unsigned int row, start, end;
- Elm_Code_Widget_Selection_Data *selection;
-
- selection = elm_code_widget_selection_normalized_get(widget);
- newline = elm_code_file_line_ending_chars_get(pd->code->file, &newline_len);
-
- line = elm_code_file_line_get(pd->code->file, selection->start_line);
- start = elm_code_widget_line_text_position_for_column_get(widget, line, selection->start_col);
- first = elm_code_line_text_substr(line, start, line->length - start + 1);
-
- line = elm_code_file_line_get(pd->code->file, selection->end_line);
- end = elm_code_widget_line_text_position_for_column_get(widget, line, selection->end_col + 1);
- last = elm_code_line_text_substr(line, 0, end);
-
- ret_len = strlen(first) + strlen(last) + newline_len;
-
- for (row = pd->selection->start_line + 1; row < selection->end_line; row++)
- {
- line = elm_code_file_line_get(pd->code->file, row);
- ret_len += line->length + newline_len;
- }
-
- ret = malloc(sizeof(char) * (ret_len + 1));
- snprintf(ret, strlen(first) + newline_len + 1, "%s%s", first, newline);
-
- ptr = ret;
- ptr += strlen(first) + newline_len;
-
- for (row = selection->start_line + 1; row < selection->end_line; row++)
- {
- line = elm_code_file_line_get(pd->code->file, row);
- if (line->modified)
- snprintf(ptr, line->length + 1, "%s", line->modified);
- else
- snprintf(ptr, line->length + 1, "%s", line->content);
-
- snprintf(ptr + line->length, newline_len + 1, "%s", newline);
- ptr += line->length + newline_len;
- }
- snprintf(ptr, strlen(last) + 1, "%s", last);
-
- free(selection);
- free(first);
- free(last);
- return ret;
-}
-
EAPI char *
elm_code_widget_selection_text_get(Evas_Object *widget)
{
Elm_Code_Widget_Data *pd;
+ Elm_Code_Widget_Selection_Data *selection;
+ char *text;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd->selection)
return strdup("");
- if (pd->selection->start_line == pd->selection->end_line)
- return _elm_code_widget_selection_text_single_get(widget, pd);
- else
- return _elm_code_widget_selection_text_multi_get(widget, pd);
+ selection = elm_code_widget_selection_normalized_get(widget);
+
+ text = elm_code_widget_text_between_positions_get(widget,
+ selection->start_col, selection->start_line,
+ selection->end_col, selection->end_line);
+
+ free(selection);
+ return text;
}
static void
diff --git a/legacy/elm_code/src/lib/widget/elm_code_widget_text.c b/legacy/elm_code/src/lib/widget/elm_code_widget_text.c
index 0ae2595563..3689e8284a 100644
--- a/legacy/elm_code/src/lib/widget/elm_code_widget_text.c
+++ b/legacy/elm_code/src/lib/widget/elm_code_widget_text.c
@@ -34,6 +34,87 @@ _elm_code_widget_text_left_gutter_width_get(Eo *obj, Elm_Code_Widget_Data *pd)
return width;
}
+static char *
+_elm_code_widget_text_multi_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd,
+ unsigned int start_col, unsigned int start_line,
+ unsigned int end_col, unsigned int end_line)
+{
+ Elm_Code_Line *line;
+ char *first, *last, *ret, *ptr;
+ const char *newline;
+ short newline_len;
+ int ret_len;
+ unsigned int row, start, end;
+
+ newline = elm_code_file_line_ending_chars_get(pd->code->file, &newline_len);
+
+ line = elm_code_file_line_get(pd->code->file, start_line);
+ start = elm_code_widget_line_text_position_for_column_get(widget, line, start_col);
+ first = elm_code_line_text_substr(line, start, line->length - start + 1);
+
+ line = elm_code_file_line_get(pd->code->file, end_line);
+ end = elm_code_widget_line_text_position_for_column_get(widget, line, end_col + 1);
+ last = elm_code_line_text_substr(line, 0, end);
+
+ ret_len = strlen(first) + strlen(last) + newline_len;
+
+ for (row = pd->selection->start_line + 1; row < end_line; row++)
+ {
+ line = elm_code_file_line_get(pd->code->file, row);
+ ret_len += line->length + newline_len;
+ }
+
+ ret = malloc(sizeof(char) * (ret_len + 1));
+
+ snprintf(ret, strlen(first) + newline_len + 1, "%s%s", first, newline);
+
+ ptr = ret;
+ ptr += strlen(first) + newline_len;
+
+ for (row = start_line + 1; row < end_line; row++)
+ {
+ line = elm_code_file_line_get(pd->code->file, row);
+ if (line->modified)
+ snprintf(ptr, line->length + 1, "%s", line->modified);
+ else
+ snprintf(ptr, line->length + 1, "%s", line->content);
+
+ snprintf(ptr + line->length, newline_len + 1, "%s", newline);
+ ptr += line->length + newline_len;
+ }
+ snprintf(ptr, strlen(last) + 1, "%s", last);
+
+ free(first);
+ free(last);
+ return ret;
+}
+
+static char *
+_elm_code_widget_text_single_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd,
+ unsigned int start_col, unsigned int start_line,
+ unsigned int end_col)
+{
+ Elm_Code_Line *line;
+ unsigned int start, end;
+
+ line = elm_code_file_line_get(pd->code->file, start_line);
+ start = elm_code_widget_line_text_position_for_column_get(widget, line, start_col);
+ end = elm_code_widget_line_text_position_for_column_get(widget, line, end_col + 1);
+
+ return elm_code_line_text_substr(line, start, end - start);
+}
+
+static char *
+_elm_code_widget_text_between_positions_get(Eo *widget, Elm_Code_Widget_Data *pd,
+ unsigned int start_col, unsigned int start_line,
+ unsigned int end_col, unsigned int end_line)
+{
+ if (start_line == end_line)
+ return _elm_code_widget_text_single_get(widget, pd, start_col, start_line, end_col);
+ else
+ return _elm_code_widget_text_multi_get(widget, pd, start_col, start_line, end_col, end_line);
+}
+
static unsigned int
_elm_code_widget_line_text_column_width_to_position(Eo *obj, Elm_Code_Widget_Data *pd EINA_UNUSED, Elm_Code_Line *line, unsigned int position)
{
diff --git a/legacy/elm_code/src/lib/widget/elm_code_widget_undo.c b/legacy/elm_code/src/lib/widget/elm_code_widget_undo.c
index d51cc5ff7e..6511be7602 100644
--- a/legacy/elm_code/src/lib/widget/elm_code_widget_undo.c
+++ b/legacy/elm_code/src/lib/widget/elm_code_widget_undo.c
@@ -6,6 +6,19 @@
#include "elm_code_widget_private.h"
+Elm_Code_Widget_Change_Info *
+_elm_code_widget_undo_info_copy(Elm_Code_Widget_Change_Info *info)
+{
+ Elm_Code_Widget_Change_Info *copy;
+
+ 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);
+
+ return copy;
+}
+
void
_elm_code_widget_undo_change_add(Evas_Object *widget,
Elm_Code_Widget_Change_Info *info)
@@ -13,9 +26,7 @@ _elm_code_widget_undo_change_add(Evas_Object *widget,
Elm_Code_Widget_Data *pd;
Elm_Code_Widget_Change_Info *info_copy;
- info_copy = calloc(1, sizeof(*info));
- memcpy(info_copy, info, sizeof(*info));
-
+ info_copy = _elm_code_widget_undo_info_copy(info);
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
pd->undo_stack_ptr = eina_list_prepend(pd->undo_stack_ptr, info_copy);
@@ -26,6 +37,10 @@ static void
_elm_code_widget_undo_change(Evas_Object *widget,
Elm_Code_Widget_Change_Info *info)
{
+ Elm_Code_Line *line;
+ Elm_Code_Widget_Data *pd;
+ unsigned int position;
+
if (info->insert)
{
elm_code_widget_selection_start(widget, info->start_line, info->start_col);
@@ -34,6 +49,12 @@ _elm_code_widget_undo_change(Evas_Object *widget,
}
else
{
+ pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
+ line = elm_code_file_line_get(pd->code->file, info->start_line);
+ position = elm_code_widget_line_text_position_for_column_get(widget, line, info->start_col);
+
+ elm_code_line_text_insert(line, position, info->content, info->length);
+ elm_code_widget_cursor_position_set(widget, info->end_col, info->end_line);
}
}
diff --git a/legacy/elm_code/src/tests/widget/elm_code_test_widget_undo.c b/legacy/elm_code/src/tests/widget/elm_code_test_widget_undo.c
index f6c13f0451..6f20909651 100644
--- a/legacy/elm_code/src/tests/widget/elm_code_test_widget_undo.c
+++ b/legacy/elm_code/src/tests/widget/elm_code_test_widget_undo.c
@@ -93,9 +93,55 @@ START_TEST (elm_code_test_widget_undo_newline)
}
END_TEST
+START_TEST (elm_code_test_widget_undo_delete)
+{
+ Elm_Code *code;
+ Elm_Code_File *file;
+ Elm_Code_Line *line;
+ Elm_Code_Widget *widget;
+ Evas_Object *win;
+ unsigned int length;
+ const char *content;
+
+ elm_init(1, NULL);
+ code = elm_code_create();
+ file = elm_code_file_new(code);
+ elm_code_file_line_append(file, "test", 4, NULL);
+
+ win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
+ widget = elm_code_widget_add(win, code);
+
+ elm_code_widget_cursor_position_set(widget, 4, 1);
+ _elm_code_widget_backspace(widget);
+
+ line = elm_code_file_line_get(file, 1);
+ content = elm_code_line_text_get(line, &length);
+ ck_assert_strn_eq("tet", content, length);
+
+ elm_code_widget_undo(widget);
+ content = elm_code_line_text_get(line, &length);
+ ck_assert_strn_eq("test", content, length);
+
+ elm_code_widget_cursor_position_set(widget, 2, 1);
+ _elm_code_widget_delete(widget);
+
+ line = elm_code_file_line_get(file, 1);
+ content = elm_code_line_text_get(line, &length);
+ ck_assert_strn_eq("tst", content, length);
+
+ elm_code_widget_undo(widget);
+ content = elm_code_line_text_get(line, &length);
+ ck_assert_strn_eq("test", content, length);
+
+ elm_code_free(code);
+ elm_shutdown();
+}
+END_TEST
+
void elm_code_test_widget_undo(TCase *tc)
{
tcase_add_test(tc, elm_code_test_widget_undo_text_insert);
tcase_add_test(tc, elm_code_test_widget_undo_newline);
+ tcase_add_test(tc, elm_code_test_widget_undo_delete);
}