#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"
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 */
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_list_free (iters);
}
-static void
-individual_store_remove_individual (EmpathyIndividualStore *self,
+void
+empathy_individual_store_remove_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
GtkTreeModel *model;
{
gchar *group_name;
gtk_tree_model_get (model, &parent,
- EMPATHY_CONTACT_LIST_STORE_COL_NAME, &group_name,
+ EMPATHY_INDIVIDUAL_STORE_COL_NAME, &group_name,
-1);
g_hash_table_remove (self->priv->empathy_group_cache,
group_name);
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)
{
- 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 (
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)
{
- GtkTreeIter iter_group, *parent;
+ /* 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
+ {
+ /* 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);
- }
- 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_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);
}
DEBUG ("Individual'%s' active timeout, removing item",
folks_alias_details_get_alias (
FOLKS_ALIAS_DETAILS (data->individual)));
- individual_store_remove_individual (data->self, data->individual);
+ empathy_individual_store_remove_individual (data->self, data->individual);
}
DEBUG ("Individual'%s' no longer active",
DEBUG ("Individual'%s' in list:NO, should be:YES",
folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual)));
- individual_store_add_individual (self, individual);
+ empathy_individual_store_add_individual (self, individual);
if (self->priv->show_active)
{
folks_favourite_details_get_is_favourite (
FOLKS_FAVOURITE_DETAILS (individual)) ? "now" : "no longer");
- individual_store_remove_individual (self, individual);
- individual_store_add_individual (self, individual);
+ empathy_individual_store_remove_individual (self, individual);
+ empathy_individual_store_add_individual (self, individual);
}
void
{
GeeSet *empty_set = gee_set_empty (G_TYPE_NONE, NULL, NULL);
- individual_store_add_individual (self, individual);
+ empathy_individual_store_add_individual (self, individual);
g_signal_connect (individual, "notify::avatar",
(GCallback) individual_store_individual_updated_cb, self);
g_clear_object (&empty_set);
}
-static void
-individual_store_disconnect_individual (EmpathyIndividualStore *self,
+void
+empathy_individual_store_disconnect_individual (EmpathyIndividualStore *self,
FolksIndividual *individual)
{
GeeSet *empty_set = gee_set_empty (G_TYPE_NONE, NULL, NULL);
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_groups_changed_cb (EmpathyIndividualManager *manager,
- FolksIndividual *individual,
- gchar *group,
- gboolean is_member,
- EmpathyIndividualStore *self)
-{
- gboolean show_active;
-
- 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 = self->priv->show_active;
- self->priv->show_active = FALSE;
- individual_store_remove_individual (self, individual);
- individual_store_add_individual (self, individual);
- self->priv->show_active = show_active;
-}
-
-static gboolean
-individual_store_manager_setup (gpointer user_data)
-{
- EmpathyIndividualStore *self = user_data;
- GList *individuals;
-
- /* Signal connection. */
-
- /* TODO: implement */
- DEBUG ("handling individual renames unimplemented");
-
- g_signal_connect (self->priv->manager,
- "members-changed",
- G_CALLBACK (individual_store_members_changed_cb), self);
-
- g_signal_connect (self->priv->manager,
- "groups-changed",
- G_CALLBACK (individual_store_groups_changed_cb), self);
-
- /* Add contacts already created. */
- individuals = empathy_individual_manager_get_members (self->priv->manager);
- if (individuals != NULL && FOLKS_IS_INDIVIDUAL (individuals->data))
- {
- individual_store_members_changed_cb (self->priv->manager, "initial add",
- individuals, NULL, 0, self);
- g_list_free (individuals);
- }
-
- self->priv->setup_idle_id = 0;
- return FALSE;
-}
-
-static void
-individual_store_set_individual_manager (EmpathyIndividualStore *self,
- EmpathyIndividualManager *manager)
-{
- self->priv->manager = g_object_ref (manager);
-
- /* Let a chance to have all properties set before populating */
- self->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)
-{
- 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)
{
EmpathyIndividualStore *self = EMPATHY_INDIVIDUAL_STORE (object);
- GList *individuals, *l;
+ GList *l;
if (self->priv->dispose_has_run)
return;
}
g_list_free (self->priv->avatar_cancellables);
- individuals = empathy_individual_manager_get_members (self->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 (self->priv->manager,
- G_CALLBACK (individual_store_member_renamed_cb), object);
- g_signal_handlers_disconnect_by_func (self->priv->manager,
- G_CALLBACK (individual_store_members_changed_cb), object);
- g_signal_handlers_disconnect_by_func (self->priv->manager,
- G_CALLBACK (individual_store_groups_changed_cb), object);
- g_object_unref (self->priv->manager);
-
if (self->priv->inhibit_active)
{
g_source_remove (self->priv->inhibit_active);
}
- if (self->priv->setup_idle_id != 0)
- {
- g_source_remove (self->priv->setup_idle_id);
- }
-
- g_hash_table_destroy (self->priv->status_icons);
- g_hash_table_destroy (self->priv->folks_individual_cache);
- g_hash_table_destroy (self->priv->empathy_group_cache);
+ 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);
}
switch (param_id)
{
- case PROP_INDIVIDUAL_MANAGER:
- g_value_set_object (value, self->priv->manager);
- break;
case PROP_SHOW_AVATARS:
g_value_set_boolean (value, self->priv->show_avatars);
break;
{
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",
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)
-{
- g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_STORE (self), FALSE);
-
- return self->priv->manager;
-}
-
gboolean
empathy_individual_store_get_show_avatars (EmpathyIndividualStore *self)
{
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->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));
/* Also clear the cache */
g_hash_table_remove_all (self->priv->folks_individual_cache);
g_hash_table_remove_all (self->priv->empathy_group_cache);
- contacts = empathy_individual_manager_get_members (self->priv->manager);
-
- individual_store_members_changed_cb (self->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");
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;
+}