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) ))