2019-09-10 00:54:28 +00:00
|
|
|
# Created By: Virgil Dupras
|
|
|
|
# Created On: 2010-06-23
|
|
|
|
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
|
|
|
#
|
|
|
|
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
|
|
|
# which should be included with this package. The terms are also available at
|
|
|
|
# http://www.gnu.org/licenses/gpl-3.0.html
|
|
|
|
|
|
|
|
# Doing i18n with GNU gettext for the core text gets complicated, so what I do is that I make the
|
|
|
|
# GUI layer responsible for supplying a tr() function.
|
|
|
|
|
|
|
|
import locale
|
|
|
|
import logging
|
2022-05-10 04:36:39 +00:00
|
|
|
import os
|
2019-09-10 00:54:28 +00:00
|
|
|
import os.path as op
|
2022-05-10 04:36:39 +00:00
|
|
|
from typing import Callable, Union
|
2019-09-10 00:54:28 +00:00
|
|
|
|
2022-05-09 06:40:08 +00:00
|
|
|
from hscommon.plat import ISLINUX
|
2019-09-10 00:54:28 +00:00
|
|
|
|
|
|
|
_trfunc = None
|
|
|
|
_trget = None
|
|
|
|
installed_lang = None
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def tr(s: str, context: Union[str, None] = None) -> str:
|
2019-09-10 00:54:28 +00:00
|
|
|
if _trfunc is None:
|
|
|
|
return s
|
|
|
|
else:
|
|
|
|
if context:
|
|
|
|
return _trfunc(s, context)
|
|
|
|
else:
|
|
|
|
return _trfunc(s)
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def trget(domain: str) -> Callable[[str], str]:
|
2019-09-10 00:54:28 +00:00
|
|
|
# Returns a tr() function for the specified domain.
|
|
|
|
if _trget is None:
|
|
|
|
return lambda s: tr(s, domain)
|
|
|
|
else:
|
|
|
|
return _trget(domain)
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def set_tr(
|
|
|
|
new_tr: Callable[[str, Union[str, None]], str], new_trget: Union[Callable[[str], Callable[[str], str]], None] = None
|
|
|
|
) -> None:
|
2019-09-10 00:54:28 +00:00
|
|
|
global _trfunc, _trget
|
|
|
|
_trfunc = new_tr
|
|
|
|
if new_trget is not None:
|
|
|
|
_trget = new_trget
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def get_locale_name(lang: str) -> Union[str, None]:
|
2021-08-07 02:39:02 +00:00
|
|
|
# Removed old conversion code as windows seems to support these
|
|
|
|
LANG2LOCALENAME = {
|
|
|
|
"cs": "cs_CZ",
|
|
|
|
"de": "de_DE",
|
|
|
|
"el": "el_GR",
|
|
|
|
"en": "en",
|
|
|
|
"es": "es_ES",
|
|
|
|
"fr": "fr_FR",
|
|
|
|
"hy": "hy_AM",
|
|
|
|
"it": "it_IT",
|
|
|
|
"ja": "ja_JP",
|
|
|
|
"ko": "ko_KR",
|
2022-01-25 03:02:57 +00:00
|
|
|
"ms": "ms_MY",
|
2021-08-07 02:39:02 +00:00
|
|
|
"nl": "nl_NL",
|
|
|
|
"pl_PL": "pl_PL",
|
|
|
|
"pt_BR": "pt_BR",
|
|
|
|
"ru": "ru_RU",
|
|
|
|
"tr": "tr_TR",
|
|
|
|
"uk": "uk_UA",
|
|
|
|
"vi": "vi_VN",
|
|
|
|
"zh_CN": "zh_CN",
|
|
|
|
}
|
2019-09-10 00:54:28 +00:00
|
|
|
if lang not in LANG2LOCALENAME:
|
|
|
|
return None
|
|
|
|
result = LANG2LOCALENAME[lang]
|
|
|
|
if ISLINUX:
|
2020-01-01 02:16:27 +00:00
|
|
|
result += ".UTF-8"
|
2019-09-10 00:54:28 +00:00
|
|
|
return result
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
|
|
|
# --- Qt
|
2022-05-10 04:36:39 +00:00
|
|
|
def install_qt_trans(lang: str = None) -> None:
|
2019-09-10 00:54:28 +00:00
|
|
|
from PyQt5.QtCore import QCoreApplication, QTranslator, QLocale
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
if not lang:
|
|
|
|
lang = str(QLocale.system().name())[:2]
|
|
|
|
localename = get_locale_name(lang)
|
|
|
|
if localename is not None:
|
|
|
|
try:
|
|
|
|
locale.setlocale(locale.LC_ALL, localename)
|
|
|
|
except locale.Error:
|
|
|
|
logging.warning("Couldn't set locale %s", localename)
|
|
|
|
else:
|
2020-01-01 02:16:27 +00:00
|
|
|
lang = "en"
|
2019-09-10 00:54:28 +00:00
|
|
|
qtr1 = QTranslator(QCoreApplication.instance())
|
2020-01-01 02:16:27 +00:00
|
|
|
qtr1.load(":/qt_%s" % lang)
|
2019-09-10 00:54:28 +00:00
|
|
|
QCoreApplication.installTranslator(qtr1)
|
|
|
|
qtr2 = QTranslator(QCoreApplication.instance())
|
2020-01-01 02:16:27 +00:00
|
|
|
qtr2.load(":/%s" % lang)
|
2019-09-10 00:54:28 +00:00
|
|
|
QCoreApplication.installTranslator(qtr2)
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def qt_tr(s: str, context: Union[str, None] = "core") -> str:
|
|
|
|
if context is None:
|
|
|
|
context = "core"
|
2019-09-10 00:54:28 +00:00
|
|
|
return str(QCoreApplication.translate(context, s, None))
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
set_tr(qt_tr)
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
|
|
|
# --- gettext
|
2022-05-10 04:36:39 +00:00
|
|
|
def install_gettext_trans(base_folder: os.PathLike, lang: str) -> None:
|
2019-09-10 00:54:28 +00:00
|
|
|
import gettext
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def gettext_trget(domain: str) -> Callable[[str], str]:
|
2019-09-10 00:54:28 +00:00
|
|
|
if not lang:
|
|
|
|
return lambda s: s
|
|
|
|
try:
|
2021-08-15 09:10:18 +00:00
|
|
|
return gettext.translation(domain, localedir=base_folder, languages=[lang]).gettext
|
2022-04-28 01:53:12 +00:00
|
|
|
except OSError:
|
2019-09-10 00:54:28 +00:00
|
|
|
return lambda s: s
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
default_gettext = gettext_trget("core")
|
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def gettext_tr(s: str, context: Union[str, None] = None) -> str:
|
2019-09-10 00:54:28 +00:00
|
|
|
if not context:
|
|
|
|
return default_gettext(s)
|
|
|
|
else:
|
|
|
|
trfunc = gettext_trget(context)
|
|
|
|
return trfunc(s)
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
set_tr(gettext_tr, gettext_trget)
|
|
|
|
global installed_lang
|
|
|
|
installed_lang = lang
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2022-05-10 04:36:39 +00:00
|
|
|
def install_gettext_trans_under_qt(base_folder: os.PathLike, lang: str = None) -> None:
|
2019-09-10 00:54:28 +00:00
|
|
|
# So, we install the gettext locale, great, but we also should try to install qt_*.qm if
|
|
|
|
# available so that strings that are inside Qt itself over which I have no control are in the
|
|
|
|
# right language.
|
|
|
|
from PyQt5.QtCore import QCoreApplication, QTranslator, QLocale, QLibraryInfo
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
if not lang:
|
|
|
|
lang = str(QLocale.system().name())[:2]
|
|
|
|
localename = get_locale_name(lang)
|
2022-03-12 10:33:27 +00:00
|
|
|
if localename is None:
|
|
|
|
lang = "en"
|
|
|
|
localename = get_locale_name(lang)
|
|
|
|
try:
|
|
|
|
locale.setlocale(locale.LC_ALL, localename)
|
|
|
|
except locale.Error:
|
|
|
|
logging.warning("Couldn't set locale %s", localename)
|
2020-01-01 02:16:27 +00:00
|
|
|
qmname = "qt_%s" % lang
|
2019-09-10 00:54:28 +00:00
|
|
|
if ISLINUX:
|
|
|
|
# Under linux, a full Qt installation is already available in the system, we didn't bundle
|
|
|
|
# up the qm files in our package, so we have to load translations from the system.
|
|
|
|
qmpath = op.join(QLibraryInfo.location(QLibraryInfo.TranslationsPath), qmname)
|
|
|
|
else:
|
|
|
|
qmpath = op.join(base_folder, qmname)
|
|
|
|
qtr = QTranslator(QCoreApplication.instance())
|
|
|
|
qtr.load(qmpath)
|
|
|
|
QCoreApplication.installTranslator(qtr)
|
|
|
|
install_gettext_trans(base_folder, lang)
|