#include <telepathy-glib/account-manager.h>
#include <telepathy-glib/interfaces.h>
#include <telepathy-glib/util.h>
+#include <telepathy-yell/telepathy-yell.h>
#include <telepathy-logger/log-manager.h>
#include <folks/folks.h>
#include <folks/folks-telepathy.h>
-#ifdef HAVE_GEOCLUE
-#include <geoclue/geoclue-geocode.h>
+#ifdef HAVE_GEOCODE
+#include <geocode-glib/geocode-glib.h>
#endif
#include "empathy-contact.h"
+#include "empathy-camera-monitor.h"
+#include "empathy-individual-manager.h"
#include "empathy-utils.h"
#include "empathy-enum-types.h"
-#include "empathy-marshal.h"
#include "empathy-location.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
FolksPersona *persona;
gchar *id;
gchar *alias;
+ gchar *logged_alias;
EmpathyAvatar *avatar;
TpConnectionPresenceType presence;
guint handle;
* more fields by searching the address using geoclue.
*/
GHashTable *location;
- GHashTable *groups;
+ GeeHashSet *groups;
+ gchar **client_types;
} EmpathyContactPriv;
static void contact_finalize (GObject *object);
static void contact_set_property (GObject *object, guint param_id,
const GValue *value, GParamSpec *pspec);
-#ifdef HAVE_GEOCLUE
+#ifdef HAVE_GEOCODE
static void update_geocode (EmpathyContact *contact);
#endif
static void empathy_contact_set_location (EmpathyContact *contact,
GHashTable *location);
+static void contact_set_client_types (EmpathyContact *contact,
+ const gchar * const *types);
+
static void set_capabilities_from_tp_caps (EmpathyContact *self,
TpCapabilities *caps);
PROP_PERSONA,
PROP_ID,
PROP_ALIAS,
+ PROP_LOGGED_ALIAS,
PROP_AVATAR,
PROP_PRESENCE,
PROP_PRESENCE_MESSAGE,
PROP_HANDLE,
PROP_CAPABILITIES,
PROP_IS_USER,
- PROP_LOCATION
+ PROP_LOCATION,
+ PROP_CLIENT_TYPES
};
enum {
{
contact_set_avatar_from_tp_contact (EMPATHY_CONTACT (contact));
}
+ else if (!tp_strdiff (param->name, "client-types"))
+ {
+ contact_set_client_types (EMPATHY_CONTACT (contact),
+ tp_contact_get_client_types (tp_contact));
+ }
}
static void
{
EmpathyContactPriv *priv = GET_PRIV (object);
- if (priv->tp_contact)
+ if (priv->tp_contact != NULL)
{
- g_hash_table_remove (contacts_table, priv->tp_contact);
g_signal_handlers_disconnect_by_func (priv->tp_contact,
tp_contact_notify_cb, object);
- g_object_unref (priv->tp_contact);
}
- priv->tp_contact = NULL;
+ tp_clear_object (&priv->tp_contact);
if (priv->account)
g_object_unref (priv->account);
GHashTable *location;
TpHandle self_handle;
TpHandle handle;
+ const gchar * const *client_types;
if (priv->tp_contact == NULL)
return;
if (location != NULL)
empathy_contact_set_location (contact, location);
+ client_types = tp_contact_get_client_types (priv->tp_contact);
+ if (client_types != NULL)
+ contact_set_client_types (contact, client_types);
+
set_capabilities_from_tp_caps (contact,
tp_contact_get_capabilities (priv->tp_contact));
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_LOGGED_ALIAS,
+ g_param_spec_string ("logged-alias",
+ "Logged alias",
+ "The alias the user had when a message was logged, "
+ "only set when using empathy_contact_from_tpl_contact()",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_property (object_class,
PROP_AVATAR,
g_param_spec_boxed ("avatar",
G_TYPE_HASH_TABLE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_CLIENT_TYPES,
+ g_param_spec_boxed ("client-types",
+ "Contact client types",
+ "Client types of the contact",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
signals[PRESENCE_CHANGED] =
g_signal_new ("presence-changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _empathy_marshal_VOID__UINT_UINT,
+ g_cclosure_marshal_generic,
G_TYPE_NONE,
2, G_TYPE_UINT,
G_TYPE_UINT);
contact->priv = priv;
priv->location = NULL;
+ priv->client_types = NULL;
priv->groups = NULL;
}
DEBUG ("finalize: %p", object);
- if (priv->groups != NULL)
- g_hash_table_destroy (priv->groups);
+ g_clear_object (&priv->groups);
g_free (priv->alias);
g_free (priv->id);
+ g_strfreev (priv->client_types);
G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
}
if (priv->persona != NULL)
{
- folks_presence_set_presence_message (FOLKS_PRESENCE (priv->persona),
- message);
+ folks_presence_details_set_presence_message (
+ FOLKS_PRESENCE_DETAILS (priv->persona), message);
}
}
case PROP_ALIAS:
g_value_set_string (value, empathy_contact_get_alias (contact));
break;
+ case PROP_LOGGED_ALIAS:
+ g_value_set_string (value, empathy_contact_get_logged_alias (contact));
+ break;
case PROP_AVATAR:
g_value_set_boxed (value, empathy_contact_get_avatar (contact));
break;
case PROP_ALIAS:
empathy_contact_set_alias (contact, g_value_get_string (value));
break;
+ case PROP_LOGGED_ALIAS:
+ g_assert (priv->logged_alias == NULL);
+ priv->logged_alias = g_value_dup_string (value);
+ break;
case PROP_PRESENCE:
empathy_contact_set_presence (contact, g_value_get_uint (value));
break;
};
}
+static void
+remove_tp_contact (gpointer data,
+ GObject *object)
+{
+ g_hash_table_remove (contacts_table, data);
+}
+
static EmpathyContact *
empathy_contact_new (TpContact *tp_contact)
{
+ EmpathyContact *retval;
+
g_return_val_if_fail (TP_IS_CONTACT (tp_contact), NULL);
- return g_object_new (EMPATHY_TYPE_CONTACT,
+ retval = g_object_new (EMPATHY_TYPE_CONTACT,
"tp-contact", tp_contact,
NULL);
+
+ g_object_weak_ref (G_OBJECT (retval), remove_tp_contact, tp_contact);
+
+ return retval;
+}
+
+typedef struct
+{
+ TplEntity *entity;
+ TpAccount *account;
+} FindContactData;
+
+static gboolean
+contact_is_tpl_entity (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ EmpathyContact *contact = value;
+ FindContactData *data = user_data;
+ TpAccount *account = empathy_contact_get_account (contact);
+ const gchar *path = NULL;
+
+ if (account != NULL)
+ path = tp_proxy_get_object_path (account);
+
+ return !tp_strdiff (empathy_contact_get_id (contact),
+ tpl_entity_get_identifier (data->entity)) &&
+ !tp_strdiff (tp_proxy_get_object_path (data->account), path);
+}
+
+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)
+{
+ EmpathyContact *self = (EmpathyContact *) weak_object;
+ EmpathyContactPriv *priv = GET_PRIV (self);
+ TpContact *tp_contact;
+
+ if (n_contacts != 1)
+ return;
+
+ tp_contact = contacts[0];
+
+ g_return_if_fail (priv->tp_contact == NULL);
+ priv->tp_contact = g_object_ref (tp_contact);
+ g_object_notify (G_OBJECT (self), "tp-contact");
+
+ /* Update capabilities now that we have a TpContact */
+ set_capabilities_from_tp_caps (self,
+ tp_contact_get_capabilities (tp_contact));
}
EmpathyContact *
{
EmpathyContact *retval;
gboolean is_user;
+ EmpathyContact *existing_contact = NULL;
g_return_val_if_fail (TPL_IS_ENTITY (tpl_entity), NULL);
- is_user = (TPL_ENTITY_SELF == tpl_entity_get_entity_type (tpl_entity));
+ if (contacts_table != NULL)
+ {
+ FindContactData data;
- retval = g_object_new (EMPATHY_TYPE_CONTACT,
- "id", tpl_entity_get_alias (tpl_entity),
- "alias", tpl_entity_get_identifier (tpl_entity),
- "account", account,
- "is-user", is_user,
- NULL);
+ data.entity = tpl_entity;
+ data.account = account;
+
+ existing_contact = g_hash_table_find (contacts_table,
+ contact_is_tpl_entity, &data);
+ }
+
+ if (existing_contact != NULL)
+ {
+ retval = g_object_new (EMPATHY_TYPE_CONTACT,
+ "tp-contact", empathy_contact_get_tp_contact (existing_contact),
+ "logged-alias", tpl_entity_get_alias (tpl_entity),
+ NULL);
+ }
+ else
+ {
+ TpConnection *conn;
+ const gchar *id;
+
+ is_user = (TPL_ENTITY_SELF == tpl_entity_get_entity_type (tpl_entity));
+
+ id = tpl_entity_get_identifier (tpl_entity);
+
+ retval = g_object_new (EMPATHY_TYPE_CONTACT,
+ "id", id,
+ "alias", tpl_entity_get_alias (tpl_entity),
+ "account", account,
+ "is-user", is_user,
+ NULL);
+
+ /* Try to get a TpContact associated to have at least contact
+ * capabilities if possible. This is useful for CM supporting calling
+ * offline contacts for example. */
+ conn = tp_account_get_connection (account);
+ if (conn != NULL)
+ {
+ TpContactFeature features[] = { TP_CONTACT_FEATURE_CAPABILITIES };
+ conn = tp_account_get_connection (account);
+
+ tp_connection_get_contacts_by_id (conn, 1, &id,
+ G_N_ELEMENTS (features), features, get_contacts_cb,
+ NULL, NULL, G_OBJECT (retval));
+ }
+ }
if (!EMP_STR_EMPTY (tpl_entity_get_avatar_token (tpl_entity)))
contact_load_avatar_cache (retval,
empathy_contact_get_alias (EmpathyContact *contact)
{
EmpathyContactPriv *priv;
- const gchar *alias;
+ const gchar *alias = NULL;
g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
priv = GET_PRIV (contact);
- if (priv->tp_contact != NULL)
- alias = tp_contact_get_alias (priv->tp_contact);
- else
+ if (!EMP_STR_EMPTY (priv->alias))
alias = priv->alias;
+ else if (priv->tp_contact != NULL)
+ alias = tp_contact_get_alias (priv->tp_contact);
if (!EMP_STR_EMPTY (alias))
return alias;
return empathy_contact_get_id (contact);
}
+const gchar *
+empathy_contact_get_logged_alias (EmpathyContact *contact)
+{
+ EmpathyContactPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ priv = GET_PRIV (contact);
+
+ if (priv->logged_alias != NULL)
+ return priv->logged_alias;
+ else
+ return empathy_contact_get_alias (contact);
+}
+
void
empathy_contact_set_alias (EmpathyContact *contact,
const gchar *alias)
/* Set the alias on the persona if possible */
persona = empathy_contact_get_persona (contact);
- if (persona != NULL && FOLKS_IS_ALIASABLE (persona))
+ if (persona != NULL && FOLKS_IS_ALIAS_DETAILS (persona))
{
DEBUG ("Setting alias for contact %s to %s",
empathy_contact_get_id (contact), alias);
- folks_aliasable_set_alias (FOLKS_ALIASABLE (persona), alias);
+ folks_alias_details_set_alias (FOLKS_ALIAS_DETAILS (persona), alias);
}
if (tp_strdiff (alias, priv->alias))
GAsyncResult *result,
gpointer user_data)
{
- FolksGroupable *groupable = FOLKS_GROUPABLE (source);
+ FolksGroupDetails *group_details = FOLKS_GROUP_DETAILS (source);
GError *error = NULL;
- folks_groupable_change_group_finish (groupable, result, &error);
+ folks_group_details_change_group_finish (group_details, result, &error);
if (error != NULL)
{
g_warning ("failed to change group: %s", error->message);
persona = empathy_contact_get_persona (contact);
if (persona != NULL)
{
- if (FOLKS_IS_GROUPABLE (persona))
- folks_groupable_change_group (FOLKS_GROUPABLE (persona), group, is_member,
- groups_change_group_cb, contact);
+ if (FOLKS_IS_GROUP_DETAILS (persona))
+ folks_group_details_change_group (FOLKS_GROUP_DETAILS (persona), group,
+ is_member, groups_change_group_cb, contact);
return;
}
* does */
if (priv->groups == NULL)
{
- priv->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- NULL);
+ priv->groups = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup,
+ g_free, g_str_hash, g_str_equal);
}
- g_hash_table_insert (priv->groups, g_strdup (group),
- GUINT_TO_POINTER (is_member));
+ gee_collection_add (GEE_COLLECTION (priv->groups), group);
}
EmpathyAvatar *
/* FIXME: This assume the account manager already exists */
connection = tp_contact_get_connection (priv->tp_contact);
priv->account =
- g_object_ref (empathy_get_account_for_connection (connection));
+ g_object_ref (tp_connection_get_account (connection));
}
return priv->account;
if (priv->persona == NULL && priv->tp_contact != NULL)
{
- /* FIXME: This is disgustingly slow */
- /* Query for the persona */
- EmpathyIndividualManager *manager;
- GList *individuals, *l;
-
- manager = empathy_individual_manager_dup_singleton ();
- individuals = empathy_individual_manager_get_members (manager);
+ TpfPersona *persona;
- for (l = individuals; l != NULL; l = l->next)
+ persona = tpf_persona_dup_for_contact (priv->tp_contact);
+ if (persona != NULL)
{
- GList *personas, *j;
- FolksIndividual *individual = FOLKS_INDIVIDUAL (l->data);
-
- personas = folks_individual_get_personas (individual);
- for (j = personas; j != NULL; j = j->next)
- {
- TpfPersona *persona = j->data;
-
- if (TPF_IS_PERSONA (persona))
- {
- TpContact *tp_contact = tpf_persona_get_contact (persona);
-
- if (tp_contact == priv->tp_contact)
- {
- /* Found the right persona */
- empathy_contact_set_persona (contact,
- (FolksPersona *) persona);
- goto finished;
- }
- }
- }
+ empathy_contact_set_persona (contact, (FolksPersona *) persona);
+ g_object_unref (persona);
}
-
-finished:
- g_list_free (individuals);
- g_object_unref (manager);
}
return priv->persona;
/* Set the persona's groups */
if (priv->groups != NULL)
{
- folks_groupable_set_groups (FOLKS_GROUPABLE (persona), priv->groups);
- g_hash_table_destroy (priv->groups);
+ folks_group_details_set_groups (FOLKS_GROUP_DETAILS (persona),
+ GEE_SET (priv->groups));
+ g_object_unref (priv->groups);
priv->groups = NULL;
}
}
priv = GET_PRIV (contact);
if (priv->persona != NULL)
- return folks_presence_get_presence_message (FOLKS_PRESENCE (priv->persona));
+ return folks_presence_details_get_presence_message (
+ FOLKS_PRESENCE_DETAILS (priv->persona));
+
+ if (priv->tp_contact != NULL)
+ return tp_contact_get_presence_message (priv->tp_contact);
return NULL;
}
empathy_contact_get_presence (contact));
}
+gboolean
+empathy_contact_can_sms (EmpathyContact *contact)
+{
+ EmpathyContactPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
+
+ priv = GET_PRIV (contact);
+
+ return priv->capabilities & EMPATHY_CAPABILITIES_SMS;
+}
+
gboolean
empathy_contact_can_voip (EmpathyContact *contact)
{
contact_has_log (EmpathyContact *contact)
{
TplLogManager *manager;
+ TplEntity *entity;
gboolean have_log;
manager = tpl_log_manager_dup_singleton ();
+ entity = tpl_entity_new (empathy_contact_get_id (contact),
+ TPL_ENTITY_CONTACT, NULL, NULL);
+
have_log = tpl_log_manager_exists (manager,
- empathy_contact_get_account (contact), empathy_contact_get_id (contact),
- FALSE);
+ empathy_contact_get_account (contact), entity, TPL_EVENT_MASK_TEXT);
+
+ g_object_unref (entity);
g_object_unref (manager);
return have_log;
case EMPATHY_ACTION_CHAT:
sensitivity = TRUE;
break;
+ case EMPATHY_ACTION_SMS:
+ sensitivity = empathy_contact_can_sms (self);
+ break;
case EMPATHY_ACTION_AUDIO_CALL:
sensitivity = empathy_contact_can_voip_audio (self);
break;
}
}
- if (data)
+ if (data != NULL)
{
DEBUG ("Avatar loaded from %s", filename);
avatar = empathy_avatar_new ((guchar *) data, len, NULL, filename);
contact_set_avatar (contact, avatar);
empathy_avatar_unref (avatar);
}
- else
- {
- g_free (filename);
- }
+
+ g_free (data);
+ g_free (filename);
return data != NULL;
}
* @format: the mime type of the avatar image
* @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 and @filename.
+ * Create a #EmpathyAvatar from the provided data.
*
* Returns: a new #EmpathyAvatar
*/
EmpathyAvatar *
-empathy_avatar_new (guchar *data,
+empathy_avatar_new (const guchar *data,
gsize len,
- gchar *format,
- gchar *filename)
+ const gchar *format,
+ const gchar *filename)
{
EmpathyAvatar *avatar;
avatar = g_slice_new0 (EmpathyAvatar);
- avatar->data = data;
+ avatar->data = g_memdup (data, len);
avatar->len = len;
- avatar->format = format;
- avatar->filename = filename;
+ avatar->format = g_strdup (format);
+ avatar->filename = g_strdup (filename);
avatar->refcount = 1;
return avatar;
g_hash_table_unref (priv->location);
priv->location = g_hash_table_ref (location);
-#ifdef HAVE_GEOCLUE
+#ifdef HAVE_GEOCODE
update_geocode (contact);
#endif
g_object_notify (G_OBJECT (contact), "location");
}
+const gchar * const *
+empathy_contact_get_client_types (EmpathyContact *contact)
+{
+ EmpathyContactPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ priv = GET_PRIV (contact);
+
+ return (const gchar * const *) priv->client_types;
+}
+
+static void
+contact_set_client_types (EmpathyContact *contact,
+ const gchar * const *client_types)
+{
+ EmpathyContactPriv *priv = GET_PRIV (contact);
+
+ if (priv->client_types != NULL)
+ g_strfreev (priv->client_types);
+
+ priv->client_types = g_strdupv ((gchar **) client_types);
+ g_object_notify (G_OBJECT (contact), "client-types");
+}
+
/**
* empathy_contact_equal:
* @contact1: an #EmpathyContact
return FALSE;
}
-#ifdef HAVE_GEOCLUE
-#define GEOCODE_SERVICE "org.freedesktop.Geoclue.Providers.Yahoo"
-#define GEOCODE_PATH "/org/freedesktop/Geoclue/Providers/Yahoo"
-
-/* This callback is called by geoclue when it found a position
+#ifdef HAVE_GEOCODE
+/* This callback is called by geocode-glib when it found a position
* for the given address. A position is necessary for a contact
* to show up on the map
*/
static void
-geocode_cb (GeoclueGeocode *geocode,
- GeocluePositionFields fields,
- double latitude,
- double longitude,
- double altitude,
- GeoclueAccuracy *accuracy,
- GError *error,
- gpointer contact)
+geocode_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
+ EmpathyContact *contact = user_data;
EmpathyContactPriv *priv = GET_PRIV (contact);
+ GError *error = NULL;
GHashTable *new_location;
+ GHashTable *resolved = NULL;
+ gdouble latitude, longitude;
if (priv->location == NULL)
goto out;
- if (error != NULL)
+ resolved = geocode_object_resolve_finish (GEOCODE_OBJECT (source), result,
+ &error);
+
+ if (resolved == NULL)
{
- DEBUG ("Error geocoding location : %s", error->message);
+ DEBUG ("Failed to resolve geocode: %s", error->message);
+ g_error_free (error);
goto out;
}
- /* No need to change location if we didn't find the position */
- if (!(fields & GEOCLUE_POSITION_FIELDS_LATITUDE))
- goto out;
-
- if (!(fields & GEOCLUE_POSITION_FIELDS_LONGITUDE))
+ if (!geocode_object_get_coords (resolved, &longitude, &latitude))
goto out;
new_location = tp_asv_new (
tp_g_hash_table_update (new_location, priv->location,
(GBoxedCopyFunc) g_strdup, (GBoxedCopyFunc) tp_g_value_slice_dup);
- /* Set the altitude only if it wasn't defined before */
- if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE &&
- g_hash_table_lookup (new_location, EMPATHY_LOCATION_ALT) == NULL)
- {
- tp_asv_set_double (new_location, g_strdup (EMPATHY_LOCATION_ALT),
- altitude);
- DEBUG ("\t - Altitude: %f", altitude);
- }
-
/* Don't change the accuracy as we used an address to get this position */
g_hash_table_unref (priv->location);
priv->location = new_location;
- g_object_notify (contact, "location");
+ g_object_notify ((GObject *) contact, "location");
+
out:
- g_object_unref (geocode);
+ tp_clear_pointer (&resolved, g_hash_table_unref);
g_object_unref (contact);
}
-static gchar *
-get_dup_string (GHashTable *location,
- gchar *key)
-{
- GValue *value;
-
- value = g_hash_table_lookup (location, key);
- if (value != NULL)
- return g_value_dup_string (value);
-
- return NULL;
-}
-
static void
update_geocode (EmpathyContact *contact)
{
- static GeoclueGeocode *geocode;
- gchar *str;
- GHashTable *address;
+ GeocodeObject *geocode;
GHashTable *location;
location = empathy_contact_get_location (contact);
- if (location == NULL)
+ if (location == NULL ||
+ g_hash_table_size (location) == 0)
return;
/* No need to search for position if contact published it */
g_hash_table_lookup (location, EMPATHY_LOCATION_LON) != NULL)
return;
+ geocode = geocode_object_new_for_params (location);
if (geocode == NULL)
- {
- geocode = geoclue_geocode_new (GEOCODE_SERVICE, GEOCODE_PATH);
- g_object_add_weak_pointer (G_OBJECT (geocode), (gpointer *) &geocode);
- }
- else
- {
- g_object_ref (geocode);
- }
-
- address = geoclue_address_details_new ();
-
- str = get_dup_string (location, EMPATHY_LOCATION_COUNTRY_CODE);
- if (str != NULL)
- {
- g_hash_table_insert (address,
- g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE), str);
- DEBUG ("\t - countrycode: %s", str);
- }
-
- str = get_dup_string (location, EMPATHY_LOCATION_COUNTRY);
- if (str != NULL)
- {
- g_hash_table_insert (address,
- g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY), str);
- DEBUG ("\t - country: %s", str);
- }
-
- str = get_dup_string (location, EMPATHY_LOCATION_POSTAL_CODE);
- if (str != NULL)
- {
- g_hash_table_insert (address,
- g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE), str);
- DEBUG ("\t - postalcode: %s", str);
- }
-
- str = get_dup_string (location, EMPATHY_LOCATION_REGION);
- if (str != NULL)
- {
- g_hash_table_insert (address,
- g_strdup (GEOCLUE_ADDRESS_KEY_REGION), str);
- DEBUG ("\t - region: %s", str);
- }
-
- str = get_dup_string (location, EMPATHY_LOCATION_LOCALITY);
- if (str != NULL)
- {
- g_hash_table_insert (address,
- g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY), str);
- DEBUG ("\t - locality: %s", str);
- }
-
- str = get_dup_string (location, EMPATHY_LOCATION_STREET);
- if (str != NULL)
- {
- g_hash_table_insert (address,
- g_strdup (GEOCLUE_ADDRESS_KEY_STREET), str);
- DEBUG ("\t - street: %s", str);
- }
-
- if (g_hash_table_size (address) > 0)
- {
- g_object_ref (contact);
+ return;
- geoclue_geocode_address_to_position_async (geocode, address,
- geocode_cb, contact);
- }
+ geocode_object_resolve_async (geocode, NULL, geocode_cb,
+ g_object_ref (contact));
- g_hash_table_unref (address);
+ g_object_unref (geocode);
}
#endif
TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO))
capabilities |= EMPATHY_CAPABILITIES_VIDEO;
}
+
+ if (tp_asv_get_boolean (fixed_prop,
+ TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, NULL))
+ capabilities |= EMPATHY_CAPABILITIES_AUDIO;
+ if (tp_asv_get_boolean (fixed_prop,
+ TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, NULL))
+ capabilities |= EMPATHY_CAPABILITIES_VIDEO;
+ }
+ else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_TEXT))
+ {
+ if (tp_asv_get_boolean (fixed_prop,
+ TP_PROP_CHANNEL_INTERFACE_SMS_SMS_CHANNEL, NULL))
+ capabilities |= EMPATHY_CAPABILITIES_SMS;
+ }
+ else if (!tp_strdiff (chan_type,
+ TPY_IFACE_CHANNEL_TYPE_CALL))
+ {
+ guint j;
+
+ if (tp_asv_get_boolean (fixed_prop,
+ TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, NULL))
+ capabilities |= EMPATHY_CAPABILITIES_AUDIO;
+
+ if (tp_asv_get_boolean (fixed_prop,
+ TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, NULL))
+ capabilities |= EMPATHY_CAPABILITIES_VIDEO;
+
+ for (j = 0; allowed_prop[j] != NULL; j++)
+ {
+ if (!tp_strdiff (allowed_prop[j],
+ TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO))
+ capabilities |= EMPATHY_CAPABILITIES_AUDIO;
+ else if (!tp_strdiff (allowed_prop[j],
+ TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO))
+ capabilities |= EMPATHY_CAPABILITIES_VIDEO;
+ }
}
}
EmpathyAvatar *avatar;
gchar *data;
gsize len;
+ gchar *path;
+ GError *error = NULL;
+
+ if (!g_file_load_contents (file, NULL, &data, &len, NULL, &error))
+ {
+ DEBUG ("Failed to load avatar: %s", error->message);
+
+ g_error_free (error);
+ contact_set_avatar (contact, NULL);
+ return;
+ }
+
+ path = g_file_get_path (file);
+
+ avatar = empathy_avatar_new ((guchar *) data, len, mime, path);
- g_file_load_contents (file, NULL, &data, &len, NULL, NULL);
- avatar = empathy_avatar_new ((guchar *) data, len, g_strdup (mime),
- g_file_get_path (file));
contact_set_avatar (contact, avatar);
empathy_avatar_unref (avatar);
+ g_free (path);
+ g_free (data);
}
else
{
presence_cmp_func (EmpathyContact *a,
EmpathyContact *b)
{
- FolksPresence *presence_a, *presence_b;
+ FolksPresenceDetails *presence_a, *presence_b;
- presence_a = FOLKS_PRESENCE (empathy_contact_get_persona (a));
- presence_b = FOLKS_PRESENCE (empathy_contact_get_persona (b));
+ presence_a = FOLKS_PRESENCE_DETAILS (empathy_contact_get_persona (a));
+ presence_b = FOLKS_PRESENCE_DETAILS (empathy_contact_get_persona (b));
/* We negate the result because we're sorting in reverse order (i.e. such that
* the Personas with the highest presence are at the beginning of the list. */
- return -folks_presence_typecmp (folks_presence_get_presence_type (presence_a),
- folks_presence_get_presence_type (presence_b));
+ return -folks_presence_details_typecmp (
+ folks_presence_details_get_presence_type (presence_a),
+ folks_presence_details_get_presence_type (presence_b));
}
static gint
empathy_contact_dup_best_for_action (FolksIndividual *individual,
EmpathyActionType action_type)
{
- GList *personas, *contacts, *l;
+ GeeSet *personas;
+ GeeIterator *iter;
+ GList *contacts;
EmpathyContact *best_contact = NULL;
/* Build a list of EmpathyContacts that we can sort */
personas = folks_individual_get_personas (individual);
contacts = NULL;
- for (l = personas; l != NULL; l = l->next)
+ iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+ while (gee_iterator_next (iter))
{
+ FolksPersona *persona = gee_iterator_get (iter);
TpContact *tp_contact;
- EmpathyContact *contact;
+ EmpathyContact *contact = NULL;
- if (!TPF_IS_PERSONA (l->data))
- continue;
+ if (!empathy_folks_persona_is_interesting (persona))
+ goto while_finish;
+
+ tp_contact = tpf_persona_get_contact (TPF_PERSONA (persona));
+ if (tp_contact == NULL)
+ goto while_finish;
- tp_contact = tpf_persona_get_contact (TPF_PERSONA (l->data));
contact = empathy_contact_dup_from_tp_contact (tp_contact);
- empathy_contact_set_persona (contact, FOLKS_PERSONA (l->data));
+ empathy_contact_set_persona (contact, FOLKS_PERSONA (persona));
/* Only choose the contact if they're actually capable of the specified
* action. */
- if (!empathy_contact_can_do_action (contact, action_type))
- {
- g_object_unref (contact);
- continue;
- }
+ if (empathy_contact_can_do_action (contact, action_type))
+ contacts = g_list_prepend (contacts, g_object_ref (contact));
- contacts = g_list_prepend (contacts, contact);
+while_finish:
+ g_clear_object (&contact);
+ g_clear_object (&persona);
}
+ g_clear_object (&iter);
/* Sort the contacts by some heuristic based on the action type, then take
* the top contact. */
return best_contact;
}
+
+#define declare_contact_cb(name) \
+static void \
+contact_##name##_cb (GObject *source, \
+ GAsyncResult *result, \
+ gpointer user_data) \
+{ \
+ TpContact *contact = (TpContact *) source; \
+ GError *error = NULL; \
+ \
+ if (!tp_contact_##name##_finish (contact, result, &error)) \
+ { \
+ DEBUG ("Failed to ##name## on %s\n", \
+ tp_contact_get_identifier (contact)); \
+ g_error_free (error); \
+ } \
+}
+
+declare_contact_cb (request_subscription)
+declare_contact_cb (authorize_publication)
+declare_contact_cb (unblock)
+
+void
+empathy_contact_add_to_contact_list (EmpathyContact *self,
+ const gchar *message)
+{
+ EmpathyContactPriv *priv = GET_PRIV (self);
+
+ g_return_if_fail (priv->tp_contact != NULL);
+
+ tp_contact_request_subscription_async (priv->tp_contact, message,
+ contact_request_subscription_cb, NULL);
+
+ tp_contact_authorize_publication_async (priv->tp_contact,
+ contact_authorize_publication_cb, NULL);
+
+ tp_contact_unblock_async (priv->tp_contact, contact_unblock_cb, NULL);
+}
+
+declare_contact_cb (remove)
+
+void
+empathy_contact_remove_from_contact_list (EmpathyContact *self)
+{
+ EmpathyContactPriv *priv = GET_PRIV (self);
+
+ g_return_if_fail (priv->tp_contact != NULL);
+
+ tp_contact_remove_async (priv->tp_contact, contact_remove_cb, NULL);
+}