anaconda/anaconda-40.22.3.13/pyanaconda/modules/localization/localization.py
2024-11-14 21:39:56 -08:00

350 lines
12 KiB
Python

#
# Kickstart module for language and keyboard settings.
#
# Copyright (C) 2018 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
# the GNU General Public License v.2, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY expressed or implied, including the implied warranties of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details. You should have received a copy of the
# GNU General Public License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
# source code or documentation are not subject to the GNU General Public
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
import langtable
from pyanaconda.core.configuration.anaconda import conf
from pyanaconda.core.dbus import DBus
from pyanaconda.core.signal import Signal
from pyanaconda.localization import get_available_translations, get_common_languages, \
get_english_name, get_language_locales, get_language_id, get_native_name
from pyanaconda.modules.common.base import KickstartService
from pyanaconda.modules.common.constants.services import LOCALIZATION
from pyanaconda.modules.common.containers import TaskContainer
from pyanaconda.modules.common.structures.language import LanguageData, LocaleData
from pyanaconda.modules.localization.localization_interface import LocalizationInterface
from pyanaconda.modules.localization.kickstart import LocalizationKickstartSpecification
from pyanaconda.modules.localization.installation import LanguageInstallationTask, \
KeyboardInstallationTask
from pyanaconda.modules.localization.runtime import GetMissingKeyboardConfigurationTask, \
ApplyKeyboardTask, AssignGenericKeyboardSettingTask
from pyanaconda.modules.localization.localed import LocaledWrapper
from pyanaconda.modules.localization.gk_keyboard_manager import GkKeyboardManager
from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
class LocalizationService(KickstartService):
"""The Localization service."""
def __init__(self):
super().__init__()
self.language_changed = Signal()
self._language = ""
self.language_support_changed = Signal()
self._language_support = []
self.language_seen_changed = Signal()
self._language_seen = False
self.vc_keymap_changed = Signal()
self._vc_keymap = ""
self.x_layouts_changed = Signal()
self._x_layouts = []
self.switch_options_changed = Signal()
self._switch_options = []
self.keyboard_seen_changed = Signal()
self._keyboard_seen = False
self.compositor_selected_layout_changed = Signal()
self.compositor_layouts_changed = Signal()
self._localed_wrapper = None
self._compositor_keyboard_manager = None
def publish(self):
"""Publish the module."""
TaskContainer.set_namespace(LOCALIZATION.namespace)
DBus.publish_object(LOCALIZATION.object_path, LocalizationInterface(self))
DBus.register_service(LOCALIZATION.service_name)
@property
def kickstart_specification(self):
"""Return the kickstart specification."""
return LocalizationKickstartSpecification
def process_kickstart(self, data):
"""Process the kickstart data."""
# lang
self.set_language(data.lang.lang)
self.set_language_support(data.lang.addsupport)
self.set_language_seen(data.lang.seen)
# keyboard
self.set_vc_keymap(data.keyboard.vc_keymap)
self.set_x_layouts(data.keyboard.x_layouts)
self.set_switch_options(data.keyboard.switch_options)
if data.keyboard._keyboard:
self.set_from_generic_keyboard_setting(data.keyboard._keyboard)
self.set_keyboard_seen(data.keyboard.seen)
def setup_kickstart(self, data):
"""Set up the kickstart data."""
# lang
data.lang.lang = self.language
data.lang.addsupport = self.language_support
# keyboard
data.keyboard.vc_keymap = self.vc_keymap
data.keyboard.x_layouts = self.x_layouts
data.keyboard.switch_options = self.switch_options
def get_languages(self):
"""Get languages with available translations.
For example: ["en", "cs"]
:return: a list of language ids
"""
return get_available_translations()
def get_language_data(self, language_id):
"""Get data about the specified language.
:param: a language id (for example, "en")
:return: a language data
"""
tdata = LanguageData()
tdata.english_name = get_english_name(language_id)
tdata.is_common = language_id in get_common_languages()
tdata.language_id = language_id
tdata.native_name = get_native_name(language_id)
return tdata
def get_locales(self, language_id):
"""Get locales available for the specified language.
For example: ["de_DE.UTF-8", "de_AT.UTF-8", ... ]
:return: a list of locale ids
"""
return get_language_locales(language_id)
def get_common_locales(self):
"""Get a list of the most commonly used locales.
For example: ["ar_EG.UTF-8", "en_US.UTF-8", "en_GB.UTF-8", ...]
:return: a list of common locale IDs
"""
return langtable.list_common_locales()
def get_locale_data(self, locale_id):
"""Get data about the specified locale.
:param: a locale id (for example, "en_US.UTF-8")
:return: a locale data
"""
tdata = LocaleData()
tdata.english_name = get_english_name(locale_id)
tdata.language_id = get_language_id(locale_id)
tdata.locale_id = locale_id
tdata.native_name = get_native_name(locale_id)
return tdata
@property
def language(self):
"""Return the language."""
return self._language
def set_language(self, language):
"""Set the language."""
self._language = language
self.language_changed.emit()
log.debug("Language is set to %s.", language)
@property
def language_support(self):
"""Return suppored languages."""
return self._language_support
def set_language_support(self, language_support):
"""Set supported languages."""
self._language_support = language_support
self.language_support_changed.emit()
log.debug("Language support is set to %s.", language_support)
@property
def language_seen(self):
"""Was language command seen in kickstart?"""
return self._language_seen
def set_language_seen(self, seen):
"""Set whether language command was seen in kickstart."""
self._language_seen = seen
self.language_seen_changed.emit()
log.debug("Language seen set to %s.", seen)
@property
def vc_keymap(self):
"""Return virtual console keymap."""
return self._vc_keymap
def set_vc_keymap(self, vc_keymap):
"""Set virtual console keymap."""
self._vc_keymap = vc_keymap
self.vc_keymap_changed.emit()
log.debug("Virtual console keymap is set to %s.", vc_keymap)
@property
def x_layouts(self):
"""Return X Keyboard Layouts."""
return self._x_layouts
def set_x_layouts(self, x_layouts):
"""Set X Keyboard Layouts."""
self._x_layouts = x_layouts
self.x_layouts_changed.emit()
log.debug("X Layouts are set to %s.", x_layouts)
@property
def switch_options(self):
"""Return X layout switching options."""
return self._switch_options
def set_switch_options(self, switch_options):
"""Set X layout switching options."""
self._switch_options = switch_options
self.switch_options_changed.emit()
log.debug("X layout switch options are set to %s.", switch_options)
@property
def keyboard_seen(self):
"""Was keyboard command seen in kickstart?"""
return self._keyboard_seen
def set_keyboard_seen(self, keyboard_seen):
"""Set whether keyboard command was seen in kickstart."""
self._keyboard_seen = keyboard_seen
self.keyboard_seen_changed.emit()
log.debug("keyboard command considered seen in kicksatart: %s.", keyboard_seen)
@property
def localed_wrapper(self):
if not self._localed_wrapper:
self._localed_wrapper = LocaledWrapper()
return self._localed_wrapper
def install_with_tasks(self):
"""Return the installation tasks of this module.
:returns: list of installation tasks
"""
return [
LanguageInstallationTask(
sysroot=conf.target.system_root,
lang=self.language
),
KeyboardInstallationTask(
sysroot=conf.target.system_root,
localed_wrapper=self.localed_wrapper,
x_layouts=self.x_layouts,
switch_options=self.switch_options,
vc_keymap=self.vc_keymap
)
]
def populate_missing_keyboard_configuration_with_task(self):
"""Populate missing keyboard configuration.
The configuration is populated by conversion and/or default values.
:returns: a task getting missing keyboard configuration
"""
task = GetMissingKeyboardConfigurationTask(
localed_wrapper=self.localed_wrapper,
x_layouts=self.x_layouts,
vc_keymap=self.vc_keymap,
)
task.succeeded_signal.connect(lambda: self._update_settings_from_task(task.get_result()))
return task
def _update_settings_from_task(self, result):
"""Update settings from task result."""
x_layouts, vc_keymap = result
self.set_vc_keymap(vc_keymap)
self.set_x_layouts(x_layouts)
def apply_keyboard_with_task(self):
"""Apply keyboard configuration to the current system.
:returns: a task applying the configuration
"""
task = ApplyKeyboardTask(
localed_wrapper=self.localed_wrapper,
x_layouts=self.x_layouts,
vc_keymap=self.vc_keymap,
switch_options=self.switch_options
)
task.succeeded_signal.connect(lambda: self._update_settings_from_task(task.get_result()))
return task
def set_from_generic_keyboard_setting(self, keyboard):
"""Set keyboard from generic keyboard setting
:param keyboard:
"""
log.debug("Setting keyboard from generic setting value '%s'.", keyboard)
if self.vc_keymap or self.x_layouts:
log.debug("Ignoring generic keyboard setting as we have a specific one.")
return
task = AssignGenericKeyboardSettingTask(
keyboard=keyboard
)
result = task.run()
self._update_settings_from_task(result)
@property
def compositor_keyboard_manager(self):
if not self._compositor_keyboard_manager:
self._compositor_keyboard_manager = GkKeyboardManager()
self._compositor_keyboard_manager.compositor_selected_layout_changed.connect(
lambda layout: self.compositor_selected_layout_changed.emit(layout)
)
self._compositor_keyboard_manager.compositor_layouts_changed.connect(
lambda layouts: self.compositor_layouts_changed.emit(layouts)
)
return self._compositor_keyboard_manager
def get_compositor_selected_layout(self):
return self.compositor_keyboard_manager.get_compositor_selected_layout()
def set_compositor_selected_layout(self, layout_variant):
return self.compositor_keyboard_manager.set_compositor_selected_layout(layout_variant)
def select_next_compositor_layout(self):
return self.compositor_keyboard_manager.select_next_compositor_layout()
def get_compositor_layouts(self):
return self.compositor_keyboard_manager.get_compositor_layouts()
def set_compositor_layouts(self, layout_variants, options):
self.compositor_keyboard_manager.set_compositor_layouts(layout_variants, options)