diff options
| author | Ulf Magnusson <ulfalizer@gmail.com> | 2018-05-18 03:20:18 +0200 |
|---|---|---|
| committer | Ulf Magnusson <ulfalizer@gmail.com> | 2018-05-18 06:57:13 +0200 |
| commit | 0a70863b4f753eac4502fad781923d6176855757 (patch) | |
| tree | d17e8c3af1f7026b61ddefe2439e2a5980cdeea3 | |
| parent | 5deda2a18da0bf2222076a2519896a39aabb3562 (diff) | |
menuconfig: Add .config loading dialog
Automatically turn on show-all mode if the currently selected node
becomes invisible after loading the new configuration.
Show an are-you-sure dialog if there are unsaved changes.
A wart here is that there currently isn't a way to get 'errno' and
'strerror' from the IOError exception returned by load_config(). Hack
around it by opening the configuration file separately with open()
first, just to catch any obvious errors.
| -rwxr-xr-x | menuconfig.py | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/menuconfig.py b/menuconfig.py index cac98ee..5e01a44 100755 --- a/menuconfig.py +++ b/menuconfig.py @@ -129,7 +129,7 @@ _N_SCROLL_ARROWS = 14 # Lines of help text shown at the bottom of the "main" display _MAIN_HELP_LINES = """ -[Space/Enter] Toggle/enter [ESC] Leave menu [S] Save +[Space/Enter] Toggle/enter [ESC] Leave menu [S] Save [O] Load [?] Symbol info [/] Jump to symbol [A] Toggle show-all mode [Q] Quit (prompts for save) [D] Save minimal config (advanced) """[1:-1].split("\n") @@ -452,6 +452,22 @@ def _menuconfig(stdscr): else: _leave_menu() + elif c in ("o", "O"): + if _conf_changed: + c = _key_dialog( + "Load", + "You have unsaved changes. Load new\n" + "configuration anyway?\n" + "\n" + " (Y)es (C)ancel", + "yc") + + if c is None or c == "c": + continue + + if _load_dialog(): + _conf_changed = False + elif c in ("s", "S"): if _save_dialog(_kconf.write_config, _config_filename, "configuration"): @@ -1160,8 +1176,63 @@ def _draw_input_dialog(win, title, info_text, s, i, hscroll): win.noutrefresh() +def _load_dialog(): + # Dialog for loading a new configuration + # + # Return value: + # True if a new configuration was loaded, and False if the user canceled + # the dialog + + global _show_all + + filename = "" + while True: + filename = _input_dialog("File to load", filename) + + if filename is None: + return False + + if _try_load(filename): + sel_node = _shown[_sel_node_i] + + # Turn on show-all mode if the current node is (no longer) visible + if not (sel_node.prompt and expr_value(sel_node.prompt[1])): + _show_all = True + + _update_menu() + + # The message dialog indirectly updates the menu display, so _msg() + # must be called after the new state has been initialized + _msg("Success", "Loaded {}".format(filename)) + return True + +def _try_load(filename): + # Tries to load a configuration file. Pops up an error and returns False on + # failure. + # + # filename: + # Configuration file to load + + # Hack: strerror and errno are lost after we raise the custom IOError with + # troubleshooting help in Kconfig.load_config(). Adding them back to the + # exception loses the custom message. As a workaround, try opening the file + # separately first and report any errors. + try: + open(filename).close() + except OSError as e: + _error("Error loading {}\n\n{} (errno: {})" + .format(filename, e.strerror, errno.errorcode[e.errno])) + return False + + try: + _kconf.load_config(filename) + return True + except OSError as e: + _error("Error loading {}\n\nUnknown error".format(filename)) + return False + def _save_dialog(save_fn, default_filename, description): - # Pops up a dialog that prompts the user for where to save a file + # Dialog for saving the current configuration # # save_fn: # Function to call with 'filename' to save the file @@ -1173,8 +1244,8 @@ def _save_dialog(save_fn, default_filename, description): # String describing the thing being saved # # Return value: - # Returns True if the configuration was saved, and False if the user - # canceled the dialog + # True if the configuration was saved, and False if the user canceled the + # dialog filename = default_filename while True: @@ -1190,7 +1261,8 @@ def _save_dialog(save_fn, default_filename, description): return True def _try_save(save_fn, filename, description): - # Tries to save a file. Pops up an error and returns False on failure. + # Tries to save a configuration file. Pops up an error and returns False on + # failure. # # save_fn: # Function to call with 'filename' to save the file |
