summaryrefslogtreecommitdiffstats
path: root/src/gui/Roster.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/Roster.vala')
-rw-r--r--src/gui/Roster.vala166
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) {}
+ }
+}