diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 771e92da..cce29b54 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2355,6 +2355,15 @@ static const struct cmd_t command_defs[] = { "/omemo char *") }, + { CMD_PREAMBLE("/changes", + parse_args, 0, 0, NULL) + CMD_MAINFUNC(cmd_changes) + CMD_SYN( + "/changes") + CMD_DESC( + "Show changes from saved configuration file.") + }, + { CMD_PREAMBLE("/save", parse_args, 0, 0, NULL) CMD_MAINFUNC(cmd_save) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index bb14cd34..b17d0493 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -9006,6 +9006,14 @@ cmd_omemo_qrcode(ProfWin* window, const char* const command, gchar** args) #endif } +gboolean +cmd_changes(ProfWin* window, const char* const command, gchar** args) +{ + cons_show("Show changes from saved configuration file."); + prefs_changes(); + return TRUE; +} + gboolean cmd_save(ProfWin* window, const char* const command, gchar** args) { diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h index b8b74e3c..ccd727eb 100644 --- a/src/command/cmd_funcs.h +++ b/src/command/cmd_funcs.h @@ -234,6 +234,7 @@ gboolean cmd_omemo_policy(ProfWin* window, const char* const command, gchar** ar gboolean cmd_omemo_clear_device_list(ProfWin* window, const char* const command, gchar** args); gboolean cmd_omemo_qrcode(ProfWin* window, const char* const command, gchar** args); +gboolean cmd_changes(ProfWin* window, const char* const command, gchar** args); gboolean cmd_save(ProfWin* window, const char* const command, gchar** args); gboolean cmd_reload(ProfWin* window, const char* const command, gchar** args); diff --git a/src/config/preferences.c b/src/config/preferences.c index bad809c8..58e613b3 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -49,6 +49,7 @@ #include "tools/autocomplete.h" #include "config/files.h" #include "config/conflists.h" +#include "ui/ui.h" // preference groups refer to the sections in .profrc or theme files // for example [ui] but not [colours] which is handled in theme.c @@ -286,6 +287,75 @@ prefs_load(const char* config_file) _prefs_load(); } +void +prefs_changes(void) +{ + const char* undef = ""; + prof_keyfile_t saved; + if (!load_custom_keyfile(&saved, g_strdup(prefs_prof_keyfile.filename))) + return; + gsize ngroups, nsavedgroups, g; + auto_gcharv gchar** groups = g_key_file_get_groups(prefs_prof_keyfile.keyfile, &ngroups); + gboolean banner_shown = FALSE; + void prefs_changes_print(const char* key, const char* newval, const char* oldval) + { +#define PREFS_CHANGES_FORMAT_STRING "%-32s | %-20s | %-20s" + if (!banner_shown) { + cons_show(PREFS_CHANGES_FORMAT_STRING, "Key", "New value", "Old value"); + banner_shown = TRUE; + } + cons_show(PREFS_CHANGES_FORMAT_STRING, key, newval, oldval); +#undef PREFS_CHANGES_FORMAT_STRING + } + for (g = 0; g < ngroups; ++g) { + gsize nkeys, k; + gboolean saved_has_group = g_key_file_has_group(saved.keyfile, groups[g]); + auto_gcharv gchar** keys = g_key_file_get_keys(prefs_prof_keyfile.keyfile, groups[g], &nkeys, NULL); + for (k = 0; k < nkeys; ++k) { + auto_gerror GError* err = NULL; + auto_gchar gchar* full_key = g_strdup_printf("%s.%s", groups[g], keys[k]); + auto_gchar gchar* new_value = g_key_file_get_value(prefs_prof_keyfile.keyfile, groups[g], keys[k], &err); + if (err || !new_value) { + cons_show_error("%s: New value (%s) error: %s", full_key, STR_MAYBE_NULL(new_value), PROF_GERROR_MESSAGE(err)); + continue; + } + if (!saved_has_group + || !g_key_file_has_key(saved.keyfile, groups[g], keys[k], NULL)) { + prefs_changes_print(full_key, new_value, undef); + continue; + } + auto_gchar gchar* old_value = g_key_file_get_value(saved.keyfile, groups[g], keys[k], &err); + if (err || !old_value) { + cons_show_error("%s: Old value (%s) error: %s", full_key, STR_MAYBE_NULL(old_value), PROF_GERROR_MESSAGE(err)); + continue; + } + if (!g_str_equal(old_value, new_value)) { + prefs_changes_print(full_key, new_value, old_value); + } + } + } + auto_gcharv gchar** savedgroups = g_key_file_get_groups(saved.keyfile, &nsavedgroups); + for (g = 0; g < nsavedgroups; ++g) { + gsize nkeys, k; + auto_gcharv gchar** keys = g_key_file_get_keys(saved.keyfile, savedgroups[g], &nkeys, NULL); + for (k = 0; k < nkeys; ++k) { + if (g_key_file_has_key(prefs_prof_keyfile.keyfile, savedgroups[g], keys[k], NULL)) + continue; + auto_gerror GError* err = NULL; + auto_gchar gchar* full_key = g_strdup_printf("%s.%s", groups[g], keys[k]); + auto_gchar gchar* old_value = g_key_file_get_value(saved.keyfile, groups[g], keys[k], &err); + if (err || !old_value) { + cons_show_error("%s: Old value (%s) error: %s", full_key, STR_MAYBE_NULL(old_value), PROF_GERROR_MESSAGE(err)); + continue; + } + prefs_changes_print(full_key, undef, old_value); + } + } + free_keyfile(&saved); + if (!banner_shown) + cons_show("No changes to saved preferences."); +} + void prefs_save(void) { diff --git a/src/config/preferences.h b/src/config/preferences.h index 750a87ee..7effe91c 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -206,6 +206,7 @@ typedef struct prof_winplacement_t } ProfWinPlacement; void prefs_load(const char* config_file); +void prefs_changes(void); void prefs_save(void); void prefs_close(void); void prefs_reload(void);