From 7611b139a1d26616cbe7a25113fca9950c2bd2a6 Mon Sep 17 00:00:00 2001 From: Julien Cochuyt Date: Tue, 13 Aug 2019 17:54:21 +0200 Subject: [PATCH 1/2] Command line switch to specify language on startup (#10044) --- source/core.py | 21 +++++++++++++++++++-- source/nvda.pyw | 17 +++++++++++++++++ user_docs/en/userGuide.t2t | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/source/core.py b/source/core.py index 3be9ef24300..c0722b250ca 100644 --- a/source/core.py +++ b/source/core.py @@ -132,6 +132,13 @@ def restart(disableAddons=False, debugLogging=False): sys.argv.remove("--ease-of-access") except ValueError: pass + if globalVars.appArgs.cmdLineLanguage: + import config + # We should better compare here with the saved value if not saveOnExit. + if config.conf["general"]["language"] != globalVars.appArgs.cmdLineLanguage: + for i, arg in list(enumerate(sys.argv)): + if arg.startswith("--lang="): + del sys.argv[i] shellapi.ShellExecute(None, None, sys.executable, subprocess.list2cmdline(sys.argv + options), @@ -163,7 +170,12 @@ def resetConfiguration(factoryDefaults=False): config.conf.reset(factoryDefaults=factoryDefaults) logHandler.setLogLevelFromConfig() #Language - lang = config.conf["general"]["language"] + lang = globalVars.appArgs.cmdLineLanguage + if lang: + # Ensure the language specified on the command line will be saved with the config. + config.conf["general"]["language"] = lang + else: + lang = config.conf["general"]["language"] log.debug("setting language to %s"%lang) languageHandler.setLanguage(lang) # Addons @@ -228,7 +240,12 @@ def main(): pass logHandler.setLogLevelFromConfig() try: - lang = config.conf["general"]["language"] + lang = globalVars.appArgs.cmdLineLanguage + if lang: + # Ensure the language specified on the command line will be saved with the config. + config.conf["general"]["language"] = lang + else: + lang = config.conf["general"]["language"] import languageHandler log.debug("setting language to %s"%lang) languageHandler.setLanguage(lang) diff --git a/source/nvda.pyw b/source/nvda.pyw index 4d8c5a4d6b0..131eaea53a0 100755 --- a/source/nvda.pyw +++ b/source/nvda.pyw @@ -89,6 +89,13 @@ parser.add_argument('-k','--check-running',action="store_true",dest='check_runni parser.add_argument('-f','--log-file',dest='logFileName',type=str,help="The file where log messages should be written to") parser.add_argument('-l','--log-level',dest='logLevel',type=int,default=0,choices=[10, 12, 15, 20, 30, 40, 50, 100],help="The lowest level of message logged (debug 10, input/output 12, debugwarning 15, info 20, warning 30, error 40, critical 50, off 100), default is info") parser.add_argument('-c','--config-path',dest='configPath',default=None,type=str,help="The path where all settings for NVDA are stored") +parser.add_argument( + '--lang', + dest='cmdLineLanguage', + default=None, + type=str, + help="Override the configured NVDA language. Set to \"Windows\" for current user default, \"en\" for English, etc." +) parser.add_argument('-m','--minimal',action="store_true",dest='minimal',default=False,help="No sounds, no interface, no start message etc") parser.add_argument('-s','--secure',action="store_true",dest='secure',default=False,help="Secure mode (disable Python console)") parser.add_argument('--disable-addons',action="store_true",dest='disableAddons',default=False,help="Disable all add-ons") @@ -204,6 +211,16 @@ logHandler.log.setLevel(logLevel) if logLevel is log.DEBUG: log.debug("Provided arguments: {}".format(sys.argv[1:])) +# Perform basic case normalization for ease of use. +lang = globalVars.appArgs.cmdLineLanguage +if lang: + if lang.casefold() == "Windows".casefold(): + lang = "Windows" + lang = lang.replace("-", "_") + if "_" in lang: + lang = lang.split("_")[0].lower() + "_" + lang.split("_")[1].upper() + globalVars.appArgs.cmdLineLanguage = lang + log.info("Starting NVDA") log.debug("Debug level logging enabled") if globalVars.appArgs.changeScreenReaderFlag: diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t index 7f7759b6b1a..53020a84f3a 100644 --- a/user_docs/en/userGuide.t2t +++ b/user_docs/en/userGuide.t2t @@ -2926,6 +2926,7 @@ Following are the command line options for NVDA: | -f LOGFILENAME | --log-file=LOGFILENAME | The file where log messages should be written to | | -l LOGLEVEL | --log-level=LOGLEVEL | The lowest level of message logged (debug 10, input/output 12, debug warning 15, info 20, warning 30, error 40, critical 50, disabled 100), default is warning | | -c CONFIGPATH | --config-path=CONFIGPATH | The path where all settings for NVDA are stored | +| None | --lang=LANGUAGE | Override the configured NVDA language. Set to "Windows" for current user default, "en" for English, etc. | | -m | --minimal | No sounds, no interface, no start message, etc. | | -s | --secure | Secure mode (disables Python console and logging features, used often in secure screens) | | None | --disable-addons | Addons will have no effect | From a852fa6ca85b419524a5daf3415e2ecab2d9c57b Mon Sep 17 00:00:00 2001 From: Julien Cochuyt Date: Sat, 7 Sep 2019 14:09:48 +0200 Subject: [PATCH 2/2] Validation of the `--lang` command line parameter (#10044) Re: https://github.com/nvaccess/nvda/pull/10089#discussion_r318892237 --- source/nvda.pyw | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/source/nvda.pyw b/source/nvda.pyw index 131eaea53a0..ac5d762e481 100755 --- a/source/nvda.pyw +++ b/source/nvda.pyw @@ -72,6 +72,7 @@ if not winVersion.isSupportedOS(): winUser.MessageBox(0, ctypes.FormatError(winUser.ERROR_OLD_WIN_VERSION), None, winUser.MB_ICONERROR) sys.exit(1) + def stringToBool(string): """Wrapper for configobj.validate.is_boolean to raise the proper exception for wrong values.""" from configobj.validate import is_boolean, ValidateError @@ -80,6 +81,26 @@ def stringToBool(string): except ValidateError as e: raise argparse.ArgumentTypeError(e.message) + +def stringToLang(value: str) -> str: + """Perform basic case normalization for ease of use. + """ + if value.casefold() == "Windows".casefold(): + return "Windows" + value = value.replace("-", "_") + lang = value.split("_")[0].lower() + dialect = value.split("_")[1].upper() if "_" in value else None + # Validating the size of the codes. + # Further validation would require L{languageHandler} to be initialized. + if len(lang) != 2 or (dialect and len(dialect) != 2): + raise argparse.ArgumentTypeError( + "Language code should be \"Windows\" or of the forms \"en\" or \"pt_BR\"." + ) + if dialect: + return f"{lang}_{dialect}" + return lang + + #Process option arguments parser=NoConsoleOptionParser() quitGroup = parser.add_mutually_exclusive_group() @@ -93,7 +114,7 @@ parser.add_argument( '--lang', dest='cmdLineLanguage', default=None, - type=str, + type=stringToLang, help="Override the configured NVDA language. Set to \"Windows\" for current user default, \"en\" for English, etc." ) parser.add_argument('-m','--minimal',action="store_true",dest='minimal',default=False,help="No sounds, no interface, no start message etc") @@ -211,16 +232,6 @@ logHandler.log.setLevel(logLevel) if logLevel is log.DEBUG: log.debug("Provided arguments: {}".format(sys.argv[1:])) -# Perform basic case normalization for ease of use. -lang = globalVars.appArgs.cmdLineLanguage -if lang: - if lang.casefold() == "Windows".casefold(): - lang = "Windows" - lang = lang.replace("-", "_") - if "_" in lang: - lang = lang.split("_")[0].lower() + "_" + lang.split("_")[1].upper() - globalVars.appArgs.cmdLineLanguage = lang - log.info("Starting NVDA") log.debug("Debug level logging enabled") if globalVars.appArgs.changeScreenReaderFlag: