diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index cae51df2..bbd530a8 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -28,6 +28,7 @@ from archinstall.lib.output import FormattedOutput from archinstall.lib.packages.packages import list_available_packages, select_additional_packages from archinstall.lib.pacman.config import PacmanConfig from archinstall.lib.translationhandler import Language, tr, translation_handler +from archinstall.tui.ui.components import tui from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -275,6 +276,8 @@ class GlobalMenu(AbstractMenu[None]): if o.key is not None: self._item_group.find_by_key(o.key).text = o.text + tui.translate_bindings() + async def _locale_selection(self, preset: LocaleConfiguration) -> LocaleConfiguration | None: locale_config = await LocaleMenu(preset).show() return locale_config diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index df0915c7..27fa4eee 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -1709,6 +1709,123 @@ msgstr "" msgid "Exit search mode" msgstr "" +msgid "General" +msgstr "" + +msgid "Navigation" +msgstr "" + +msgid "Selection" +msgstr "" + +msgid "Search" +msgstr "" + +msgid "Down" +msgstr "" + +msgid "Up" +msgstr "" + +msgid "Confirm" +msgstr "" + +msgid "Focus right" +msgstr "" + +msgid "Focus left" +msgstr "" + +msgid "Toggle" +msgstr "" + +msgid "Show/Hide help" +msgstr "" + +msgid "Quit" +msgstr "" + +msgid "First" +msgstr "" + +msgid "Last" +msgstr "" + +msgid "Select" +msgstr "" + +msgid "Page Up" +msgstr "" + +msgid "Page Down" +msgstr "" + +msgid "Page up" +msgstr "" + +msgid "Page down" +msgstr "" + +msgid "Page Left" +msgstr "" + +msgid "Page Right" +msgstr "" + +msgid "Cursor up" +msgstr "" + +msgid "Cursor down" +msgstr "" + +msgid "Cursor right" +msgstr "" + +msgid "Cursor left" +msgstr "" + +msgid "Top" +msgstr "" + +msgid "Bottom" +msgstr "" + +msgid "Home" +msgstr "" + +msgid "End" +msgstr "" + +msgid "Toggle option" +msgstr "" + +msgid "Scroll Up" +msgstr "" + +msgid "Scroll Down" +msgstr "" + +msgid "Scroll Left" +msgstr "" + +msgid "Scroll Right" +msgstr "" + +msgid "Scroll Home" +msgstr "" + +msgid "Scroll End" +msgstr "" + +msgid "Focus Next" +msgstr "" + +msgid "Focus Previous" +msgstr "" + +msgid "Copy selected text" +msgstr "" + msgid "" "labwc needs access to your seat (collection of hardware devices i.e. " "keyboard, mouse, etc)" diff --git a/archinstall/locales/uk/LC_MESSAGES/base.mo b/archinstall/locales/uk/LC_MESSAGES/base.mo index 6d6f7558..ad130139 100644 Binary files a/archinstall/locales/uk/LC_MESSAGES/base.mo and b/archinstall/locales/uk/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index b88fd290..5ad4bcb3 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -1663,6 +1663,123 @@ msgstr "Запустити режим пошуку" msgid "Exit search mode" msgstr "Вийти з режиму пошуку" +msgid "General" +msgstr "Загальне" + +msgid "Navigation" +msgstr "Навігація" + +msgid "Selection" +msgstr "Вибір" + +msgid "Search" +msgstr "Пошук" + +msgid "Down" +msgstr "Вниз" + +msgid "Up" +msgstr "Вгору" + +msgid "Confirm" +msgstr "Підтвердити" + +msgid "Focus right" +msgstr "Фокус вправо" + +msgid "Focus left" +msgstr "Фокус вліво" + +msgid "Toggle" +msgstr "Перемкнути" + +msgid "Show/Hide help" +msgstr "Показати/Сховати довідку" + +msgid "Quit" +msgstr "Вийти" + +msgid "First" +msgstr "На початок" + +msgid "Last" +msgstr "В кінець" + +msgid "Select" +msgstr "Обрати" + +msgid "Page Up" +msgstr "Сторінка вгору" + +msgid "Page Down" +msgstr "Сторінка вниз" + +msgid "Page up" +msgstr "Сторінка вгору" + +msgid "Page down" +msgstr "Сторінка вниз" + +msgid "Page Left" +msgstr "Сторінка вліво" + +msgid "Page Right" +msgstr "Сторінка вправо" + +msgid "Cursor up" +msgstr "Курсор вгору" + +msgid "Cursor down" +msgstr "Курсор вниз" + +msgid "Cursor right" +msgstr "Курсор вправо" + +msgid "Cursor left" +msgstr "Курсор вліво" + +msgid "Top" +msgstr "На початок" + +msgid "Bottom" +msgstr "В кінець" + +msgid "Home" +msgstr "Початок" + +msgid "End" +msgstr "Кінець" + +msgid "Toggle option" +msgstr "Перемкнути опцію" + +msgid "Scroll Up" +msgstr "Прокрутка вгору" + +msgid "Scroll Down" +msgstr "Прокрутка вниз" + +msgid "Scroll Left" +msgstr "Прокрутка вліво" + +msgid "Scroll Right" +msgstr "Прокрутка вправо" + +msgid "Scroll Home" +msgstr "Прокрутка на початок" + +msgid "Scroll End" +msgstr "Прокрутка в кінець" + +msgid "Focus Next" +msgstr "Фокус на наступний" + +msgid "Focus Previous" +msgstr "Фокус на попередній" + +msgid "Copy selected text" +msgstr "Копіювати виділений текст" + msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" msgstr "labwc потребує доступ до вашого місця (набору апаратних пристроїв, таких як клавіатура, миша тощо)" diff --git a/archinstall/tui/ui/components.py b/archinstall/tui/ui/components.py index 7882b1ef..e06dd216 100644 --- a/archinstall/tui/ui/components.py +++ b/archinstall/tui/ui/components.py @@ -1,13 +1,13 @@ import sys from abc import ABC, abstractmethod from collections.abc import Awaitable, Callable -from dataclasses import dataclass +from dataclasses import dataclass, replace from enum import Enum, auto from typing import Any, ClassVar, Literal, TypeVar, cast, override from textual import work from textual.app import App, ComposeResult -from textual.binding import Binding +from textual.binding import Binding, BindingsMap from textual.containers import Center, Horizontal, ScrollableContainer, Vertical from textual.events import Key from textual.geometry import Offset @@ -27,6 +27,18 @@ from archinstall.tui.ui.result import Result, ResultType ValueT = TypeVar('ValueT') +def _translate_bindings(source: BindingsMap | None, target: BindingsMap) -> None: + """Translate binding descriptions from source to target. + + Uses source (original, immutable class-level cache) to avoid + double-translation on repeated calls (e.g. language switch). + """ + if source is None: + return + for key, bindings in source.key_to_bindings.items(): + target.key_to_bindings[key] = [replace(b, description=tr(b.description)) if b.description else b for b in bindings] + + class BaseScreen(Screen[Result[ValueT]]): BINDINGS: ClassVar = [ Binding('escape', 'cancel_operation', 'Cancel', show=True), @@ -97,6 +109,7 @@ class LoadingScreen(BaseScreen[ValueT]): yield Footer() def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) if self._data_callback: self._exec_callback() else: @@ -129,6 +142,10 @@ class _OptionList(OptionList): Binding('k', 'cursor_up', 'Up', show=False), ] + @override + def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) + class OptionListScreen(BaseScreen[ValueT]): """ @@ -271,6 +288,7 @@ class OptionListScreen(BaseScreen[ValueT]): yield Footer() def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) self._update_options(self._options) self.query_one(OptionList).focus() @@ -356,6 +374,10 @@ class _SelectionList(SelectionList[ValueT]): Binding('space', 'select', 'Toggle', show=True), ] + @override + def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) + class SelectListScreen(BaseScreen[ValueT]): """ @@ -500,6 +522,7 @@ class SelectListScreen(BaseScreen[ValueT]): self._handle_search_action() def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) self._update_options(self._options) self.query_one(SelectionList).focus() @@ -670,6 +693,7 @@ class ConfirmationScreen(BaseScreen[ValueT]): yield Footer() def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) self._update_selection() def action_focus_right(self) -> None: @@ -825,6 +849,7 @@ class InputScreen(BaseScreen[str]): yield Footer() def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) input_field = self.query_one('#main_input', Input) input_field.focus() @@ -872,6 +897,10 @@ class _DataTable(DataTable[ValueT]): Binding('enter', 'select_cursor', 'Confirm', show=True), ] + @override + def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) + class TableSelectionScreen(BaseScreen[ValueT]): BINDINGS: ClassVar = [ @@ -992,6 +1021,7 @@ class TableSelectionScreen(BaseScreen[ValueT]): yield Footer() def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) self._display_header(True) data_table = self.query_one(DataTable) data_table.cell_padding = 2 @@ -1245,6 +1275,7 @@ class _AppInstance(App[ValueT]): _ = self.screen.mount(HelpPanel()) def on_mount(self) -> None: + _translate_bindings(self._merged_bindings, self._bindings) self._run_worker() @work @@ -1291,5 +1322,10 @@ class TApp: assert TApp.app TApp.app.exit(result) + def translate_bindings(self) -> None: + """Re-translate app-level binding descriptions after language change.""" + if TApp.app is not None: + _translate_bindings(TApp.app._merged_bindings, TApp.app._bindings) + tui = TApp()