]> git.0d.be Git - empathy.git/commitdiff
chat-manager: take an EmpathyChat instead of an EmpathyContact
authorJonny Lamb <jonnylamb@gnome.org>
Sat, 6 Mar 2010 10:58:11 +0000 (10:58 +0000)
committerJonny Lamb <jonnylamb@gnome.org>
Sat, 6 Mar 2010 10:58:11 +0000 (10:58 +0000)
This way, we can support both 1-to-1 chats, *and* MUCs.

Signed-off-by: Jonny Lamb <jonnylamb@gnome.org>
src/empathy-chat-manager.c
src/empathy-chat-manager.h
src/empathy-chat-window.c

index 087077c56eef05c410e37e6793cbc1f9ec6f912f..01506f52e939b71551c83ded1bb257a698eadb23 100644 (file)
@@ -47,6 +47,45 @@ struct _EmpathyChatManagerPriv
 
 static EmpathyChatManager *chat_manager_singleton = NULL;
 
+typedef struct
+{
+  TpAccount *account;
+  gchar *id;
+  gboolean room;
+} ChatData;
+
+static ChatData *
+chat_data_new (EmpathyChat *chat)
+{
+  ChatData *data = NULL;
+
+  data = g_slice_new0 (ChatData);
+
+  data->account = g_object_ref (empathy_chat_get_account (chat));
+  data->id = g_strdup (empathy_chat_get_id (chat));
+  data->room = empathy_chat_is_room (chat);
+
+  return data;
+}
+
+static void
+chat_data_free (ChatData *data)
+{
+  if (data->account != NULL)
+    {
+      g_object_unref (data->account);
+      data->account = NULL;
+    }
+
+  if (data->id != NULL)
+    {
+      g_free (data->id);
+      data->id = NULL;
+    }
+
+  g_slice_free (ChatData, data);
+}
+
 static void
 empathy_chat_manager_init (EmpathyChatManager *self)
 {
@@ -63,7 +102,7 @@ empathy_chat_manager_finalize (GObject *object)
 
   if (priv->queue != NULL)
     {
-      g_queue_foreach (priv->queue, (GFunc) g_object_unref, NULL);
+      g_queue_foreach (priv->queue, (GFunc) chat_data_free, NULL);
       g_queue_free (priv->queue);
       priv->queue = NULL;
     }
@@ -125,38 +164,84 @@ empathy_chat_manager_dup_singleton (void)
 
 void
 empathy_chat_manager_closed_chat (EmpathyChatManager *self,
-    EmpathyContact *contact)
+    EmpathyChat *chat)
 {
   EmpathyChatManagerPriv *priv = GET_PRIV (self);
+  ChatData *data;
 
-  DEBUG ("Adding contact to queue: %s", empathy_contact_get_id (contact));
+  data = chat_data_new (chat);
 
-  g_queue_push_tail (priv->queue, g_object_ref (contact));
+  DEBUG ("Adding %s to queue: %s", data->room ? "room" : "contact", data->id);
+
+  g_queue_push_tail (priv->queue, data);
 
   g_signal_emit (self, signals[CHATS_CHANGED], 0,
       g_queue_get_length (priv->queue));
 }
 
+static void
+connection_ready_cb (TpConnection *connection,
+    const GError *error,
+    gpointer user_data)
+{
+  ChatData *data = user_data;
+  EmpathyChatManager *self = chat_manager_singleton;
+  EmpathyChatManagerPriv *priv;
+
+  /* Extremely unlikely to happen, but I don't really want to keep refs to the
+   * chat manager in the ChatData structs as it'll then prevent the manager
+   * from being finalized. */
+  if (G_UNLIKELY (self == NULL))
+    goto out;
+
+  priv = GET_PRIV (self);
+
+  if (error == NULL)
+    {
+      if (data->room)
+        empathy_dispatcher_join_muc (connection, data->id, NULL, NULL);
+      else
+        empathy_dispatcher_chat_with_contact_id (connection, data->id,
+            NULL, NULL);
+
+      g_signal_emit (self, signals[CHATS_CHANGED], 0,
+          g_queue_get_length (priv->queue));
+    }
+  else
+    {
+      DEBUG ("Error readying connection, no chat: %s", error->message);
+    }
+
+out:
+  chat_data_free (data);
+}
+
 void
 empathy_chat_manager_undo_closed_chat (EmpathyChatManager *self)
 {
   EmpathyChatManagerPriv *priv = GET_PRIV (self);
-  EmpathyContact *contact;
+  ChatData *data;
+  TpConnection *connection;
 
-  contact = g_queue_pop_tail (priv->queue);
+  data = g_queue_pop_tail (priv->queue);
 
-  if (contact == NULL)
+  if (data == NULL)
     return;
 
-  DEBUG ("Removing contact from queue and starting a chat with them: %s",
-      empathy_contact_get_id (contact));
-
-  empathy_dispatcher_chat_with_contact (contact, NULL, NULL);
+  DEBUG ("Removing %s from queue and starting a chat with: %s",
+      data->room ? "room" : "contact", data->id);
 
-  g_object_unref (contact);
+  connection = tp_account_get_connection (data->account);
 
-  g_signal_emit (self, signals[CHATS_CHANGED], 0,
-      g_queue_get_length (priv->queue));
+  if (connection != NULL)
+    {
+      tp_connection_call_when_ready (connection, connection_ready_cb, data);
+    }
+  else
+    {
+      DEBUG ("No connection, no chat.");
+      chat_data_free (data);
+    }
 }
 
 guint
index 1dc121c2a48952770192591908cc8fd78ebc0dbc..3a20ab826cdaa782c8344a74bb6e277d55ed7a6b 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <glib-object.h>
 
-#include <libempathy/empathy-contact.h>
+#include <libempathy-gtk/empathy-chat.h>
 
 G_BEGIN_DECLS
 
@@ -61,7 +61,7 @@ GType empathy_chat_manager_get_type (void);
 EmpathyChatManager *empathy_chat_manager_dup_singleton (void);
 
 void empathy_chat_manager_closed_chat (EmpathyChatManager *self,
-    EmpathyContact *contact);
+    EmpathyChat *chat);
 void empathy_chat_manager_undo_closed_chat (EmpathyChatManager *self);
 guint empathy_chat_manager_get_num_chats (EmpathyChatManager *self);
 
index 1df42f14a237eedac7b3065cddddbf83cc8de0b6..9748b61c6d6c3e708ea475c4901ff930f92a8b5f 100644 (file)
@@ -2158,12 +2158,12 @@ empathy_chat_window_remove_chat (EmpathyChatWindow *window,
                g_signal_handlers_disconnect_by_func (remote_contact,
                                                      chat_window_update_chat_tab,
                                                      chat);
-
-               chat_manager = empathy_chat_manager_dup_singleton ();
-               empathy_chat_manager_closed_chat (chat_manager, remote_contact);
-               g_object_unref (chat_manager);
        }
 
+       chat_manager = empathy_chat_manager_dup_singleton ();
+       empathy_chat_manager_closed_chat (chat_manager, chat);
+       g_object_unref (chat_manager);
+
        position = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook),
                                          GTK_WIDGET (chat));
        gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), position);