]> git.0d.be Git - empathy.git/commitdiff
roster-view: add live search support
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Tue, 29 May 2012 13:30:37 +0000 (15:30 +0200)
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Thu, 14 Jun 2012 07:21:49 +0000 (09:21 +0200)
libempathy-gtk/empathy-roster-view.c
libempathy-gtk/empathy-roster-view.h
tests/interactive/test-empathy-roster-view.c

index 6281cf2e6b8c0ece36ba7643c512b6a51cf3bb80..4db824b95f9b431eb97b7d4c8af9faef1ef1862d 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <libempathy-gtk/empathy-roster-contact.h>
 #include <libempathy-gtk/empathy-roster-group.h>
+#include <libempathy-gtk/empathy-ui-utils.h>
 
 G_DEFINE_TYPE (EmpathyRosterView, empathy_roster_view, EGG_TYPE_LIST_BOX)
 
@@ -46,6 +47,8 @@ struct _EmpathyRosterViewPriv
 
   gboolean show_offline;
   gboolean show_groups;
+
+  EmpathyLiveSearch *search;
 };
 
 static void
@@ -455,19 +458,41 @@ update_separator (GtkWidget **separator,
   g_object_ref_sink (*separator);
 }
 
+static gboolean
+is_searching (EmpathyRosterView *self)
+{
+  if (self->priv->search == NULL)
+    return FALSE;
+
+  return gtk_widget_get_visible (GTK_WIDGET (self->priv->search));
+}
+
 static gboolean
 filter_contact (EmpathyRosterView *self,
     EmpathyRosterContact *contact)
 {
   gboolean displayed;
 
-  if (self->priv->show_offline)
+  if (is_searching (self))
     {
-      displayed = TRUE;
+      FolksIndividual *individual;
+
+      individual = empathy_roster_contact_get_individual (contact);
+
+      displayed = empathy_individual_match_string (individual,
+          empathy_live_search_get_text (self->priv->search),
+          empathy_live_search_get_words (self->priv->search));
     }
   else
     {
-      displayed = empathy_roster_contact_is_online (contact);
+      if (self->priv->show_offline)
+        {
+          displayed = TRUE;
+        }
+      else
+        {
+          displayed = empathy_roster_contact_is_online (contact);
+        }
     }
 
   if (self->priv->show_groups)
@@ -482,7 +507,9 @@ filter_contact (EmpathyRosterView *self,
         {
           update_group_widgets_count (self, group, contact, displayed);
 
-          if (!gtk_expander_get_expanded (GTK_EXPANDER (group)))
+          /* When searching, always display even if the group is closed */
+          if (!is_searching (self) &&
+              !gtk_expander_get_expanded (GTK_EXPANDER (group)))
             return FALSE;
         }
     }
@@ -618,6 +645,7 @@ empathy_roster_view_dispose (GObject *object)
   void (*chain_up) (GObject *) =
       ((GObjectClass *) empathy_roster_view_parent_class)->dispose;
 
+  empathy_roster_view_set_live_search (self, NULL);
   g_clear_object (&self->priv->manager);
 
   if (chain_up != NULL)
@@ -737,3 +765,68 @@ empathy_roster_view_show_groups (EmpathyRosterView *self,
 
   g_object_notify (G_OBJECT (self), "show-groups");
 }
+
+static void
+select_first_contact (EmpathyRosterView *self)
+{
+  GList *children, *l;
+
+  children = gtk_container_get_children (GTK_CONTAINER (self));
+  for (l = children; l != NULL; l = g_list_next (l))
+    {
+      GtkWidget *child = l->data;
+
+      if (!gtk_widget_get_child_visible (child))
+        continue;
+
+      if (!EMPATHY_IS_ROSTER_CONTACT (child))
+        continue;
+
+      egg_list_box_select_child (EGG_LIST_BOX (self), child);
+      break;
+    }
+
+  g_list_free (children);
+}
+
+static void
+search_text_notify_cb (EmpathyLiveSearch *search,
+    GParamSpec *pspec,
+    EmpathyRosterView *self)
+{
+  egg_list_box_refilter (EGG_LIST_BOX (self));
+
+  select_first_contact (self);
+}
+
+static void
+search_activate_cb (GtkWidget *search,
+  EmpathyRosterView *self)
+{
+  /* TODO */
+}
+
+void
+empathy_roster_view_set_live_search (EmpathyRosterView *self,
+    EmpathyLiveSearch *search)
+{
+  if (self->priv->search != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (self->priv->search,
+          search_text_notify_cb, self);
+      g_signal_handlers_disconnect_by_func (self->priv->search,
+          search_activate_cb, self);
+
+      g_clear_object (&self->priv->search);
+    }
+
+  if (search == NULL)
+    return;
+
+  self->priv->search = g_object_ref (search);
+
+  g_signal_connect (self->priv->search, "notify::text",
+      G_CALLBACK (search_text_notify_cb), self);
+  g_signal_connect (self->priv->search, "activate",
+      G_CALLBACK (search_activate_cb), self);
+}
index 8706da3512618097f506c366078770162c2a099c..e5c3a6f40a0051dbc244e7d873a5167793df8ee8 100644 (file)
@@ -3,6 +3,8 @@
 #define __EMPATHY_ROSTER_VIEW_H__
 
 #include <libempathy-gtk/egg-list-box/egg-list-box.h>
+#include <libempathy-gtk/empathy-live-search.h>
+
 #include <libempathy/empathy-individual-manager.h>
 
 G_BEGIN_DECLS
@@ -59,6 +61,9 @@ void empathy_roster_view_show_offline (EmpathyRosterView *self,
 void empathy_roster_view_show_groups (EmpathyRosterView *self,
     gboolean show);
 
+void empathy_roster_view_set_live_search (EmpathyRosterView *self,
+    EmpathyLiveSearch *search);
+
 G_END_DECLS
 
 #endif /* #ifndef __EMPATHY_ROSTER_VIEW_H__*/
index 7c29634ebfe64c1094f90c2e23dd93b2bae867e5..5700c1518b7dc09705026e869732040df99f946f 100644 (file)
@@ -17,7 +17,7 @@ int
 main (int argc,
     char **argv)
 {
-  GtkWidget *window, *view, *scrolled;
+  GtkWidget *window, *view, *scrolled, *box, *search;
   EmpathyIndividualManager *mgr;
   GError *error = NULL;
   GOptionContext *context;
@@ -38,6 +38,8 @@ main (int argc,
 
   empathy_set_css_provider (window);
 
+  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
+
   mgr = empathy_individual_manager_dup_singleton ();
 
   view = empathy_roster_view_new (mgr);
@@ -47,13 +49,20 @@ main (int argc,
 
   g_object_unref (mgr);
 
+  search = empathy_live_search_new (view);
+  empathy_roster_view_set_live_search (EMPATHY_ROSTER_VIEW (view),
+      EMPATHY_LIVE_SEARCH (search));
+
   scrolled = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
   egg_list_box_add_to_scrolled (EGG_LIST_BOX (view),
       GTK_SCROLLED_WINDOW (scrolled));
-  gtk_container_add (GTK_CONTAINER (window), scrolled);
+
+  gtk_box_pack_start (GTK_BOX (box), search, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0);
+  gtk_container_add (GTK_CONTAINER (window), box);
 
   gtk_window_set_default_size (GTK_WINDOW (window), 300, 600);
   gtk_widget_show_all (window);