mirror of
https://github.com/Julow/Unexpected-Keyboard.git
synced 2024-11-23 15:53:14 +01:00
dad5f57a03
The two layout selection options are replaced by a ListGroupPreference that allow to enter an arbitrary amount of layouts. The "switch_second" and "switch_second_back" keys are replaced by "switch_forward" and "switch_backward", which allow to cycle through the selected layouts in two directions. Layouts are changed to place these two key on the space bar. The backward key is not shown if there's only two layouts.
72 lines
2.9 KiB
Python
72 lines
2.9 KiB
Python
#!/usr/bin/env python
|
|
|
|
# Generates the list of layouts in res/values/layouts.xml from the layout files
|
|
# in res/xml. Every layouts must have a 'name' attribute to be listed.
|
|
|
|
import itertools as it
|
|
import sys, os, glob
|
|
import xml.etree.ElementTree as XML
|
|
|
|
# Layouts first in the list (these are the programming layouts). Other layouts
|
|
# are sorted alphabetically.
|
|
FIRST_LAYOUTS = [ "latn_qwerty_us", "latn_colemak", "latn_dvorak" ]
|
|
|
|
# File names that are known not to be layouts. Avoid warning about them.
|
|
KNOWN_NOT_LAYOUT = set([
|
|
"number_row", "numpad", "pin", "bottom_row", "settings", "method",
|
|
"greekmath", "numeric" ])
|
|
|
|
# Read a layout from a file. Returns [None] if [fname] is not a layout.
|
|
def read_layout(fname):
|
|
root = XML.parse(fname).getroot()
|
|
if root.tag != "keyboard":
|
|
return None
|
|
return { "name": root.get("name") }
|
|
|
|
# Yields the id (based on the file name) and the display name for every layouts
|
|
def read_layouts(files):
|
|
for layout_file in files:
|
|
layout_id, _ = os.path.splitext(os.path.basename(layout_file))
|
|
layout = read_layout(layout_file)
|
|
if layout_id in KNOWN_NOT_LAYOUT:
|
|
continue
|
|
elif layout == None:
|
|
print("Not a layout file: %s" % layout_file)
|
|
elif layout["name"] == None:
|
|
print("Layout doesn't have a name: %s" % layout_id)
|
|
else:
|
|
yield (layout_id, layout["name"])
|
|
|
|
# Sort layouts alphabetically, except for layouts in FIRST_LAYOUTS, which are
|
|
# placed at the top.
|
|
# Returns a list. 'layouts' can be an iterator.
|
|
def sort_layouts(layouts):
|
|
layouts = dict(layouts)
|
|
head = [ (lid, layouts.pop(lid)) for lid in FIRST_LAYOUTS ]
|
|
return head + sorted(layouts.items())
|
|
|
|
# Write the XML arrays used in the preferences.
|
|
def generate_arrays(out, layouts):
|
|
def mk_array(tag, name, strings_items):
|
|
elem = XML.Element(tag, name=name)
|
|
for s in strings_items:
|
|
item = XML.Element("item")
|
|
item.text = s
|
|
elem.append(item)
|
|
return elem
|
|
none_item = [ ("system", "@string/pref_layout_e_system") ]
|
|
custom_item = [ ("custom", "@string/pref_layout_e_custom") ]
|
|
values_items, entries_items = zip(*(none_item + layouts + custom_item)) # unzip
|
|
ids_items = map(lambda s: "@xml/%s" % s if s not in ["system", "custom"] else "-1", values_items)
|
|
root = XML.Element("resources")
|
|
root.append(XML.Comment(text="DO NOT EDIT. This file is generated, see gen_layouts.py."))
|
|
root.append(mk_array("string-array", "pref_layout_values", values_items))
|
|
root.append(mk_array("string-array", "pref_layout_entries", entries_items))
|
|
root.append(mk_array("integer-array", "layout_ids", ids_items))
|
|
XML.indent(root)
|
|
XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True)
|
|
|
|
layouts = sort_layouts(read_layouts(glob.glob("res/xml/*.xml")))
|
|
with open("res/values/layouts.xml", "w") as out:
|
|
generate_arrays(out, layouts)
|