netstar pushed a commit to branch master. http://git.enlightenment.org/tools/edi.git/commit/?id=59a0ec1bae34d85c244b323a257cce7879b3ecec
commit 59a0ec1bae34d85c244b323a257cce7879b3ecec Author: Al Poole <nets...@gmail.com> Date: Sat Sep 16 01:19:54 2017 +0100 scm: add support for file listing file status. Add support for file listing status. Also some refactoring. More to do, more testing first. --- src/bin/edi_filepanel.c | 140 +++++++++++++++++++++++++++++++++++-- src/bin/edi_filepanel.h | 16 +++++ src/bin/edi_main.c | 3 + src/bin/screens/edi_file_screens.c | 3 + src/bin/screens/edi_scm_screens.c | 114 ++++++++++++++++-------------- src/lib/edi_exe.c | 2 +- src/lib/edi_scm.c | 54 +++++++++----- src/lib/edi_scm.h | 8 ++- 8 files changed, 262 insertions(+), 78 deletions(-) diff --git a/src/bin/edi_filepanel.c b/src/bin/edi_filepanel.c index c558d39..a696fd2 100644 --- a/src/bin/edi_filepanel.c +++ b/src/bin/edi_filepanel.c @@ -210,6 +210,7 @@ _item_menu_scm_add_cb(void *data, Evas_Object *obj EINA_UNUSED, sd = data; edi_scm_add(sd->path); + edi_filepanel_update_path(sd->path); } static void @@ -227,6 +228,8 @@ _item_menu_scm_del_do_cb(void *data) edi_scm_del(sd->path); else ecore_file_unlink(sd->path); + + edi_filepanel_update_path(sd->path); } static void @@ -422,12 +425,85 @@ _item_clicked_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, evas_object_show(menu); } +static const char * +_file_icon_status(const char *path) +{ + Edi_Scm_Status_Code status; + + if (!edi_scm_enabled() || ecore_file_is_dir(path)) + return NULL; + + status = edi_scm_file_status(path); + switch (status) + { + case EDI_SCM_STATUS_NONE: + case EDI_SCM_STATUS_RENAMED: + case EDI_SCM_STATUS_DELETED: + case EDI_SCM_STATUS_RENAMED_STAGED: + case EDI_SCM_STATUS_DELETED_STAGED: + case EDI_SCM_STATUS_UNKNOWN: + case EDI_SCM_STATUS_ADDED: + return NULL; + case EDI_SCM_STATUS_ADDED_STAGED: + return "document-new"; + case EDI_SCM_STATUS_MODIFIED: + case EDI_SCM_STATUS_MODIFIED_STAGED: + return "document-save-as"; + case EDI_SCM_STATUS_UNTRACKED: + return "dialog-question"; + } + + return NULL; +} + +static char * +_file_path_status(const char *path) +{ + char *orig; + Edi_Scm_Status_Code status; + static char text[4096]; + + orig = basename((char *)path); + + if (!edi_scm_enabled() || ecore_file_is_dir(path)) + return orig; + + text[0] = '\0'; + strcat(text, orig); + + status = edi_scm_file_status(path); + switch (status) + { + case EDI_SCM_STATUS_NONE: + case EDI_SCM_STATUS_DELETED: + case EDI_SCM_STATUS_DELETED_STAGED: + case EDI_SCM_STATUS_UNKNOWN: + return text; + case EDI_SCM_STATUS_ADDED: + return strcat(text, _(" (Added & Unstaged)")); + case EDI_SCM_STATUS_ADDED_STAGED: + return strcat(text, _(" (Added)")); + case EDI_SCM_STATUS_RENAMED: + return strcat(text, _(" (Renamed & Unstaged)")); + case EDI_SCM_STATUS_RENAMED_STAGED: + return strcat(text, _(" (Renamed)")); + case EDI_SCM_STATUS_MODIFIED: + return strcat(text, _(" (Modified & Unstaged)")); + case EDI_SCM_STATUS_MODIFIED_STAGED: + return strcat(text, _(" (Modified)")); + case EDI_SCM_STATUS_UNTRACKED: + return strcat(text, _(" (Untracked)")); + } + + return text; +} + static char * _text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *source EINA_UNUSED) { Edi_Dir_Data *sd = data; - return strdup(basename((char *)sd->path)); + return strdup(_file_path_status(sd->path)); } static Eina_Hash *mime_entries = NULL; @@ -454,6 +530,7 @@ _content_get(void *data, Evas_Object *obj, const char *source) Edi_Content_Provider *provider; Edi_Dir_Data *sd = data; Evas_Object *ic; + const char *icon_name; if (strcmp(source, "elm.swallow.icon")) return NULL; @@ -461,10 +538,19 @@ _content_get(void *data, Evas_Object *obj, const char *source) provider = _get_provider_from_hashset(sd->path); ic = elm_icon_add(obj); - if (provider) - elm_icon_standard_set(ic, provider->icon); + + icon_name = _file_icon_status(sd->path); + if (icon_name) + { + elm_icon_standard_set(ic, icon_name); + } else - elm_icon_standard_set(ic, "empty"); + { + if (provider) + elm_icon_standard_set(ic, provider->icon); + else + elm_icon_standard_set(ic, "empty"); + } evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); evas_object_show(ic); @@ -705,6 +791,48 @@ _file_listing_fill(Edi_Dir_Data *dir, Elm_Object_Item *parent_it) } static void +_edi_filepanel_update_dir(const char *directory) +{ + Eina_List *files; + char *path; + char *file; + + files = ecore_file_ls(directory); + + EINA_LIST_FREE(files, file) + { + if (file[0] != '.') + { + path = edi_path_append(directory, file); + if (ecore_file_is_dir(path)) + _edi_filepanel_update_dir(path); + else + edi_filepanel_update_path(path); + free(path); + } + free(file); + } + + if (files) + eina_list_free(files); +} + +void +edi_filepanel_update_all(void) +{ + _edi_filepanel_update_dir(edi_project_get()); +} + +void edi_filepanel_update_path(const char *path) +{ + Elm_Object_Item *item = _file_listing_item_find(path); + if (!item) + return; + + elm_genlist_item_update(item); +} + +static void _file_listing_updated(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) { @@ -727,7 +855,9 @@ _file_listing_updated(void *data EINA_UNUSED, int type EINA_UNUSED, else if (type == EIO_MONITOR_DIRECTORY_DELETED) _file_listing_item_delete(ev->filename); else - DBG("Ignoring file update event for %s", ev->filename); + DBG("Ignoring file update event for %s", ev->filename); + + edi_filepanel_update_path(ev->filename); } /* Panel filtering */ diff --git a/src/bin/edi_filepanel.h b/src/bin/edi_filepanel.h index 83e08f7..046aeae 100644 --- a/src/bin/edi_filepanel.h +++ b/src/bin/edi_filepanel.h @@ -59,6 +59,22 @@ const char *edi_filepanel_selected_path_get(Evas_Object *obj); void edi_filepanel_select_path(const char *path); /** + * Notify a file change has occurred to trigger an update to item content. + * + * @param path The path of the file to be updated in the file panel. + * + * @ingroup UI + */ +void edi_filepanel_update_path(const char *path); + +/** + * Notify filepanel to update all file items. + * + * @ingroup UI + */ +void edi_filepanel_update_all(void); + +/** * Initialise a file panel search. * * @ingroup UI diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index 3813b5b..5679713 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -1023,6 +1023,7 @@ static void _edi_scm_stash_do_cb(void *data EINA_UNUSED) { edi_scm_stash(); + edi_filepanel_update_all(); } static void @@ -1049,6 +1050,7 @@ _edi_menu_scm_pull_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, edi_consolepanel_clear(); edi_consolepanel_show(); edi_scm_pull(); + edi_filepanel_update_all(); } static void @@ -1064,6 +1066,7 @@ _edi_menu_scm_push_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, edi_consolepanel_clear(); edi_consolepanel_show(); edi_scm_push(); + edi_filepanel_update_all(); } static void diff --git a/src/bin/screens/edi_file_screens.c b/src/bin/screens/edi_file_screens.c index d9c9a55..05e55ff 100644 --- a/src/bin/screens/edi_file_screens.c +++ b/src/bin/screens/edi_file_screens.c @@ -1,6 +1,7 @@ #include "Edi.h" #include "mainview/edi_mainview.h" #include "edi_file_screens.h" +#include "edi_filepanel.h" #include "edi_private.h" static Evas_Object *_parent_obj, *_popup, *_popup_dir, *_edi_file_screens_message_popup; @@ -156,6 +157,8 @@ _edi_file_screens_rename_cb(void *data, ecore_file_mv(existing_path, path); else edi_scm_move(existing_path, path); + + edi_filepanel_update_path(path); } evas_object_del(_popup); diff --git a/src/bin/screens/edi_scm_screens.c b/src/bin/screens/edi_scm_screens.c index f15c991..8abb686 100644 --- a/src/bin/screens/edi_scm_screens.c +++ b/src/bin/screens/edi_scm_screens.c @@ -5,6 +5,8 @@ #include "Edi.h" #include "mainview/edi_mainview.h" #include "edi_config.h" +#include "edi_filepanel.h" +#include "edi_file.h" #include "edi_consolepanel.h" #include "edi_scm_screens.h" #include "edi_private.h" @@ -78,9 +80,9 @@ _edi_scm_screens_commit_cb(void *data, } static void -_entry_lines_append(Elm_Code *code, char *diff) +_entry_lines_append(Elm_Code *code, char *diff_text) { - char *pos = diff; + char *pos = diff_text; char *start, *end = NULL; if (!*pos) return; @@ -103,6 +105,47 @@ _entry_lines_append(Elm_Code *code, char *diff) elm_code_file_line_append(code->file, start, end - start, NULL); } +static void +_set_icon_text(Evas_Object *icon, Eina_Strbuf *text, Edi_Scm_Status *status) +{ + eina_strbuf_append_printf(text, "%s ", status->path); + + switch (status->change) + { + case EDI_SCM_STATUS_ADDED: + case EDI_SCM_STATUS_ADDED_STAGED: + elm_icon_standard_set(icon, "document-new"); + eina_strbuf_append_printf(text, "(%s", _("Added")); + break; + case EDI_SCM_STATUS_MODIFIED: + case EDI_SCM_STATUS_MODIFIED_STAGED: + elm_icon_standard_set(icon, "document-save-as"); + eina_strbuf_append_printf(text, "(%s", _("Modified")); + break; + case EDI_SCM_STATUS_DELETED: + case EDI_SCM_STATUS_DELETED_STAGED: + elm_icon_standard_set(icon, "edit-delete"); + eina_strbuf_append_printf(text, "(%s", _("Deleted")); + break; + case EDI_SCM_STATUS_RENAMED: + case EDI_SCM_STATUS_RENAMED_STAGED: + elm_icon_standard_set(icon, "document-save-as"); + eina_strbuf_append_printf(text, "(%s", _("Renamed")); + break; + case EDI_SCM_STATUS_UNTRACKED: + elm_icon_standard_set(icon, "dialog-question"); + eina_strbuf_append_printf(text, "(%s", _("Untracked")); + break; + default: + elm_icon_standard_set(icon, "text-x-generic"); + } + + if (!status->staged && status->change != EDI_SCM_STATUS_UNTRACKED) + eina_strbuf_append(text, _(" & Unstaged)")); + else + eina_strbuf_append(text, ")"); +} + void edi_scm_screens_commit(Evas_Object *parent) { @@ -110,11 +153,10 @@ edi_scm_screens_commit(Evas_Object *parent) Evas_Object *list, *icon; Elm_Code_Widget *entry; Elm_Code *code; - Eina_Strbuf *text, *user; - Eina_List *l; + Eina_Strbuf *text; Edi_Scm_Engine *engine; Edi_Scm_Status *status; - char *diff; + char *diff_text; Eina_Bool staged_changes; engine= edi_scm_engine_get(); @@ -155,11 +197,11 @@ edi_scm_screens_commit(Evas_Object *parent) evas_object_show(label); elm_box_pack_end(hbox, label); - user = eina_strbuf_new(); - eina_strbuf_append_printf(user, "%s:<br><b>%s</b><br><%s>", _("Author"), + text = eina_strbuf_new(); + eina_strbuf_append_printf(text, "%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(user)); - eina_strbuf_free(user); + elm_object_text_set(label, eina_strbuf_string_get(text)); + eina_strbuf_reset(text); avatar = elm_image_add(hbox); edi_scm_screens_avatar_load(avatar, engine->remote_email_get()); @@ -172,7 +214,7 @@ edi_scm_screens_commit(Evas_Object *parent) 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_size_hint_min_set(cbox, 350 * elm_config_scale_get(), 100 * elm_config_scale_get()); evas_object_show(cbox); list = elm_list_add(box); @@ -186,48 +228,14 @@ edi_scm_screens_commit(Evas_Object *parent) if (edi_scm_status_get()) { - text = eina_strbuf_new(); - EINA_LIST_FOREACH(engine->statuses, l, status) + EINA_LIST_FREE(engine->statuses, status) { icon = elm_icon_add(box); - if (status->staged) - staged_changes = EINA_TRUE; - - eina_strbuf_append_printf(text, "%s ", status->path); - - switch (status->change) - { - case EDI_SCM_STATUS_ADDED: - elm_icon_standard_set(icon, "document-new"); - eina_strbuf_append_printf(text, "(%s) ", _("add")); - break; - case EDI_SCM_STATUS_MODIFIED: - elm_icon_standard_set(icon, "document-save-as"); - eina_strbuf_append_printf(text, "(%s) ", _("mod")); - break; - case EDI_SCM_STATUS_DELETED: - elm_icon_standard_set(icon, "edit-delete"); - eina_strbuf_append_printf(text, "(%s) ", _("del")); - break; - case EDI_SCM_STATUS_RENAMED: - elm_icon_standard_set(icon, "document-save-as"); - eina_strbuf_append_printf(text, "(%s) ", _("ren")); - break; - case EDI_SCM_STATUS_UNTRACKED: - elm_icon_standard_set(icon, "dialog-question"); - eina_strbuf_append_printf(text, "(%s)", _("untracked")); - break; - default: - elm_icon_standard_set(icon, "text-x-generic"); - } - - if (!status->staged && status->change != EDI_SCM_STATUS_UNTRACKED) - eina_strbuf_append_printf(text, "- %s", _("unstaged")); - + _set_icon_text(icon, text, status); elm_list_item_append(list, eina_strbuf_string_get(text), icon, NULL, NULL, NULL); - eina_strbuf_reset(text); - + if (status->staged) + staged_changes = EINA_TRUE; eina_stringshare_del(status->path); free(status); } @@ -265,8 +273,8 @@ edi_scm_screens_commit(Evas_Object *parent) elm_object_content_set(frame, input); elm_box_pack_end(box, frame); - diff = edi_scm_diff(); - if (strlen(diff)) + diff_text = edi_scm_diff(); + if (diff_text[0] && diff_text[1]) { frame = elm_frame_add(popup); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); @@ -277,7 +285,7 @@ edi_scm_screens_commit(Evas_Object *parent) cbox = elm_box_add(popup); 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, 350 * elm_config_scale_get(), 250 * elm_config_scale_get()); + evas_object_size_hint_min_set(cbox, 500 * elm_config_scale_get(), 250 * elm_config_scale_get()); evas_object_show(cbox); elm_object_content_set(frame, cbox); elm_box_pack_end(box, frame); @@ -294,10 +302,10 @@ edi_scm_screens_commit(Evas_Object *parent) evas_object_show(entry); elm_box_pack_end(cbox, entry); - _entry_lines_append(code, diff); + _entry_lines_append(code, diff_text); } - free(diff); + free(diff_text); button = elm_button_add(popup); elm_object_text_set(button, _("Cancel")); diff --git a/src/lib/edi_exe.c b/src/lib/edi_exe.c index bbfaf03..48d3ce9 100644 --- a/src/lib/edi_exe.c +++ b/src/lib/edi_exe.c @@ -135,7 +135,7 @@ edi_exe_response(const char *command) while ((fgets(buf, sizeof(buf), p)) != NULL) { - eina_strbuf_append_printf(lines, "%s", buf); + eina_strbuf_append(lines, buf); } pclose(p); diff --git a/src/lib/edi_scm.c b/src/lib/edi_scm.c index 2ab93be..f99ddc4 100644 --- a/src/lib/edi_scm.c +++ b/src/lib/edi_scm.c @@ -168,22 +168,34 @@ _parse_line(char *line) if (change[0] == 'A' || change[1] == 'A') { status->change = EDI_SCM_STATUS_ADDED; - if (change[0] == 'A') status->staged = EINA_TRUE; + if (change[0] == 'A') + { + status->staged = status->change = EDI_SCM_STATUS_ADDED_STAGED; + } } else if (change[0] == 'R' || change[1] == 'R') { status->change = EDI_SCM_STATUS_RENAMED; - if (change[0] == 'R') status->staged = EINA_TRUE; + if (change[0] == 'R') + { + status->staged = status->change = EDI_SCM_STATUS_RENAMED_STAGED; + } } else if (change[0] == 'M' || change[1] == 'M') { status->change = EDI_SCM_STATUS_MODIFIED; - if (change[0] == 'M') status->staged = EINA_TRUE; + if (change[0] == 'M') + { + status->staged = status->change = EDI_SCM_STATUS_MODIFIED_STAGED; + } } else if (change[0] == 'D' || change[1] == 'D') { status->change = EDI_SCM_STATUS_DELETED; - if (change[0] == 'D') status->staged = EINA_TRUE; + if (change[0] == 'D') + { + status->staged = status->change = EDI_SCM_STATUS_DELETED_STAGED; + } } else if (change[0] == '?' && change[1] == '?') { @@ -200,26 +212,27 @@ _parse_line(char *line) static Edi_Scm_Status_Code _edi_scm_git_file_status(const char *path) { - Eina_Strbuf *command; Edi_Scm_Status *status; - Edi_Scm_Status_Code result; + char command[4096]; char *line; + Edi_Scm_Status_Code result; - command = eina_strbuf_new(); - - eina_strbuf_append_printf(command, "git status --porcelain %s", path); - - line = _edi_scm_exec_response(eina_strbuf_string_get(command)); - - status = _parse_line(line); + snprintf(command, sizeof(command), "git status --porcelain '%s'", path); - eina_strbuf_free(command); + line = _edi_scm_exec_response(command); + if (!line[0] || !line[1]) + { + result = EDI_SCM_STATUS_NONE; + } + else + { + status = _parse_line(line); + result = status->change; + eina_stringshare_del(status->path); + free(status); + } free(line); - result = status->change; - - eina_stringshare_del(status->path); - free(status); return result; } @@ -468,6 +481,9 @@ edi_scm_enabled(void) if (!engine) return EINA_FALSE; + if (!engine->initialized) + return EINA_FALSE; + return _edi_scm_enabled(engine); } @@ -687,6 +703,8 @@ _edi_scm_git_init() engine->credentials_set = _edi_scm_git_credentials_set; engine->status_get = _edi_scm_git_status_get; + engine->initialized = EINA_TRUE; + return engine; } diff --git a/src/lib/edi_scm.h b/src/lib/edi_scm.h index 3e8676a..c3842ca 100644 --- a/src/lib/edi_scm.h +++ b/src/lib/edi_scm.h @@ -11,11 +11,16 @@ extern "C" { */ typedef enum { - EDI_SCM_STATUS_ADDED = 1, + EDI_SCM_STATUS_NONE = 0, + EDI_SCM_STATUS_ADDED, EDI_SCM_STATUS_DELETED, EDI_SCM_STATUS_MODIFIED, EDI_SCM_STATUS_RENAMED, EDI_SCM_STATUS_UNTRACKED, + EDI_SCM_STATUS_ADDED_STAGED, + EDI_SCM_STATUS_DELETED_STAGED, + EDI_SCM_STATUS_MODIFIED_STAGED, + EDI_SCM_STATUS_RENAMED_STAGED, EDI_SCM_STATUS_UNKNOWN, } Edi_Scm_Status_Code; @@ -70,6 +75,7 @@ typedef struct _Edi_Scm_Engine scm_fn_remote_url *remote_url_get; scm_fn_credentials *credentials_set; scm_fn_status_get *status_get; + Eina_Bool initialized; } Edi_Scm_Engine; /** --