]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-chat.c
Add en_GB in gitignore
[empathy.git] / libempathy-gtk / empathy-chat.c
index e305f58ab1258b68f6a9c94daee9481b502fc061..453209ee37b28aad1d7e6f6a1151cc5084c29cf1 100644 (file)
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 
-#include <libmissioncontrol/mission-control.h>
 #include <telepathy-glib/util.h>
 
+#include <libempathy/empathy-account-manager.h>
 #include <libempathy/empathy-log-manager.h>
 #include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-dispatcher.h>
 
 #include "empathy-chat.h"
 #include "empathy-conf.h"
@@ -48,7 +49,7 @@
 #include "empathy-contact-list-store.h"
 #include "empathy-contact-list-view.h"
 #include "empathy-contact-menu.h"
-#include "empathy-chat-simple-view.h"
+#include "empathy-theme-manager.h"
 #include "empathy-smiley-manager.h"
 #include "empathy-ui-utils.h"
 
@@ -64,6 +65,7 @@
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChat)
 typedef struct {
        EmpathyTpChat     *tp_chat;
+       gulong            tp_chat_destroy_handler;
        McAccount         *account;
        gchar             *id;
        gchar             *name;
@@ -71,7 +73,7 @@ typedef struct {
        EmpathyContact    *remote_contact;
 
        EmpathyLogManager *log_manager;
-       MissionControl    *mc;
+       EmpathyAccountManager *account_manager;
        GSList            *sent_messages;
        gint               sent_messages_index;
        GList             *compositors;
@@ -79,7 +81,6 @@ typedef struct {
        guint              composing_stop_timeout_id;
        guint              block_events_timeout_id;
        TpHandleType       handle_type;
-       gpointer           token;
        gint               contacts_width;
        gboolean           has_input_vscroll;
 
@@ -167,35 +168,34 @@ chat_set_property (GObject      *object,
 }
 
 static void
-chat_status_changed_cb (MissionControl           *mc,
-                       TpConnectionStatus        status,
-                       McPresence                presence,
-                       TpConnectionStatusReason  reason,
-                       const gchar              *unique_name,
-                       EmpathyChat              *chat)
+chat_connection_changed_cb (EmpathyAccountManager *manager,
+                           McAccount *account,
+                           TpConnectionStatusReason reason,
+                           TpConnectionStatus current,
+                           TpConnectionStatus previous,
+                           EmpathyChat *chat)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);
-       McAccount       *account;
 
-       account = mc_account_lookup (unique_name);
-
-       if (status == TP_CONNECTION_STATUS_CONNECTED && !priv->tp_chat &&
+       if (current == TP_CONNECTION_STATUS_CONNECTED && !priv->tp_chat &&
            empathy_account_equal (account, priv->account) &&
            priv->handle_type != TP_HANDLE_TYPE_NONE) {
-               TpConnection *connection;
-
+               
                DEBUG ("Account reconnected, request a new Text channel");
-               connection = mission_control_get_tpconnection (mc, account, NULL);
-               tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
-               empathy_connection_request_channel (connection, -1,
-                                                   TP_IFACE_CHANNEL_TYPE_TEXT,
-                                                   priv->handle_type,
-                                                   priv->id, TRUE,
-                                                   NULL, NULL, NULL, NULL);
-               g_object_unref (connection);
-       }
 
-       g_object_unref (account);
+               switch (priv->handle_type) {
+                       case TP_HANDLE_TYPE_CONTACT:
+                               empathy_dispatcher_chat_with_contact_id (account, priv->id,
+                                       NULL, NULL);
+                               break;
+                       case TP_HANDLE_TYPE_ROOM:
+                               empathy_dispatcher_join_muc (account, priv->id, NULL, NULL);
+                               break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+               }
+       }
 }
 
 static void
@@ -352,7 +352,7 @@ chat_send (EmpathyChat  *chat,
 
        priv = GET_PRIV (chat);
 
-       if (G_STR_EMPTY (msg)) {
+       if (EMP_STR_EMPTY (msg)) {
                return;
        }
 
@@ -454,9 +454,7 @@ chat_state_changed_cb (EmpathyTpChat      *tp_chat,
 }
 
 static void
-chat_message_received_cb (EmpathyTpChat  *tp_chat,
-                         EmpathyMessage *message,
-                         EmpathyChat    *chat)
+chat_message_received (EmpathyChat *chat, EmpathyMessage *message)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);
        EmpathyContact  *sender;
@@ -478,14 +476,23 @@ chat_message_received_cb (EmpathyTpChat  *tp_chat,
 
        empathy_chat_view_append_message (chat->view, message);
 
-       /* We received a message so the contact is no more composing */
-       chat_state_changed_cb (tp_chat, sender,
+       /* We received a message so the contact is no longer composing */
+       chat_state_changed_cb (priv->tp_chat, sender,
                               TP_CHANNEL_CHAT_STATE_ACTIVE,
                               chat);
 
        g_signal_emit (chat, signals[NEW_MESSAGE], 0, message);
 }
 
+static void
+chat_message_received_cb (EmpathyTpChat  *tp_chat,
+                         EmpathyMessage *message,
+                         EmpathyChat    *chat)
+{
+       chat_message_received (chat, message);
+       empathy_tp_chat_acknowledge_message (tp_chat, message);
+}
+
 static void
 chat_send_error_cb (EmpathyTpChat          *tp_chat,
                    EmpathyMessage         *message,
@@ -536,7 +543,7 @@ chat_property_changed_cb (EmpathyTpChat *tp_chat,
                priv->subject = g_value_dup_string (value);
                g_object_notify (G_OBJECT (chat), "subject");
 
-               if (G_STR_EMPTY (priv->subject)) {
+               if (EMP_STR_EMPTY (priv->subject)) {
                        gtk_widget_hide (priv->hbox_topic);
                } else {
                        gtk_label_set_text (GTK_LABEL (priv->label_topic), priv->subject);
@@ -545,7 +552,7 @@ chat_property_changed_cb (EmpathyTpChat *tp_chat,
                if (priv->block_events_timeout_id == 0) {
                        gchar *str;
 
-                       if (!G_STR_EMPTY (priv->subject)) {
+                       if (!EMP_STR_EMPTY (priv->subject)) {
                                str = g_strdup_printf (_("Topic set to: %s"), priv->subject);
                        } else {
                                str = g_strdup (_("No topic defined"));
@@ -970,7 +977,7 @@ chat_input_populate_popup_cb (GtkTextView *view,
        gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
        gtk_widget_show (item);
 
-       smiley_manager = empathy_smiley_manager_new ();
+       smiley_manager = empathy_smiley_manager_dup_singleton ();
        smiley_menu = empathy_smiley_menu_new (smiley_manager,
                                               chat_insert_smiley_activate_cb,
                                               chat);
@@ -980,7 +987,7 @@ chat_input_populate_popup_cb (GtkTextView *view,
        /* Add the Send menu item. */
        gtk_text_buffer_get_bounds (buffer, &start, &end);
        str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-       if (!G_STR_EMPTY (str)) {
+       if (!EMP_STR_EMPTY (str)) {
                item = gtk_menu_item_new_with_mnemonic (_("_Send"));
                g_signal_connect (G_OBJECT (item), "activate",
                                  G_CALLBACK (chat_text_send_cb), chat);
@@ -1005,7 +1012,7 @@ chat_input_populate_popup_cb (GtkTextView *view,
                str = gtk_text_buffer_get_text (buffer,
                                                &start, &end, FALSE);
        }
-       if (!G_STR_EMPTY (str)) {
+       if (!EMP_STR_EMPTY (str)) {
                chat_spell = chat_spell_new (chat, str, start, end);
                g_object_set_data_full (G_OBJECT (menu),
                                        "chat_spell", chat_spell,
@@ -1243,6 +1250,23 @@ chat_destroy_cb (EmpathyTpChat *tp_chat,
        chat_set_show_contacts (chat, FALSE);
 }
 
+static void
+show_pending_messages (EmpathyChat *chat) {
+       EmpathyChatPriv *priv = GET_PRIV (chat);
+       const GList *messages, *l;
+
+       if (chat->view == NULL || priv->tp_chat == NULL)
+               return;
+
+       messages = empathy_tp_chat_get_pending_messages (priv->tp_chat);
+
+       for (l = messages; l != NULL ; l = g_list_next (l)) {
+               EmpathyMessage *message = EMPATHY_MESSAGE (l->data);
+               chat_message_received (chat, message);
+       }
+       empathy_tp_chat_acknowledge_messages (priv->tp_chat, messages);
+}
+
 static void
 chat_create_ui (EmpathyChat *chat)
 {
@@ -1269,8 +1293,8 @@ chat_create_ui (EmpathyChat *chat)
        g_free (filename);
        g_object_unref (glade);
 
-       /* Add message GtkTextView. */
-       chat->view = EMPATHY_CHAT_VIEW (empathy_chat_simple_view_new ());
+       /* Add message view. */
+       chat->view = empathy_theme_manager_create_view (empathy_theme_manager_get ());
        g_signal_connect (chat->view, "focus_in_event",
                          G_CALLBACK (chat_text_view_focus_in_event_cb),
                          chat);
@@ -1394,11 +1418,15 @@ chat_finalize (GObject *object)
 
        chat_composing_remove_timeout (chat);
 
-       empathy_disconnect_account_status_changed (priv->token);
-       g_object_unref (priv->mc);
+       g_signal_handlers_disconnect_by_func (priv->account_manager,
+                                             chat_connection_changed_cb, object);
+
+       g_object_unref (priv->account_manager);
        g_object_unref (priv->log_manager);
 
        if (priv->tp_chat) {
+               g_signal_handler_disconnect (priv->tp_chat, priv->tp_chat_destroy_handler);
+               empathy_tp_chat_close (priv->tp_chat);
                g_object_unref (priv->tp_chat);
        }
        if (priv->account) {
@@ -1426,6 +1454,7 @@ chat_constructed (GObject *object)
 
        chat_create_ui (chat);
        chat_add_logs (chat);
+       show_pending_messages (chat);
 }
 
 static void
@@ -1526,15 +1555,16 @@ empathy_chat_init (EmpathyChat *chat)
                EMPATHY_TYPE_CHAT, EmpathyChatPriv);
 
        chat->priv = priv;
-       priv->log_manager = empathy_log_manager_new ();
+       priv->log_manager = empathy_log_manager_dup_singleton ();
        priv->contacts_width = -1;
        priv->sent_messages = NULL;
        priv->sent_messages_index = -1;
-       priv->mc = empathy_mission_control_new ();
+       priv->account_manager = empathy_account_manager_dup_singleton ();
 
-       priv->token = empathy_connect_to_account_status_changed (priv->mc,
-                                                  G_CALLBACK (chat_status_changed_cb),
-                                                  chat, NULL);
+       g_signal_connect (priv->account_manager,
+                         "account-connection-changed",
+                         G_CALLBACK (chat_connection_changed_cb),
+                         chat);
 
        /* Block events for some time to avoid having "has come online" or
         * "joined" messages. */
@@ -1601,7 +1631,8 @@ empathy_chat_set_tp_chat (EmpathyChat   *chat,
        g_signal_connect_swapped (tp_chat, "notify::remote-contact",
                                  G_CALLBACK (chat_remote_contact_changed_cb),
                                  chat);
-       g_signal_connect (tp_chat, "destroy",
+       priv->tp_chat_destroy_handler =
+               g_signal_connect (tp_chat, "destroy",
                          G_CALLBACK (chat_destroy_cb),
                          chat);
 
@@ -1614,12 +1645,14 @@ empathy_chat_set_tp_chat (EmpathyChat   *chat,
                }
        }
 
-       empathy_tp_chat_set_acknowledge (priv->tp_chat, TRUE);
-       empathy_tp_chat_emit_pendings (priv->tp_chat);
-
        g_object_notify (G_OBJECT (chat), "tp-chat");
        g_object_notify (G_OBJECT (chat), "id");
        g_object_notify (G_OBJECT (chat), "account");
+
+       /* This is a noop when tp-chat is set at object construction time and causes
+        * the pending messages to be show when it's set on the object after it has
+        * been created */
+       show_pending_messages (chat);
 }
 
 McAccount *