]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-individual-manager.c
Merge remote-tracking branch 'glassrose/add-All-service-selection-in-debug-window'
[empathy.git] / libempathy / empathy-individual-manager.c
index b391d3ca9ac2baf478ba5f394659e9df80916ef5..68b094ef1be14d492ba8ceeab466b905a8b21bf7 100644 (file)
@@ -50,6 +50,7 @@ typedef struct
 {
   FolksIndividualAggregator *aggregator;
   GHashTable *individuals; /* Individual.id -> Individual */
+  gboolean contacts_loaded;
 } EmpathyIndividualManagerPriv;
 
 enum
@@ -57,6 +58,7 @@ enum
   FAVOURITES_CHANGED,
   GROUPS_CHANGED,
   MEMBERS_CHANGED,
+  CONTACTS_LOADED,
   LAST_SIGNAL
 };
 
@@ -334,10 +336,41 @@ empathy_individual_manager_class_init (EmpathyIndividualManagerClass *klass)
           G_TYPE_NONE,
           4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT);
 
+  signals[CONTACTS_LOADED] =
+      g_signal_new ("contacts-loaded",
+          G_TYPE_FROM_CLASS (klass),
+          G_SIGNAL_RUN_LAST,
+          0,
+          NULL, NULL,
+          g_cclosure_marshal_generic,
+          G_TYPE_NONE,
+          0);
+
   g_type_class_add_private (object_class,
       sizeof (EmpathyIndividualManagerPriv));
 }
 
+static void
+aggregator_is_quiescent_notify_cb (FolksIndividualAggregator *aggregator,
+    GParamSpec *spec,
+    EmpathyIndividualManager *self)
+{
+  EmpathyIndividualManagerPriv *priv = GET_PRIV (self);
+  gboolean is_quiescent;
+
+  if (priv->contacts_loaded)
+    return;
+
+  g_object_get (aggregator, "is-quiescent", &is_quiescent, NULL);
+
+  if (!is_quiescent)
+    return;
+
+  priv->contacts_loaded = TRUE;
+
+  g_signal_emit (self, signals[CONTACTS_LOADED], 0);
+}
+
 static void
 empathy_individual_manager_init (EmpathyIndividualManager *self)
 {
@@ -351,6 +384,8 @@ empathy_individual_manager_init (EmpathyIndividualManager *self)
   priv->aggregator = folks_individual_aggregator_new ();
   g_signal_connect (priv->aggregator, "individuals-changed-detailed",
       G_CALLBACK (aggregator_individuals_changed_cb), self);
+  g_signal_connect (priv->aggregator, "notify::is-quiescent",
+      G_CALLBACK (aggregator_is_quiescent_notify_cb), self);
   folks_individual_aggregator_prepare (priv->aggregator, NULL, NULL);
 }
 
@@ -720,3 +755,63 @@ empathy_individual_manager_unlink_individual (EmpathyIndividualManager *self,
   folks_individual_aggregator_unlink_individual (priv->aggregator, individual,
       (GAsyncReadyCallback) unlink_individual_cb, NULL);
 }
+
+gboolean
+empathy_individual_manager_get_contacts_loaded (EmpathyIndividualManager *self)
+{
+  EmpathyIndividualManagerPriv *priv = GET_PRIV (self);
+
+  return priv->contacts_loaded;
+}
+
+static gboolean
+individual_has_contact (FolksIndividual *individual,
+    TpContact *contact)
+{
+  GeeSet *personas;
+  GeeIterator *iter;
+  gboolean found = FALSE;
+
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+
+  while (!found && gee_iterator_next (iter))
+    {
+      TpfPersona *persona = gee_iterator_get (iter);
+
+      if (TPF_IS_PERSONA (persona))
+        {
+          TpContact *c = tpf_persona_get_contact (persona);
+
+          if (c == contact)
+            found = TRUE;
+        }
+
+      g_clear_object (&persona);
+    }
+
+  g_clear_object (&iter);
+
+  return found;
+}
+
+/* Try finding a FolksIndividual containing @contact as one of his persona */
+FolksIndividual *
+empathy_individual_manager_lookup_by_contact (EmpathyIndividualManager *self,
+    TpContact *contact)
+{
+  EmpathyIndividualManagerPriv *priv = GET_PRIV (self);
+  GHashTableIter iter;
+  gpointer value;
+
+  g_hash_table_iter_init (&iter, priv->individuals);
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+      FolksIndividual *individual = value;
+
+      if (individual_has_contact (individual, contact))
+        return individual;
+    }
+
+  return NULL;
+}