2023-06-25 15:52:24 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
# Generates the list of layouts in res/values/layouts.xml from the layout files
|
2024-01-21 16:34:49 +01:00
|
|
|
# in srcs/layouts. Every layouts must have a 'name' attribute to be listed.
|
2023-06-25 15:52:24 +02:00
|
|
|
|
|
|
|
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" ]
|
|
|
|
|
|
|
|
# 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)
|
2024-01-21 16:34:49 +01:00
|
|
|
if layout == None:
|
2023-06-25 15:52:24 +02:00
|
|
|
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):
|
2023-06-25 16:34:05 +02:00
|
|
|
def mk_array(tag, name, strings_items):
|
|
|
|
elem = XML.Element(tag, name=name)
|
|
|
|
for s in strings_items:
|
2023-06-25 15:52:24 +02:00
|
|
|
item = XML.Element("item")
|
|
|
|
item.text = s
|
2023-06-25 16:34:05 +02:00
|
|
|
elem.append(item)
|
|
|
|
return elem
|
2023-08-10 12:57:31 +02:00
|
|
|
system_item = [ ("system", "@string/pref_layout_e_system") ]
|
2023-06-25 15:52:24 +02:00
|
|
|
custom_item = [ ("custom", "@string/pref_layout_e_custom") ]
|
2023-08-10 12:57:31 +02:00
|
|
|
values_items, entries_items = zip(*(system_item + layouts + custom_item)) # unzip
|
2023-07-29 18:37:06 +02:00
|
|
|
ids_items = map(lambda s: "@xml/%s" % s if s not in ["system", "custom"] else "-1", values_items)
|
2023-06-25 15:52:24 +02:00
|
|
|
root = XML.Element("resources")
|
|
|
|
root.append(XML.Comment(text="DO NOT EDIT. This file is generated, see gen_layouts.py."))
|
2023-06-25 16:34:05 +02:00
|
|
|
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))
|
2023-06-25 15:52:24 +02:00
|
|
|
XML.indent(root)
|
|
|
|
XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True)
|
|
|
|
|
2024-01-21 16:34:49 +01:00
|
|
|
layouts = sort_layouts(read_layouts(glob.glob("srcs/layouts/*.xml")))
|
2023-06-25 15:52:24 +02:00
|
|
|
with open("res/values/layouts.xml", "w") as out:
|
|
|
|
generate_arrays(out, layouts)
|