keyboard: suggest language / variant for locale

This commit is contained in:
Dan Bungert 2022-07-19 16:11:33 -06:00
parent 7bb4a1a5f3
commit dbb8be4e72
3 changed files with 117 additions and 5 deletions

View File

@ -35,6 +35,40 @@ XKBOPTIONS="{options}"
BACKSPACE="guess" BACKSPACE="guess"
""" """
layout_for_lang = {
# In the same order as the Welcome screen
# https://salsa.debian.org/installer-team/console-setup/-/blob/master/debian/keyboard-configuration.config
# None values indicate that this lang should use the default setting.
'ast_ES.UTF-8': KeyboardSetting(layout='es', variant='ast'),
'id_ID.UTF-8': None,
'ca_ES.UTF-8': KeyboardSetting(layout='es', variant='cat'),
'de_DE.UTF-8': KeyboardSetting(layout='de'),
'en_US.UTF-8': KeyboardSetting(layout='us'),
'en_GB.UTF-8': KeyboardSetting(layout='gb'),
'es_ES.UTF-8': KeyboardSetting(layout='es'),
'fr_FR.UTF-8': KeyboardSetting(layout='fr', variant='latin9'),
'hr_HR.UTF-8': KeyboardSetting(layout='hr'),
'lv_LV.UTF-8': KeyboardSetting(layout='lv'),
'lt_LT.UTF-8': KeyboardSetting(layout='lt'),
'hu_HU.UTF-8': KeyboardSetting(layout='hu'),
'nl_NL.UTF-8': KeyboardSetting(layout='us'),
'nb': KeyboardSetting(layout='no'),
'bo_IN': KeyboardSetting(layout='us,cn', variant=',tib'),
'pl_PL.UTF-8': KeyboardSetting(layout='pl'),
'fi_FI.UTF-8': KeyboardSetting(layout='fi'),
'sv_SE.UTF-8': KeyboardSetting(layout='se'),
'kab_DZ.UTF-8': KeyboardSetting(layout='dz', variant='la'),
'cs_CZ.UTF-8': KeyboardSetting(layout='cz'),
'el_GR.UTF-8': KeyboardSetting(layout='us,gr'),
'be_BY.UTF-8': KeyboardSetting(layout='us,by'),
'ru_RU.UTF-8': KeyboardSetting(layout='us,ru'),
'sr_RS': KeyboardSetting(layout='rs', variant='latin'),
'uk_UA.UTF-8': KeyboardSetting(layout='us,ua'),
'he_IL.UTF-8': KeyboardSetting(layout='us,il'),
'oc': None,
'zh_CN.UTF-8': KeyboardSetting(layout='cn'),
}
def from_config_file(config_file): def from_config_file(config_file):
with open(config_file) as fp: with open(config_file) as fp:
@ -64,9 +98,20 @@ class KeyboardModel:
self.config_path = os.path.join( self.config_path = os.path.join(
root, 'etc', 'default', 'keyboard') root, 'etc', 'default', 'keyboard')
if os.path.exists(self.config_path): if os.path.exists(self.config_path):
self.setting = from_config_file(self.config_path) self.default_setting = from_config_file(self.config_path)
else: else:
self.setting = KeyboardSetting(layout='us') self.default_setting = layout_for_lang['en_US.UTF-8']
self._setting = None
@property
def setting(self):
if self._setting is None:
return self.default_setting
return self._setting
@setting.setter
def setting(self, value):
self._setting = value
def render_config_file(self): def render_config_file(self):
options = "" options = ""
@ -87,3 +132,11 @@ class KeyboardModel:
}, },
}, },
} }
def setting_for_lang(self, lang):
if self._setting is not None:
return self._setting
layout = layout_for_lang.get(lang, None)
if layout is None:
return self.default_setting
return layout

View File

@ -0,0 +1,59 @@
# Copyright 2022 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 <http://www.gnu.org/licenses/>.
from parameterized import parameterized
from subiquitycore.tests import SubiTestCase
from subiquity.common.types import KeyboardSetting
from subiquity.models.keyboard import (
KeyboardModel,
layout_for_lang,
)
class TestKeyboardModel(SubiTestCase):
def setUp(self):
self.model = KeyboardModel(self.tmp_dir())
def testDefaultUS(self):
self.assertIsNone(self.model._setting)
self.assertEqual('us', self.model.setting.layout)
def testSetToZZ(self):
val = KeyboardSetting(layout='zz')
self.model.setting = val
self.assertEqual(val, self.model.setting)
self.assertEqual(val, self.model._setting)
@parameterized.expand([
['ast_ES.UTF-8', 'es', 'ast'],
['de_DE.UTF-8', 'de', ''],
['fr_FR.UTF-8', 'fr', 'latin9'],
['oc', 'us', ''],
])
def testSettingForLang(self, lang, layout, variant):
val = self.model.setting_for_lang(lang)
self.assertEqual(layout, val.layout)
self.assertEqual(variant, val.variant)
def testAllLangsHaveKeyboardSuggestion(self):
# every language in the list needs a suggestion,
# even if only the default
with open('languagelist') as fp:
for line in fp.readlines():
tokens = line.split(':')
locale = tokens[1]
self.assertIn(locale, layout_for_lang.keys())

View File

@ -215,10 +215,10 @@ class KeyboardController(SubiquityController):
await arun_command(cmd) await arun_command(cmd)
async def GET(self) -> KeyboardSetup: async def GET(self) -> KeyboardSetup:
self.keyboard_list.load_language( lang = self.app.base_model.locale.selected_language
self.app.base_model.locale.selected_language) self.keyboard_list.load_language(lang)
return KeyboardSetup( return KeyboardSetup(
setting=for_ui(self.model.setting), setting=for_ui(self.model.setting_for_lang(lang)),
layouts=self.keyboard_list.layouts) layouts=self.keyboard_list.layouts)
async def POST(self, data: KeyboardSetting): async def POST(self, data: KeyboardSetting):