[dconf] Make dconf-editor understand and display schemas
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf] Make dconf-editor understand and display schemas
- Date: Tue, 15 Jun 2010 07:35:27 +0000 (UTC)
commit 68ee02e3654e13da7c0c53928ab2de2a36313f87
Author: Robert Ancell <robert ancell canonical com>
Date: Tue Jun 15 17:33:08 2010 +1000
Make dconf-editor understand and display schemas
configure.ac | 2 +
editor/Makefile.am | 8 +-
editor/dconf-editor.vala | 231 ++++++++++++++-----------
editor/dconf-model.vala | 428 ++++++++++++++++++++++++++++++++++++++++++++++
editor/dconf-schema.vala | 147 ++++++++++++++++
editor/dconf-view.vala | 201 ++++++++++++++++++++++
editor/dconf.vapi | 8 +-
7 files changed, 918 insertions(+), 107 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 29b3dbd..f4633a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,8 @@ AC_PROG_CC
PKG_CHECK_MODULES(gio, gio-2.0 >= 2.25.7)
PKG_CHECK_MODULES(gtk, gtk+-2.0)
+PKG_CHECK_MODULES(gee, gee-1.0)
+PKG_CHECK_MODULES(libxml, libxml-2.0)
AC_ARG_WITH(gio_modules_dir, [ --with-gio-modules-dir=PATH choose directory for the GIO module, [default=LIBDIR/gio/modules]], giomodulesdir="$withval", giomodulesdir=${libdir}/gio/modules)
AC_SUBST(giomodulesdir)
diff --git a/editor/Makefile.am b/editor/Makefile.am
index 2d6a486..e2e77a6 100644
--- a/editor/Makefile.am
+++ b/editor/Makefile.am
@@ -1,6 +1,6 @@
bin_PROGRAMS = dconf-editor
-AM_CFLAGS = $(gtk_CFLAGS) -I$(top_srcdir)/common -I$(top_srcdir)/client
-AM_VALAFLAGS = --pkg gtk+-2.0
-dconf_editor_LDADD = ../client/libdconf.la $(gtk_LIBS)
-dconf_editor_SOURCES = dconf-editor.vala dconf.vapi
+AM_CFLAGS = $(gtk_CFLAGS) $(gee_CFLAGS) $(libxml_CFLAGS) -I$(top_srcdir)/common -I$(top_srcdir)/client
+AM_VALAFLAGS = --pkg gee-1.0 --pkg gtk+-2.0 --pkg libxml-2.0
+dconf_editor_LDADD = ../client/libdconf.la $(gtk_LIBS) $(gee_LIBS) $(libxml_LIBS)
+dconf_editor_SOURCES = dconf-editor.vala dconf-model.vala dconf-schema.vala dconf-view.vala dconf.vapi
diff --git a/editor/dconf-editor.vala b/editor/dconf-editor.vala
index 127881a..e52057a 100644
--- a/editor/dconf-editor.vala
+++ b/editor/dconf-editor.vala
@@ -1,61 +1,18 @@
-public class ConfModel : Gtk.TreeStore
-{
- public ConfModel()
- {
- set_column_types({typeof(string), typeof(string)});
- }
-
- private Gtk.TreeIter? get_iter(string[] split_key, int length)
- {
- if (length == 1) // NOTE: Assumes key started with /
- return null;
-
- Gtk.TreeIter? parent = get_iter(split_key, length - 1);
- string key = split_key[length - 1];
-
- Gtk.TreeIter iter;
- bool have_iter = iter_children(out iter, parent);
- while (have_iter)
- {
- string name;
- get(iter, 0, out name, -1);
- if (name == key)
- return iter;
- if (name > key)
- {
- insert_before(out iter, parent, iter);
- break;
- }
- have_iter = iter_next(ref iter);
- }
- if (!have_iter)
- append(out iter, parent);
-
- set(iter, 0, key, -1);
-
- return iter;
- }
-
- public void add_key(string key)
- {
- string[] tokens = key.split("/", -1);
- Gtk.TreeIter? iter = get_iter(tokens, tokens.length);
- set(iter, 1, key, -1);
- }
-}
-
public class EditorWindow : Gtk.Window
{
- public ConfModel model;
-
- private DConf.Client client;
- private Gtk.TreeView tree_view;
- private Gtk.Label name_label;
- private Gtk.Label value_label;
-
- public EditorWindow(DConf.Client client)
+ public SettingsModel model;
+ public SchemaList schemas;
+
+ private Gtk.TreeView dir_tree_view;
+ private Gtk.TreeView key_tree_view;
+ private Gtk.Label schema_label;
+ private Gtk.Label summary_label;
+ private Gtk.Label description_label;
+ private Gtk.Label type_label;
+ private Gtk.Label default_label;
+
+ public EditorWindow()
{
- this.client = client;
set_title("Configuration Editor");
set_default_size(600, 300);
set_border_width(6);
@@ -64,87 +21,163 @@ public class EditorWindow : Gtk.Window
hbox.show();
add(hbox);
- model = new ConfModel();
+ model = new SettingsModel();
+ schemas = new SchemaList();
+ try
+ {
+ schemas.load_directory("/usr/share/glib-2.0/schemas");
+ } catch (Error e) {
+ warning("Failed to parse schemas: %s", e.message);
+ }
+
+ Gtk.ScrolledWindow scroll = new Gtk.ScrolledWindow(null, null);
+ scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+ scroll.show();
+ hbox.pack_start(scroll, false, false, 0);
- tree_view = new Gtk.TreeView();
- tree_view.set_headers_visible(false);
- tree_view.set_model(model);
- tree_view.insert_column_with_attributes(-1, "Key", new Gtk.CellRendererText(), "text", 0, null);
- tree_view.get_selection().changed.connect(key_selected_cb);
- tree_view.show();
- hbox.pack_start(tree_view, false, false, 0);
+ dir_tree_view = new DConfDirView();
+ dir_tree_view.set_model(model);
+ dir_tree_view.get_selection().changed.connect(dir_selected_cb); // FIXME: Put in view
+ dir_tree_view.show();
+ scroll.add(dir_tree_view);
Gtk.VBox vbox = new Gtk.VBox(false, 6);
vbox.show();
hbox.pack_start(vbox, true, true, 0);
+
+ scroll = new Gtk.ScrolledWindow(null, null);
+ scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
+ scroll.show();
+ vbox.pack_start(scroll, true, true, 0);
+
+ key_tree_view = new DConfKeyView();
+ key_tree_view.show();
+ key_tree_view.get_selection().changed.connect(key_selected_cb);
+ scroll.add(key_tree_view);
+
+ Gtk.Table schema_table = new Gtk.Table(0, 2, false);
+ schema_table.set_row_spacings(6);
+ schema_table.set_col_spacings(6);
+ schema_table.show();
+ vbox.pack_start(schema_table, false, true, 0);
+
+ schema_label = add_row(schema_table, 0, "Schema:");
+ summary_label = add_row(schema_table, 1, "Summary:");
+ description_label = add_row(schema_table, 2, "Description:");
+ type_label = add_row(schema_table, 3, "Type:");
+ default_label = add_row(schema_table, 4, "Default:");
+
+ /* Always select something */
+ Gtk.TreeIter iter;
+ if (model.get_iter_first(out iter))
+ dir_tree_view.get_selection().select_iter(iter);
+ }
+
+ private Gtk.Label add_row(Gtk.Table table, int row, string label)
+ {
+ Gtk.Label name_label, value_label;
- name_label = new Gtk.Label("");
+ name_label = new Gtk.Label(label);
name_label.set_alignment(0.0f, 0.5f);
- name_label.show();
- vbox.pack_start(name_label, false, true, 0);
+ table.attach(name_label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0);
value_label = new Gtk.Label("");
value_label.set_alignment(0.0f, 0.5f);
+ table.attach_defaults(value_label, 1, 2, row, row+1);
+
+ name_label.show();
value_label.show();
- vbox.pack_start(value_label, false, true, 0);
+
+ return value_label;
}
- private string? get_selected_key()
+ private void dir_selected_cb()
{
+ KeyModel? key_model = null;
+
Gtk.TreeIter iter;
- if (!tree_view.get_selection().get_selected(null, out iter))
- return null;
+ if (dir_tree_view.get_selection().get_selected(null, out iter))
+ key_model = model.get_directory(iter).key_model;
+
+ key_tree_view.set_model(key_model);
- string key;
- model.get(iter, 1, out key, -1);
- return key;
+ /* Always select something */
+ if (key_model != null && key_model.get_iter_first(out iter))
+ key_tree_view.get_selection().select_iter(iter);
}
-
- private void key_selected_cb()
+
+ private Key? get_selected_key()
{
- string? key = get_selected_key();
- if (key == null)
+ Gtk.TreeIter iter;
+ Gtk.TreeModel model;
+ if (key_tree_view.get_selection().get_selected(out model, out iter))
{
- name_label.set_text("");
- value_label.set_text("");
+ KeyModel key_model = (KeyModel) model;
+ return key_model.get_key(iter);
}
else
+ return null;
+ }
+
+ private string type_to_description(string type)
+ {
+ switch(type)
{
- GLib.Variant value = client.read(key);
- name_label.set_text(key);
- value_label.set_text(value == null ? "(unset)" : value.print(false));
+ case "i":
+ return "Integer";
+ case "b":
+ return "Boolean";
+ case "s":
+ return "String";
+ default:
+ return type;
}
}
+
+ private void key_selected_cb()
+ {
+ Key? key = get_selected_key();
+ string schema_name = "", summary = "", description = "", type = "", default_value = "";
+
+ if (key != null)
+ {
+ SchemaKey? schema = schemas.keys.get(key.full_name);
+ if (schema != null)
+ {
+ schema_name = schema.schema.id;
+ if (schema.summary != null)
+ summary = schema.summary;
+ if (schema.description != null)
+ description = schema.description;
+ type = type_to_description(schema.type);
+ default_value = schema.default_value;
+ }
+ else
+ {
+ schema_name = "No schema";
+ }
+ }
+
+ schema_label.set_text(schema_name);
+ summary_label.set_text(summary);
+ description_label.set_text(description);
+ type_label.set_text(type);
+ default_label.set_text(default_value);
+ }
}
class ConfigurationEditor
{
- private DConf.Client client;
private EditorWindow window;
public ConfigurationEditor()
{
- client = new DConf.Client("", true, null, null);
- window = new EditorWindow(client);
+ window = new EditorWindow();
window.destroy.connect(Gtk.main_quit);
- read_keys("/");
-
window.show();
}
- private void read_keys(string parent)
- {
- string[] keys = client.list(parent);
- for (int i = 0; i < keys.length; i++)
- {
- if (DConf.is_rel_dir(keys[i]))
- read_keys(parent + keys[i]);
- else
- window.model.add_key(parent + keys[i]);
- }
- }
-
public static int main(string[] args)
{
Gtk.init(ref args);
diff --git a/editor/dconf-model.vala b/editor/dconf-model.vala
new file mode 100644
index 0000000..f17daff
--- /dev/null
+++ b/editor/dconf-model.vala
@@ -0,0 +1,428 @@
+public class Key : GLib.Object
+{
+ private DConf.Client client;
+
+ public string name;
+ public string full_name;
+
+ public Key? next;
+
+ private Variant _value;
+ public Variant value
+ {
+ get { update_value(); return _value; }
+ set {
+ _value = value;
+ try
+ {
+ client.write(full_name, value, 0, null);
+ }
+ catch (GLib.Error e)
+ {
+ }
+ }
+ }
+
+ public Key(DConf.Client client, string name, string full_name)
+ {
+ this.client = client;
+ this.name = name;
+ this.full_name = full_name;
+ }
+
+ private void update_value()
+ {
+ _value = client.read(full_name);
+ }
+}
+
+public class Directory : GLib.Object
+{
+ private DConf.Client client;
+
+ public string name;
+ public string full_name;
+
+ public Directory? parent;
+
+ private KeyModel _key_model;
+ public KeyModel key_model
+ {
+ get { update_children(); if (_key_model == null) _key_model = new KeyModel(this); return _key_model; }
+ private set {}
+ }
+
+ private int _n_children;
+ public int n_children
+ {
+ get { update_children(); return _n_children; }
+ private set { _n_children = value; }
+ }
+ public Directory? _child;
+ public Directory? child
+ {
+ get { update_children(); return _child; }
+ private set { _child = value; }
+ }
+ public Directory? next;
+
+ private int _n_keys;
+ public int n_keys
+ {
+ get { update_children(); return _n_keys; }
+ private set { _n_keys = value; }
+ }
+ private Key? _keys;
+ public Key? keys
+ {
+ get { update_children(); return _keys; }
+ private set { _keys = value; }
+ }
+
+ private bool have_children;
+
+ public Directory(DConf.Client client, string name, string full_name, Directory? parent = null)
+ {
+ this.client = client;
+ this.parent = parent;
+ this.name = name;
+ this.full_name = full_name;
+ }
+
+ private void update_children()
+ {
+ if (have_children)
+ return;
+ have_children = true;
+
+ Directory? last_directory = null;
+ Key? last_key = null;
+ string[] items = client.list(full_name);
+ _n_children = 0;
+ _n_keys = 0;
+ for (int i = 0; i < items.length; i++)
+ {
+ string item_name = full_name + items[i];
+
+ if (DConf.is_dir(item_name))
+ {
+ string dir_name = items[i][0:-1];
+
+ Directory directory = new Directory(client, dir_name, item_name, this);
+ if (last_directory == null)
+ child = directory;
+ else
+ last_directory.next = directory;
+ last_directory = directory;
+ _n_children++;
+ }
+ else
+ {
+ Key key = new Key(client, items[i], item_name);
+ if (last_key == null)
+ keys = key;
+ else
+ last_key.next = key;
+ last_key = key;
+ _n_keys++;
+ }
+ }
+ }
+}
+
+public class KeyModel: GLib.Object, Gtk.TreeModel/*, Gtk.TreeSortable*/
+{
+ private Directory directory;
+
+ construct {}
+
+ public KeyModel(Directory directory)
+ {
+ this.directory = directory;
+ }
+
+ public Gtk.TreeModelFlags get_flags()
+ {
+ return Gtk.TreeModelFlags.LIST_ONLY;
+ }
+
+ public int get_n_columns()
+ {
+ return 3;
+ }
+
+ public Type get_column_type(int index)
+ {
+ if (index == 0)
+ return typeof(Key);
+ else
+ return typeof(string);
+ }
+
+ private void set_iter(out Gtk.TreeIter iter, Key key)
+ {
+ iter.stamp = 0;
+ iter.user_data = key;
+ iter.user_data2 = key;
+ iter.user_data3 = key;
+ }
+
+ public Key get_key(Gtk.TreeIter iter)
+ {
+ return (Key)iter.user_data;
+ }
+
+ public bool get_iter(out Gtk.TreeIter iter, Gtk.TreePath path)
+ {
+ if (path.get_depth() != 1)
+ return false;
+
+ return iter_nth_child(out iter, null, path.get_indices()[0]);
+ }
+
+ public Gtk.TreePath get_path(Gtk.TreeIter iter)
+ {
+ Gtk.TreePath path = new Gtk.TreePath();
+ Key key = directory.keys;
+ int index = 0;
+ while (key != get_key(iter))
+ {
+ key = key.next;
+ index++;
+ }
+ path.append_index(index);
+ return path;
+ }
+
+ public void get_value(Gtk.TreeIter iter, int column, out Value value)
+ {
+ if (column == 0)
+ value = get_key(iter);
+ else if (column == 1)
+ value = get_key(iter).name;
+ else
+ value = get_key(iter).value.print(false);
+ }
+
+ public bool iter_next(ref Gtk.TreeIter iter)
+ {
+ Key key = get_key(iter);
+ if (key.next == null)
+ return false;
+ set_iter(out iter, key.next);
+ return true;
+ }
+
+ public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent)
+ {
+ if (parent != null || directory.n_keys == 0)
+ return false;
+ set_iter(out iter, directory.keys);
+ return true;
+ }
+
+ public bool iter_has_child(Gtk.TreeIter iter)
+ {
+ return false;
+ }
+
+ public int iter_n_children(Gtk.TreeIter? iter)
+ {
+ if (iter == null)
+ return directory.n_keys;
+ else
+ return 0;
+ }
+
+ public bool iter_nth_child(out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n)
+ {
+ if (parent != null)
+ return false;
+
+ Key key = directory.keys;
+ if (key == null)
+ return false;
+ for (int i = 0; i < n; i++)
+ {
+ key = key.next;
+ if (key == null)
+ return false;
+ }
+
+ set_iter(out iter, key);
+ return true;
+ }
+
+ public bool iter_parent(out Gtk.TreeIter iter, Gtk.TreeIter child)
+ {
+ return false;
+ }
+
+ public void ref_node(Gtk.TreeIter iter)
+ {
+ get_key(iter).ref();
+ }
+
+ public void unref_node(Gtk.TreeIter iter)
+ {
+ get_key(iter).unref();
+ }
+}
+
+public class SettingsModel: GLib.Object, Gtk.TreeModel
+{
+ private DConf.Client client;
+ private Directory root;
+
+ construct {}
+
+ public SettingsModel()
+ {
+ client = new DConf.Client("", true, null, null);
+ root = new Directory(client, "/", "/");
+ }
+
+ public Gtk.TreeModelFlags get_flags()
+ {
+ return 0;
+ }
+
+ public int get_n_columns()
+ {
+ return 2;
+ }
+
+ public Type get_column_type(int index)
+ {
+ if (index == 0)
+ return typeof(Directory);
+ else
+ return typeof(string);
+ }
+
+ private void set_iter(out Gtk.TreeIter iter, Directory directory)
+ {
+ iter.stamp = 0;
+ iter.user_data = directory;
+ iter.user_data2 = directory;
+ iter.user_data3 = directory;
+ }
+
+ public Directory get_directory(Gtk.TreeIter? iter)
+ {
+ if (iter == null)
+ return root;
+ else
+ return (Directory)iter.user_data;
+ }
+
+ public bool get_iter(out Gtk.TreeIter iter, Gtk.TreePath path)
+ {
+ if (!iter_nth_child(out iter, null, path.get_indices()[0]))
+ return false;
+
+ for (int i = 1; i < path.get_depth(); i++)
+ {
+ Gtk.TreeIter parent = iter;
+ if (!iter_nth_child(out iter, parent, path.get_indices()[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ public Gtk.TreePath get_path(Gtk.TreeIter iter)
+ {
+ Gtk.TreePath path;
+ Gtk.TreeIter parent;
+ if (iter_parent(out parent, iter))
+ path = get_path(parent);
+ else
+ path = new Gtk.TreePath();
+
+ int index = 0;
+ Directory directory = get_directory(iter);
+ Directory d = directory.parent.child;
+ while (d != directory)
+ {
+ d = d.next;
+ index++;
+ }
+ path.append_index(index);
+
+ return path;
+ }
+
+ public void get_value(Gtk.TreeIter iter, int column, out Value value)
+ {
+ if (column == 0)
+ value = get_directory(iter);
+ else
+ value = get_directory(iter).name;
+ }
+
+ public bool iter_next(ref Gtk.TreeIter iter)
+ {
+ Directory directory = get_directory(iter);
+ if (directory.next == null)
+ return false;
+ set_iter(out iter, directory.next);
+ return true;
+ }
+
+ public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent)
+ {
+ Directory directory = get_directory(parent);
+ if (directory.n_children == 0)
+ return false;
+ set_iter(out iter, directory.child);
+ return true;
+ }
+
+ public bool iter_has_child(Gtk.TreeIter iter)
+ {
+ return get_directory(iter).n_children > 0;
+ }
+
+ public int iter_n_children(Gtk.TreeIter? iter)
+ {
+ return get_directory(iter).n_children;
+ }
+
+ public bool iter_nth_child(out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n)
+ {
+ Directory directory = get_directory(parent);
+
+ directory = directory.child;
+ if (directory == null)
+ return false;
+ for (int i = 0; i < n; i++)
+ {
+ directory = directory.next;
+ if (directory == null)
+ return false;
+ }
+
+ set_iter(out iter, directory);
+ return true;
+ }
+
+ public bool iter_parent(out Gtk.TreeIter iter, Gtk.TreeIter child)
+ {
+ Directory directory = get_directory(child);
+ if (directory.parent == root)
+ return false;
+ set_iter(out iter, directory.parent);
+ return true;
+ }
+
+ public void ref_node(Gtk.TreeIter iter)
+ {
+ get_directory(iter).ref();
+ }
+
+ public void unref_node(Gtk.TreeIter iter)
+ {
+ get_directory(iter).unref();
+ }
+}
diff --git a/editor/dconf-schema.vala b/editor/dconf-schema.vala
new file mode 100644
index 0000000..ee17e02
--- /dev/null
+++ b/editor/dconf-schema.vala
@@ -0,0 +1,147 @@
+using Gee;
+
+public class SchemaKey
+{
+ public Schema schema;
+ public string name;
+ public string type;
+ public string default_value;
+ public string? summary;
+ public string? description;
+ public string? gettext_domain;
+
+ public SchemaKey(Xml.Node* node, Schema schema, string? gettext_domain)
+ {
+ this.schema = schema;
+ this.gettext_domain = gettext_domain;
+
+ for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next)
+ {
+ if (prop->name == "name")
+ name = prop->children->content;
+ else if (prop->name == "type")
+ type = prop->children->content;
+ //else
+ // ?
+ }
+
+ //if (name == null || type == null)
+ // ?
+
+ for (Xml.Node* child = node->children; child != null; child = child->next)
+ {
+ if (child->name == "default")
+ default_value = child->children->content;
+ else if (child->name == "summary")
+ summary = child->children->content;
+ else if (child->name == "description")
+ description = child->children->content;
+ //else
+ // ?
+ }
+
+ //if (default_value == null)
+ // ?
+ }
+}
+
+public class Schema
+{
+ public SchemaList list;
+ public string id;
+ public string? path;
+ public HashMap<string, SchemaKey> keys = new HashMap<string, SchemaKey>();
+
+ public Schema(SchemaList list, Xml.Node* node, string? gettext_domain)
+ {
+ this.list = list;
+
+ for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next)
+ {
+ if (prop->name == "id")
+ id = prop->children->content;
+ else if (prop->name == "path")
+ path = prop->children->content; // FIXME: Does the path have to end with '/'?
+ else if (prop->name == "gettext-domain")
+ gettext_domain = prop->children->content;
+ //else
+ // ?
+ }
+
+ //if (id == null)
+ // ?
+
+ for (Xml.Node* child = node->children; child != null; child = child->next)
+ {
+ if (child->name != "key")
+ continue;
+ SchemaKey key = new SchemaKey(child, this, gettext_domain);
+ keys.set(key.name, key);
+ }
+ }
+}
+
+public class SchemaList
+{
+ public ArrayList<Schema> schemas = new ArrayList<Schema>();
+ public HashMap<string, SchemaKey> keys = new HashMap<string, SchemaKey>();
+
+ public void parse_file(string path)
+ {
+ Xml.Doc* doc = Xml.Parser.parse_file(path);
+ if (doc == null)
+ return;
+
+ Xml.Node* root = doc->get_root_element();
+ if (root == null)
+ return;
+ if (root->name != "schemalist")
+ return;
+
+ string? gettext_domain = null;
+ for (Xml.Attr* prop = root->properties; prop != null; prop = prop->next)
+ {
+ if (prop->name == "gettext-domain")
+ gettext_domain = prop->children->content;
+ }
+
+ for (Xml.Node* node = root->children; node != null; node = node->next)
+ {
+ if (node->name != "schema")
+ continue;
+
+ Schema schema = new Schema(this, node, gettext_domain);
+ schemas.add(schema);
+ if (schema.path == null)
+ {
+ // FIXME: What to do here?
+ continue;
+ }
+
+ foreach (var key in schema.keys.values)
+ {
+ string full_name = schema.path + key.name;
+ keys.set(full_name, key);
+ }
+ }
+
+ delete doc;
+ }
+
+ public void load_directory(string dir) throws Error
+ {
+ File directory = File.new_for_path(dir);
+ var i = directory.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, 0, null);
+ FileInfo info;
+ while ((info = i.next_file (null)) != null) {
+ string name = info.get_name();
+
+ if (!name.has_suffix(".gschema.xml"))
+ continue;
+
+ string path = Path.build_filename(dir, name, null);
+ debug("Loading schema: %s", path);
+ parse_file(path);
+ }
+ }
+}
diff --git a/editor/dconf-view.vala b/editor/dconf-view.vala
new file mode 100644
index 0000000..8ec36e8
--- /dev/null
+++ b/editor/dconf-view.vala
@@ -0,0 +1,201 @@
+private class KeyValueRenderer: Gtk.CellRenderer
+{
+ private Gtk.CellRendererText text_renderer;
+ private Gtk.CellRendererToggle toggle_renderer;
+ private Gtk.CellEditable cell_editor;
+
+ private Key _key;
+ public Key key
+ {
+ get { return _key; }
+ set
+ {
+ _key = value;
+ if (_key.value.is_of_type(VariantType.BOOLEAN))
+ mode = Gtk.CellRendererMode.ACTIVATABLE;
+ else if (_key.value.is_of_type(VariantType.STRING) ||
+ _key.value.is_of_type(VariantType.BYTE) ||
+ _key.value.is_of_type(VariantType.INT16) ||
+ _key.value.is_of_type(VariantType.UINT16) ||
+ _key.value.is_of_type(VariantType.INT32) ||
+ _key.value.is_of_type(VariantType.UINT32) ||
+ _key.value.is_of_type(VariantType.INT64) ||
+ _key.value.is_of_type(VariantType.UINT64) ||
+ _key.value.is_of_type(VariantType.DOUBLE))
+ mode = Gtk.CellRendererMode.EDITABLE;
+ else
+ mode = Gtk.CellRendererMode.INERT;
+ }
+ }
+
+ construct
+ {
+ text_renderer = new Gtk.CellRendererText();
+ toggle_renderer = new Gtk.CellRendererToggle();
+ toggle_renderer.xalign = 0f;
+ }
+
+ private Gtk.CellRenderer get_renderer()
+ {
+ if (key.value.is_of_type(VariantType.BOOLEAN))
+ {
+ toggle_renderer.active = key.value.get_boolean();
+ return toggle_renderer;
+ }
+ else
+ {
+ text_renderer.text = key.value.print(false);
+ return text_renderer;
+ }
+ }
+
+ public override void get_size(Gtk.Widget widget,
+ Gdk.Rectangle? cell_area,
+ out int x_offset,
+ out int y_offset,
+ out int width,
+ out int height)
+ {
+ get_renderer().get_size(widget, cell_area, out x_offset, out y_offset, out width, out height);
+ }
+
+ public override void render(Gdk.Window window,
+ Gtk.Widget widget,
+ Gdk.Rectangle background_area,
+ Gdk.Rectangle cell_area,
+ Gdk.Rectangle expose_area,
+ Gtk.CellRendererState flags)
+ {
+ get_renderer().render(window, widget, background_area, cell_area, expose_area, flags);
+ }
+
+ public override bool activate(Gdk.Event event,
+ Gtk.Widget widget,
+ string path,
+ Gdk.Rectangle background_area,
+ Gdk.Rectangle cell_area,
+ Gtk.CellRendererState flags)
+ {
+ key.value = new Variant.boolean(!key.value.get_boolean());
+ return true;
+ }
+
+ private void editing_done_cb(Gtk.CellEditable cell_editable)
+ {
+ cell_editor = null;
+ // FIXME: Appears to be broken
+ /*if (cell_editable.editing_canceled)
+ return;*/
+
+ if (key.value.is_of_type(VariantType.STRING))
+ {
+ var entry = (Gtk.Entry)cell_editable;
+ key.value = new Variant.string(entry.get_text());
+ return;
+ }
+
+ var spin = (Gtk.SpinButton)cell_editable;
+ if (key.value.is_of_type(VariantType.BYTE))
+ key.value = new Variant.byte((uchar)spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.INT16))
+ key.value = new Variant.int16((int16)spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.UINT16))
+ key.value = new Variant.uint16((uint16)spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.INT32))
+ key.value = new Variant.int32(spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.UINT32))
+ key.value = new Variant.uint32(spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.INT64))
+ key.value = new Variant.int64(spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.UINT64))
+ key.value = new Variant.uint64(spin.get_value_as_int());
+ else if (key.value.is_of_type(VariantType.DOUBLE))
+ key.value = new Variant.double(spin.get_value());
+ }
+
+ public override unowned Gtk.CellEditable start_editing(Gdk.Event event,
+ Gtk.Widget widget,
+ string path,
+ Gdk.Rectangle background_area,
+ Gdk.Rectangle cell_area,
+ Gtk.CellRendererState flags)
+ {
+ if (key.value.is_of_type(VariantType.STRING))
+ {
+ var entry = new Gtk.Entry();
+ entry.set_text(_key.value.get_string());
+ cell_editor = entry;
+ }
+ else if (key.value.is_of_type(VariantType.BYTE))
+ {
+ var spin = new Gtk.SpinButton.with_range(0, 255, 1);
+ spin.set_value(key.value.get_byte());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.INT16))
+ {
+ var spin = new Gtk.SpinButton.with_range(int16.MIN, int16.MAX, 1);
+ spin.set_value(key.value.get_int16());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.UINT16))
+ {
+ var spin = new Gtk.SpinButton.with_range(0, uint16.MAX, 1);
+ spin.set_value(key.value.get_uint16());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.INT32))
+ {
+ var spin = new Gtk.SpinButton.with_range(int32.MIN, int32.MAX, 1);
+ spin.set_value(key.value.get_int32());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.UINT32))
+ {
+ var spin = new Gtk.SpinButton.with_range(0, uint32.MAX, 1);
+ spin.set_value(key.value.get_uint32());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.INT64))
+ {
+ var spin = new Gtk.SpinButton.with_range(int64.MIN, int64.MAX, 1);
+ spin.set_value(key.value.get_int64());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.UINT64))
+ {
+ var spin = new Gtk.SpinButton.with_range(0, uint64.MAX, 1);
+ spin.set_value(key.value.get_uint64());
+ cell_editor = spin;
+ }
+ else if (key.value.is_of_type(VariantType.DOUBLE))
+ {
+ var spin = new Gtk.SpinButton.with_range(double.MIN, double.MAX, 1);
+ spin.set_value(key.value.get_uint64());
+ cell_editor = spin;
+ }
+ cell_editor.editing_done.connect(editing_done_cb);
+ cell_editor.show();
+ return cell_editor;
+ }
+}
+
+public class DConfDirView : Gtk.TreeView
+{
+ public DConfDirView()
+ {
+ set_headers_visible(false);
+ insert_column_with_attributes(-1, "Key", new Gtk.CellRendererText(), "text", 1, null);
+ }
+}
+
+public class DConfKeyView : Gtk.TreeView
+{
+ public DConfKeyView()
+ {
+ var column = new Gtk.TreeViewColumn.with_attributes("Name", new Gtk.CellRendererText(), "text", 1, null);
+ /*column.set_sort_column_id(1);*/
+ append_column(column);
+ insert_column_with_attributes(-1, "Value", new KeyValueRenderer(), "key", 0, null);
+ }
+}
diff --git a/editor/dconf.vapi b/editor/dconf.vapi
index 1a1f15b..52a49b4 100644
--- a/editor/dconf.vapi
+++ b/editor/dconf.vapi
@@ -19,11 +19,11 @@ namespace DConf {
public bool watch (string name) throws GLib.Error;
public async bool watch_async (string name);
public bool watch_finish (GLib.AsyncResult _result);
- public bool write (string key, GLib.Variant value, uint64 sequence, GLib.Cancellable cancellable) throws GLib.Error;
- public async bool write_async (string key, GLib.Variant value, GLib.Cancellable cancellable) throws GLib.Error;
+ public bool write (string key, GLib.Variant value, uint64 sequence, GLib.Cancellable? cancellable) throws GLib.Error;
+ public async bool write_async (string key, GLib.Variant value, GLib.Cancellable? cancellable) throws GLib.Error;
public bool write_finish (GLib.AsyncResult _result, uint64 sequence) throws GLib.Error;
- public bool write_many (string prefix, string keys, out unowned GLib.Variant values, uint64 sequence, GLib.Cancellable cancellable) throws GLib.Error;
- public async bool write_many_async (string prefix, string keys, out unowned GLib.Variant values, GLib.Cancellable cancellable) throws GLib.Error;
+ public bool write_many (string prefix, string keys, out unowned GLib.Variant values, uint64 sequence, GLib.Cancellable? cancellable) throws GLib.Error;
+ public async bool write_many_async (string prefix, string keys, out unowned GLib.Variant values, GLib.Cancellable? cancellable) throws GLib.Error;
public bool write_many_finish (GLib.AsyncResult _result, uint64 sequence) throws GLib.Error;
}
[CCode (cheader_filename = "dconf.h")]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]