*/
#include "config.h"
+#include "empathy-individual-store.h"
-#include <string.h>
-
-#include <glib.h>
#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-
-#include <folks/folks.h>
-#include <folks/folks-telepathy.h>
-#include <telepathy-glib/util.h>
+#include <tp-account-widgets/tpaw-utils.h>
-#include <libempathy/empathy-utils.h>
-#include <libempathy/empathy-enum-types.h>
-
-#include "empathy-individual-store.h"
-#include "empathy-ui-utils.h"
#include "empathy-gtk-enum-types.h"
+#include "empathy-ui-utils.h"
+#include "empathy-utils.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
-#include <libempathy/empathy-debug.h>
+#include "empathy-debug.h"
/* Active users are those which have recently changed state
* (e.g. online, offline or from normal to a busy state).
GHashTable *folks_individual_cache;
/* Hash: char *groupname -> GtkTreeIter * */
GHashTable *empathy_group_cache;
+ gboolean show_active;
};
typedef struct
G_DEFINE_TYPE (EmpathyIndividualStore, empathy_individual_store,
GTK_TYPE_TREE_STORE);
-static const gchar * const *
-individual_get_client_types (FolksIndividual *individual)
-{
- GeeSet *personas;
- GeeIterator *iter;
- const gchar * const *types = NULL;
- FolksPresenceType presence_type = FOLKS_PRESENCE_TYPE_UNSET;
-
- personas = folks_individual_get_personas (individual);
- iter = gee_iterable_iterator (GEE_ITERABLE (personas));
- while (gee_iterator_next (iter))
- {
- FolksPresenceDetails *presence;
- FolksPersona *persona = gee_iterator_get (iter);
-
- /* We only want personas which have presence and a TpContact */
- if (!empathy_folks_persona_is_interesting (persona))
- goto while_finish;
-
- presence = FOLKS_PRESENCE_DETAILS (persona);
-
- if (folks_presence_details_typecmp (
- folks_presence_details_get_presence_type (presence),
- presence_type) > 0)
- {
- TpContact *tp_contact;
-
- presence_type = folks_presence_details_get_presence_type (presence);
-
- tp_contact = tpf_persona_get_contact (TPF_PERSONA (persona));
- if (tp_contact != NULL)
- types = tp_contact_get_client_types (tp_contact);
- }
-
-while_finish:
- g_clear_object (&persona);
- }
- g_clear_object (&iter);
-
- return types;
-}
-
static void
add_individual_to_store (GtkTreeStore *store,
GtkTreeIter *iter,
empathy_individual_can_audio_video_call (individual, &can_audio_call,
&can_video_call, NULL);
- types = individual_get_client_types (individual);
+ types = empathy_individual_get_client_types (individual);
gtk_tree_store_insert_with_values (store, iter, parent, 0,
EMPATHY_INDIVIDUAL_STORE_COL_NAME,
}
}
-static GList *
-individual_store_find_contact (EmpathyIndividualStore *self,
+GList *
+/* (transfer full) free with empathy_individual_store_free_iters() */
+empathy_individual_store_find_contact (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
GQueue *row_refs_queue;
return iters_list;
}
-static void
-free_iters (GList *iters)
+void
+empathy_individual_store_free_iters (GList *iters)
{
g_list_foreach (iters, (GFunc) gtk_tree_iter_free, NULL);
g_list_free (iters);
empathy_individual_store_add_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- GtkTreeIter iter;
- GeeIterator *group_iter = NULL;
+ GtkTreeIter iter, iter_group;
+ GeeSet *group_set = NULL;
+ gboolean grouped = FALSE;
- if (EMP_STR_EMPTY (folks_alias_details_get_alias (
+ if (TPAW_STR_EMPTY (folks_alias_details_get_alias (
FOLKS_ALIAS_DETAILS (individual))))
return;
- if (self->priv->show_groups)
+ if (!self->priv->show_groups)
{
- GeeSet *group_set = NULL;
-
- group_set = folks_group_details_get_groups (
- FOLKS_GROUP_DETAILS (individual));
+ /* add our individual to the toplevel of the store */
+ add_individual_to_store (GTK_TREE_STORE (self), &iter, NULL,
+ individual);
- if (gee_collection_get_size (GEE_COLLECTION (group_set)) > 0)
- group_iter = gee_iterable_iterator (GEE_ITERABLE (group_set));
+ goto finally;
}
- /* fall-back groups, in case there are no named groups */
- if (group_iter == NULL)
+ group_set = folks_group_details_get_groups (
+ FOLKS_GROUP_DETAILS (individual));
+
+ if (gee_collection_get_size (GEE_COLLECTION (group_set)) > 0)
+ {
+ /* add the contact to its groups */
+ GeeIterator *group_iter =
+ gee_iterable_iterator (GEE_ITERABLE (group_set));
+
+ while (group_iter != NULL && gee_iterator_next (group_iter))
+ {
+ gchar *group_name = gee_iterator_get (group_iter);
+
+ individual_store_get_group (self, group_name, &iter_group,
+ NULL, NULL, FALSE);
+
+ add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group,
+ individual);
+ grouped = TRUE;
+
+ g_free (group_name);
+ }
+
+ g_clear_object (&group_iter);
+ }
+ else
{
- GtkTreeIter iter_group, *parent;
+ /* fall-back groups, in case there are no named groups */
EmpathyContact *contact;
TpConnection *connection;
- gchar *protocol_name = NULL;
-
- parent = &iter_group;
+ const gchar *protocol_name = NULL;
contact = empathy_contact_dup_from_folks_individual (individual);
if (contact != NULL)
{
connection = empathy_contact_get_connection (contact);
- tp_connection_parse_object_path (connection, &protocol_name, NULL);
+ protocol_name = tp_connection_get_protocol_name (connection);
}
- if (!self->priv->show_groups)
- parent = NULL;
- else if (!tp_strdiff (protocol_name, "local-xmpp"))
+ if (!tp_strdiff (protocol_name, "local-xmpp"))
{
/* these are People Nearby */
individual_store_get_group (self,
EMPATHY_INDIVIDUAL_STORE_PEOPLE_NEARBY, &iter_group, NULL, NULL,
TRUE);
+ add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group,
+ individual);
+ grouped = TRUE;
}
- else
- {
- individual_store_get_group (self,
- EMPATHY_INDIVIDUAL_STORE_UNGROUPED,
- &iter_group, NULL, NULL, TRUE);
- }
-
- add_individual_to_store (GTK_TREE_STORE (self), &iter, parent,
- individual);
- g_free (protocol_name);
g_clear_object (&contact);
}
- /* Else add to each group. */
- while (group_iter != NULL && gee_iterator_next (group_iter))
+ if (folks_favourite_details_get_is_favourite (
+ FOLKS_FAVOURITE_DETAILS (individual)))
{
- gchar *group_name = gee_iterator_get (group_iter);
- GtkTreeIter iter_group;
-
- individual_store_get_group (self, group_name, &iter_group, NULL, NULL,
- FALSE);
+ /* Add contact to the fake 'Favorites' group */
+ individual_store_get_group (self, EMPATHY_INDIVIDUAL_STORE_FAVORITE,
+ &iter_group, NULL, NULL, TRUE);
add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group,
individual);
-
- g_free (group_name);
+ grouped = TRUE;
}
- g_clear_object (&group_iter);
- if (self->priv->show_groups &&
- folks_favourite_details_get_is_favourite (
- FOLKS_FAVOURITE_DETAILS (individual)))
+ if (!grouped)
{
- /* Add contact to the fake 'Favorites' group */
- GtkTreeIter iter_group;
-
- individual_store_get_group (self, EMPATHY_INDIVIDUAL_STORE_FAVORITE,
+ /* Else add the contact to 'Ungrouped' */
+ individual_store_get_group (self,
+ EMPATHY_INDIVIDUAL_STORE_UNGROUPED,
&iter_group, NULL, NULL, TRUE);
-
add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group,
individual);
}
+
+finally:
individual_store_contact_update (self, individual);
}
model = GTK_TREE_MODEL (self);
- iters = individual_store_find_contact (self, individual);
+ iters = empathy_individual_store_find_contact (self, individual);
for (l = iters; l; l = l->next)
{
GtkTreePath *path;
EMPATHY_INDIVIDUAL_STORE_COL_IS_ACTIVE, active,
-1);
- DEBUG ("Set item %s", active ? "active" : "inactive");
-
if (set_changed)
{
path = gtk_tree_model_get_path (model, l->data);
}
}
- free_iters (iters);
+ empathy_individual_store_free_iters (iters);
}
static void individual_store_contact_active_free (ShowActiveData *data);
{
ShowActiveData *data;
- DEBUG ("Individual'%s' now active, and %s be removed",
- folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)),
- remove_ ? "WILL" : "WILL NOT");
-
data = g_slice_new0 (ShowActiveData);
/* We don't actually want to force either the IndividualStore or the
empathy_individual_store_remove_individual (data->self, data->individual);
}
- DEBUG ("Individual'%s' no longer active",
- folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (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_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)),
- error->message);
+ /* No need to display an error if the individal just doesn't have an
+ * avatar */
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ DEBUG ("failed to retrieve pixbuf for individual %s: %s",
+ folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)),
+ error->message);
+ }
+
g_clear_error (&error);
}
else if (data->store != NULL)
{
GList *iters, *l;
- iters = individual_store_find_contact (data->store, individual);
+ iters = empathy_individual_store_find_contact (data->store, individual);
for (l = iters; l; l = l->next)
{
gtk_tree_store_set (GTK_TREE_STORE (data->store), l->data,
-1);
}
- free_iters (iters);
+ empathy_individual_store_free_iters (iters);
}
/* Free things */
model = GTK_TREE_MODEL (self);
- iters = individual_store_find_contact (self, individual);
+ iters = empathy_individual_store_find_contact (self, individual);
if (!iters)
{
in_list = FALSE;
empathy_individual_store_add_individual (self, individual);
- if (self->show_active)
+ if (self->priv->show_active)
{
do_set_active = TRUE;
-
- DEBUG ("Set active (individual added)");
}
}
else
{
- DEBUG ("Individual'%s' in list:YES, should be:YES",
- folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)));
-
/* Get online state before. */
if (iters && g_list_length (iters) > 0)
{
}
/* Is this really an update or an online/offline. */
- if (self->show_active)
+ if (self->priv->show_active)
{
if (was_online != now_online)
{
do_set_active = TRUE;
do_set_refresh = TRUE;
-
- DEBUG ("Set active (individual updated %s)",
- was_online ? "online -> offline" : "offline -> online");
}
else
{
/* Was TRUE for presence updates. */
/* do_set_active = FALSE; */
do_set_refresh = TRUE;
-
- DEBUG ("Set active (individual updated)");
}
}
empathy_individual_can_audio_video_call (individual, &can_audio_call,
&can_video_call, NULL);
- types = individual_get_client_types (individual);
+ types = empathy_individual_get_client_types (individual);
gtk_tree_store_set (GTK_TREE_STORE (self), l->data,
EMPATHY_INDIVIDUAL_STORE_COL_ICON_STATUS, pixbuf_status,
-1);
}
- if (self->show_active && do_set_active)
+ if (self->priv->show_active && do_set_active)
{
individual_store_contact_set_active (self, individual, do_set_active,
do_set_refresh);
* timeout removes the user from the contact list, really we
* should remove the first timeout.
*/
- free_iters (iters);
+ empathy_individual_store_free_iters (iters);
}
static void
GParamSpec *param,
EmpathyIndividualStore *self)
{
- DEBUG ("Individual'%s' updated, checking roster is in sync...",
- folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)));
-
individual_store_contact_update (self, individual);
}
{
FolksIndividual *individual;
- DEBUG ("Contact '%s' updated, checking roster is in sync...",
- empathy_contact_get_alias (contact));
-
individual = g_object_get_data (G_OBJECT (contact), "individual");
if (individual == NULL)
return;
{
GeeIterator *iter;
- DEBUG ("Individual '%s' personas-changed.",
- folks_individual_get_id (individual));
-
iter = gee_iterable_iterator (GEE_ITERABLE (removed));
/* FIXME: libfolks hasn't grown capabilities support yet, so we have to go
* through the EmpathyContacts for them. */
g_source_remove (self->priv->inhibit_active);
}
- if (self->setup_idle_id != 0)
- {
- g_source_remove (self->setup_idle_id);
- }
-
g_hash_table_unref (self->priv->status_icons);
g_hash_table_unref (self->priv->folks_individual_cache);
g_hash_table_unref (self->priv->empathy_group_cache);
g_assert (account_b != NULL);
/* protocol */
- ret_val = g_strcmp0 (tp_account_get_protocol (account_a),
- tp_account_get_protocol (account_b));
+ ret_val = g_strcmp0 (tp_account_get_protocol_name (account_a),
+ tp_account_get_protocol_name (account_b));
if (ret_val != 0)
goto out;
static gboolean
individual_store_inhibit_active_cb (EmpathyIndividualStore *self)
{
- self->show_active = TRUE;
+ self->priv->show_active = TRUE;
self->priv->inhibit_active = 0;
return FALSE;
empathy_individual_store_set_show_groups (EmpathyIndividualStore *self,
gboolean show_groups)
{
+ EmpathyIndividualStoreClass *klass;
+
g_return_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self));
+ klass = EMPATHY_INDIVIDUAL_STORE_GET_CLASS ( self);
+
if (self->priv->show_groups == show_groups)
{
return;
self->priv->show_groups = show_groups;
- if (self->setup_idle_id == 0)
+ if (!klass->initial_loading (self))
{
/* Remove all contacts and add them back, not optimized but
* that's the easy way :)
* This is only done if there's not a pending setup idle
* callback, otherwise it will race and the contacts will get
* added twice */
- EmpathyIndividualStoreClass *klass = EMPATHY_INDIVIDUAL_STORE_GET_CLASS (
- self);
gtk_tree_store_clear (GTK_TREE_STORE (self));
/* Also clear the cache */
return pixbuf_status;
}
+
+void
+empathy_individual_store_refresh_individual (EmpathyIndividualStore *self,
+ FolksIndividual *individual)
+{
+ gboolean show_active;
+
+ show_active = self->priv->show_active;
+ self->priv->show_active = FALSE;
+ empathy_individual_store_remove_individual (self, individual);
+ empathy_individual_store_add_individual (self, individual);
+ self->priv->show_active = show_active;
+}