aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/empathy-contact-list.c14
-rw-r--r--libempathy/empathy-contact-list.h6
-rw-r--r--libempathy/empathy-contact-manager.c26
-rw-r--r--libempathy/empathy-tp-contact-list.c116
-rw-r--r--libempathy/gossip-contact.c8
5 files changed, 130 insertions, 40 deletions
diff --git a/libempathy/empathy-contact-list.c b/libempathy/empathy-contact-list.c
index c55d0abf9..3dd398c06 100644
--- a/libempathy/empathy-contact-list.c
+++ b/libempathy/empathy-contact-list.c
@@ -185,3 +185,17 @@ empathy_contact_list_get_local_pending (EmpathyContactList *list)
return NULL;
}
+void
+empathy_contact_list_process_pending (EmpathyContactList *list,
+ GossipContact *contact,
+ gboolean accept)
+{
+ g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+
+ if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->process_pending) {
+ EMPATHY_CONTACT_LIST_GET_IFACE (list)->process_pending (list,
+ contact,
+ accept);
+ }
+}
+
diff --git a/libempathy/empathy-contact-list.h b/libempathy/empathy-contact-list.h
index 09f54621d..c1f9b41e4 100644
--- a/libempathy/empathy-contact-list.h
+++ b/libempathy/empathy-contact-list.h
@@ -57,6 +57,9 @@ struct _EmpathyContactListIface {
const gchar *message);
GList * (*get_members) (EmpathyContactList *list);
GList * (*get_local_pending) (EmpathyContactList *list);
+ void (*process_pending) (EmpathyContactList *list,
+ GossipContact *contact,
+ gboolean accept);
};
GType empathy_contact_list_get_type (void) G_GNUC_CONST;
@@ -74,6 +77,9 @@ void empathy_contact_list_remove (EmpathyContactLi
const gchar *message);
GList * empathy_contact_list_get_members (EmpathyContactList *list);
GList * empathy_contact_list_get_local_pending (EmpathyContactList *list);
+void empathy_contact_list_process_pending (EmpathyContactList *list,
+ GossipContact *contact,
+ gboolean accept);
G_END_DECLS
diff --git a/libempathy/empathy-contact-manager.c b/libempathy/empathy-contact-manager.c
index 5e5f09a43..7f8cdfed5 100644
--- a/libempathy/empathy-contact-manager.c
+++ b/libempathy/empathy-contact-manager.c
@@ -67,6 +67,9 @@ static void contact_manager_remove (EmpathyContactList
const gchar *message);
static GList * contact_manager_get_members (EmpathyContactList *manager);
static GList * contact_manager_get_local_pending (EmpathyContactList *manager);
+static void contact_manager_process_pending (EmpathyContactList *manager,
+ GossipContact *contact,
+ gboolean accept);
static void contact_manager_setup_foreach (McAccount *account,
EmpathyTpContactList *list,
EmpathyContactManager *manager);
@@ -129,6 +132,7 @@ contact_manager_iface_init (EmpathyContactListIface *iface)
iface->remove = contact_manager_remove;
iface->get_members = contact_manager_get_members;
iface->get_local_pending = contact_manager_get_local_pending;
+ iface->process_pending = contact_manager_process_pending;
}
static void
@@ -311,6 +315,28 @@ contact_manager_get_local_pending (EmpathyContactList *manager)
return pending;
}
+static void
+contact_manager_process_pending (EmpathyContactList *manager,
+ GossipContact *contact,
+ gboolean accept)
+{
+ EmpathyContactManagerPriv *priv;
+ EmpathyContactList *list;
+ McAccount *account;
+
+ g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
+ g_return_if_fail (GOSSIP_IS_CONTACT (contact));
+
+ priv = GET_PRIV (manager);
+
+ account = gossip_contact_get_account (contact);
+ list = g_hash_table_lookup (priv->lists, account);
+
+ if (list) {
+ empathy_contact_list_process_pending (list, contact, accept);
+ }
+}
+
EmpathyTpContactList *
empathy_contact_manager_get_list (EmpathyContactManager *manager,
McAccount *account)
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index b696e990c..d94eb071e 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -57,6 +57,7 @@ struct _EmpathyTpContactListPriv {
GHashTable *groups;
GHashTable *contacts;
+ GList *members;
GList *local_pending;
DBusGProxy *aliasing_iface;
@@ -104,6 +105,9 @@ static void tp_contact_list_remove (EmpathyC
const gchar *message);
static GList * tp_contact_list_get_members (EmpathyContactList *list);
static GList * tp_contact_list_get_local_pending (EmpathyContactList *list);
+static void tp_contact_list_process_pending (EmpathyContactList *list,
+ GossipContact *contact,
+ gboolean accept);
static void tp_contact_list_remove_local_pending (EmpathyTpContactList *list,
GossipContact *contact);
static void tp_contact_list_contact_removed_foreach (guint handle,
@@ -172,9 +176,6 @@ static void tp_contact_list_group_members_removed_cb (GossipTe
guint reason,
const gchar *message,
EmpathyTpContactList *list);
-static void tp_contact_list_get_members_foreach (guint handle,
- GossipContact *contact,
- GList **contacts);
static void tp_contact_list_get_info (EmpathyTpContactList *list,
GArray *handles);
static void tp_contact_list_request_avatar (EmpathyTpContactList *list,
@@ -253,6 +254,7 @@ tp_contact_list_iface_init (EmpathyContactListIface *iface)
iface->remove = tp_contact_list_remove;
iface->get_members = tp_contact_list_get_members;
iface->get_local_pending = tp_contact_list_get_local_pending;
+ iface->process_pending = tp_contact_list_process_pending;
}
static void
@@ -309,6 +311,9 @@ tp_contact_list_finalize (GObject *object)
g_list_foreach (priv->local_pending, (GFunc) empathy_contact_list_info_free, NULL);
g_list_free (priv->local_pending);
+ g_list_foreach (priv->members, (GFunc) g_object_unref, NULL);
+ g_list_free (priv->members);
+
G_OBJECT_CLASS (empathy_tp_contact_list_parent_class)->finalize (object);
}
@@ -471,7 +476,6 @@ tp_contact_list_add (EmpathyContactList *list,
handle = gossip_contact_get_handle (contact);
gossip_telepathy_group_add_member (priv->subscribe, handle, message);
- gossip_telepathy_group_add_member (priv->publish, handle, message);
}
static void
@@ -488,24 +492,19 @@ tp_contact_list_remove (EmpathyContactList *list,
handle = gossip_contact_get_handle (contact);
gossip_telepathy_group_remove_member (priv->subscribe, handle, message);
- gossip_telepathy_group_remove_member (priv->publish, handle, message);
}
static GList *
tp_contact_list_get_members (EmpathyContactList *list)
{
EmpathyTpContactListPriv *priv;
- GList *contacts = NULL;
g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
priv = GET_PRIV (list);
- g_hash_table_foreach (priv->contacts,
- (GHFunc) tp_contact_list_get_members_foreach,
- &contacts);
-
- return contacts;
+ g_list_foreach (priv->local_pending, (GFunc) g_object_ref, NULL);
+ return g_list_copy (priv->members);
}
static GList *
@@ -520,6 +519,27 @@ tp_contact_list_get_local_pending (EmpathyContactList *list)
return g_list_copy (priv->local_pending);
}
+static void
+tp_contact_list_process_pending (EmpathyContactList *list,
+ GossipContact *contact,
+ gboolean accept)
+{
+ EmpathyTpContactListPriv *priv;
+ guint handle;
+
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
+ g_return_if_fail (GOSSIP_IS_CONTACT (contact));
+
+ priv = GET_PRIV (list);
+
+ handle = gossip_contact_get_handle (contact);
+ if (accept) {
+ gossip_telepathy_group_add_member (priv->publish, handle, NULL);
+ } else {
+ gossip_telepathy_group_remove_member (priv->publish, handle, NULL);
+ }
+}
+
McAccount *
empathy_tp_contact_list_get_account (EmpathyTpContactList *list)
{
@@ -964,12 +984,6 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy,
G_CALLBACK (tp_contact_list_removed_cb),
list);
- members = gossip_telepathy_group_get_members (group);
- tp_contact_list_added_cb (group, members, 0,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
- NULL, list);
- g_array_free (members, TRUE);
-
if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
GList *pendings, *l;
@@ -1004,14 +1018,36 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy,
gossip_telepathy_group_info_list_free (pendings);
}
}
- else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
+ if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
+ GArray *remote_pendings = NULL;
+
if (priv->subscribe) {
g_object_unref (priv->subscribe);
}
priv->subscribe = group;
+
+ /* Makes no sense to be in local-pending */
+ g_signal_connect (group, "remote-pending",
+ G_CALLBACK (tp_contact_list_pending_cb),
+ list);
+ gossip_telepathy_group_get_all_members (group,
+ &members,
+ NULL,
+ &remote_pendings);
+
+ tp_contact_list_pending_cb (group, remote_pendings, 0,
+ TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
+ NULL,
+ list);
+ g_array_free (remote_pendings, TRUE);
} else {
- g_assert_not_reached ();
+ members = gossip_telepathy_group_get_members (group);
}
+
+ tp_contact_list_added_cb (group, members, 0,
+ TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
+ NULL, list);
+ g_array_free (members, TRUE);
}
else if (handle_type == TP_HANDLE_TYPE_GROUP) {
const gchar *object_path;
@@ -1105,15 +1141,19 @@ tp_contact_list_added_cb (GossipTelepathyGroup *group,
}
else if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
subscription |= GOSSIP_SUBSCRIPTION_TO;
+ tp_contact_list_remove_local_pending (list, contact);
}
tp_contact_list_block_contact (list, contact);
gossip_contact_set_subscription (contact, subscription);
tp_contact_list_unblock_contact (list, contact);
- if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
- tp_contact_list_remove_local_pending (list, contact);
- g_signal_emit_by_name (list, "contact-added", contact);
+ if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
+ if (!g_list_find (priv->members, contact)) {
+ priv->members = g_list_prepend (priv->members,
+ g_object_ref (contact));
+ g_signal_emit_by_name (list, "contact-added", contact);
+ }
}
g_object_unref (contact);
@@ -1155,15 +1195,21 @@ tp_contact_list_removed_cb (GossipTelepathyGroup *group,
}
else if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
subscription &= !GOSSIP_SUBSCRIPTION_TO;
+ tp_contact_list_remove_local_pending (list, contact);
}
tp_contact_list_block_contact (list, contact);
gossip_contact_set_subscription (contact, subscription);
tp_contact_list_unblock_contact (list, contact);
- if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
- tp_contact_list_remove_local_pending (list, contact);
- g_signal_emit_by_name (list, "contact-removed", contact);
+ if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
+ GList *l;
+
+ if ((l = g_list_find (priv->members, contact))) {
+ g_signal_emit_by_name (list, "contact-removed", contact);
+ priv->members = g_list_delete_link (priv->members, l);
+ g_object_unref (contact);
+ }
}
g_object_unref (contact);
}
@@ -1207,6 +1253,13 @@ tp_contact_list_pending_cb (GossipTelepathyGroup *group,
g_signal_emit_by_name (list, "local-pending",
contact, message);
}
+ else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
+ if (!g_list_find (priv->members, contact)) {
+ priv->members = g_list_prepend (priv->members,
+ g_object_ref (contact));
+ g_signal_emit_by_name (list, "contact-added", contact);
+ }
+ }
g_object_unref (contact);
}
@@ -1520,19 +1573,6 @@ tp_contact_list_group_members_removed_cb (GossipTelepathyGroup *group,
}
static void
-tp_contact_list_get_members_foreach (guint handle,
- GossipContact *contact,
- GList **contacts)
-{
- GossipSubscription subscription;
-
- subscription = gossip_contact_get_subscription (contact);
- if (subscription & GOSSIP_SUBSCRIPTION_TO) {
- *contacts = g_list_append (*contacts, g_object_ref (contact));
- }
-}
-
-static void
tp_contact_list_get_info (EmpathyTpContactList *list,
GArray *handles)
{
diff --git a/libempathy/gossip-contact.c b/libempathy/gossip-contact.c
index 53fe7e182..ba97fa758 100644
--- a/libempathy/gossip-contact.c
+++ b/libempathy/gossip-contact.c
@@ -373,7 +373,7 @@ gossip_contact_get_name (GossipContact *contact)
priv = GET_PRIV (contact);
- if (priv->name == NULL) {
+ if (G_STR_EMPTY (priv->name)) {
return gossip_contact_get_id (contact);
}
@@ -710,7 +710,11 @@ gossip_contact_is_online (GossipContact *contact)
priv = GET_PRIV (contact);
- return (priv->presence != NULL);
+ if (!priv->presence) {
+ return FALSE;
+ }
+
+ return (gossip_presence_get_state (priv->presence) > MC_PRESENCE_OFFLINE);
}
gboolean