]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-contact.c
Merge commit 'jtellier/video-call-button-sensitivity'
[empathy.git] / libempathy / empathy-contact.c
index eca16b9dc4a61fba1220934c520230a275e5b43d..c82ecd46714a2580715430107dfeea1348b331b2 100644 (file)
@@ -26,7 +26,6 @@
 #include <glib/gi18n-lib.h>
 
 #include <telepathy-glib/util.h>
-#include <libmissioncontrol/mc-enum-types.h>
 
 #include "empathy-contact.h"
 #include "empathy-account-manager.h"
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyContact)
 typedef struct {
   TpContact *tp_contact;
-  McAccount *account;
+  EmpathyAccount *account;
   gchar *id;
   gchar *name;
   EmpathyAvatar *avatar;
-  McPresence presence;
+  TpConnectionPresenceType presence;
   gchar *presence_message;
   guint handle;
   EmpathyCapabilities capabilities;
@@ -99,10 +98,11 @@ tp_contact_notify_cb (TpContact *tp_contact,
   if (!tp_strdiff (param->name, "alias"))
     g_object_notify (contact, "name");
   else if (!tp_strdiff (param->name, "presence-type")) {
-    McPresence presence;
+    TpConnectionPresenceType presence;
 
     presence = empathy_contact_get_presence (EMPATHY_CONTACT (contact));
-    g_signal_emit (contact, signals[PRESENCE_CHANGED], 0, presence, priv->presence);
+    g_signal_emit (contact, signals[PRESENCE_CHANGED], 0, presence,
+      priv->presence);
     priv->presence = presence;
     g_object_notify (contact, "presence");
   }
@@ -159,7 +159,7 @@ empathy_contact_class_init (EmpathyContactClass *class)
       g_param_spec_object ("account",
         "The account",
         "The account associated with the contact",
-        MC_TYPE_ACCOUNT,
+        EMPATHY_TYPE_ACCOUNT,
         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (object_class,
@@ -191,9 +191,9 @@ empathy_contact_class_init (EmpathyContactClass *class)
       g_param_spec_uint ("presence",
         "Contact presence",
         "Presence of contact",
-        MC_PRESENCE_UNSET,
-        LAST_MC_PRESENCE,
-        MC_PRESENCE_UNSET,
+        TP_CONNECTION_PRESENCE_TYPE_UNSET,
+        NUM_TP_CONNECTION_PRESENCE_TYPES,
+        TP_CONNECTION_PRESENCE_TYPE_UNSET,
         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (object_class,
@@ -246,10 +246,10 @@ empathy_contact_class_init (EmpathyContactClass *class)
                   G_SIGNAL_RUN_LAST,
                   0,
                   NULL, NULL,
-                  _empathy_marshal_VOID__ENUM_ENUM,
+                  _empathy_marshal_VOID__UINT_UINT,
                   G_TYPE_NONE,
-                  2, MC_TYPE_PRESENCE,
-                  MC_TYPE_PRESENCE);
+                  2, G_TYPE_UINT,
+                  G_TYPE_UINT);
 
   g_type_class_add_private (object_class, sizeof (EmpathyContactPriv));
 }
@@ -262,9 +262,7 @@ empathy_contact_init (EmpathyContact *contact)
 
   contact->priv = priv;
 
-  priv->location = g_hash_table_new_full (g_str_hash, g_str_equal,
-                       (GDestroyNotify) g_free,
-                       (GDestroyNotify) tp_g_value_slice_free);
+  priv->location = NULL;
 }
 
 static void
@@ -283,6 +281,9 @@ contact_finalize (GObject *object)
   if (priv->avatar)
       empathy_avatar_unref (priv->avatar);
 
+  if (priv->location != NULL)
+      g_hash_table_unref (priv->location);
+
   G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
 }
 
@@ -408,12 +409,11 @@ empathy_contact_new (TpContact *tp_contact)
 }
 
 EmpathyContact *
-empathy_contact_new_for_log (McAccount *account,
+empathy_contact_new_for_log (EmpathyAccount *account,
                              const gchar *id,
                              const gchar *name,
                              gboolean is_user)
 {
-  g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
   g_return_val_if_fail (id != NULL, NULL);
 
   return g_object_new (EMPATHY_TYPE_CONTACT,
@@ -553,7 +553,7 @@ empathy_contact_set_avatar (EmpathyContact *contact,
   g_object_notify (G_OBJECT (contact), "avatar");
 }
 
-McAccount *
+EmpathyAccount *
 empathy_contact_get_account (EmpathyContact *contact)
 {
   EmpathyContactPriv *priv;
@@ -593,54 +593,28 @@ empathy_contact_get_connection (EmpathyContact *contact)
   return NULL;
 }
 
-static McPresence
-presence_type_to_mc_presence (TpConnectionPresenceType type)
-{
-  switch (type)
-    {
-      case TP_CONNECTION_PRESENCE_TYPE_UNSET:
-      case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
-      case TP_CONNECTION_PRESENCE_TYPE_ERROR:
-        return MC_PRESENCE_UNSET;
-      case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
-        return MC_PRESENCE_OFFLINE;
-      case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
-        return MC_PRESENCE_AVAILABLE;
-      case TP_CONNECTION_PRESENCE_TYPE_AWAY:
-        return MC_PRESENCE_AWAY;
-      case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
-        return MC_PRESENCE_EXTENDED_AWAY;
-      case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
-        return MC_PRESENCE_HIDDEN;
-      case TP_CONNECTION_PRESENCE_TYPE_BUSY:
-        return MC_PRESENCE_DO_NOT_DISTURB;
-    }
-
-  return MC_PRESENCE_UNSET;
-}
-
-McPresence
+TpConnectionPresenceType
 empathy_contact_get_presence (EmpathyContact *contact)
 {
   EmpathyContactPriv *priv;
 
-  g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), MC_PRESENCE_UNSET);
+  g_return_val_if_fail (EMPATHY_IS_CONTACT (contact),
+    TP_CONNECTION_PRESENCE_TYPE_UNSET);
 
   priv = GET_PRIV (contact);
 
   if (priv->tp_contact != NULL)
-    return presence_type_to_mc_presence (tp_contact_get_presence_type (
-        priv->tp_contact));
+    return tp_contact_get_presence_type (priv->tp_contact);
 
   return priv->presence;
 }
 
 void
 empathy_contact_set_presence (EmpathyContact *contact,
-                              McPresence presence)
+                              TpConnectionPresenceType presence)
 {
   EmpathyContactPriv *priv;
-  McPresence old_presence;
+  TpConnectionPresenceType old_presence;
 
   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
@@ -788,7 +762,15 @@ empathy_contact_is_online (EmpathyContact *contact)
 {
   g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
 
-  return (empathy_contact_get_presence (contact) > MC_PRESENCE_OFFLINE);
+  switch (empathy_contact_get_presence (contact))
+    {
+      case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
+      case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
+      case TP_CONNECTION_PRESENCE_TYPE_ERROR:
+        return FALSE;
+      default:
+        return TRUE;
+    }
 }
 
 const gchar *
@@ -819,6 +801,30 @@ empathy_contact_can_voip (EmpathyContact *contact)
       EMPATHY_CAPABILITIES_VIDEO);
 }
 
+gboolean
+empathy_contact_can_voip_audio (EmpathyContact *contact)
+{
+  EmpathyContactPriv *priv;
+
+  g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
+
+  priv = GET_PRIV (contact);
+
+  return priv->capabilities & EMPATHY_CAPABILITIES_AUDIO;
+}
+
+gboolean
+empathy_contact_can_voip_video (EmpathyContact *contact)
+{
+  EmpathyContactPriv *priv;
+
+  g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
+
+  priv = GET_PRIV (contact);
+
+  return priv->capabilities & EMPATHY_CAPABILITIES_VIDEO;
+}
+
 gboolean
 empathy_contact_can_send_files (EmpathyContact *contact)
 {
@@ -831,21 +837,32 @@ empathy_contact_can_send_files (EmpathyContact *contact)
   return priv->capabilities & EMPATHY_CAPABILITIES_FT;
 }
 
+gboolean
+empathy_contact_can_use_stream_tube (EmpathyContact *contact)
+{
+  EmpathyContactPriv *priv;
+
+  g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
+
+  priv = GET_PRIV (contact);
+
+  return priv->capabilities & EMPATHY_CAPABILITIES_STREAM_TUBE;
+}
+
 static gchar *
 contact_get_avatar_filename (EmpathyContact *contact,
                              const gchar *token)
 {
-  EmpathyContactPriv *priv = GET_PRIV (contact);
-  McAccount *account;
+  EmpathyAccount *account;
   gchar *avatar_path;
   gchar *avatar_file;
   gchar *token_escaped;
   gchar *contact_escaped;
 
-  if (EMP_STR_EMPTY (priv->id))
+  if (EMP_STR_EMPTY (empathy_contact_get_id (contact)))
     return NULL;
 
-  contact_escaped = tp_escape_as_identifier (priv->id);
+  contact_escaped = tp_escape_as_identifier (empathy_contact_get_id (contact));
   token_escaped = tp_escape_as_identifier (token);
   account = empathy_contact_get_account (contact);
 
@@ -853,7 +870,7 @@ contact_get_avatar_filename (EmpathyContact *contact,
   avatar_path = g_build_filename (g_get_user_cache_dir (),
       PACKAGE_NAME,
       "avatars",
-      mc_account_get_unique_name (account),
+      empathy_account_get_unique_name (account),
       contact_escaped,
       NULL);
   g_mkdir_with_parents (avatar_path, 0700);
@@ -869,7 +886,7 @@ contact_get_avatar_filename (EmpathyContact *contact,
 
 void
 empathy_contact_load_avatar_data (EmpathyContact *contact,
-                                  const guchar  *data,
+                                  const guchar *data,
                                   const gsize len,
                                   const gchar *format,
                                   const gchar *token)
@@ -885,13 +902,13 @@ empathy_contact_load_avatar_data (EmpathyContact *contact,
   g_return_if_fail (!EMP_STR_EMPTY (token));
 
   /* Load and set the avatar */
+  filename = contact_get_avatar_filename (contact, token);
   avatar = empathy_avatar_new (g_memdup (data, len), len, g_strdup (format),
-      g_strdup (token));
+      g_strdup (token), filename);
   empathy_contact_set_avatar (contact, avatar);
   empathy_avatar_unref (avatar);
 
   /* Save to cache if not yet in it */
-  filename = contact_get_avatar_filename (contact, token);
   if (filename && !g_file_test (filename, G_FILE_TEST_EXISTS))
     {
       if (!empathy_avatar_save_to_file (avatar, filename, &error))
@@ -903,7 +920,6 @@ empathy_contact_load_avatar_data (EmpathyContact *contact,
       else
           DEBUG ("Avatar saved to %s", filename);
     }
-  g_free (filename);
 }
 
 gboolean
@@ -934,13 +950,11 @@ empathy_contact_load_avatar_cache (EmpathyContact *contact,
   if (data)
     {
       DEBUG ("Avatar loaded from %s", filename);
-      avatar = empathy_avatar_new (data, len, NULL, g_strdup (token));
+      avatar = empathy_avatar_new (data, len, NULL, g_strdup (token), filename);
       empathy_contact_set_avatar (contact, avatar);
       empathy_avatar_unref (avatar);
     }
 
-  g_free (filename);
-
   return data != NULL;
 }
 
@@ -959,11 +973,25 @@ empathy_avatar_get_type (void)
   return type_id;
 }
 
+/**
+ * empathy_avatar_new:
+ * @data: the avatar data
+ * @len: the size of avatar data
+ * @format: the mime type of the avatar image
+ * @token: the token of the avatar
+ * @filename: the filename where the avatar is stored in cache
+ *
+ * Create a #EmpathyAvatar from the provided data. This function takes the
+ * ownership of @data, @format, @token and @filename.
+ *
+ * Returns: a new #EmpathyAvatar
+ */
 EmpathyAvatar *
 empathy_avatar_new (guchar *data,
                     gsize len,
                     gchar *format,
-                    gchar *token)
+                    gchar *token,
+                    gchar *filename)
 {
   EmpathyAvatar *avatar;
 
@@ -972,6 +1000,7 @@ empathy_avatar_new (guchar *data,
   avatar->len = len;
   avatar->format = format;
   avatar->token = token;
+  avatar->filename = filename;
   avatar->refcount = 1;
 
   return avatar;
@@ -1010,7 +1039,7 @@ empathy_avatar_ref (EmpathyAvatar *avatar)
  *
  * Save the avatar to a file named filename
  *
- * Returns: %TRUE on success, %FALSE if an error occurred 
+ * Returns: %TRUE on success, %FALSE if an error occurred
  */
 gboolean
 empathy_avatar_save_to_file (EmpathyAvatar *self,
@@ -1045,7 +1074,7 @@ empathy_contact_get_location (EmpathyContact *contact)
 
   priv = GET_PRIV (contact);
 
-  return g_hash_table_ref (priv->location);
+  return priv->location;
 }
 
 /**
@@ -1059,7 +1088,7 @@ empathy_contact_get_location (EmpathyContact *contact)
  * Example: a "city" key would have "Helsinki" as string GValue,
  *          a "latitude" would have 65.0 as double GValue.
  */
-void 
+void
 empathy_contact_set_location (EmpathyContact *contact,
                               GHashTable *location)
 {
@@ -1070,8 +1099,46 @@ empathy_contact_set_location (EmpathyContact *contact,
 
   priv = GET_PRIV (contact);
 
-  g_hash_table_unref (priv->location);
+  if (priv->location != NULL)
+    g_hash_table_unref (priv->location);
 
   priv->location = g_hash_table_ref (location);
   g_object_notify (G_OBJECT (contact), "location");
 }
+
+/**
+ * empathy_contact_equal:
+ * @contact1: an #EmpathyContact
+ * @contact2: an #EmpathyContact
+ *
+ * Returns FALSE if one of the contacts is NULL but the other is not.
+ * Otherwise returns TRUE if both pointer are equal or if they bith
+ * refer to the same id.
+ * It's only necessary to call this function if your contact objects
+ * come from logs where contacts are created dynamically and comparing
+ * pointers is not enough.
+ */
+gboolean
+empathy_contact_equal (gconstpointer contact1,
+                       gconstpointer contact2)
+{
+  EmpathyContact *c1;
+  EmpathyContact *c2;
+  const gchar *id1;
+  const gchar *id2;
+
+  if ((contact1 == NULL) != (contact2 == NULL)) {
+    return FALSE;
+  }
+  if (contact1 == contact2) {
+    return TRUE;
+  }
+  c1 = EMPATHY_CONTACT (contact1);
+  c2 = EMPATHY_CONTACT (contact2);
+  id1 = empathy_contact_get_id (c1);
+  id2 = empathy_contact_get_id (c2);
+  if (!tp_strdiff (id1, id2)) {
+    return TRUE;
+  }
+  return FALSE;
+}