]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-tp-chat.c
Merge branch 'part-reasons'
[empathy.git] / libempathy / empathy-tp-chat.c
index 54e08d07139cebb04b921338a88dd5ab936349e5..a3282818f09935fe04928e23a12be9ae4c14b2a0 100644 (file)
@@ -15,7 +15,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Authors: Xavier Claessens <xclaesse@gmail.com>
  */
 
@@ -108,7 +108,7 @@ tp_chat_async_cb (TpChannel *proxy,
                  GObject *weak_object)
 {
        if (error) {
-               DEBUG ("Error %s: %s", (gchar*) user_data, error->message);
+               DEBUG ("Error %s: %s", (gchar *) user_data, error->message);
        }
 }
 
@@ -275,7 +275,7 @@ tp_chat_received_cb (TpChannel   *channel,
        if (priv->listing_pending_messages) {
                return;
        }
+
        DEBUG ("Message received: %s", message_body);
 
        if (message_flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_NON_TEXT_CONTENT &&
@@ -694,7 +694,7 @@ tp_chat_dispose (GObject *object)
                g_object_unref (priv->factory);
        priv->factory = NULL;
 
-       if (priv->user != NULL);
+       if (priv->user != NULL)
                g_object_unref (priv->user);
        priv->user = NULL;
 
@@ -753,6 +753,10 @@ tp_chat_check_if_ready (EmpathyTpChat *chat)
 
        DEBUG ("Ready!");
 
+       tp_cli_channel_type_text_connect_to_received (priv->channel,
+                                                     tp_chat_received_cb,
+                                                     NULL, NULL,
+                                                     G_OBJECT (chat), NULL);
        priv->listing_pending_messages = TRUE;
        tp_cli_channel_type_text_call_list_pending_messages (priv->channel, -1,
                                                             FALSE,
@@ -760,10 +764,6 @@ tp_chat_check_if_ready (EmpathyTpChat *chat)
                                                             NULL, NULL,
                                                             G_OBJECT (chat));
 
-       tp_cli_channel_type_text_connect_to_received (priv->channel,
-                                                     tp_chat_received_cb,
-                                                     NULL, NULL,
-                                                     G_OBJECT (chat), NULL);
        tp_cli_channel_type_text_connect_to_sent (priv->channel,
                                                  tp_chat_sent_cb,
                                                  NULL, NULL,
@@ -867,7 +867,7 @@ tp_chat_got_added_contacts_cb (EmpathyTpContactFactory *factory,
                        priv->members = g_list_prepend (priv->members,
                                g_object_ref (contact));
                        g_signal_emit_by_name (chat, "members-changed",
-                                              contact, NULL, 0, NULL, FALSE);
+                                              contact, NULL, 0, NULL, TRUE);
                }
        }
 
@@ -875,6 +875,34 @@ tp_chat_got_added_contacts_cb (EmpathyTpContactFactory *factory,
        tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
 }
 
+static EmpathyContact *
+chat_lookup_contact (EmpathyTpChat *chat,
+                    TpHandle       handle,
+                    gboolean       remove)
+{
+       EmpathyTpChatPriv *priv = GET_PRIV (chat);
+       GList *l;
+
+       for (l = priv->members; l; l = l->next) {
+               EmpathyContact *c = l->data;
+
+               if (empathy_contact_get_handle (c) != handle) {
+                       continue;
+               }
+
+               if (remove) {
+                       /* Caller takes the reference. */
+                       priv->members = g_list_delete_link (priv->members, l);
+               } else {
+                       g_object_ref (c);
+               }
+
+               return c;
+       }
+
+       return NULL;
+}
+
 static void
 tp_chat_group_members_changed_cb (TpChannel     *self,
                                  gchar         *message,
@@ -888,35 +916,46 @@ tp_chat_group_members_changed_cb (TpChannel     *self,
 {
        EmpathyTpChatPriv *priv = GET_PRIV (chat);
        EmpathyContact *contact;
-       TpHandle handle;
+       EmpathyContact *actor_contact = NULL;
        guint i;
-       GList *l;
+
+       if (actor != 0) {
+               actor_contact = chat_lookup_contact (chat, actor, FALSE);
+               if (actor_contact == NULL) {
+                       /* FIXME: handle this a tad more gracefully: perhaps
+                        * the actor was a server op. We could use the
+                        * contact-ids detail of MembersChangedDetailed.
+                        */
+                       DEBUG ("actor %u not a channel member", actor);
+               }
+       }
 
        /* Remove contacts that are not members anymore */
        for (i = 0; i < removed->len; i++) {
-               for (l = priv->members; l; l = l->next) {
-                       contact = l->data;
-                       handle = empathy_contact_get_handle (contact);
-                       if (handle == g_array_index (removed, TpHandle, i)) {
-                               priv->members = g_list_delete_link (priv->members, l);
-                               g_signal_emit_by_name (chat, "members-changed",
-                                                      contact, NULL, reason,
-                                                      message, FALSE);
-                               g_object_unref (contact);
-                               break;
-                       }
+               contact = chat_lookup_contact (chat,
+                       g_array_index (removed, TpHandle, i), TRUE);
+
+               if (contact != NULL) {
+                       g_signal_emit_by_name (chat, "members-changed", contact,
+                                              actor_contact, reason, message,
+                                              FALSE);
+                       g_object_unref (contact);
                }
        }
 
        /* Request added contacts */
        if (added->len > 0) {
                empathy_tp_contact_factory_get_from_handles (priv->factory,
-                       added->len, (TpHandle*) added->data,
+                       added->len, (TpHandle *) added->data,
                        tp_chat_got_added_contacts_cb, NULL, NULL,
                        G_OBJECT (chat));
        }
 
        tp_chat_update_remote_contact (chat);
+
+       if (actor_contact != NULL) {
+               g_object_unref (actor_contact);
+       }
 }
 
 static void
@@ -993,9 +1032,9 @@ tp_chat_constructor (GType                  type,
 
                /* Get initial member contacts */
                members = tp_channel_group_get_members (priv->channel);
-               handles = tp_intset_to_array (members);         
+               handles = tp_intset_to_array (members);
                empathy_tp_contact_factory_get_from_handles (priv->factory,
-                       handles->len, (TpHandle*) handles->data,
+                       handles->len, (TpHandle *) handles->data,
                        tp_chat_got_added_contacts_cb, NULL, NULL, chat);
 
                g_signal_connect (priv->channel, "group-members-changed",
@@ -1360,7 +1399,7 @@ empathy_tp_chat_acknowledge_messages (EmpathyTpChat *chat,
        g_return_if_fail (EMPATHY_IS_TP_CHAT (chat));
        g_return_if_fail (priv->ready);
 
-       length = g_list_length ((GList *)messages);
+       length = g_list_length ((GList *) messages);
 
        if (length == 0)
                return;