diff options
Diffstat (limited to 'src/gui/Roster.vala')
-rw-r--r-- | src/gui/Roster.vala | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala new file mode 100644 index 0000000..2ef4618 --- /dev/null +++ b/src/gui/Roster.vala @@ -0,0 +1,166 @@ +public class Roster : Object { + private int stamp; + private Gee.TreeMap<string, Contact> entries = new Gee.TreeMap<string, Contact>(); + private Gee.TreeMap<string, RosterGroup> groups = new Gee.TreeMap<string, RosterGroup>(); + + + public Roster() { + stamp = 0; + groups["default"] = new RosterGroup(this); + } + + public Gtk.TreeModel get_default_group() { + return groups["default"]; + } + + public void update_contact(Contact c) { + entries[c.jid] = c; + groups["default"].update_contact(c); + } + + private class RosterGroup : Object, Gtk.TreeModel { + private unowned Roster roster {get; set;} + private Gee.TreeMap<string, Contact> entries = new Gee.TreeMap<string, Contact>(); + + + public RosterGroup(Roster roster0) { + roster = roster0; + } + + public void update_contact(Contact c) { + bool added = !entries.has_key(c.jid); + + entries[c.jid] = c; + + Gtk.TreeIter iter = Gtk.TreeIter(); + iter.stamp = roster.stamp; + iter.user_data = this; + iter.user_data2 = c; + + Gtk.TreePath path = get_path(iter); + + if (added) + row_inserted(path, iter); + else + row_changed(path, iter); + } + + public Type get_column_type (int index) { + switch(index) { + case 0: + return typeof(Contact); + } + + return Type.INVALID; + } + + public Gtk.TreeModelFlags get_flags () { + return Gtk.TreeModelFlags.LIST_ONLY; + } + + public bool get_iter (out Gtk.TreeIter iter, Gtk.TreePath path) { + if(path.get_depth() != 1) + return false; + + int index = path.get_indices()[0]; + if(index < 0 || index >= entries.size) + return false; + + Gee.MapIterator<string, Contact> it = entries.map_iterator(); + it.first(); + for(int i = 0; i < index; ++i) + it.next(); + + iter.stamp = roster.stamp; + iter.user_data = this; + iter.user_data2 = it.get_value(); + + return true; + } + + public int get_n_columns () { + return 1; + } + + public Gtk.TreePath get_path (Gtk.TreeIter iter) { + if(iter.stamp != roster.stamp || iter.user_data != this) + return (Gtk.TreePath)null; + + int index = 0; + + foreach(Contact c in entries.values) { + if(c == iter.user_data2) + break; + + ++index; + } + + return new Gtk.TreePath.from_indices(index, -1); + } + + public void get_value (Gtk.TreeIter iter, int column, out Value value) { + if (column != 0 || iter.stamp != roster.stamp || iter.user_data != this) + return; + + Contact c = iter.user_data2 as Contact; + value = Value(typeof(Contact)); + value.take_object(c); + } + + public bool iter_children (out Gtk.TreeIter iter, Gtk.TreeIter? parent) { + if (parent != null) { + iter.stamp = -1; + return false; + } + + return get_iter(out iter, new Gtk.TreePath.from_indices(0, -1)); + } + + public bool iter_has_child (Gtk.TreeIter iter) { + return false; + } + + public int iter_n_children (Gtk.TreeIter? iter) { + if (iter == null) + return entries.size; + else + return 0; + } + + public bool iter_next (ref Gtk.TreeIter iter) { + if(iter.stamp != roster.stamp || iter.user_data != this) + return false; + + bool next = false; + foreach(Contact c in entries.values) { + if(next) { + iter.user_data2 = c; + return true; + } + + if(c == iter.user_data2) + next = true; + } + + iter.stamp = -1; + return false; + } + + public bool iter_nth_child (out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n) { + if (parent != null) { + iter.stamp = -1; + return false; + } + + return get_iter(out iter, new Gtk.TreePath.from_indices(n, -1)); + } + + public bool iter_parent (out Gtk.TreeIter iter, Gtk.TreeIter child) { + iter.stamp = -1; + return false; + } + + public void ref_node (Gtk.TreeIter iter) {} + public void unref_node (Gtk.TreeIter iter) {} + } +} |