#include "empathy-debug.h"
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIndividualManager)
+
+/* This class doesn't store or ref any of the individuals, since they're already
+ * stored and referenced in the aggregator.
+ *
+ * This class merely forwards along signals from the aggregator and individuals
+ * and wraps aggregator functions for other client code. */
typedef struct
{
FolksIndividualAggregator *aggregator;
EmpathyContactManager *contact_manager;
- TpProxy *logger;
} EmpathyIndividualManagerPriv;
+enum
+{
+ FAVOURITES_CHANGED,
+ GROUPS_CHANGED,
+ MEMBERS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE (EmpathyIndividualManager, empathy_individual_manager,
G_TYPE_OBJECT);
gboolean is_member,
EmpathyIndividualManager *self)
{
- g_signal_emit_by_name (self, "groups-changed", individual, group,
+ g_signal_emit (self, signals[GROUPS_CHANGED], 0, individual, group,
is_member);
}
{
gboolean is_favourite = folks_favourite_get_is_favourite (
FOLKS_FAVOURITE (individual));
- g_signal_emit_by_name (self, "favourites-changed", individual, is_favourite);
+ g_signal_emit (self, signals[FAVOURITES_CHANGED], 0, individual,
+ is_favourite);
}
static void
-aggregator_individuals_added_cb (FolksIndividualAggregator *aggregator,
- GList *individuals,
+aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator,
+ GList *added,
+ GList *removed,
+ const char *message,
+ FolksPersona *actor,
+ guint reason,
EmpathyIndividualManager *self)
{
GList *l;
- for (l = individuals; l; l = l->next)
+ for (l = added; l; l = l->next)
{
g_signal_connect (l->data, "group-changed",
G_CALLBACK (individual_group_changed_cb), self);
G_CALLBACK (individual_notify_is_favourite_cb), self);
}
- /* TODO: don't hard-code the reason or message */
- g_signal_emit_by_name (self, "members-changed",
- "individual(s) added", individuals, NULL,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE, TRUE);
-}
-
-static void
-aggregator_individuals_removed_cb (FolksIndividualAggregator *aggregator,
- GList *individuals,
- EmpathyIndividualManager *self)
-{
- GList *l;
-
- for (l = individuals; l; l = l->next)
+ for (l = removed; l; l = l->next)
{
g_signal_handlers_disconnect_by_func (l->data,
individual_group_changed_cb, self);
individual_notify_is_favourite_cb, self);
}
- /* TODO: don't hard-code the reason or message */
- g_signal_emit_by_name (self, "members-changed",
- "individual(s) removed", NULL, individuals,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE, TRUE);
+ g_signal_emit (self, signals[MEMBERS_CHANGED], 0, message,
+ added, removed,
+ tp_chanel_group_change_reason_from_folks_groups_change_reason (reason),
+ TRUE);
}
static void
-individual_manager_finalize (GObject *object)
+individual_manager_dispose (GObject *object)
{
EmpathyIndividualManagerPriv *priv = GET_PRIV (object);
- if (priv->logger != NULL)
- g_object_unref (priv->logger);
-
- if (priv->contact_manager != NULL)
- g_object_unref (priv->contact_manager);
+ tp_clear_object (&priv->contact_manager);
+ tp_clear_object (&priv->aggregator);
- if (priv->aggregator != NULL)
- g_object_unref (priv->aggregator);
+ G_OBJECT_CLASS (empathy_individual_manager_parent_class)->dispose (object);
}
static GObject *
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = individual_manager_finalize;
+ object_class->dispose = individual_manager_dispose;
object_class->constructor = individual_manager_constructor;
- g_signal_new ("groups-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- _empathy_marshal_VOID__OBJECT_STRING_BOOLEAN,
- G_TYPE_NONE, 3, FOLKS_TYPE_INDIVIDUAL, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
- g_signal_new ("favourites-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- _empathy_marshal_VOID__OBJECT_BOOLEAN,
- G_TYPE_NONE, 2, FOLKS_TYPE_INDIVIDUAL, G_TYPE_BOOLEAN);
-
- g_signal_new ("members-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- _empathy_marshal_VOID__STRING_OBJECT_OBJECT_UINT,
- G_TYPE_NONE,
- 4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT);
+ signals[GROUPS_CHANGED] =
+ g_signal_new ("groups-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _empathy_marshal_VOID__OBJECT_STRING_BOOLEAN,
+ G_TYPE_NONE, 3, FOLKS_TYPE_INDIVIDUAL, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+ signals[FAVOURITES_CHANGED] =
+ g_signal_new ("favourites-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _empathy_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2, FOLKS_TYPE_INDIVIDUAL, G_TYPE_BOOLEAN);
+
+ signals[MEMBERS_CHANGED] =
+ g_signal_new ("members-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _empathy_marshal_VOID__STRING_OBJECT_OBJECT_UINT,
+ G_TYPE_NONE,
+ 4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT);
g_type_class_add_private (object_class,
sizeof (EmpathyIndividualManagerPriv));
{
EmpathyIndividualManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EMPATHY_TYPE_INDIVIDUAL_MANAGER, EmpathyIndividualManagerPriv);
- TpDBusDaemon *bus;
- GError *error = NULL;
self->priv = priv;
priv->contact_manager = empathy_contact_manager_dup_singleton ();
priv->aggregator = folks_individual_aggregator_new ();
- g_signal_connect (priv->aggregator, "individuals-added",
- G_CALLBACK (aggregator_individuals_added_cb), self);
- g_signal_connect (priv->aggregator, "individuals-removed",
- G_CALLBACK (aggregator_individuals_removed_cb), self);
-
- bus = tp_dbus_daemon_dup (&error);
-
- if (error == NULL)
- {
- priv->logger = g_object_new (TP_TYPE_PROXY,
- "bus-name", "org.freedesktop.Telepathy.Logger",
- "object-path",
- "/org/freedesktop/Telepathy/Logger", "dbus-daemon", bus, NULL);
- g_object_unref (bus);
-
- tp_proxy_add_interface_by_id (priv->logger, EMP_IFACE_QUARK_LOGGER);
- }
- else
- {
- DEBUG ("Failed to get telepathy-logger proxy: %s", error->message);
- g_clear_error (&error);
- }
+ g_signal_connect (priv->aggregator, "individuals-changed",
+ G_CALLBACK (aggregator_individuals_changed_cb), self);
+ folks_individual_aggregator_prepare (priv->aggregator, NULL, NULL);
}
EmpathyIndividualManager *
GAsyncResult *result,
gpointer user_data)
{
- EmpathyIndividualManager *self = EMPATHY_INDIVIDUAL_MANAGER (user_data);
- EmpathyIndividualManagerPriv *priv = GET_PRIV (self);
+ FolksIndividualAggregator *aggregator = FOLKS_INDIVIDUAL_AGGREGATOR (source);
+ EmpathyContact *contact = EMPATHY_CONTACT (user_data);
FolksPersona *persona;
GError *error = NULL;
persona = folks_individual_aggregator_add_persona_from_details_finish (
- priv->aggregator, result, &error);
+ aggregator, result, &error);
if (error != NULL)
{
g_warning ("failed to add individual from contact: %s", error->message);
g_clear_error (&error);
}
+
+ /* Set the contact's persona */
+ empathy_contact_set_persona (contact, persona);
+
+ /* We can unref the contact now */
+ g_object_unref (contact);
+ g_object_unref (persona);
}
void
priv = GET_PRIV (self);
- DEBUG (G_STRLOC ": adding individual from contact %s (%s)",
- empathy_contact_get_id (contact), empathy_contact_get_name (contact));
+ /* We need to ref the contact since otherwise its linked TpHandle will be
+ * destroyed. */
+ g_object_ref (contact);
+
+ DEBUG ("adding individual from contact %s (%s)",
+ empathy_contact_get_id (contact), empathy_contact_get_alias (contact));
account = empathy_contact_get_account (contact);
store_id = tp_proxy_get_object_path (TP_PROXY (account));
- details = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (details, "contact",
- (gchar*) empathy_contact_get_id (contact));
+ details = tp_asv_new (
+ "contact", G_TYPE_STRING, empathy_contact_get_id (contact),
+ NULL);
folks_individual_aggregator_add_persona_from_details (
priv->aggregator, NULL, "telepathy", store_id, details,
- aggregator_add_persona_from_details_cb, self);
+ aggregator_add_persona_from_details_cb, contact);
g_hash_table_destroy (details);
}
+static void
+aggregator_remove_individual_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FolksIndividualAggregator *aggregator = FOLKS_INDIVIDUAL_AGGREGATOR (source);
+ GError *error = NULL;
+
+ folks_individual_aggregator_remove_individual_finish (
+ aggregator, result, &error);
+ if (error != NULL)
+ {
+ g_warning ("failed to remove individual: %s", error->message);
+ g_clear_error (&error);
+ }
+}
+
/**
* Removes the inner contact from the server (and thus the Individual). Not
* meant for de-shelling inner personas from an Individual.
priv = GET_PRIV (self);
- DEBUG (G_STRLOC ": removing individual %s (%s)",
+ DEBUG ("removing individual %s (%s)",
folks_individual_get_id (individual),
folks_individual_get_alias (individual));
- folks_individual_aggregator_remove_individual (priv->aggregator, individual);
+ folks_individual_aggregator_remove_individual (priv->aggregator, individual,
+ aggregator_remove_individual_cb, self);
+}
+
+static void
+groups_change_group_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FolksGroups *groups = FOLKS_GROUPS (source);
+ GError *error = NULL;
+
+ folks_groups_change_group_finish (groups, result, &error);
+ if (error != NULL)
+ {
+ g_warning ("failed to change group: %s", error->message);
+ g_clear_error (&error);
+ }
+}
+
+static void
+remove_group_cb (const gchar *id,
+ FolksIndividual *individual,
+ const gchar *group)
+{
+ folks_groups_change_group (FOLKS_GROUPS (individual), group, FALSE,
+ groups_change_group_cb, NULL);
+}
+
+void
+empathy_individual_manager_remove_group (EmpathyIndividualManager *manager,
+ const gchar *group)
+{
+ EmpathyIndividualManagerPriv *priv;
+ GHashTable *individuals;
+
+ g_return_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager));
+ g_return_if_fail (group != NULL);
+
+ priv = GET_PRIV (manager);
+
+ DEBUG ("removing group %s", group);
+
+ /* Remove every individual from the group */
+ individuals = folks_individual_aggregator_get_individuals (priv->aggregator);
+ g_hash_table_foreach (individuals, (GHFunc) remove_group_cb,
+ (gpointer) group);
}
EmpathyIndividualManagerFlags