mirror of https://github.com/borgbase/vorta
98 lines
3.3 KiB
Python
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
|