From fe2714ea7e2cba30ee194b8f98524ab06328778d Mon Sep 17 00:00:00 2001 From: Al Poole Date: Mon, 21 Aug 2017 17:14:09 +0100 Subject: [PATCH] editor: handle file modifications properly. Reviewers: ajwillia.ms Reviewed By: ajwillia.ms Differential Revision: https://phab.enlightenment.org/D5114 --- src/bin/edi_filepanel.c | 29 +++++- src/bin/editor/edi_editor.c | 127 +++++++++++++++++--------- src/bin/editor/edi_editor.h | 9 ++ src/bin/mainview/edi_mainview.h | 2 +- src/bin/mainview/edi_mainview_panel.c | 24 +++-- 5 files changed, 138 insertions(+), 53 deletions(-) diff --git a/src/bin/edi_filepanel.c b/src/bin/edi_filepanel.c index 3188f97..43c0321 100644 --- a/src/bin/edi_filepanel.c +++ b/src/bin/edi_filepanel.c @@ -106,32 +106,51 @@ static void _item_menu_open_as_text_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { + Edi_Mainview_Panel *panel; + Edi_Path_Options *options; Edi_Dir_Data *sd; sd = data; - edi_mainview_item_close_path(sd->path); - _open_cb(sd->path, "text", EINA_FALSE); + + panel = edi_mainview_panel_current_get(); + options = edi_path_options_create(sd->path); + edi_mainview_panel_item_close_path(panel, sd->path); + options->type = "text"; + edi_mainview_panel_open(panel, options); } static void _item_menu_open_as_code_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { + Edi_Mainview_Panel *panel; + Edi_Path_Options *options; Edi_Dir_Data *sd; sd = data; - edi_mainview_item_close_path(sd->path); - _open_cb(sd->path, "code", EINA_FALSE); + + panel = edi_mainview_panel_current_get(); + options = edi_path_options_create(sd->path); + edi_mainview_panel_item_close_path(panel, sd->path); + options->type = "code"; + edi_mainview_panel_open(panel, options); } static void _item_menu_open_as_image_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { + Edi_Mainview_Panel *panel; + Edi_Path_Options *options; Edi_Dir_Data *sd; sd = data; - _open_cb(sd->path, "image", EINA_FALSE); + + panel = edi_mainview_panel_current_get(); + options = edi_path_options_create(sd->path); + edi_mainview_panel_item_close_path(panel, sd->path); + options->type = "image"; + edi_mainview_panel_open(panel, options); } static void diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index d9fb404..ea02435 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -34,19 +34,14 @@ static void _edi_editor_file_change_reload_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) { Edi_Editor *editor; - const char *filename; - Elm_Code *code; editor = (Edi_Editor *)data; if (!editor) return; - code = elm_code_widget_code_get(editor->entry); - filename = elm_code_file_path_get(code->file); - - edi_mainview_close(); - edi_mainview_open_path(filename); + edi_editor_reload(editor); evas_object_del(editor->popup); + editor->popup = NULL; } static void @@ -60,44 +55,60 @@ _edi_editor_file_change_ignore_cb(void *data, Evas_Object *obj EINA_UNUSED, void edi_editor_save(editor); editor->save_time = time(NULL); evas_object_del(editor->popup); + editor->popup = NULL; } static void -_edi_editor_file_change_popup(Edi_Editor *editor) +_edi_editor_file_change_popup(Evas_Object *parent, Edi_Editor *editor) { - Evas_Object *box, *table; - Evas_Object *label, *bt_reload, *bt_ignore; + Evas_Object *table, *box, *label, *sep, *icon, *button; - editor->popup = elm_popup_add(editor->entry); + if (editor->popup) + return; + + editor->popup = elm_popup_add(parent); + elm_popup_orient_set(editor->popup, ELM_POPUP_ORIENT_CENTER); elm_popup_scrollable_set(editor->popup, EINA_TRUE); - elm_object_part_text_set(editor->popup, "title,text", "File has changed..."); + elm_object_part_text_set(editor->popup, "title,text", "Confirmation"); evas_object_size_hint_align_set(editor->popup, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(editor->popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(editor->popup); + + table = elm_table_add(editor->popup); + icon = elm_icon_add(table); + elm_icon_standard_set(icon, "dialog-warning"); + evas_object_size_hint_min_set(icon, 47 * elm_config_scale_get(), 48 * elm_config_scale_get()); + evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(icon); + elm_table_pack(table, icon, 0, 0, 1, 1); box = elm_box_add(editor->popup); label = elm_label_add(editor->popup); - elm_object_text_set(label, "File has changed on disk."); + elm_object_text_set(label, "File contents have changed. Would you like to refresh
the contents of this file?"); evas_object_show(label); elm_box_pack_end(box, label); - table = elm_table_add(editor->popup); - bt_reload = elm_button_add(editor->popup); - elm_object_text_set(bt_reload, "Reload"); - elm_table_pack(table, bt_reload, 0, 0, 1, 1); - evas_object_smart_callback_add(bt_reload, "clicked", _edi_editor_file_change_reload_cb, editor); - evas_object_show(bt_reload); + sep = elm_separator_add(box); + elm_separator_horizontal_set(sep, EINA_TRUE); + evas_object_show(sep); + elm_box_pack_end(box, sep); + evas_object_show(box); + elm_table_pack(table, box, 1, 0, 1, 1); - bt_ignore = elm_button_add(editor->popup); - elm_object_text_set(bt_ignore, "Ignore"); - elm_table_pack(table, bt_ignore, 1, 0, 1, 1); - evas_object_smart_callback_add(bt_ignore, "clicked", _edi_editor_file_change_ignore_cb, editor); - - elm_box_pack_end(box, table); - evas_object_show(bt_ignore); - elm_object_content_set(editor->popup, box); + elm_object_content_set(editor->popup, table); evas_object_show(table); - evas_object_resize(editor->popup, 200 * elm_config_scale_get(), 200 * elm_config_scale_get()); + + button = elm_button_add(editor->popup); + elm_object_text_set(button, "Refresh"); + elm_object_part_content_set(editor->popup, "button1", button); + evas_object_smart_callback_add(button, "clicked", _edi_editor_file_change_reload_cb, editor); + + button = elm_button_add(editor->popup); + elm_object_text_set(button, "No, continue editing"); + elm_object_part_content_set(editor->popup, "button2", button); + evas_object_smart_callback_add(button, "clicked", _edi_editor_file_change_ignore_cb, editor); + + evas_object_show(editor->popup); } void @@ -105,7 +116,6 @@ edi_editor_save(Edi_Editor *editor) { Elm_Code *code; const char *filename; - time_t mtime; if (!editor->modified) return; @@ -114,17 +124,6 @@ edi_editor_save(Edi_Editor *editor) filename = elm_code_file_path_get(code->file); - mtime = ecore_file_mod_time(filename); - - if ((editor->save_time) && (editor->save_time < mtime)) - { - ecore_timer_del(editor->save_timer); - editor->save_timer = NULL; - _edi_editor_file_change_popup(editor); - editor->modified = EINA_FALSE; - return; - } - edi_mainview_save(); editor->save_time = ecore_file_mod_time(filename); @@ -966,11 +965,31 @@ _focused_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUS { Edi_Mainview_Panel *panel; Edi_Mainview_Item *item; + Elm_Code *code; + Edi_Editor *editor; + const char *filename; + time_t mtime; item = (Edi_Mainview_Item *)data; panel = edi_mainview_panel_for_item_get(item); edi_mainview_panel_focus(panel); + + editor = evas_object_data_get(obj, "editor"); + + code = elm_code_widget_code_get(editor->entry); + filename = elm_code_file_path_get(code->file); + + mtime = ecore_file_mod_time(filename); + + if ((editor->save_time) && (editor->save_time < mtime)) + { + ecore_timer_del(editor->save_timer); + editor->save_timer = NULL; + _edi_editor_file_change_popup(evas_object_smart_parent_get(obj), editor); + editor->modified = EINA_FALSE; + return; + } } static void @@ -1079,6 +1098,31 @@ _editor_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o, void *event_info edi_language_provider_get(editor)->del(editor); } +void +edi_editor_reload(Edi_Editor *editor) +{ + Elm_Code *code; + const char *path; + + ecore_thread_main_loop_begin(); + + code = elm_code_widget_code_get(editor->entry); + path = elm_code_file_path_get(code->file); + elm_code_file_clear(code->file); + code->file = elm_code_file_open(code, path); + + editor->modified = EINA_FALSE; + editor->save_time = ecore_file_mod_time(path); + + if (editor->save_timer) + { + ecore_timer_del(editor->save_timer); + editor->save_timer = NULL; + } + + ecore_thread_main_loop_end(); +} + Evas_Object * edi_editor_add(Evas_Object *parent, Edi_Mainview_Item *item) { @@ -1123,6 +1167,7 @@ edi_editor_add(Evas_Object *parent, Edi_Mainview_Item *item) editor = calloc(1, sizeof(*editor)); editor->entry = widget; editor->mimetype = item->mimetype; + evas_object_data_set(widget, "editor", editor); evas_object_event_callback_add(widget, EVAS_CALLBACK_KEY_DOWN, _smart_cb_key_down, editor); evas_object_smart_callback_add(widget, "changed,user", _changed_cb, editor); diff --git a/src/bin/editor/edi_editor.h b/src/bin/editor/edi_editor.h index 888c9e5..7db9abc 100644 --- a/src/bin/editor/edi_editor.h +++ b/src/bin/editor/edi_editor.h @@ -87,6 +87,15 @@ struct _Edi_Editor */ Evas_Object *edi_editor_add(Evas_Object *parent, Edi_Mainview_Item *item); +/** + * Reload existing editor's content from disk. + * + * @param editor the editor instance to reload content from. + * + * @ingroup Editor + */ +void edi_editor_reload(Edi_Editor *editor); + /** * @} * diff --git a/src/bin/mainview/edi_mainview.h b/src/bin/mainview/edi_mainview.h index 895400b..ce9fd39 100644 --- a/src/bin/mainview/edi_mainview.h +++ b/src/bin/mainview/edi_mainview.h @@ -54,7 +54,7 @@ void edi_mainview_add(Evas_Object *parent, Evas_Object *win); /** * Close mainview by path. * - * @praram path The path of file to close. + * @param path The path of file to close. * * @ingroup Content */ diff --git a/src/bin/mainview/edi_mainview_panel.c b/src/bin/mainview/edi_mainview_panel.c index 84f7e7e..3efccc6 100644 --- a/src/bin/mainview/edi_mainview_panel.c +++ b/src/bin/mainview/edi_mainview_panel.c @@ -34,6 +34,7 @@ edi_mainview_panel_item_count(Edi_Mainview_Panel *panel) Edi_Mainview_Item * edi_mainview_panel_item_current_get(Edi_Mainview_Panel *panel) { + if (!panel) return NULL; return panel->current; } @@ -207,7 +208,8 @@ edi_mainview_panel_item_close(Edi_Mainview_Panel *panel, Edi_Mainview_Item *item return; edi_mainview_item_prev(); - evas_object_del(item->view); + if (item->view) + evas_object_del(item->view); elm_box_unpack(panel->tabs, item->tab); evas_object_del(item->tab); panel->items = eina_list_remove(panel->items, item); @@ -309,6 +311,7 @@ _edi_mainview_panel_item_tab_add(Edi_Mainview_Panel *panel, Edi_Path_Options *op Evas_Object *content, *tab;//, *icon; Edi_Mainview_Item *item; Edi_Editor *editor; + Elm_Code *code; if (!panel) return; @@ -345,7 +348,12 @@ _edi_mainview_panel_item_tab_add(Edi_Mainview_Panel *panel, Edi_Path_Options *op // Set focus on the newly opening window so that one can just start typing editor = (Edi_Editor *)evas_object_data_get(content, "editor"); if (editor) - elm_object_focus_set(editor->entry, EINA_TRUE); + { + elm_object_focus_set(editor->entry, EINA_TRUE); + code = elm_code_widget_code_get(editor->entry); + editor->save_time = ecore_file_mod_time(elm_code_file_path_get(code->file)); + editor->modified = EINA_FALSE; + } if (options->line) { @@ -364,6 +372,8 @@ _get_item_for_path(Edi_Mainview_Panel *panel, const char *path) Eina_List *item; Edi_Mainview_Item *it; + if (!panel) return NULL; + EINA_LIST_FOREACH(panel->items, item, it) { if (it && !strcmp(it->path, path)) @@ -417,14 +427,14 @@ edi_mainview_panel_save(Edi_Mainview_Panel *panel) Elm_Code *code; editor = (Edi_Editor *)evas_object_data_get(panel->current->view, "editor"); - if (!editor) return; - editor->modified = EINA_FALSE; - code = elm_code_widget_code_get(editor->entry); elm_code_file_save(code->file); + editor->save_time = ecore_file_mod_time(elm_code_file_path_get(code->file)); + editor->modified = EINA_FALSE; + ecore_event_add(EDI_EVENT_FILE_SAVED, NULL, NULL, NULL); } @@ -727,7 +737,7 @@ edi_mainview_panel_refresh_all(Edi_Mainview_Panel *panel) EINA_LIST_FOREACH(panel->items, item, it) { options = edi_path_options_create(it->path); - options->type = eina_stringshare_add(it->mimetype); + options->type = eina_stringshare_add(it->editortype); options->background = it != panel->current; tabs = eina_list_append(tabs, options); @@ -753,6 +763,8 @@ edi_mainview_panel_item_close_path(Edi_Mainview_Panel *panel, const char *path) Eina_List *item; Edi_Mainview_Item *it; + if (!panel) return; + EINA_LIST_FOREACH(panel->items, item, it) { if (it && !strcmp(it->path, path))