*/
#include "config.h"
-
#include "empathy-roster-model-manager.h"
+#include <glib/gi18n-lib.h>
+
#include "empathy-roster-model.h"
+#include "empathy-utils.h"
static void roster_model_iface_init (EmpathyRosterModelInterface *iface);
struct _EmpathyRosterModelManagerPriv
{
EmpathyIndividualManager *manager;
+ /* FolksIndividual (borrowed) */
+ GList *top_group_members;
};
+static gboolean
+is_xmpp_local_contact (FolksIndividual *individual)
+{
+ EmpathyContact *contact;
+ TpConnection *connection;
+ const gchar *protocol_name = NULL;
+ gboolean result;
+
+ contact = empathy_contact_dup_from_folks_individual (individual);
+
+ if (contact == NULL)
+ return FALSE;
+
+ connection = empathy_contact_get_connection (contact);
+ protocol_name = tp_connection_get_protocol_name (connection);
+ result = !tp_strdiff (protocol_name, "local-xmpp");
+ g_object_unref (contact);
+
+ return result;
+}
+
+static gboolean
+individual_in_top_group_members (EmpathyRosterModelManager *self,
+ FolksIndividual *individual)
+{
+ return (g_list_find (self->priv->top_group_members, individual) != NULL);
+}
+
+static gboolean
+individual_should_be_in_top_group_members (EmpathyRosterModelManager *self,
+ FolksIndividual *individual)
+{
+ GList *tops;
+
+ tops = empathy_individual_manager_get_top_individuals (self->priv->manager);
+
+ return (folks_favourite_details_get_is_favourite (
+ FOLKS_FAVOURITE_DETAILS (individual)) ||
+ g_list_find (tops, individual) != NULL);
+}
+
+static void
+add_to_top_group_members (EmpathyRosterModelManager *self,
+ FolksIndividual *individual)
+{
+ self->priv->top_group_members = g_list_prepend (self->priv->top_group_members,
+ individual);
+}
+
+static void
+remove_from_top_group_members (EmpathyRosterModelManager *self,
+ FolksIndividual *individual)
+{
+ self->priv->top_group_members = g_list_remove (self->priv->top_group_members,
+ individual);
+}
+
+static void
+populate_model (EmpathyRosterModelManager *self)
+{
+ GList *individuals, *l;
+
+ individuals = empathy_individual_manager_get_members (self->priv->manager);
+
+ for (l = individuals; l != NULL; l = g_list_next (l))
+ {
+ if (individual_should_be_in_top_group_members (self, l->data))
+ add_to_top_group_members (self, l->data);
+
+ empathy_roster_model_fire_individual_added (EMPATHY_ROSTER_MODEL (self),
+ l->data);
+ }
+}
+
static void
members_changed_cb (EmpathyIndividualManager *manager,
const gchar *message,
for (l = added; l != NULL; l = g_list_next (l))
{
+ if (individual_should_be_in_top_group_members (self, l->data) &&
+ !individual_in_top_group_members (self, l->data))
+ add_to_top_group_members (self, l->data);
+
empathy_roster_model_fire_individual_added (EMPATHY_ROSTER_MODEL (self),
l->data);
}
for (l = removed; l != NULL; l = g_list_next (l))
{
+ if (individual_in_top_group_members (self, l->data))
+ remove_from_top_group_members (self, l->data);
+
empathy_roster_model_fire_individual_removed (EMPATHY_ROSTER_MODEL (self),
l->data);
}
individual, group, is_member);
}
+static void
+top_individuals_changed_cb (EmpathyIndividualManager *manager,
+ GParamSpec *spec,
+ EmpathyRosterModelManager *self)
+{
+ GList *tops, *l;
+
+ tops = empathy_individual_manager_get_top_individuals (self->priv->manager);
+
+ for (l = tops; l != NULL; l = g_list_next (l))
+ {
+ if (!individual_in_top_group_members (self, l->data))
+ {
+ add_to_top_group_members (self, l->data);
+
+ empathy_roster_model_fire_groups_changed (
+ EMPATHY_ROSTER_MODEL (self), l->data,
+ EMPATHY_ROSTER_MODEL_GROUP_TOP_GROUP, TRUE);
+ }
+ }
+
+ l = self->priv->top_group_members;
+ while (l != NULL)
+ {
+ FolksIndividual *individual = l->data;
+
+ /* remove_from_top_group_members will modify the list so we already take
+ * the next pointer. */
+ l = g_list_next (l);
+
+ if (!individual_should_be_in_top_group_members (self, individual))
+ {
+ remove_from_top_group_members (self, individual);
+
+ empathy_roster_model_fire_groups_changed (EMPATHY_ROSTER_MODEL (self),
+ individual, EMPATHY_ROSTER_MODEL_GROUP_TOP_GROUP, FALSE);
+ }
+ }
+}
+
+static void
+favourites_changed_cb (EmpathyIndividualManager *manager,
+ FolksIndividual *individual,
+ gboolean favourite,
+ EmpathyRosterModelManager *self)
+{
+ if (favourite && !individual_in_top_group_members (self, individual))
+ {
+ add_to_top_group_members (self, individual);
+
+ empathy_roster_model_fire_groups_changed (
+ EMPATHY_ROSTER_MODEL (self), individual,
+ EMPATHY_ROSTER_MODEL_GROUP_TOP_GROUP, favourite);
+ }
+ else if (!favourite &&
+ !individual_should_be_in_top_group_members (self, individual))
+ {
+ remove_from_top_group_members (self, individual);
+
+ empathy_roster_model_fire_groups_changed (
+ EMPATHY_ROSTER_MODEL (self), individual,
+ EMPATHY_ROSTER_MODEL_GROUP_TOP_GROUP, favourite);
+ }
+}
+
static void
empathy_roster_model_manager_get_property (GObject *object,
guint property_id,
g_assert (EMPATHY_IS_INDIVIDUAL_MANAGER (self->priv->manager));
+ populate_model (self);
+
tp_g_signal_connect_object (self->priv->manager, "members-changed",
G_CALLBACK (members_changed_cb), self, 0);
tp_g_signal_connect_object (self->priv->manager, "groups-changed",
G_CALLBACK (groups_changed_cb), self, 0);
+ tp_g_signal_connect_object (self->priv->manager, "notify::top-individuals",
+ G_CALLBACK (top_individuals_changed_cb), self, 0);
+ tp_g_signal_connect_object (self->priv->manager, "favourites-changed",
+ G_CALLBACK (favourites_changed_cb), self, 0);
}
static void
static void
empathy_roster_model_manager_finalize (GObject *object)
{
- //EmpathyRosterModelManager *self = EMPATHY_ROSTER_MODEL_MANAGER (object);
+ EmpathyRosterModelManager *self = EMPATHY_ROSTER_MODEL_MANAGER (object);
void (*chain_up) (GObject *) =
((GObjectClass *) empathy_roster_model_manager_parent_class)->finalize;
+ g_list_free (self->priv->top_group_members);
+
if (chain_up != NULL)
chain_up (object);
}
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EMPATHY_TYPE_ROSTER_MODEL_MANAGER, EmpathyRosterModelManagerPriv);
+
+ self->priv->top_group_members = NULL;
}
EmpathyRosterModelManager *
}
static GList *
-empathy_roster_model_manager_get_groups_for_individual (EmpathyRosterModel *model,
+empathy_roster_model_manager_dup_groups_for_individual (
+ EmpathyRosterModel *model,
FolksIndividual *individual)
{
GList *groups_list = NULL;
GeeSet *groups_set;
- groups_set = folks_group_details_get_groups (FOLKS_GROUP_DETAILS (individual));
+ if (is_xmpp_local_contact (individual))
+ {
+ groups_list = g_list_prepend (groups_list,
+ g_strdup (EMPATHY_ROSTER_MODEL_GROUP_PEOPLE_NEARBY));
+ return groups_list;
+ }
+
+ if (individual_in_top_group_members (EMPATHY_ROSTER_MODEL_MANAGER (model),
+ individual))
+ groups_list = g_list_prepend (groups_list,
+ g_strdup (EMPATHY_ROSTER_MODEL_GROUP_TOP_GROUP));
+
+ groups_set = folks_group_details_get_groups (
+ FOLKS_GROUP_DETAILS (individual));
if (gee_collection_get_size (GEE_COLLECTION (groups_set)) > 0)
{
GeeIterator *iter = gee_iterable_iterator (GEE_ITERABLE (groups_set));
roster_model_iface_init (EmpathyRosterModelInterface *iface)
{
iface->get_individuals = empathy_roster_model_manager_get_individuals;
- iface->get_groups_for_individual = empathy_roster_model_manager_get_groups_for_individual;
+ iface->dup_groups_for_individual =
+ empathy_roster_model_manager_dup_groups_for_individual;
}