[newui] [PATCH] Use libxklavier to get a list of available layouts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux