diff options
-rw-r--r-- | src/core/ephraim_roster.erl | 26 | ||||
-rw-r--r-- | src/gui/CellRendererContact.vala | 3 | ||||
-rw-r--r-- | src/gui/Contact.vala | 16 | ||||
-rw-r--r-- | src/gui/CoreConnector.vala | 15 | ||||
-rw-r--r-- | src/gui/Ephraim.vala | 2 | ||||
-rw-r--r-- | src/gui/Roster.vala | 222 |
6 files changed, 147 insertions, 137 deletions
diff --git a/src/core/ephraim_roster.erl b/src/core/ephraim_roster.erl index 2998782..6360a34 100644 --- a/src/core/ephraim_roster.erl +++ b/src/core/ephraim_roster.erl @@ -51,33 +51,45 @@ updateResource(Roster, JID, Priority, Type, Show, Status) -> end, Roster#roster{entries=Entries}. --spec updateRosterEntry(#roster{}, binary(), binary(), atom()) -> #roster{}. -updateRosterEntry(Roster, JID, Name, Subscription) -> +-spec updateRosterEntry(#roster{}, binary(), binary(), atom(), set()) -> #roster{}. +updateRosterEntry(Roster, JID, Name, Subscription, Groups) -> Resources = case dict:find(JID, Roster#roster.entries) of {ok, Entry} -> Entry#roster_entry.resources; error -> dict:new() end, - Groups = sets:new(), NewEntry = #roster_entry{subscription=Subscription,name=Name,resources=Resources,groups=Groups}, Entries = dict:store(JID, NewEntry, Roster#roster.entries), - ephraim ! {ui_update, {roster_update, JID, dict:to_list(Resources)}}, + ephraim ! {ui_update, {roster_update, JID, Name, Subscription, sets:to_list(Groups), dict:to_list(Resources)}}, Roster#roster{entries=Entries}. +-spec getGroups([#xmlel{}]) -> set(). +getGroups(Els) -> + getGroups(sets:new(), Els). + +-spec getGroups(set(), [#xmlel{}]) -> set(). +getGroups(Groups, []) -> + Groups; +getGroups(Groups, [#xmlel{ns='jabber:iq:roster',name=group,children=[#xmlcdata{cdata=Group}]}|Rest]) -> + getGroups(sets:add_element(Group, Groups), Rest); +getGroups(Groups, [_|Rest]) -> + getGroups(Groups, Rest). + -spec handleRosterIQ(#roster{}, #xmlel{}) -> #roster{}. handleRosterIQ(Roster, Item) -> JID = exmpp_xml:get_attribute(Item, jid, undefined), Name = exmpp_xml:get_attribute(Item, name, undefined), + Groups = getGroups(Item#xmlel.children), Subscription = binary_to_atom(exmpp_xml:get_attribute(Item, subscription, undefined), utf8), - updateRosterEntry(Roster, JID, Name, Subscription). + updateRosterEntry(Roster, JID, Name, Subscription, Groups). -spec handleRosterIQs(#roster{}, [#xmlel{}]) -> #roster{}. handleRosterIQs(Roster, []) -> Roster; -handleRosterIQs(Roster, [Item = #xmlel{name=item}|Rest]) -> +handleRosterIQs(Roster, [Item = #xmlel{ns='jabber:iq:roster',name=item}|Rest]) -> Roster2 = handleRosterIQ(Roster, Item), handleRosterIQs(Roster2, Rest); @@ -103,7 +115,7 @@ loop(Roster) -> {roster_iq, Payload} -> Roster2 = handleRosterIQs(Roster, Payload#xmlel.children), - io:format("ephraim_roster: IQ: ~p~n", [Payload]), + %io:format("ephraim_roster: IQ: ~p~n", [Payload]), loop(Roster2); Msg -> diff --git a/src/gui/CellRendererContact.vala b/src/gui/CellRendererContact.vala index f8aa6a1..7efe8cc 100644 --- a/src/gui/CellRendererContact.vala +++ b/src/gui/CellRendererContact.vala @@ -7,7 +7,8 @@ public class CellRendererContact : Gtk.CellRendererText { } set { _contact = value; - text = contact.jid; + + text = contact.display_string; } } } diff --git a/src/gui/Contact.vala b/src/gui/Contact.vala index 2eb40ae..1db1e62 100644 --- a/src/gui/Contact.vala +++ b/src/gui/Contact.vala @@ -7,8 +7,8 @@ public class Contact : Object { BOTH } - public Contact(string jid0) { - Object(jid: jid0); + public Contact(string jid0, string? name0) { + Object(jid: jid0, name: name0); } public class Resource : Object { @@ -18,7 +18,17 @@ public class Contact : Object { } public string jid {get; construct;} + public string? name {get; construct;} public Subscription subscription {get; set;} - public string name {get; set;} + public Gee.TreeSet<string> groups; public Gee.HashMap<string, Resource> resources {get; private set;} + + public string display_string { + get { + if (name != null) + return name; + else + return jid; + } + } } diff --git a/src/gui/CoreConnector.vala b/src/gui/CoreConnector.vala index fdd74ee..7486aec 100644 --- a/src/gui/CoreConnector.vala +++ b/src/gui/CoreConnector.vala @@ -90,11 +90,18 @@ public class CoreConnector { unowned Erl.Term term = store.term; Erl.Term match_term; - if((match_term = match("{roster_update,JID,Resources}", term)) != null) { - Erl.Term JID_term = match_term.var_content("JID"); - string JID = ((string)JID_term.bin_ptr()).ndup(JID_term.bin_size()); + if((match_term = match("{roster_update,JID,Name,Subscription,Groups,Resources}", term)) != null) { + Erl.Term jid_term = match_term.var_content("JID"); + string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); - roster.update_contact(new Contact(JID)); + Erl.Term name_term = match_term.var_content("Name"); + string? name; + if (name_term.is_binary()) + name = ((string)name_term.bin_ptr()).ndup(name_term.bin_size()); + else + name = null; + + roster.update_contact(new Contact(jid, name)); } else { Erl.print_term(stdout, term); diff --git a/src/gui/Ephraim.vala b/src/gui/Ephraim.vala index cf87965..0b50ff4 100644 --- a/src/gui/Ephraim.vala +++ b/src/gui/Ephraim.vala @@ -22,7 +22,7 @@ public class Ephraim { quitItem.activate.connect(() => window.visible = false); unowned Gtk.TreeView rosterView = builder.get_object("Roster") as Gtk.TreeView; - rosterView.set_model(roster.get_default_group()); + rosterView.set_model(roster); rosterView.append_column(new Gtk.TreeViewColumn.with_attributes("Contact", new CellRendererContact(), "contact", 0, null)); diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala index 2ef4618..bd6b663 100644 --- a/src/gui/Roster.vala +++ b/src/gui/Roster.vala @@ -1,166 +1,146 @@ -public class Roster : Object { +public class Roster : Object, Gtk.TreeModel { 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); + ++stamp; + bool added = !entries.has_key(c.jid); - entries[c.jid] = c; + entries[c.jid] = c; - Gtk.TreeIter iter = Gtk.TreeIter(); - iter.stamp = roster.stamp; - iter.user_data = this; - iter.user_data2 = c; + Gtk.TreeIter iter = Gtk.TreeIter(); + iter.stamp = stamp; + iter.user_data = this; + iter.user_data2 = c; - Gtk.TreePath path = get_path(iter); + 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); - } + if (added) + row_inserted(path, iter); + else + row_changed(path, iter); + } - return Type.INVALID; + public Type get_column_type (int index) { + switch(index) { + case 0: + return typeof(Contact); } - public Gtk.TreeModelFlags get_flags () { - return Gtk.TreeModelFlags.LIST_ONLY; - } + 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; + 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; + 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(); + 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(); + iter.stamp = stamp; + iter.user_data = this; + iter.user_data2 = it.get_value(); - return true; - } + return true; + } - public int get_n_columns () { - return 1; - } + 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; + public Gtk.TreePath get_path (Gtk.TreeIter iter) { + if(iter.stamp != stamp || iter.user_data != this) + return (Gtk.TreePath)null; - int index = 0; + int index = 0; - foreach(Contact c in entries.values) { - if(c == iter.user_data2) - break; + foreach(Contact c in entries.values) { + if(c == iter.user_data2) + break; - ++index; - } - - return new Gtk.TreePath.from_indices(index, -1); + ++index; } - - 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); - } + return new Gtk.TreePath.from_indices(index, -1); + } - public bool iter_children (out Gtk.TreeIter iter, Gtk.TreeIter? parent) { - if (parent != null) { - iter.stamp = -1; - return false; - } + public void get_value (Gtk.TreeIter iter, int column, out Value value) { + if (column != 0 || iter.stamp != stamp || iter.user_data != this) + return; - return get_iter(out iter, new Gtk.TreePath.from_indices(0, -1)); - } + Contact c = iter.user_data2 as Contact; + value = Value(typeof(Contact)); + value.take_object(c); + } - public bool iter_has_child (Gtk.TreeIter iter) { + 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 int iter_n_children (Gtk.TreeIter? iter) { - if (iter == null) - return entries.size; - else - return 0; - } + public bool iter_has_child (Gtk.TreeIter iter) { + return false; + } - 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 int iter_n_children (Gtk.TreeIter? iter) { + if (iter == null) + return entries.size; + else + return 0; + } - public bool iter_nth_child (out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n) { - if (parent != null) { - iter.stamp = -1; - return false; - } + public bool iter_next (ref Gtk.TreeIter iter) { + if(iter.stamp != stamp || iter.user_data != this) + return false; - return get_iter(out iter, new Gtk.TreePath.from_indices(n, -1)); + 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_parent (out Gtk.TreeIter iter, Gtk.TreeIter child) { + 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 void ref_node (Gtk.TreeIter iter) {} - public void unref_node (Gtk.TreeIter iter) {} + 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) {} } |