-
-
Notifications
You must be signed in to change notification settings - Fork 826
Command line switch to specify language on startup (#10044) #10089
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7611b13
a852fa6
113ae13
1fce583
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -131,6 +131,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), | ||
|
|
@@ -165,7 +172,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. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I"m not sure whether this is what people expect from command line arguments. They are most of the time only seen as temporary overrides. I think I prefer the language setting to be that way as well, i.e. it should only be effective to the current session of NVDA, until there is a restart triggered from outside that resets the params. It should not touch the configuration at all.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(Before and after this PR, same process)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The original poster of #10144 accidentally changed language to Hebrew, a language which he cannot understand. To get him back on his feet, we need a way to change this setting. The point is: If the language specified on the command line is different from the configuration, what should the settings dialog present as the selected language? I see four options here:
What do you think? Would you prefer option 2?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In other situations where we override from the command-line we disable the control so that we avoid this confusion. That, of course, defeats the purpose of this PR. My preference would be to insert a new item in the language list (at index 0) with something like
|
||
| config.conf["general"]["language"] = lang | ||
| else: | ||
| lang = config.conf["general"]["language"] | ||
| log.debug("setting language to %s"%lang) | ||
| languageHandler.setLanguage(lang) | ||
| # Addons | ||
|
|
@@ -235,7 +247,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) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,6 +73,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 | ||
|
|
@@ -81,6 +82,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): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be great if this could check that the |
||
| 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() | ||
|
|
@@ -89,6 +110,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=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") | ||
| 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") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think cmdLanguage can just be language. globalVars.appArgs already implies that we're dealing with a command line argument here. Having said that, I note that some magic is happening with the configPath, but that could be considered confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If i'm not wrong, other members of
globalVars.appArgsconvey their default value if not specified from the command line. This one is different as, if not specified on the command line, it would not be set to the value in the configuration. Thus, I chose that name to be extra explicit and ensure no one mistakes the intent behind this member.Let me know if you feel like my reasoning is wrong here and I will rename it as you suggest.
I don't get your point here. Could you please elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do not start NVDA with the --config-path parameter, globalVars.appArgs.configPath is still populated with the actual config path. It is also widely used throughout the code base to refer to the config path. A similar thing could happen with globalVars.appArgs.language in that if it is not overridden using the command line, can be set to the actual language.
I think this suggestion makes sense, as it will address the concern about what is displayed in the general settings panel for the language.