]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-roster-model-aggregator.c
remove released flag
[empathy.git] / libempathy-gtk / empathy-roster-model-aggregator.c
index 5ef310b66cd4415f2a38a8c5b8750bf722e1db83..26c8f2ae7909c4d585d74fea0f93ab817d301e27 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-
 #include "config.h"
+#include "empathy-roster-model-aggregator.h"
 
-#include <folks/folks.h>
 #include <folks/folks-telepathy.h>
 
-#include "empathy-roster-model-aggregator.h"
-
 /**
  * SECTION: empathy-roster-model-aggregator
  * @title: EmpathyRosterModelAggregator
@@ -80,7 +77,7 @@ static guint signals[LAST_SIGNAL];
 struct _EmpathyRosterModelAggregatorPriv
 {
   FolksIndividualAggregator *aggregator;
-  GHashTable *individuals; /* Individual -> Individual */
+  GHashTable *filtered_individuals; /* Individual -> Individual */
 
   EmpathyRosterModelAggregatorFilterFunc filter_func;
   gpointer filter_data;
@@ -97,36 +94,76 @@ individual_group_changed_cb (FolksIndividual *individual,
 }
 
 static void
-add_individual (EmpathyRosterModelAggregator *self,
+add_to_filtered_individuals (EmpathyRosterModelAggregator *self,
     FolksIndividual *individual)
 {
-  if (self->priv->filter_func != NULL && !self->priv->filter_func (
-          EMPATHY_ROSTER_MODEL (self), individual, self))
-        return;
-
-  g_hash_table_add (self->priv->individuals,
+  g_hash_table_add (self->priv->filtered_individuals,
       g_object_ref (individual));
 
-  g_signal_connect (individual, "group-changed",
-      G_CALLBACK (individual_group_changed_cb), self);
+  tp_g_signal_connect_object (individual, "group-changed",
+      G_CALLBACK (individual_group_changed_cb), self, 0);
 
   empathy_roster_model_fire_individual_added (EMPATHY_ROSTER_MODEL (self),
       individual);
 }
 
 static void
-remove_individual (EmpathyRosterModelAggregator *self,
+remove_from_filtered_individuals (EmpathyRosterModelAggregator *self,
     FolksIndividual *individual)
 {
   g_signal_handlers_disconnect_by_func (individual,
       individual_group_changed_cb, self);
 
-  g_hash_table_remove (self->priv->individuals, individual);
+  g_hash_table_remove (self->priv->filtered_individuals, individual);
 
   empathy_roster_model_fire_individual_removed (EMPATHY_ROSTER_MODEL (self),
       individual);
 }
 
+static void
+individual_notify_cb (FolksIndividual *individual,
+    GParamSpec *param,
+    EmpathyRosterModelAggregator *self)
+{
+  if (!self->priv->filter_func (EMPATHY_ROSTER_MODEL (self), individual, self)
+      && g_hash_table_contains (self->priv->filtered_individuals, individual))
+    remove_from_filtered_individuals (self, individual);
+
+  if (self->priv->filter_func (EMPATHY_ROSTER_MODEL (self), individual, self)
+      && !g_hash_table_contains (self->priv->filtered_individuals, individual))
+    add_to_filtered_individuals (self, individual);
+}
+
+static void
+add_individual (EmpathyRosterModelAggregator *self,
+    FolksIndividual *individual)
+{
+  if (self->priv->filter_func != NULL)
+    {
+      tp_g_signal_connect_object (individual, "notify",
+          G_CALLBACK (individual_notify_cb), self, 0);
+
+      if (!self->priv->filter_func (EMPATHY_ROSTER_MODEL (self), individual,
+              self))
+        return;
+    }
+
+  add_to_filtered_individuals (self, individual);
+}
+
+static void
+remove_individual (EmpathyRosterModelAggregator *self,
+    FolksIndividual *individual)
+{
+  if (self->priv->filter_func != NULL)
+    g_signal_handlers_disconnect_by_func (individual,
+        individual_notify_cb, self);
+
+  if (g_hash_table_contains (self->priv->filtered_individuals,
+          individual))
+    remove_from_filtered_individuals (self, individual);
+}
+
 static void
 populate_individuals (EmpathyRosterModelAggregator *self)
 {
@@ -138,7 +175,9 @@ populate_individuals (EmpathyRosterModelAggregator *self)
   iter = gee_map_map_iterator (individuals);
   while (gee_map_iterator_next (iter))
     {
-      add_individual (self, gee_map_iterator_get_value (iter));
+      FolksIndividual *individual = gee_map_iterator_get_value (iter);
+      add_individual (self, individual);
+      g_object_unref (individual);
     }
   g_clear_object (&iter);
 }
@@ -158,7 +197,9 @@ aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator,
 
       while (iter != NULL && gee_iterator_next (iter))
         {
-          add_individual (self, gee_iterator_get (iter));
+          FolksIndividual *individual = gee_iterator_get (iter);
+          add_individual (self, individual);
+          g_object_unref (individual);
         }
       g_clear_object (&iter);
     }
@@ -169,7 +210,9 @@ aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator,
 
       while (iter != NULL && gee_iterator_next (iter))
         {
-          remove_individual (self, gee_iterator_get (iter));
+          FolksIndividual *individual = gee_iterator_get (iter);
+          remove_individual (self, individual);
+          g_object_unref (individual);
         }
       g_clear_object (&iter);
     }
@@ -239,7 +282,7 @@ empathy_roster_model_aggregator_constructed (GObject *object)
     chain_up (object);
 
   if (self->priv->aggregator == NULL)
-    self->priv->aggregator = folks_individual_aggregator_new ();
+    self->priv->aggregator = folks_individual_aggregator_dup ();
 
   g_assert (FOLKS_IS_INDIVIDUAL_AGGREGATOR (self->priv->aggregator));
 
@@ -259,6 +302,7 @@ empathy_roster_model_aggregator_dispose (GObject *object)
       ((GObjectClass *) empathy_roster_model_aggregator_parent_class)->dispose;
 
   g_clear_object (&self->priv->aggregator);
+  g_clear_pointer (&self->priv->filtered_individuals, g_hash_table_unref);
 
   if (chain_up != NULL)
     chain_up (object);
@@ -313,7 +357,7 @@ empathy_roster_model_aggregator_init (EmpathyRosterModelAggregator *self)
   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
       EMPATHY_TYPE_ROSTER_MODEL_AGGREGATOR, EmpathyRosterModelAggregatorPriv);
 
-  self->priv->individuals = g_hash_table_new_full (NULL, NULL, NULL,
+  self->priv->filtered_individuals = g_hash_table_new_full (NULL, NULL, NULL,
       g_object_unref);
 }
 
@@ -348,11 +392,11 @@ empathy_roster_model_aggregator_get_individuals (EmpathyRosterModel *model)
 {
   EmpathyRosterModelAggregator *self = EMPATHY_ROSTER_MODEL_AGGREGATOR (model);
 
-  return g_hash_table_get_values (self->priv->individuals);
+  return g_hash_table_get_values (self->priv->filtered_individuals);
 }
 
 static GList *
-empathy_roster_model_aggregator_get_groups_for_individual (
+empathy_roster_model_aggregator_dup_groups_for_individual (
     EmpathyRosterModel *model,
     FolksIndividual *individual)
 {
@@ -367,6 +411,7 @@ empathy_roster_model_aggregator_get_groups_for_individual (
 
       while (iter != NULL && gee_iterator_next (iter))
         {
+          /* Transfer ownership: */
           groups_list = g_list_prepend (groups_list, gee_iterator_get (iter));
         }
       g_clear_object (&iter);
@@ -379,6 +424,6 @@ static void
 roster_model_iface_init (EmpathyRosterModelInterface *iface)
 {
   iface->get_individuals = empathy_roster_model_aggregator_get_individuals;
-  iface->get_groups_for_individual =
-    empathy_roster_model_aggregator_get_groups_for_individual;
+  iface->dup_groups_for_individual =
+    empathy_roster_model_aggregator_dup_groups_for_individual;
 }