diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | libcaribou/Makefile.am | 8 | ||||
-rw-r--r-- | libcaribou/json-deserializer.vala | 136 | ||||
-rw-r--r-- | libcaribou/key-model.vala | 3 | ||||
-rw-r--r-- | libcaribou/keyboard-model.vala | 2 | ||||
-rw-r--r-- | libcaribou/xml-deserializer.vala | 148 |
6 files changed, 155 insertions, 144 deletions
diff --git a/configure.ac b/configure.ac index 04e28c1..1de639f 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,7 @@ PKG_CHECK_MODULES(LIBCARIBOU, [ xtst, x11, libxklavier, - json-glib-1.0, + libxml-2.0, gee-1.0 ]) AC_SUBST(LIBCARIBOU_CFLAGS) diff --git a/libcaribou/Makefile.am b/libcaribou/Makefile.am index e879eb3..e01a188 100644 --- a/libcaribou/Makefile.am +++ b/libcaribou/Makefile.am @@ -9,8 +9,8 @@ libcaribou_la_VALAFLAGS = \ -H caribou.h --vapi caribou-1.0.vapi \ -h caribou-internals.h \ --vapidir=. \ - --pkg x11 --pkg json-glib-1.0 --pkg gdk-3.0 --pkg gio-2.0 --pkg gee-1.0 \ - --pkg libxklavier --pkg external-libs --pkg gdk-x11-3.0 \ + --pkg x11 --pkg gdk-3.0 --pkg gio-2.0 --pkg gee-1.0 \ + --pkg libxklavier --pkg external-libs --pkg gdk-x11-3.0 --pkg libxml-2.0 \ --internal-vapi caribou-internals-1.0.vapi \ --library caribou-1.0 --gir _Caribou-1.0.gir \ $(VALAFLAGS) @@ -39,11 +39,11 @@ libcaribou_la_SOURCES = \ key-model.vala \ column-model.vala \ scanner.vala \ - json-deserializer.vala \ iscannable-item.vala \ iscannable-group.vala \ scannable-group.vala \ - ikeyboard-object.vala + ikeyboard-object.vala \ + xml-deserializer.vala EXTRA_DIST = \ external-libs.vapi \ diff --git a/libcaribou/json-deserializer.vala b/libcaribou/json-deserializer.vala deleted file mode 100644 index ea448a4..0000000 --- a/libcaribou/json-deserializer.vala +++ /dev/null @@ -1,136 +0,0 @@ -namespace Caribou { - - private class JsonDeserializer : Object { - - public static bool get_layout_file_inner (string data_dir, - string group, - string variant, - out File fp) { - string[] files = {@"$(group)_$(variant).json", @"$(group).json"}; - - foreach (string fn in files) { - string layout_fn = GLib.Path.build_filename (data_dir, fn); - fp = GLib.File.new_for_path (layout_fn); - if (fp.query_exists ()) - return true; - } - - return false; - } - - public static GLib.File get_layout_file (string keyboard_type, string group, - string variant) throws IOError { - - List<string> dirs = new List<string> (); - string custom_dir = Environment.get_variable("CARIBOU_LAYOUTS_DIR"); - - if (custom_dir != null) - dirs.append (Path.build_filename (custom_dir, "layouts", - keyboard_type)); - - dirs.append (Path.build_filename (Environment.get_user_data_dir (), - "caribou", "layouts", keyboard_type)); - - foreach (string data_dir in Environment.get_system_data_dirs ()) { - dirs.append (Path.build_filename ( - data_dir, "caribou", "layouts", keyboard_type)); - } - - foreach (string data_dir in dirs) { - File fp; - if (get_layout_file_inner (data_dir, group, variant, out fp)) - return fp; - } - - throw new IOError.NOT_FOUND ( - "Could not find layout file for %s %s", group, variant); } - - public static GroupModel? load_group (string keyboard_type, - string group, string variant) { - Json.Parser parser = new Json.Parser (); - - try { - GLib.File f = get_layout_file (keyboard_type, group, variant); - parser.load_from_stream (f.read (), (Cancellable) null); - } catch (GLib.Error e) { - stdout.printf ("Failed to load JSON: %s\n", e.message); - return null; - } - - GroupModel grp = new GroupModel (group, variant); - create_levels_from_json (grp, parser.get_root ()); - - return grp; - } - - public static void create_levels_from_json (GroupModel group, - Json.Node root) { - Json.Object obj = root.get_object (); - - if (root.get_node_type () != Json.NodeType.OBJECT) - return; - - foreach (string levelname in obj.get_members ()) { - unowned Json.Object json_level = obj.get_object_member (levelname); - string mode = ""; - - if (json_level.has_member ("mode")) - mode = json_level.get_string_member ("mode"); - - Json.Array json_rows = json_level.get_array_member ("rows"); - LevelModel level = new LevelModel(mode); - load_rows (level, json_rows); - - group.add_level(levelname, level); - } - } - - public static void load_rows (LevelModel level, Json.Array json_rows) { - for (int i=0;i<json_rows.get_length ();i++) { - Json.Array json_children = json_rows.get_array_element (i); - unowned Json.Node child = json_children.get_element(0); - if (child.get_node_type () == Json.NodeType.OBJECT) { - for (int j=0;j<json_children.get_length ();j++) { - Json.Object json_key = json_children.get_object_element (j); - level.add_key (i, 0, load_key (json_key)); - } - } else if (child.get_node_type () == Json.NodeType.ARRAY) { - for (int k=0;k<json_children.get_length ();k++) { - Json.Array json_keys = json_children.get_array_element (k); - for (int j=0;j<json_keys.get_length ();j++) { - Json.Object json_key = json_keys.get_object_element (j); - level.add_key (i, k, load_key (json_key)); - } - } - } - } - } - - public static KeyModel load_key (Json.Object json_key) { - KeyModel key = new KeyModel (json_key.get_string_member ("name")); - - if (json_key.has_member ("toggle")) - key.toggle = json_key.get_string_member ("toggle"); - - if (json_key.has_member ("margin_left")) - key.margin_left = json_key.get_double_member ("margin_left"); - - if (json_key.has_member ("width")) - key.width = json_key.get_double_member ("width"); - - if (json_key.has_member ("extended_names")) { - Json.Array json_keys = json_key.get_array_member ("extended_names"); - uint nkeys = json_keys.get_length (); - uint i; - - key.add_subkey(key.name); - - for (i=0;i<nkeys;i++) - key.add_subkey(json_keys.get_string_element (i)); - } - - return key; - } - - } -}
\ No newline at end of file diff --git a/libcaribou/key-model.vala b/libcaribou/key-model.vala index 81babd6..da90c4f 100644 --- a/libcaribou/key-model.vala +++ b/libcaribou/key-model.vala @@ -40,8 +40,7 @@ namespace Caribou { extended_keys = new Gee.ArrayList<KeyModel> (); } - internal void add_subkey (string name) { - KeyModel key = new KeyModel (name); + internal void add_subkey (KeyModel key) { key.key_activated.connect(on_subkey_activated); extended_keys.add (key); } diff --git a/libcaribou/keyboard-model.vala b/libcaribou/keyboard-model.vala index e34a3a3..0b7bea0 100644 --- a/libcaribou/keyboard-model.vala +++ b/libcaribou/keyboard-model.vala @@ -32,7 +32,7 @@ namespace Caribou { } private void populate_group (string group, string variant) { - GroupModel grp = JsonDeserializer.load_group (keyboard_type, + GroupModel grp = XmlDeserializer.load_group (keyboard_type, group, variant); if (grp != null) { groups.set (GroupModel.create_group_name (group, variant), grp); diff --git a/libcaribou/xml-deserializer.vala b/libcaribou/xml-deserializer.vala new file mode 100644 index 0000000..4656f28 --- /dev/null +++ b/libcaribou/xml-deserializer.vala @@ -0,0 +1,148 @@ +using Xml; + +namespace Caribou { + + private class XmlDeserializer : Object { + + public static string? get_layout_file_inner (string data_dir, + string group, + string variant) { + string[] files = {@"$(group)_$(variant).xml", @"$(group).xml"}; + + foreach (string fn in files) { + string layout_fn = GLib.Path.build_filename (data_dir, fn); + GLib.File fp = GLib.File.new_for_path (layout_fn); + if (fp.query_exists ()) + return layout_fn; + } + + return null; + } + + public static string get_layout_file (string keyboard_type, string group, + string variant) throws IOError { + + List<string> dirs = new List<string> (); + string custom_dir = Environment.get_variable("CARIBOU_LAYOUTS_DIR"); + + if (custom_dir != null) + dirs.append (Path.build_filename (custom_dir, "layouts", + keyboard_type)); + + dirs.append (Path.build_filename (Environment.get_user_data_dir (), + "caribou", "layouts", keyboard_type)); + + foreach (string dir in Environment.get_system_data_dirs ()) { + dirs.append (Path.build_filename ( + dir, "caribou", "layouts", keyboard_type)); + } + + foreach (string data_dir in dirs) { + string fn = get_layout_file_inner (data_dir, group, variant); + if (fn != null) + return fn; + } + + throw new IOError.NOT_FOUND ( + "Could not find layout file for %s %s", group, variant); } + + public static GroupModel? load_group (string keyboard_type, + string group, string variant) { + Doc* doc; + + try { + string fn = get_layout_file (keyboard_type, group, variant); + doc = Parser.parse_file (fn); + if (doc == null) + throw new IOError.FAILED ( + "Cannot load XML text reader for %s", fn); + } catch (GLib.Error e) { + stdout.printf ("Failed to load XML: %s\n", e.message); + return null; + } + + GroupModel grp = new GroupModel (group, variant); + Xml.Node* node = doc->children; + + create_levels_from_xml (grp, node); + + delete doc; + Parser.cleanup (); + + return grp; + } + + public static void create_levels_from_xml (GroupModel group, + Xml.Node* node) { + assert (node->name == "layout"); + for (Xml.Node* iter = node->children; iter != null; iter = iter->next) { + if (iter->type != ElementType.ELEMENT_NODE) + continue; + + string levelname = iter->get_prop ("name"); + string mode = iter->get_prop ("mode"); + + LevelModel level = new LevelModel(mode); + load_rows (level, iter); + + group.add_level(levelname, level); + } + } + + public static void load_rows (LevelModel level, Xml.Node* node) { + assert (node->name == "level"); + int rownum = 0; + for (Xml.Node* i = node->children; i != null; i = i->next) { + if (i->type != ElementType.ELEMENT_NODE) + continue; + + int colnum = 0; + for (Xml.Node* i2 = i->children; i2 != null; i2 = i2->next) { + if (i2->name == "key") + level.add_key (rownum, colnum, load_key(i2)); + else if (i2->name == "column") + load_column (level, rownum, colnum++, i2); + } + rownum++; + } + } + + public static void load_column (LevelModel level, int row, int col, + Xml.Node* node) { + assert (node->name == "column"); + for (Xml.Node* i = node->children; i != null; i = i->next) { + if (i->type != ElementType.ELEMENT_NODE) + continue; + + level.add_key (row, col, load_key (i)); + } + } + + public static KeyModel load_key (Xml.Node* node) { + assert (node->name == "key"); + + string name = node->get_prop ("name"); + assert (name != null); + + KeyModel key = new KeyModel (name); + + for (Attr* prop = node->properties; prop != null; prop = prop->next) { + if (prop->name == "toggle") + key.toggle = prop->children->content; + else if (prop->name == "margin-left") + key.margin_left = double.parse (prop->children->content); + else if (prop->name == "width") + key.width = double.parse (prop->children->content); + } + + for (Xml.Node* i = node->children; i != null; i = i->next) { + if (i->type != ElementType.ELEMENT_NODE) + continue; + + key.add_subkey (load_key (i)); + } + + return key; + } + } +}
\ No newline at end of file |