]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-chat.c
Merge commit 'jtellier/confirm-lose-accounts-settings'
[empathy.git] / libempathy-gtk / empathy-chat.c
index ab31c608ede48f1b915f324d5f2771a751a937d6..c08b49c3fbe7a21b22be279d24dff67eb490e34f 100644 (file)
@@ -64,7 +64,7 @@
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChat)
 typedef struct {
        EmpathyTpChat     *tp_chat;
-       McAccount         *account;
+       EmpathyAccount    *account;
        gchar             *id;
        gchar             *name;
        gchar             *subject;
@@ -201,13 +201,14 @@ chat_new_connection_cb (EmpathyAccountManager *manager,
                        EmpathyChat *chat)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);
-       McAccount *account;
+       EmpathyAccount *account;
 
-       account = empathy_account_manager_get_account (manager, connection);
-       if (!priv->tp_chat && empathy_account_equal (account, priv->account) &&
+       account = empathy_account_manager_get_account_for_connection (manager,
+               connection);
+       if (!priv->tp_chat && account == priv->account &&
            priv->handle_type != TP_HANDLE_TYPE_NONE &&
            !EMP_STR_EMPTY (priv->id)) {
-               
+
                DEBUG ("Account reconnected, request a new Text channel");
 
                switch (priv->handle_type) {
@@ -302,7 +303,7 @@ chat_sent_message_add (EmpathyChat  *chat,
 
        /* Save the sent message in our repeat buffer */
        list = priv->sent_messages;
-       
+
        /* Remove any other occurances of this msg */
        while ((item = g_slist_find_custom (list, str, (GCompareFunc) strcmp)) != NULL) {
                list = g_slist_remove_link (list, item);
@@ -333,7 +334,7 @@ chat_sent_message_get_next (EmpathyChat *chat)
 {
        EmpathyChatPriv *priv;
        gint            max;
-       
+
        priv = GET_PRIV (chat);
 
        if (!priv->sent_messages) {
@@ -346,7 +347,7 @@ chat_sent_message_get_next (EmpathyChat *chat)
        if (priv->sent_messages_index < max) {
                priv->sent_messages_index++;
        }
-       
+
        DEBUG ("Returning next message index:%d", priv->sent_messages_index);
 
        return g_slist_nth_data (priv->sent_messages, priv->sent_messages_index);
@@ -360,7 +361,7 @@ chat_sent_message_get_last (EmpathyChat *chat)
        g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL);
 
        priv = GET_PRIV (chat);
-       
+
        if (!priv->sent_messages) {
                DEBUG ("No sent messages, last message is NULL");
                return NULL;
@@ -390,25 +391,20 @@ chat_send (EmpathyChat  *chat,
 
        chat_sent_message_add (chat, msg);
 
-       if (g_str_has_prefix (msg, "/clear")) {
+       if (strcmp (msg, "/clear") == 0) {
                empathy_chat_view_clear (chat->view);
                return;
        }
 
-       /* Blacklist messages begining by '/', except for "/me" and "/say"
-        * because they are handled in EmpathyMessage */
-       if (msg[0] == '/' &&
-           !g_str_has_prefix (msg, "/me") &&
-           !g_str_has_prefix (msg, "/say")) {
+       message = empathy_message_new_from_entry (msg);
+
+       if (message == NULL) {
                empathy_chat_view_append_event (chat->view,
                        _("Unsupported command"));
-               return;
+       } else {
+               empathy_tp_chat_send (priv->tp_chat, message);
+               g_object_unref (message);
        }
-
-       /* We can send the message */
-       message = empathy_message_new (msg);
-       empathy_tp_chat_send (priv->tp_chat, message);
-       g_object_unref (message);
 }
 
 static void
@@ -527,7 +523,7 @@ chat_message_received_cb (EmpathyTpChat  *tp_chat,
 
 static void
 chat_send_error_cb (EmpathyTpChat          *tp_chat,
-                   EmpathyMessage         *message,
+                   const gchar            *message_body,
                    TpChannelTextSendError  error_code,
                    EmpathyChat            *chat)
 {
@@ -556,7 +552,7 @@ chat_send_error_cb (EmpathyTpChat          *tp_chat,
        }
 
        str = g_strdup_printf (_("Error sending message '%s': %s"),
-                              empathy_message_get_body (message),
+                              message_body,
                               error);
        empathy_chat_view_append_event (chat->view, str);
        g_free (str);
@@ -748,13 +744,14 @@ chat_input_key_press_event_cb (GtkWidget   *widget,
        if (!(event->state & GDK_CONTROL_MASK) &&
            event->keyval == GDK_Page_Up) {
                adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (text_view_sw));
-               gtk_adjustment_set_value (adj, adj->value - adj->page_size);
+               gtk_adjustment_set_value (adj, gtk_adjustment_get_value (adj) - gtk_adjustment_get_page_size (adj));
                return TRUE;
        }
        if ((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK &&
            event->keyval == GDK_Page_Down) {
                adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (text_view_sw));
-               val = MIN (adj->value + adj->page_size, adj->upper - adj->page_size);
+               val = MIN (gtk_adjustment_get_value (adj) + gtk_adjustment_get_page_size (adj),
+                          gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
                gtk_adjustment_set_value (adj, val);
                return TRUE;
        }
@@ -1161,6 +1158,62 @@ chat_contacts_completion_func (const gchar *s1,
        return ret;
 }
 
+static gchar *
+build_part_message (guint           reason,
+                   const gchar    *name,
+                   EmpathyContact *actor,
+                   const gchar    *message)
+{
+       GString *s = g_string_new ("");
+       const gchar *actor_name = NULL;
+
+       if (actor != NULL) {
+               actor_name = empathy_contact_get_name (actor);
+       }
+
+       /* Having an actor only really makes sense for a few actions... */
+       switch (reason) {
+       case TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE:
+               g_string_append_printf (s, _("%s has disconnected"), name);
+               break;
+       case TP_CHANNEL_GROUP_CHANGE_REASON_KICKED:
+               if (actor_name != NULL) {
+                       /* translators: reverse the order of these arguments
+                        * if the kicked should come before the kicker in your locale.
+                        */
+                       g_string_append_printf (s, _("%1$s was kicked by %2$s"),
+                               name, actor_name);
+               } else {
+                       g_string_append_printf (s, _("%s was kicked"), name);
+               }
+               break;
+       case TP_CHANNEL_GROUP_CHANGE_REASON_BANNED:
+               if (actor_name != NULL) {
+                       /* translators: reverse the order of these arguments
+                        * if the banned should come before the banner in your locale.
+                        */
+                       g_string_append_printf (s, _("%1$s was banned by %2$s"),
+                               name, actor_name);
+               } else {
+                       g_string_append_printf (s, _("%s was banned"), name);
+               }
+               break;
+       default:
+               g_string_append_printf (s, _("%s has left the room"), name);
+       }
+
+       if (!EMP_STR_EMPTY (message)) {
+               /* Note to translators: this string is appended to
+                * notifications like "foo has left the room", with the message
+                * given by the user living the room. If this poses a problem,
+                * please let us know. :-)
+                */
+               g_string_append_printf (s, _(" (%s)"), message);
+       }
+
+       return g_string_free (s, FALSE);
+}
+
 static void
 chat_members_changed_cb (EmpathyTpChat  *tp_chat,
                         EmpathyContact *contact,
@@ -1171,20 +1224,21 @@ chat_members_changed_cb (EmpathyTpChat  *tp_chat,
                         EmpathyChat    *chat)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);
+       const gchar *name = empathy_contact_get_name (contact);
+       gchar *str;
 
-       if (priv->block_events_timeout_id == 0) {
-               gchar *str;
+       if (priv->block_events_timeout_id != 0)
+               return;
 
-               if (is_member) {
-                       str = g_strdup_printf (_("%s has joined the room"),
-                                              empathy_contact_get_name (contact));
-               } else {
-                       str = g_strdup_printf (_("%s has left the room"),
-                                              empathy_contact_get_name (contact));
-               }
-               empathy_chat_view_append_event (chat->view, str);
-               g_free (str);
+       if (is_member) {
+               str = g_strdup_printf (_("%s has joined the room"),
+                                      name);
+       } else {
+               str = build_part_message (reason, name, actor, message);
        }
+
+       empathy_chat_view_append_event (chat->view, str);
+       g_free (str);
 }
 
 static gboolean
@@ -1195,19 +1249,19 @@ chat_reset_size_request (gpointer widget)
        return FALSE;
 }
 
-void
-empathy_chat_set_show_contacts (EmpathyChat *chat,
-                               gboolean     show)
+static void
+chat_update_contacts_visibility (EmpathyChat *chat)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);
-       
-       priv->show_contacts = show;
+       gboolean show;
+
+       show = priv->remote_contact == NULL && priv->show_contacts;
 
        if (!priv->scrolled_window_contacts) {
                return;
-       }               
+       }
 
-       if (show) {
+       if (show && priv->contact_list_view == NULL) {
                EmpathyContactListStore *store;
                gint                     min_width;
 
@@ -1238,21 +1292,33 @@ empathy_chat_set_show_contacts (EmpathyChat *chat,
                gtk_widget_show (priv->contact_list_view);
                gtk_widget_show (priv->scrolled_window_contacts);
                g_object_unref (store);
-       } else {
+       } else if (!show) {
                priv->contacts_width = gtk_paned_get_position (GTK_PANED (priv->hpaned));
                gtk_widget_hide (priv->scrolled_window_contacts);
-               if (priv->contact_list_view) {
+               if (priv->contact_list_view != NULL) {
                        gtk_widget_destroy (priv->contact_list_view);
                        priv->contact_list_view = NULL;
                }
        }
 }
 
+void
+empathy_chat_set_show_contacts (EmpathyChat *chat,
+                               gboolean     show)
+{
+       EmpathyChatPriv *priv = GET_PRIV (chat);
+
+       priv->show_contacts = show;
+
+       chat_update_contacts_visibility (chat);
+
+       g_object_notify (G_OBJECT (chat), "show-contacts");
+}
+
 static void
 chat_remote_contact_changed_cb (EmpathyChat *chat)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);
-       gboolean         active;
 
        if (priv->remote_contact != NULL) {
                g_object_unref (priv->remote_contact);
@@ -1275,8 +1341,7 @@ chat_remote_contact_changed_cb (EmpathyChat *chat)
                priv->id = g_strdup (empathy_tp_chat_get_id (priv->tp_chat));
        }
 
-       active = (priv->remote_contact == NULL && priv->show_contacts == TRUE);
-       empathy_chat_set_show_contacts (chat, active);
+       chat_update_contacts_visibility (chat);
 
        g_object_notify (G_OBJECT (chat), "remote-contact");
        g_object_notify (G_OBJECT (chat), "id");
@@ -1329,7 +1394,6 @@ chat_create_ui (EmpathyChat *chat)
        GList           *list = NULL;
        gchar           *filename;
        GtkTextBuffer   *buffer;
-       gboolean         active;
 
        filename = empathy_file_lookup ("empathy-chat.ui",
                                        "libempathy-gtk");
@@ -1387,8 +1451,7 @@ chat_create_ui (EmpathyChat *chat)
        gtk_widget_show (chat->input_text_view);
 
        /* Create contact list */
-       active = (priv->remote_contact == NULL && priv->show_contacts == TRUE);
-       empathy_chat_set_show_contacts (chat, active);
+       chat_update_contacts_visibility (chat);
 
        /* Initialy hide the topic, will be shown if not empty */
        gtk_widget_hide (priv->hbox_topic);
@@ -1418,15 +1481,18 @@ chat_size_request (GtkWidget      *widget,
                   GtkRequisition *requisition)
 {
   GtkBin *bin = GTK_BIN (widget);
+  GtkWidget *child;
+
+  requisition->width = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
+  requisition->height = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
 
-  requisition->width = GTK_CONTAINER (widget)->border_width * 2;
-  requisition->height = GTK_CONTAINER (widget)->border_width * 2;
+  child = gtk_bin_get_child (bin);
 
-  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+  if (child && GTK_WIDGET_VISIBLE (child))
     {
       GtkRequisition child_requisition;
 
-      gtk_widget_size_request (bin->child, &child_requisition);
+      gtk_widget_size_request (child, &child_requisition);
 
       requisition->width += child_requisition.width;
       requisition->height += child_requisition.height;
@@ -1439,17 +1505,20 @@ chat_size_allocate (GtkWidget     *widget,
 {
   GtkBin *bin = GTK_BIN (widget);
   GtkAllocation child_allocation;
+  GtkWidget *child;
 
   widget->allocation = *allocation;
 
-  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+  child = gtk_bin_get_child (bin);
+
+  if (child && GTK_WIDGET_VISIBLE (child))
     {
-      child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
-      child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width;
-      child_allocation.width = MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0);
-      child_allocation.height = MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0);
+      child_allocation.x = allocation->x + gtk_container_get_border_width (GTK_CONTAINER (widget));
+      child_allocation.y = allocation->y + gtk_container_get_border_width (GTK_CONTAINER (widget));
+      child_allocation.width = MAX (allocation->width - gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2, 0);
+      child_allocation.height = MAX (allocation->height - gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2, 0);
 
-      gtk_widget_size_allocate (bin->child, &child_allocation);
+      gtk_widget_size_allocate (child, &child_allocation);
     }
 }
 
@@ -1546,49 +1615,56 @@ empathy_chat_class_init (EmpathyChatClass *klass)
                                                              "The tp chat object",
                                                              EMPATHY_TYPE_TP_CHAT,
                                                              G_PARAM_CONSTRUCT |
-                                                             G_PARAM_READWRITE));
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (object_class,
                                         PROP_ACCOUNT,
                                         g_param_spec_object ("account",
                                                              "Account of the chat",
                                                              "The account of the chat",
-                                                             MC_TYPE_ACCOUNT,
-                                                             G_PARAM_READABLE));
+                                                             EMPATHY_TYPE_ACCOUNT,
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (object_class,
                                         PROP_ID,
                                         g_param_spec_string ("id",
                                                              "Chat's id",
                                                              "The id of the chat",
                                                              NULL,
-                                                             G_PARAM_READABLE));
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (object_class,
                                         PROP_NAME,
                                         g_param_spec_string ("name",
                                                              "Chat's name",
                                                              "The name of the chat",
                                                              NULL,
-                                                             G_PARAM_READABLE));
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (object_class,
                                         PROP_SUBJECT,
                                         g_param_spec_string ("subject",
                                                              "Chat's subject",
                                                              "The subject or topic of the chat",
                                                              NULL,
-                                                             G_PARAM_READABLE));
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (object_class,
                                         PROP_REMOTE_CONTACT,
                                         g_param_spec_object ("remote-contact",
                                                              "The remote contact",
                                                              "The remote contact is any",
                                                              EMPATHY_TYPE_CONTACT,
-                                                             G_PARAM_READABLE));
+                                                             G_PARAM_READABLE |
+                                                             G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (object_class,
                                         PROP_SHOW_CONTACTS,
                                         g_param_spec_boolean ("show-contacts",
                                                               "Contacts' visibility",
                                                               "The visibility of the contacts' list",
                                                               TRUE,
-                                                              G_PARAM_READWRITE));
+                                                              G_PARAM_READWRITE |
+                                                              G_PARAM_STATIC_STRINGS));
 
        signals[COMPOSING] =
                g_signal_new ("composing",
@@ -1626,7 +1702,6 @@ chat_block_events_timeout_cb (gpointer data)
 static void
 empathy_chat_init (EmpathyChat *chat)
 {
-       gboolean         active;
        EmpathyChatPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (chat,
                EMPATHY_TYPE_CHAT, EmpathyChatPriv);
 
@@ -1644,10 +1719,8 @@ empathy_chat_init (EmpathyChat *chat)
 
        empathy_conf_get_bool (empathy_conf_get (),
                               EMPATHY_PREFS_CHAT_SHOW_CONTACTS_IN_ROOMS,
-                              &active);
+                              &priv->show_contacts);
 
-       empathy_chat_set_show_contacts (chat, active);
-                         
        /* Block events for some time to avoid having "has come online" or
         * "joined" messages. */
        priv->block_events_timeout_id =
@@ -1695,7 +1768,8 @@ empathy_chat_set_tp_chat (EmpathyChat   *chat,
 
        priv->tp_chat = g_object_ref (tp_chat);
        connection = empathy_tp_chat_get_connection (priv->tp_chat);
-       priv->account = empathy_account_manager_get_account (priv->account_manager,
+       priv->account = empathy_account_manager_get_account_for_connection (
+                                                            priv->account_manager,
                                                             connection);
        g_object_ref (priv->account);
 
@@ -1740,7 +1814,7 @@ empathy_chat_set_tp_chat (EmpathyChat   *chat,
        show_pending_messages (chat);
 }
 
-McAccount *
+EmpathyAccount *
 empathy_chat_get_account (EmpathyChat *chat)
 {
        EmpathyChatPriv *priv = GET_PRIV (chat);