def replace_layouts(self, layouts_list): """ Method that replaces the layouts defined in the current X configuration with the new ones given. :param layouts_list: list of layouts defined as either 'layout' or 'layout (variant)' :raise XklWrapperError: if layouts cannot be replaced with the new ones """ new_layouts = list() new_variants = list() for layout_variant in layouts_list: (layout, variant) = parse_layout_variant(layout_variant) new_layouts.append(layout) new_variants.append(variant) self._rec.set_layouts(new_layouts) self._rec.set_variants(new_variants) if not self._rec.activate(self._engine): msg = "Failed to replace layouts with: %s" % ",".join(layouts_list) raise XklWrapperError(msg)
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 is invalid or cannot be added """ try: #we can get 'layout' or 'layout (variant)' (layout, variant) = parse_layout_variant(layout) except InvalidLayoutVariantSpec as ilverr: raise XklWrapperError("Failed to add layout: %s" % ilverr) #do not add the same layout-variant combinanion multiple times if (layout, variant) in list(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) = parse_layout_variant(layout) layouts_variants = list(zip(self._rec.layouts, self._rec.variants)) if not (layout, variant) in layouts_variants: msg = "'%s (%s)' not in the list of added layouts" % (layout, variant) raise XklWrapperError(msg) idx = layouts_variants.index((layout, variant)) new_layouts = self._rec.layouts[:idx] + self._rec.layouts[(idx + 1):] # pylint: disable=unsubscriptable-object new_variants = self._rec.variants[:idx] + self._rec.variants[(idx + 1):] # pylint: disable=unsubscriptable-object 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))
def test_layout_variant_parse_join(self): """Parsing and joining valid layout and variant spec should have no effect.""" specs = ("cz", "cz (qwerty)") for spec in specs: (layout, variant) = keyboard.parse_layout_variant(spec) assert spec == keyboard.join_layout_variant(layout, variant)
def layout_variant_parse_join_test(self): """Parsing and joining valid layout and variant spec should have no effect.""" specs = ("cz", "cz (qwerty)") for spec in specs: (layout, variant) = keyboard.parse_layout_variant(spec) self.assertEqual(spec, keyboard._join_layout_variant(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) = parse_layout_variant(layout) layouts_variants = list(zip(self._rec.layouts, self._rec.variants)) if not (layout, variant) in layouts_variants: msg = "'%s (%s)' not in the list of added layouts" % (layout, variant) raise XklWrapperError(msg) 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))
def set_layouts(self, layouts_variants, options=None, convert=False): """Set X11 layouts. :param layouts_variants: list of 'layout (variant)' or 'layout' specifications of layouts and variants :type layouts_variants: list(str) :param options: list of X11 options that should be set :type options: list(str) :param convert: whether the layouts should be converted to a VConsole keymap (see set_and_convert_layouts) :type convert: bool """ if not self._localed_proxy: return layouts = [] variants = [] for layout_variant in (nonempty for nonempty in layouts_variants if nonempty): (layout, variant) = parse_layout_variant(layout_variant) layouts.append(layout) variants.append(variant) layouts_str = ",".join(layouts) variants_str = ",".join(variants) options_str = ",".join(options) if options else "" self._localed_proxy.SetX11Keyboard( layouts_str, "", variants_str, options_str, convert, False )
def layout_variant_parsing_test(self): """Should correctly parse keyboard layout and variant string specs.""" # valid layout variant specs layout, variant = keyboard.parse_layout_variant("cz (qwerty)") self.assertEqual(layout, "cz") self.assertEqual(variant, "qwerty") layout, variant = keyboard.parse_layout_variant("cz (dvorak-ucw)") self.assertEqual(layout, "cz") self.assertEqual(variant, "dvorak-ucw") # a valid layout variant spec with no variant specified layout, variant = keyboard.parse_layout_variant("cz") self.assertEqual(layout, "cz") self.assertEqual(variant, "") # an invalid layout variant spec (missing layout) with self.assertRaises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("") # another invalid layout variant spec (invalid layout) with self.assertRaises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("&*&%$") # another invalid layout variant spec (square brackets) with self.assertRaises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("cz [qwerty]") # another invalid layout variant spec (invalid variant) with self.assertRaises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("cz (&*&*)")
def on_preview_clicked(self, button): selection = self.builder.get_object("layoutSelection") (store, cur) = selection.get_selected() layout_row = store[cur] if not layout_row: return layout, variant = keyboard.parse_layout_variant(layout_row[0]) lay_var_spec = "%s\t%s" % (layout, variant) dialog = Gkbd.KeyboardDrawing.dialog_new() Gkbd.KeyboardDrawing.dialog_set_layout(dialog, self._xkl_wrapper.configreg, lay_var_spec) dialog.set_size_request(750, 350) dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) with enlightbox(self.window, dialog): dialog.show_all() dialog.run()
def set_layouts(self, layouts_variants, options=None, convert=False): """Set X11 layouts. :param layouts_variants: list of 'layout (variant)' or 'layout' specifications of layouts and variants :type layouts_variants: list(str) :param options: list of X11 options that should be set :type options: list(str) :param convert: whether the layouts should be converted to a VConsole keymap (see set_and_convert_layouts) :type convert: bool """ if not self._localed_proxy: return layouts = [] variants = [] parsing_failed = False for layout_variant in (nonempty for nonempty in layouts_variants if nonempty): try: (layout, variant) = parse_layout_variant(layout_variant) except InvalidLayoutVariantSpec as e: log.debug("Parsing of %s failed: %s", layout_variant, e) parsing_failed = True continue layouts.append(layout) variants.append(variant) if not layouts and parsing_failed: return layouts_str = ",".join(layouts) variants_str = ",".join(variants) options_str = ",".join(options) if options else "" self._localed_proxy.SetX11Keyboard( layouts_str, "", variants_str, options_str, convert, False )
def test_layout_variant_parsing(self): """Should correctly parse keyboard layout and variant string specs.""" # valid layout variant specs layout, variant = keyboard.parse_layout_variant("cz (qwerty)") assert layout == "cz" assert variant == "qwerty" layout, variant = keyboard.parse_layout_variant("cz (dvorak-ucw)") assert layout == "cz" assert variant == "dvorak-ucw" # a valid layout variant spec with no variant specified layout, variant = keyboard.parse_layout_variant("cz") assert layout == "cz" assert variant == "" # a valid layout variant spec containing a slash layout, variant = keyboard.parse_layout_variant("nec_vndr/jp") assert layout == "nec_vndr/jp" assert variant == "" # an invalid layout variant spec (missing layout) with pytest.raises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("") # another invalid layout variant spec (invalid layout) with pytest.raises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("&*&%$") # another invalid layout variant spec (square brackets) with pytest.raises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("cz [qwerty]") # another invalid layout variant spec (invalid variant) with pytest.raises(keyboard.InvalidLayoutVariantSpec): layout, variant = keyboard.parse_layout_variant("cz (&*&*)")
def on_preview_clicked(self, button): (store, cur) = self._selection.get_selected() layout_row = store[cur] if not layout_row: return layout, variant = keyboard.parse_layout_variant(layout_row[0]) if variant: lay_var_spec = "%s\t%s" % (layout, variant) else: lay_var_spec = layout dialog = Gkbd.KeyboardDrawing.dialog_new() Gkbd.KeyboardDrawing.dialog_set_layout(dialog, self._xkl_wrapper.configreg, lay_var_spec) dialog.set_size_request(750, 350) dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) with self.main_window.enlightbox(dialog): dialog.show_all() dialog.run() dialog.destroy()