aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-chat.c29
-rw-r--r--libempathy-gtk/empathy-contact-list-store.c56
-rw-r--r--libempathy/empathy-contact-list.c9
-rw-r--r--libempathy/empathy-tp-chat.c95
4 files changed, 189 insertions, 0 deletions
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 07bd35711..cc946b1e1 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -1791,6 +1791,8 @@ chat_members_changed_cb (EmpathyTpChat *tp_chat,
gboolean is_member,
EmpathyChat *chat)
{
+ g_return_if_fail (TP_CHANNEL_GROUP_CHANGE_REASON_RENAMED != reason);
+
EmpathyChatPriv *priv = GET_PRIV (chat);
const gchar *name = empathy_contact_get_name (contact);
gchar *str;
@@ -1809,6 +1811,30 @@ chat_members_changed_cb (EmpathyTpChat *tp_chat,
g_free (str);
}
+static void
+chat_member_renamed_cb (EmpathyTpChat *tp_chat,
+ EmpathyContact *old_contact,
+ EmpathyContact *new_contact,
+ guint reason,
+ gchar *message,
+ EmpathyChat *chat)
+{
+ g_return_if_fail (TP_CHANNEL_GROUP_CHANGE_REASON_RENAMED == reason);
+
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+
+ if (priv->block_events_timeout_id == 0) {
+ gchar *str;
+
+ str = g_strdup_printf (_("%s is now known as %s"),
+ empathy_contact_get_name (old_contact),
+ empathy_contact_get_name (new_contact));
+ empathy_chat_view_append_event (chat->view, str);
+ g_free (str);
+ }
+
+}
+
static gboolean
chat_reset_size_request (gpointer widget)
{
@@ -2536,6 +2562,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat,
g_signal_connect (tp_chat, "members-changed",
G_CALLBACK (chat_members_changed_cb),
chat);
+ g_signal_connect (tp_chat, "member-renamed",
+ G_CALLBACK (chat_member_renamed_cb),
+ chat);
g_signal_connect_swapped (tp_chat, "notify::remote-contact",
G_CALLBACK (chat_remote_contact_changed_cb),
chat);
diff --git a/libempathy-gtk/empathy-contact-list-store.c b/libempathy-gtk/empathy-contact-list-store.c
index 6572b4c90..417250fcd 100644
--- a/libempathy-gtk/empathy-contact-list-store.c
+++ b/libempathy-gtk/empathy-contact-list-store.c
@@ -103,6 +103,12 @@ static void contact_list_store_members_changed_cb (EmpathyCon
gchar *message,
gboolean is_member,
EmpathyContactListStore *store);
+static void contact_list_store_member_renamed_cb (EmpathyContactList *list_iface,
+ EmpathyContact *old_contact,
+ EmpathyContact *new_contact,
+ guint reason,
+ gchar *message,
+ EmpathyContactListStore *store);
static void contact_list_store_groups_changed_cb (EmpathyContactList *list_iface,
EmpathyContact *contact,
gchar *group,
@@ -175,6 +181,10 @@ contact_list_store_iface_setup (gpointer user_data)
/* Signal connection. */
g_signal_connect (priv->list,
+ "member-renamed",
+ G_CALLBACK (contact_list_store_member_renamed_cb),
+ store);
+ g_signal_connect (priv->list,
"members-changed",
G_CALLBACK (contact_list_store_members_changed_cb),
store);
@@ -309,6 +319,9 @@ contact_list_store_dispose (GObject *object)
g_list_free (contacts);
g_signal_handlers_disconnect_by_func (priv->list,
+ G_CALLBACK (contact_list_store_member_renamed_cb),
+ object);
+ g_signal_handlers_disconnect_by_func (priv->list,
G_CALLBACK (contact_list_store_members_changed_cb),
object);
g_signal_handlers_disconnect_by_func (priv->list,
@@ -835,6 +848,49 @@ contact_list_store_members_changed_cb (EmpathyContactList *list_iface,
}
static void
+contact_list_store_member_renamed_cb (EmpathyContactList *list_iface,
+ EmpathyContact *old_contact,
+ EmpathyContact *new_contact,
+ guint reason,
+ gchar *message,
+ EmpathyContactListStore *store)
+{
+ EmpathyContactListStorePriv *priv;
+
+ priv = GET_PRIV (store);
+
+ DEBUG ("Contact %s (%d) renamed to %s (%d)",
+ empathy_contact_get_id (old_contact),
+ empathy_contact_get_handle (old_contact),
+ empathy_contact_get_id (new_contact),
+ empathy_contact_get_handle (new_contact));
+
+ /* connect to signals of new contact */
+ g_signal_connect (new_contact, "notify::presence",
+ G_CALLBACK (contact_list_store_contact_updated_cb),
+ store);
+ g_signal_connect (new_contact, "notify::presence-message",
+ G_CALLBACK (contact_list_store_contact_updated_cb),
+ store);
+ g_signal_connect (new_contact, "notify::name",
+ G_CALLBACK (contact_list_store_contact_updated_cb),
+ store);
+ g_signal_connect (new_contact, "notify::avatar",
+ G_CALLBACK (contact_list_store_contact_updated_cb),
+ store);
+ g_signal_connect (new_contact, "notify::capabilities",
+ G_CALLBACK (contact_list_store_contact_updated_cb),
+ store);
+ contact_list_store_add_contact (store, new_contact);
+
+ /* disconnect from old contact */
+ g_signal_handlers_disconnect_by_func (old_contact,
+ G_CALLBACK (contact_list_store_contact_updated_cb),
+ store);
+ contact_list_store_remove_contact (store, old_contact);
+}
+
+static void
contact_list_store_groups_changed_cb (EmpathyContactList *list_iface,
EmpathyContact *contact,
gchar *group,
diff --git a/libempathy/empathy-contact-list.c b/libempathy/empathy-contact-list.c
index d9493af1e..d4859210a 100644
--- a/libempathy/empathy-contact-list.c
+++ b/libempathy/empathy-contact-list.c
@@ -54,6 +54,15 @@ contact_list_base_init (gpointer klass)
static gboolean initialized = FALSE;
if (!initialized) {
+ g_signal_new ("member-renamed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
+ G_TYPE_NONE,
+ 4, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT, G_TYPE_UINT, G_TYPE_STRING);
+
g_signal_new ("members-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index aa8c1a1c5..aebeb6670 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -946,6 +946,83 @@ chat_lookup_contact (EmpathyTpChat *chat,
return NULL;
}
+typedef struct
+{
+ TpHandle old_handle;
+ guint reason;
+ const gchar *message;
+} ContactRenameData;
+
+static ContactRenameData*
+contact_rename_data_new (TpHandle handle,
+ guint reason,
+ const gchar* message)
+{
+ ContactRenameData *data = g_new (ContactRenameData, 1);
+ data->old_handle = handle;
+ data->reason = reason;
+ data->message = message;
+
+ return data;
+}
+
+static void
+contact_rename_data_free (ContactRenameData* data)
+{
+ g_free (data);
+}
+
+static void
+tp_chat_got_renamed_contacts_cb (EmpathyTpContactFactory *factory,
+ guint n_contacts,
+ EmpathyContact * const * contacts,
+ guint n_failed,
+ const TpHandle *failed,
+ const GError *error,
+ gpointer user_data,
+ GObject *chat)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+ const TpIntSet *members;
+ TpHandle handle;
+ EmpathyContact *old = NULL, *new = NULL;
+
+ if (error) {
+ DEBUG ("Error: %s", error->message);
+ return;
+ }
+
+ /* renamed members can only be delivered one at a time */
+ g_warn_if_fail (n_contacts == 1);
+
+ ContactRenameData *rename_data = (ContactRenameData*) user_data;
+
+ new = contacts[0];
+
+ members = tp_channel_group_get_members (priv->channel);
+ handle = empathy_contact_get_handle (new);
+
+ old = chat_lookup_contact (EMPATHY_TP_CHAT (chat),
+ rename_data->old_handle, TRUE);
+
+ /* Make sure the contact is still member */
+ if (tp_intset_is_member (members, handle)) {
+ priv->members = g_list_prepend (priv->members,
+ g_object_ref (new));
+
+ if (old != NULL) {
+ g_signal_emit_by_name (chat, "member-renamed",
+ old, new, rename_data->reason,
+ rename_data->message);
+ g_object_unref (old);
+ }
+ }
+
+ tp_chat_update_remote_contact (EMPATHY_TP_CHAT (chat));
+ tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
+}
+
+
static void
tp_chat_group_members_changed_cb (TpChannel *self,
gchar *message,
@@ -961,6 +1038,24 @@ tp_chat_group_members_changed_cb (TpChannel *self,
EmpathyContact *contact;
EmpathyContact *actor_contact = NULL;
guint i;
+ ContactRenameData *rename_data;
+
+ /* Contact renamed */
+ if (reason == TP_CHANNEL_GROUP_CHANGE_REASON_RENAMED) {
+ /* there can only be a single 'added' and a single 'removed' handle */
+ g_warn_if_fail(removed->len == 1);
+ g_warn_if_fail(added->len == 1);
+
+ TpHandle old_handle = g_array_index (removed, guint, 0);
+
+ rename_data = contact_rename_data_new (old_handle, reason, message);
+ empathy_tp_contact_factory_get_from_handles (priv->factory,
+ added->len, (TpHandle *) added->data,
+ tp_chat_got_renamed_contacts_cb,
+ rename_data, (GDestroyNotify) contact_rename_data_free,
+ G_OBJECT (chat));
+ return;
+ }
if (actor != 0) {
actor_contact = chat_lookup_contact (chat, actor, FALSE);