G_DEFINE_TYPE (EmpathyIndividualStore, empathy_individual_store,
GTK_TYPE_TREE_STORE);
+/* Calculate whether the Individual can do audio or video calls.
+ * FIXME: We can remove this once libfolks has grown capabilities support
+ * again: bgo#626179. */
+static void
+individual_can_audio_video_call (FolksIndividual *individual,
+ gboolean *can_audio_call,
+ gboolean *can_video_call)
+{
+ GList *personas, *l;
+ gboolean can_audio = FALSE, can_video = FALSE;
+
+ personas = folks_individual_get_personas (individual);
+ for (l = personas; l != NULL; l = l->next)
+ {
+ TpContact *tp_contact;
+ EmpathyContact *contact;
+
+ if (!TPF_IS_PERSONA (l->data))
+ continue;
+
+ 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));
+
+ can_audio = can_audio || empathy_contact_get_capabilities (contact) &
+ EMPATHY_CAPABILITIES_AUDIO;
+ can_video = can_video || empathy_contact_get_capabilities (contact) &
+ EMPATHY_CAPABILITIES_VIDEO;
+
+ g_object_unref (contact);
+
+ if (can_audio && can_video)
+ break;
+ }
+
+ *can_audio_call = can_audio;
+ *can_video_call = can_video;
+}
+
+static const gchar * const *
+individual_get_client_types (FolksIndividual *individual)
+{
+ GList *personas, *l;
+ const gchar * const *types = NULL;
+ FolksPresenceType presence_type = FOLKS_PRESENCE_TYPE_UNSET;
+
+ personas = folks_individual_get_personas (individual);
+ for (l = personas; l != NULL; l = l->next)
+ {
+ FolksPresence *presence;
+
+ /* We only want personas which implement FolksPresence */
+ if (!FOLKS_IS_PRESENCE (l->data))
+ continue;
+
+ presence = FOLKS_PRESENCE (l->data);
+
+ if (folks_presence_typecmp (folks_presence_get_presence_type (presence),
+ presence_type) > 0)
+ {
+ TpContact *tp_contact;
+
+ presence_type = folks_presence_get_presence_type (presence);
+
+ tp_contact = tpf_persona_get_contact (TPF_PERSONA (l->data));
+ types = tp_contact_get_client_types (tp_contact);
+ }
+ }
+
+ return types;
+}
+
static void
add_individual_to_store (GtkTreeStore *self,
GtkTreeIter *iter,
GtkTreeIter *parent,
- FolksIndividual *individual,
- EmpathyIndividualManagerFlags flags)
+ FolksIndividual *individual)
{
- EmpathyContact *contact;
+ gboolean can_audio_call, can_video_call;
+ const gchar * const *types;
- contact = empathy_contact_dup_from_folks_individual (individual);
+ individual_can_audio_video_call (individual, &can_audio_call,
+ &can_video_call);
+
+ types = individual_get_client_types (individual);
gtk_tree_store_insert_with_values (self, iter, parent, 0,
EMPATHY_INDIVIDUAL_STORE_COL_NAME,
- folks_individual_get_alias (individual),
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, individual,
EMPATHY_INDIVIDUAL_STORE_COL_IS_GROUP, FALSE,
EMPATHY_INDIVIDUAL_STORE_COL_IS_SEPARATOR, FALSE,
- EMPATHY_INDIVIDUAL_STORE_COL_FLAGS, flags,
+ EMPATHY_INDIVIDUAL_STORE_COL_CAN_AUDIO_CALL, can_audio_call,
+ EMPATHY_INDIVIDUAL_STORE_COL_CAN_VIDEO_CALL, can_video_call,
+ EMPATHY_INDIVIDUAL_STORE_COL_CLIENT_TYPES, types,
-1);
-
- if (contact != NULL)
- {
- gtk_tree_store_set (GTK_TREE_STORE (self), iter,
- EMPATHY_INDIVIDUAL_STORE_COL_CAN_AUDIO_CALL,
- empathy_contact_get_capabilities (contact) &
- EMPATHY_CAPABILITIES_AUDIO,
- EMPATHY_INDIVIDUAL_STORE_COL_CAN_VIDEO_CALL,
- empathy_contact_get_capabilities (contact) &
- EMPATHY_CAPABILITIES_VIDEO,
- -1);
- }
-
- tp_clear_object (&contact);
}
static gboolean
return l;
}
+static void
+free_iters (GList *iters)
+{
+ g_list_foreach (iters, (GFunc) gtk_tree_iter_free, NULL);
+ g_list_free (iters);
+}
+
static void
individual_store_remove_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
}
}
- g_list_foreach (iters, (GFunc) gtk_tree_iter_free, NULL);
- g_list_free (iters);
+ free_iters (iters);
}
static void
GList *groups = NULL, *l;
EmpathyContact *contact;
TpConnection *connection;
- EmpathyIndividualManagerFlags flags = 0;
gchar *protocol_name;
priv = GET_PRIV (self);
- if (EMP_STR_EMPTY (folks_individual_get_alias (individual)))
+ if (EMP_STR_EMPTY (folks_aliasable_get_alias (FOLKS_ALIASABLE (individual))))
return;
if (priv->show_groups)
{
- group_set = folks_individual_get_groups (individual);
+ group_set = folks_groupable_get_groups (FOLKS_GROUPABLE (individual));
groups = g_hash_table_get_keys (group_set);
}
contact = empathy_contact_dup_from_folks_individual (individual);
connection = empathy_contact_get_connection (contact);
- flags = empathy_individual_manager_get_flags_for_connection (priv->manager,
- connection);
tp_connection_parse_object_path (connection, &protocol_name, NULL);
}
add_individual_to_store (GTK_TREE_STORE (self), &iter, parent,
- individual, flags);
+ individual);
}
g_free (protocol_name);
FALSE);
add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group,
- individual, flags);
+ individual);
}
g_list_free (groups);
- if (group_set != NULL)
- g_hash_table_unref (group_set);
if (priv->show_groups &&
folks_favourite_get_is_favourite (FOLKS_FAVOURITE (individual)))
&iter_group, NULL, NULL, TRUE);
add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group,
- individual, flags);
+ individual);
}
individual_store_contact_update (self, individual);
}
}
- g_list_foreach (iters, (GFunc) gtk_tree_iter_free, NULL);
- g_list_free (iters);
-
+ free_iters (iters);
}
static void individual_store_contact_active_free (ShowActiveData *data);
ShowActiveData *data;
DEBUG ("Individual'%s' now active, and %s be removed",
- folks_individual_get_alias (individual), remove_ ? "WILL" : "WILL NOT");
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
+ remove_ ? "WILL" : "WILL NOT");
data = g_slice_new0 (ShowActiveData);
if (data->remove)
{
DEBUG ("Individual'%s' active timeout, removing item",
- folks_individual_get_alias (data->individual));
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (data->individual)));
individual_store_remove_individual (data->self, data->individual);
}
DEBUG ("Individual'%s' no longer active",
- folks_individual_get_alias (data->individual));
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (data->individual)));
individual_store_contact_set_active (data->self,
data->individual, FALSE, TRUE);
if (error != NULL)
{
DEBUG ("failed to retrieve pixbuf for individual %s: %s",
- folks_individual_get_alias (individual),
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
error->message);
g_clear_error (&error);
}
EMPATHY_INDIVIDUAL_STORE_COL_PIXBUF_AVATAR, pixbuf,
-1);
}
+
+ free_iters (iters);
}
/* Free things */
data->cancellable);
}
+ tp_clear_object (&pixbuf);
g_object_unref (data->cancellable);
g_slice_free (LoadAvatarData, data);
}
EmpathyIndividualStorePriv *priv;
ShowActiveData *data;
GtkTreeModel *model;
- EmpathyContact *contact;
GList *iters, *l;
gboolean in_list;
gboolean was_online = TRUE;
priv = GET_PRIV (self);
model = GTK_TREE_MODEL (self);
- contact = empathy_contact_dup_from_folks_individual (individual);
iters = individual_store_find_contact (self, individual);
if (!iters)
}
/* Get online state now. */
- now_online = folks_individual_is_online (individual);
+ now_online = folks_presence_is_online (FOLKS_PRESENCE (individual));
if (!in_list)
{
DEBUG ("Individual'%s' in list:NO, should be:YES",
- folks_individual_get_alias (individual));
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)));
individual_store_add_individual (self, individual);
else
{
DEBUG ("Individual'%s' in list:YES, should be:YES",
- folks_individual_get_alias (individual));
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)));
/* Get online state before. */
if (iters && g_list_length (iters) > 0)
for (l = iters; l && set_model; l = l->next)
{
+ gboolean can_audio_call, can_video_call;
+ const gchar * const *types;
+
+ individual_can_audio_video_call (individual, &can_audio_call,
+ &can_video_call);
+
+ types = individual_get_client_types (individual);
+
gtk_tree_store_set (GTK_TREE_STORE (self), l->data,
EMPATHY_INDIVIDUAL_STORE_COL_ICON_STATUS, pixbuf_status,
EMPATHY_INDIVIDUAL_STORE_COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
EMPATHY_INDIVIDUAL_STORE_COL_NAME,
- folks_individual_get_alias (individual),
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
EMPATHY_INDIVIDUAL_STORE_COL_PRESENCE_TYPE,
- folks_individual_get_presence_type (individual),
+ folks_presence_get_presence_type (FOLKS_PRESENCE (individual)),
EMPATHY_INDIVIDUAL_STORE_COL_STATUS,
- folks_individual_get_presence_message (individual),
+ folks_presence_get_presence_message (FOLKS_PRESENCE (individual)),
EMPATHY_INDIVIDUAL_STORE_COL_COMPACT, priv->is_compact,
EMPATHY_INDIVIDUAL_STORE_COL_IS_GROUP, FALSE,
EMPATHY_INDIVIDUAL_STORE_COL_IS_ONLINE, now_online,
EMPATHY_INDIVIDUAL_STORE_COL_IS_SEPARATOR, FALSE,
+ EMPATHY_INDIVIDUAL_STORE_COL_CAN_AUDIO_CALL, can_audio_call,
+ EMPATHY_INDIVIDUAL_STORE_COL_CAN_VIDEO_CALL, can_video_call,
+ EMPATHY_INDIVIDUAL_STORE_COL_CLIENT_TYPES, types,
-1);
-
- if (contact != NULL)
- {
- gtk_tree_store_set (GTK_TREE_STORE (self), l->data,
- EMPATHY_INDIVIDUAL_STORE_COL_CAN_AUDIO_CALL,
- empathy_contact_get_capabilities (contact) &
- EMPATHY_CAPABILITIES_AUDIO,
- EMPATHY_INDIVIDUAL_STORE_COL_CAN_VIDEO_CALL,
- empathy_contact_get_capabilities (contact) &
- EMPATHY_CAPABILITIES_VIDEO,
- -1);
- }
}
if (priv->show_active && do_set_active)
* timeout removes the user from the contact list, really we
* should remove the first timeout.
*/
- g_list_foreach (iters, (GFunc) gtk_tree_iter_free, NULL);
- g_list_free (iters);
- tp_clear_object (&contact);
+ free_iters (iters);
}
static void
EmpathyIndividualStore *self)
{
DEBUG ("Individual'%s' updated, checking roster is in sync...",
- folks_individual_get_alias (individual));
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)));
individual_store_contact_update (self, individual);
}
}
static void
-individual_store_add_individual_and_connect (EmpathyIndividualStore *self,
- FolksIndividual *individual)
+individual_personas_changed_cb (FolksIndividual *individual,
+ GList *added,
+ GList *removed,
+ EmpathyIndividualStore *self)
{
- GList *personas, *l;
+ GList *l;
- g_signal_connect (individual, "notify::avatar",
- G_CALLBACK (individual_store_individual_updated_cb), self);
- g_signal_connect (individual, "notify::presence-type",
- G_CALLBACK (individual_store_individual_updated_cb), self);
- g_signal_connect (individual, "notify::presence-message",
- G_CALLBACK (individual_store_individual_updated_cb), self);
- g_signal_connect (individual, "notify::alias",
- G_CALLBACK (individual_store_individual_updated_cb), self);
+ DEBUG ("Individual '%s' personas-changed.",
+ folks_individual_get_id (individual));
/* FIXME: libfolks hasn't grown capabilities support yet, so we have to go
* through the EmpathyContacts for them. */
- personas = folks_individual_get_personas (individual);
- for (l = personas; l != NULL; l = l->next)
+ for (l = removed; l != NULL; l = l->next)
{
TpContact *tp_contact;
EmpathyContact *contact;
contact = empathy_contact_dup_from_tp_contact (tp_contact);
empathy_contact_set_persona (contact, FOLKS_PERSONA (l->data));
- g_object_set_data (G_OBJECT (contact), "individual", individual);
- g_signal_connect (contact, "notify::capabilities",
- G_CALLBACK (individual_store_contact_updated_cb), self);
+ g_object_set_data (G_OBJECT (contact), "individual", NULL);
+ g_signal_handlers_disconnect_by_func (contact,
+ (GCallback) individual_store_contact_updated_cb, self);
g_object_unref (contact);
}
- individual_store_add_individual (self, individual);
-}
-
-static void
-individual_store_disconnect_individual (EmpathyIndividualStore *self,
- FolksIndividual *individual)
-{
- GList *personas, *l;
-
- g_signal_handlers_disconnect_by_func (individual,
- G_CALLBACK (individual_store_individual_updated_cb), self);
-
- /* FIXME: libfolks hasn't grown capabilities support yet, so we have to go
- * through the EmpathyContacts for them. */
- personas = folks_individual_get_personas (individual);
- for (l = personas; l != NULL; l = l->next)
+ for (l = added; l != NULL; l = l->next)
{
TpContact *tp_contact;
EmpathyContact *contact;
contact = empathy_contact_dup_from_tp_contact (tp_contact);
empathy_contact_set_persona (contact, FOLKS_PERSONA (l->data));
- g_signal_handlers_disconnect_by_func (contact,
- G_CALLBACK (individual_store_contact_updated_cb), self);
+ g_object_set_data (G_OBJECT (contact), "individual", individual);
+ g_signal_connect (contact, "notify::capabilities",
+ (GCallback) individual_store_contact_updated_cb, self);
+ g_signal_connect (contact, "notify::client-types",
+ (GCallback) individual_store_contact_updated_cb, self);
g_object_unref (contact);
}
}
+static void
+individual_store_add_individual_and_connect (EmpathyIndividualStore *self,
+ FolksIndividual *individual)
+{
+ individual_store_add_individual (self, individual);
+
+ g_signal_connect (individual, "notify::avatar",
+ (GCallback) individual_store_individual_updated_cb, self);
+ g_signal_connect (individual, "notify::presence-type",
+ (GCallback) individual_store_individual_updated_cb, self);
+ g_signal_connect (individual, "notify::presence-message",
+ (GCallback) individual_store_individual_updated_cb, self);
+ g_signal_connect (individual, "notify::alias",
+ (GCallback) individual_store_individual_updated_cb, self);
+ g_signal_connect (individual, "personas-changed",
+ (GCallback) individual_personas_changed_cb, self);
+
+ individual_personas_changed_cb (individual,
+ folks_individual_get_personas (individual), NULL, self);
+}
+
+static void
+individual_store_disconnect_individual (EmpathyIndividualStore *self,
+ FolksIndividual *individual)
+{
+ individual_personas_changed_cb (individual, NULL,
+ folks_individual_get_personas (individual), self);
+
+ g_signal_handlers_disconnect_by_func (individual,
+ (GCallback) individual_store_individual_updated_cb, self);
+ g_signal_handlers_disconnect_by_func (individual,
+ (GCallback) individual_personas_changed_cb, self);
+}
+
static void
individual_store_remove_individual_and_disconnect (
EmpathyIndividualStore *self,
g_return_val_if_fail (individual_a != NULL || individual_b != NULL, 0);
/* alias */
- ret_val = g_utf8_collate (folks_individual_get_alias (individual_a),
- folks_individual_get_alias (individual_b));
+ ret_val = g_utf8_collate (
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual_a)),
+ folks_aliasable_get_alias (FOLKS_ALIASABLE (individual_b)));
if (ret_val != 0)
goto out;
account_a = empathy_contact_get_account (contact_a);
account_b = empathy_contact_get_account (contact_b);
+ g_assert (account_a != NULL);
+ g_assert (account_b != NULL);
+
/* protocol */
ret_val = g_strcmp0 (tp_account_get_protocol (account_a),
tp_account_get_protocol (account_b));
/* If we managed to get this far, we can start looking at
* the presences.
*/
- folks_presence_type_a = folks_individual_get_presence_type (individual_a);
- folks_presence_type_b = folks_individual_get_presence_type (individual_b);
+ folks_presence_type_a =
+ folks_presence_get_presence_type (FOLKS_PRESENCE (individual_a));
+ folks_presence_type_b =
+ folks_presence_get_presence_type (FOLKS_PRESENCE (individual_b));
tp_presence_a = empathy_folks_presence_type_to_tp (folks_presence_type_a);
tp_presence_b = empathy_folks_presence_type_to_tp (folks_presence_type_b);
tp_clear_object (&individual_a);
tp_clear_object (&individual_b);
+ g_free (name_a);
+ g_free (name_b);
return ret_val;
}
G_TYPE_BOOLEAN, /* Is separator */
G_TYPE_BOOLEAN, /* Can make audio calls */
G_TYPE_BOOLEAN, /* Can make video calls */
- EMPATHY_TYPE_INDIVIDUAL_MANAGER_FLAGS, /* Flags */
G_TYPE_BOOLEAN, /* Is a fake group */
+ G_TYPE_STRV, /* Client types */
};
priv = GET_PRIV (self);
GtkTreeIter parent_iter, iter;
gchar *name = NULL;
gboolean is_group;
- gboolean fake;
+ gboolean fake = FALSE;
g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
{
pixbuf_status =
empathy_pixbuf_contact_status_icon_with_icon_name (contact,
- status_icon_name, priv->show_protocols);
+ status_icon_name, show_protocols_here);
if (pixbuf_status != NULL)
{
g_hash_table_insert (priv->status_icons,