#ifdef HAVE_CONFIG_H # include "config.h" #endif #include "Edi.h" #include "edi_scm_ui.h" #include "edi_private.h" static Evas_Object *_parent_obj, *_popup, *_edi_scm_ui_screens_message_popup; static Evas_Object *_list, *_check; static Evas_Object *_commit_button, *_commit_entry; static Elm_Code *_code; static Eina_Bool scm_configured = EINA_FALSE; static Eina_Bool results_full = EINA_FALSE; static void _edi_scm_ui_refresh(void); const char * _edi_scm_ui_avatar_cache_path_get(const char *email) { return eina_stringshare_printf("%s/%s/avatars/%s.jpeg", efreet_cache_home_get(), PACKAGE_NAME, email); } void _edi_scm_ui_screens_avatar_download_complete(void *data, const char *file, int status) { Evas_Object *image = data; if (status != 200) { ecore_file_remove(file); return; } elm_image_file_set(image, file, NULL); } static void _edi_scm_ui_screens_avatar_load(Evas_Object *image, const char *email) { const char *tmp, *cache, *cachedir, *cacheparentdir; cache = _edi_scm_ui_avatar_cache_path_get(email); if (ecore_file_exists(cache)) { elm_image_file_set(image, cache, NULL); return; } tmp = dirname((char *) cache); cachedir = strdup(tmp); cacheparentdir = dirname((char *) tmp); if (!ecore_file_exists(cacheparentdir) && !ecore_file_mkdir(cacheparentdir)) goto clear; if (!ecore_file_exists(cachedir) && !ecore_file_mkdir(cachedir)) goto clear; ecore_file_download(edi_scm_avatar_url_get(email), cache, _edi_scm_ui_screens_avatar_download_complete, NULL, image, NULL); clear: free((char *)cachedir); } static void _edi_scm_ui_screens_message_close_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *popup = data; evas_object_del(popup); elm_exit(); } static void _edi_scm_ui_screens_message_open(const char *message) { Evas_Object *popup, *button; _edi_scm_ui_screens_message_popup = popup = elm_popup_add(_parent_obj); elm_object_part_text_set(popup, "title,text", message); button = elm_button_add(popup); elm_object_text_set(button, _("OK")); elm_object_part_content_set(popup, "button1", button); evas_object_smart_callback_add(button, "clicked", _edi_scm_ui_screens_message_close_cb, popup); evas_object_show(popup); } static void _edi_scm_ui_screens_popup_cancel_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { evas_object_del((Evas_Object *) data); } static void _edi_scm_ui_screens_commit_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Edi_Scm_Engine *engine; const char *text; char *message; engine = edi_scm_engine_get(); // engine has been checked before now if (!engine) return; text = elm_object_text_get((Evas_Object *) data); if (!text || !text[0]) { _edi_scm_ui_screens_message_open(_("Please enter a valid commit message.")); return; } message = elm_entry_markup_to_utf8(text); edi_scm_commit(message); evas_object_del(_popup); free(message); elm_exit(); } static void _entry_lines_append(Elm_Code *code, char *text) { char *pos = text; char *start, *end = NULL; if (!*pos) return; start = pos; while (*pos++ != '\0') { if (*pos == '\n') end = pos; if (start && end) { elm_code_file_line_append(code->file, start, end - start, NULL); start = end + 1; end = NULL; } } end = pos; if (end > start) elm_code_file_line_append(code->file, start, end - start, NULL); } static const char * _icon_status(Edi_Scm_Status_Code code) { switch (code) { case EDI_SCM_STATUS_NONE: case EDI_SCM_STATUS_UNKNOWN: return NULL; case EDI_SCM_STATUS_RENAMED: return "document-new"; case EDI_SCM_STATUS_DELETED: return "edit-delete"; case EDI_SCM_STATUS_RENAMED_STAGED: return "document-new"; case EDI_SCM_STATUS_DELETED_STAGED: return "edit-delete"; case EDI_SCM_STATUS_ADDED: return "document-new"; case EDI_SCM_STATUS_ADDED_STAGED: return "document-new"; case EDI_SCM_STATUS_MODIFIED: return "document-save-as"; case EDI_SCM_STATUS_MODIFIED_STAGED: return "document-save-as"; case EDI_SCM_STATUS_UNTRACKED: return "dialog-question"; } return NULL; } static void _edi_scm_ui_status_free(Edi_Scm_Status *status) { eina_stringshare_del(status->fullpath); eina_stringshare_del(status->path); eina_stringshare_del(status->unescaped); free(status); } static void _content_del(void *data, Evas_Object *obj EINA_UNUSED) { Edi_Scm_Status *status = (Edi_Scm_Status *) data; _edi_scm_ui_status_free(status); } static Evas_Object * _content_get(void *data, Evas_Object *obj, const char *source) { Evas_Object *box, *lbox, *mbox, *rbox, *label, *ic; const char *text, *icon_name, *icon_status, *mime; Edi_Scm_Status *status; if (strcmp(source, "elm.swallow.content")) return NULL; status = (Edi_Scm_Status *) data; icon_status = _icon_status(status->change); mime = efreet_mime_type_get(status->fullpath); if (mime) icon_name = efreet_mime_type_icon_get(mime, elm_config_icon_theme_get(), 32); if (!icon_name) 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, status->unescaped); 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 (status->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 (status->change != 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 _edi_scm_ui_status_list_fill(Evas_Object *list) { Elm_Genlist_Item_Class *itc; Edi_Scm_Status *status; Edi_Scm_Engine *e; Eina_List *l; Eina_Bool staged = EINA_FALSE; e = edi_scm_engine_get(); if (!e) return EINA_FALSE; 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_FOREACH(e->statuses, l, status) { if (results_full) { elm_genlist_item_append(list, itc, status, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); } else { if (status->staged) elm_genlist_item_append(list, itc, status, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); else _edi_scm_ui_status_free(status); } if (status->staged) staged = EINA_TRUE; } } if (e->statuses) { eina_list_free(e->statuses); e->statuses = NULL; } elm_genlist_item_class_free(itc); return staged; } static void _edi_scm_ui_refresh(void) { char *text; Eina_Bool staged; Evas_Object *check = _check; results_full = elm_check_state_get(check); elm_genlist_clear(_list); elm_code_file_clear(_code->file); staged = _edi_scm_ui_status_list_fill(_list); if (!scm_configured) { elm_object_disabled_set(_commit_button, EINA_TRUE); elm_entry_editable_set(_commit_entry, EINA_FALSE); } else { elm_object_disabled_set(_commit_button, !staged); elm_entry_editable_set(_commit_entry, staged); } elm_genlist_realized_items_update(_list); text = edi_scm_diff(!results_full); _entry_lines_append(_code, text); free(text); } static void _edi_scm_ui_refresh_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { _edi_scm_ui_refresh(); } void edi_scm_ui_add(Evas_Object *parent) { Evas_Object *box, *frame, *hbox, *cbox, *label, *avatar, *input, *button; Evas_Object *table, *rect, *list, *pbox, *check, *sep; Elm_Code_Widget *entry; Elm_Code *code; Eina_Strbuf *string; Edi_Scm_Engine *engine; const char *remote_name, *remote_email; char *text; Eina_Bool staged_changes; _parent_obj = parent; if (!edi_scm_generic_init()) exit(1 << 2); engine = edi_scm_engine_get(); if (!engine) exit(1 << 3); box = elm_box_add(parent); elm_box_horizontal_set(box, EINA_FALSE); evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_content_set(parent, box); evas_object_show(box); hbox = elm_box_add(parent); elm_box_horizontal_set(hbox, EINA_TRUE); evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(hbox); /* General information*/ label = elm_label_add(hbox); evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(label); elm_box_pack_end(hbox, label); remote_name = engine->remote_name_get(); remote_email = engine->remote_email_get(); string = eina_strbuf_new(); if (!remote_name[0] && !remote_email[0]) { eina_strbuf_append(string, _("Unable to obtain user information.")); } else { eina_strbuf_append_printf(string, "%s:
%s
<%s>", _("Author"), engine->remote_name_get(), engine->remote_email_get()); avatar = elm_image_add(hbox); _edi_scm_ui_screens_avatar_load(avatar, engine->remote_email_get()); evas_object_size_hint_min_set(avatar, 48 * elm_config_scale_get(), 48 * elm_config_scale_get()); evas_object_size_hint_weight_set(avatar, 0.1, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(avatar, 1.0, EVAS_HINT_FILL); evas_object_show(avatar); elm_box_pack_end(hbox, avatar); scm_configured = EINA_TRUE; } elm_object_text_set(label, eina_strbuf_string_get(string)); eina_strbuf_free(string); elm_box_pack_end(box, hbox); /* Options */ hbox = elm_box_add(parent); evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_box_horizontal_set(hbox, EINA_TRUE); _check = check = elm_check_add(parent); elm_object_text_set(check, _("Show all changes?")); elm_check_state_set(check, EINA_FALSE); evas_object_show(check); elm_box_pack_end(hbox, check); pbox = elm_box_add(parent); evas_object_size_hint_weight_set(pbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(pbox, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(pbox); elm_box_pack_end(hbox, pbox); evas_object_show(hbox); evas_object_smart_callback_add(check, "changed", _edi_scm_ui_refresh_cb, NULL); elm_box_pack_end(box, hbox); sep = elm_separator_add(parent); elm_separator_horizontal_set(sep, EINA_TRUE); evas_object_show(sep); elm_box_pack_end(box, sep); hbox = elm_box_add(parent); elm_box_horizontal_set(hbox, EINA_TRUE); evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(hbox); /* File listting */ _list = 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); evas_object_show(list); table = elm_table_add(parent); 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(parent); 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(hbox, frame); elm_box_pack_end(box, hbox); staged_changes = _edi_scm_ui_status_list_fill(list); /* Commit entry */ table = elm_table_add(parent); 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(parent); 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); _commit_entry = input = elm_entry_add(box); elm_object_text_set(input, _("Enter commit summary

And change details
")); evas_object_size_hint_weight_set(input, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 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_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, table); elm_box_pack_end(hbox, frame); elm_box_pack_end(box, hbox); /* Start of elm_code diff widget */ frame = elm_frame_add(parent); 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, _("Source changes")); evas_object_show(frame); cbox = elm_box_add(parent); 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(), 150 * elm_config_scale_get()); evas_object_show(cbox); elm_object_content_set(frame, cbox); elm_box_pack_end(box, frame); _code = code = elm_code_create(); entry = elm_code_widget_add(box, code); elm_code_parser_standard_add(code, ELM_CODE_PARSER_STANDARD_DIFF); elm_obj_code_widget_gravity_set(entry, 0.0, 1.0); elm_obj_code_widget_editable_set(entry, EINA_FALSE); elm_obj_code_widget_line_numbers_set(entry, EINA_FALSE); evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(entry); elm_box_pack_end(cbox, entry); text = edi_scm_diff(EINA_TRUE); _entry_lines_append(code, text); free(text); sep = elm_separator_add(parent); elm_separator_horizontal_set(sep, EINA_TRUE); evas_object_show(sep); elm_box_pack_end(box, sep); /* Start of confirm and cancel buttons */ hbox = elm_box_add(parent); evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_box_horizontal_set(hbox, EINA_TRUE); evas_object_show(hbox); button = elm_button_add(parent); evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(button); elm_object_text_set(button, _("Cancel")); evas_object_smart_callback_add(button, "clicked", _edi_scm_ui_screens_popup_cancel_cb, parent); elm_box_pack_end(hbox, button); _commit_button = button = elm_button_add(parent); evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_data_set(button, "input", input); evas_object_show(button); elm_object_text_set(button, _("Commit")); elm_object_disabled_set(button, !staged_changes); evas_object_smart_callback_add(button, "clicked", _edi_scm_ui_screens_commit_cb, input); elm_box_pack_end(hbox, button); elm_box_pack_end(box, hbox); if (staged_changes && scm_configured) { elm_entry_select_all(input); elm_object_focus_set(input, EINA_TRUE); } }