[gnome-contacts/wip/sorted: 6/8] Initial use of ContactsSorted for view



commit bd8316edee5834ba1a0435e3e7df314a892fbbbd
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Feb 20 01:11:49 2012 +0100

    Initial use of ContactsSorted for view

 src/Makefile.am               |    1 +
 src/contacts-link-dialog.vala |    2 +-
 src/contacts-list-pane.vala   |    3 +-
 src/contacts-sorted.vala      |   99 ++++++---
 src/contacts-view.vala        |  478 +++++++++--------------------------------
 5 files changed, 174 insertions(+), 409 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index f8423da..66bc8a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,7 @@ vala_sources = \
 	contacts-linking.vala \
 	contacts-menu-button.vala \
 	contacts-row.vala \
+	contacts-sorted.vala \
 	contacts-store.vala \
 	contacts-view.vala \
 	contacts-utils.vala \
diff --git a/src/contacts-link-dialog.vala b/src/contacts-link-dialog.vala
index 03a61d4..186de24 100644
--- a/src/contacts-link-dialog.vala
+++ b/src/contacts-link-dialog.vala
@@ -220,7 +220,7 @@ public class Contacts.LinkDialog : Dialog {
     scrolled.set_vexpand (true);
     scrolled.set_hexpand (true);
     scrolled.set_shadow_type (ShadowType.NONE);
-    scrolled.add (view);
+    scrolled.add_with_viewport (view);
     list_grid.add (scrolled);
 
     view.selection_changed.connect ( (c) => {
diff --git a/src/contacts-list-pane.vala b/src/contacts-list-pane.vala
index 50ae1fe..636c6d0 100644
--- a/src/contacts-list-pane.vala
+++ b/src/contacts-list-pane.vala
@@ -143,7 +143,7 @@ public class Contacts.ListPane : Frame {
 	  selection_changed (contact);
       });
 
-    scrolled.add (contacts_view);
+    scrolled.add_with_viewport (contacts_view);
     contacts_view.show_all ();
     scrolled.set_no_show_all (true);
 
@@ -160,7 +160,6 @@ public class Contacts.ListPane : Frame {
   public void select_contact (Contact contact, bool ignore_change = false) {
     if (ignore_change)
       ignore_selection_change = true;
-    contacts_view.select_contact (contact);
     ignore_selection_change = false;
   }
 }
diff --git a/src/contacts-sorted.vala b/src/contacts-sorted.vala
index 23483ed..7045f40 100644
--- a/src/contacts-sorted.vala
+++ b/src/contacts-sorted.vala
@@ -99,11 +99,16 @@ public class Contacts.Sorted : Container {
 	}
       }
       selected_child = child_info;
+
+      child_selected (selected_child != null ? selected_child.widget : null);
       queue_draw ();
     }
     return false;
   }
-  
+
+  public virtual signal void child_selected (Widget? child) {
+  }
+
   public override bool draw (Cairo.Context cr) {
     Allocation allocation;
     this.get_allocation (out allocation);
@@ -120,14 +125,14 @@ public class Contacts.Sorted : Container {
 			     0, selected_child.y,
 			     allocation.width, selected_child.height);
     }
-    
+
     context.restore ();
 
     base.draw (cr);
 
     return true;
   }
-  
+
   public override void realize () {
     Allocation allocation;
     get_allocation (out allocation);
@@ -198,22 +203,54 @@ public class Contacts.Sorted : Container {
     queue_resize ();
   }
 
-  private void update_separator (SequenceIter<ChildInfo?> iter, SequenceIter<ChildInfo?>? before_iter,
-				bool update_if_exist) {
+  private SequenceIter<ChildInfo?>? get_previous_visible (SequenceIter<ChildInfo?> _iter) {
+    if (_iter.is_begin())
+      return null;
+    var iter = _iter;
+
+    do {
+      iter = iter.prev ();
+
+      unowned ChildInfo? child_info = iter.get ();
+      unowned Widget widget = child_info.widget;
+      if (widget.get_visible () && widget.get_child_visible ())
+	return iter;
+    } while (!iter.is_begin ());
+
+    return null;
+  }
+
+  private SequenceIter<ChildInfo?>? get_next_visible (SequenceIter<ChildInfo?> _iter) {
+    if (_iter.is_end())
+      return _iter;
+
+    var iter = _iter;
+    do {
+      iter = iter.next ();
+
+      if (!iter.is_end ()) {
+	unowned ChildInfo? child_info = iter.get ();
+	unowned Widget widget = child_info.widget;
+	if (widget.get_visible () && widget.get_child_visible ())
+	  return iter;
+      }
+    } while (!iter.is_end ());
+
+    return iter;
+  }
+
+  private void update_separator (SequenceIter<ChildInfo?> iter, bool update_if_exist) {
     if (iter.is_end ())
       return;
 
     unowned ChildInfo? info = iter.get ();
-    unowned ChildInfo? before_info = null;
-    if (!iter.is_begin()) {
-      if (before_iter == null)
-	before_info = iter.prev ().get ();
-      else
-	before_info = before_iter.get ();
-    }
-
+    var before_iter = get_previous_visible (iter);
     var widget = info.widget;
-    Widget? before_widget = before_info != null ? before_info.widget : null;
+    Widget? before_widget = null;
+    if (before_iter != null) {
+      unowned ChildInfo? before_info = before_iter.get ();
+      before_widget = before_info.widget;
+    }
 
     bool need_separator = false;
 
@@ -244,10 +281,8 @@ public class Contacts.Sorted : Container {
   }
 
   public void reseparate () {
-    SequenceIter<ChildInfo?>? last = null;
     for (var iter = children.get_begin_iter (); !iter.is_end (); iter = iter.next ()) {
-      update_separator (iter, last, false);
-      last = iter;
+      update_separator (iter, false);
     }
     queue_resize ();
   }
@@ -285,10 +320,10 @@ public class Contacts.Sorted : Container {
 
     apply_filter (widget);
 
-    var prev_next = iter.next ();
-    update_separator (iter, null, true);
-    update_separator (iter.next (), iter, true);
-    update_separator (prev_next, null, true);
+    var prev_next = get_next_visible (iter);
+    update_separator (iter, true);
+    update_separator (get_next_visible (iter), true);
+    update_separator (prev_next, true);
 
     info.iter = iter;
 
@@ -300,16 +335,16 @@ public class Contacts.Sorted : Container {
     if (info == null)
       return;
 
-    var prev_next = info.iter.next ();
+    var prev_next = get_previous_visible (info.iter);
 
     if (sort_func != null) {
       children.sort_changed (info.iter, do_sort);
       this.queue_resize ();
     }
     apply_filter (info.widget);
-    update_separator (info.iter, null, true);
-    update_separator (info.iter.next (), info.iter, true);
-    update_separator (prev_next, null, true);
+    update_separator (info.iter, true);
+    update_separator (get_next_visible (info.iter), true);
+    update_separator (prev_next, true);
 
   }
 
@@ -318,14 +353,14 @@ public class Contacts.Sorted : Container {
     if (info == null)
       return;
 
-    var next = info.iter.next ();
+    var next = get_next_visible (info.iter);
 
     bool was_visible = widget.get_visible ();
     widget.unparent ();
 
     child_hash.unset (widget);
 
-    update_separator (next, null, false);
+    update_separator (next, false);
 
     if (was_visible && this.get_visible ())
       this.queue_resize ();
@@ -371,6 +406,11 @@ public class Contacts.Sorted : Container {
       if (!widget.get_visible () || !widget.get_child_visible ())
 	continue;
 
+      if (child_info.separator != null) {
+	child_info.separator.get_preferred_height_for_width (width, out child_min, null);
+	minimum_height += child_min;
+      }
+
       widget.get_preferred_height_for_width (width, out child_min, null);
       minimum_height += child_min;
     }
@@ -429,8 +469,11 @@ public class Contacts.Sorted : Container {
       unowned Widget widget = child_info.widget;
       int child_min;
 
-      if (!widget.get_visible () || !widget.get_child_visible ())
+      if (!widget.get_visible () || !widget.get_child_visible ()) {
+	child_info.y = child_allocation.y;
+	child_info.height = 0;
 	continue;
+      }
 
       if (child_info.separator != null) {
 	child_info.separator.get_preferred_height_for_width (allocation.width, out child_min, null);
diff --git a/src/contacts-view.vala b/src/contacts-view.vala
index dc7722e..c747bba 100644
--- a/src/contacts-view.vala
+++ b/src/contacts-view.vala
@@ -20,13 +20,16 @@ using Gtk;
 using Folks;
 using Gee;
 
-public class Contacts.View : TreeView {
+public class Contacts.View : Contacts.Sorted {
   private class ContactData {
     public Contact contact;
-    public TreeIter iter;
-    public bool visible;
-    public bool is_first;
+    public Grid grid;
+    public Label label;
+    public ContactFrame image_frame;
     public int sort_prio;
+    public string display_name;
+    public unichar initial_letter;
+    public bool filtered;
   }
 
   public enum Subset {
@@ -36,46 +39,48 @@ public class Contacts.View : TreeView {
     ALL
   }
 
+  public enum TextDisplay {
+    NONE,
+    PRESENCE,
+    STORES
+  }
+
+  public signal void selection_changed (Contact? contact);
+
   Store contacts_store;
   Subset show_subset;
-  ListStore list_store;
+  HashMap<Contact,ContactData> contacts;
   HashSet<Contact> hidden_contacts;
+
   string []? filter_values;
   int custom_visible_count;
   ContactData suggestions_header_data;
   ContactData padding_data;
   ContactData other_header_data;
+  private TextDisplay text_display;
 
   public View (Store store, TextDisplay text_display = TextDisplay.PRESENCE) {
     contacts_store = store;
     hidden_contacts = new HashSet<Contact>();
     show_subset = Subset.ALL;
 
-    list_store = new ListStore (2, typeof (Contact), typeof (ContactData *));
-    suggestions_header_data = new ContactData ();
-    suggestions_header_data.sort_prio = int.MAX;
-    padding_data = new ContactData ();
-    padding_data.sort_prio = 1;
-
-    other_header_data = new ContactData ();
-    other_header_data.sort_prio = -1;
-
-    list_store.set_sort_func (0, (model, iter_a, iter_b) => {
-	ContactData *aa, bb;
-	model.get (iter_a, 1, out aa);
-	model.get (iter_b, 1, out bb);
+    contacts = new HashMap<Contact,ContactData> ();
 
-	return compare_data (aa, bb);
+    this.set_sort_func ((widget_a, widget_b) => {
+	var a = widget_a.get_data<ContactData> ("data");
+	var b = widget_b.get_data<ContactData> ("data");
+	return compare_data (a, b);
       });
-    list_store.set_sort_column_id (0, SortType.ASCENDING);
+    this.set_filter_func (filter);
+    this.set_separator_funcs (need_separator,
+			      create_separator,
+			      update_separator);
 
     contacts_store.added.connect (contact_added_cb);
     contacts_store.removed.connect (contact_removed_cb);
     contacts_store.changed.connect (contact_changed_cb);
     foreach (var c in store.get_contacts ())
       contact_added_cb (store, c);
-
-      init_view (text_display);
   }
 
   private int compare_data (ContactData a_data, ContactData b_data) {
@@ -90,13 +95,13 @@ public class Contacts.View : TreeView {
     var a = a_data.contact;
     var b = b_data.contact;
 
-    if (is_set (a.display_name) && is_set (b.display_name))
-      return a.display_name.collate (b.display_name);
+    if (is_set (a_data.display_name) && is_set (b_data.display_name))
+      return a.display_name.collate (b_data.display_name);
 
     // Sort empty names last
-    if (is_set (a.display_name))
+    if (is_set (a_data.display_name))
       return -1;
-    if (is_set (b.display_name))
+    if (is_set (b_data.display_name))
       return 1;
 
     return 0;
@@ -121,36 +126,9 @@ public class Contacts.View : TreeView {
     return 0;
   }
 
-  public string get_header_text (TreeIter iter) {
-    ContactData *data;
-    list_store.get (iter, 1, out data);
-    if (data == suggestions_header_data) {
-      /* Translators: This is the header for the list of suggested contacts to
-	 link to the current contact */
-      return ngettext ("Suggestion", "Suggestions", custom_visible_count);
-    }
-    if (data == other_header_data) {
-      /* Translators: This is the header for the list of suggested contacts to
-	 link to the current contact */
-      return _("Other Contacts");
-    }
-    return "";
-  }
-
   public void set_show_subset (Subset subset) {
     show_subset = subset;
-
-    bool new_visible = show_subset == Subset.ALL_SEPARATED;
-    if (new_visible && !other_header_data.visible) {
-      other_header_data.visible = true;
-      list_store.append (out other_header_data.iter);
-      list_store.set (other_header_data.iter, 1, other_header_data);
-    }
-    if (!new_visible && other_header_data.visible) {
-      other_header_data.visible = false;
-      list_store.remove (other_header_data.iter);
-    }
-
+    update_all_filtered ();
     refilter ();
   }
 
@@ -158,376 +136,120 @@ public class Contacts.View : TreeView {
     /* We use negative prios internally */
     assert (prio >= 0);
 
-    var data = lookup_data (c);
-
+    var data = contacts.get (c);
     if (data == null)
       return;
+  }
 
-    // We insert a priority between 0 and 1 for the padding
-    if (prio > 0)
-      prio += 1;
-    data.sort_prio = prio;
-    contact_changed_cb (contacts_store, c);
-
-    if (data.visible) {
-      if (prio > 0) {
-	if (custom_visible_count++ == 0)
-	  add_custom_headers ();
-      } else {
-	if (custom_visible_count-- == 1)
-	  remove_custom_headers ();
-      }
-    }
+  public void hide_contact (Contact contact) {
+    hidden_contacts.add (contact);
+    update_all_filtered ();
+    refilter ();
+  }
+
+  public void set_filter_values (string []? values) {
+    filter_values = values;
+    update_all_filtered ();
+    refilter ();
   }
 
-  private bool apply_filter (Contact contact) {
-    if (contact.is_hidden)
+  private bool calculate_filtered (Contact c) {
+    if (c.is_hidden)
       return false;
 
-    if (contact in hidden_contacts)
+    if (c in hidden_contacts)
       return false;
 
     if ((show_subset == Subset.MAIN &&
-	 !contact.is_main) ||
+	 !c.is_main) ||
 	(show_subset == Subset.OTHER &&
-	 contact.is_main))
+	 c.is_main))
       return false;
 
     if (filter_values == null || filter_values.length == 0)
       return true;
 
-    return contact.contains_strings (filter_values);
-  }
-
-  public bool is_first (TreeIter iter) {
-    ContactData *data;
-    list_store.get (iter, 1, out data);
-    if (data != null)
-      return data->is_first;
-    return false;
+    return c.contains_strings (filter_values);
   }
 
-  private ContactData? get_previous (ContactData data) {
-    ContactData *previous = null;
-    TreeIter iter = data.iter;
-    if (list_store.iter_previous (ref iter))
-      list_store.get (iter, 1, out previous);
-    return previous;
-  }
+  private void update_data (ContactData data) {
+    var c = data.contact;
+    data.display_name = c.display_name;
+    data.initial_letter = c.initial_letter;
+    data.filtered = calculate_filtered (c);
 
-  private ContactData? get_next (ContactData data) {
-    ContactData *next = null;
-    TreeIter iter = data.iter;
-    if (list_store.iter_next (ref iter))
-      list_store.get (iter, 1, out next);
-    return next;
+    data.label.set_text (data.display_name);
+    data.image_frame.set_image (c.individual, c);
   }
 
-  private void row_changed_no_resort (ContactData data) {
-    var path = list_store.get_path (data.iter);
-    list_store.row_changed (path, data.iter);
-  }
-
-  private void row_changed_resort (ContactData data) {
-    list_store.set (data.iter, 0, data.contact);
-  }
-
-  private bool update_is_first (ContactData data, ContactData? previous) {
-    bool old_is_first = data.is_first;
-
-    bool is_custom = data.sort_prio != 0;
-    bool previous_is_custom = previous != null && (previous.sort_prio != 0) ;
-
-    if (is_custom) {
-      data.is_first = false;
-    } else if (previous != null && !previous_is_custom) {
-      unichar previous_initial = previous.contact.initial_letter;
-      unichar initial = data.contact.initial_letter;
-      data.is_first = previous_initial != initial;
-    } else {
-      data.is_first = true;
+  private void update_all_filtered () {
+    foreach (var data in contacts.values) {
+      data.filtered = calculate_filtered (data.contact);
     }
-
-    if (old_is_first != data.is_first) {
-      row_changed_no_resort (data);
-      return true;
-    }
-
-    return false;
-  }
-
-  private void add_custom_headers () {
-    suggestions_header_data.visible = true;
-    list_store.append (out suggestions_header_data.iter);
-    list_store.set (suggestions_header_data.iter, 1, suggestions_header_data);
-    padding_data.visible = true;
-    list_store.append (out padding_data.iter);
-    list_store.set (padding_data.iter, 1, padding_data);
-  }
-
-  private void remove_custom_headers () {
-    suggestions_header_data.visible = false;
-    list_store.remove (suggestions_header_data.iter);
-    padding_data.visible = false;
-    list_store.remove (padding_data.iter);
-  }
-
-  private void add_to_model (ContactData data) {
-    list_store.append (out data.iter);
-    list_store.set (data.iter, 0, data.contact, 1, data);
-
-    if (data.sort_prio > 0) {
-      if (custom_visible_count++ == 0)
-	add_custom_headers ();
-    }
-
-    if (update_is_first (data, get_previous (data)) && data.is_first) {
-      /* The newly added row is first, the next one might not be anymore */
-      var next = get_next (data);
-      if (next != null)
-	update_is_first (next, data);
-    }
-  }
-
-  private void remove_from_model (ContactData data) {
-    if (data.sort_prio > 0) {
-      if (custom_visible_count-- == 1)
-	remove_custom_headers ();
-    }
-
-    ContactData? next = null;
-    if (data.is_first)
-      next = get_next (data);
-
-    list_store.remove (data.iter);
-    data.is_first = false;
-
-    if (next != null)
-      update_is_first (next, get_previous (next));
-  }
-
-  private void update_visible (ContactData data) {
-    bool was_visible = data.visible;
-    data.visible = apply_filter (data.contact);
-
-    if (was_visible && !data.visible)
-      remove_from_model (data);
-
-    if (!was_visible && data.visible)
-      add_to_model (data);
-  }
-
-  private void refilter () {
-    foreach (var c in contacts_store.get_contacts ()) {
-      update_visible (lookup_data (c));
-    }
-  }
-
-  public void hide_contact (Contact contact) {
-    hidden_contacts.add (contact);
-    refilter ();
-  }
-
-  public void set_filter_values (string []? values) {
-    filter_values = values;
-    refilter ();
   }
 
   private void contact_changed_cb (Store store, Contact c) {
-    ContactData data = lookup_data (c);
-
-    bool was_visible = data.visible;
-
-    ContactData? next = null;
-    if (data.visible)
-      next = get_next (data);
-
-    update_visible (data);
-
-    if (was_visible && data.visible) {
-      /* We just moved position in the list while visible */
-
-      row_changed_resort (data);
-
-      /* Update the is_first on the previous next row */
-      if (next != null)
-	update_is_first (next, get_previous (next));
-
-      /* Update the is_first on the new next row */
-      next = get_next (data);
-      if (next != null)
-	update_is_first (next, data);
-    }
-  }
-
-  private ContactData lookup_data (Contact c) {
-    return c.lookup<ContactData> (this);
+    var data = contacts.get (c);
+    update_data (data);
+    child_changed (data.grid);
   }
 
   private void contact_added_cb (Store store, Contact c) {
-    ContactData data =  new ContactData();
+    var data =  new ContactData();
     data.contact = c;
-    data.visible = false;
+    data.grid = new Grid ();
+    data.image_frame = new ContactFrame (Contact.SMALL_AVATAR_SIZE);
+    data.label = new Label ("");
+    data.grid.add (data.image_frame);
+    data.grid.add (data.label);
 
-    c.set_lookup (this, data);
+    update_data (data);
 
-    update_visible (data);
+    data.grid.set_data<ContactData> ("data", data);
+    data.grid.show_all ();
+    contacts.set (c, data);
+    this.add (data.grid);
   }
 
   private void contact_removed_cb (Store store, Contact c) {
-    var data = lookup_data (c);
-
-    if (data.visible)
-      remove_from_model (data);
-
-    c.remove_lookup<ContactData> (this);
+    var data = contacts.get (c);
+    data.grid.destroy ();
+    data.label.destroy ();
+    data.image_frame.destroy ();
+    this.remove (data.grid);
+    contacts.unset (c);
   }
 
-  public bool lookup_iter (Contact c, out TreeIter iter) {
-    var data = lookup_data (c);
-    iter = data.iter;
-    return data.visible;
+  public override void child_selected (Widget? child) {
+    var data = child.get_data<ContactData> ("data");
+    selection_changed (data != null ? data.contact : null);
   }
 
+  private bool need_separator (Widget widget, Widget? before) {
+    if (before == null) {
+      return true;
+    }
+    var w_data = widget.get_data<ContactData> ("data");
+    var before_data = before.get_data<ContactData> ("data");
 
+    return w_data.initial_letter != before_data.initial_letter;
 
-  private CellRendererShape shape;
-  public enum TextDisplay {
-    NONE,
-    PRESENCE,
-    STORES
+    return false;
   }
-  private TextDisplay text_display;
-
-  public signal void selection_changed (Contact? contact);
-
-  private void init_view (TextDisplay text_display) {
-    this.text_display = text_display;
-
-    set_model (list_store);
-    set_headers_visible (false);
-
-    var row_padding = 12;
-
-    var selection = get_selection ();
-    selection.set_mode (SelectionMode.BROWSE);
-    selection.set_select_function ( (selection, model, path, path_currently_selected) => {
-	Contact contact;
-	TreeIter iter;
-	model.get_iter (out iter, path);
-	model.get (iter, 0, out contact);
-	return contact != null;
-      });
-    selection.changed.connect (contacts_selection_changed);
-
-    var column = new TreeViewColumn ();
-    column.set_spacing (8);
-
-    var icon = new CellRendererPixbuf ();
-    icon.set_padding (0, row_padding);
-    icon.xalign = 1.0f;
-    icon.yalign = 0.0f;
-    icon.width = Contact.SMALL_AVATAR_SIZE + 12;
-    column.pack_start (icon, false);
-    column.set_cell_data_func (icon, (column, cell, model, iter) => {
-	Contact contact;
-
-	model.get (iter, 0, out contact);
-
-	if (contact == null) {
-	  cell.set ("pixbuf", null);
-	  cell.visible = false;
-	  return;
-	}
-	cell.visible = true;
-
-	if (contact != null)
-	  cell.set ("pixbuf", contact.small_avatar);
-	else
-	  cell.set ("pixbuf", null);
-      });
 
-    shape = new CellRendererShape ();
-    shape.set_padding (0, row_padding);
-
-    Pango.cairo_context_set_shape_renderer (get_pango_context (), shape.render_shape);
-
-    column.pack_start (shape, true);
-    column.set_cell_data_func (shape, (column, cell, model, iter) => {
-	Contact contact;
-
-	model.get (iter, 0, out contact);
-
-	if (contact == null) {
-	  cell.visible = false;
-	  return;
-	}
-	cell.visible = true;
-
-	var name = contact.display_name;
-	switch (text_display) {
-	default:
-	case TextDisplay.NONE:
-	  cell.set ("name", name,
-		    "show_presence", false,
-		    "message", "");
-	  break;
-	case TextDisplay.PRESENCE:
-	  cell.set ("name", name,
-		    "show_presence", true,
-		    "presence", contact.presence_type,
-		    "message", contact.presence_message,
-		    "is_phone", contact.is_phone);
-	  break;
-	case TextDisplay.STORES:
-	  string stores = contact.format_persona_stores ();
-	  cell.set ("name", name,
-		    "show_presence", false,
-		    "message", stores);
-	  break;
-	}
-      });
-
-    var text = new CellRendererText ();
-    text.set_alignment (0, 0);
-    column.pack_start (text, true);
-    text.set ("weight", Pango.Weight.BOLD);
-    column.set_cell_data_func (text, (column, cell, model, iter) => {
-	Contact contact;
-
-	model.get (iter, 0, out contact);
-	cell.visible = contact == null;
-	if (cell.visible) {
-	  string header = get_header_text (iter);
-	  cell.set ("text", header);
-	  if (header == "")
-	    cell.height = 6; // PADDING
-	  else
-	    cell.height = -1;
-	}
-      });
-
-    append_column (column);
+  private Widget create_separator () {
+    var s = new Label ("---------------------");
+    return s;
   }
 
-  private void contacts_selection_changed (TreeSelection selection) {
-    TreeIter iter;
-    TreeModel model;
+  private bool filter (Widget child) {
+    var data = child.get_data<ContactData> ("data");
 
-    Contact? contact = null;
-    if (selection.get_selected (out model, out iter)) {
-      model.get (iter, 0, out contact);
-    }
-
-    selection_changed (contact);
+    return data.filtered;
   }
 
-  public void select_contact (Contact contact) {
-    TreeIter iter;
-    if (lookup_iter (contact, out iter)) {
-      get_selection ().select_iter (iter);
-      scroll_to_cell (list_store.get_path (iter),
-		      null, true, 0.0f, 0.0f);
-    }
+  private void update_separator (Widget separator,
+				 Widget child,
+				 Widget? before_widget) {
   }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]