[dconf-editor] Use a ListBox.
- From: Arnaud Bonatti <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf-editor] Use a ListBox.
- Date: Tue, 22 Sep 2015 17:02:06 +0000 (UTC)
commit e0a53361b6ad015a2f09f93be99886f5ee9c1cbc
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Tue Sep 22 18:34:38 2015 +0200
Use a ListBox.
editor/Makefile.am | 4 +-
editor/dconf-editor.gresource.xml | 2 +
editor/dconf-editor.ui | 235 +--------------
editor/dconf-model.vala | 339 ++--------------------
editor/dconf-view.vala | 590 ++++++++++++++++++++++---------------
editor/dconf-window.vala | 301 +++++++------------
editor/key-editor.ui | 244 +++++++++++++++
editor/key-list-box-row.ui | 46 +++
8 files changed, 782 insertions(+), 979 deletions(-)
---
diff --git a/editor/Makefile.am b/editor/Makefile.am
index ee3d495..3b903e0 100644
--- a/editor/Makefile.am
+++ b/editor/Makefile.am
@@ -23,7 +23,9 @@ dconf_editor_CFLAGS = \
resource_data = \
dconf-editor.gresource.xml \
dconf-editor-menu.ui \
- dconf-editor.ui
+ dconf-editor.ui \
+ key-list-box-row.ui \
+ key-editor.ui
resources.c: $(resource_data)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --target=$@ --generate-source $<
diff --git a/editor/dconf-editor.gresource.xml b/editor/dconf-editor.gresource.xml
index 8f91396..67da824 100644
--- a/editor/dconf-editor.gresource.xml
+++ b/editor/dconf-editor.gresource.xml
@@ -2,6 +2,8 @@
<gresources>
<gresource prefix="/ca/desrt/dconf-editor/ui">
<file preprocess="xml-stripblanks">dconf-editor.ui</file>
+ <file preprocess="xml-stripblanks">key-list-box-row.ui</file>
+ <file preprocess="xml-stripblanks">key-editor.ui</file>
</gresource>
<gresource prefix="/ca/desrt/dconf-editor/gtk">
<file preprocess="xml-stripblanks" alias="menus.ui">dconf-editor-menu.ui</file>
diff --git a/editor/dconf-editor.ui b/editor/dconf-editor.ui
index bb1698a..7d8d0d8 100644
--- a/editor/dconf-editor.ui
+++ b/editor/dconf-editor.ui
@@ -20,7 +20,6 @@
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="width_request">222</property>
<child>
@@ -53,241 +52,17 @@
</packing>
</child>
<child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
+ <object class="GtkScrolledWindow">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<child>
- <object class="GtkGrid" id="key_info_grid">
+ <object class="GtkListBox" id="key_list_box">
<property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">False</property>
- <property name="margin_start">6</property>
- <property name="margin_end">6</property>
- <property name="margin_top">6</property>
- <property name="margin_bottom">6</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Schema:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Summary:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Description:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes" comments="Translators: as in datatype
(integer, boolean, string, etc)">Type:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Default:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="schema_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="summary_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="wrap">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="description_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="wrap">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="type_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox">
- <property name="orientation">horizontal</property>
- <property name="hexpand">True</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="default_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="wrap">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Set to Default</property>
- <property name="can_focus">True</property>
- <property name="valign">end</property>
- <property name="receives_default">True</property>
- <property name="action_name">win.set-default</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
+ <property name="activate-on-single-click">True</property>
+ <property name="selection-mode">browse</property><!-- permits to not have an item
selected -->
+ <signal name="row-activated" handler="row_activated_cb"/>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="key_scrolledwindow">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- </packing>
</child>
</object>
<packing>
diff --git a/editor/dconf-model.vala b/editor/dconf-model.vala
index 21f8af7..ff35303 100644
--- a/editor/dconf-model.vala
+++ b/editor/dconf-model.vala
@@ -23,6 +23,12 @@ public class Key : GLib.Object
public string name;
public string full_name;
+ public string cool_text_value () // TODO better
+ {
+ // TODO number of chars after coma for double
+ // bool is the only type that permits translation; keep strings for translators
+ return type_string == "b" ? (value.get_boolean () ? _("True") : _("False")) : value.print (false);
+ }
public SchemaKey? schema;
@@ -31,11 +37,6 @@ public class Key : GLib.Object
get { return schema != null; }
}
- public int index
- {
- get { return parent.keys.index (this); }
- }
-
public string type_string
{
private set {}
@@ -132,10 +133,8 @@ public class Key : GLib.Object
}
public void set_to_default()
+ requires (has_schema)
{
- if (!has_schema)
- return;
-
value = null;
}
@@ -154,15 +153,13 @@ public class Directory : GLib.Object
public Directory? parent;
- private KeyModel _key_model;
- public KeyModel key_model
+ private GLib.ListStore _key_model;
+ public GLib.ListStore key_model
{
get {
update_children ();
if (_key_model == null)
- {
- _key_model = new KeyModel (this);
- }
+ _key_model = new GLib.ListStore (typeof (Key));
return _key_model;
}
private set {}
@@ -182,12 +179,6 @@ public class Directory : GLib.Object
}
public GLib.HashTable<string, Key> _key_map = new GLib.HashTable<string, Key>(str_hash, str_equal);
- private GLib.List<Key> _keys = new GLib.List<Key>();
- public GLib.List<Key> keys
- {
- get { update_children(); return _keys; }
- private set { }
- }
private bool have_children = false;
@@ -220,7 +211,7 @@ public class Directory : GLib.Object
if (key == null)
{
key = new Key (model, this, name, full_name + name);
- _keys.insert_sorted (key, (a, b) => { return strcmp (((Key) a).name, ((Key) b).name); });
+ key_model.insert_sorted (key, (a, b) => { return strcmp (((Key) a).name, ((Key) b).name); });
_key_map.insert (name, key);
}
@@ -244,312 +235,18 @@ public class Directory : GLib.Object
}
}
- private void update_children()
+ private void update_children ()
{
- if (have_children)
+ if (have_children) // crashes if in the constructor
return;
have_children = true;
- string[] items = model.client.list(full_name);
+ string [] items = model.client.list (full_name);
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];
- get_child(dir_name);
- }
+ if (DConf.is_dir (full_name + items[i]))
+ get_child (items [i][0:-1]);
else
- {
- get_key(items[i]);
- }
- }
- }
-}
-
-public class KeyModel: GLib.Object, Gtk.TreeModel
-{
- private Directory directory;
-
- public KeyModel(Directory directory)
- {
- this.directory = directory;
- foreach (var key in directory.keys)
- key.value_changed.connect(key_changed_cb); // FIXME: Need to delete this callbacks
- }
-
- private void key_changed_cb(Key key)
- {
- Gtk.TreeIter iter;
- if (!get_iter_first(out iter))
- return;
-
- do
- {
- if(get_key(iter) == key)
- {
- row_changed(get_path(iter), iter);
- return;
- }
- } while(iter_next(ref iter));
- }
-
- 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(ref 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)
- {
- iter = Gtk.TreeIter();
-
- 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)
- {
- var path = new Gtk.TreePath();
- path.append_index(get_key(iter).index);
- return path;
- }
-
- public void get_value(Gtk.TreeIter iter, int column, out Value value)
- {
- Key key = get_key(iter);
-
- if (column == 0)
- value = key;
- else if (column == 1)
- value = key.name;
- else if (column == 2)
- value = key.value != null ? key.value.print(false) : "";
- else if (column == 4)
- value = key.is_default ? Pango.Weight.NORMAL : Pango.Weight.BOLD;
- else
- value = 0;
- }
-
- public bool iter_next(ref Gtk.TreeIter iter)
- {
- int index = get_key(iter).index;
- if (index >= directory.keys.length() - 1)
- return false;
- set_iter(ref iter, directory.keys.nth_data(index+1));
- return true;
- }
-
- public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent)
- {
- iter = Gtk.TreeIter();
-
- if (parent != null || directory.keys.length() == 0)
- return false;
- set_iter(ref iter, directory.keys.nth_data(0));
-
- return true;
- }
-
- public bool iter_has_child(Gtk.TreeIter iter)
- {
- return false;
- }
-
- public int iter_n_children(Gtk.TreeIter? iter)
- {
- if (iter == null)
- return (int)directory.keys.length();
- else
- return 0;
- }
-
- public bool iter_nth_child(out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n)
- {
- iter = Gtk.TreeIter();
-
- if (parent != null)
- return false;
-
- if (n >= directory.keys.length())
- return false;
- set_iter(ref iter, directory.keys.nth_data(n));
- return true;
- }
-
- public bool iter_parent(out Gtk.TreeIter iter, Gtk.TreeIter child)
- {
- iter = Gtk.TreeIter();
- 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 EnumModel: GLib.Object, Gtk.TreeModel
-{
- private SchemaEnum schema_enum;
-
- public EnumModel(SchemaEnum schema_enum)
- {
- this.schema_enum = schema_enum;
- }
-
- public Gtk.TreeModelFlags get_flags()
- {
- return Gtk.TreeModelFlags.LIST_ONLY;
- }
-
- public int get_n_columns()
- {
- return 2;
- }
-
- public Type get_column_type(int index)
- {
- if (index == 0)
- return typeof(string);
- else
- return typeof(int);
- }
-
- private void set_iter(ref Gtk.TreeIter iter, SchemaValue value)
- {
- iter.stamp = 0;
- iter.user_data = value;
- iter.user_data2 = value;
- iter.user_data3 = value;
- }
-
- public SchemaValue get_enum_value(Gtk.TreeIter iter)
- {
- return (SchemaValue)iter.user_data;
- }
-
- public bool get_iter(out Gtk.TreeIter iter, Gtk.TreePath path)
- {
- iter = Gtk.TreeIter();
-
- 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)
- {
- var path = new Gtk.TreePath();
- path.append_index((int)get_enum_value(iter).index);
- return path;
- }
-
- public void get_value(Gtk.TreeIter iter, int column, out Value value)
- {
- if (column == 0)
- value = get_enum_value(iter).nick;
- else if (column == 1)
- value = get_enum_value(iter).value;
- else
- value = 0;
- }
-
- public bool iter_next(ref Gtk.TreeIter iter)
- {
- uint index = get_enum_value(iter).index;
- if (index >= schema_enum.values.length () - 1)
- return false;
- set_iter(ref iter, schema_enum.values.nth_data(index + 1));
- return true;
- }
-
- public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent)
- {
- iter = Gtk.TreeIter();
-
- if (parent != null || schema_enum.values.length() == 0)
- return false;
-
- set_iter(ref iter, schema_enum.values.nth_data(0));
-
- return true;
- }
-
- public bool iter_has_child(Gtk.TreeIter iter)
- {
- return false;
- }
-
- public int iter_n_children(Gtk.TreeIter? iter)
- {
- if (iter == null)
- return (int) schema_enum.values.length();
- else
- return 0;
- }
-
- public bool iter_nth_child(out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n)
- {
- iter = Gtk.TreeIter();
-
- if (parent != null)
- return false;
-
- if (n >= schema_enum.values.length())
- return false;
- set_iter(ref iter, schema_enum.values.nth_data(n));
- return true;
- }
-
- public bool iter_parent(out Gtk.TreeIter iter, Gtk.TreeIter child)
- {
- iter = Gtk.TreeIter();
- return false;
- }
-
- public void ref_node(Gtk.TreeIter iter)
- {
- get_enum_value(iter).ref();
- }
-
- public void unref_node(Gtk.TreeIter iter)
- {
- get_enum_value(iter).unref();
+ get_key (items [i]);
}
}
@@ -564,7 +261,9 @@ public class SettingsModel: GLib.Object, Gtk.TreeModel
void watch_func (DConf.Client client, string path, string[] items, string? tag) {
foreach (var item in items)
+ { // don't remove that!
item_changed (path + item);
+ }
}
public SettingsModel()
diff --git a/editor/dconf-view.vala b/editor/dconf-view.vala
index 839961a..d059d0e 100644
--- a/editor/dconf-view.vala
+++ b/editor/dconf-view.vala
@@ -15,52 +15,75 @@
along with Dconf Editor. If not, see <http://www.gnu.org/licenses/>.
*/
-private class KeyValueRenderer: Gtk.CellRenderer
+using Gtk;
+
+[GtkTemplate (ui = "/ca/desrt/dconf-editor/ui/key-editor.ui")]
+private class KeyEditor : Dialog
{
- private DConfKeyView view;
- private Gtk.CellRendererText text_renderer;
- private Gtk.CellRendererSpin spin_renderer;
- private Gtk.CellRendererToggle toggle_renderer;
- private Gtk.CellRendererCombo combo_renderer;
-
- private Key _key;
- public Key key
+ [GtkChild] private Label schema_label;
+ [GtkChild] private Label summary_label;
+ [GtkChild] private Label description_label;
+ [GtkChild] private Label type_label;
+ [GtkChild] private Label default_label;
+
+ [GtkChild] private Button button_apply;
+ [GtkChild] private Switch custom_value_switch;
+ [GtkChild] private Grid custom_value_grid;
+
+ private Key key;
+ private bool custom_value_is_valid = true;
+
+ public KeyEditor (Key _key)
+ requires (_key.has_schema)
{
- get { return _key; }
- set
- {
- _key = value;
+ Object (use_header_bar: Gtk.Settings.get_default ().gtk_dialogs_use_header ? 1 : 0);
- if (key.has_schema && key.schema.choices != null)
- {
- combo_renderer.text = key.value.print(false);
- var model = new Gtk.ListStore(2, typeof(string), typeof(string));
- foreach (var choice in key.schema.choices)
- {
- Gtk.TreeIter iter;
- model.append(out iter);
- model.set(iter, 0, choice.name, 1, choice.value.print(false), -1);
- }
- combo_renderer.model = model;
- mode = Gtk.CellRendererMode.EDITABLE;
- return;
- }
+ this.key = _key;
- switch (key.type_string)
- {
+ // infos
+ this.title = key.name;
+ if (this.use_header_bar == 1) // TODO else..?
+ ((HeaderBar) this.get_header_bar ()).subtitle = key.parent.full_name; // TODO
get_header_bar() is [transfer none]
+
+ string? gettext_domain = key.schema.gettext_domain;
+
+ string summary = key.schema.summary ?? "";
+ if (gettext_domain != null && summary != "")
+ summary = dgettext (gettext_domain, summary);
+
+ string description = key.schema.description ?? "";
+ if (gettext_domain != null && description != "")
+ description = dgettext (gettext_domain, description);
+
+ schema_label.set_text (key.schema.schema.id);
+ summary_label.set_text (summary.strip ());
+ description_label.set_text (description.strip ());
+ type_label.set_text (key_to_description ());
+ default_label.set_text (key.schema.default_value.print (false));
+
+ // widgets creation
+
+ custom_value_switch.set_active (key.is_default);
+ custom_value_switch.notify["active"].connect (() => { button_apply.set_sensitive
(custom_value_switch.get_active () ? true : custom_value_is_valid); });
+
+ custom_value_grid.add (create_child ());
+
+ this.response.connect (response_cb);
+ }
+
+ private KeyEditorChild create_child ()
+ {
+ if (key.schema.choices != null)
+ return new KeyEditorChildChoices (key);
+
+ switch (key.type_string)
+ {
case "<enum>":
- combo_renderer.text = key.value.get_string();
- combo_renderer.model = new
EnumModel(key.schema.schema.list.enums.lookup(key.schema.enum_name));
- mode = Gtk.CellRendererMode.EDITABLE;
- break;
+ return new KeyEditorChildEnum (key);
case "b":
- toggle_renderer.active = key.value.get_boolean();
- mode = Gtk.CellRendererMode.ACTIVATABLE;
- break;
+ return new KeyEditorChildBool (key.value.get_boolean ());
case "s":
- text_renderer.text = key.value.get_string();
- mode = Gtk.CellRendererMode.EDITABLE;
- break;
+ return new KeyEditorChildString (key.value.get_string ());
case "y":
case "n":
case "q":
@@ -69,101 +92,18 @@ private class KeyValueRenderer: Gtk.CellRenderer
case "x":
case "t":
case "d":
- spin_renderer.text = key.value.print(false);
- var v = get_variant_as_double(key.value);
- double min = 0.0, max = 0.0;
- if (key.has_schema && key.schema.range != null)
- {
- min = get_variant_as_double(key.schema.range.min);
- max = get_variant_as_double(key.schema.range.max);
- }
- else
- {
- min = get_variant_as_double(key.get_min());
- max = get_variant_as_double(key.get_max());
- }
- spin_renderer.adjustment = new Gtk.Adjustment(v, min, max, 1, 0, 0);
- spin_renderer.digits = 0;
- if (key.type_string == "d")
- {
- spin_renderer.digits = 20;
- }
- mode = Gtk.CellRendererMode.EDITABLE;
- break;
+ return new KeyEditorChildNumber (key);
default:
- text_renderer.text = key.value.print(false);
- mode = Gtk.CellRendererMode.EDITABLE;
- break;
- }
- }
- }
-
- private static double get_variant_as_double(Variant value)
- {
- if (value == null)
- return 0.0;
-
- switch (value.classify ())
- {
- case Variant.Class.BYTE:
- return (double)value.get_byte();
- case Variant.Class.INT16:
- return (double)value.get_int16();
- case Variant.Class.UINT16:
- return (double)value.get_uint16();
- case Variant.Class.INT32:
- return (double)value.get_int32();
- case Variant.Class.UINT32:
- return (double)value.get_uint32();
- case Variant.Class.INT64:
- return (double)value.get_int64();
- case Variant.Class.UINT64:
- return (double)value.get_uint64();
- case Variant.Class.DOUBLE:
- return value.get_double();
- default:
- return 0.0;
+ KeyEditorChildDefault key_editor_child_default = new KeyEditorChildDefault (key.type_string,
key.value);
+ key_editor_child_default.is_valid.connect ((is_valid) => { custom_value_is_valid = is_valid;
button_apply.set_sensitive (is_valid); });
+ return key_editor_child_default;
}
}
- public KeyValueRenderer(DConfKeyView view)
+ private string key_to_description ()
{
- this.view = view;
-
- text_renderer = new Gtk.CellRendererText();
- text_renderer.editable = true;
- text_renderer.edited.connect(text_edited_cb);
-
- spin_renderer = new Gtk.CellRendererSpin();
- spin_renderer.editable = true;
- spin_renderer.edited.connect(spin_edited_cb);
-
- toggle_renderer = new Gtk.CellRendererToggle();
- toggle_renderer.xalign = 0f;
- toggle_renderer.activatable = true;
- toggle_renderer.toggled.connect(toggle_cb);
-
- combo_renderer = new Gtk.CellRendererCombo();
- combo_renderer.has_entry = false;
- combo_renderer.text_column = 0;
- combo_renderer.editable = true;
- combo_renderer.edited.connect(text_edited_cb);
- }
-
- private Gtk.CellRenderer renderer
- {
- set {}
- get
+ switch (key.type_string)
{
- if (key.has_schema && key.schema.choices != null)
- return combo_renderer;
-
- switch (key.type_string)
- {
- case "<enum>":
- return combo_renderer;
- case "b":
- return toggle_renderer;
case "y":
case "n":
case "q":
@@ -171,166 +111,342 @@ private class KeyValueRenderer: Gtk.CellRenderer
case "u":
case "x":
case "t":
+ Variant min, max;
+ if (key.schema.range != null)
+ {
+ min = key.schema.range.min;
+ max = key.schema.range.max;
+ }
+ else
+ {
+ min = key.get_min ();
+ max = key.get_max ();
+ }
+ return _("Integer [%s..%s]").printf (min.print (false), max.print (false));
case "d":
- return spin_renderer;
- default:
+ Variant min, max;
+ if (key.schema.range != null)
+ {
+ min = key.schema.range.min;
+ max = key.schema.range.max;
+ }
+ else
+ {
+ min = key.get_min ();
+ max = key.get_max ();
+ }
+ return _("Double [%s..%s]").printf (min.print (false), max.print (false));
+ case "b":
+ return _("Boolean");
case "s":
- return text_renderer;
- }
+ return _("String");
+ case "<enum>":
+ return _("Enumeration");
+ default:
+ return key.schema.type;
}
}
- 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)
+ private void response_cb (Dialog dialog, int response_id)
{
- renderer.get_size(widget, cell_area, out x_offset, out y_offset, out width, out height);
+ if (response_id == ResponseType.APPLY)
+ {
+ if (!custom_value_switch.active)
+ {
+ Variant variant = ((KeyEditorChild) custom_value_grid.get_child_at (0, 0)).get_variant ();
+ if (key.is_default || key.value != variant)
+ key.value = variant;
+ }
+ else if (!key.is_default)
+ key.set_to_default ();
+ }
+ this.destroy ();
}
+}
- public override void get_preferred_width(Gtk.Widget widget,
- out int minimum_size,
- out int natural_size)
+public interface KeyEditorChild : Widget
+{
+ public abstract Variant get_variant ();
+}
+
+private class KeyEditorChildMulti : Grid, KeyEditorChild
+{
+ private static const string ACTION_NAME = "key_value";
+ private static const string GROUP_PREFIX = "bool_switch";
+
+ private SimpleAction action;
+ private VariantType variant_type;
+
+ private Grid grid;
+ private MenuButton button;
+ private Popover popover;
+
+ public KeyEditorChildMulti ()
{
- renderer.get_preferred_width(widget, out minimum_size, out natural_size);
- }
+ this.visible = true;
+ this.hexpand = true;
+
+ Label label = new Label (_("Custom Value"));
+ label.visible = true;
+ label.halign = Align.START;
+ label.hexpand = true;
+ this.attach (label, 0, 0, 1, 1);
+
+ button = new MenuButton ();
+ button.visible = true;
+ button.use_popover = true;
+ button.halign = Align.END;
+ button.width_request = 100;
+ this.attach (button, 1, 0, 1, 1);
+
+ popover = new Popover (button);
+ button.set_popover (popover);
- public override void get_preferred_height_for_width(Gtk.Widget widget,
- int width,
- out int minimum_height,
- out int natural_height)
+ grid = new Grid ();
+ grid.orientation = Orientation.VERTICAL;
+ grid.visible = true;
+ grid.row_homogeneous = true;
+ // grid.width_request = 100;
+ popover.add (grid);
+ }
+ protected void init (VariantType _type, Variant initial_value)
{
- renderer.get_preferred_height_for_width(widget, width, out minimum_height, out natural_height);
+ variant_type = _type;
+ set_text (initial_value);
+
+ action = new SimpleAction.stateful (ACTION_NAME, variant_type, initial_value);
+ SimpleActionGroup group = new SimpleActionGroup ();
+ ((ActionMap) group).add_action (action);
+ grid.insert_action_group (GROUP_PREFIX, group);
+
+ group.action_state_changed [ACTION_NAME].connect ((unknown_string, variant) => {
+ set_text (variant);
+ popover.closed ();
+ });
}
- public override void get_preferred_height(Gtk.Widget widget,
- out int minimum_size,
- out int natural_size)
+ private void set_text (Variant variant)
{
- renderer.get_preferred_height(widget, out minimum_size, out natural_size);
+ button.label = variant_type == VariantType.STRING ? variant.get_string () : variant.print (false);
}
- public override void get_preferred_width_for_height(Gtk.Widget widget,
- int height,
- out int minimum_width,
- out int natural_width)
+ protected void add_model_button (string text, Variant variant)
{
- renderer.get_preferred_width_for_height(widget, height, out minimum_width, out natural_width);
+ ModelButton button = new ModelButton ();
+ button.visible = true;
+ button.text = text;
+ button.action_name = GROUP_PREFIX + "." + ACTION_NAME;
+ button.action_target = variant;
+ grid.add (button);
}
- public override void render(Cairo.Context context,
- Gtk.Widget widget,
- Gdk.Rectangle background_area,
- Gdk.Rectangle cell_area,
- Gtk.CellRendererState flags)
+ public Variant get_variant ()
{
- renderer.render(context, widget, background_area, cell_area, flags);
+ return action.get_state ();
}
+}
- public override bool activate(Gdk.Event event,
- Gtk.Widget widget,
- string path,
- Gdk.Rectangle background_area,
- Gdk.Rectangle cell_area,
- Gtk.CellRendererState flags)
+private class KeyEditorChildChoices : KeyEditorChildMulti
+{
+ public KeyEditorChildChoices (Key key)
{
- return renderer.activate(event, widget, path, background_area, cell_area, flags);
+ init (VariantType.ANY, key.value);
+
+ foreach (SchemaChoice choice in key.schema.choices)
+ add_model_button (choice.name, choice.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)
+private class KeyEditorChildEnum : KeyEditorChildMulti
+{
+ public KeyEditorChildEnum (Key key)
{
- return renderer.start_editing(event, widget, path, background_area, cell_area, flags);
+ init (VariantType.STRING, key.value);
+
+ SchemaEnum schema_enum = key.schema.schema.list.enums.lookup (key.schema.enum_name);
+ if (schema_enum.values.length () <= 0)
+ assert_not_reached (); // TODO special case 0?
+// else if (schema_enum.values.length () == 1)
+// assert_not_reached (); // TODO
+
+ for (uint index = 0; index < schema_enum.values.length (); index++)
+ {
+ string nick = schema_enum.values.nth_data (index).nick; // value.get_string ()); ?
key.value.get_string () ? key.value.print (false) ? nick ?
+ add_model_button (nick, new Variant.string (nick));
+ }
}
+}
- private Key get_key_from_path(string path)
+private class KeyEditorChildBool : Grid, KeyEditorChild // might be managed by action, but can't find a way
to ensure one-and-only-one button is active
+{
+ private ToggleButton button_true;
+
+ public KeyEditorChildBool (bool initial_value)
{
- Gtk.TreeIter iter;
- view.model.get_iter_from_string(out iter, path);
+ this.visible = true;
+ this.hexpand = true;
+
+ Label label = new Label (_("Custom Value"));
+ label.visible = true;
+ label.halign = Align.START;
+ label.hexpand = true;
+ this.attach (label, 0, 0, 1, 1);
+
+ Grid grid = new Grid ();
+ grid.visible = true;
+ grid.halign = Align.END;
+ grid.column_homogeneous = true;
+ grid.width_request = 100;
+ ((StyleContext) grid.get_style_context ()).add_class ("linked");
+ this.attach (grid, 1, 0, 1, 1);
- Key key;
- view.model.get(iter, 0, out key, -1);
+ ToggleButton button_false = new ToggleButton ();
+ button_false.visible = true;
+ button_false.label = _("False");
+ grid.attach (button_false, 0, 0, 1, 1);
- return key;
+ button_true = new ToggleButton ();
+ button_true.visible = true;
+ button_true.label = _("True");
+ grid.attach (button_true, 1, 0, 1, 1);
+
+ button_true.active = initial_value;
+ button_true.bind_property ("active", button_false, "active",
BindingFlags.INVERT_BOOLEAN|BindingFlags.SYNC_CREATE|BindingFlags.BIDIRECTIONAL);
}
- private void toggle_cb(Gtk.CellRendererToggle renderer, string path)
+ public Variant get_variant ()
{
- var key = get_key_from_path(path);
- key.value = new Variant.boolean(!key.value.get_boolean());
+ return new Variant.boolean (button_true.active);
}
+}
+
+private class KeyEditorChildNumber : Grid, KeyEditorChild
+{
+ private SpinButton spin;
+ private string key_type;
- private void text_edited_cb(Gtk.CellRendererText renderer, string path, string text)
+ public KeyEditorChildNumber (Key key)
{
- var key = get_key_from_path(path);
- if (key.type_string == "s" || key.type_string == "<enum>")
+ this.key_type = key.type_string;
+
+ this.visible = true;
+ this.hexpand = true;
+
+ Label label = new Label (_("Custom Value"));
+ label.visible = true;
+ label.halign = Align.START;
+ label.hexpand = true;
+ this.attach (label, 0, 0, 1, 1);
+
+ bool has_range = /* key.has_schema && */ key.schema.range != null;
+ double min = get_variant_as_double ((has_range && key.schema.range.min != null) ?
key.schema.range.min : key.get_min ());
+ double max = get_variant_as_double ((has_range && key.schema.range.max != null) ?
key.schema.range.max : key.get_max ());
+
+ if (key.type_string == "d")
{
- key.value = new Variant.string(text);
+ Adjustment adjustment = new Adjustment (key.value.get_double (), min, max, 0.01, 0.1, 0.0);
+ spin = new SpinButton (adjustment, 0.01, 2);
}
else
{
- try
- {
- var value = Variant.parse(new VariantType(key.type_string), text);
- key.value = value;
- }
- catch (VariantParseError e)
- {
- var dialog = new Gtk.MessageDialog(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING,
Gtk.ButtonsType.OK, _("Error setting value: %s"), e.message);
- dialog.run();
- dialog.destroy();
- }
+ Adjustment adjustment = new Adjustment (get_variant_as_double (key.value), min, max, 1.0, 5.0,
0.0);
+ spin = new SpinButton (adjustment, 1.0, 0);
}
+
+ spin.visible = true;
+ spin.update_policy = SpinButtonUpdatePolicy.IF_VALID;
+ spin.snap_to_ticks = true;
+ spin.input_purpose = InputPurpose.NUMBER; // TODO spin.input_purpose = InputPurpose.DIGITS &
spin.numeric = true; (no “e”) if not double?
+ spin.width_chars = 30;
+ this.attach (spin, 1, 0, 1, 1);
}
- private void spin_edited_cb(Gtk.CellRendererText renderer, string path, string text)
+ private static double get_variant_as_double (Variant variant)
+ requires (variant != null) // TODO is that realllly useful? it shouldn't...
{
- var key = get_key_from_path(path);
- switch (key.type_string)
+ switch (variant.classify ())
{
- case "y":
- key.value = new Variant.byte((uchar)int.parse(text));
- break;
- case "n":
- key.value = new Variant.int16((int16)int.parse(text));
- break;
- case "q":
- key.value = new Variant.uint16((uint16)int.parse(text));
- break;
- case "i":
- key.value = new Variant.int32(int.parse(text));
- break;
- case "u":
- key.value = new Variant.uint32(int.parse(text));
- break;
- case "x":
- key.value = new Variant.int64(int.parse(text));
- break;
- case "t":
- key.value = new Variant.uint64(int.parse(text));
- break;
- case "d":
- key.value = new Variant.double(double.parse(text));
- break;
+ case Variant.Class.BYTE: return (double) variant.get_byte ();
+ case Variant.Class.INT16: return (double) variant.get_int16 ();
+ case Variant.Class.UINT16: return (double) variant.get_uint16 ();
+ case Variant.Class.INT32: return (double) variant.get_int32 ();
+ case Variant.Class.UINT32: return (double) variant.get_uint32 ();
+ case Variant.Class.INT64: return (double) variant.get_int64 ();
+ case Variant.Class.UINT64: return (double) variant.get_uint64 ();
+ case Variant.Class.DOUBLE: return variant.get_double ();
+ default: assert_not_reached ();
+ }
+ }
+
+ public Variant get_variant ()
+ {
+ switch (key_type)
+ {
+ case "y": return new Variant.byte ((uchar) spin.get_value ());
+ case "n": return new Variant.int16 ((int16) spin.get_value ());
+ case "q": return new Variant.uint16 ((uint16) spin.get_value ());
+ case "i": return new Variant.int32 ((int) spin.get_value ());
+ case "u": return new Variant.uint32 ((int) spin.get_value ());
+ case "x": return new Variant.int64 ((int) spin.get_value ());
+ case "t": return new Variant.uint64 ((int) spin.get_value ());
+ case "d": return new Variant.double (spin.get_value ());
+ default : assert_not_reached ();
}
}
}
-public class DConfKeyView : Gtk.TreeView
+private class KeyEditorChildString : Entry, KeyEditorChild
{
- public DConfKeyView()
+ public KeyEditorChildString (string _text)
+ {
+ this.visible = true;
+ this.hexpand = true;
+ this.text = _text;
+ }
+
+ public Variant get_variant ()
+ {
+ return new Variant.string (this.text);
+ }
+}
+
+private class KeyEditorChildDefault : Entry, KeyEditorChild
+{
+ public signal void is_valid (bool is_valid);
+
+ private string variant_type;
+ private Variant variant;
+
+ public KeyEditorChildDefault (string type, Variant initial_value)
+ {
+ this.variant_type = type;
+ this.variant = initial_value;
+
+ this.visible = true;
+ this.hexpand = true;
+ this.text = initial_value.print (false);
+
+ this.buffer.deleted_text.connect (test_value);
+ this.buffer.inserted_text.connect (test_value);
+ test_value ();
+ }
+
+ private void test_value ()
+ {
+ try
+ {
+ Variant? tmp_variant = Variant.parse (new VariantType (variant_type), this.text);
+ variant = tmp_variant;
+ is_valid (true);
+ }
+ catch (VariantParseError e)
+ {
+ is_valid (false);
+ }
+ }
+
+ public Variant get_variant ()
{
- /* Translators: this is the column header label in the main view */
- var column = new Gtk.TreeViewColumn.with_attributes(_("Name"), new Gtk.CellRendererText(), "text",
1, "weight", 4, null);
- /*column.set_sort_column_id(1);*/
- append_column(column);
- /* Translators: this is the column header label in the main view */
- insert_column_with_attributes(-1, _("Value"), new KeyValueRenderer(this), "key", 0, null);
+ return variant;
}
}
diff --git a/editor/dconf-window.vala b/editor/dconf-window.vala
index 36c44e9..b211ec5 100644
--- a/editor/dconf-window.vala
+++ b/editor/dconf-window.vala
@@ -23,49 +23,14 @@ class DConfWindow : ApplicationWindow
private SettingsModel model;
[GtkChild] private TreeView dir_tree_view;
[GtkChild] private TreeSelection dir_tree_selection;
+ [GtkChild] private ListBox key_list_box;
[GtkChild] private Box search_box;
[GtkChild] private Entry search_entry;
[GtkChild] private Label search_label;
- private TreeView key_tree_view;
- [GtkChild]
- private ScrolledWindow key_scrolledwindow; // TODO used only for adding key_tree_view, a pseudo-TreeView
-
- [GtkChild]
- private Grid key_info_grid;
- [GtkChild]
- private Label schema_label;
- [GtkChild]
- private Label summary_label;
- [GtkChild]
- private Label description_label;
- [GtkChild]
- private Label type_label;
- [GtkChild]
- private Label default_label;
-
- private Key? selected_key;
-
- private const GLib.ActionEntry[] window_actions =
- {
- { "set-default", set_default_cb }
- };
- private SimpleAction set_default_action;
-
public DConfWindow ()
{
- add_action_entries (window_actions, this);
- set_default_action = (SimpleAction) lookup_action ("set-default");
- set_default_action.set_enabled (false);
-
- /* key tree */
- key_tree_view = new DConfKeyView ();
- key_tree_view.show ();
- key_tree_view.get_selection ().changed.connect (key_selected_cb);
- key_scrolledwindow.add (key_tree_view);
-
- /* dir tree */
model = new SettingsModel ();
dir_tree_view.set_model (model);
@@ -81,140 +46,36 @@ class DConfWindow : ApplicationWindow
[GtkCallback]
private void dir_selected_cb ()
{
- KeyModel? key_model = null;
+ GLib.ListStore? key_model = null;
TreeIter iter;
if (dir_tree_selection.get_selected (null, out iter))
key_model = model.get_directory (iter).key_model;
- key_tree_view.set_model (key_model);
-
- /* Always select something */
- if (key_model != null && key_model.get_iter_first (out iter))
- key_tree_view.get_selection ().select_iter (iter);
+ key_list_box.bind_model (key_model, new_list_box_row);
}
/*\
- * * Key TreeView & informations
+ * * Key ListBox
\*/
- private string key_to_description (Key key)
+ private Widget new_list_box_row (Object item)
{
- switch (key.type_string)
+ Key key = (Key) item;
+ if (key.has_schema)
{
- case "y":
- case "n":
- case "q":
- case "i":
- case "u":
- case "x":
- case "t":
- Variant min, max;
- if (key.schema.range != null)
- {
- min = key.schema.range.min;
- max = key.schema.range.max;
- }
- else
- {
- min = key.get_min ();
- max = key.get_max ();
- }
- return _("Integer [%s..%s]").printf (min.print (false), max.print (false));
- case "d":
- Variant min, max;
- if (key.schema.range != null)
- {
- min = key.schema.range.min;
- max = key.schema.range.max;
- }
- else
- {
- min = key.get_min ();
- max = key.get_max ();
- }
- return _("Double [%s..%s]").printf (min.print (false), max.print (false));
- case "b":
- return _("Boolean");
- case "s":
- return _("String");
- case "<enum>":
- return _("Enumeration");
- default:
- return key.schema.type;
- }
- }
-
- private void key_selected_cb ()
- {
- if (selected_key != null)
- selected_key.value_changed.disconnect (key_changed_cb);
-
- TreeIter iter;
- TreeModel model;
- if (key_tree_view.get_selection ().get_selected (out model, out iter))
- {
- var key_model = (KeyModel) model;
- selected_key = key_model.get_key (iter);
+ KeyListBoxRowEditable key_list_box_row = new KeyListBoxRowEditable (key);
+ key.value_changed.connect (() => { key_list_box_row.update (); });
+ return key_list_box_row;
}
else
- selected_key = null;
-
- if (selected_key != null)
- selected_key.value_changed.connect (key_changed_cb);
-
- key_info_grid.sensitive = selected_key != null;
- set_default_action.set_enabled (selected_key != null && !selected_key.is_default);
-
- string schema_name = "", summary = "", description = "", type = "", default_value = "";
-
- if (selected_key != null)
- {
- if (selected_key.schema != null)
- {
- var gettext_domain = selected_key.schema.gettext_domain;
- schema_name = selected_key.schema.schema.id;
-
- if (selected_key.schema.summary != null)
- summary = selected_key.schema.summary;
- if (gettext_domain != null && summary != "")
- summary = dgettext (gettext_domain, summary);
-
- if (selected_key.schema.description != null)
- description = selected_key.schema.description;
- if (gettext_domain != null && description != "")
- description = dgettext (gettext_domain, description);
-
- type = key_to_description (selected_key);
- default_value = selected_key.schema.default_value.print (false);
- }
- else
- {
- schema_name = _("No schema");
- }
- }
-
- schema_label.set_text (schema_name);
- summary_label.set_text (summary.strip ());
- description_label.set_text (description.strip ());
- type_label.set_text (type);
- default_label.set_text (default_value);
- }
-
- /*\
- * * Set_default button
- \*/
-
- private void key_changed_cb (Key key) /* TODO reuse */
- {
- set_default_action.set_enabled (selected_key != null && !selected_key.is_default);
+ return new KeyListBoxRowNonEditable (key.name, key.cool_text_value ());
}
- private void set_default_cb ()
+ [GtkCallback]
+ private void row_activated_cb (ListBoxRow list_box_row)
{
- if (selected_key == null)
- return;
- selected_key.set_to_default ();
+ ((KeyListBoxRow) list_box_row.get_child ()).show_dialog (this);
}
/*\
@@ -249,66 +110,57 @@ class DConfWindow : ApplicationWindow
{
search_label.label = "";
- /* Get the current position in the tree */
TreeIter iter;
- TreeIter key_iter = TreeIter ();
- bool have_key_iter = false;
+ int position = 0;
if (dir_tree_selection.get_selected (null, out iter))
{
- if (key_tree_view.get_selection ().get_selected (null, out key_iter))
- {
- var dir = model.get_directory (iter);
- if (dir.key_model.iter_next (ref key_iter))
- have_key_iter = true;
- else
- get_next_iter (ref iter);
- }
+ ListBoxRow? selected_row = (ListBoxRow) key_list_box.get_selected_row ();
+ if (selected_row != null)
+ position = selected_row.get_index () + 1;
}
- else if (!model.get_iter_first (out iter))
- return;
+ else if (!model.get_iter_first (out iter)) // TODO doesn't that reset iter?
+ return; // TODO better
bool on_first_directory = true;
do
{
- /* Select next directory that matches */
Directory dir = model.get_directory (iter);
- if (!have_key_iter)
+
+ if (!on_first_directory && dir.name.index_of (search_entry.text) >= 0)
{
- have_key_iter = dir.key_model.get_iter_first (out key_iter);
- if (!on_first_directory && dir.name.index_of (search_entry.text) >= 0)
- {
- dir_tree_view.expand_to_path (model.get_path (iter));
- dir_tree_selection.select_iter (iter);
- dir_tree_view.scroll_to_cell (model.get_path (iter), null, false, 0, 0);
- return;
- }
+ select_dir (iter);
+ return;
}
on_first_directory = false;
/* Select next key that matches */
- if (have_key_iter)
+ GLib.ListStore key_model = dir.key_model;
+ while (position < key_model.get_n_items ())
{
- do
+ Key key = (Key) key_model.get_object (position);
+ if (key_matches (key, search_entry.text))
{
- var key = dir.key_model.get_key (key_iter);
- if (key_matches (key, search_entry.text))
- {
- dir_tree_view.expand_to_path (model.get_path (iter));
- dir_tree_selection.select_iter (iter);
- dir_tree_view.scroll_to_cell (model.get_path (iter), null, false, 0, 0);
- key_tree_view.get_selection ().select_iter (key_iter);
- key_tree_view.scroll_to_cell (dir.key_model.get_path (key_iter), null, false, 0, 0);
- return;
- }
- } while (dir.key_model.iter_next (ref key_iter));
+ select_dir (iter);
+ key_list_box.select_row (key_list_box.get_row_at_index (position));
+ return;
+ }
+ position++;
}
- have_key_iter = false;
+
+ position = 0;
}
while (get_next_iter (ref iter));
search_label.label = _("Not found");
}
+ private void select_dir (TreeIter iter)
+ {
+ dir_tree_view.expand_to_path (model.get_path (iter));
+ dir_tree_selection.select_iter (iter);
+ dir_tree_view.scroll_to_cell (model.get_path (iter), null, false, 0, 0);
+ }
+
private bool key_matches (Key key, string text)
{
/* Check key name */
@@ -316,7 +168,7 @@ class DConfWindow : ApplicationWindow
return true;
/* Check key schema (description) */
- if (key.schema != null)
+ if (key.has_schema)
{
if (key.schema.summary != null && key.schema.summary.index_of (text) >= 0)
return true;
@@ -351,3 +203,70 @@ class DConfWindow : ApplicationWindow
return true;
}
}
+
+[GtkTemplate (ui = "/ca/desrt/dconf-editor/ui/key-list-box-row.ui")]
+private abstract class KeyListBoxRow : Grid
+{
+ [GtkChild] protected Label key_name_label;
+ [GtkChild] protected Label key_value_label;
+ [GtkChild] protected Label key_info_label;
+
+ public abstract void show_dialog (ApplicationWindow window);
+}
+
+private class KeyListBoxRowNonEditable : KeyListBoxRow
+{
+ public KeyListBoxRowNonEditable (string key_name, string key_value)
+ {
+ key_name_label.label = key_name;
+ key_value_label.label = key_value;
+ key_info_label.set_markup ("<i>" + _("No Schema") + "</i>");
+ }
+
+ public override void show_dialog (ApplicationWindow window)
+ {
+ MessageDialog dialog = new MessageDialog (window, DialogFlags.MODAL, MessageType.WARNING,
ButtonsType.OK, _("No Schema, cannot edit value.")); // TODO with or without punctuation? // TODO
insert key name/path/..?
+ dialog.run ();
+ dialog.destroy ();
+ }
+}
+
+private class KeyListBoxRowEditable : KeyListBoxRow
+{
+ public Key key { get; private set; }
+
+ private Pango.AttrList attr_list = new Pango.AttrList ();
+
+ public KeyListBoxRowEditable (Key _key)
+ {
+ this.key = _key;
+ key_value_label.set_attributes (attr_list);
+ update (); // sets key_name_label attributes and key_value_label label
+ key_name_label.label = key.name;
+
+ string? summary = key.schema.summary;
+ if (summary == null || summary == "")
+ return;
+
+ string? gettext_domain = key.schema.gettext_domain;
+ if (gettext_domain != null)
+ summary = dgettext (gettext_domain, summary);
+ key_info_label.label = summary.strip ();
+ }
+
+ public void update ()
+ {
+ attr_list.change (Pango.attr_weight_new (key.is_default ? Pango.Weight.NORMAL : Pango.Weight.BOLD));
// TODO good?
+ key_name_label.set_attributes (attr_list);
+ // TODO key_info_label.set_attributes (attr_list); ?
+
+ key_value_label.label = key.cool_text_value ();
+ }
+
+ public override void show_dialog (ApplicationWindow window)
+ {
+ KeyEditor key_editor = new KeyEditor (key);
+ key_editor.set_transient_for (window);
+ key_editor.run ();
+ }
+}
diff --git a/editor/key-editor.ui b/editor/key-editor.ui
new file mode 100644
index 0000000..3401669
--- /dev/null
+++ b/editor/key-editor.ui
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <template class="KeyEditor" parent="GtkDialog">
+ <property name="visible">False</property>
+ <property name="modal">True</property>
+ <property name="default-height">1</property><!-- TODO bug of GtkDialog, that reserves space for bottom
buttons -->
+ <property name="default-width">600</property>
+ <property name="width-request">600</property>
+ <property name="resizable">False</property>
+ <property name="title" translatable="yes">Key Editor</property>
+ <child type="action">
+ <object class="GtkButton" id="button-cancel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Cancel</property><!-- TODO _Cancel? -->
+ <property name="width-request">100</property><!-- button_apply is in the same horizontal
GtkSizeGroup; same width request for custom_value_switch -->
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="button_apply">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Apply</property><!-- TODO _Apply? -->
+ <property name="can-default">True</property>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="cancel">button-cancel</action-widget>
+ <action-widget response="apply" default="true">button_apply</action-widget>
+ </action-widgets>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="margin">6</property><!-- TODO test -->
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Schema:</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Summary:</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Description:</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes" comments="Translators: as in datatype (integer,
boolean, string, etc)">Type:</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Default:</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="schema_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="wrap">True</property>
+ <property name="selectable">True</property>
+ <property name="can-focus">False</property>
+<!-- <property name="hexpand">True</property> -->
+ <property name="max-width-chars">42</property>
+ <property name="width-chars">42</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="summary_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="wrap">True</property>
+ <property name="selectable">True</property>
+ <property name="can-focus">False</property>
+<!-- <property name="hexpand">True</property> -->
+ <property name="max-width-chars">42</property>
+ <property name="width-chars">42</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="description_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="wrap">True</property>
+ <property name="selectable">True</property>
+ <property name="can-focus">False</property>
+<!-- <property name="hexpand">True</property> -->
+ <property name="max-width-chars">42</property>
+ <property name="width-chars">42</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="type_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="wrap">True</property>
+ <property name="selectable">True</property>
+ <property name="can-focus">False</property>
+<!-- <property name="hexpand">True</property> -->
+ <property name="max-width-chars">42</property>
+ <property name="width-chars">42</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="default_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="wrap">True</property>
+ <property name="selectable">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <!--<property name="max-width-chars">42</property>
+ <property name="width-chars">42</property> -->
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Use default value</property>
+ <property name="valign">baseline</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="custom_value_switch">
+ <property name="visible">True</property>
+ <property name="width-request">100</property><!-- same request than for
button_cancel/button_apply -->
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">5</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkGrid" id="custom_value_grid">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="margin-top">6</property><!-- TODO better -->
+ <property name="sensitive" bind-source="custom_value_switch" bind-property="active"
bind-flags="sync-create|invert-boolean"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/editor/key-list-box-row.ui b/editor/key-list-box-row.ui
new file mode 100644
index 0000000..45fd9bf
--- /dev/null
+++ b/editor/key-list-box-row.ui
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <template class="KeyListBoxRow" parent="GtkGrid">
+ <property name="visible">True</property>
+ <property name="orientation">horizontal</property>
+ <property name="height-request">42</property>
+ <property name="margin-start">10</property><!-- looks cool -->
+ <property name="column-spacing">6</property>
+ <property name="margin-end">6</property><!-- same as column_spacing -->
+ <child>
+ <object class="GtkLabel" id="key_name_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="vexpand">True</property>
+ <property name="width-request">222</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">PANGO_WRAP_WORD_CHAR</property>
+ <property name="halign">start</property>
+ <property name="single-line-mode">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="key_value_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="vexpand">True</property>
+ <property name="width-request">166</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">PANGO_WRAP_WORD_CHAR</property>
+ <property name="halign">start</property>
+ <property name="single-line-mode">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="key_info_label">
+ <property name="visible">True</property>
+ <property name="expand">True</property>
+ <property name="wrap">False</property>
+ <property name="halign">start</property>
+ <property name="single-line-mode">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ </child>
+ </template>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]