diff options
author | Andy Williams <andy@andywilliams.me> | 2017-05-16 22:10:56 +0100 |
---|---|---|
committer | Andy Williams <andy@andywilliams.me> | 2017-05-16 22:13:43 +0100 |
commit | eb04ab591cf294517bf47782779087b21af919b5 (patch) | |
tree | d883a11004032f1820be30c25bb4c9de80d3b7a4 | |
parent | 75727592df7c286e48c267b7544be68ccbf6dc2c (diff) | |
download | efl-eb04ab591cf294517bf47782779087b21af919b5.tar.gz |
elm_code: Fix insertion of multiline content in widget
A small refactoring to reduce code duplication as well :)
-rw-r--r-- | src/lib/elementary/elm_code_widget.c | 74 | ||||
-rw-r--r-- | src/lib/elementary/elm_code_widget_selection.c | 84 | ||||
-rw-r--r-- | src/lib/elementary/elm_code_widget_text.c | 114 |
3 files changed, 118 insertions, 154 deletions
diff --git a/src/lib/elementary/elm_code_widget.c b/src/lib/elementary/elm_code_widget.c index a263c48c15..d40271df92 100644 --- a/src/lib/elementary/elm_code_widget.c +++ b/src/lib/elementary/elm_code_widget.c @@ -1316,74 +1316,6 @@ _elm_code_widget_change_selection_add(Evas_Object *widget) free(selection); } -void -_elm_code_widget_text_at_cursor_insert_do(Elm_Code_Widget *widget, const char *text, int length, Eina_Bool undo) -{ - Elm_Code *code; - Elm_Code_Line *line; - Elm_Code_Widget_Change_Info *change; - unsigned int row, col, position, col_width, curlen, indent; - const char *curtext, *indent_text; - - if (undo) - elm_code_widget_selection_delete(widget); - - code = elm_obj_code_widget_code_get(widget); - elm_obj_code_widget_cursor_position_get(widget, &row, &col); - line = elm_code_file_line_get(code->file, row); - if (line == NULL) - { - elm_code_file_line_append(code->file, "", 0, NULL); - row = elm_code_file_lines_get(code->file); - line = elm_code_file_line_get(code->file, row); - } - if (text[0] == '}') - { - curtext = elm_code_line_text_get(line, &curlen); - - if (elm_code_text_is_whitespace(curtext, line->length)) - { - indent_text = elm_code_line_indent_matching_braces_get(line, &indent); - elm_code_line_text_leading_whitespace_strip(line); - - if (indent > 0) - elm_code_line_text_insert(line, 0, indent_text, indent); - - elm_obj_code_widget_cursor_position_set(widget, row, indent + 1); - 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_text_insert(line, position, text, length); - col_width = elm_code_widget_line_text_column_width_to_position(widget, line, position + length) - - elm_code_widget_line_text_column_width_to_position(widget, line, position); - - // a workaround for when the cursor position would be off the line width - _elm_code_widget_resize(widget, line); - elm_obj_code_widget_cursor_position_set(widget, row, col + col_width); - efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL); - - if (undo) - { - 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); - } -} - -EOLIAN void -_elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd EINA_UNUSED, const char *text) -{ - _elm_code_widget_text_at_cursor_insert_do(widget, text, strlen(text), EINA_TRUE); -} - -void -_elm_code_widget_text_at_cursor_insert_no_undo(Elm_Code_Widget *widget, const char *text, unsigned int length) -{ - _elm_code_widget_text_at_cursor_insert_do(widget, text, length, EINA_FALSE); -} - static void _elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget) { @@ -1393,7 +1325,7 @@ _elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget) pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); if (!pd->tab_inserts_spaces) { - _elm_code_widget_text_at_cursor_insert(widget, pd, "\t"); + elm_code_widget_text_at_cursor_insert(widget, "\t"); return; } @@ -1402,7 +1334,7 @@ _elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget) while (rem < pd->tabstop) { - _elm_code_widget_text_at_cursor_insert(widget, pd, " "); + elm_code_widget_text_at_cursor_insert(widget, " "); rem++; } } @@ -1719,7 +1651,7 @@ _elm_code_widget_key_down_cb(void *data, Evas *evas EINA_UNUSED, elm_code_widget_selection_clear(widget); else if (ev->string && strlen(ev->string) == 1) - _elm_code_widget_text_at_cursor_insert(widget, pd, ev->string); + elm_code_widget_text_at_cursor_insert(widget, ev->string); else INF("Unhandled key %s (%s) (%s)", ev->key, ev->keyname, ev->string); } diff --git a/src/lib/elementary/elm_code_widget_selection.c b/src/lib/elementary/elm_code_widget_selection.c index cba2bd1c4b..c8c1dacde8 100644 --- a/src/lib/elementary/elm_code_widget_selection.c +++ b/src/lib/elementary/elm_code_widget_selection.c @@ -397,96 +397,14 @@ elm_code_widget_selection_copy(Evas_Object *widget) free(text); } -static void -_selection_paste_single(Elm_Code_Widget *widget, Elm_Code *code, - unsigned int col, unsigned int row, const char *text, unsigned int len) -{ - Elm_Code_Line *line; - unsigned int position, newcol; - - line = elm_code_file_line_get(code->file, row); - position = elm_code_widget_line_text_position_for_column_get(widget, line, col); - elm_code_line_text_insert(line, position, text, len); - - newcol = elm_code_widget_line_text_column_width_to_position(widget, line, position + len); - elm_obj_code_widget_cursor_position_set(widget, row, newcol); -} - -static void -_selection_paste_multi(Elm_Code_Widget *widget, Elm_Code *code, - unsigned int col, unsigned int row, const char *text, unsigned int len) -{ - Elm_Code_Line *line; - unsigned int position, newrow, remain; - int nlpos; - short nllen; - char *ptr; - - line = elm_code_file_line_get(code->file, row); - position = elm_code_widget_line_text_position_for_column_get(widget, line, col); - elm_code_line_split_at(line, position); - - newrow = row; - ptr = (char *)text; - remain = len; - while ((nlpos = elm_code_text_newlinenpos(ptr, remain, &nllen)) != ELM_CODE_TEXT_NOT_FOUND) - { - if (newrow == row) - _selection_paste_single(widget, code, col, row, text, nlpos); - else - elm_code_file_line_insert(code->file, newrow, ptr, nlpos, NULL); - - remain -= nlpos + nllen; - ptr += nlpos + nllen; - newrow++; - } - - _selection_paste_single(widget, code, 1, newrow, ptr, len - (ptr - text)); -} - static Eina_Bool _selection_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, Elm_Selection_Data *ev) { - Elm_Code *code; - Elm_Code_Line *line; Elm_Code_Widget *widget; - Elm_Code_Widget_Change_Info *change; - unsigned int row, col, end_row, end_col, position; widget = (Elm_Code_Widget *)data; - if (ev->format != ELM_SEL_FORMAT_TEXT) - return EINA_TRUE; - if (ev->len <= 0) - return EINA_TRUE; - - code = elm_obj_code_widget_code_get(widget); - elm_obj_code_widget_cursor_position_get(widget, &row, &col); - - if (elm_code_text_newlinenpos(ev->data, ev->len, NULL) == ELM_CODE_TEXT_NOT_FOUND) - _selection_paste_single(widget, code, col, row, ev->data, ev->len - 1); - else - _selection_paste_multi(widget, code, col, row, ev->data, ev->len - 1); - - elm_obj_code_widget_cursor_position_get(widget, &end_row, &end_col); - - line = elm_code_file_line_get(code->file, end_row); - position = elm_code_widget_line_text_position_for_column_get(widget, line, end_col); - - change = calloc(1, sizeof(Elm_Code_Widget_Change_Info)); - change->insert = EINA_TRUE; - change->start_col = col; - change->start_line = row; - change->end_col = position; - change->end_line = end_row; - change->content = strndup(ev->data, ev->len); - change->length = ev->len; - - _elm_code_widget_undo_change_add(widget, change); - free((char *)change->content); - free(change); - - efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL); + elm_code_widget_text_at_cursor_insert(widget, ev->data); return EINA_TRUE; } diff --git a/src/lib/elementary/elm_code_widget_text.c b/src/lib/elementary/elm_code_widget_text.c index 1b1b9cbcdd..a06fb8aa0b 100644 --- a/src/lib/elementary/elm_code_widget_text.c +++ b/src/lib/elementary/elm_code_widget_text.c @@ -193,3 +193,117 @@ _elm_code_widget_text_tabwidth_at_column_get(Eo *obj EINA_UNUSED, Elm_Code_Widge return pd->tabstop - ((column - 1) % pd->tabstop); } +static void +_elm_code_widget_text_insert_single(Elm_Code_Widget *widget, Elm_Code *code, + unsigned int col, unsigned int row, const char *text, unsigned int len) +{ + Elm_Code_Line *line; + unsigned int position, newcol; + + line = elm_code_file_line_get(code->file, row); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); + elm_code_line_text_insert(line, position, text, len); + + newcol = elm_code_widget_line_text_column_width_to_position(widget, line, position + len); + elm_obj_code_widget_cursor_position_set(widget, row, newcol); +} + +static void +_elm_code_widget_text_insert_multi(Elm_Code_Widget *widget, Elm_Code *code, + unsigned int col, unsigned int row, const char *text, unsigned int len) +{ + Elm_Code_Line *line; + unsigned int position, newrow, remain; + int nlpos; + short nllen; + char *ptr; + + line = elm_code_file_line_get(code->file, row); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); + elm_code_line_split_at(line, position); + + newrow = row; + ptr = (char *)text; + remain = len; + while ((nlpos = elm_code_text_newlinenpos(ptr, remain, &nllen)) != ELM_CODE_TEXT_NOT_FOUND) + { + if (newrow == row) + _elm_code_widget_text_insert_single(widget, code, col, row, text, nlpos); + else + elm_code_file_line_insert(code->file, newrow, ptr, nlpos, NULL); + + remain -= nlpos + nllen; + ptr += nlpos + nllen; + newrow++; + } + + _elm_code_widget_text_insert_single(widget, code, 1, newrow, ptr, len - (ptr - text)); +} + +void +_elm_code_widget_text_at_cursor_insert_do(Elm_Code_Widget *widget, const char *text, int length, Eina_Bool undo) +{ + Elm_Code *code; + Elm_Code_Line *line; + Elm_Code_Widget_Change_Info *change; + unsigned int row, col, end_row, end_col, curlen, indent; + const char *curtext, *indent_text; + + if (undo) + elm_code_widget_selection_delete(widget); + + code = elm_obj_code_widget_code_get(widget); + elm_obj_code_widget_cursor_position_get(widget, &row, &col); + line = elm_code_file_line_get(code->file, row); + if (line == NULL) + { + elm_code_file_line_append(code->file, "", 0, NULL); + row = elm_code_file_lines_get(code->file); + line = elm_code_file_line_get(code->file, row); + } + if (text[0] == '}') + { + curtext = elm_code_line_text_get(line, &curlen); + + if (elm_code_text_is_whitespace(curtext, line->length)) + { + indent_text = elm_code_line_indent_matching_braces_get(line, &indent); + elm_code_line_text_leading_whitespace_strip(line); + + if (indent > 0) + elm_code_line_text_insert(line, 0, indent_text, indent); + + elm_obj_code_widget_cursor_position_set(widget, row, indent + 1); + elm_obj_code_widget_cursor_position_get(widget, &row, &col); + } + } + + if (elm_code_text_newlinenpos(text, length, NULL) == ELM_CODE_TEXT_NOT_FOUND) + _elm_code_widget_text_insert_single(widget, code, col, row, text, length); + else + _elm_code_widget_text_insert_multi(widget, code, col, row, text, length); + elm_obj_code_widget_cursor_position_get(widget, &end_row, &end_col); + + // a workaround for when the cursor position would be off the line width + _elm_code_widget_resize(widget, line); + efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL); + + if (undo) + { + change = _elm_code_widget_change_create(col, row, end_col, end_row, text, length, EINA_TRUE); + _elm_code_widget_undo_change_add(widget, change); + _elm_code_widget_change_free(change); + } +} + +EOLIAN void +_elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd EINA_UNUSED, const char *text) +{ + _elm_code_widget_text_at_cursor_insert_do(widget, text, strlen(text), EINA_TRUE); +} + +void +_elm_code_widget_text_at_cursor_insert_no_undo(Elm_Code_Widget *widget, const char *text, unsigned int length) +{ + _elm_code_widget_text_at_cursor_insert_do(widget, text, length, EINA_FALSE); +} |