static void remove_individual (EmpathyIndividualManager *self, FolksIndividual *individual) { EmpathyIndividualManagerPriv *priv = GET_PRIV (self); g_signal_handlers_disconnect_by_func (individual, individual_group_changed_cb, self); g_signal_handlers_disconnect_by_func (individual, individual_notify_is_favourite_cb, self); g_hash_table_remove (priv->individuals, folks_individual_get_id (individual)); }
static void add_individual (EmpathyIndividualManager *self, FolksIndividual *individual) { EmpathyIndividualManagerPriv *priv = GET_PRIV (self); g_hash_table_insert (priv->individuals, g_strdup (folks_individual_get_id (individual)), g_object_ref (individual)); g_signal_connect (individual, "group-changed", G_CALLBACK (individual_group_changed_cb), self); g_signal_connect (individual, "notify::is-favourite", G_CALLBACK (individual_notify_is_favourite_cb), self); }
void empathy_individual_manager_unlink_individual (EmpathyIndividualManager *self, FolksIndividual *individual) { EmpathyIndividualManagerPriv *priv; g_return_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self)); g_return_if_fail (FOLKS_IS_INDIVIDUAL (individual)); priv = GET_PRIV (self); DEBUG ("Unlinking individual '%s'", folks_individual_get_id (individual)); folks_individual_aggregator_unlink_individual (priv->aggregator, individual, (GAsyncReadyCallback) unlink_individual_cb, NULL); }
/** * Removes the inner contact from the server (and thus the Individual). Not * meant for de-shelling inner personas from an Individual. */ void empathy_individual_manager_remove (EmpathyIndividualManager *self, FolksIndividual *individual, const gchar *message) { EmpathyIndividualManagerPriv *priv; g_return_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self)); g_return_if_fail (FOLKS_IS_INDIVIDUAL (individual)); priv = GET_PRIV (self); DEBUG ("removing individual %s (%s)", folks_individual_get_id (individual), folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (individual))); folks_individual_aggregator_remove_individual (priv->aggregator, individual, aggregator_remove_individual_cb, self); }
/* Retrieve the EmpathyContact corresponding to the first TpContact contained * within the given Individual. Note that this is a temporary convenience. See * the TODO above. */ EmpathyContact * empathy_contact_dup_from_folks_individual (FolksIndividual *individual) { GeeSet *personas; GeeIterator *iter; EmpathyContact *contact = NULL; g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); personas = folks_individual_get_personas (individual); iter = gee_iterable_iterator (GEE_ITERABLE (personas)); while (gee_iterator_next (iter) && (contact == NULL)) { TpfPersona *persona = gee_iterator_get (iter); if (empathy_folks_persona_is_interesting (FOLKS_PERSONA (persona))) { TpContact *tp_contact; 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)); } } g_clear_object (&persona); } g_clear_object (&iter); if (contact == NULL) { DEBUG ("Can't create an EmpathyContact for Individual %s", folks_individual_get_id (individual)); } return contact; }
/* This is emitted for *all* individuals in the individual aggregator (not * just the ones we keep a reference to), to allow for the case where a new * individual doesn't contain an EmpathyContact, but later has a persona added * which does. */ static void individual_notify_personas_cb (FolksIndividual *individual, GParamSpec *pspec, EmpathyIndividualManager *self) { EmpathyIndividualManagerPriv *priv = GET_PRIV (self); const gchar *id = folks_individual_get_id (individual); gboolean has_contact = empathy_folks_individual_contains_contact (individual); gboolean had_contact = (g_hash_table_lookup (priv->individuals, id) != NULL) ? TRUE : FALSE; if (had_contact == TRUE && has_contact == FALSE) { GList *removed = NULL; /* The Individual has lost its EmpathyContact */ removed = g_list_prepend (removed, individual); g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL, NULL, removed, TP_CHANNEL_GROUP_CHANGE_REASON_NONE /* FIXME */); g_list_free (removed); remove_individual (self, individual); } else if (had_contact == FALSE && has_contact == TRUE) { GList *added = NULL; /* The Individual has gained its first EmpathyContact */ add_individual (self, individual); added = g_list_prepend (added, individual); g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL, added, NULL, TP_CHANNEL_GROUP_CHANGE_REASON_NONE /* FIXME */); g_list_free (added); } }
static void aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator, GeeMultiMap *changes, EmpathyIndividualManager *self) { EmpathyIndividualManagerPriv *priv = GET_PRIV (self); GeeIterator *iter; GeeSet *removed; GeeCollection *added; GList *added_set = NULL, *added_filtered = NULL, *removed_list = NULL; /* We're not interested in the relationships between the added and removed * individuals, so just extract collections of them. Note that the added * collection may contain duplicates, while the removed set won't. */ removed = gee_multi_map_get_keys (changes); added = gee_multi_map_get_values (changes); /* Handle the removals first, as one of the added Individuals might have the * same ID as one of the removed Individuals (due to linking). */ iter = gee_iterable_iterator (GEE_ITERABLE (removed)); while (gee_iterator_next (iter)) { FolksIndividual *ind = gee_iterator_get (iter); if (ind == NULL) continue; g_signal_handlers_disconnect_by_func (ind, individual_notify_personas_cb, self); if (g_hash_table_lookup (priv->individuals, folks_individual_get_id (ind)) != NULL) { remove_individual (self, ind); removed_list = g_list_prepend (removed_list, ind); } g_clear_object (&ind); } g_clear_object (&iter); /* Filter the individuals for ones which contain EmpathyContacts */ iter = gee_iterable_iterator (GEE_ITERABLE (added)); while (gee_iterator_next (iter)) { FolksIndividual *ind = gee_iterator_get (iter); /* Make sure we handle each added individual only once. */ if (ind == NULL || g_list_find (added_set, ind) != NULL) continue; added_set = g_list_prepend (added_set, ind); g_signal_connect (ind, "notify::personas", G_CALLBACK (individual_notify_personas_cb), self); if (empathy_folks_individual_contains_contact (ind) == TRUE) { add_individual (self, ind); added_filtered = g_list_prepend (added_filtered, ind); } g_clear_object (&ind); } g_clear_object (&iter); g_list_free (added_set); g_object_unref (added); g_object_unref (removed); /* Bail if we have no individuals left */ if (added_filtered == NULL && removed == NULL) return; added_filtered = g_list_reverse (added_filtered); g_signal_emit (self, signals[MEMBERS_CHANGED], 0, NULL, added_filtered, removed_list, TP_CHANNEL_GROUP_CHANGE_REASON_NONE, TRUE); g_list_free (added_filtered); g_list_free (removed_list); }