*/
#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 <libempathy/empathy-individual-manager.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).
/* Time in seconds after connecting which we wait before active users are enabled */
#define ACTIVE_USER_WAIT_TO_ENABLE_TIME 5
-#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIndividualStore)
-typedef struct
+struct _EmpathyIndividualStorePriv
{
- EmpathyIndividualManager *manager;
gboolean show_avatars;
gboolean show_groups;
gboolean is_compact;
gboolean show_protocols;
- gboolean show_active;
EmpathyIndividualStoreSort sort_criterium;
guint inhibit_active;
- guint setup_idle_id;
gboolean dispose_has_run;
GHashTable *status_icons;
/* List of owned GCancellables for each pending avatar load operation */
GList *avatar_cancellables;
-} EmpathyIndividualStorePriv;
-
-typedef struct
-{
- GtkTreeIter iter;
- const gchar *name;
- gboolean found;
-} FindGroup;
-
-typedef struct
-{
- FolksIndividual *individual;
- gboolean found;
- GList *iters;
-} FindContact;
+ /* Hash: FolksIndividual* -> GQueue (GtkTreeIter *) */
+ GHashTable *folks_individual_cache;
+ /* Hash: char *groupname -> GtkTreeIter * */
+ GHashTable *empathy_group_cache;
+ gboolean show_active;
+};
typedef struct
{
enum
{
PROP_0,
- PROP_INDIVIDUAL_MANAGER,
PROP_SHOW_AVATARS,
PROP_SHOW_PROTOCOLS,
PROP_SHOW_GROUPS,
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)
- {
- FolksHasPresence *presence;
-
- /* We only want personas which implement FolksHasPresence */
- if (!FOLKS_IS_HAS_PRESENCE (l->data))
- continue;
-
- presence = FOLKS_HAS_PRESENCE (l->data);
-
- if (folks_has_presence_typecmp (
- folks_has_presence_get_presence_type (presence),
- presence_type) > 0)
- {
- TpContact *tp_contact;
-
- presence_type = folks_has_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,
+add_individual_to_store (GtkTreeStore *store,
GtkTreeIter *iter,
GtkTreeIter *parent,
FolksIndividual *individual)
{
+ EmpathyIndividualStore *self = EMPATHY_INDIVIDUAL_STORE (store);
gboolean can_audio_call, can_video_call;
const gchar * const *types;
+ GQueue *queue;
- individual_can_audio_video_call (individual, &can_audio_call,
- &can_video_call);
+ 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 (self, iter, parent, 0,
+ gtk_tree_store_insert_with_values (store, iter, parent, 0,
EMPATHY_INDIVIDUAL_STORE_COL_NAME,
- folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
+ folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (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_CAN_VIDEO_CALL, can_video_call,
EMPATHY_INDIVIDUAL_STORE_COL_CLIENT_TYPES, types,
-1);
-}
-
-static gboolean
-individual_store_get_group_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- FindGroup *fg)
-{
- gchar *str;
- gboolean is_group;
-
- /* Groups are only at the top level. */
- if (gtk_tree_path_get_depth (path) != 1)
- return FALSE;
-
- gtk_tree_model_get (model, iter,
- EMPATHY_INDIVIDUAL_STORE_COL_NAME, &str,
- EMPATHY_INDIVIDUAL_STORE_COL_IS_GROUP, &is_group, -1);
- if (is_group && !tp_strdiff (str, fg->name))
+ queue = g_hash_table_lookup (self->priv->folks_individual_cache, individual);
+ if (queue)
{
- fg->found = TRUE;
- fg->iter = *iter;
+ g_queue_push_tail (queue, gtk_tree_iter_copy (iter));
+ }
+ else
+ {
+ queue = g_queue_new ();
+ g_queue_push_tail (queue, gtk_tree_iter_copy (iter));
+ g_hash_table_insert (self->priv->folks_individual_cache, individual,
+ queue);
}
-
- g_free (str);
-
- return fg->found;
}
static void
gboolean *created,
gboolean is_fake_group)
{
- EmpathyIndividualStorePriv *priv;
GtkTreeModel *model;
GtkTreeIter iter_group;
GtkTreeIter iter_separator;
- FindGroup fg;
-
- priv = GET_PRIV (self);
-
- memset (&fg, 0, sizeof (fg));
-
- fg.name = name;
+ GtkTreeIter *iter;
model = GTK_TREE_MODEL (self);
- gtk_tree_model_foreach (model,
- (GtkTreeModelForeachFunc) individual_store_get_group_foreach, &fg);
+ iter = g_hash_table_lookup (self->priv->empathy_group_cache, name);
- if (!fg.found)
+ if (iter == NULL)
{
if (created)
*created = TRUE;
EMPATHY_INDIVIDUAL_STORE_COL_IS_FAKE_GROUP, is_fake_group,
-1);
+ g_hash_table_insert (self->priv->empathy_group_cache, g_strdup (name),
+ gtk_tree_iter_copy (&iter_group));
+
if (iter_group_to_set)
*iter_group_to_set = iter_group;
*created = FALSE;
if (iter_group_to_set)
- *iter_group_to_set = fg.iter;
+ *iter_group_to_set = *iter;
- iter_separator = fg.iter;
+ iter_separator = *iter;
if (gtk_tree_model_iter_next (model, &iter_separator))
{
}
}
-static gboolean
-individual_store_find_contact_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- FindContact *fc)
-{
- FolksIndividual *individual;
-
- gtk_tree_model_get (model, iter,
- EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual, -1);
-
- if (individual == fc->individual)
- {
- fc->found = TRUE;
- fc->iters = g_list_append (fc->iters, gtk_tree_iter_copy (iter));
- }
-
- tp_clear_object (&individual);
-
- return FALSE;
-}
-
-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)
{
- EmpathyIndividualStorePriv *priv;
- GtkTreeModel *model;
- GList *l = NULL;
- FindContact fc;
-
- priv = GET_PRIV (self);
-
- memset (&fc, 0, sizeof (fc));
+ GQueue *row_refs_queue;
+ GList *i;
+ GList *iters_list = NULL;
- fc.individual = individual;
+ row_refs_queue = g_hash_table_lookup (self->priv->folks_individual_cache,
+ individual);
+ if (!row_refs_queue)
+ return NULL;
- model = GTK_TREE_MODEL (self);
- gtk_tree_model_foreach (model,
- (GtkTreeModelForeachFunc) individual_store_find_contact_foreach, &fc);
+ for (i = g_queue_peek_head_link (row_refs_queue) ; i != NULL ; i = i->next)
+ {
+ GtkTreeIter *iter = i->data;
- if (fc.found)
- l = fc.iters;
+ iters_list = g_list_prepend (iters_list, gtk_tree_iter_copy (iter));
+ }
- return l;
+ 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);
}
-static void
-individual_store_remove_individual (EmpathyIndividualStore *self,
+void
+empathy_individual_store_remove_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- EmpathyIndividualStorePriv *priv;
GtkTreeModel *model;
- GList *iters, *l;
-
- priv = GET_PRIV (self);
+ GQueue *row_refs;
+ GList *l;
- iters = individual_store_find_contact (self, individual);
- if (iters == NULL)
+ row_refs = g_hash_table_lookup (self->priv->folks_individual_cache,
+ individual);
+ if (!row_refs)
return;
/* Clean up model */
model = GTK_TREE_MODEL (self);
- for (l = iters; l; l = l->next)
+ for (l = g_queue_peek_head_link (row_refs); l; l = l->next)
{
+ GtkTreeIter *iter = l->data;
GtkTreeIter parent;
/* NOTE: it is only <= 2 here because we have
* separators after the group name, otherwise it
* should be 1.
*/
- if (gtk_tree_model_iter_parent (model, &parent, l->data) &&
+ if (gtk_tree_model_iter_parent (model, &parent, iter) &&
gtk_tree_model_iter_n_children (model, &parent) <= 2)
{
+ gchar *group_name;
+ gtk_tree_model_get (model, &parent,
+ EMPATHY_INDIVIDUAL_STORE_COL_NAME, &group_name,
+ -1);
+ g_hash_table_remove (self->priv->empathy_group_cache,
+ group_name);
gtk_tree_store_remove (GTK_TREE_STORE (self), &parent);
}
else
{
- gtk_tree_store_remove (GTK_TREE_STORE (self), l->data);
+ gtk_tree_store_remove (GTK_TREE_STORE (self), iter);
}
}
- free_iters (iters);
+ g_hash_table_remove (self->priv->folks_individual_cache, individual);
}
-static void
-individual_store_add_individual (EmpathyIndividualStore *self,
+void
+empathy_individual_store_add_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- EmpathyIndividualStorePriv *priv;
- GtkTreeIter iter;
- GHashTable *group_set = NULL;
- GList *groups = NULL, *l;
- EmpathyContact *contact;
- TpConnection *connection;
- gchar *protocol_name;
-
- priv = GET_PRIV (self);
+ GtkTreeIter iter, iter_group;
+ GeeSet *group_set = NULL;
+ gboolean grouped = FALSE;
- if (EMP_STR_EMPTY (folks_aliasable_get_alias (FOLKS_ALIASABLE (individual))))
+ if (TPAW_STR_EMPTY (folks_alias_details_get_alias (
+ FOLKS_ALIAS_DETAILS (individual))))
return;
- if (priv->show_groups)
+ if (!self->priv->show_groups)
{
- group_set = folks_groupable_get_groups (FOLKS_GROUPABLE (individual));
- groups = g_hash_table_get_keys (group_set);
+ /* add our individual to the toplevel of the store */
+ add_individual_to_store (GTK_TREE_STORE (self), &iter, NULL,
+ individual);
+
+ goto finally;
}
- contact = empathy_contact_dup_from_folks_individual (individual);
- connection = empathy_contact_get_connection (contact);
+ 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;
- tp_connection_parse_object_path (connection, &protocol_name, NULL);
+ g_free (group_name);
+ }
- if (groups == NULL)
+ g_clear_object (&group_iter);
+ }
+ else
{
- GtkTreeIter iter_group, *parent;
+ /* fall-back groups, in case there are no named groups */
+ EmpathyContact *contact;
+ TpConnection *connection;
+ const gchar *protocol_name = NULL;
- parent = &iter_group;
+ contact = empathy_contact_dup_from_folks_individual (individual);
+ if (contact != NULL)
+ {
+ connection = empathy_contact_get_connection (contact);
+ protocol_name = tp_connection_get_protocol_name (connection);
+ }
- if (!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);
- }
- else
- {
- 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);
+ grouped = TRUE;
}
- add_individual_to_store (GTK_TREE_STORE (self), &iter, parent,
- individual);
+ g_clear_object (&contact);
}
- g_free (protocol_name);
-
- /* Else add to each group. */
- for (l = groups; l; l = l->next)
+ if (folks_favourite_details_get_is_favourite (
+ FOLKS_FAVOURITE_DETAILS (individual)))
{
- GtkTreeIter iter_group;
-
- individual_store_get_group (self, l->data, &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);
+ grouped = TRUE;
}
- g_list_free (groups);
- if (priv->show_groups &&
- folks_favouritable_get_is_favourite (FOLKS_FAVOURITABLE (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);
}
- individual_store_contact_update (self, individual);
- tp_clear_object (&contact);
+finally:
+ individual_store_contact_update (self, individual);
}
static void
gboolean active,
gboolean set_changed)
{
- EmpathyIndividualStorePriv *priv;
GtkTreeModel *model;
GList *iters, *l;
- priv = GET_PRIV (self);
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_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
- remove_ ? "WILL" : "WILL NOT");
-
data = g_slice_new0 (ShowActiveData);
/* We don't actually want to force either the IndividualStore or the
if (data->remove)
{
DEBUG ("Individual'%s' active timeout, removing item",
- folks_aliasable_get_alias (FOLKS_ALIASABLE (data->individual)));
- individual_store_remove_individual (data->self, data->individual);
+ folks_alias_details_get_alias (
+ FOLKS_ALIAS_DETAILS (data->individual)));
+ empathy_individual_store_remove_individual (data->self, data->individual);
}
- DEBUG ("Individual'%s' no longer active",
- 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_aliasable_get_alias (FOLKS_ALIASABLE (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 */
if (data->store != NULL)
{
- EmpathyIndividualStorePriv *priv = GET_PRIV (data->store);
-
g_object_remove_weak_pointer (G_OBJECT (data->store),
(gpointer *) &data->store);
- priv->avatar_cancellables = g_list_remove (priv->avatar_cancellables,
- data->cancellable);
+ data->store->priv->avatar_cancellables = g_list_remove (
+ data->store->priv->avatar_cancellables, data->cancellable);
}
tp_clear_object (&pixbuf);
individual_store_contact_update (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- EmpathyIndividualStorePriv *priv;
ShowActiveData *data;
GtkTreeModel *model;
GList *iters, *l;
GdkPixbuf *pixbuf_status;
LoadAvatarData *load_avatar_data;
- priv = GET_PRIV (self);
-
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;
}
/* Get online state now. */
- now_online = folks_has_presence_is_online (FOLKS_HAS_PRESENCE (individual));
+ now_online = folks_presence_details_is_online (
+ FOLKS_PRESENCE_DETAILS (individual));
if (!in_list)
{
DEBUG ("Individual'%s' in list:NO, should be:YES",
- folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)));
+ folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)));
- individual_store_add_individual (self, individual);
+ empathy_individual_store_add_individual (self, individual);
- if (priv->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_aliasable_get_alias (FOLKS_ALIASABLE (individual)));
-
/* Get online state before. */
if (iters && g_list_length (iters) > 0)
{
}
/* Is this really an update or an online/offline. */
- if (priv->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)");
}
}
set_model = TRUE;
}
- if (priv->show_avatars && !priv->is_compact)
+ if (self->priv->show_avatars && !self->priv->is_compact)
{
show_avatar = TRUE;
}
(gpointer *) &load_avatar_data->store);
load_avatar_data->cancellable = g_cancellable_new ();
- priv->avatar_cancellables = g_list_prepend (priv->avatar_cancellables,
- load_avatar_data->cancellable);
+ self->priv->avatar_cancellables = g_list_prepend (
+ self->priv->avatar_cancellables, load_avatar_data->cancellable);
+
empathy_pixbuf_avatar_from_individual_scaled_async (individual, 32, 32,
load_avatar_data->cancellable,
(GAsyncReadyCallback) individual_avatar_pixbuf_received_cb,
gboolean can_audio_call, can_video_call;
const gchar * const *types;
- individual_can_audio_video_call (individual, &can_audio_call,
- &can_video_call);
+ 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,
EMPATHY_INDIVIDUAL_STORE_COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
EMPATHY_INDIVIDUAL_STORE_COL_NAME,
- folks_aliasable_get_alias (FOLKS_ALIASABLE (individual)),
+ folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)),
EMPATHY_INDIVIDUAL_STORE_COL_PRESENCE_TYPE,
- folks_has_presence_get_presence_type (
- FOLKS_HAS_PRESENCE (individual)),
+ folks_presence_details_get_presence_type (
+ FOLKS_PRESENCE_DETAILS (individual)),
EMPATHY_INDIVIDUAL_STORE_COL_STATUS,
- folks_has_presence_get_presence_message (
- FOLKS_HAS_PRESENCE (individual)),
- EMPATHY_INDIVIDUAL_STORE_COL_COMPACT, priv->is_compact,
+ folks_presence_details_get_presence_message (
+ FOLKS_PRESENCE_DETAILS (individual)),
+ EMPATHY_INDIVIDUAL_STORE_COL_COMPACT, self->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,
-1);
}
- if (priv->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_aliasable_get_alias (FOLKS_ALIASABLE (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;
static void
individual_personas_changed_cb (FolksIndividual *individual,
- GList *added,
- GList *removed,
+ GeeSet *added,
+ GeeSet *removed,
EmpathyIndividualStore *self)
{
- GList *l;
-
- DEBUG ("Individual '%s' personas-changed.",
- folks_individual_get_id (individual));
+ GeeIterator *iter;
+ 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. */
- for (l = removed; l != NULL; l = l->next)
+ while (gee_iterator_next (iter))
{
+ TpfPersona *persona = gee_iterator_get (iter);
TpContact *tp_contact;
EmpathyContact *contact;
- if (!TPF_IS_PERSONA (l->data))
- continue;
+ if (TPF_IS_PERSONA (persona))
+ {
+ tp_contact = tpf_persona_get_contact (persona);
+ if (tp_contact != NULL)
+ {
+ contact = empathy_contact_dup_from_tp_contact (tp_contact);
+ empathy_contact_set_persona (contact, FOLKS_PERSONA (persona));
- 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));
+ 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_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);
+ }
+ }
- g_object_unref (contact);
+ g_clear_object (&persona);
}
+ g_clear_object (&iter);
- for (l = added; l != NULL; l = l->next)
+ iter = gee_iterable_iterator (GEE_ITERABLE (added));
+ while (gee_iterator_next (iter))
{
+ TpfPersona *persona = gee_iterator_get (iter);
TpContact *tp_contact;
EmpathyContact *contact;
- if (!TPF_IS_PERSONA (l->data))
- continue;
+ if (TPF_IS_PERSONA (persona))
+ {
+ tp_contact = tpf_persona_get_contact (persona);
+ if (tp_contact != NULL)
+ {
+ contact = empathy_contact_dup_from_tp_contact (tp_contact);
+ empathy_contact_set_persona (contact, FOLKS_PERSONA (persona));
- 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));
+ 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_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);
+ }
+ }
- g_object_unref (contact);
+ g_clear_object (&persona);
}
+ g_clear_object (&iter);
}
static void
+individual_store_favourites_changed_cb (FolksIndividual *individual,
+ GParamSpec *param,
+ EmpathyIndividualStore *self)
+{
+ DEBUG ("Individual %s is %s a favourite",
+ folks_individual_get_id (individual),
+ folks_favourite_details_get_is_favourite (
+ FOLKS_FAVOURITE_DETAILS (individual)) ? "now" : "no longer");
+
+ empathy_individual_store_remove_individual (self, individual);
+ empathy_individual_store_add_individual (self, individual);
+}
+
+void
individual_store_add_individual_and_connect (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- individual_store_add_individual (self, individual);
+ GeeSet *empty_set = gee_set_empty (G_TYPE_NONE, NULL, NULL);
+
+ empathy_individual_store_add_individual (self, individual);
g_signal_connect (individual, "notify::avatar",
(GCallback) individual_store_individual_updated_cb, self);
(GCallback) individual_store_individual_updated_cb, self);
g_signal_connect (individual, "personas-changed",
(GCallback) individual_personas_changed_cb, self);
+ g_signal_connect (individual, "notify::is-favourite",
+ (GCallback) individual_store_favourites_changed_cb, self);
+ /* provide an empty set so the callback can assume non-NULL sets */
individual_personas_changed_cb (individual,
- folks_individual_get_personas (individual), NULL, self);
+ folks_individual_get_personas (individual), empty_set, self);
+ g_clear_object (&empty_set);
}
-static void
-individual_store_disconnect_individual (EmpathyIndividualStore *self,
+void
+empathy_individual_store_disconnect_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- individual_personas_changed_cb (individual, NULL,
+ GeeSet *empty_set = gee_set_empty (G_TYPE_NONE, NULL, NULL);
+
+ /* provide an empty set so the callback can assume non-NULL sets */
+ individual_personas_changed_cb (individual, empty_set,
folks_individual_get_personas (individual), self);
+ g_clear_object (&empty_set);
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);
+ g_signal_handlers_disconnect_by_func (individual,
+ (GCallback) individual_store_favourites_changed_cb, self);
}
-static void
+void
individual_store_remove_individual_and_disconnect (
EmpathyIndividualStore *self,
FolksIndividual *individual)
{
- individual_store_disconnect_individual (self, individual);
- individual_store_remove_individual (self, individual);
-}
-
-static void
-individual_store_members_changed_cb (EmpathyIndividualManager *manager,
- const gchar *message,
- GList *added,
- GList *removed,
- guint reason,
- EmpathyIndividualStore *self)
-{
- GList *l;
-
- for (l = added; l; l = l->next)
- {
- DEBUG ("Individual %s %s", folks_individual_get_id (l->data), "added");
-
- individual_store_add_individual_and_connect (self, l->data);
- }
- for (l = removed; l; l = l->next)
- {
- DEBUG ("Individual %s %s",
- folks_individual_get_id (l->data), "removed");
-
- individual_store_remove_individual_and_disconnect (self, l->data);
- }
-}
-
-static void
-individual_store_favourites_changed_cb (EmpathyIndividualManager *manager,
- FolksIndividual *individual,
- gboolean is_favourite,
- EmpathyIndividualStore *self)
-{
- EmpathyIndividualStorePriv *priv;
-
- priv = GET_PRIV (self);
-
- DEBUG ("Individual %s is %s a favourite",
- folks_individual_get_id (individual),
- is_favourite ? "now" : "no longer");
-
- individual_store_remove_individual (self, individual);
- individual_store_add_individual (self, individual);
-}
-
-static void
-individual_store_groups_changed_cb (EmpathyIndividualManager *manager,
- FolksIndividual *individual,
- gchar *group,
- gboolean is_member,
- EmpathyIndividualStore *self)
-{
- EmpathyIndividualStorePriv *priv;
- gboolean show_active;
-
- priv = GET_PRIV (self);
-
- DEBUG ("Updating groups for individual %s",
- folks_individual_get_id (individual));
-
- /* We do this to make sure the groups are correct, if not, we
- * would have to check the groups already set up for each
- * contact and then see what has been updated.
- */
- show_active = priv->show_active;
- priv->show_active = FALSE;
- individual_store_remove_individual (self, individual);
- individual_store_add_individual (self, individual);
- priv->show_active = show_active;
-}
-
-static gboolean
-individual_store_manager_setup (gpointer user_data)
-{
- EmpathyIndividualStore *self = user_data;
- EmpathyIndividualStorePriv *priv = GET_PRIV (self);
- GList *individuals;
-
- /* Signal connection. */
-
- /* TODO: implement */
- DEBUG ("handling individual renames unimplemented");
-
- g_signal_connect (priv->manager,
- "members-changed",
- G_CALLBACK (individual_store_members_changed_cb), self);
-
- g_signal_connect (priv->manager,
- "favourites-changed",
- G_CALLBACK (individual_store_favourites_changed_cb), self);
-
- g_signal_connect (priv->manager,
- "groups-changed",
- G_CALLBACK (individual_store_groups_changed_cb), self);
-
- /* Add contacts already created. */
- individuals = empathy_individual_manager_get_members (priv->manager);
- if (individuals != NULL && FOLKS_IS_INDIVIDUAL (individuals->data))
- {
- individual_store_members_changed_cb (priv->manager, "initial add",
- individuals, NULL, 0, self);
- g_list_free (individuals);
- }
-
- priv->setup_idle_id = 0;
- return FALSE;
-}
-
-static void
-individual_store_set_individual_manager (EmpathyIndividualStore *self,
- EmpathyIndividualManager *manager)
-{
- EmpathyIndividualStorePriv *priv = GET_PRIV (self);
-
- priv->manager = g_object_ref (manager);
-
- /* Let a chance to have all properties set before populating */
- priv->setup_idle_id = g_idle_add (individual_store_manager_setup, self);
-}
-
-static void
-individual_store_member_renamed_cb (EmpathyIndividualManager *manager,
- FolksIndividual *old_individual,
- FolksIndividual *new_individual,
- guint reason,
- const gchar *message,
- EmpathyIndividualStore *self)
-{
- EmpathyIndividualStorePriv *priv;
-
- priv = GET_PRIV (self);
-
- DEBUG ("Individual %s renamed to %s",
- folks_individual_get_id (old_individual),
- folks_individual_get_id (new_individual));
-
- /* add the new contact */
- individual_store_add_individual_and_connect (self, new_individual);
-
- /* remove old contact */
- individual_store_remove_individual_and_disconnect (self, old_individual);
+ empathy_individual_store_disconnect_individual (self, individual);
+ empathy_individual_store_remove_individual (self, individual);
}
static void
individual_store_dispose (GObject *object)
{
- EmpathyIndividualStorePriv *priv = GET_PRIV (object);
- GList *individuals, *l;
+ EmpathyIndividualStore *self = EMPATHY_INDIVIDUAL_STORE (object);
+ GList *l;
- if (priv->dispose_has_run)
+ if (self->priv->dispose_has_run)
return;
- priv->dispose_has_run = TRUE;
+ self->priv->dispose_has_run = TRUE;
/* Cancel any pending avatar load operations */
- for (l = priv->avatar_cancellables; l != NULL; l = l->next)
+ for (l = self->priv->avatar_cancellables; l != NULL; l = l->next)
{
/* The cancellables are freed in individual_avatar_pixbuf_received_cb() */
g_cancellable_cancel (G_CANCELLABLE (l->data));
}
- g_list_free (priv->avatar_cancellables);
-
- individuals = empathy_individual_manager_get_members (priv->manager);
- for (l = individuals; l; l = l->next)
- {
- individual_store_disconnect_individual (EMPATHY_INDIVIDUAL_STORE (object),
- FOLKS_INDIVIDUAL (l->data));
- }
- g_list_free (individuals);
-
- g_signal_handlers_disconnect_by_func (priv->manager,
- G_CALLBACK (individual_store_member_renamed_cb), object);
- g_signal_handlers_disconnect_by_func (priv->manager,
- G_CALLBACK (individual_store_members_changed_cb), object);
- g_signal_handlers_disconnect_by_func (priv->manager,
- G_CALLBACK (individual_store_favourites_changed_cb), object);
- g_signal_handlers_disconnect_by_func (priv->manager,
- G_CALLBACK (individual_store_groups_changed_cb), object);
- g_object_unref (priv->manager);
-
- if (priv->inhibit_active)
- {
- g_source_remove (priv->inhibit_active);
- }
+ g_list_free (self->priv->avatar_cancellables);
- if (priv->setup_idle_id != 0)
+ if (self->priv->inhibit_active)
{
- g_source_remove (priv->setup_idle_id);
+ g_source_remove (self->priv->inhibit_active);
}
- g_hash_table_destroy (priv->status_icons);
+ 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_OBJECT_CLASS (empathy_individual_store_parent_class)->dispose (object);
}
GValue *value,
GParamSpec *pspec)
{
- EmpathyIndividualStorePriv *priv;
-
- priv = GET_PRIV (object);
+ EmpathyIndividualStore *self = EMPATHY_INDIVIDUAL_STORE (object);
switch (param_id)
{
- case PROP_INDIVIDUAL_MANAGER:
- g_value_set_object (value, priv->manager);
- break;
case PROP_SHOW_AVATARS:
- g_value_set_boolean (value, priv->show_avatars);
+ g_value_set_boolean (value, self->priv->show_avatars);
break;
case PROP_SHOW_PROTOCOLS:
- g_value_set_boolean (value, priv->show_protocols);
+ g_value_set_boolean (value, self->priv->show_protocols);
break;
case PROP_SHOW_GROUPS:
- g_value_set_boolean (value, priv->show_groups);
+ g_value_set_boolean (value, self->priv->show_groups);
break;
case PROP_IS_COMPACT:
- g_value_set_boolean (value, priv->is_compact);
+ g_value_set_boolean (value, self->priv->is_compact);
break;
case PROP_SORT_CRITERIUM:
- g_value_set_enum (value, priv->sort_criterium);
+ g_value_set_enum (value, self->priv->sort_criterium);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
const GValue *value,
GParamSpec *pspec)
{
- EmpathyIndividualStorePriv *priv;
-
- priv = GET_PRIV (object);
-
switch (param_id)
{
- case PROP_INDIVIDUAL_MANAGER:
- individual_store_set_individual_manager (EMPATHY_INDIVIDUAL_STORE
- (object), g_value_get_object (value));
- break;
case PROP_SHOW_AVATARS:
empathy_individual_store_set_show_avatars (EMPATHY_INDIVIDUAL_STORE
(object), g_value_get_boolean (value));
object_class->get_property = individual_store_get_property;
object_class->set_property = individual_store_set_property;
- g_object_class_install_property (object_class,
- PROP_INDIVIDUAL_MANAGER,
- g_param_spec_object ("individual-manager",
- "The individual manager",
- "The individual manager",
- EMPATHY_TYPE_INDIVIDUAL_MANAGER,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_SHOW_AVATARS,
g_param_spec_boolean ("show-avatars",
/* alias */
ret_val = g_utf8_collate (
- folks_aliasable_get_alias (FOLKS_ALIASABLE (individual_a)),
- folks_aliasable_get_alias (FOLKS_ALIASABLE (individual_b)));
+ folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual_a)),
+ folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual_b)));
if (ret_val != 0)
goto out;
contact_a = empathy_contact_dup_from_folks_individual (individual_a);
contact_b = empathy_contact_dup_from_folks_individual (individual_b);
- account_a = empathy_contact_get_account (contact_a);
- account_b = empathy_contact_get_account (contact_b);
+ if (contact_a != NULL && contact_b != NULL)
+ {
+ 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);
+ 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));
+ /* protocol */
+ ret_val = g_strcmp0 (tp_account_get_protocol_name (account_a),
+ tp_account_get_protocol_name (account_b));
- if (ret_val != 0)
- goto out;
+ if (ret_val != 0)
+ goto out;
- /* account ID */
- ret_val = g_strcmp0 (tp_proxy_get_object_path (account_a),
- tp_proxy_get_object_path (account_b));
+ /* account ID */
+ ret_val = g_strcmp0 (tp_proxy_get_object_path (account_a),
+ tp_proxy_get_object_path (account_b));
- if (ret_val != 0)
- goto out;
+ if (ret_val != 0)
+ goto out;
+ }
/* identifier */
ret_val = g_utf8_collate (folks_individual_get_id (individual_a),
* the presences.
*/
folks_presence_type_a =
- folks_has_presence_get_presence_type (FOLKS_HAS_PRESENCE (individual_a));
+ folks_presence_details_get_presence_type (
+ FOLKS_PRESENCE_DETAILS (individual_a));
folks_presence_type_b =
- folks_has_presence_get_presence_type (FOLKS_HAS_PRESENCE (individual_b));
+ folks_presence_details_get_presence_type (
+ FOLKS_PRESENCE_DETAILS (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);
static void
individual_store_setup (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
GType types[] = {
GDK_TYPE_PIXBUF, /* Status pixbuf */
GDK_TYPE_PIXBUF, /* Avatar pixbuf */
G_TYPE_BOOLEAN, /* Can make video calls */
G_TYPE_BOOLEAN, /* Is a fake group */
G_TYPE_STRV, /* Client types */
+ G_TYPE_UINT, /* Event count */
};
- priv = GET_PRIV (self);
-
gtk_tree_store_set_column_types (GTK_TREE_STORE (self),
EMPATHY_INDIVIDUAL_STORE_COL_COUNT, types);
EMPATHY_INDIVIDUAL_STORE_COL_STATUS,
individual_store_state_sort_func, self, NULL);
- priv->sort_criterium = EMPATHY_INDIVIDUAL_STORE_SORT_NAME;
- empathy_individual_store_set_sort_criterium (self, priv->sort_criterium);
+ self->priv->sort_criterium = EMPATHY_INDIVIDUAL_STORE_SORT_NAME;
+
+ empathy_individual_store_set_sort_criterium (self,
+ self->priv->sort_criterium);
}
static gboolean
individual_store_inhibit_active_cb (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
-
- priv = GET_PRIV (self);
-
- priv->show_active = TRUE;
- priv->inhibit_active = 0;
+ self->priv->show_active = TRUE;
+ self->priv->inhibit_active = 0;
return FALSE;
}
+static void
+g_queue_free_full_iter (gpointer data)
+{
+ GQueue *queue = (GQueue *) data;
+ g_queue_foreach (queue, (GFunc) gtk_tree_iter_free, NULL);
+ g_queue_free (queue);
+}
+
static void
empathy_individual_store_init (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EMPATHY_TYPE_INDIVIDUAL_STORE, EmpathyIndividualStorePriv);
- self->priv = priv;
- priv->show_avatars = TRUE;
- priv->show_groups = TRUE;
- priv->show_protocols = FALSE;
- priv->inhibit_active =
+ self->priv->show_avatars = TRUE;
+ self->priv->show_groups = TRUE;
+ self->priv->show_protocols = FALSE;
+ self->priv->inhibit_active =
g_timeout_add_seconds (ACTIVE_USER_WAIT_TO_ENABLE_TIME,
(GSourceFunc) individual_store_inhibit_active_cb, self);
- priv->status_icons =
+ self->priv->status_icons =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ self->priv->folks_individual_cache = g_hash_table_new_full (NULL, NULL, NULL,
+ g_queue_free_full_iter);
+ self->priv->empathy_group_cache = g_hash_table_new_full (g_str_hash,
+ g_str_equal, g_free, (GDestroyNotify) gtk_tree_iter_free);
individual_store_setup (self);
}
-EmpathyIndividualStore *
-empathy_individual_store_new (EmpathyIndividualManager *manager)
-{
- g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager), NULL);
-
- return g_object_new (EMPATHY_TYPE_INDIVIDUAL_STORE,
- "individual-manager", manager, NULL);
-}
-
-EmpathyIndividualManager *
-empathy_individual_store_get_manager (EmpathyIndividualStore *self)
-{
- EmpathyIndividualStorePriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), FALSE);
-
- priv = GET_PRIV (self);
-
- return priv->manager;
-}
-
gboolean
empathy_individual_store_get_show_avatars (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
-
g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), TRUE);
- priv = GET_PRIV (self);
-
- return priv->show_avatars;
+ return self->priv->show_avatars;
}
static gboolean
GtkTreeIter *iter,
EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
gboolean show_avatar = FALSE;
FolksIndividual *individual;
GdkPixbuf *pixbuf_status;
- priv = GET_PRIV (self);
-
- if (priv->show_avatars && !priv->is_compact)
+ if (self->priv->show_avatars && !self->priv->is_compact)
{
show_avatar = TRUE;
}
gtk_tree_store_set (GTK_TREE_STORE (self), iter,
EMPATHY_INDIVIDUAL_STORE_COL_ICON_STATUS, pixbuf_status,
EMPATHY_INDIVIDUAL_STORE_COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
- EMPATHY_INDIVIDUAL_STORE_COL_COMPACT, priv->is_compact, -1);
+ EMPATHY_INDIVIDUAL_STORE_COL_COMPACT, self->priv->is_compact, -1);
g_object_unref (individual);
empathy_individual_store_set_show_avatars (EmpathyIndividualStore *self,
gboolean show_avatars)
{
- EmpathyIndividualStorePriv *priv;
GtkTreeModel *model;
g_return_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self));
- priv = GET_PRIV (self);
-
- priv->show_avatars = show_avatars;
+ self->priv->show_avatars = show_avatars;
model = GTK_TREE_MODEL (self);
gboolean
empathy_individual_store_get_show_protocols (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
-
g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), TRUE);
- priv = GET_PRIV (self);
-
- return priv->show_protocols;
+ return self->priv->show_protocols;
}
void
empathy_individual_store_set_show_protocols (EmpathyIndividualStore *self,
gboolean show_protocols)
{
- EmpathyIndividualStorePriv *priv;
GtkTreeModel *model;
g_return_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self));
- priv = GET_PRIV (self);
-
- priv->show_protocols = show_protocols;
+ self->priv->show_protocols = show_protocols;
model = GTK_TREE_MODEL (self);
gboolean
empathy_individual_store_get_show_groups (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
-
g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), TRUE);
- priv = GET_PRIV (self);
-
- return priv->show_groups;
+ return self->priv->show_groups;
}
void
empathy_individual_store_set_show_groups (EmpathyIndividualStore *self,
gboolean show_groups)
{
- EmpathyIndividualStorePriv *priv;
+ EmpathyIndividualStoreClass *klass;
g_return_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self));
- priv = GET_PRIV (self);
+ klass = EMPATHY_INDIVIDUAL_STORE_GET_CLASS ( self);
- if (priv->show_groups == show_groups)
+ if (self->priv->show_groups == show_groups)
{
return;
}
- priv->show_groups = show_groups;
+ self->priv->show_groups = show_groups;
- if (priv->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 */
- GList *contacts;
gtk_tree_store_clear (GTK_TREE_STORE (self));
- contacts = empathy_individual_manager_get_members (priv->manager);
+ /* Also clear the cache */
+ g_hash_table_remove_all (self->priv->folks_individual_cache);
+ g_hash_table_remove_all (self->priv->empathy_group_cache);
- individual_store_members_changed_cb (priv->manager,
- "re-adding members: toggled group visibility",
- contacts, NULL, 0, self);
- g_list_free (contacts);
+ klass->reload_individuals (self);
}
g_object_notify (G_OBJECT (self), "show-groups");
gboolean
empathy_individual_store_get_is_compact (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
-
g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), TRUE);
- priv = GET_PRIV (self);
-
- return priv->is_compact;
+ return self->priv->is_compact;
}
void
empathy_individual_store_set_is_compact (EmpathyIndividualStore *self,
gboolean is_compact)
{
- EmpathyIndividualStorePriv *priv;
GtkTreeModel *model;
g_return_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self));
- priv = GET_PRIV (self);
-
- priv->is_compact = is_compact;
+ self->priv->is_compact = is_compact;
model = GTK_TREE_MODEL (self);
EmpathyIndividualStoreSort
empathy_individual_store_get_sort_criterium (EmpathyIndividualStore *self)
{
- EmpathyIndividualStorePriv *priv;
-
g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), 0);
- priv = GET_PRIV (self);
-
- return priv->sort_criterium;
+ return self->priv->sort_criterium;
}
void
empathy_individual_store_set_sort_criterium (EmpathyIndividualStore *self,
EmpathyIndividualStoreSort sort_criterium)
{
- EmpathyIndividualStorePriv *priv;
-
g_return_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self));
- priv = GET_PRIV (self);
-
- priv->sort_criterium = sort_criterium;
+ self->priv->sort_criterium = sort_criterium;
switch (sort_criterium)
{
FolksIndividual *individual,
const gchar *status_icon_name)
{
- GdkPixbuf *pixbuf_status = NULL;
- EmpathyIndividualStorePriv *priv;
+ GdkPixbuf *pixbuf_status;
const gchar *protocol_name = NULL;
gchar *icon_name = NULL;
- GList *personas, *l;
- guint contact_count;
+ GeeSet *personas;
+ GeeIterator *iter;
+ guint contact_count = 0;
EmpathyContact *contact = NULL;
gboolean show_protocols_here;
- priv = GET_PRIV (self);
-
personas = folks_individual_get_personas (individual);
- for (l = personas, contact_count = 0; l; l = l->next)
+ iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+ while (gee_iterator_next (iter))
{
- if (TPF_IS_PERSONA (l->data))
+ FolksPersona *persona = gee_iterator_get (iter);
+ if (empathy_folks_persona_is_interesting (persona))
contact_count++;
+ g_clear_object (&persona);
+
if (contact_count > 1)
break;
}
+ g_clear_object (&iter);
- show_protocols_here = (priv->show_protocols && (contact_count == 1));
+ show_protocols_here = (self->priv->show_protocols && (contact_count == 1));
if (show_protocols_here)
{
contact = empathy_contact_dup_from_folks_individual (individual);
- protocol_name = empathy_protocol_name_for_contact (contact);
- icon_name = g_strdup_printf ("%s-%s", status_icon_name, protocol_name);
+ if (contact != NULL)
+ {
+ protocol_name = empathy_protocol_name_for_contact (contact);
+ icon_name = g_strdup_printf ("%s-%s", status_icon_name,
+ protocol_name);
+ }
+ else
+ {
+ g_warning ("Cannot retrieve contact from individual '%s'",
+ folks_alias_details_get_alias (
+ FOLKS_ALIAS_DETAILS (individual)));
+
+ return NULL;
+ }
}
else
{
icon_name = g_strdup_printf ("%s", status_icon_name);
}
+
+ pixbuf_status = g_hash_table_lookup (self->priv->status_icons, icon_name);
+
if (pixbuf_status == NULL)
{
pixbuf_status =
empathy_pixbuf_contact_status_icon_with_icon_name (contact,
status_icon_name, show_protocols_here);
+
if (pixbuf_status != NULL)
{
- g_hash_table_insert (priv->status_icons,
+ /* pass the reference to the hash table */
+ g_hash_table_insert (self->priv->status_icons,
g_strdup (icon_name), pixbuf_status);
}
}
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;
+}