vorta/src/vorta/i18n/__init__.py

98 lines
3.3 KiB
Python

"""
internationalisation (i18n) support code
"""
import logging
import os
from PyQt6.QtCore import QLocale, QTranslator
logger = logging.getLogger(__name__)
# To check if the UI layout copes flexibly with translated strings, an env var
# TRANS_SCALE can be used - it will result in transformed translated strings, e.g.:
# 100 = scale 100%, normal
# N>0 = scale to N%
# N<0 = additionally, do a RTL simulation at scale -N%
# usage: TRANS_SCALE=200 LANG=de_DE vorta --foreground
trans_scale = int(os.environ.get('TRANS_SCALE', '100'))
class VortaTranslator(QTranslator):
"""
Extends QTranslator to increase the length of strings for testing. Fallback for untranslated
strings to English doesn't work currently. So only use for testing.
"""
def translate(self, context, text, disambiguation=None, n=-1):
translated = super().translate(context, text, disambiguation=disambiguation, n=n)
scale = trans_scale
# for UI layout debugging:
has_placeholders = '%' in translated
has_html = translated.startswith('<') and translated.endswith('>')
if has_placeholders or has_html:
# not supported kinds of strings, just return normal:
return translated
if scale < 0:
# for simple RTL checking: reverse translated string
translated = translated[::-1]
scale = -scale
if 0 < scale < 100:
step = 100 // scale
scale = None
else:
step = None
scale = scale // 100
return translated * scale if step is None else translated[::step]
def init_translations(app):
"""
Loads translations for a given input app. If a scaling factor is defined for testing, we use
our own subclass of QTranslator.
"""
global application, translator, locale # if we don't keep a reference on these, it stops working. pyqt bug?
application = app
translator = QTranslator() if trans_scale == 100 else VortaTranslator()
# Use LANG var if set, else let Qt detect it.
env_lang = os.environ.get('LANG', False)
if env_lang:
locale = QLocale(env_lang)
else:
locale = QLocale()
qm_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'qm'))
ui_langs = locale.uiLanguages()
succeeded = translator.load(locale, 'vorta', prefix='.', directory=qm_path) # e.g. vorta/i18n/qm/vorta.de_DE.qm
if succeeded:
app.installTranslator(translator)
logger.debug('Loading translation %s for %r.' % ('succeeded' if succeeded else 'failed', ui_langs))
def get_locale():
"""Get the locale used for translation."""
# global translator
# QTranslator.language was added with Qt 15.15
# return QLocale(translator.language())
global locale
return locale
def translate(*args, **kwargs):
"""
small wrapper around QCoreApplication.translate()
"""
global application # see init_translation
return application.translate(*args, **kwargs)
def trans_late(scope, text):
"""
dummy translate function - only purpose is to mark scope/text for message extraction.
later, at another place, there will be a translate(scope, text) call, with same
scope and text, potentially not literal scope, not literal text, but from a variable.
"""
return text