Source code for betty.gui.locale
"""
Provide locale management for the Graphical User Interface.
"""
from __future__ import annotations
from typing import Any
from PyQt6 import QtGui
from PyQt6.QtWidgets import QComboBox, QLabel, QWidget
from betty.app import App
from betty.asyncio import wait
from betty.gui.text import Caption
from betty.locale import negotiate_locale, get_display_name
[docs]
class LocalizedObject:
def __init__(self, app: App, *args: Any, **kwargs: Any):
super().__init__(*args, **kwargs)
self._app = app
[docs]
def showEvent( # type: ignore[misc]
self: LocalizedObject & QWidget,
a0: QtGui.QShowEvent | None,
) -> None:
super().showEvent(a0) # type: ignore[misc]
self._set_translatables()
self._app.configuration.on_change(self._set_translatables)
def _set_translatables(self) -> None:
pass
[docs]
class TranslationsLocaleCollector(LocalizedObject):
def __init__(self, app: App, allowed_locales: set[str]):
super().__init__(app)
self._allowed_locales = allowed_locales
allowed_locale_names: list[tuple[str, str]] = []
for allowed_locale in allowed_locales:
locale_name = get_display_name(allowed_locale)
if locale_name is not None:
allowed_locale_names.append((
allowed_locale,
locale_name,
))
allowed_locale_names = sorted(allowed_locale_names, key=lambda x: x[1])
def _update_configuration_locale() -> None:
self._app.configuration.locale = self._configuration_locale.currentData()
self._configuration_locale = QComboBox()
for i, (locale, locale_name) in enumerate(allowed_locale_names):
self._configuration_locale.addItem(locale_name, locale)
if locale == self._app.configuration.locale:
self._configuration_locale.setCurrentIndex(i)
self._configuration_locale.currentIndexChanged.connect(_update_configuration_locale)
self._configuration_locale_label = QLabel()
self._configuration_locale_caption = Caption()
self._set_translatables()
self._app.configuration.on_change(self._set_translatables)
@property
def locale(self) -> QComboBox:
return self._configuration_locale
@property
def rows(self) -> list[list[Any]]:
return [
[self._configuration_locale_label, self._configuration_locale],
[self._configuration_locale_caption],
]
def _set_translatables(self) -> None:
super()._set_translatables()
localizer = self._app.localizer
localizers = self._app.localizers
self._configuration_locale_label.setText(localizer._('Locale'))
locale = self.locale.currentData()
if locale:
translations_locale = negotiate_locale(
locale,
list(localizers.locales),
)
if translations_locale is None:
self._configuration_locale_caption.setText(localizer._('There are no translations for {locale_name}.').format(
locale_name=get_display_name(locale, localizer.locale),
))
else:
negotiated_locale_translations_coverage = wait(localizers.coverage(translations_locale))
if negotiated_locale_translations_coverage[1] == 0:
negotiated_locale_translations_coverage_percentage = 0
else:
negotiated_locale_translations_coverage_percentage = round(100 / (negotiated_locale_translations_coverage[1] / negotiated_locale_translations_coverage[0]))
self._configuration_locale_caption.setText(localizer._('The translations for {locale_name} are {coverage_percentage}%% complete.').format(
locale_name=get_display_name(translations_locale, localizer.locale),
coverage_percentage=round(negotiated_locale_translations_coverage_percentage)
))