FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Gentoo > Gentoo Development

 
 
LinkBack Thread Tools
 
Old 05-14-2012, 03:47 PM
Vratislav Podzimek
 
Default Add and remove layouts from the X runtime configuration

When user adds/removes a layout, we want to add/remove it from the
X runtime configuration so that the change really happens.
---
pyanaconda/ui/gui/spokes/keyboard.py | 4 +
pyanaconda/ui/gui/spokes/welcome.py | 1 +
pyanaconda/xklavier.py | 106 +++++++++++++++++++++++++++++++++-
3 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py
index 1223a63..6a04d6d 100644
--- a/pyanaconda/ui/gui/spokes/keyboard.py
+++ b/pyanaconda/ui/gui/spokes/keyboard.py
@@ -183,6 +183,7 @@ class KeyboardSpoke(NormalSpoke):

def _addLayout(self, store, name):
store.append([name])
+ self._xkl_wrapper.add_layout(name)

# Signal handlers.
def on_add_clicked(self, button):
@@ -222,6 +223,7 @@ class KeyboardSpoke(NormalSpoke):
itr2 = store.iter_next(itr2)
if itr2: #next one existing
selection.select_iter(itr2)
+ self._xkl_wrapper.remove_layout(store[itr][0])
store.remove(itr)
return

@@ -239,6 +241,8 @@ class KeyboardSpoke(NormalSpoke):
while itr3 and (store[itr3][0] != store[itr][0]):
itr2 = store.iter_next(itr2)
itr3 = store.iter_next(itr3)
+
+ self._xkl_wrapper.remove_layout(store[itr][0])
store.remove(itr)
selection.select_iter(itr2)

diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index 7e7444d..e4dd145 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -74,6 +74,7 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
for layout in new_layouts:
if layout not in self.data.keyboard.layouts_list:
self.data.keyboard.layouts_list.append(layout)
+ self._xklwrapper.add_layout(layout)

#TODO: better use GeoIP data once it is available
if self.language.territory and not self.data.timezone.timezone:
diff --git a/pyanaconda/xklavier.py b/pyanaconda/xklavier.py
index 386dea2..3dad44f 100755
--- a/pyanaconda/xklavier.py
+++ b/pyanaconda/xklavier.py
@@ -50,6 +50,11 @@ class _Layout(object):
def description(self):
return self.desc

+class XklWrapperError(Exception):
+ """Exception class for reporting libxklavier-related problems"""
+
+ pass
+
class XklWrapper(object):
"""
Class wrapping the libxklavier functionality
@@ -72,10 +77,29 @@ class XklWrapper(object):
def __init__(self):
#initialize Xkl-related stuff
display = GdkX11.x11_get_default_xdisplay()
- engine = Xkl.Engine.get_instance(display)
+ self._engine = Xkl.Engine.get_instance(display)
+
+ self._rec = Xkl.ConfigRec()
+ if not self._rec.get_from_server(self._engine):
+ raise XklWrapperError("Failed to get configuration from server")
+
+ #X is probably initialized to the 'us' layout without any variant and
+ #since we want to add layouts with variants we need the layouts and
+ #variants lists to have the same length. Add "" padding to variants.
+ #See docstring of the add_layout method for details.
+ diff = len(self._rec.layouts) - len(self._rec.variants)
+ if diff > 0:
+ self._rec.set_variants(self._rec.variants + (diff * [""]))
+ if not self._rec.activate(self._engine):
+ raise XklWrapperError("Failed to initialize layouts")
+
+ #initialize layout switching to Alt+Shift
+ self._rec.set_options(self._rec.options + ["grp:alt_shift_toggle"])
+ if not self._rec.activate(self._engine):
+ raise XklWrapperError("Cannot initialize layout switching")

#needed also for Gkbd.KeyboardDrawingDialog
- self.configreg = Xkl.ConfigRegistry.get_instance(engine)
+ self.configreg = Xkl.ConfigRegistry.get_instance(self._engine)
self.configreg.load(False)

self._language_keyboard_variants = dict()
@@ -134,3 +158,81 @@ class XklWrapper(object):
#first layout (should exist for every language)
return language_layouts[0].name

+ def _parse_layout_variant(self, layout):
+ """
+ Parse layout and variant from the string that may look like 'layout' or
+ 'layout (variant)'.
+
+ @return: the (layout, variant) pair, where variant can be ""
+ @rtype: tuple
+
+ """
+
+ variant = ""
+
+ lbracket_idx = layout.find("(")
+ rbracket_idx = layout.rfind(")")
+ if lbracket_idx != -1:
+ variant = layout[(lbracket_idx + 1) : rbracket_idx]
+ layout = layout[:lbracket_idx].strip()
+
+ return (layout, variant)
+
+ def add_layout(self, layout):
+ """
+ Method that tries to add a given layout to the current X configuration.
+
+ The X layouts configuration is handled by two lists. A list of layouts
+ and a list of variants. Index-matching items in these lists (as if they
+ were zipped) are used for the construction of real layouts (e.g.
+ 'cz (qwerty)').
+
+ @param layout: either 'layout' or 'layout (variant)'
+ @raise XklWrapperError: if the given layout cannot be added
+
+ """
+
+ #we can get 'layout' or 'layout (variant)'
+ (layout, variant) = self._parse_layout_variant(layout)
+
+ #do not add the same layout-variant combinanion multiple times
+ if (layout, variant) in zip(self._rec.layouts, self._rec.variants):
+ return
+
+ self._rec.set_layouts(self._rec.layouts + [layout])
+ self._rec.set_variants(self._rec.variants + [variant])
+
+ if not self._rec.activate(self._engine):
+ raise XklWrapperError("Failed to add layout '%s (%s)'" % (layout,
+ variant))
+
+ def remove_layout(self, layout):
+ """
+ Method that tries to remove a given layout from the current X
+ configuration.
+
+ See also the documentation for the add_layout method.
+
+ @param layout: either 'layout' or 'layout (variant)'
+ @raise XklWrapperError: if the given layout cannot be removed
+
+ """
+
+ #we can get 'layout' or 'layout (variant)'
+ (layout, variant) = self._parse_layout_variant(layout)
+
+ layouts_variants = zip(self._rec.layouts, self._rec.variants)
+
+ if not (layout, variant) in layouts_variants:
+ raise XklWrapperError("'%s (%s)' not in the list of added layouts")
+
+ idx = layouts_variants.index((layout, variant))
+ new_layouts = self._rec.layouts[:idx] + self._rec.layouts[(idx + 1):]
+ new_variants = self._rec.variants[:idx] + self._rec.variants[(idx + 1):]
+
+ self._rec.set_layouts(new_layouts)
+ self._rec.set_variants(new_variants)
+
+ if not self._rec.activate(self._engine):
+ raise XklWrapperError("Failed to remove layout '%s (%s)'" % (layout,
+ variant))
--
1.7.4.4

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 

Thread Tools




All times are GMT. The time now is 04:07 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org