[model] make GtkTreeModel more robust
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [model] make GtkTreeModel more robust
- Date: Fri, 12 Mar 2010 07:42:58 +0000 (UTC)
commit 4e215bfbc866834be56bc2102a3484b2e6aca8e4
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Mar 11 21:35:59 2010 -0500
make GtkTreeModel more robust
gtk/mg.vala | 8 +--
gtk/model-gtk.vala | 156 ++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 117 insertions(+), 47 deletions(-)
---
diff --git a/gtk/mg.vala b/gtk/mg.vala
index 3262cdc..025acd8 100644
--- a/gtk/mg.vala
+++ b/gtk/mg.vala
@@ -1,20 +1,16 @@
Gtk.TreeView v;
Model.List list;
-bool setup () {
- v.set_model (new Model.GtkModel (list, {typeof(string),typeof(string)}, {"name", "type"}, "contents"));
- return false;
-}
-
void main (string[]args) {
Gtk.init (ref args);
var w = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
+ w.set_default_size (800, 600);
list = new FS.Directory (File.new_for_path ("/home/desrt/Desktop/small"));
v = new Gtk.TreeView ();
v.insert_column_with_attributes (0, "name", new Gtk.CellRendererText (), "text", 0);
v.insert_column_with_attributes (0, "type", new Gtk.CellRendererText (), "text", 1);
- Timeout.add (1000, setup);
+ v.set_model (new Model.GtkModel (list, {typeof(string),typeof(string)}, {"name", "type"}, "contents"));
var sc = new Gtk.ScrolledWindow (null, null);
sc.add (v);
w.add (sc);
diff --git a/gtk/model-gtk.vala b/gtk/model-gtk.vala
index 3377418..e5ec1b7 100644
--- a/gtk/model-gtk.vala
+++ b/gtk/model-gtk.vala
@@ -1,7 +1,7 @@
namespace Model {
class ListTracker {
internal DictionaryTracker? first;
- //DictionaryTracker[]? array;
+ DictionaryTracker[]? array;
internal int length;
ulong changed_id;
@@ -12,17 +12,19 @@ namespace Model {
DictionaryTracker **cached_child;
ulong cached_child_index;
+ internal Gtk.TreePath get_tree_path () {
+ if (parent != null) {
+ return ((!) parent).get_tree_path ();
+ } else {
+ return new Gtk.TreePath ();
+ }
+ }
+
void source_changed (Model.List source, ulong position, ulong deleted, ulong inserted, bool more) {
- Gtk.TreePath path;
bool was_empty;
was_empty = length == 0;
-
- if (parent != null) {
- path = parent.get_tree_path ();
- } else {
- path = new Gtk.TreePath ();
- }
+ array = null;
/* seek to position */
if (cached_child_index > position) {
@@ -37,6 +39,7 @@ namespace Model {
}
}
+ var path = get_tree_path ();
path.append_index ((int) position);
while (deleted --> 0) {
@@ -75,9 +78,23 @@ namespace Model {
if (more == false) {
cached_child = null;
+ build_array ();
}
}
+ void build_array () {
+ var link = first;
+
+ array = new DictionaryTracker[length];
+ for (var i = 0; i < length; i++) {
+ array[i] = link;
+ link.index = i;
+ link = link.next;
+ }
+
+ assert (link == null);
+ }
+
internal ListTracker (GtkModel model, Model.List source, DictionaryTracker? parent = null) {
this.parent = parent;
this.source = source;
@@ -90,16 +107,21 @@ namespace Model {
}
changed_id = source.changed.connect (source_changed);
+ build_array ();
}
internal DictionaryTracker? get_nth (int n) {
- var dt = first;
+ if (array != null) {
+ return array[n];
+ } else {
+ var dt = first;
- while (dt != null && n --> 0) {
- dt = dt.next;
- }
+ while (dt != null && n --> 0) {
+ dt = dt.next;
+ }
- return dt;
+ return dt;
+ }
}
internal DictionaryTracker? get_for_path (Gtk.TreePath path, int depth = 0) {
@@ -116,6 +138,45 @@ namespace Model {
return item;
}
+ internal int find (DictionaryTracker child) {
+ if (array != null) {
+ assert (array[child.index] == child);
+ return child.index;
+ } else {
+ var link = first;
+ var i = 0;
+
+ while (link != child) {
+ link = link.next;
+ i++;
+ }
+
+ return i;
+ }
+ }
+
+ internal void delete_all () {
+ if (length > 0) {
+ var path = get_tree_path ();
+ path.append_index (0);
+
+ array = null;
+ while (first != null) {
+ model.row_deleted (path);
+ first = first.next;
+ length--;
+ }
+
+ assert (length == 0);
+ path.up ();
+
+ Gtk.TreeIter iter;
+ if (model.write_iter (out iter, parent)) {
+ model.row_has_child_toggled (path, iter);
+ }
+ }
+ }
+
~ListTracker () {
source.disconnect (changed_id);
}
@@ -124,66 +185,79 @@ namespace Model {
class DictionaryTracker {
Model.Reference? children_reference;
internal ListTracker? children;
+ ulong children_handler;
+
+ Model.Reference[] references;
+ ulong[] reference_handlers;
internal weak ListTracker siblings;
- internal Model.Dictionary source;
- weak GtkModel model;
+ internal int index;
internal DictionaryTracker? next;
void children_reference_changed (Model.Reference reference) {
var list = reference.get_value () as Model.List;
+ if (children != null) {
+ children.delete_all ();
+ }
+
if (list != null) {
- children = new ListTracker (model, list, this);
+ children = new ListTracker (siblings.model, list, this);
} else {
children = null;
}
}
+ void reference_changed (Model.Reference reference) {
+ var path = get_tree_path ();
+ Gtk.TreeIter iter;
+
+ siblings.model.write_iter (out iter, this);
+ siblings.model.row_changed (path, iter);
+ }
+
public DictionaryTracker (ListTracker siblings, Model.Dictionary source, DictionaryTracker? next) {
- this.model = siblings.model;
+ var model = siblings.model;
+
this.siblings = siblings;
- this.source = source;
this.next = next;
if (model.children_key != null) {
children_reference = source.get_reference ((!) model.children_key);
- children_reference.changed += children_reference_changed;
+ children_handler = children_reference.changed.connect (children_reference_changed);
children_reference_changed ((!) children_reference);
}
- }
- internal int get_index () {
- var chain = siblings.first;
- var i = 0;
-
- while (chain != this) {
- chain = chain.next;
- i++;
+ references = new Model.Reference[model.keys.length];
+ reference_handlers = new ulong[model.keys.length];
+ for (var i = 0; i < model.keys.length; i++) {
+ references[i] = source.get_reference (model.keys[i]);
+ reference_handlers[i] = references[i].changed.connect (reference_changed);
}
-
- return i;
}
internal Gtk.TreePath get_tree_path () {
- Gtk.TreePath path;
-
- if (siblings.parent != null) {
- path = siblings.parent.get_tree_path ();
- } else {
- path = new Gtk.TreePath ();
- }
+ var path = siblings.get_tree_path ();
+ path.append_index (siblings.find (this));
+ return path;
+ }
- path.append_index (get_index ());
+ internal Model.Object get_value (int index) {
+ return references[index].get_value ();
+ }
- return path;
+ ~DictionaryTracker () {
+ children_reference.disconnect (children_handler);
+ for (var i = 0; i < references.length; i++) {
+ references[i].disconnect (reference_handlers[i]);
+ }
}
}
public class GtkModel : GLib.Object, Gtk.TreeModel {
internal string? children_key;
- string[] keys;
+ internal string[] keys;
Type[] types;
ListTracker root;
@@ -219,7 +293,7 @@ namespace Model {
void get_value (Gtk.TreeIter iter, int column, out GLib.Value value) {
var dt = iter_to_dt (iter);
- var object = dt.source.get_value (keys[column]);
+ var object = dt.get_value (column);
value.init (types[column]);
@@ -316,4 +390,4 @@ namespace Model {
}
}
-// vim:ts=8 sw=8 noet:
+// vim:ts=4 sw=4 noet:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]