diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2010-08-17 00:22:21 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2010-08-17 00:22:21 +0200 |
commit | 6ec7efc36f44dfddff4c9d843cd4c70cffb95837 (patch) | |
tree | 35475563668e508b711517827fba6e2aeb54a0a3 /src/gui/Roster.vala | |
parent | eb4193538b99cf9d49ad0650b1bb816844361ab5 (diff) | |
download | ephraim-6ec7efc36f44dfddff4c9d843cd4c70cffb95837.tar ephraim-6ec7efc36f44dfddff4c9d843cd4c70cffb95837.zip |
Many improvements to roster view
Diffstat (limited to 'src/gui/Roster.vala')
-rw-r--r-- | src/gui/Roster.vala | 125 |
1 files changed, 93 insertions, 32 deletions
diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala index ca1ef16..32bdb6d 100644 --- a/src/gui/Roster.vala +++ b/src/gui/Roster.vala @@ -2,17 +2,16 @@ public class Roster { private Gtk.TreeView rosterView; private ContactListModel contactList; private RosterModel model; - private Gee.Map<string, int> groups = new Gee.HashMap<string, int>(); + private Gee.Map<string, Gee.Map<string, Contact>> groups = new Gee.HashMap<string, Gee.Map<string, Contact>>(); public signal void start_conversation(string jid); - public Roster(Gtk.TreeView rosterView0) { rosterView = rosterView0; contactList = new ContactListModel(this); model = new RosterModel(contactList); - - rosterView.set_model(model); + + rosterView.set_model(new RosterFilter(this, model)); rosterView.query_tooltip.connect((x, y, keyboard_tip, tooltip) => { Gtk.TreeModel model; @@ -57,7 +56,7 @@ public class Roster { start_conversation(contact.jid + "/" + res.key); }); - model.row_inserted.connect((path, iter) => { + rosterView.model.row_inserted.connect((path, iter) => { rosterView.expand_to_path(path); }); @@ -74,17 +73,21 @@ public class Roster { } private void update_groups() { - foreach(Gee.Map.Entry<string, int> group in groups) { - if(group.value <= 0) { - model.removeGroup(group.key); - groups.remove(group.key); + foreach(Gee.Map.Entry<string, Gee.Map<string, Contact>> group in groups) { + if(group.value.is_empty) { + model.remove_group(group.key); + groups.unset(group.key); } else { - model.addGroup(group.key); + model.add_group(group.key); } } } - + + public Gee.Map<string, Contact> get_group(string group) { + return groups[group]; + } + private class RosterModel : Object, Gtk.TreeModel { private int stamp = 0; private Gee.Map<String, Gtk.TreeModel> groupModels = new Gee.TreeMap<String, Gtk.TreeModel>(); @@ -101,10 +104,19 @@ public class Roster { contactList = contactList0; } - public void addGroup(string name) { + public void add_group(string name) { + int index = 0; foreach(String group in groupModels.keys) { - if(group.data == name) + if(group.data == name) { + Gtk.TreePath path = new Gtk.TreePath.from_indices(index, -1); + Gtk.TreeIter iter; + get_iter(out iter, path); + row_changed(path, iter); + return; + } + + index++; } Gtk.TreeModel model = new GroupFilter(contactList, name); @@ -119,12 +131,20 @@ public class Roster { model.row_deleted.connect((path) => { path.prepend_index(0); row_deleted(path); - incrementStamp(); + + Gtk.TreePath parent = path.copy(); + parent.up(); + if(parent.get_depth() == 1) { + Gtk.TreeIter iter; + get_iter(out iter, parent); + if(!iter_has_child(iter)) { + row_has_child_toggled(parent, iter); + } + } }); model.row_has_child_toggled.connect((subpath, subiter) => { Gtk.TreePath path = child_path_to_path(name, subpath); - incrementStamp(); Gtk.TreeIter iter; get_iter(out iter, path); row_has_child_toggled(path, iter); @@ -132,15 +152,26 @@ public class Roster { model.row_inserted.connect((subpath, subiter) => { Gtk.TreePath path = child_path_to_path(name, subpath); + incrementStamp(); Gtk.TreeIter iter; get_iter(out iter, path); row_inserted(path, iter); + + Gtk.TreePath parent = path.copy(); + parent.up(); + if(parent.get_depth() == 1) { + get_iter(out iter, parent); + Value value; + get_value(iter, 0, out value); + if(iter_n_children(iter) == 0) { + row_has_child_toggled(parent, iter); + } + } }); model.rows_reordered.connect((subpath, subiter, new_order) => { Gtk.TreePath path = child_path_to_path(name, subpath); - incrementStamp(); Gtk.TreeIter iter; get_iter(out iter, path); rows_reordered(path, iter, new_order); @@ -148,7 +179,7 @@ public class Roster { groupModels[new String(name)] = model; - int index = 0; + index = 0; foreach(String group in groupModels.keys) { if(group.data == name) break; @@ -171,7 +202,7 @@ public class Roster { }); } - public void removeGroup(string name) { + public void remove_group(string name) { int index = 0; foreach(String group in groupModels.keys) { if(group.data == name) { @@ -190,7 +221,7 @@ public class Roster { Gtk.TreePath path = new Gtk.TreePath.from_indices(index, -1); row_deleted(path); - groupModels.remove(group); + groupModels.unset(group); return; } @@ -454,20 +485,14 @@ public class Roster { public void update_contact(Contact c) { ++stamp; bool added = true; - if(c.jid in entries) { + if(c.jid in entries.keys) { added = false; foreach(string group in entries[c.jid].get_groups()) { - if(group in roster.groups) { - roster.groups[group] = roster.groups[group]-1; - } - else { - warn_if_reached(); - } + roster.groups[group].unset(c.jid); } } - entries[c.jid] = c; Gtk.TreeIter iter = Gtk.TreeIter(); @@ -484,10 +509,11 @@ public class Roster { row_changed(path, iter); foreach(string group in c.get_groups()) { - if(!(group in roster.groups)) - roster.groups[group] = 0; - - roster.groups[group] = roster.groups[group]+1; + if(!(group in roster.groups.keys)) { + roster.groups[group] = new Gee.HashMap<string, Contact>(); + } + + roster.groups[group][c.jid] = c; } roster.update_groups(); @@ -632,9 +658,44 @@ public class Roster { if(c == null) return true; - + return (group in c.get_groups()); }); } } + + private class RosterFilter : Gtk.TreeModelFilter { + private unowned Roster roster; + + private bool show_contact(Contact c) { + return (c.get_resource_with_highest_priority() != null); + } + + public RosterFilter(Roster roster0, Gtk.TreeModel childModel) { + Object(child_model: childModel); + roster = roster0; + + set_visible_func((model, iter) => { + Value value; + model.get_value(iter, 0, out value); + + Contact c = value.get_object() as Contact; + + if(c != null) { + return show_contact(c); + } + else { + assert(value.get_object() is String); + string group = (value.get_object() as String).data; + + foreach(Gee.Map.Entry<string, Contact> contact in roster.get_group(group)) { + if(show_contact(contact.value)) + return true; + } + + return false; + } + }); + } + } } |