summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2010-07-28 00:00:37 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2010-07-28 00:00:37 +0200
commit00e8a7d9d07e87a31e3086c2e2e3f71107cbafdb (patch)
tree744876c3c6fd953e9c1edd25fc580c95ceee6fcc
parent69aaef2680ff5c96b34ad983b665a80c06c20224 (diff)
downloadephraim-00e8a7d9d07e87a31e3086c2e2e3f71107cbafdb.tar
ephraim-00e8a7d9d07e87a31e3086c2e2e3f71107cbafdb.zip
Revised roster groups (still unfinished)
-rw-r--r--data/ephraim.glade15
-rw-r--r--src/core/ephraim_roster.erl2
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/CellRendererContact.vala27
-rw-r--r--src/gui/Conversation.vala4
-rw-r--r--src/gui/Ephraim.vala9
-rw-r--r--src/gui/Roster.vala535
-rw-r--r--src/gui/String.vala7
8 files changed, 423 insertions, 177 deletions
diff --git a/data/ephraim.glade b/data/ephraim.glade
index cde3c10..5535b26 100644
--- a/data/ephraim.glade
+++ b/data/ephraim.glade
@@ -84,18 +84,11 @@
<property name="visible">True</property>
<property name="resize_mode">queue</property>
<child>
- <object class="GtkVBox" id="Roster">
+ <object class="GtkTreeView" id="Roster">
<property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
</object>
</child>
</object>
diff --git a/src/core/ephraim_roster.erl b/src/core/ephraim_roster.erl
index b0fa7cf..e9eb9f8 100644
--- a/src/core/ephraim_roster.erl
+++ b/src/core/ephraim_roster.erl
@@ -168,7 +168,7 @@ get_alias(Roster, JID) ->
{ok, Entry} ->
case Entry#roster_entry.name of
undefined ->
- case dict:find('NICKNAME',Entry#roster_entry.vcard) of
+ case dict:find('NICKNAME', Entry#roster_entry.vcard) of
{ok, Value} ->
Value;
error ->
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index ac62f9a..e446c77 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -9,6 +9,7 @@ vala_precompile(VALA_C
"Conversation.vala"
"CoreConnector.vala"
"Roster.vala"
+ "String.vala"
PACKAGES
gtk+-2.0
gee-1.0
diff --git a/src/gui/CellRendererContact.vala b/src/gui/CellRendererContact.vala
index 5c7d2e9..d7d9309 100644
--- a/src/gui/CellRendererContact.vala
+++ b/src/gui/CellRendererContact.vala
@@ -1,21 +1,28 @@
public class CellRendererContact : Gtk.CellRendererText {
- private Contact _contact;
+ private Object _data;
- public Contact contact {
+ public Object data {
get {
- return _contact;
+ return _data;
}
set {
- _contact = value;
+ _data = value;
- string str = Markup.escape_text(contact.display_string);
+ if(_data is Contact) {
+ Contact contact = _data as Contact;
+
+ string str = Markup.escape_text(contact.display_string);
- Gee.Map.Entry<string, Contact.Resource> res = contact.get_resource_with_highest_priority();
- if(res != null && res.value.status != null) {
- str += "\n<span size=\"small\" fgcolor=\"grey40\" style=\"italic\">" + Markup.escape_text(res.value.status) + "</span>";
- }
+ Gee.Map.Entry<string, Contact.Resource> res = contact.get_resource_with_highest_priority();
+ if(res != null && res.value.status != null) {
+ str += "\n<span size=\"small\" fgcolor=\"grey40\" style=\"italic\">" + Markup.escape_text(res.value.status) + "</span>";
+ }
- markup = str;
+ markup = str;
+ }
+ else if(_data is String) {
+ markup = Markup.escape_text((_data as String).data);
+ }
}
}
diff --git a/src/gui/Conversation.vala b/src/gui/Conversation.vala
index 246aba0..7c8dc03 100644
--- a/src/gui/Conversation.vala
+++ b/src/gui/Conversation.vala
@@ -3,7 +3,6 @@ public class Conversation {
private Gtk.Widget widget;
private Gtk.TextView content;
private Gtk.Entry entry;
- private string me;
private string jid;
private string display_name;
@@ -25,9 +24,8 @@ public class Conversation {
}
}
- public Conversation(Gtk.Notebook conversations0, string me0, string jid0, string? display_name0, bool explicit = true) {
+ public Conversation(Gtk.Notebook conversations0, string jid0, string? display_name0, bool explicit = true) {
conversations = conversations0;
- me = me0;
jid = jid0;
if(display_name0 != null)
diff --git a/src/gui/Ephraim.vala b/src/gui/Ephraim.vala
index c75d926..f13516e 100644
--- a/src/gui/Ephraim.vala
+++ b/src/gui/Ephraim.vala
@@ -15,16 +15,13 @@ public class Ephraim {
unowned Gtk.MenuItem quitItem = builder.get_object("MenuItemQuit") as Gtk.MenuItem;
quitItem.activate.connect(() => window.visible = false);
- unowned Gtk.VBox rosterView = builder.get_object("Roster") as Gtk.VBox;
+ unowned Gtk.TreeView rosterView = builder.get_object("Roster") as Gtk.TreeView;
Gee.TreeMap<string, Conversation> conversations = new Gee.TreeMap<string, Conversation>();
unowned Gtk.Notebook conversationNotebook = builder.get_object("Conversations") as Gtk.Notebook;
Roster roster = new Roster(rosterView);
- // FIXME
- string me = "/me";
-
CoreConnector coreconn = new CoreConnector();
roster.start_conversation.connect((jid) => coreconn.start_conversation(jid));
@@ -35,10 +32,10 @@ public class Ephraim {
Contact contact = roster.get_contact(jid);
if(contact != null) {
- conversations[jid] = new Conversation(conversationNotebook, me, jid, contact.display_string);
+ conversations[jid] = new Conversation(conversationNotebook, jid, contact.display_string);
}
else {
- conversations[jid] = new Conversation(conversationNotebook, me, jid, null);
+ conversations[jid] = new Conversation(conversationNotebook, jid, null);
}
conversations[jid].send_message.connect((type, message) => coreconn.send_message(jid, type, message));
diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala
index 65119e2..feb4fd3 100644
--- a/src/gui/Roster.vala
+++ b/src/gui/Roster.vala
@@ -1,130 +1,381 @@
public class Roster {
- private Gtk.VBox rosterView;
+ private Gtk.TreeView rosterView;
+ private ContactListModel contactList;
private RosterModel model;
- private Gee.TreeMap<string, GroupInfo> groups = new Gee.TreeMap<string, GroupInfo>();
-
+ private Gee.Map<string, int> groups = new Gee.HashMap<string, int>();
+
public signal void start_conversation(string jid);
-
-
- public Roster(Gtk.VBox rosterView0) {
+
+
+ public Roster(Gtk.TreeView rosterView0) {
rosterView = rosterView0;
- model = new RosterModel(this);
- }
-
- public Gtk.TreeModel get_model() {
- return model;
- }
-
- public void update_contact(Contact c) {
- model.update_contact(c);
- }
-
- public Contact get_contact(string jid) {
- return model.get_contact(jid);
- }
-
- private Gtk.TreeView new_tree_view() {
- Gtk.TreeView view = new Gtk.TreeView();
-
- view.headers_visible = false;
-
- view.query_tooltip.connect((x, y, keyboard_tip, tooltip) => {
+ contactList = new ContactListModel(this);
+ model = new RosterModel(contactList);
+
+ rosterView.set_model(model);
+
+ rosterView.query_tooltip.connect((x, y, keyboard_tip, tooltip) => {
Gtk.TreeModel model;
Gtk.TreeIter iter;
-
- if(!view.get_tooltip_context(out x, out y, keyboard_tip, out model, null, out iter))
+
+ if(!rosterView.get_tooltip_context(out x, out y, keyboard_tip, out model, null, out iter))
return false;
-
+
Value value;
model.get_value(iter, 0, out value);
-
+
Contact? c = value.get_object() as Contact;
if(c == null)
return false;
-
+
Gee.Map.Entry<string, Contact.Resource>? r = c.get_resource_with_highest_priority();
-
+
if(r == null)
return false;
-
+
tooltip.set_text("Resource: " + r.key + " (" + r.value.priority.to_string() + ")");
-
+
return true;
});
- view.has_tooltip = true;
-
- view.row_activated.connect((view, path, column) => {
+ rosterView.has_tooltip = true;
+
+ rosterView.row_activated.connect((view, path, column) => {
Gtk.TreeIter iter;
view.model.get_iter(out iter, path);
-
+
Value value;
view.model.get_value(iter, 0, out value);
-
+
Contact contact = value.get_object() as Contact;
if(contact == null)
return;
-
+
Gee.Map.Entry<string, Contact.Resource> res = contact.get_resource_with_highest_priority();
if(res == null)
return; //FIXME
-
+
start_conversation(contact.jid + "/" + res.key);
});
+
+ 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);
+ }
+
+ public Contact get_contact(string jid) {
+ return contactList.get_contact(jid);
+ }
+
+ private void update_groups() {
+ foreach(Gee.Map.Entry<string, int> group in groups) {
+ if(group.value <= 0) {
+ //rosterView.remove(group.value.expander);
+ continue;
+ }
+
+
+ }
+ }
+
+ private class RosterModel : Object, Gtk.TreeModel {
+ private int stamp = 0;
+ private Gee.Map<String, Gtk.TreeModel> groupModels = new Gee.TreeMap<String, Gtk.TreeModel>();
+ private Gee.ArrayList<Gtk.TreeIter?> childIters = new Gee.ArrayList<Gtk.TreeIter?>();
+ private ContactListModel contactList;
+
+
+ public RosterModel(ContactListModel contactList0) {
+ contactList = contactList0;
+
+ groupModels[new String("Test")] = contactList;
+
+ contactList.row_changed.connect((subpath, subiter) => {
+ Gtk.TreePath path = child_path_to_path("Test", subpath);
+ stamp++;
+ Gtk.TreeIter iter;
+ get_iter(out iter, path);
+ row_changed(path, iter);
+ });
+
+ contactList.row_deleted.connect((path) => {
+ stamp++;
+ path.prepend_index(0);
+ row_deleted(path);
+ });
+
+ contactList.row_has_child_toggled.connect((subpath, subiter) => {
+ Gtk.TreePath path = child_path_to_path("Test", subpath);
+ stamp++;
+ 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++;
+ 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++;
+ Gtk.TreeIter iter;
+ get_iter(out iter, path);
+ rows_reordered(path, iter, new_order);
+ });
+ }
- Gtk.TreeViewColumn presenceColumn = new Gtk.TreeViewColumn.with_attributes(null, new CellRendererPresence(), "contact", 0, null);
- presenceColumn.min_width = 32;
- view.append_column(presenceColumn);
-
- Gtk.TreeViewColumn contactColumn = new Gtk.TreeViewColumn();
+ private Gtk.TreePath child_path_to_path(string group, Gtk.TreePath childPath) {
+ Gtk.TreePath path = childPath.copy();
+ path.prepend_index(0);
+ return path;
+ }
- Gtk.CellRenderer cellRendererContact = new CellRendererContact();
- contactColumn.pack_start(cellRendererContact, true);
- contactColumn.set_attributes(cellRendererContact, "contact", 0, null);
+ 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);
+ }
+ else {
+ childIters.add(iter);
+ stderr.printf("Added child iter %i\r\n", childIters.size-1);
+ return childIters.size-1;
+ }
+ }
- Gtk.CellRenderer cellRendererAvatar = new CellRendererAvatar();
- contactColumn.pack_end(cellRendererAvatar, false);
- contactColumn.set_attributes(cellRendererAvatar, "contact", 0, null);
+ private Gtk.TreeIter get_nth_child_iter(int n) {
+ return childIters[n];
+ }
- view.append_column(contactColumn);
+ private Gtk.TreeIter? get_child_iter(Gtk.TreeIter iter) {
+ assert(iter.stamp == stamp && iter.user_data == this);
+ if((int)iter.user_data3 != -1)
+ return get_nth_child_iter((int)iter.user_data3);
+ else
+ return null;
+ }
- return view;
- }
-
- private void update_groups() {
- int i = 0;
+ private Gtk.TreeModel get_child_model(Gtk.TreeIter iter) {
+ assert(iter.stamp == stamp && iter.user_data == this);
+ return groupModels[iter.user_data2 as String];
+ }
- foreach(Gee.Map.Entry<string, GroupInfo> group in groups) {
- if(group.value.count <= 0) {
- rosterView.remove(group.value.expander);
- group.value.expander.remove(group.value.view);
- groups.remove(group.key);
- continue;
+ public Type get_column_type(int index) {
+ switch(index) {
+ case 0:
+ return typeof(Object);
+ }
+
+ assert_not_reached();
+ }
+
+ public Gtk.TreeModelFlags get_flags() {
+ return 0;
+ }
+
+ public bool get_iter(out Gtk.TreeIter iter, Gtk.TreePath path) {
+ 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)
+ return false;
+
+ Gee.MapIterator<String, Gtk.TreeModel> it = groupModels.map_iterator();
+ it.first();
+ for(int i = 0; i < index; ++i)
+ it.next();
+
+ iter.stamp = stamp;
+ iter.user_data = this;
+ iter.user_data2 = it.get_key();
+ iter.user_data3 = (void*)(-1);
+
+ if(path.get_depth() > 1) {
+ Gtk.TreePath subpath = new Gtk.TreePath();
+ for(int i = 1; i < path.get_depth(); ++i) {
+ subpath.append_index(indices[i]);
+ }
+
+ Gtk.TreeIter subiter;
+
+ if(!it.get_value().get_iter(out subiter, subpath))
+ return false;
+
+ iter.user_data3 = (void*)child_iter_index(subiter);
+ }
+
+ return true;
+ }
+
+ public int get_n_columns() {
+ return 1;
+ }
+
+ 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;
+
+ foreach(String group in groupModels.keys) {
+ if(group == iter.user_data2)
+ break;
+
+ ++index;
+ }
+
+ Gtk.TreePath subpath = new Gtk.TreePath();
+
+ 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);
+ }
+ else {
+ get_child_model(iter).get_value(get_child_iter(iter), 0, out value);
+ }
+ }
+
+ public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent) {
+ if (parent == null) {
+ return get_iter(out iter, new Gtk.TreePath.from_indices(0, -1));
+ }
+
+ assert(parent.stamp == stamp && parent.user_data == this);
+
+ Gtk.TreeIter childIter;
+ if(!get_child_model(parent).iter_children(out childIter, get_child_iter(parent)))
+ return false;
+
+ iter.stamp = stamp;
+ iter.user_data = this;
+ iter.user_data2 = parent.user_data2;
+ iter.user_data3 = (void*)child_iter_index(childIter);
+
+ return true;
+ }
+
+ public bool iter_has_child(Gtk.TreeIter iter) {
+ assert(iter.stamp == stamp && iter.user_data == this);
+
+ return (iter_n_children(iter) > 0);
+ }
+
+ public int iter_n_children(Gtk.TreeIter? iter) {
+ if (iter == null)
+ return groupModels.size;
+
+ assert(iter.stamp == stamp && iter.user_data == this);
+
+ return get_child_model(iter).iter_n_children(get_child_iter(iter));
+ }
+
+ public bool iter_next(ref Gtk.TreeIter iter) {
+ assert(iter.stamp == stamp && iter.user_data == this);
+
+ if((int)iter.user_data3 == -1) {
+ bool next = false;
+ foreach(String group in groupModels.keys) {
+ if(next) {
+ iter.user_data2 = group;
+ return true;
+ }
+
+ if(group == iter.user_data2)
+ next = true;
+ }
+
+ iter.stamp = -1;
+ return false;
+ }
+
+ else {
+ Gtk.TreeModel m = get_child_model(iter);
+ Gtk.TreeIter subiter = get_child_iter(iter);
+ if(!m.iter_next(ref subiter)) {
+ iter.stamp = -1;
+ return false;
+ }
+
+ iter.user_data3 = (void*)child_iter_index(subiter);
+ return true;
+ }
+ }
+
+ public bool iter_nth_child(out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n) {
+ if (parent == null) {
+ return get_iter(out iter, new Gtk.TreePath.from_indices(n, -1));
+ }
+ else {
+ Gtk.TreePath path = get_path(parent);
+ path.append_index(n);
+ return get_iter(out iter, path);
}
+ }
+
+ public bool iter_parent(out Gtk.TreeIter iter, Gtk.TreeIter child) {
+ assert(child.stamp == stamp && child.user_data == this);
- if(group.value.count > 0 && group.value.view == null) {
- group.value.view = new_tree_view();
- group.value.view.model = new GroupFilter(this, group.key);
-
- group.value.expander = new Gtk.Expander("<i>" + Markup.escape_text(group.key) + "</i>");
- group.value.expander.set_use_markup(true);
- group.value.expander.expanded = true;
- group.value.expander.add(group.value.view);
- group.value.expander.show_all();
-
- rosterView.pack_start(group.value.expander, false, false, 0);
+ if((int)child.user_data3 == -1) {
+ iter.stamp = -1;
+ return false;
+ }
+
+ iter.stamp = stamp;
+ iter.user_data = this;
+ iter.user_data2 = child.user_data2;
+
+ Gtk.TreeIter childParent;
+ if(get_child_model(child).iter_parent(out childParent, get_child_iter(child))) {
+ iter.user_data3 = (void*)child_iter_index(childParent);
+ }
+ else {
+ iter.user_data3 = (void*)(-1);
}
- rosterView.reorder_child(group.value.expander, i++);
+ return true;
}
+
+ public void ref_node(Gtk.TreeIter iter) {}
+ public void unref_node(Gtk.TreeIter iter) {}
}
-
- private class RosterModel : Object, Gtk.TreeModel {
- private Roster roster;
+
+ private class ContactListModel : Object, Gtk.TreeModel {
+ private unowned Roster roster;
private int stamp = 0;
private Gee.TreeMap<string, Contact> entries = new Gee.TreeMap<string, Contact>();
-
-
- public RosterModel(Roster roster0) {
+
+
+ public ContactListModel(Roster roster0) {
roster = roster0;
}
@@ -133,27 +384,28 @@ public class Roster {
bool added = true;
if(c.jid in entries) {
added = false;
-
+
foreach(string group in entries[c.jid].get_groups()) {
if(group in roster.groups) {
- roster.groups[group].count--;
+ roster.groups[group] = roster.groups[group]-1;
}
else {
warn_if_reached();
}
}
}
-
-
+
+
entries[c.jid] = c;
-
+
Gtk.TreeIter iter = Gtk.TreeIter();
iter.stamp = stamp;
iter.user_data = this;
iter.user_data2 = c;
-
+ iter.user_data3 = null;
+
Gtk.TreePath path = get_path(iter);
-
+
if(added)
row_inserted(path, iter);
else
@@ -161,17 +413,17 @@ public class Roster {
foreach(string group in c.get_groups()) {
if(!(group in roster.groups))
- roster.groups[group] = new GroupInfo();
-
- roster.groups[group].count++;
+ roster.groups[group] = 0;
+
+ roster.groups[group] = roster.groups[group]+1;
}
-
+
roster.update_groups();
}
-
+
public Contact get_contact(string jid) {
string bareJID = jid.split("/", 2)[0];
-
+
return entries[bareJID];
}
@@ -180,149 +432,140 @@ public class Roster {
case 0:
return typeof(Contact);
}
-
- return Type.INVALID;
+
+ assert_not_reached();
}
-
+
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 = stamp;
iter.user_data = this;
iter.user_data2 = it.get_value();
-
+ iter.user_data3 = null;
+
return true;
}
-
+
public int get_n_columns() {
return 1;
}
-
+
public Gtk.TreePath get_path(Gtk.TreeIter iter) {
- if(iter.stamp != stamp || iter.user_data != this)
- return (Gtk.TreePath)null;
-
+ assert(iter.stamp == stamp && iter.user_data == this);
+
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 != stamp || iter.user_data != this) {
- value = Value(Type.INVALID);
- return;
- }
-
+ 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;
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 != stamp || iter.user_data != this)
- return false;
-
+ assert(iter.stamp == stamp && iter.user_data == this);
+
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) {}
- }
-
+ }
+
private class GroupFilter : Gtk.TreeModelFilter {
private Roster roster;
private string group;
-
+
public GroupFilter(Roster roster0, string group0) {
Object(child_model: roster0.model);
-
+
roster = roster0;
group = group0;
-
+
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 true;
-
+
return (group in c.get_groups());
});
}
}
-
- private class GroupInfo {
- public int count = 0;
- public Gtk.Expander expander = null;
- public Gtk.TreeView view = null;
- }
}
diff --git a/src/gui/String.vala b/src/gui/String.vala
new file mode 100644
index 0000000..5d1520f
--- /dev/null
+++ b/src/gui/String.vala
@@ -0,0 +1,7 @@
+public class String : Object {
+ public string data {get; construct;}
+
+ public String(string data0) {
+ Object(data: data0);
+ }
+}