This patch introduces the libxklavier wrapper and makes a use of it for getting available layouts in the KeyboardSpoke. --- anaconda.spec.in | 1 + pyanaconda/ui/gui/spokes/keyboard.py | 12 ++-- pyanaconda/xklavier.py | 102 ++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 6 deletions(-) create mode 100755 pyanaconda/xklavier.py diff --git a/anaconda.spec.in b/anaconda.spec.in index cddcb77..834106d 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -133,6 +133,7 @@ Requires: python-bugzilla Requires: python-nss Requires: tigervnc-server-minimal Requires: pytz +Requires: libxklavier-devel %ifarch %livearches Requires: usermode Requires: zenity diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py index 441f43b..1f7dc95 100644 --- a/pyanaconda/ui/gui/spokes/keyboard.py +++ b/pyanaconda/ui/gui/spokes/keyboard.py @@ -30,6 +30,7 @@ from pyanaconda.ui.gui import UIObject from pyanaconda.ui.gui.spokes import NormalSpoke from pyanaconda.ui.gui.categories.localization import LocalizationCategory from pyanaconda.ui.gui.utils import enlightbox +from pyanaconda import xklavier __all__ = ["KeyboardSpoke"] @@ -38,6 +39,9 @@ class AddLayoutDialog(UIObject): mainWidgetName = "addLayoutDialog" uiFile = "spokes/keyboard.ui" + def __init__(self): + self._xkl_wrapper = xklavier.XklWrapper() + def matches_entry(self, model, itr, user_data=None): value = model.get_value(itr, 0) entry_text = self._entry.get_text() @@ -64,12 +68,8 @@ class AddLayoutDialog(UIObject): def initialize(self): self._store = self.builder.get_object("newLayoutStore") - #XXX: will use values from the libxklavier - self._addLayout(self._store, "English (US)") - self._addLayout(self._store, "English (US, with some other stuff)") - self._addLayout(self._store, "Czech") - self._addLayout(self._store, "Czech (qwerty)") - self._addLayout(self._store, "values from libxklavier") + for layout in self._xkl_wrapper.get_available_layouts(): + self._addLayout(self._store, layout) def run(self): rc = self.window.run() diff --git a/pyanaconda/xklavier.py b/pyanaconda/xklavier.py new file mode 100755 index 0000000..bac19db --- /dev/null +++ b/pyanaconda/xklavier.py @@ -0,0 +1,102 @@ +# +# Copyright (C) 2012 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. +# +# Red Hat Author(s): Martin Gracik <mgracik@xxxxxxxxxx> +# Vratislav Podzimek <vpodzime@xxxxxxxxxx> +# + +""" +This module wraps the libxklavier functionality to protect Anaconda +from dealing with it's "nice" API that looks like a Lisp-influenced +"good old C". + +It provides a XklWrapper class with several methods that can be used +for listing and various modifications of keyboard layouts settings. +""" + +from gi.repository import Xkl, Gdk, GdkX11 + +def item_str(s): + """Convert a zero-terminated byte array to a proper str""" + + i = s.find(b'\x00') + return s[:i].decode("utf-8") #there are some non-ascii layout descriptions + +class _Variant(object): + """Internal class representing a single layout variant""" + + def __init__(self, name, desc): + self.name = name + self.desc = desc + + def __str__(self): + return '%s (%s)' % (self.name, self.desc) + + @property + def description(self): + return self.desc + +class XklWrapper(object): + """Class wrapping the libxklavier functionality""" + + def __init__(self): + #initialize Xkl-related stuff + display = GdkX11.x11_get_default_xdisplay() + engine = Xkl.Engine.get_instance(display) + self._configreg = Xkl.ConfigRegistry.get_instance(engine) + self._configreg.load(False) + + self._language_keyboard_variants = dict() + self._country_keyboard_variants = dict() + + def get_variant(self, c_reg, item, subitem, user_data=None): + variants = list() + + if subitem: + variants.append(_Variant(item_str(subitem.name), item_str(subitem.description))) + else: + variants.append(_Variant(item_str(item.name), item_str(item.description))) + + self._variants_list.append(variants) + + def get_language_variants(self, c_reg, item, user_data=None): + #helper "global" variable + self._variants_list = list() + lang_name, lang_desc = item_str(item.name), item_str(item.description) + + c_reg.foreach_language_variant(lang_name, self.get_variant, None) + + self._language_keyboard_variants[(lang_name, lang_desc)] = self._variants_list + + def get_country_variants(self, c_reg, item, user_data=None): + #helper "global" variable + self._variants_list = list() + country_name, country_desc = item_str(item.name), item_str(item.description) + + c_reg.foreach_country_variant(country_name, self.get_variant, None) + + self._country_keyboard_variants[(country_name, country_desc)] = self._variants_list + + def get_available_layouts(self): + """A generator yielding layouts (no need to store them as a bunch)""" + self._configreg.foreach_language(self.get_language_variants, None) + + for (lang_name, lang_desc), variants in sorted(self._language_keyboard_variants.items()): + for variant in variants: + for layout in variant: + yield "%s (%s)" % (lang_desc.encode("utf-8"), layout.description.encode("utf-8")) + -- 1.7.4.4 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list