]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-contact-chooser.c
libempathy-gtk: fix uninitialized variable
[empathy.git] / libempathy-gtk / empathy-contact-chooser.c
index 5ff17a432581b2bac80ebd2df932e9c3d0d505f1..05dbe3449a21baa7bc89a2e8e821e22d93e700bf 100644 (file)
@@ -9,13 +9,14 @@
  *    Danielle Madeley <danielle.madeley@collabora.co.uk>
  */
 
-#include <glib/gi18n.h>
-#include <folks/folks-telepathy.h>
-
+#include "config.h"
 #include "empathy-contact-chooser.h"
 
-#include <libempathy-gtk/empathy-individual-view.h>
-#include <libempathy-gtk/empathy-ui-utils.h>
+#include "empathy-client-factory.h"
+#include "empathy-individual-store-manager.h"
+#include "empathy-individual-view.h"
+#include "empathy-ui-utils.h"
+#include "empathy-utils.h"
 
 G_DEFINE_TYPE (EmpathyContactChooser,
     empathy_contact_chooser, GTK_TYPE_BOX);
@@ -48,6 +49,9 @@ struct _EmpathyContactChooserPrivate
 
   EmpathyContactChooserFilterFunc filter_func;
   gpointer filter_data;
+
+  /* list of reffed TpContact */
+  GList *tp_contacts;
 };
 
 struct _AddTemporaryIndividualCtx
@@ -101,6 +105,9 @@ contact_chooser_dispose (GObject *object)
 
   tp_clear_object (&self->priv->account_mgr);
 
+  g_list_free_full (self->priv->tp_contacts, g_object_unref);
+  self->priv->tp_contacts = NULL;
+
   G_OBJECT_CLASS (empathy_contact_chooser_parent_class)->dispose (
       object);
 }
@@ -196,46 +203,47 @@ contact_capabilities_changed (TpContact *contact,
 }
 
 static void
-get_contacts_cb (TpConnection *connection,
-    guint n_contacts,
-    TpContact * const *contacts,
-    const gchar * const *requested_ids,
-    GHashTable *failed_id_errors,
-    const GError *error,
-    gpointer user_data,
-    GObject *weak_object)
+get_contacts_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
 {
-  EmpathyContactChooser *self =
-    (EmpathyContactChooser *) weak_object;
-  AddTemporaryIndividualCtx *ctx = user_data;
-  TpAccount *account;
-  TpfPersonaStore *store;
+  TpWeakRef *wr = user_data;
+  AddTemporaryIndividualCtx *ctx;
+  EmpathyContactChooser *self;
+  GError *error = NULL;
   FolksIndividual *individual;
-  TpfPersona *persona;
-  GeeSet *personas;
+  TpContact *contact;
+  EmpathyContact *emp_contact = NULL;
 
-  if (self->priv->add_temp_ctx != ctx)
-    /* another request has been started */
-    return;
+  self = tp_weak_ref_dup_object (wr);
+  if (self == NULL)
+    goto out;
 
-  if (n_contacts != 1)
-    return;
+  ctx = tp_weak_ref_get_user_data (wr);
 
-  account = tp_connection_get_account (connection);
+  emp_contact = empathy_client_factory_dup_contact_by_id_finish (
+        EMPATHY_CLIENT_FACTORY (source), result, &error);
+  if (emp_contact == NULL)
+    goto out;
 
-  store = tpf_persona_store_new (account);
-  personas = GEE_SET (
-      gee_hash_set_new (FOLKS_TYPE_PERSONA, g_object_ref, g_object_unref,
-      g_direct_hash, g_direct_equal));
+  contact = empathy_contact_get_tp_contact (emp_contact);
 
-  persona = tpf_persona_new (contacts[0], store);
+  if (self->priv->add_temp_ctx != ctx)
+    /* another request has been started */
+    goto out;
 
-  gee_collection_add (GEE_COLLECTION (personas), persona);
+  individual =  empathy_ensure_individual_from_tp_contact (contact);
+  if (individual == NULL)
+    goto out;
 
-  individual = folks_individual_new (personas);
+  /* tp-glib will unref the TpContact once we return from this callback
+   * but folks expect us to keep a reference on the TpContact.
+   * Ideally folks shouldn't force us to do that: bgo #666580 */
+  self->priv->tp_contacts = g_list_prepend (self->priv->tp_contacts,
+      g_object_ref (contact));
 
   /* listen for updates to the capabilities */
-  tp_g_signal_connect_object (contacts[0], "notify::capabilities",
+  tp_g_signal_connect_object (contact, "notify::capabilities",
       G_CALLBACK (contact_capabilities_changed), self, 0);
 
   /* Pass ownership to the list */
@@ -249,9 +257,10 @@ get_contacts_cb (TpConnection *connection,
         NULL, NULL))
     empathy_individual_view_select_first (self->priv->view);
 
-  g_clear_object (&persona);
-  g_clear_object (&personas);
-  g_object_unref (store);
+out:
+  g_clear_object (&emp_contact);
+  g_clear_object (&self);
+  tp_weak_ref_destroy (wr);
 }
 
 static void
@@ -269,26 +278,27 @@ add_temporary_individuals (EmpathyContactChooser *self,
   self->priv->add_temp_ctx = add_temporary_individual_ctx_new (self);
 
   /* Try to add an individual for each connected account */
-  accounts = tp_account_manager_get_valid_accounts (self->priv->account_mgr);
+  accounts = tp_account_manager_dup_valid_accounts (self->priv->account_mgr);
   for (l = accounts; l != NULL; l = g_list_next (l))
     {
       TpAccount *account = l->data;
       TpConnection *conn;
-      TpContactFeature features[] = { TP_CONTACT_FEATURE_ALIAS,
-          TP_CONTACT_FEATURE_AVATAR_DATA,
-          TP_CONTACT_FEATURE_PRESENCE,
-          TP_CONTACT_FEATURE_CAPABILITIES };
+      EmpathyClientFactory *factory;
 
       conn = tp_account_get_connection (account);
       if (conn == NULL)
         continue;
 
-      tp_connection_get_contacts_by_id (conn, 1, &id, G_N_ELEMENTS (features),
-          features, get_contacts_cb, self->priv->add_temp_ctx, NULL,
-          G_OBJECT (self));
+      factory = empathy_client_factory_dup ();
+
+      empathy_client_factory_dup_contact_by_id_async (factory, conn, id,
+          get_contacts_cb,
+          tp_weak_ref_new (self, self->priv->add_temp_ctx, NULL));
+
+      g_object_unref (factory);
     }
 
-  g_list_free (accounts);
+  g_list_free_full (accounts, g_object_unref);
 }
 
 static void
@@ -302,7 +312,7 @@ search_text_changed (GtkEntry *entry,
 
   id = gtk_entry_get_text (entry);
 
-  self->priv->search_words = empathy_live_search_strip_utf8_string (id);
+  self->priv->search_words = tpaw_live_search_strip_utf8_string (id);
   self->priv->search_str = g_strdup (id);
 
   add_temporary_individuals (self, id);
@@ -412,7 +422,8 @@ empathy_contact_chooser_init (EmpathyContactChooser *self)
 
   /* Add the treeview */
   mgr = empathy_individual_manager_dup_singleton ();
-  self->priv->store = empathy_individual_store_new (mgr);
+  self->priv->store = EMPATHY_INDIVIDUAL_STORE (
+      empathy_individual_store_manager_new (mgr));
   g_object_unref (mgr);
 
   empathy_individual_store_set_show_groups (self->priv->store, FALSE);
@@ -448,6 +459,9 @@ empathy_contact_chooser_new (void)
       NULL);
 }
 
+/* Note that because of bgo #666580 the returned invidivdual is valid until
+ * @self is destroyed. To keep it around after that, the TpContact associated
+ * with the individual needs to be manually reffed. */
 FolksIndividual *
 empathy_contact_chooser_dup_selected (EmpathyContactChooser *self)
 {