Merge pull request #835 from abdnh/init-lang
Set up default language before loading profile
This commit is contained in:
commit
0c08ff5317
@ -8,3 +8,8 @@ profiles-profile-corrupt = Profile Corrupt
|
||||
profiles-profiles = Profiles
|
||||
profiles-quit = Quit
|
||||
profiles-user-1 = User 1
|
||||
profiles-confirm-lang-choice = Are you sure you wish to display Anki's interface in { $lang }?
|
||||
profiles-could-not-create-data-folder = Anki could not create its data folder. Please see the File Locations section of the manual, and ensure that location is not read-only.
|
||||
profiles-prefs-corrupt-title = Preferences Corrupt
|
||||
profiles-prefs-file-is-corrupt = Anki's prefs21.db file was corrupt and has been recreated. If you were using multiple profiles, please add them back using the same names to recover your cards.
|
||||
profiles-profile-does-not-exist = Requested profile does not exist.
|
||||
|
@ -61,6 +61,12 @@ qt-misc-would-you-like-to-download-it = Would you like to download it now?
|
||||
qt-misc-your-collection-file-appears-to-be = Your collection file appears to be corrupt. This can happen when the file is copied or moved while Anki is open, or when the collection is stored on a network or cloud drive. If problems persist after restarting your computer, please open an automatic backup from the profile screen.
|
||||
qt-misc-your-computers-storage-may-be-full = Your computer's storage may be full. Please delete some unneeded files, then try again.
|
||||
qt-misc-your-firewall-or-antivirus-program-is = Your firewall or antivirus program is preventing Anki from creating a connection to itself. Please add an exception for Anki.
|
||||
qt-misc-error = Error
|
||||
qt-misc-no-temp-folder = No usable temporary folder found. Make sure C:\\temp exists or TEMP in your environment points to a valid, writable folder.
|
||||
qt-misc-incompatible-video-driver = Your video driver is incompatible. Please start Anki again, and Anki will switch to a slower, more compatible mode.
|
||||
qt-misc-error-loading-graphics-driver = Error loading '{ $mode }' graphics driver. Please start Anki again to try next driver. { $context }
|
||||
qt-misc-anki-is-running = Anki Already Running
|
||||
qt-misc-if-instance-is-not-responding = If the existing instance of Anki is not responding, please close it using your task manager, or restart your computer.
|
||||
qt-misc-second =
|
||||
{ $count ->
|
||||
[one] { $count } second
|
||||
|
@ -3,8 +3,9 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import locale
|
||||
import re
|
||||
from typing import Optional
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import anki
|
||||
|
||||
@ -171,6 +172,36 @@ def set_lang(lang: str, locale_dir: str) -> None:
|
||||
locale_folder = locale_dir
|
||||
|
||||
|
||||
def get_def_lang(lang: Optional[str] = None) -> Tuple[int, str]:
|
||||
"""Return lang converted to name used on disk and its index, defaulting to system language
|
||||
or English if not available."""
|
||||
try:
|
||||
(sys_lang, enc) = locale.getdefaultlocale()
|
||||
except:
|
||||
# fails on osx
|
||||
sys_lang = "en_US"
|
||||
user_lang = lang
|
||||
if user_lang in compatMap:
|
||||
user_lang = compatMap[user_lang]
|
||||
idx = None
|
||||
lang = None
|
||||
en = None
|
||||
for l in (user_lang, sys_lang):
|
||||
for c, (name, code) in enumerate(langs):
|
||||
if code == "en_US":
|
||||
en = c
|
||||
if code == l:
|
||||
idx = c
|
||||
lang = l
|
||||
if idx is not None:
|
||||
break
|
||||
# if the specified language and the system language aren't available, revert to english
|
||||
if idx is None:
|
||||
idx = en
|
||||
lang = "en_US"
|
||||
return (idx, lang)
|
||||
|
||||
|
||||
def is_rtl(lang: str) -> bool:
|
||||
return lang in ("he", "ar", "fa")
|
||||
|
||||
|
@ -17,7 +17,7 @@ from anki.consts import HELP_SITE
|
||||
from anki.rsbackend import RustBackend
|
||||
from anki.utils import checksum, isLin, isMac
|
||||
from aqt.qt import *
|
||||
from aqt.utils import locale_dir
|
||||
from aqt.utils import TR, locale_dir, tr
|
||||
|
||||
# we want to be able to print unicode debug info to console without
|
||||
# fear of a traceback on systems with the console set to ASCII
|
||||
@ -175,7 +175,10 @@ _qtrans: Optional[QTranslator] = None
|
||||
|
||||
|
||||
def setupLangAndBackend(
|
||||
pm: ProfileManager, app: QApplication, force: Optional[str] = None
|
||||
pm: ProfileManager,
|
||||
app: QApplication,
|
||||
force: Optional[str] = None,
|
||||
firstTime: bool = False,
|
||||
) -> RustBackend:
|
||||
global _qtrans
|
||||
try:
|
||||
@ -198,11 +201,15 @@ def setupLangAndBackend(
|
||||
builtins.__dict__["ngettext"] = fn_ngettext
|
||||
|
||||
# get lang and normalize into ja/zh-CN form
|
||||
if firstTime:
|
||||
lang = pm.meta["defaultLang"]
|
||||
else:
|
||||
lang = force or pm.meta["defaultLang"]
|
||||
lang = anki.lang.lang_to_disk_lang(lang)
|
||||
|
||||
# set active language
|
||||
ldir = locale_dir()
|
||||
if not firstTime:
|
||||
# set active language
|
||||
anki.lang.set_lang(lang, ldir)
|
||||
|
||||
# switch direction for RTL languages
|
||||
@ -269,8 +276,8 @@ class AnkiApp(QApplication):
|
||||
# existing instance running but hung
|
||||
QMessageBox.warning(
|
||||
None,
|
||||
"Anki Already Running",
|
||||
"If the existing instance of Anki is not responding, please close it using your task manager, or restart your computer.",
|
||||
tr(TR.QT_MISC_ANKI_IS_RUNNING),
|
||||
tr(TR.QT_MISC_IF_INSTANCE_IS_NOT_RESPONDING),
|
||||
)
|
||||
|
||||
sys.exit(1)
|
||||
@ -356,8 +363,10 @@ def setupGL(pm):
|
||||
if "Failed to create OpenGL context" in msg:
|
||||
QMessageBox.critical(
|
||||
None,
|
||||
"Error",
|
||||
f"Error loading '{mode}' graphics driver. Please start Anki again to try next driver. {context}",
|
||||
tr(TR.QT_MISC_ERROR),
|
||||
tr(
|
||||
TR.QT_MISC_ERROR_LOADING_GRAPHICS_DRIVER, mode=mode, context=context
|
||||
),
|
||||
)
|
||||
pm.nextGlMode()
|
||||
return
|
||||
@ -427,6 +436,10 @@ def _run(argv=None, exec=True):
|
||||
profiler = cProfile.Profile()
|
||||
profiler.enable()
|
||||
|
||||
# default to specified/system language before getting user's preference so that we can localize some more strings
|
||||
lang = anki.lang.get_def_lang(opts.lang)
|
||||
anki.lang.set_lang(lang[1], locale_dir())
|
||||
|
||||
# profile manager
|
||||
pm = None
|
||||
try:
|
||||
@ -475,10 +488,8 @@ def _run(argv=None, exec=True):
|
||||
if not pm:
|
||||
QMessageBox.critical(
|
||||
None,
|
||||
"Error",
|
||||
"""\
|
||||
Anki could not create its data folder. Please see the File Locations \
|
||||
section of the manual, and ensure that location is not read-only.""",
|
||||
tr(TR.QT_MISC_ERROR),
|
||||
tr(TR.PROFILES_COULD_NOT_CREATE_DATA_FOLDER),
|
||||
)
|
||||
return
|
||||
|
||||
@ -517,29 +528,26 @@ section of the manual, and ensure that location is not read-only.""",
|
||||
except:
|
||||
QMessageBox.critical(
|
||||
None,
|
||||
"Error",
|
||||
"""\
|
||||
No usable temporary folder found. Make sure C:\\temp exists or TEMP in your \
|
||||
environment points to a valid, writable folder.""",
|
||||
tr(TR.QT_MISC_ERROR),
|
||||
tr(TR.QT_MISC_NO_TEMP_FOLDER),
|
||||
)
|
||||
return
|
||||
|
||||
if pmLoadResult.firstTime:
|
||||
pm.setDefaultLang()
|
||||
pm.setDefaultLang(lang[0])
|
||||
|
||||
if pmLoadResult.loadError:
|
||||
QMessageBox.warning(
|
||||
None,
|
||||
"Preferences Corrupt",
|
||||
"""Anki's prefs21.db file was corrupt and has been recreated. If you were using multiple \
|
||||
profiles, please add them back using the same names to recover your cards.""",
|
||||
tr(TR.PROFILES_PREFS_CORRUPT_TITLE),
|
||||
tr(TR.PROFILES_PREFS_FILE_IS_CORRUPT),
|
||||
)
|
||||
|
||||
if opts.profile:
|
||||
pm.openProfile(opts.profile)
|
||||
|
||||
# i18n & backend
|
||||
backend = setupLangAndBackend(pm, app, opts.lang)
|
||||
backend = setupLangAndBackend(pm, app, opts.lang, pmLoadResult.firstTime)
|
||||
|
||||
if isLin and pm.glMode() == "auto":
|
||||
from aqt.utils import gfxDriverIsBroken
|
||||
@ -548,8 +556,8 @@ environment points to a valid, writable folder.""",
|
||||
pm.nextGlMode()
|
||||
QMessageBox.critical(
|
||||
None,
|
||||
"Error",
|
||||
"Your video driver is incompatible. Please start Anki again, and Anki will switch to a slower, more compatible mode.",
|
||||
tr(TR.QT_MISC_ERROR),
|
||||
tr(TR.QT_MISC_INCOMPATIBLE_VIDEO_DRIVER),
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -97,7 +97,9 @@ class ProfileManager:
|
||||
def openProfile(self, profile) -> None:
|
||||
if profile:
|
||||
if profile not in self.profiles():
|
||||
QMessageBox.critical(None, "Error", "Requested profile does not exist.")
|
||||
QMessageBox.critical(
|
||||
None, tr(TR.QT_MISC_ERROR), tr(TR.PROFILES_PROFILE_DOES_NOT_EXIST)
|
||||
)
|
||||
sys.exit(1)
|
||||
try:
|
||||
self.load(profile)
|
||||
@ -482,7 +484,7 @@ create table if not exists profiles
|
||||
######################################################################
|
||||
# On first run, allow the user to choose the default language
|
||||
|
||||
def setDefaultLang(self) -> None:
|
||||
def setDefaultLang(self, idx: int) -> None:
|
||||
# create dialog
|
||||
class NoCloseDiag(QDialog):
|
||||
def reject(self):
|
||||
@ -490,28 +492,9 @@ create table if not exists profiles
|
||||
|
||||
d = self.langDiag = NoCloseDiag()
|
||||
f = self.langForm = aqt.forms.setlang.Ui_Dialog()
|
||||
f.setupUi(d)
|
||||
qconnect(d.accepted, self._onLangSelected)
|
||||
qconnect(d.rejected, lambda: True)
|
||||
# default to the system language
|
||||
try:
|
||||
(lang, enc) = locale.getdefaultlocale()
|
||||
except:
|
||||
# fails on osx
|
||||
lang = "en_US"
|
||||
# find index
|
||||
idx = None
|
||||
en = None
|
||||
for c, (name, code) in enumerate(anki.lang.langs):
|
||||
if code == "en_US":
|
||||
en = c
|
||||
if code == lang:
|
||||
idx = c
|
||||
# if the system language isn't available, revert to english
|
||||
if idx is None:
|
||||
idx = en
|
||||
lang = "en_US"
|
||||
anki.lang.set_lang(lang, locale_dir())
|
||||
f.setupUi(d)
|
||||
# update list
|
||||
f.lang.addItems([x[0] for x in anki.lang.langs])
|
||||
f.lang.setCurrentRow(idx)
|
||||
@ -522,12 +505,11 @@ create table if not exists profiles
|
||||
obj = anki.lang.langs[f.lang.currentRow()]
|
||||
code = obj[1]
|
||||
name = obj[0]
|
||||
en = "Are you sure you wish to display Anki's interface in %s?"
|
||||
r = QMessageBox.question(
|
||||
None, "Anki", en % name, QMessageBox.Yes | QMessageBox.No, QMessageBox.No # type: ignore
|
||||
None, "Anki", tr(TR.PROFILES_CONFIRM_LANG_CHOICE, lang=name), QMessageBox.Yes | QMessageBox.No, QMessageBox.No # type: ignore
|
||||
)
|
||||
if r != QMessageBox.Yes:
|
||||
return self.setDefaultLang()
|
||||
return self.setDefaultLang(f.lang.currentRow())
|
||||
self.setLang(code)
|
||||
|
||||
def setLang(self, code) -> None:
|
||||
|
Loading…
Reference in New Issue
Block a user