]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-group-chat.c
Cleanup chat objects API and request a new Text channel if account gets
[empathy.git] / libempathy-gtk / empathy-group-chat.c
index 4d62d51b68e412bb04acecf8baceab9e7a34d68c..777514652697ca6174d2d46a8297ed8bf7ce517e 100644 (file)
 
 #include <string.h>
 
+#include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
 #include <glib/gi18n.h>
 
+#include <telepathy-glib/util.h>
+
 #include <libempathy/empathy-tp-chat.h>
 #include <libempathy/empathy-tp-chatroom.h>
 #include <libempathy/empathy-contact.h>
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-debug.h>
+#include <libempathy/empathy-conf.h>
 
 #include "empathy-group-chat.h"
 #include "empathy-chat.h"
@@ -47,6 +51,7 @@
 //#include "empathy-sound.h"
 #include "empathy-images.h"
 #include "empathy-ui-utils.h"
+#include "empathy-preferences.h"
 
 #define DEBUG_DOMAIN "GroupChat"
 
@@ -78,11 +83,12 @@ static void          group_chat_finalize                 (GObject           *obj
 static void          group_chat_create_ui                (EmpathyGroupChat  *chat);
 static void          group_chat_widget_destroy_cb        (GtkWidget         *widget,
                                                          EmpathyGroupChat  *chat);
-static void          group_chat_contact_added_cb         (EmpathyTpChatroom *tp_chat,
-                                                         EmpathyContact    *contact,
-                                                         EmpathyGroupChat  *chat);
-static void          group_chat_contact_removed_cb       (EmpathyTpChatroom *tp_chat,
+static void          group_chat_members_changed_cb       (EmpathyTpChatroom *tp_chat,
                                                          EmpathyContact    *contact,
+                                                         EmpathyContact    *actor,
+                                                         guint              reason,
+                                                         gchar             *message,
+                                                         gboolean           is_member,
                                                          EmpathyGroupChat  *chat);
 static void          group_chat_topic_entry_activate_cb  (GtkWidget         *entry,
                                                          GtkDialog         *dialog);
@@ -102,9 +108,8 @@ static void          group_chat_subject_notify_cb        (EmpathyTpChat     *tp_
 static void          group_chat_name_notify_cb           (EmpathyTpChat     *tp_chat,
                                                          GParamSpec        *param,
                                                          EmpathyGroupChat  *chat);
-/*static gboolean      group_chat_key_press_event          (GtkWidget         *widget,
-                                                         GdkEventKey       *event,
-                                                         EmpathyGroupChat  *chat);*/
+static gboolean      group_chat_key_press_event          (EmpathyChat       *chat,
+                                                         GdkEventKey       *event);
 static gint          group_chat_contacts_completion_func (const gchar       *s1,
                                                          const gchar       *s2,
                                                          gsize              n);
@@ -128,6 +133,7 @@ empathy_group_chat_class_init (EmpathyGroupChatClass *klass)
        chat_class->get_widget           = group_chat_get_widget;
        chat_class->is_group_chat        = group_chat_is_group_chat;
        chat_class->set_tp_chat          = group_chat_set_tp_chat;
+       chat_class->key_press_event      = group_chat_key_press_event;
 
        g_type_class_add_private (object_class, sizeof (EmpathyGroupChatPriv));
 }
@@ -169,22 +175,15 @@ group_chat_finalize (GObject *object)
 }
 
 EmpathyGroupChat *
-empathy_group_chat_new (McAccount *account,
-                       TpChan    *tp_chan)
+empathy_group_chat_new (EmpathyTpChatroom *tp_chat)
 {
-       EmpathyGroupChat     *chat;
-       EmpathyGroupChatPriv *priv;
+       EmpathyGroupChat *chat;
 
-       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
-       g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
+       g_return_val_if_fail (EMPATHY_IS_TP_CHAT (tp_chat), NULL);
 
-       chat = g_object_new (EMPATHY_TYPE_GROUP_CHAT, NULL);
-
-       priv = GET_PRIV (chat);
-
-       EMPATHY_CHAT (chat)->account = g_object_ref (account);
-       priv->tp_chat = empathy_tp_chatroom_new (account, tp_chan);
-       empathy_chat_set_tp_chat (EMPATHY_CHAT (chat), EMPATHY_TP_CHAT (priv->tp_chat));
+       chat = g_object_new (EMPATHY_TYPE_GROUP_CHAT,
+                            "tp-chat", tp_chat,
+                            NULL);
 
        return chat;
 }
@@ -318,7 +317,7 @@ group_chat_create_ui (EmpathyGroupChat *chat)
        gtk_widget_show (EMPATHY_CHAT (chat)->input_text_view);
 
        /* Add nick name completion */
-       priv->completion = g_completion_new (NULL);
+       priv->completion = g_completion_new ((GCompletionFunc) empathy_contact_get_name);
        g_completion_set_compare (priv->completion,
                                  group_chat_contacts_completion_func);
 
@@ -348,33 +347,26 @@ group_chat_widget_destroy_cb (GtkWidget       *widget,
 }
 
 static void
-group_chat_contact_added_cb (EmpathyTpChatroom *tp_chat,
-                            EmpathyContact     *contact,
-                            EmpathyGroupChat   *chat)
-{
-       EmpathyGroupChatPriv *priv;
-       gchar               *str;
-
-       priv = GET_PRIV (chat);
-
-       str = g_strdup_printf (_("%s has joined the room"),
-                              empathy_contact_get_name (contact));
-       empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, str);
-       g_free (str);
-}
-
-static void
-group_chat_contact_removed_cb (EmpathyTpChatroom *tp_chat,
+group_chat_members_changed_cb (EmpathyTpChatroom *tp_chat,
                               EmpathyContact     *contact,
+                              EmpathyContact     *actor,
+                              guint               reason,
+                              gchar              *message,
+                              gboolean            is_member,
                               EmpathyGroupChat   *chat)
 {
        EmpathyGroupChatPriv *priv;
-       gchar               *str;
+       gchar                *str;
 
        priv = GET_PRIV (chat);
 
-       str = g_strdup_printf (_("%s has left the room"),
-                              empathy_contact_get_name (contact));
+       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 (EMPATHY_CHAT (chat)->view, str);
        g_free (str);
 }
@@ -529,22 +521,21 @@ group_chat_set_tp_chat (EmpathyChat    *chat,
 
        priv->tp_chat = g_object_ref (tp_chat);
 
-       /* FIXME: Ask the user before accepting */
-       empathy_tp_chatroom_accept_invitation (priv->tp_chat);
+       if (empathy_tp_chatroom_get_invitation (priv->tp_chat, NULL, NULL)) {
+               empathy_tp_chatroom_accept_invitation (priv->tp_chat);
+       }
 
        /* Create contact list */
        priv->store = empathy_contact_list_store_new (EMPATHY_CONTACT_LIST (priv->tp_chat));
        priv->view = empathy_contact_list_view_new (priv->store);
+       empathy_contact_list_view_set_interactive (priv->view, TRUE);
        gtk_container_add (GTK_CONTAINER (priv->scrolled_window_contacts),
                           GTK_WIDGET (priv->view));
        gtk_widget_show (GTK_WIDGET (priv->view));
 
        /* Connect signals */
-       g_signal_connect (priv->tp_chat, "contact-added",
-                         G_CALLBACK (group_chat_contact_added_cb),
-                         chat);
-       g_signal_connect (priv->tp_chat, "contact-removed",
-                         G_CALLBACK (group_chat_contact_removed_cb),
+       g_signal_connect (priv->tp_chat, "members-changed",
+                         G_CALLBACK (group_chat_members_changed_cb),
                          chat);
        g_signal_connect (priv->tp_chat, "notify::subject",
                          G_CALLBACK (group_chat_subject_notify_cb),
@@ -560,13 +551,18 @@ group_chat_subject_notify_cb (EmpathyTpChat   *tp_chat,
                              EmpathyGroupChat *chat)
 {
        EmpathyGroupChatPriv *priv;
-       gchar               *str;
+       gchar                *str = NULL;
 
        priv = GET_PRIV (chat);
 
-       g_free (priv->topic);
+       g_object_get (priv->tp_chat, "subject", &str, NULL);
+       if (!tp_strdiff (priv->topic, str)) {
+               g_free (str);
+               return;
+       }
 
-       g_object_get (priv->tp_chat, "subject", &priv->topic, NULL);
+       g_free (priv->topic);
+       priv->topic = str;
        gtk_label_set_text (GTK_LABEL (priv->label_topic), priv->topic);
 
        if (!G_STR_EMPTY (priv->topic)) {
@@ -591,27 +587,20 @@ group_chat_name_notify_cb (EmpathyTpChat   *tp_chat,
        g_object_get (priv->tp_chat, "name", &priv->name, NULL);
 }
 
-#if 0
 static gboolean
-group_chat_key_press_event (GtkWidget       *widget,
-                           GdkEventKey     *event,
-                           EmpathyGroupChat *chat)
+group_chat_key_press_event (EmpathyChat *chat,
+                           GdkEventKey *event)
 {
-       EmpathyGroupChatPriv *priv;
-       GtkAdjustment       *adj;
-       gdouble              val;
-       GtkTextBuffer       *buffer;
-       GtkTextIter          start, current;
-       gchar               *nick, *completed;
-       gint                 len;
-       GList               *list, *l, *completed_list;
-       gboolean             is_start_of_buffer;
+       EmpathyGroupChatPriv *priv = GET_PRIV (chat);
 
-       priv = GET_PRIV (chat);
-
-       if ((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK &&
-           (event->state & GDK_SHIFT_MASK) != GDK_SHIFT_MASK &&
+       if (!(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) &&
            event->keyval == GDK_Tab) {
+               GtkTextBuffer *buffer;
+               GtkTextIter    start, current;
+               gchar         *nick, *completed;
+               GList         *list, *completed_list;
+               gboolean       is_start_of_buffer;
+
                buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (EMPATHY_CHAT (chat)->input_text_view));
                gtk_text_buffer_get_iter_at_mark (buffer, &current, gtk_text_buffer_get_insert (buffer));
 
@@ -620,16 +609,10 @@ group_chat_key_press_event (GtkWidget       *widget,
                gtk_text_iter_backward_word_start (&start);
                is_start_of_buffer = gtk_text_iter_is_start (&start);
 
-               nick = gtk_text_buffer_get_text (buffer, &start, &current, FALSE);
-
-               g_completion_clear_items (priv->completion);
-
-               len = strlen (nick);
-
-               list = group_chat_get_nick_list (chat);
-
+               list = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (priv->tp_chat));
                g_completion_add_items (priv->completion, list);
 
+               nick = gtk_text_buffer_get_text (buffer, &start, &current, FALSE);
                completed_list = g_completion_complete (priv->completion,
                                                        nick,
                                                        &completed);
@@ -637,8 +620,9 @@ group_chat_key_press_event (GtkWidget       *widget,
                g_free (nick);
 
                if (completed) {
-                       int       len;
-                       gchar    *text;
+                       guint        len;
+                       const gchar *text;
+                       gchar       *complete_char = NULL;
 
                        gtk_text_buffer_delete (buffer, &start, &current);
 
@@ -651,17 +635,23 @@ group_chat_key_press_event (GtkWidget       *widget,
                                 * which might be cased all wrong.
                                 * Fixes #120876
                                 * */
-                               text = (gchar *) completed_list->data;
+                               text = empathy_contact_get_name (completed_list->data);
                        } else {
                                text = completed;
                        }
 
                        gtk_text_buffer_insert_at_cursor (buffer, text, strlen (text));
 
-                       if (len == 1) {
-                               if (is_start_of_buffer) {
-                                       gtk_text_buffer_insert_at_cursor (buffer, ", ", 2);
-                               }
+                       if (len == 1 && is_start_of_buffer &&
+                           empathy_conf_get_string (empathy_conf_get (),
+                                                    EMPATHY_PREFS_CHAT_NICK_COMPLETION_CHAR,
+                                                    &complete_char) &&
+                           complete_char != NULL) {
+                               gtk_text_buffer_insert_at_cursor (buffer,
+                                                                 complete_char,
+                                                                 strlen (complete_char));
+                               gtk_text_buffer_insert_at_cursor (buffer, " ", 1);
+                               g_free (complete_char);
                        }
 
                        g_free (completed);
@@ -669,10 +659,7 @@ group_chat_key_press_event (GtkWidget       *widget,
 
                g_completion_clear_items (priv->completion);
 
-               for (l = list; l; l = l->next) {
-                       g_free (l->data);
-               }
-
+               g_list_foreach (list, (GFunc) g_object_unref, NULL);
                g_list_free (list);
 
                return TRUE;
@@ -680,7 +667,6 @@ group_chat_key_press_event (GtkWidget       *widget,
 
        return FALSE;
 }
-#endif
 
 static gint
 group_chat_contacts_completion_func (const gchar *s1,