diff --git a/po/POTFILES.in b/po/POTFILES.in index fdb59f17..414dc7ad 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,7 +15,6 @@ subiquity/client/controllers/ssh.py subiquity/client/controllers/welcome.py subiquity/client/controllers/zdev.py subiquity/client/__init__.py -subiquity/client/keyboard.py subiquity/client/keycodes.py subiquity/cmd/common.py subiquity/cmd/__init__.py diff --git a/subiquity/client/controllers/keyboard.py b/subiquity/client/controllers/keyboard.py index 26037b82..cc6d8f6f 100644 --- a/subiquity/client/controllers/keyboard.py +++ b/subiquity/client/controllers/keyboard.py @@ -17,7 +17,6 @@ import logging from subiquity.client.controller import SubiquityTuiController -from subiquity.client.keyboard import KeyboardList from subiquity.common.types import KeyboardSetting from subiquity.ui.views import KeyboardView @@ -28,29 +27,9 @@ class KeyboardController(SubiquityTuiController): endpoint_name = 'keyboard' - signals = [ - ('l10n:language-selected', 'language_selected'), - ] - - def __init__(self, app): - super().__init__(app) - self.keyboard_list = KeyboardList() - - def language_selected(self, code): - log.debug("language_selected %s", code) - if not self.keyboard_list.has_language(code): - code = code.split('_')[0] - if not self.keyboard_list.has_language(code): - code = 'C' - log.debug("loading language %s", code) - self.keyboard_list.load_language(code) - async def make_ui(self): - if self.keyboard_list.current_lang is None: - self.keyboard_list.load_language('C') - initial_setting = await self.endpoint.GET() - view = KeyboardView(self, initial_setting) - return view + setup = await self.endpoint.GET() + return KeyboardView(self, setup) async def run_answers(self): if 'layout' in self.answers: diff --git a/subiquity/client/keyboard.py b/subiquity/client/keyboard.py deleted file mode 100644 index 5b3bf99a..00000000 --- a/subiquity/client/keyboard.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2020 Canonical, Ltd. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import os - -from subiquity.common.serialize import Serializer -from subiquity.common.types import ( - KeyboardLayout, - ) - - -class KeyboardList: - - def __init__(self): - self._kbnames_dir = os.path.join(os.environ.get("SNAP", '.'), 'kbds') - self.serializer = Serializer(compact=True) - self._clear() - - def _file_for_lang(self, code): - return os.path.join(self._kbnames_dir, code + '.jsonl') - - def has_language(self, code): - return os.path.exists(self._file_for_lang(code)) - - def load_language(self, code): - if code == self.current_lang: - return - - self._clear() - - with open(self._file_for_lang(code)) as kbdnames: - self.layouts = [ - self.serializer.from_json(KeyboardLayout, line) - for line in kbdnames - ] - self.current_lang = code - - def _clear(self): - self.current_lang = None - self.layouts = [] diff --git a/subiquity/common/apidef.py b/subiquity/common/apidef.py index 18d51ec0..5964cc98 100644 --- a/subiquity/common/apidef.py +++ b/subiquity/common/apidef.py @@ -29,6 +29,7 @@ from subiquity.common.types import ( ApplicationStatus, ErrorReportRef, KeyboardSetting, + KeyboardSetup, IdentityData, RefreshStatus, SnapInfo, @@ -91,7 +92,7 @@ class API: def GET(change_id: str) -> dict: ... class keyboard: - def GET() -> KeyboardSetting: ... + def GET() -> KeyboardSetup: ... def POST(data: Payload[KeyboardSetting]): ... class needs_toggle: diff --git a/subiquity/common/types.py b/subiquity/common/types.py index 66b5ef7c..a163de86 100644 --- a/subiquity/common/types.py +++ b/subiquity/common/types.py @@ -137,6 +137,12 @@ class KeyboardLayout: variants: List[KeyboardVariant] +@attr.s(auto_attribs=True) +class KeyboardSetup: + setting: KeyboardSetting + layouts: List[KeyboardLayout] + + @attr.s(auto_attribs=True) class ZdevInfo: id: str diff --git a/subiquity/server/controllers/keyboard.py b/subiquity/server/controllers/keyboard.py index 14652510..63124cf4 100644 --- a/subiquity/server/controllers/keyboard.py +++ b/subiquity/server/controllers/keyboard.py @@ -26,7 +26,9 @@ from subiquity.common.apidef import API from subiquity.common.serialize import Serializer from subiquity.common.types import ( AnyStep, + KeyboardLayout, KeyboardSetting, + KeyboardSetup, ) from subiquity.server.controller import SubiquityController @@ -112,6 +114,44 @@ def for_ui(setting): layout=layout, variant=variant, toggle=setting.toggle) +class KeyboardList: + + def __init__(self): + self._kbnames_dir = os.path.join(os.environ.get("SNAP", '.'), 'kbds') + self.serializer = Serializer(compact=True) + self._clear() + + def _file_for_lang(self, code): + return os.path.join(self._kbnames_dir, code + '.jsonl') + + def _has_language(self, code): + return os.path.exists(self._file_for_lang(code)) + + def load_language(self, code): + if '.' in code: + code = code.split('.')[0] + if not self._has_language(code): + code = code.split('_')[0] + if not self._has_language(code): + code = 'C' + + if code == self.current_lang: + return + + self._clear() + + with open(self._file_for_lang(code)) as kbdnames: + self.layouts = [ + self.serializer.from_json(KeyboardLayout, line) + for line in kbdnames + ] + self.current_lang = code + + def _clear(self): + self.current_lang = None + self.layouts = [] + + class KeyboardController(SubiquityController): endpoint = API.keyboard @@ -133,6 +173,7 @@ class KeyboardController(SubiquityController): self.serializer = Serializer(compact=True) self.pc105_steps = None self.needs_set_keyboard = False + self.keyboard_list = KeyboardList() super().__init__(app) def load_autoinstall_data(self, data): @@ -166,8 +207,12 @@ class KeyboardController(SubiquityController): for cmd in cmds: await arun_command(cmd) - async def GET(self) -> KeyboardSetting: - return for_ui(self.model.setting) + async def GET(self) -> KeyboardSetup: + self.keyboard_list.load_language( + self.app.base_model.locale.selected_language) + return KeyboardSetup( + setting=for_ui(self.model.setting), + layouts=self.keyboard_list.layouts) async def POST(self, data: KeyboardSetting): new = latinizable(data.layout, data.variant) diff --git a/subiquity/ui/views/keyboard.py b/subiquity/ui/views/keyboard.py index 482ba32d..73bbf758 100644 --- a/subiquity/ui/views/keyboard.py +++ b/subiquity/ui/views/keyboard.py @@ -360,21 +360,22 @@ class KeyboardView(BaseView): title = _("Keyboard configuration") - def __init__(self, controller, setting): + def __init__(self, controller, setup): self.controller = controller - self.keyboard_list = controller.keyboard_list - self.initial_setting = setting + self.initial_setting = setup.setting + self.layouts = setup.layouts self.form = KeyboardForm() opts = [] - for layout in self.keyboard_list.layouts: + for layout in self.layouts: opts.append(Option((layout.name, True, layout))) opts.sort(key=lambda o: locale.strxfrm(o.label.text)) connect_signal(self.form, 'submit', self.done) connect_signal(self.form, 'cancel', self.cancel) connect_signal(self.form.layout.widget, "select", self.select_layout) self.form.layout.widget.options = opts - layout, variant = self.lookup(setting.layout, setting.variant) + layout, variant = self.lookup( + setup.setting.layout, setup.setting.variant) self.set_values(layout, variant) if self.controller.opts.run_on_serial: @@ -448,7 +449,7 @@ class KeyboardView(BaseView): self.form.variant.enabled = len(opts) > 1 def lookup(self, layout_code, variant_code): - for layout in self.keyboard_list.layouts: + for layout in self.layouts: if layout.code == layout_code: break if layout.code == "us":