[empathy] Implement filtering logic in EmpathyInviteParticipantDialog



commit 3aa8239213c026f5b09d50669f7a4a65c9906659
Author: Guillaume Desmottes <guillaume desmottes collabora co uk>
Date:   Fri Aug 5 11:57:25 2011 +0200

    Implement filtering logic in EmpathyInviteParticipantDialog
    
    https://bugzilla.gnome.org/show_bug.cgi?id=656020

 libempathy-gtk/empathy-contact-chooser.c |   67 ++++++++-------------
 libempathy-gtk/empathy-contact-chooser.h |   11 ++++
 src/empathy-invite-participant-dialog.c  |   96 ++++++++++++++++++++++++++++++
 3 files changed, 131 insertions(+), 43 deletions(-)
---
diff --git a/libempathy-gtk/empathy-contact-chooser.c b/libempathy-gtk/empathy-contact-chooser.c
index 38956ba..9605855 100644
--- a/libempathy-gtk/empathy-contact-chooser.c
+++ b/libempathy-gtk/empathy-contact-chooser.c
@@ -48,6 +48,9 @@ struct _EmpathyContactChooserPrivate
   /* Context representing the FolksIndividual which are added because of the
    * current search from the user. */
   AddTemporaryIndividualCtx *add_temp_ctx;
+
+  EmpathyContactChooserFilterFunc filter_func;
+  gpointer filter_data;
 };
 
 static void
@@ -237,10 +240,9 @@ filter_func (GtkTreeModel *model,
 {
   EmpathyContactChooser *self = user_data;
   FolksIndividual *individual;
-  TpContact *contact;
   gboolean is_online;
-  GList *members, *l;
   gboolean display = FALSE;
+  gboolean searching = FALSE;
 
   gtk_tree_model_get (model, iter,
       EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual,
@@ -250,53 +252,21 @@ filter_func (GtkTreeModel *model,
   if (individual == NULL)
     goto out;
 
-  if (self->priv->search_words == NULL)
-    {
-      /* Not searching, display online contacts */
-      if (!is_online)
-        goto out;
-    }
-  else
+  if (self->priv->search_words != NULL)
     {
+      searching = TRUE;
+
+      /* Filter out the contact if we are searching and it doesn't match */
       if (!empathy_individual_match_string (individual,
             self->priv->search_str, self->priv->search_words))
         goto out;
     }
 
-  /* Filter out individuals not having a persona on the same connection as the
-   * EmpathyTpChat. */
-  contact = get_tp_contact_for_chat (self, individual);
-
-  if (contact == NULL)
-    goto out;
-
-  /* Filter out contacts which are already in the chat */
-  members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (
-        self->priv->tp_chat));
-
-  display = TRUE;
-
-  for (l = members; l != NULL; l = g_list_next (l))
-    {
-      EmpathyContact *member = l->data;
-      TpHandle handle;
-
-      /* Try to get the non-channel specific handle. */
-      handle = tp_channel_group_get_handle_owner (
-          TP_CHANNEL (self->priv->tp_chat),
-          empathy_contact_get_handle (member));
-      if (handle == 0)
-        handle = empathy_contact_get_handle (member);
-
-      if (handle == tp_contact_get_handle (contact))
-        {
-          display = FALSE;
-          break;
-        }
-    }
-
-  g_list_free_full (members, g_object_unref);
-
+  if (self->priv->filter_func == NULL)
+    display = TRUE;
+  else
+    display = self->priv->filter_func (self, individual, is_online, searching,
+      self->priv->filter_data);
 out:
   tp_clear_object (&individual);
   return display;
@@ -491,3 +461,14 @@ empathy_contact_chooser_get_selected (EmpathyContactChooser *self)
   g_object_unref (individual);
   return contact;
 }
+
+void
+empathy_contact_chooser_set_filter_func (EmpathyContactChooser *self,
+    EmpathyContactChooserFilterFunc func,
+    gpointer user_data)
+{
+  g_assert (self->priv->filter_func == NULL);
+
+  self->priv->filter_func = func;
+  self->priv->filter_data = user_data;
+}
diff --git a/libempathy-gtk/empathy-contact-chooser.h b/libempathy-gtk/empathy-contact-chooser.h
index 5af938d..142660a 100644
--- a/libempathy-gtk/empathy-contact-chooser.h
+++ b/libempathy-gtk/empathy-contact-chooser.h
@@ -31,6 +31,13 @@ typedef struct _EmpathyContactChooser EmpathyContactChooser;
 typedef struct _EmpathyContactChooserClass EmpathyContactChooserClass;
 typedef struct _EmpathyContactChooserPrivate EmpathyContactChooserPrivate;
 
+typedef gboolean (*EmpathyContactChooserFilterFunc) (
+    EmpathyContactChooser *self,
+    FolksIndividual *individual,
+    gboolean is_online,
+    gboolean searching,
+    gpointer user_data);
+
 struct _EmpathyContactChooser
 {
   GtkBox parent;
@@ -50,6 +57,10 @@ GtkWidget * empathy_contact_chooser_new (EmpathyTpChat *tp_chat);
 TpContact * empathy_contact_chooser_get_selected (
     EmpathyContactChooser *self);
 
+void empathy_contact_chooser_set_filter_func (EmpathyContactChooser *self,
+    EmpathyContactChooserFilterFunc func,
+    gpointer user_data);
+
 G_END_DECLS
 
 #endif
diff --git a/src/empathy-invite-participant-dialog.c b/src/empathy-invite-participant-dialog.c
index f6471fb..eedc6af 100644
--- a/src/empathy-invite-participant-dialog.c
+++ b/src/empathy-invite-participant-dialog.c
@@ -95,6 +95,98 @@ selection_changed_cb (GtkWidget *treeview,
   gtk_widget_set_sensitive (self->priv->invite_button, selected != NULL);
 }
 
+/* Return the TpContact of @individual which is on the same connection as the
+ * EmpathyTpChat */
+static TpContact *
+get_tp_contact_for_chat (EmpathyInviteParticipantDialog *self,
+    FolksIndividual *individual)
+{
+  TpContact *contact = NULL;
+  TpConnection *chat_conn;
+  GeeSet *personas;
+  GeeIterator *iter;
+
+  chat_conn = tp_channel_borrow_connection (TP_CHANNEL (self->priv->tp_chat));
+
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+  while (contact == FALSE && gee_iterator_next (iter))
+    {
+      TpfPersona *persona = gee_iterator_get (iter);
+      TpConnection *contact_conn;
+      TpContact *contact_cur = NULL;
+
+      if (TPF_IS_PERSONA (persona))
+        {
+          contact_cur = tpf_persona_get_contact (persona);
+          if (contact_cur != NULL)
+            {
+              contact_conn = tp_contact_get_connection (contact_cur);
+
+              if (!tp_strdiff (tp_proxy_get_object_path (contact_conn),
+                    tp_proxy_get_object_path (chat_conn)))
+                contact = contact_cur;
+            }
+        }
+
+      g_clear_object (&persona);
+    }
+  g_clear_object (&iter);
+
+  return contact;
+}
+
+static gboolean
+filter_individual (EmpathyContactChooser *chooser,
+    FolksIndividual *individual,
+    gboolean is_online,
+    gboolean searching,
+    gpointer user_data)
+{
+  EmpathyInviteParticipantDialog *self = user_data;
+  GList *members, *l;
+  TpContact *contact;
+  gboolean display = TRUE;
+
+  /* Filter out offline contacts if we are not searching */
+  if (!searching && !is_online)
+    return FALSE;
+
+  /* Filter out individuals not having a persona on the same connection as the
+   * EmpathyTpChat. */
+  contact = get_tp_contact_for_chat (self, individual);
+
+  if (contact == NULL)
+    return FALSE;
+
+  /* Filter out contacts which are already in the chat */
+  members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (
+        self->priv->tp_chat));
+
+  for (l = members; l != NULL; l = g_list_next (l))
+    {
+      EmpathyContact *member = l->data;
+      TpHandle handle;
+
+      /* Try to get the non-channel specific handle. */
+      handle = tp_channel_group_get_handle_owner (
+          TP_CHANNEL (self->priv->tp_chat),
+          empathy_contact_get_handle (member));
+      if (handle == 0)
+        handle = empathy_contact_get_handle (member);
+
+      if (handle == tp_contact_get_handle (contact))
+        {
+          display = FALSE;
+          break;
+        }
+    }
+
+  g_list_free_full (members, g_object_unref);
+
+  return display;
+}
+
 static void
 invite_participant_dialog_constructed (GObject *object)
 {
@@ -122,6 +214,10 @@ invite_participant_dialog_constructed (GObject *object)
 
   /* contact chooser */
   self->priv->chooser = empathy_contact_chooser_new (self->priv->tp_chat);
+
+  empathy_contact_chooser_set_filter_func (
+      EMPATHY_CONTACT_CHOOSER (self->priv->chooser), filter_individual, self);
+
   gtk_box_pack_start (GTK_BOX (content), self->priv->chooser, TRUE, TRUE, 6);
   gtk_widget_show (self->priv->chooser);
 



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