]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-utils.c
improve TP_ERROR_STR_ALREADY_CONNECTED displayed error string
[empathy.git] / libempathy / empathy-utils.c
index 172e9e182cff9404d16f42586a52f615a9ca470c..8e3509b025f9cc71ecde40017c61f4e711e6e013 100644 (file)
@@ -40,6 +40,8 @@
 #include <folks/folks.h>
 #include <folks/folks-telepathy.h>
 
+#include <dbus/dbus-protocol.h>
+
 #include <telepathy-glib/account-manager.h>
 #include <telepathy-glib/connection.h>
 #include <telepathy-glib/channel.h>
@@ -48,7 +50,6 @@
 
 #include "empathy-client-factory.h"
 #include "empathy-utils.h"
-#include "empathy-contact-manager.h"
 #include "empathy-individual-manager.h"
 #include "empathy-presence-manager.h"
 #include "empathy-request-util.h"
@@ -80,6 +81,16 @@ static struct {
   { NULL, },
 };
 
+static gboolean
+properties_contains (gchar **list,
+                    gint length,
+                    const gchar *property);
+
+static gboolean
+check_writeable_property (TpConnection *connection,
+                         FolksIndividual *individual,
+                         gchar *property);
+
 void
 empathy_init (void)
 {
@@ -341,7 +352,7 @@ create_errors_to_message_hash (void)
   g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_LOST,
     _("Connection has been lost"));
   g_hash_table_insert (errors, TP_ERROR_STR_ALREADY_CONNECTED,
-    _("This resource is already connected to the server"));
+    _("This account is already connected to the server"));
   g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_REPLACED,
     _("Connection has been replaced by a new connection using the "
     "same resource"));
@@ -358,6 +369,10 @@ create_errors_to_message_hash (void)
     _("The length of the server certificate, or the depth of the "
     "server certificate chain, exceed the limits imposed by the "
     "cryptography library"));
+  g_hash_table_insert (errors, TP_ERROR_STR_SOFTWARE_UPGRADE_REQUIRED,
+    _("Your software is too old"));
+  g_hash_table_insert (errors, DBUS_ERROR_NO_REPLY,
+    _("Internal error"));
 
   return errors;
 }
@@ -382,7 +397,7 @@ empathy_account_get_error_message (TpAccount *account,
 {
   const gchar *dbus_error;
   const gchar *message;
-        const GHashTable *details = NULL;
+  const GHashTable *details = NULL;
   TpConnectionStatusReason reason;
 
   dbus_error = tp_account_get_detailed_error (account, &details);
@@ -399,11 +414,11 @@ empathy_account_get_error_message (TpAccount *account,
   if (message != NULL)
     return message;
 
+  tp_account_get_connection_status (account, &reason);
+
   DEBUG ("Don't understand error '%s'; fallback to the status reason (%u)",
     dbus_error, reason);
 
-  tp_account_get_connection_status (account, &reason);
-
   return empathy_status_reason_get_default_message (reason);
 }
 
@@ -802,10 +817,10 @@ empathy_connection_can_add_personas (TpConnection *connection)
 }
 
 gboolean
-empathy_connection_can_alias_personas (TpConnection *connection)
+empathy_connection_can_alias_personas (TpConnection *connection,
+                                      FolksIndividual *individual)
 {
   gboolean retval;
-  FolksPersonaStore *persona_store;
 
   g_return_val_if_fail (TP_IS_CONNECTION (connection), FALSE);
 
@@ -813,22 +828,16 @@ empathy_connection_can_alias_personas (TpConnection *connection)
           TP_CONNECTION_STATUS_CONNECTED)
       return FALSE;
 
-  persona_store = FOLKS_PERSONA_STORE (
-      empathy_dup_persona_store_for_connection (connection));
-
-  retval = (folks_persona_store_get_can_alias_personas (persona_store) ==
-      FOLKS_MAYBE_BOOL_TRUE);
-
-  g_clear_object (&persona_store);
+  retval = check_writeable_property (connection, individual, "alias");
 
   return retval;
 }
 
 gboolean
-empathy_connection_can_group_personas (TpConnection *connection)
+empathy_connection_can_group_personas (TpConnection *connection,
+                                      FolksIndividual *individual)
 {
   gboolean retval;
-  FolksPersonaStore *persona_store;
 
   g_return_val_if_fail (TP_IS_CONNECTION (connection), FALSE);
 
@@ -836,13 +845,7 @@ empathy_connection_can_group_personas (TpConnection *connection)
           TP_CONNECTION_STATUS_CONNECTED)
       return FALSE;
 
-  persona_store = FOLKS_PERSONA_STORE (
-      empathy_dup_persona_store_for_connection (connection));
-
-  retval = (folks_persona_store_get_can_group_personas (persona_store) ==
-      FOLKS_MAYBE_BOOL_TRUE);
-
-  g_clear_object (&persona_store);
+  retval = check_writeable_property (connection, individual, "groups");
 
   return retval;
 }
@@ -1030,3 +1033,165 @@ empathy_get_tp_contact_for_individual (FolksIndividual *individual,
   return contact;
 }
 
+static gboolean
+properties_contains (gchar **list,
+                    gint length,
+                    const gchar *property)
+{
+  gint i;
+
+  for (i = 0; i < length; i++)
+    {
+      if (!tp_strdiff (list[i], property))
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+check_writeable_property (TpConnection *connection,
+                         FolksIndividual *individual,
+                         gchar *property)
+{
+  gchar **properties;
+  gint prop_len;
+  gboolean retval = FALSE;
+  GeeSet *personas;
+  GeeIterator *iter;
+  FolksPersonaStore *persona_store;
+
+  persona_store = FOLKS_PERSONA_STORE (
+      empathy_dup_persona_store_for_connection (connection));
+
+  properties =
+    folks_persona_store_get_always_writeable_properties (persona_store,
+                                                        &prop_len);
+  retval = properties_contains (properties, prop_len, property);
+  if (retval == TRUE)
+    goto out;
+
+  /* Lets see if the Individual contains a Persona with the given property */
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+  while (!retval && gee_iterator_next (iter))
+    {
+      FolksPersona *persona = gee_iterator_get (iter);
+
+      properties =
+       folks_persona_get_writeable_properties (persona, &prop_len);
+      retval = properties_contains (properties, prop_len, property);
+
+      g_clear_object (&persona);
+
+      if (retval == TRUE)
+       break;
+    }
+  g_clear_object (&iter);
+
+out:
+  g_clear_object (&persona_store);
+  return retval;
+}
+
+/* Calculate whether the Individual can do audio or video calls.
+ * FIXME: We can remove this once libfolks has grown capabilities support
+ * again: bgo#626179. */
+void
+empathy_individual_can_audio_video_call (FolksIndividual *individual,
+    gboolean *can_audio_call,
+    gboolean *can_video_call,
+    EmpathyContact **out_contact)
+{
+  GeeSet *personas;
+  GeeIterator *iter;
+  gboolean can_audio = FALSE, can_video = FALSE;
+
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+  while (gee_iterator_next (iter))
+    {
+      FolksPersona *persona = gee_iterator_get (iter);
+      TpContact *tp_contact;
+
+      if (!empathy_folks_persona_is_interesting (persona))
+        goto while_finish;
+
+      tp_contact = tpf_persona_get_contact (TPF_PERSONA (persona));
+      if (tp_contact != NULL)
+        {
+          EmpathyContact *contact;
+
+          contact = empathy_contact_dup_from_tp_contact (tp_contact);
+          empathy_contact_set_persona (contact, persona);
+
+          can_audio = can_audio || empathy_contact_get_capabilities (contact) &
+              EMPATHY_CAPABILITIES_AUDIO;
+          can_video = can_video || empathy_contact_get_capabilities (contact) &
+              EMPATHY_CAPABILITIES_VIDEO;
+
+          if (out_contact != NULL)
+            *out_contact = g_object_ref (contact);
+
+          g_object_unref (contact);
+        }
+
+while_finish:
+      g_clear_object (&persona);
+
+      if (can_audio && can_video)
+        break;
+    }
+
+  g_clear_object (&iter);
+
+  if (can_audio_call != NULL)
+    *can_audio_call = can_audio;
+
+  if (can_video_call != NULL)
+    *can_video_call = can_video;
+}
+
+gboolean
+empathy_sasl_channel_supports_mechanism (TpChannel *channel,
+    const gchar *mechanism)
+{
+  GHashTable *props;
+  const gchar * const *available_mechanisms;
+
+  props = tp_channel_borrow_immutable_properties (channel);
+  available_mechanisms = tp_asv_get_boxed (props,
+      TP_PROP_CHANNEL_INTERFACE_SASL_AUTHENTICATION_AVAILABLE_MECHANISMS,
+      G_TYPE_STRV);
+
+  return tp_strv_contains (available_mechanisms, mechanism);
+}
+
+FolksIndividual *
+empathy_create_individual_from_tp_contact (TpContact *contact)
+{
+  GeeSet *personas;
+  TpfPersona *persona;
+  FolksIndividual *individual;
+
+  persona = tpf_persona_dup_for_contact (contact);
+  if (persona == NULL)
+    {
+      DEBUG ("Failed to get a persona for %s",
+          tp_contact_get_identifier (contact));
+      return NULL;
+    }
+
+  personas = GEE_SET (
+      gee_hash_set_new (FOLKS_TYPE_PERSONA, g_object_ref, g_object_unref,
+      g_direct_hash, g_direct_equal));
+
+  gee_collection_add (GEE_COLLECTION (personas), persona);
+
+  individual = folks_individual_new (personas);
+
+  g_clear_object (&persona);
+  g_clear_object (&personas);
+
+  return individual;
+}