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.vala125
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;
+ }
+ });
+ }
+ }
}