netstar pushed a commit to branch master. http://git.enlightenment.org/tools/edi.git/commit/?id=2e045c0a43e269b1c18b9b3c450845bcc8b8c16e
commit 2e045c0a43e269b1c18b9b3c450845bcc8b8c16e Author: Al Poole <[email protected]> Date: Thu Sep 21 14:13:41 2017 +0100 screeens: scm. Replace list with genlist and make commit entry more usable. The original elm_list_ would segv if there were many hundreds of items, so redone with a genlist. Also the entry for commit message is less of a pain as it was. --- src/bin/screens/edi_scm_screens.c | 358 ++++++++++++++++++++++++++++---------- 1 file changed, 265 insertions(+), 93 deletions(-) diff --git a/src/bin/screens/edi_scm_screens.c b/src/bin/screens/edi_scm_screens.c index 6a3e811..bf7fc33 100644 --- a/src/bin/screens/edi_scm_screens.c +++ b/src/bin/screens/edi_scm_screens.c @@ -12,6 +12,7 @@ #include "edi_private.h" static Evas_Object *_parent_obj, *_popup, *_edi_scm_screens_message_popup; +static Eina_Hash *_hash_statuses = NULL; static void _edi_scm_screens_message_close_cb(void *data EINA_UNUSED, @@ -61,7 +62,7 @@ _edi_scm_screens_commit_cb(void *data, if (!engine) return; - text = elm_entry_entry_get((Evas_Object *) data); + text = elm_object_text_get((Evas_Object *) data); if (!text || !text[0]) { _edi_scm_screens_message_open(_("Please enter a valid commit message.")); @@ -80,9 +81,9 @@ _edi_scm_screens_commit_cb(void *data, } static void -_entry_lines_append(Elm_Code *code, char *diff_text) +_entry_lines_append(Elm_Code *code, char *text) { - char *pos = diff_text; + char *pos = text; char *start, *end = NULL; if (!*pos) return; @@ -105,54 +106,234 @@ _entry_lines_append(Elm_Code *code, char *diff_text) elm_code_file_line_append(code->file, start, end - start, NULL); } +static Edi_Scm_Status_Code * +_file_status_item_find(const char *path) +{ + return eina_hash_find(_hash_statuses, path); +} + static void -_set_icons_status(Evas_Object *icon, Evas_Object *icon_status, Edi_Scm_Status *status) +_file_status_item_add(const char *path, Edi_Scm_Status_Code status) +{ + Edi_Scm_Status_Code *code; + + if (_file_status_item_find(path)) return; + + code = malloc(sizeof(Edi_Scm_Status_Code)); + + *code = status; + eina_hash_add(_hash_statuses, path, code); +} + + +static void _list_status_free_cb(void *data) +{ + Edi_Scm_Status_Code *code = data; + + free(code); +} + +static const char * +_icon_status(Edi_Scm_Status_Code code, Eina_Bool *staged) { - switch (status->change) + switch (code) { + case EDI_SCM_STATUS_NONE: + case EDI_SCM_STATUS_RENAMED: + return "document-new"; + case EDI_SCM_STATUS_DELETED: + return "edit-delete"; + case EDI_SCM_STATUS_UNKNOWN: + return NULL; + case EDI_SCM_STATUS_RENAMED_STAGED: + *staged = EINA_TRUE; + return "document-new"; + case EDI_SCM_STATUS_DELETED_STAGED: + *staged = EINA_TRUE; + return "edit-delete"; case EDI_SCM_STATUS_ADDED: + return "document-new"; case EDI_SCM_STATUS_ADDED_STAGED: - elm_icon_standard_set(icon, "document-new"); - break; + *staged = EINA_TRUE; + return "document-new"; case EDI_SCM_STATUS_MODIFIED: + return "document-save-as"; case EDI_SCM_STATUS_MODIFIED_STAGED: - elm_icon_standard_set(icon, "document-save-as"); - break; - case EDI_SCM_STATUS_DELETED: - case EDI_SCM_STATUS_DELETED_STAGED: - elm_icon_standard_set(icon, "edit-delete"); - break; - case EDI_SCM_STATUS_RENAMED: - case EDI_SCM_STATUS_RENAMED_STAGED: - elm_icon_standard_set(icon, "document-save-as"); - break; + *staged = EINA_TRUE; + return "document-save-as"; case EDI_SCM_STATUS_UNTRACKED: - elm_icon_standard_set(icon, "dialog-question"); - break; - default: - elm_icon_standard_set(icon, "text-x-generic"); + return "dialog-question"; } - if (status->change == EDI_SCM_STATUS_UNTRACKED) - elm_icon_standard_set(icon_status, "dialog-error"); - else if (status->staged) - elm_icon_standard_set(icon_status, "dialog-information"); - else - elm_icon_standard_set(icon_status, "dialog-error"); + return NULL; +} + +static void +_content_del(void *data, Evas_Object *obj EINA_UNUSED) +{ + char *path = data; + + free(path); +} + +static Evas_Object * +_content_get(void *data, Evas_Object *obj, const char *source) +{ + Evas_Object *box, *lbox, *mbox, *rbox, *label, *ic; + Edi_Scm_Status_Code *code; + char *text, *path; + const char *icon_name, *icon_status; + Eina_Bool staged = EINA_FALSE; + + if (strcmp(source, "elm.swallow.content")) + return NULL; + + path = (char *) data; + text = NULL; icon_name = icon_status = NULL; + + code = _file_status_item_find(path); + if (code) + icon_status = _icon_status(*code, &staged); + + text = strdup(basename((char *)path)); + + icon_name = "dialog-information"; + + box = elm_box_add(obj); + elm_box_horizontal_set(box, EINA_TRUE); + elm_box_align_set(box, 0, 0); + + lbox = elm_box_add(box); + elm_box_horizontal_set(lbox, EINA_TRUE); + elm_box_padding_set(lbox, 5, 0); + evas_object_show(lbox); + + ic = elm_icon_add(lbox); + elm_icon_standard_set(ic, icon_name); + evas_object_size_hint_min_set(ic, ELM_SCALE_SIZE(16), ELM_SCALE_SIZE(16)); + evas_object_show(ic); + elm_box_pack_end(lbox, ic); + + label = elm_label_add(lbox); + elm_object_text_set(label, text); + free(text); + evas_object_show(label); + elm_box_pack_end(lbox, label); + + mbox = elm_box_add(lbox); + elm_box_horizontal_set(mbox, EINA_TRUE); + evas_object_size_hint_weight_set(mbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(mbox); + + rbox = elm_box_add(mbox); + elm_box_horizontal_set(rbox, EINA_TRUE); + elm_box_padding_set(rbox, 5, 0); + evas_object_show(rbox); + + if (icon_status) + { + ic = elm_icon_add(rbox); + elm_icon_standard_set(ic, icon_status); + evas_object_size_hint_min_set(ic, ELM_SCALE_SIZE(16), ELM_SCALE_SIZE(16)); + evas_object_show(ic); + elm_box_pack_end(rbox, ic); + + if (staged) + { + ic = elm_icon_add(mbox); + elm_icon_standard_set(ic, "dialog-information"); + evas_object_size_hint_min_set(ic, ELM_SCALE_SIZE(16), ELM_SCALE_SIZE(16)); + evas_object_show(ic); + elm_box_pack_end(rbox, ic); + text = _("Staged changes"); + } + else + { + ic = elm_icon_add(mbox); + elm_icon_standard_set(ic, "dialog-error"); + evas_object_size_hint_min_set(ic, ELM_SCALE_SIZE(16), ELM_SCALE_SIZE(16)); + evas_object_show(ic); + elm_box_pack_end(rbox, ic); + + if (*code != EDI_SCM_STATUS_UNTRACKED) + text = _("Unstaged changes"); + else + text = _("Untracked changes"); + } + + elm_object_tooltip_text_set(box, text); + } + + elm_box_pack_end(box, lbox); + elm_box_pack_end(box, mbox); + elm_box_pack_end(box, rbox); + + return box; +} + +static Eina_Bool +_file_status_list_fill(Evas_Object *list) +{ + Edi_Scm_Engine *e; + Edi_Scm_Status *status; + Elm_Genlist_Item_Class *itc; + Eina_Bool staged = EINA_FALSE; + + e = edi_scm_engine_get(); + if (!e) + return EINA_FALSE; + + if (_hash_statuses) + { + eina_hash_free_buckets(_hash_statuses); + eina_hash_free(_hash_statuses); + } + + _hash_statuses = eina_hash_string_superfast_new(_list_status_free_cb); + eina_hash_free_buckets(_hash_statuses); + + itc = elm_genlist_item_class_new(); + itc->item_style = "full"; + itc->func.text_get = NULL; + itc->func.content_get = _content_get; + itc->func.state_get = NULL; + itc->func.del = _content_del; + + if (edi_scm_status_get()) + { + EINA_LIST_FREE(e->statuses, status) + { + _file_status_item_add(status->fullpath, status->change); + elm_genlist_item_append(list, itc, strdup(status->fullpath), NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + if (status->staged) staged = EINA_TRUE; + + eina_stringshare_del(status->fullpath); + eina_stringshare_del(status->path); + free(status); + } + } + + if (e->statuses) + { + eina_list_free(e->statuses); + e->statuses = NULL; + } + + elm_genlist_item_class_free(itc); + + return staged; } void edi_scm_screens_commit(Evas_Object *parent) { Evas_Object *popup, *box, *frame, *hbox, *cbox, *label, *avatar, *input, *button; - Evas_Object *list, *icon, *icon_status; + Evas_Object *table, *rect, *list; Elm_Code_Widget *entry; Elm_Code *code; - Eina_Strbuf *text; + Eina_Strbuf *string; Edi_Scm_Engine *engine; - Edi_Scm_Status *status; - Elm_Object_Item *item; - char *diff_text; + char *text; Eina_Bool staged_changes; engine= edi_scm_engine_get(); @@ -193,11 +374,11 @@ edi_scm_screens_commit(Evas_Object *parent) evas_object_show(label); elm_box_pack_end(hbox, label); - text = eina_strbuf_new(); - eina_strbuf_append_printf(text, "%s:<br><b>%s</b><br><%s>", _("Author"), + string = eina_strbuf_new(); + eina_strbuf_append_printf(string, "%s:<br><b>%s</b><br><%s>", _("Author"), engine->remote_name_get(), engine->remote_email_get()); - elm_object_text_set(label, eina_strbuf_string_get(text)); - eina_strbuf_reset(text); + elm_object_text_set(label, eina_strbuf_string_get(string)); + eina_strbuf_free(string); avatar = elm_image_add(hbox); edi_scm_screens_avatar_load(avatar, engine->remote_email_get()); @@ -207,69 +388,56 @@ edi_scm_screens_commit(Evas_Object *parent) evas_object_show(avatar); elm_box_pack_end(hbox, avatar); - cbox = elm_box_add(box); - evas_object_size_hint_weight_set(cbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(cbox, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_size_hint_min_set(cbox, 250 * elm_config_scale_get(), 100 * elm_config_scale_get()); - evas_object_show(cbox); - - list = elm_list_add(box); + list = elm_genlist_add(box); + elm_genlist_mode_set(list, ELM_LIST_SCROLL); elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_NONE); + elm_scroller_bounce_set(list, EINA_TRUE, EINA_TRUE); + elm_scroller_policy_set(list, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON); evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_box_pack_end(cbox, list); - elm_box_pack_end(box, cbox); + evas_object_show(list); - staged_changes = EINA_FALSE; + // Start of trick + table = elm_table_add(popup); + evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL); + rect = evas_object_rectangle_add(table); + evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(rect, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_min_set(rect, 300 * elm_config_scale_get(), 100 * elm_config_scale_get()); + elm_table_pack(table, rect, 0, 0, 1, 1); + evas_object_show(table); - if (edi_scm_status_get()) - { - EINA_LIST_FREE(engine->statuses, status) - { - icon = elm_icon_add(box); - icon_status = elm_icon_add(box); - - _set_icons_status(icon, icon_status, status); - - item = elm_list_item_append(list, status->path, icon, icon_status, NULL, NULL); - - if (status->change == EDI_SCM_STATUS_UNTRACKED) - { - elm_object_item_tooltip_text_set(item, _("Untracked changes")); - } - else if (status->staged) - { - staged_changes = EINA_TRUE; - elm_object_item_tooltip_text_set(item, _("Staged changes")); - } - else - { - elm_object_item_tooltip_text_set(item, _("Unstaged changes")); - } + frame = elm_frame_add(popup); + evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(frame, _("File changes")); + evas_object_show(frame); + elm_object_content_set(frame, table); + elm_table_pack(table, list, 0, 0, 1, 1); + elm_object_content_set(frame, table); + elm_box_pack_end(box, frame); + // End of Trick - eina_stringshare_del(status->path); - free(status); - } - eina_list_free(engine->statuses); - engine->statuses = NULL; - } - else - { - icon = elm_icon_add(box); - elm_icon_standard_set(icon, "dialog-information"); - elm_list_item_append(list, _("Nothing to commit."), icon, NULL, NULL, NULL); - } + staged_changes = _file_status_list_fill(list); - elm_scroller_bounce_set(list, EINA_TRUE, EINA_TRUE); - elm_scroller_policy_set(list, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON); - elm_list_go(list); - evas_object_show(list); + // Start of trick + table = elm_table_add(popup); + evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL); + rect = evas_object_rectangle_add(table); + evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(rect, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_min_set(rect, 300 * elm_config_scale_get(), 100 * elm_config_scale_get()); + elm_table_pack(table, rect, 0, 0, 1, 1); + evas_object_show(table); frame = elm_frame_add(popup); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_text_set(frame, _("Commit message")); evas_object_show(frame); + elm_object_content_set(frame, table); input = elm_entry_add(box); elm_object_text_set(input, _("Enter commit summary<br><br>And change details<br>")); @@ -277,14 +445,18 @@ edi_scm_screens_commit(Evas_Object *parent) evas_object_size_hint_align_set(input, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_entry_editable_set(input, staged_changes); elm_entry_scrollable_set(input, EINA_TRUE); - elm_entry_single_line_set(input, EINA_TRUE); - elm_object_style_set(input, "entry"); + elm_entry_single_line_set(input, EINA_FALSE); + elm_entry_line_wrap_set(input, ELM_WRAP_WORD); + + elm_table_pack(table, input, 0, 0, 1, 1); evas_object_show(input); - elm_object_content_set(frame, input); + + elm_object_content_set(frame, table); elm_box_pack_end(box, frame); + // End of Trick - diff_text = edi_scm_diff(); - if (diff_text[0] && diff_text[1]) + text = edi_scm_diff(); + if (text[0] && text[1]) { frame = elm_frame_add(popup); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); @@ -312,10 +484,10 @@ edi_scm_screens_commit(Evas_Object *parent) evas_object_show(entry); elm_box_pack_end(cbox, entry); - _entry_lines_append(code, diff_text); + _entry_lines_append(code, text); } - free(diff_text); + free(text); button = elm_button_add(popup); elm_object_text_set(button, _("Cancel")); --
