From 38a9cf9209e8960e93631d757a3b6e974222307a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 28 Jul 2010 02:54:51 +0200 Subject: Roster groups are now displayed correctly. --- src/core/ephraim_roster.erl | 7 +- src/gui/Roster.vala | 175 ++++++++++++++++++++++++++++++-------------- 2 files changed, 127 insertions(+), 55 deletions(-) diff --git a/src/core/ephraim_roster.erl b/src/core/ephraim_roster.erl index e9eb9f8..e0a1da6 100644 --- a/src/core/ephraim_roster.erl +++ b/src/core/ephraim_roster.erl @@ -146,10 +146,13 @@ handleRosterIQs(Roster, [_|Rest]) -> handleRosterIQs(Roster, Rest). --spec handleVCardIQ(dict(), #xmlel{}) -> dict(). +-spec handleVCardIQ(dict(), #xmlel{}|#xmlcdata{}) -> dict(). handleVCardIQ(Dict, Item=#xmlel{name=Key}) -> Value = exmpp_xml:get_cdata(Item), - dict:store(Key, Value, Dict). + dict:store(Key, Value, Dict); + +handleVCardIQ(Dict, #xmlcdata{}) -> + Dict. -spec handleVCardIQs(dict(), [#xmlel{}]) -> dict(). handleVCardIQs(VCard, []) -> diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala index feb4fd3..ca1ef16 100644 --- a/src/gui/Roster.vala +++ b/src/gui/Roster.vala @@ -56,15 +56,15 @@ public class Roster { start_conversation(contact.jid + "/" + res.key); }); - + + model.row_inserted.connect((path, iter) => { + rosterView.expand_to_path(path); + }); + Gtk.TreeViewColumn contactColumn = new Gtk.TreeViewColumn.with_attributes(null, new CellRendererContact(), "data", 0, null); rosterView.append_column(contactColumn); } - - public Gtk.TreeModel get_model() { - return model; - } - + public void update_contact(Contact c) { contactList.update_contact(c); } @@ -76,11 +76,12 @@ public class Roster { private void update_groups() { foreach(Gee.Map.Entry group in groups) { if(group.value <= 0) { - //rosterView.remove(group.value.expander); - continue; + model.removeGroup(group.key); + groups.remove(group.key); + } + else { + model.addGroup(group.key); } - - } } @@ -90,67 +91,146 @@ public class Roster { private Gee.ArrayList childIters = new Gee.ArrayList(); private ContactListModel contactList; - + + private void incrementStamp() { + stamp++; + childIters.clear(); + } + public RosterModel(ContactListModel contactList0) { contactList = contactList0; + } + + public void addGroup(string name) { + foreach(String group in groupModels.keys) { + if(group.data == name) + return; + } - groupModels[new String("Test")] = contactList; - - contactList.row_changed.connect((subpath, subiter) => { - Gtk.TreePath path = child_path_to_path("Test", subpath); - stamp++; + Gtk.TreeModel model = new GroupFilter(contactList, name); + + model.row_changed.connect((subpath, subiter) => { + Gtk.TreePath path = child_path_to_path(name, subpath); Gtk.TreeIter iter; get_iter(out iter, path); row_changed(path, iter); }); - contactList.row_deleted.connect((path) => { - stamp++; + model.row_deleted.connect((path) => { path.prepend_index(0); row_deleted(path); + incrementStamp(); }); - contactList.row_has_child_toggled.connect((subpath, subiter) => { - Gtk.TreePath path = child_path_to_path("Test", subpath); - stamp++; + 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); }); - contactList.row_inserted.connect((subpath, subiter) => { - Gtk.TreePath path = child_path_to_path("Test", subpath); - stamp++; + 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); }); - contactList.rows_reordered.connect((subpath, subiter, new_order) => { - Gtk.TreePath path = child_path_to_path("Test", subpath); - stamp++; + 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); }); + + groupModels[new String(name)] = model; + + int index = 0; + foreach(String group in groupModels.keys) { + if(group.data == name) + break; + + index++; + } + + Gtk.TreePath path = new Gtk.TreePath.from_indices(index, -1); + Gtk.TreeIter iter; + get_iter(out iter, path); + row_inserted(path, iter); + + model.foreach((childModel, childPath, childIter) => { + Gtk.TreePath subpath = child_path_to_path(name, childPath); + Gtk.TreeIter subiter; + get_iter(out subiter, subpath); + row_inserted(subpath, subiter); + + return false; + }); } - private Gtk.TreePath child_path_to_path(string group, Gtk.TreePath childPath) { - Gtk.TreePath path = childPath.copy(); - path.prepend_index(0); - return path; + public void removeGroup(string name) { + int index = 0; + foreach(String group in groupModels.keys) { + if(group.data == name) { + Gee.LinkedList children = new Gee.LinkedList(); + + groupModels[group].foreach((childModel, childPath, childIter) => { + children.offer_head(childPath); + + return false; + }); + + while(!children.is_empty) { + row_deleted(child_path_to_path(name, children.poll_head())); + } + + Gtk.TreePath path = new Gtk.TreePath.from_indices(index, -1); + row_deleted(path); + + groupModels.remove(group); + + return; + } + + index++; + } } - private int child_iter_index(Gtk.TreeIter iter) { - if(iter in childIters) { - stderr.printf("Reusing child iter %i\r\n", childIters.index_of(iter)); - return childIters.index_of(iter); + private Gtk.TreePath child_path_to_path(string groupName, Gtk.TreePath childPath) { + int index = 0; + foreach(String group in groupModels.keys) { + if(group.data == groupName) { + Gtk.TreePath path = childPath.copy(); + path.prepend_index(index); + + return path; + } + + index++; } - else { - childIters.add(iter); - stderr.printf("Added child iter %i\r\n", childIters.size-1); - return childIters.size-1; + + assert_not_reached(); + } + + private int child_iter_index(Gtk.TreeIter iter) { + for(int index = 0; index < childIters.size; ++index) { + if(childIters[index].stamp != iter.stamp) + continue; + if(childIters[index].user_data != iter.user_data) + continue; + if(childIters[index].user_data2 != iter.user_data2) + continue; + if(childIters[index].user_data3 != iter.user_data3) + continue; + + return index; } + + childIters.add(iter); + return childIters.size-1; } private Gtk.TreeIter get_nth_child_iter(int n) { @@ -187,8 +267,6 @@ public class Roster { if(path.get_depth() == 0) return false; - stderr.printf("Called get_iter for path %s\r\n", path.to_string()); - unowned int[] indices = path.get_indices(); int index = indices[0]; if(index < 0 || index >= groupModels.size) @@ -226,7 +304,6 @@ public class Roster { } public Gtk.TreePath get_path(Gtk.TreeIter iter) { - stderr.printf("get_path: %i %p %p %i\r\n", iter.stamp, iter.user_data, iter.user_data2, (int)iter.user_data3); assert(iter.stamp == stamp && iter.user_data == this); int index = 0; @@ -242,20 +319,15 @@ public class Roster { if((int)iter.user_data3 != -1) { Gtk.TreeIter subiter = get_child_iter(iter); - stderr.printf("get_path: subiter: %i %p %p %i\r\n", subiter.stamp, subiter.user_data, subiter.user_data2, (int)subiter.user_data3); subpath = get_child_model(iter).get_path(subiter); } subpath.prepend_index(index); - stderr.printf("Returning path %s\r\n", subpath.to_string()); return subpath; } public void get_value(Gtk.TreeIter iter, int column, out Value value) { - stderr.printf("get_value: iter=%i %p %p %i, column=%i\r\n", iter.stamp, iter.user_data, iter.user_data2, (int)iter.user_data3, column); assert (column == 0 && iter.stamp == stamp && iter.user_data == this); - stderr.printf("Getting value %s\r\n", get_path(iter).to_string()); - if((int)iter.user_data3 == -1) { value = Value(typeof(String)); value.take_object(iter.user_data2 as String); @@ -374,7 +446,7 @@ public class Roster { private int stamp = 0; private Gee.TreeMap entries = new Gee.TreeMap(); - + public ContactListModel(Roster roster0) { roster = roster0; } @@ -481,7 +553,6 @@ public class Roster { } public void get_value(Gtk.TreeIter iter, int column, out Value value) { - stderr.printf("get_value2: iter=%i %p %p %i, column=%i\r\n", iter.stamp, iter.user_data, iter.user_data2, (int)iter.user_data3, column); assert (column == 0 && iter.stamp == stamp && iter.user_data == this); Contact c = iter.user_data2 as Contact; @@ -546,13 +617,11 @@ public class Roster { } private class GroupFilter : Gtk.TreeModelFilter { - private Roster roster; private string group; - public GroupFilter(Roster roster0, string group0) { - Object(child_model: roster0.model); + public GroupFilter(Gtk.TreeModel childModel, string group0) { + Object(child_model: childModel); - roster = roster0; group = group0; set_visible_func((model, iter) => { -- cgit v1.2.3