]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-contact.c
Merge branch 'folks-async-and-prepare'
[empathy.git] / libempathy / empathy-contact.c
index 64235ea9a4375e8ee3a38e39bb294b279bca8704..6842cde09d8078f60afd055236836eabf5d551bb 100644 (file)
@@ -51,10 +51,9 @@ typedef struct {
   TpAccount *account;
   FolksPersona *persona;
   gchar *id;
-  gchar *name;
+  gchar *alias;
   EmpathyAvatar *avatar;
   TpConnectionPresenceType presence;
-  gchar *presence_message;
   guint handle;
   EmpathyCapabilities capabilities;
   gboolean is_user;
@@ -67,6 +66,7 @@ typedef struct {
    * more fields by searching the address using geoclue.
    */
   GHashTable *location;
+  GHashTable *groups;
 } EmpathyContactPriv;
 
 static void contact_finalize (GObject *object);
@@ -96,7 +96,7 @@ enum
   PROP_ACCOUNT,
   PROP_PERSONA,
   PROP_ID,
-  PROP_NAME,
+  PROP_ALIAS,
   PROP_AVATAR,
   PROP_PRESENCE,
   PROP_PRESENCE_MESSAGE,
@@ -125,7 +125,7 @@ tp_contact_notify_cb (TpContact *tp_contact,
 
   /* Forward property notifications */
   if (!tp_strdiff (param->name, "alias"))
-    g_object_notify (contact, "name");
+    g_object_notify (contact, "alias");
   else if (!tp_strdiff (param->name, "presence-type")) {
     TpConnectionPresenceType presence;
 
@@ -135,8 +135,6 @@ tp_contact_notify_cb (TpContact *tp_contact,
     priv->presence = presence;
     g_object_notify (contact, "presence");
   }
-  else if (!tp_strdiff (param->name, "presence-message"))
-    g_object_notify (contact, "presence-message");
   else if (!tp_strdiff (param->name, "identifier"))
     g_object_notify (contact, "id");
   else if (!tp_strdiff (param->name, "handle"))
@@ -160,6 +158,15 @@ tp_contact_notify_cb (TpContact *tp_contact,
     }
 }
 
+static void
+folks_persona_notify_cb (FolksPersona *folks_persona,
+                         GParamSpec *param,
+                         GObject *contact)
+{
+  if (!tp_strdiff (param->name, "presence-message"))
+    g_object_notify (contact, "presence-message");
+}
+
 static void
 contact_dispose (GObject *object)
 {
@@ -179,7 +186,11 @@ contact_dispose (GObject *object)
   priv->account = NULL;
 
   if (priv->persona)
-    g_object_unref (priv->persona);
+    {
+      g_signal_handlers_disconnect_by_func (priv->persona,
+          folks_persona_notify_cb, object);
+      g_object_unref (priv->persona);
+    }
   priv->persona = NULL;
 
   if (priv->avatar != NULL)
@@ -242,10 +253,10 @@ empathy_contact_class_init (EmpathyContactClass *class)
         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (object_class,
-      PROP_NAME,
-      g_param_spec_string ("name",
-        "Contact Name",
-        "The name of the contact",
+      PROP_ALIAS,
+      g_param_spec_string ("alias",
+        "Contact alias",
+        "An alias for the contact",
         NULL,
         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -334,6 +345,7 @@ empathy_contact_init (EmpathyContact *contact)
   contact->priv = priv;
 
   priv->location = NULL;
+  priv->groups = NULL;
 }
 
 static void
@@ -345,9 +357,10 @@ contact_finalize (GObject *object)
 
   DEBUG ("finalize: %p", object);
 
-  g_free (priv->name);
+  if (priv->groups != NULL)
+    g_hash_table_destroy (priv->groups);
+  g_free (priv->alias);
   g_free (priv->id);
-  g_free (priv->presence_message);
 
   G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
 }
@@ -411,8 +424,8 @@ contact_get_property (GObject *object,
       case PROP_ID:
         g_value_set_string (value, empathy_contact_get_id (contact));
         break;
-      case PROP_NAME:
-        g_value_set_string (value, empathy_contact_get_name (contact));
+      case PROP_ALIAS:
+        g_value_set_string (value, empathy_contact_get_alias (contact));
         break;
       case PROP_AVATAR:
         g_value_set_boxed (value, empathy_contact_get_avatar (contact));
@@ -462,8 +475,8 @@ contact_set_property (GObject *object,
       case PROP_ID:
         empathy_contact_set_id (contact, g_value_get_string (value));
         break;
-      case PROP_NAME:
-        empathy_contact_set_name (contact, g_value_get_string (value));
+      case PROP_ALIAS:
+        empathy_contact_set_alias (contact, g_value_get_string (value));
         break;
       case PROP_AVATAR:
         empathy_contact_set_avatar (contact, g_value_get_boxed (value));
@@ -512,7 +525,7 @@ empathy_contact_from_tpl_contact (TpAccount *account,
 
   retval = g_object_new (EMPATHY_TYPE_CONTACT,
       "id", tpl_entity_get_alias (tpl_entity),
-      "name", tpl_entity_get_identifier (tpl_entity),
+      "alias", tpl_entity_get_identifier (tpl_entity),
       "account", account,
       "is-user", is_user,
       NULL);
@@ -527,7 +540,7 @@ empathy_contact_from_tpl_contact (TpAccount *account,
 EmpathyContact *
 empathy_contact_new_for_log (TpAccount *account,
                              const gchar *id,
-                             const gchar *name,
+                             const gchar *alias,
                              gboolean is_user)
 {
   g_return_val_if_fail (id != NULL, NULL);
@@ -536,7 +549,7 @@ empathy_contact_new_for_log (TpAccount *account,
   return g_object_new (EMPATHY_TYPE_CONTACT,
       "account", account,
       "id", id,
-      "name", name,
+      "alias", alias,
       "is-user", is_user,
       NULL);
 }
@@ -588,15 +601,15 @@ empathy_contact_set_id (EmpathyContact *contact,
       priv->id = g_strdup (id);
 
       g_object_notify (G_OBJECT (contact), "id");
-      if (EMP_STR_EMPTY (priv->name))
-          g_object_notify (G_OBJECT (contact), "name");
+      if (EMP_STR_EMPTY (priv->alias))
+          g_object_notify (G_OBJECT (contact), "alias");
     }
 
   g_object_unref (contact);
 }
 
 const gchar *
-empathy_contact_get_name (EmpathyContact *contact)
+empathy_contact_get_alias (EmpathyContact *contact)
 {
   EmpathyContactPriv *priv;
   const gchar        *alias;
@@ -608,7 +621,7 @@ empathy_contact_get_name (EmpathyContact *contact)
   if (priv->tp_contact != NULL)
     alias = tp_contact_get_alias (priv->tp_contact);
   else
-    alias = priv->name;
+    alias = priv->alias;
 
   if (!EMP_STR_EMPTY (alias))
     return alias;
@@ -617,61 +630,86 @@ empathy_contact_get_name (EmpathyContact *contact)
 }
 
 void
-empathy_contact_set_name (EmpathyContact *contact,
-                          const gchar *name)
+empathy_contact_set_alias (EmpathyContact *contact,
+                          const gchar *alias)
 {
   EmpathyContactPriv *priv;
+  FolksPersona *persona;
 
   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
   priv = GET_PRIV (contact);
 
   g_object_ref (contact);
-  if (tp_strdiff (name, priv->name))
+
+  /* Set the alias on the persona if possible */
+  persona = empathy_contact_get_persona (contact);
+  if (persona != NULL && FOLKS_IS_ALIAS (persona))
     {
-      g_free (priv->name);
-      priv->name = g_strdup (name);
-      g_object_notify (G_OBJECT (contact), "name");
+      DEBUG ("Setting alias for contact %s to %s",
+          empathy_contact_get_id (contact), alias);
+
+      folks_alias_set_alias (FOLKS_ALIAS (persona), alias);
+    }
+
+  if (tp_strdiff (alias, priv->alias))
+    {
+      g_free (priv->alias);
+      priv->alias = g_strdup (alias);
+      g_object_notify (G_OBJECT (contact), "alias");
     }
+
   g_object_unref (contact);
 }
 
 static void
-contact_set_aliases_cb (TpConnection *connection,
-    const GError *error,
-    gpointer user_data,
-    GObject *weak_object)
+groups_change_group_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
 {
-       if (error)
-               DEBUG ("Error: %s", error->message);
+  FolksGroups *groups = FOLKS_GROUPS (source);
+  GError *error = NULL;
+
+  folks_groups_change_group_finish (groups, result, &error);
+  if (error != NULL)
+    {
+      g_warning ("failed to change group: %s", error->message);
+      g_clear_error (&error);
+    }
 }
 
 void
-empathy_contact_set_alias (EmpathyContact *contact,
-    const gchar *alias)
+empathy_contact_change_group (EmpathyContact *contact, const gchar *group,
+    gboolean is_member)
 {
-       TpConnection *connection;
-       GHashTable *new_alias;
-       guint handle;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-       handle = empathy_contact_get_handle (contact);
+  EmpathyContactPriv *priv;
+  FolksPersona *persona;
 
-       DEBUG ("Setting alias for contact %s (%d) to %s",
-               empathy_contact_get_id (contact),
-               handle, alias);
+  g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+  g_return_if_fail (group != NULL);
 
-       new_alias = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
-           g_free);
+  priv = GET_PRIV (contact);
 
-       g_hash_table_insert (new_alias, GUINT_TO_POINTER (handle), g_strdup (alias));
+  /* Normally pass through the changes to the persona */
+  persona = empathy_contact_get_persona (contact);
+  if (persona != NULL)
+    {
+      if (FOLKS_IS_GROUPS (persona))
+        folks_groups_change_group (FOLKS_GROUPS (persona), group, is_member,
+          groups_change_group_cb, contact);
+      return;
+    }
 
-       connection = empathy_contact_get_connection (contact);
-       tp_cli_connection_interface_aliasing_call_set_aliases (connection, -1,
-           new_alias, contact_set_aliases_cb, NULL, NULL, NULL);
+  /* If the persona doesn't exist yet, we have to cache the changes until it
+   * does */
+  if (priv->groups == NULL)
+    {
+      priv->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+          NULL);
+    }
 
-       g_hash_table_destroy (new_alias);
+  g_hash_table_insert (priv->groups, g_strdup (group),
+      GUINT_TO_POINTER (is_member));
 }
 
 EmpathyAvatar *
@@ -791,7 +829,7 @@ empathy_contact_set_persona (EmpathyContact *contact,
   EmpathyContactPriv *priv;
 
   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-  g_return_if_fail (FOLKS_IS_PERSONA (persona));
+  g_return_if_fail (TPF_IS_PERSONA (persona));
 
   priv = GET_PRIV (contact);
 
@@ -802,7 +840,23 @@ empathy_contact_set_persona (EmpathyContact *contact,
     g_object_unref (priv->persona);
   priv->persona = g_object_ref (persona);
 
+  g_signal_connect (priv->persona, "notify",
+    G_CALLBACK (folks_persona_notify_cb), contact);
+
   g_object_notify (G_OBJECT (contact), "persona");
+
+  /* Set the persona's alias, since ours could've been set using
+   * empathy_contact_set_alias() before we had a persona; this happens when
+   * adding a contact. */
+  empathy_contact_set_alias (contact, priv->alias);
+
+  /* Set the persona's groups */
+  if (priv->groups != NULL)
+    {
+      folks_groups_set_groups (FOLKS_GROUPS (persona), priv->groups);
+      g_hash_table_destroy (priv->groups);
+      priv->groups = NULL;
+    }
 }
 
 TpConnection *
@@ -867,10 +921,10 @@ empathy_contact_get_presence_message (EmpathyContact *contact)
 
   priv = GET_PRIV (contact);
 
-  if (priv->tp_contact != NULL)
-    return tp_contact_get_presence_message (priv->tp_contact);
+  if (priv->persona != NULL)
+    return folks_presence_get_presence_message (FOLKS_PRESENCE (priv->persona));
 
-  return priv->presence_message;
+  return NULL;
 }
 
 void
@@ -881,13 +935,11 @@ empathy_contact_set_presence_message (EmpathyContact *contact,
 
   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
-  if (!tp_strdiff (message, priv->presence_message))
-    return;
-
-  g_free (priv->presence_message);
-  priv->presence_message = g_strdup (message);
-
-  g_object_notify (G_OBJECT (contact), "presence-message");
+  if (priv->persona != NULL)
+    {
+      folks_presence_set_presence_message (FOLKS_PRESENCE (priv->persona),
+          message);
+    }
 }
 
 guint