From 8b39637a628cba915e81f836aad74ec05bf0c285 Mon Sep 17 00:00:00 2001 From: Lars Henriksen Date: Sun, 26 Aug 2018 14:45:58 +0200 Subject: Move user information after save/reload to the command level Moving user information to calcurse.c makes it easier to perform the actual save/reload operatons in io.c, e.g. it is possible to load instead of reload after a merge in conflict resolving. The save/reload operations are of such importance that the user should always be informed of the result (it's a bit disquieting when there is no reaction to a save or reload command). Hence, the save/reload status messages are no longer conditioned by show_dialogs(). No confirmation is asked for, so a message stays until the status bar is updated by another action. Care is taken to inform about save/reload actions that result in no change. Texts are kept concise because of the limited message area. When conflicts are present, whether saving or reloading, the "continue/merge/cancel" pattern seems easier to grasp. Signed-off-by: Lars Henriksen Signed-off-by: Lukas Fleischer --- src/calcurse.c | 44 ++++++++++++++++++++++++++++++++++++++++-- src/calcurse.h | 14 ++++++++++++-- src/io.c | 60 +++++++++++++++++++++++++--------------------------------- 3 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/calcurse.c b/src/calcurse.c index 533f78c..4560e5c 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -271,7 +271,12 @@ static inline void key_generic_help(void) static inline void key_generic_save(void) { - if (io_save_cal(IO_SAVE_DISPLAY_BAR) == IO_SAVE_RELOAD) { + char *msg = NULL; + int ret; + + ret = io_save_cal(IO_SAVE_DISPLAY_BAR); + + if (ret == IO_SAVE_RELOAD) { ui_todo_load_items(); ui_todo_sel_reset(); do_storage(0); @@ -279,11 +284,30 @@ static inline void key_generic_save(void) ui_calendar_monthly_view_cache_set_invalid(); } wins_update(FLAG_ALL); + switch (ret) { + case IO_SAVE_CTINUE: + msg = _("Data were saved successfully"); + break; + case IO_SAVE_RELOAD: + msg = _("Data were saved/reloaded successfully"); + break; + case IO_SAVE_CANCEL: + msg = _("Save cancelled"); + break; + case IO_SAVE_NOOP: + msg = _("Data were already saved"); + break; + } + status_mesg(msg, ""); } static inline void key_generic_reload(void) { - if (io_reload_data()) { + char *msg = NULL; + int ret; + + ret = io_reload_data(); + if (ret != IO_RELOAD_CANCEL && ret != IO_RELOAD_NOOP) { ui_todo_load_items(); ui_todo_sel_reset(); do_storage(0); @@ -291,6 +315,22 @@ static inline void key_generic_reload(void) ui_calendar_monthly_view_cache_set_invalid(); } wins_update(FLAG_ALL); + switch (ret) { + case IO_RELOAD_LOAD: + case IO_RELOAD_CTINUE: + msg = _("Data were reloaded successfully"); + break; + case IO_RELOAD_MERGE: + msg = _("Date were merged/reloaded successfully"); + break; + case IO_RELOAD_CANCEL: + msg = _("Reload cancelled"); + break; + case IO_RELOAD_NOOP: + msg = _("Data were already loaded"); + break; + } + status_mesg(msg, ""); } static inline void key_generic_import(void) diff --git a/src/calcurse.h b/src/calcurse.h index ddeec21..bec2a93 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -658,7 +658,17 @@ enum getstr { enum { IO_SAVE_CTINUE, IO_SAVE_RELOAD, - IO_SAVE_CANCEL + IO_SAVE_CANCEL, + IO_SAVE_NOOP +}; + +/* Return codes for the io_reload_data() function. */ +enum { + IO_RELOAD_LOAD, + IO_RELOAD_CTINUE, + IO_RELOAD_MERGE, + IO_RELOAD_CANCEL, + IO_RELOAD_NOOP }; /* Week days. */ @@ -860,7 +870,7 @@ unsigned io_save_keys(void); int io_save_cal(enum save_display); void io_load_app(struct item_filter *); void io_load_todo(struct item_filter *); -void io_load_data(struct item_filter *, int); +int io_load_data(struct item_filter *, int); int io_reload_data(void); void io_load_keys(const char *); int io_check_dir(const char *); diff --git a/src/io.c b/src/io.c index 1ca2c2f..e63182d 100644 --- a/src/io.c +++ b/src/io.c @@ -503,12 +503,12 @@ static int resolve_save_conflict(void) { char *msg_um_asktype = NULL; const char *msg_um_prefix = - _("Data have changed since loaded:"); - const char *msg_um_overwrite = _("(o)verwrite"); + _("Data files have changed and will be overwritten:"); + const char *msg_um_overwrite = _("(c)ontinue"); const char *msg_um_merge = _("(m)erge"); - const char *msg_um_keep = _("(c)ancel"); - const char *msg_um_choice = _("[omc]"); - int ret; + const char *msg_um_keep = _("c(a)ncel"); + const char *msg_um_choice = _("[cma]"); + int ret = IO_SAVE_CANCEL; asprintf(&msg_um_asktype, "%s %s, %s, %s", msg_um_prefix, msg_um_overwrite, msg_um_merge, msg_um_keep); @@ -519,7 +519,7 @@ static int resolve_save_conflict(void) break; case 2: io_merge_data(); - io_reload_data(); + io_load_data(NULL, FORCE); ret = IO_SAVE_RELOAD; break; case 3: @@ -573,14 +573,12 @@ cleanup: * The return value tells how a possible save conflict should be/was resolved: * IO_SAVE_CTINUE: continue save operation and overwrite the data files * IO_SAVE_RELOAD: cancel save operation (data files changed and reloaded) - * IO_SAVE_CANCEL: cancel save operation (keep data files, no reload) + * IO_SAVE_CANCEL: cancel save operation (user's decision, keep data files, no reload) + * IO_SAVE_NOOP: cancel save operation (nothing has changed) */ int io_save_cal(enum save_display display) { const char *access_pb = _("Problems accessing data file ..."); - const char *save_success = - _("The data files were successfully saved"); - const char *enter = _("Press [ENTER] to continue"); int show_bar, ret = IO_SAVE_CTINUE; if (read_only) @@ -591,7 +589,7 @@ int io_save_cal(enum save_display display) return ret; } else if (!io_get_modified()) - return IO_SAVE_CANCEL; + return IO_SAVE_NOOP; run_hook("pre-save"); io_mutex_lock(); @@ -623,13 +621,6 @@ int io_save_cal(enum save_display display) io_unset_modified(); - /* Print a message telling data were saved */ - if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_BAR && - show_dialogs()) { - status_mesg(save_success, enter); - keys_wait_for_any_key(win[KEY].p); - } - io_compute_hash(path_apts, apts_sha1); io_compute_hash(path_todo, todo_sha1); @@ -925,8 +916,9 @@ void io_load_todo(struct item_filter *filter) * Load appointments and todo items. * Unless told otherwise, the function will only load a file that has changed * since last saved or loaded, see new_data() return codes. + * Return codes are for use in io_reload_data() only. */ -void io_load_data(struct item_filter *filter, int force) +int io_load_data(struct item_filter *filter, int force) { run_hook("pre-load"); if (force) @@ -957,24 +949,25 @@ void io_load_data(struct item_filter *filter, int force) io_mutex_unlock(); run_hook("post-load"); + return force; } +/* + * The return codes reflect the user choice in case of unsaved in-memory changes. + */ int io_reload_data(void) { char *msg_um_asktype = NULL; - const char *reload_success = - _("The data files were reloaded successfully"); - const char *enter = _("Press [ENTER] to continue"); - int ret = 0; int load = NOFORCE; + int ret = IO_RELOAD_LOAD; if (io_get_modified()) { const char *msg_um_prefix = - _("There are unsaved modifications:"); - const char *msg_um_discard = _("(d)iscard"); + _("Screen data have changed and will be lost:"); + const char *msg_um_discard = _("(c)ontinue"); const char *msg_um_merge = _("(m)erge"); - const char *msg_um_keep = _("(c)ancel"); - const char *msg_um_choice = _("[dmc]"); + const char *msg_um_keep = _("c(a)ncel"); + const char *msg_um_choice = _("[cma]"); asprintf(&msg_um_asktype, "%s %s, %s, %s", msg_um_prefix, msg_um_discard, msg_um_merge, msg_um_keep); @@ -982,26 +975,25 @@ int io_reload_data(void) switch (status_ask_choice(msg_um_asktype, msg_um_choice, 3)) { case 1: load = FORCE; + ret = IO_RELOAD_CTINUE; break; case 2: io_merge_data(); load = FORCE; + ret = IO_RELOAD_MERGE; break; case 3: + ret = IO_RELOAD_CANCEL; /* FALLTHROUGH */ default: goto cleanup; } } - io_load_data(NULL, load); - - if (show_dialogs()) { - status_mesg(reload_success, enter); - keys_wait_for_any_key(win[KEY].p); - } + load = io_load_data(NULL, load); + if (load == NONEW) + ret = IO_RELOAD_NOOP; - ret = 1; cleanup: mem_free(msg_um_asktype); return ret; -- cgit v1.2.3-54-g00ecf