diff options
author | Xavier Claessens <xclaesse@gmail.com> | 2007-05-21 06:34:10 +0800 |
---|---|---|
committer | Xavier Claessens <xclaesse@src.gnome.org> | 2007-05-21 06:34:10 +0800 |
commit | e9da37418519e89f8489491310b5f3ca3ef59f76 (patch) | |
tree | 1c071ef8c6bbbd3922dc5d70888bd30074313d1c | |
parent | 03d20e55433ca5d11633dec62435ea66ebdaf1ae (diff) | |
download | gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.tar gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.tar.gz gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.tar.bz2 gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.tar.lz gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.tar.xz gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.tar.zst gsoc2013-empathy-e9da37418519e89f8489491310b5f3ca3ef59f76.zip |
Implementing basic chatroom support. Actually it works only if we get
2007-05-21 Xavier Claessens <xclaesse@gmail.com>
* libempathy-gtk/gossip-group-chat.c:
* libempathy-gtk/gossip-group-chat.h:
* libempathy-gtk/gossip-private-chat.c:
* libempathy-gtk/gossip-private-chat.h:
* libempathy-gtk/gossip-group-chat.glade:
* libempathy-gtk/Makefile.am:
* src/empathy-chat-main.c:
* libempathy/empathy-tp-contact-list.c:
* libempathy/gossip-telepathy-group.c:
* libempathy/gossip-telepathy-group.h:
* libempathy/empathy-tp-chatroom.c:
* libempathy/empathy-tp-chatroom.h: Implementing basic chatroom support.
Actually it works only if we get invited in a chatroom.
svn path=/trunk/; revision=87
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | libempathy-gtk/Makefile.am | 2 | ||||
-rw-r--r-- | libempathy-gtk/gossip-group-chat.c | 630 | ||||
-rw-r--r-- | libempathy-gtk/gossip-group-chat.glade | 183 | ||||
-rw-r--r-- | libempathy-gtk/gossip-group-chat.h | 68 | ||||
-rw-r--r-- | libempathy-gtk/gossip-private-chat.c | 34 | ||||
-rw-r--r-- | libempathy-gtk/gossip-private-chat.h | 7 | ||||
-rw-r--r-- | libempathy/empathy-tp-chatroom.c | 163 | ||||
-rw-r--r-- | libempathy/empathy-tp-chatroom.h | 13 | ||||
-rw-r--r-- | libempathy/empathy-tp-contact-list.c | 46 | ||||
-rw-r--r-- | libempathy/gossip-telepathy-group.c | 57 | ||||
-rw-r--r-- | libempathy/gossip-telepathy-group.h | 10 | ||||
-rw-r--r-- | src/empathy-chat-main.c | 60 |
13 files changed, 1192 insertions, 97 deletions
@@ -1,3 +1,19 @@ +2007-05-21 Xavier Claessens <xclaesse@gmail.com> + + * libempathy-gtk/gossip-group-chat.c: + * libempathy-gtk/gossip-group-chat.h: + * libempathy-gtk/gossip-private-chat.c: + * libempathy-gtk/gossip-private-chat.h: + * libempathy-gtk/gossip-group-chat.glade: + * libempathy-gtk/Makefile.am: + * src/empathy-chat-main.c: + * libempathy/empathy-tp-contact-list.c: + * libempathy/gossip-telepathy-group.c: + * libempathy/gossip-telepathy-group.h: + * libempathy/empathy-tp-chatroom.c: + * libempathy/empathy-tp-chatroom.h: Implementing basic chatroom support. + Actually it works only if we get invited in a chatroom. + 2007-05-20 Xavier Claessens <xclaesse@gmail.com> * libempathy-gtk/gossip-chat-view.c: Correctly remember the contact diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index 42fd8b095..7a5d1893a 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -27,6 +27,7 @@ libempathy_gtk_la_SOURCES = \ gossip-chat.c gossip-chat.h \ gossip-chat-view.c gossip-chat-view.h \ gossip-private-chat.c gossip-private-chat.h \ + gossip-group-chat.c gossip-group-chat.h \ gossip-geometry.c gossip-geometry.h \ gossip-status-presets.c gossip-status-presets.h \ gossip-presence-chooser.c gossip-presence-chooser.h \ @@ -47,6 +48,7 @@ glade_DATA = \ gossip-presence-chooser.glade \ gossip-accounts-dialog.glade \ gossip-account-widget-jabber.glade \ + gossip-group-chat.glade \ gossip-chat.glade dtddir = $(datadir)/empathy diff --git a/libempathy-gtk/gossip-group-chat.c b/libempathy-gtk/gossip-group-chat.c new file mode 100644 index 000000000..b955ee21e --- /dev/null +++ b/libempathy-gtk/gossip-group-chat.c @@ -0,0 +1,630 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2002-2007 Imendio AB + * Copyright (C) 2007 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Mikael Hallendal <micke@imendio.com> + * Richard Hult <richard@imendio.com> + * Martyn Russell <martyn@imendio.com> + * Xavier Claessens <xclaesse@gmail.com> + */ + +#include "config.h" + +#include <string.h> + +#include <gtk/gtk.h> +#include <glade/glade.h> +#include <glib/gi18n.h> + +#include <libempathy/empathy-tp-chat.h> +#include <libempathy/empathy-tp-chatroom.h> +#include <libempathy/gossip-contact.h> +#include <libempathy/gossip-utils.h> +#include <libempathy/gossip-debug.h> + +#include "gossip-group-chat.h" +#include "gossip-chat.h" +#include "gossip-chat-view.h" +#include "gossip-contact-list-store.h" +#include "gossip-contact-list-view.h" +//#include "gossip-chat-invite.h" +//#include "gossip-sound.h" +#include "empathy-images.h" +#include "gossip-ui-utils.h" + +#define DEBUG_DOMAIN "GroupChat" + +#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_GROUP_CHAT, GossipGroupChatPriv)) + +struct _GossipGroupChatPriv { + GossipContactListStore *store; + GossipContactListView *view; + EmpathyTpChatroom *tp_chat; + + GtkWidget *widget; + GtkWidget *hpaned; + GtkWidget *vbox_left; + GtkWidget *scrolled_window_chat; + GtkWidget *scrolled_window_input; + GtkWidget *scrolled_window_contacts; + GtkWidget *hbox_topic; + GtkWidget *label_topic; + + gchar *topic; + gchar *name; + GCompletion *completion; + + gint contacts_width; + gboolean contacts_visible; +}; + +static void group_chat_finalize (GObject *object); +static void group_chat_create_ui (GossipGroupChat *chat); +static void group_chat_widget_destroy_cb (GtkWidget *widget, + GossipGroupChat *chat); +static void group_chat_contact_added_cb (EmpathyTpChatroom *tp_chat, + GossipContact *contact, + GossipGroupChat *chat); +static void group_chat_contact_removed_cb (EmpathyTpChatroom *tp_chat, + GossipContact *contact, + GossipGroupChat *chat); +/*static void group_chat_topic_changed_cb (EmpathyTpChatroom *tp_chat, + const gchar *new_topic, + GossipGroupChat *chat);*/ +static void group_chat_topic_entry_activate_cb (GtkWidget *entry, + GtkDialog *dialog); +static void group_chat_topic_response_cb (GtkWidget *dialog, + gint response, + GossipGroupChat *chat); +void gossip_group_chat_set_topic (GossipGroupChat *chat); +static const gchar * group_chat_get_name (GossipChat *chat); +static gchar * group_chat_get_tooltip (GossipChat *chat); +static const gchar * group_chat_get_status_icon_name (GossipChat *chat); +static GtkWidget * group_chat_get_widget (GossipChat *chat); +static gboolean group_chat_is_group_chat (GossipChat *chat); +/*static gboolean group_chat_key_press_event (GtkWidget *widget, + GdkEventKey *event, + GossipGroupChat *chat);*/ +static gint group_chat_contacts_completion_func (const gchar *s1, + const gchar *s2, + gsize n); + +G_DEFINE_TYPE (GossipGroupChat, gossip_group_chat, GOSSIP_TYPE_CHAT) + +static void +gossip_group_chat_class_init (GossipGroupChatClass *klass) +{ + GObjectClass *object_class; + GossipChatClass *chat_class; + + object_class = G_OBJECT_CLASS (klass); + chat_class = GOSSIP_CHAT_CLASS (klass); + + object_class->finalize = group_chat_finalize; + + chat_class->get_name = group_chat_get_name; + chat_class->get_tooltip = group_chat_get_tooltip; + chat_class->get_status_icon_name = group_chat_get_status_icon_name; + chat_class->get_widget = group_chat_get_widget; + chat_class->is_group_chat = group_chat_is_group_chat; + + g_type_class_add_private (object_class, sizeof (GossipGroupChatPriv)); +} + +static void +gossip_group_chat_init (GossipGroupChat *chat) +{ + GossipGroupChatPriv *priv; + GossipChatView *chatview; + + priv = GET_PRIV (chat); + + priv->contacts_visible = TRUE; + + chatview = GOSSIP_CHAT_VIEW (GOSSIP_CHAT (chat)->view); + gossip_chat_view_set_is_group_chat (chatview, TRUE); + + group_chat_create_ui (chat); +} + +static void +group_chat_finalize (GObject *object) +{ + GossipGroupChat *chat; + GossipGroupChatPriv *priv; + + gossip_debug (DEBUG_DOMAIN, "Finalized:%p", object); + + chat = GOSSIP_GROUP_CHAT (object); + priv = GET_PRIV (chat); + + g_free (priv->name); + g_free (priv->topic); + g_object_unref (priv->store); + g_object_unref (priv->tp_chat); + g_completion_free (priv->completion); + + G_OBJECT_CLASS (gossip_group_chat_parent_class)->finalize (object); +} + +GossipGroupChat * +gossip_group_chat_new (McAccount *account, + TpChan *tp_chan) +{ + GossipGroupChat *chat; + GossipGroupChatPriv *priv; + + g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); + g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); + + chat = g_object_new (GOSSIP_TYPE_GROUP_CHAT, NULL); + + priv = GET_PRIV (chat); + + priv->tp_chat = empathy_tp_chatroom_new (account, tp_chan); + gossip_chat_set_tp_chat (GOSSIP_CHAT (chat), EMPATHY_TP_CHAT (priv->tp_chat)); + GOSSIP_CHAT (chat)->account = g_object_ref (account); + + /* FIXME: Ask the user before accepting */ + empathy_tp_chatroom_accept_invitation (priv->tp_chat); + + /* Create contact list */ + priv->store = gossip_contact_list_store_new (EMPATHY_CONTACT_LIST (priv->tp_chat)); + priv->view = gossip_contact_list_view_new (priv->store); + gtk_container_add (GTK_CONTAINER (priv->scrolled_window_contacts), + GTK_WIDGET (priv->view)); + gtk_widget_show (GTK_WIDGET (priv->view)); + + 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), + chat); +/* g_signal_connect (priv->tp_chat, "chatroom-topic-changed", + G_CALLBACK (group_chat_topic_changed_cb), + chat); + g_signal_connect (priv->tp_chat, "contact-info-changed", + G_CALLBACK (group_chat_contact_info_changed_cb), + chat);*/ + + return chat; +} + +gboolean +gossip_group_chat_get_show_contacts (GossipChat *chat) +{ + GossipGroupChat *group_chat; + GossipGroupChatPriv *priv; + + g_return_val_if_fail (GOSSIP_IS_GROUP_CHAT (chat), FALSE); + + group_chat = GOSSIP_GROUP_CHAT (chat); + priv = GET_PRIV (group_chat); + + return priv->contacts_visible; +} + +void +gossip_group_chat_set_show_contacts (GossipChat *chat, + gboolean show) +{ + GossipGroupChat *group_chat; + GossipGroupChatPriv *priv; + + g_return_if_fail (GOSSIP_IS_GROUP_CHAT (chat)); + + group_chat = GOSSIP_GROUP_CHAT (chat); + priv = GET_PRIV (group_chat); + + priv->contacts_visible = show; + + if (show) { + gtk_widget_show (priv->scrolled_window_contacts); + gtk_paned_set_position (GTK_PANED (priv->hpaned), + priv->contacts_width); + } else { + priv->contacts_width = gtk_paned_get_position (GTK_PANED (priv->hpaned)); + gtk_widget_hide (priv->scrolled_window_contacts); + } +} + +static void +group_chat_create_ui (GossipGroupChat *chat) +{ + GossipGroupChatPriv *priv; + GladeXML *glade; + GList *list = NULL; + + priv = GET_PRIV (chat); + + glade = gossip_glade_get_file ("gossip-group-chat.glade", + "group_chat_widget", + NULL, + "group_chat_widget", &priv->widget, + "hpaned", &priv->hpaned, + "vbox_left", &priv->vbox_left, + "scrolled_window_chat", &priv->scrolled_window_chat, + "scrolled_window_input", &priv->scrolled_window_input, + "hbox_topic", &priv->hbox_topic, + "label_topic", &priv->label_topic, + "scrolled_window_contacts", &priv->scrolled_window_contacts, + NULL); + + gossip_glade_connect (glade, + chat, + "group_chat_widget", "destroy", group_chat_widget_destroy_cb, + NULL); + + g_object_unref (glade); + + g_object_set_data (G_OBJECT (priv->widget), "chat", chat); + + /* Add room GtkTextView. */ + gtk_container_add (GTK_CONTAINER (priv->scrolled_window_chat), + GTK_WIDGET (GOSSIP_CHAT (chat)->view)); + gtk_widget_show (GTK_WIDGET (GOSSIP_CHAT (chat)->view)); + + /* Add input GtkTextView */ + gtk_container_add (GTK_CONTAINER (priv->scrolled_window_input), + GOSSIP_CHAT (chat)->input_text_view); + gtk_widget_show (GOSSIP_CHAT (chat)->input_text_view); + + /* Add nick name completion */ + priv->completion = g_completion_new (NULL); + g_completion_set_compare (priv->completion, + group_chat_contacts_completion_func); + + /* Set widget focus order */ + list = g_list_append (NULL, priv->scrolled_window_input); + gtk_container_set_focus_chain (GTK_CONTAINER (priv->vbox_left), list); + g_list_free (list); + + list = g_list_append (NULL, priv->vbox_left); + list = g_list_append (list, priv->scrolled_window_contacts); + gtk_container_set_focus_chain (GTK_CONTAINER (priv->hpaned), list); + g_list_free (list); + + list = g_list_append (NULL, priv->hpaned); + list = g_list_append (list, priv->hbox_topic); + gtk_container_set_focus_chain (GTK_CONTAINER (priv->widget), list); + g_list_free (list); +} + +static void +group_chat_widget_destroy_cb (GtkWidget *widget, + GossipGroupChat *chat) +{ + gossip_debug (DEBUG_DOMAIN, "Destroyed"); + + g_object_unref (chat); +} + +static void +group_chat_contact_added_cb (EmpathyTpChatroom *tp_chat, + GossipContact *contact, + GossipGroupChat *chat) +{ + GossipGroupChatPriv *priv; + gchar *str; + + priv = GET_PRIV (chat); + + str = g_strdup_printf (_("%s has joined the room"), + gossip_contact_get_name (contact)); + gossip_chat_view_append_event (GOSSIP_CHAT (chat)->view, str); + g_free (str); +} + +static void +group_chat_contact_removed_cb (EmpathyTpChatroom *tp_chat, + GossipContact *contact, + GossipGroupChat *chat) +{ + GossipGroupChatPriv *priv; + gchar *str; + + priv = GET_PRIV (chat); + + str = g_strdup_printf (_("%s has left the room"), + gossip_contact_get_name (contact)); + gossip_chat_view_append_event (GOSSIP_CHAT (chat)->view, str); + g_free (str); +} +/* +static void +group_chat_topic_changed_cb (EmpathyTpChatroom *tp_chat, + const gchar *new_topic, + GossipGroupChat *chat) +{ + GossipGroupChatPriv *priv; + gchar *str; + + priv = GET_PRIV (chat); + + gossip_debug (DEBUG_DOMAIN, "Topic changed by to:'%s'", new_topic); + + g_free (priv->topic); + priv->topic = g_strdup (new_topic); + + gtk_label_set_text (GTK_LABEL (priv->label_topic), new_topic); + + str = g_strdup_printf (_("Topic set to: %s"), new_topic); + gossip_chat_view_append_event (GOSSIP_CHAT (chat)->view, str); + g_free (str); +} +*/ +static void +group_chat_topic_entry_activate_cb (GtkWidget *entry, + GtkDialog *dialog) +{ + gtk_dialog_response (dialog, GTK_RESPONSE_OK); +} + +static void +group_chat_topic_response_cb (GtkWidget *dialog, + gint response, + GossipGroupChat *chat) +{ + if (response == GTK_RESPONSE_OK) { + GtkWidget *entry; + const gchar *topic; + + entry = g_object_get_data (G_OBJECT (dialog), "entry"); + topic = gtk_entry_get_text (GTK_ENTRY (entry)); + + if (!G_STR_EMPTY (topic)) { + GossipGroupChatPriv *priv; + + priv = GET_PRIV (chat); + + empathy_tp_chatroom_set_topic (priv->tp_chat, topic); + } + } + + gtk_widget_destroy (dialog); +} + +void +gossip_group_chat_set_topic (GossipGroupChat *chat) +{ + GossipGroupChatPriv *priv; + GossipChatWindow *chat_window; + GtkWidget *chat_dialog; + GtkWidget *dialog; + GtkWidget *entry; + GtkWidget *hbox; + const gchar *topic; + + priv = GET_PRIV (chat); + + chat_window = gossip_chat_get_window (GOSSIP_CHAT (chat)); + chat_dialog = gossip_chat_window_get_dialog (chat_window); + + dialog = gtk_message_dialog_new (GTK_WINDOW (chat_dialog), + 0, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_OK_CANCEL, + _("Enter the new topic you want to set for this room:")); + + topic = gtk_label_get_text (GTK_LABEL (priv->label_topic)); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + hbox, FALSE, TRUE, 4); + + entry = gtk_entry_new (); + gtk_entry_set_text (GTK_ENTRY (entry), topic); + gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1); + + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 4); + + g_object_set (GTK_MESSAGE_DIALOG (dialog)->label, "use-markup", TRUE, NULL); + g_object_set_data (G_OBJECT (dialog), "entry", entry); + + g_signal_connect (entry, "activate", + G_CALLBACK (group_chat_topic_entry_activate_cb), + dialog); + g_signal_connect (dialog, "response", + G_CALLBACK (group_chat_topic_response_cb), + chat); + + gtk_widget_show_all (dialog); +} + +static const gchar * +group_chat_get_name (GossipChat *chat) +{ + GossipGroupChat *group_chat; + GossipGroupChatPriv *priv; + + g_return_val_if_fail (GOSSIP_IS_GROUP_CHAT (chat), NULL); + + group_chat = GOSSIP_GROUP_CHAT (chat); + priv = GET_PRIV (group_chat); + + return priv->name; +} + +static gchar * +group_chat_get_tooltip (GossipChat *chat) +{ + GossipGroupChat *group_chat; + GossipGroupChatPriv *priv; + + g_return_val_if_fail (GOSSIP_IS_GROUP_CHAT (chat), NULL); + + group_chat = GOSSIP_GROUP_CHAT (chat); + priv = GET_PRIV (group_chat); + + if (priv->topic) { + gchar *topic, *tmp; + + topic = g_strdup_printf (_("Topic: %s"), priv->topic); + tmp = g_strdup_printf ("%s\n%s", priv->name, topic); + g_free (topic); + + return tmp; + } + + return g_strdup (priv->name); +} + +static const gchar * +group_chat_get_status_icon_name (GossipChat *chat) +{ + return EMPATHY_IMAGE_GROUP_MESSAGE; +} + +static GtkWidget * +group_chat_get_widget (GossipChat *chat) +{ + GossipGroupChat *group_chat; + GossipGroupChatPriv *priv; + + g_return_val_if_fail (GOSSIP_IS_GROUP_CHAT (chat), NULL); + + group_chat = GOSSIP_GROUP_CHAT (chat); + priv = GET_PRIV (group_chat); + + return priv->widget; +} + +static gboolean +group_chat_is_group_chat (GossipChat *chat) +{ + g_return_val_if_fail (GOSSIP_IS_GROUP_CHAT (chat), FALSE); + + return TRUE; +} +#if 0 +static gboolean +group_chat_key_press_event (GtkWidget *widget, + GdkEventKey *event, + GossipGroupChat *chat) +{ + GossipGroupChatPriv *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; + + priv = GET_PRIV (chat); + + if ((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK && + (event->state & GDK_SHIFT_MASK) != GDK_SHIFT_MASK && + event->keyval == GDK_Tab) { + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (GOSSIP_CHAT (chat)->input_text_view)); + gtk_text_buffer_get_iter_at_mark (buffer, ¤t, gtk_text_buffer_get_insert (buffer)); + + /* Get the start of the nick to complete. */ + gtk_text_buffer_get_iter_at_mark (buffer, &start, gtk_text_buffer_get_insert (buffer)); + 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, ¤t, FALSE); + + g_completion_clear_items (priv->completion); + + len = strlen (nick); + + list = group_chat_get_nick_list (chat); + + g_completion_add_items (priv->completion, list); + + completed_list = g_completion_complete (priv->completion, + nick, + &completed); + + g_free (nick); + + if (completed) { + int len; + gchar *text; + + gtk_text_buffer_delete (buffer, &start, ¤t); + + len = g_list_length (completed_list); + + if (len == 1) { + /* If we only have one hit, use that text + * instead of the text in completed since the + * completed text will use the typed string + * which might be cased all wrong. + * Fixes #120876 + * */ + text = (gchar *) 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); + } + } + + g_free (completed); + } + + g_completion_clear_items (priv->completion); + + for (l = list; l; l = l->next) { + g_free (l->data); + } + + g_list_free (list); + + return TRUE; + } + + return FALSE; +} +#endif + +static gint +group_chat_contacts_completion_func (const gchar *s1, + const gchar *s2, + gsize n) +{ + gchar *tmp, *nick1, *nick2; + gint ret; + + tmp = g_utf8_normalize (s1, -1, G_NORMALIZE_DEFAULT); + nick1 = g_utf8_casefold (tmp, -1); + g_free (tmp); + + tmp = g_utf8_normalize (s2, -1, G_NORMALIZE_DEFAULT); + nick2 = g_utf8_casefold (tmp, -1); + g_free (tmp); + + ret = strncmp (nick1, nick2, n); + + g_free (nick1); + g_free (nick2); + + return ret; +} + diff --git a/libempathy-gtk/gossip-group-chat.glade b/libempathy-gtk/gossip-group-chat.glade new file mode 100644 index 000000000..7b6f2c00f --- /dev/null +++ b/libempathy-gtk/gossip-group-chat.glade @@ -0,0 +1,183 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkWindow" id="group_chat_window"> + <property name="border_width">6</property> + <property name="title" translatable="yes">Group Chat</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="default_width">600</property> + <property name="default_height">400</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="icon">gossip-group-message.png</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="focus_on_map">True</property> + <property name="urgency_hint">False</property> + + <child> + <widget class="GtkVBox" id="group_chat_widget"> + <property name="border_width">4</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkHBox" id="hbox_topic"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label80"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Topic:</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label_topic"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">True</property> + <property name="selectable">True</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_END</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">True</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHPaned" id="hpaned"> + <property name="visible">True</property> + <property name="can_focus">True</property> + + <child> + <widget class="GtkVBox" id="vbox_left"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolled_window_chat"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolled_window_input"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolled_window_contacts"> + <property name="width_request">0</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="shrink">False</property> + <property name="resize">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/libempathy-gtk/gossip-group-chat.h b/libempathy-gtk/gossip-group-chat.h new file mode 100644 index 000000000..871d65d61 --- /dev/null +++ b/libempathy-gtk/gossip-group-chat.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2002-2007 Imendio AB + * Copyright (C) 2007 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Mikael Hallendal <micke@imendio.com> + * Richard Hult <richard@imendio.com> + * Martyn Russell <martyn@imendio.com> + * Xavier Claessens <xclaesse@gmail.com> + */ + +#ifndef __GOSSIP_GROUP_CHAT_H__ +#define __GOSSIP_GROUP_CHAT_H__ + +G_BEGIN_DECLS + +#include <libtelepathy/tp-chan.h> + +#include <libmissioncontrol/mc-account.h> + +#define GOSSIP_TYPE_GROUP_CHAT (gossip_group_chat_get_type ()) +#define GOSSIP_GROUP_CHAT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_GROUP_CHAT, GossipGroupChat)) +#define GOSSIP_GROUP_CHAT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOSSIP_TYPE_GROUP_CHAT, GossipGroupChatClass)) +#define GOSSIP_IS_GROUP_CHAT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOSSIP_TYPE_GROUP_CHAT)) +#define GOSSIP_IS_GROUP_CHAT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOSSIP_TYPE_GROUP_CHAT)) +#define GOSSIP_GROUP_CHAT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOSSIP_TYPE_GROUP_CHAT, GossipGroupChatClass)) + +typedef struct _GossipGroupChat GossipGroupChat; +typedef struct _GossipGroupChatClass GossipGroupChatClass; +typedef struct _GossipGroupChatPriv GossipGroupChatPriv; + +#include "gossip-chat.h" + +struct _GossipGroupChat { + GossipChat parent; + + GossipGroupChatPriv *priv; +}; + +struct _GossipGroupChatClass { + GossipChatClass parent_class; +}; + +GType gossip_group_chat_get_type (void) G_GNUC_CONST; +GossipGroupChat *gossip_group_chat_new (McAccount *account, + TpChan *tp_chan); +gboolean gossip_group_chat_get_show_contacts (GossipChat *chat); +void gossip_group_chat_set_show_contacts (GossipChat *chat, + gboolean show); + +G_END_DECLS + +#endif /* __GOSSIP_GROUP_CHAT_H__ */ diff --git a/libempathy-gtk/gossip-private-chat.c b/libempathy-gtk/gossip-private-chat.c index 84cc156e8..fb7198ff0 100644 --- a/libempathy-gtk/gossip-private-chat.c +++ b/libempathy-gtk/gossip-private-chat.c @@ -33,10 +33,10 @@ #include <glade/glade.h> #include <glib/gi18n.h> -#include <libmissioncontrol/mc-account.h> - #include <libempathy/gossip-debug.h> #include <libempathy/empathy-tp-chat.h> +#include <libempathy/empathy-tp-contact-list.h> +#include <libempathy/empathy-contact-manager.h> //#include <libgossip/gossip-log.h> #include "gossip-private-chat.h" @@ -328,36 +328,44 @@ private_chat_setup (GossipPrivateChat *chat, } GossipPrivateChat * -gossip_private_chat_new (GossipContact *contact) +gossip_private_chat_new (McAccount *account, + TpChan *tp_chan) { - GossipPrivateChat *chat; - EmpathyTpChat *tp_chat; + GossipPrivateChat *chat; + EmpathyTpChat *tp_chat; + EmpathyContactManager *manager; + EmpathyTpContactList *list; + GossipContact *contact; - g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL); + g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); + g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); + + manager = empathy_contact_manager_new (); + list = empathy_contact_manager_get_list (manager, account); + contact = empathy_tp_contact_list_get_from_handle (list, tp_chan->handle); chat = g_object_new (GOSSIP_TYPE_PRIVATE_CHAT, NULL); - tp_chat = empathy_tp_chat_new_with_contact (contact); + tp_chat = empathy_tp_chat_new (account, tp_chan); private_chat_setup (chat, contact, tp_chat); + g_object_unref (tp_chat); + g_object_unref (contact); + g_object_unref (manager); return chat; } GossipPrivateChat * -gossip_private_chat_new_with_channel (GossipContact *contact, - TpChan *tp_chan) +gossip_private_chat_new_with_contact (GossipContact *contact) { GossipPrivateChat *chat; EmpathyTpChat *tp_chat; - McAccount *account; g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL); - g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); - account = gossip_contact_get_account (contact); chat = g_object_new (GOSSIP_TYPE_PRIVATE_CHAT, NULL); - tp_chat = empathy_tp_chat_new (account, tp_chan); + tp_chat = empathy_tp_chat_new_with_contact (contact); private_chat_setup (chat, contact, tp_chat); g_object_unref (tp_chat); diff --git a/libempathy-gtk/gossip-private-chat.h b/libempathy-gtk/gossip-private-chat.h index c93b239e5..326d0f60e 100644 --- a/libempathy-gtk/gossip-private-chat.h +++ b/libempathy-gtk/gossip-private-chat.h @@ -30,8 +30,9 @@ #include <libtelepathy/tp-chan.h> +#include <libmissioncontrol/mc-account.h> + #include <libempathy/gossip-contact.h> -#include <libempathy/gossip-message.h> G_BEGIN_DECLS @@ -57,9 +58,9 @@ struct _GossipPrivateChatClass { }; GType gossip_private_chat_get_type (void); -GossipPrivateChat * gossip_private_chat_new (GossipContact *contact); -GossipPrivateChat * gossip_private_chat_new_with_channel (GossipContact *contact, +GossipPrivateChat * gossip_private_chat_new (McAccount *account, TpChan *tp_chan); +GossipPrivateChat * gossip_private_chat_new_with_contact (GossipContact *contact); GossipContact * gossip_private_chat_get_contact (GossipPrivateChat *chat); G_END_DECLS diff --git a/libempathy/empathy-tp-chatroom.c b/libempathy/empathy-tp-chatroom.c index 6feef549d..34875c10c 100644 --- a/libempathy/empathy-tp-chatroom.c +++ b/libempathy/empathy-tp-chatroom.c @@ -30,6 +30,7 @@ #include "empathy-contact-manager.h" #include "gossip-telepathy-group.h" #include "gossip-utils.h" +#include "gossip-debug.h" #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ EMPATHY_TYPE_TP_CHATROOM, EmpathyTpChatroomPriv)) @@ -40,12 +41,28 @@ struct _EmpathyTpChatroomPriv { EmpathyContactManager *manager; EmpathyTpContactList *list; GossipTelepathyGroup *group; + + gboolean is_invited; + GossipContact *invitor; + gchar *invit_message; }; static void empathy_tp_chatroom_class_init (EmpathyTpChatroomClass *klass); static void tp_chatroom_iface_init (EmpathyContactListIface *iface); static void empathy_tp_chatroom_init (EmpathyTpChatroom *chatroom); static void tp_chatroom_finalize (GObject *object); +static void tp_chatroom_members_added_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *list); +static void tp_chatroom_members_removed_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *list); static void tp_chatroom_setup (EmpathyContactList *list); static GossipContact * tp_chatroom_find (EmpathyContactList *list, const gchar *id); @@ -97,7 +114,12 @@ tp_chatroom_finalize (GObject *object) g_object_unref (priv->group); g_object_unref (priv->manager); - g_object_unref (priv->list); + + if (priv->invitor) { + g_object_unref (priv->invitor); + } + + g_free (priv->invit_message); G_OBJECT_CLASS (empathy_tp_chatroom_parent_class)->finalize (object); } @@ -110,6 +132,8 @@ empathy_tp_chatroom_new (McAccount *account, EmpathyTpChatroom *chatroom; TpConn *tp_conn; MissionControl *mc; + GList *members, *l; + guint self_handle; g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); @@ -124,18 +148,139 @@ empathy_tp_chatroom_new (McAccount *account, mc = gossip_mission_control_new (); tp_conn = mission_control_get_connection (mc, account, NULL); priv->manager = empathy_contact_manager_new (); - priv->group = gossip_telepathy_group_new (tp_chan, tp_conn); priv->list = empathy_contact_manager_get_list (priv->manager, account); + priv->group = gossip_telepathy_group_new (tp_chan, tp_conn); + + g_signal_connect (priv->group, "members-added", + G_CALLBACK (tp_chatroom_members_added_cb), + chatroom); + g_signal_connect (priv->group, "members-removed", + G_CALLBACK (tp_chatroom_members_removed_cb), + chatroom); + + /* Check if we are invited to join the chat */ + self_handle = gossip_telepathy_group_get_self_handle (priv->group); + members = gossip_telepathy_group_get_local_pending_members_with_info (priv->group); + for (l = members; l; l = l->next) { + GossipTpGroupInfo *info; + info = l->data; + + if (info->member != self_handle) { + continue; + } + + priv->invitor = empathy_tp_contact_list_get_from_handle (priv->list, + info->actor); + priv->invit_message = g_strdup (info->message); + priv->is_invited = TRUE; + + gossip_debug (DEBUG_DOMAIN, "We are invited to join by %s: %s", + gossip_contact_get_name (priv->invitor), + priv->invit_message); + } + + gossip_telepathy_group_info_list_free (members); g_object_unref (mc); g_object_unref (tp_conn); return chatroom; } +gboolean +empathy_tp_chatroom_get_invitation (EmpathyTpChatroom *chatroom, + GossipContact **contact, + const gchar **message) +{ + EmpathyTpChatroomPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom), FALSE); + + priv = GET_PRIV (chatroom); + + if (*contact) { + *contact = priv->invitor; + } + if (*message) { + *message = priv->invit_message; + } + + return priv->is_invited; +} + +void +empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom) +{ + EmpathyTpChatroomPriv *priv; + guint self_handle; + + g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom)); + + priv = GET_PRIV (chatroom); + + /* Clear invitation data */ + priv->is_invited = FALSE; + if (priv->invitor) { + g_object_unref (priv->invitor); + priv->invitor = NULL; + } + g_free (priv->invit_message); + priv->invit_message = NULL; + + /* Add ourself in the members of the room */ + self_handle = gossip_telepathy_group_get_self_handle (priv->group); + gossip_telepathy_group_add_member (priv->group, self_handle, + "Just for fun"); +} + +void +empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom, + const gchar *topic) +{ +} + +static void +tp_chatroom_members_added_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *chatroom) +{ + EmpathyTpChatroomPriv *priv; + GList *contacts, *l; + + g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom)); + + priv = GET_PRIV (chatroom); + + contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles); + for (l = contacts; l; l = l->next) { + GossipContact *contact; + + contact = l->data; + + g_signal_emit_by_name (chatroom, "contact-added", contact); + + g_object_unref (contact); + } + g_list_free (contacts); +} + +static void +tp_chatroom_members_removed_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *chatroom) +{ +} + static void tp_chatroom_setup (EmpathyContactList *list) { + /* Nothing to do */ } static GossipContact * @@ -162,6 +307,18 @@ tp_chatroom_remove (EmpathyContactList *list, static GList * tp_chatroom_get_contacts (EmpathyContactList *list) { - return NULL; + EmpathyTpChatroomPriv *priv; + GArray *members; + GList *contacts; + + g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL); + + priv = GET_PRIV (list); + + members = gossip_telepathy_group_get_members (priv->group); + contacts = empathy_tp_contact_list_get_from_handles (priv->list, members); + g_array_free (members, TRUE); + + return contacts; } diff --git a/libempathy/empathy-tp-chatroom.h b/libempathy/empathy-tp-chatroom.h index 75ccc58c1..488ac74fb 100644 --- a/libempathy/empathy-tp-chatroom.h +++ b/libempathy/empathy-tp-chatroom.h @@ -52,10 +52,15 @@ struct _EmpathyTpChatroomClass { EmpathyTpChatClass parent_class; }; -GType empathy_tp_chatroom_get_type (void) G_GNUC_CONST; -EmpathyTpChatroom *empathy_tp_chatroom_new (McAccount *account, - TpChan *tp_chan); - +GType empathy_tp_chatroom_get_type (void) G_GNUC_CONST; +EmpathyTpChatroom *empathy_tp_chatroom_new (McAccount *account, + TpChan *tp_chan); +gboolean empathy_tp_chatroom_get_invitation (EmpathyTpChatroom *chatroom, + GossipContact **contact, + const gchar **message); +void empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom); +void empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom, + const gchar *topic); G_END_DECLS #endif /* __EMPATHY_TP_CHATROOM_H__ */ diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c index 60a7fd535..2ebb648a3 100644 --- a/libempathy/empathy-tp-contact-list.c +++ b/libempathy/empathy-tp-contact-list.c @@ -622,6 +622,11 @@ empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list, guint handle; handle = g_array_index (handles, guint, i); + + if (handle == 0) { + continue; + } + contact = g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle)); @@ -974,49 +979,34 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy, g_array_free (members, TRUE); } if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) { - GPtrArray *info; - GArray *pending; - guint i; + GList *members, *l; + GArray *pending; g_signal_connect (group, "local-pending", G_CALLBACK (tp_contact_list_local_pending_cb), list); - info = gossip_telepathy_group_get_local_pending_members_with_info (group); - - if (!info) { - /* This happens with butterfly because - * GetLocalPendingMembersWithInfo is not - * implemented */ + members = gossip_telepathy_group_get_local_pending_members_with_info (group); + if (!members) { g_object_unref (new_chan); return; } pending = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); - for (i = 0; info->len > i; i++) { - GValueArray *pending_struct; - guint member; - guint invitor; - guint reason; - const gchar *message; - - pending_struct = g_ptr_array_index (info, i); - member = g_value_get_uint (g_value_array_get_nth (pending_struct, 0)); - invitor = g_value_get_uint (g_value_array_get_nth (pending_struct, 1)); - reason = g_value_get_uint (g_value_array_get_nth (pending_struct, 2)); - message = g_value_get_string (g_value_array_get_nth (pending_struct, 3)); + for (l = members; l; l = l->next) { + GossipTpGroupInfo *info; - g_array_insert_val (pending, 0, member); + info = l->data; + g_array_insert_val (pending, 0, info->member); tp_contact_list_local_pending_cb (group, pending, - invitor, - reason, - message, list); - - g_value_array_free (pending_struct); + info->actor, + info->reason, + info->message, + list); } - g_ptr_array_free (info, TRUE); + gossip_telepathy_group_info_list_free (members); g_array_free (pending, TRUE); } } diff --git a/libempathy/gossip-telepathy-group.c b/libempathy/gossip-telepathy-group.c index 3f9998c0d..5d6bff670 100644 --- a/libempathy/gossip-telepathy-group.c +++ b/libempathy/gossip-telepathy-group.c @@ -314,11 +314,13 @@ gossip_telepathy_group_get_all_members (GossipTelepathyGroup *group, } } -GPtrArray * -gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup *group) +GList * +gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup *group) { GossipTelepathyGroupPriv *priv; - GPtrArray *info = NULL; + GPtrArray *array; + guint i; + GList *infos = NULL; GError *error = NULL; g_return_val_if_fail (GOSSIP_IS_TELEPATHY_GROUP (group), NULL); @@ -326,17 +328,62 @@ gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup priv = GET_PRIV (group); if (!tp_chan_iface_group_get_local_pending_members_with_info (priv->group_iface, - &info, + &array, &error)) { gossip_debug (DEBUG_DOMAIN, "GetLocalPendingMembersWithInfo failed: %s", error ? error->message : "No error given"); g_clear_error (&error); + + return NULL; + } + + if (!array) { + /* This happens with butterfly because + * GetLocalPendingMembersWithInfo is not + * implemented */ + return NULL; + } + + for (i = 0; array->len > i; i++) { + GValueArray *pending_struct; + GossipTpGroupInfo *info; + const gchar *message; + + info = g_slice_new (GossipTpGroupInfo); + + pending_struct = g_ptr_array_index (array, i); + info->member = g_value_get_uint (g_value_array_get_nth (pending_struct, 0)); + info->actor = g_value_get_uint (g_value_array_get_nth (pending_struct, 1)); + info->reason = g_value_get_uint (g_value_array_get_nth (pending_struct, 2)); + message = g_value_get_string (g_value_array_get_nth (pending_struct, 3)); + info->message = g_strdup (message); + g_value_array_free (pending_struct); + + infos = g_list_prepend (infos, info); } + g_ptr_array_free (array, TRUE); - return info; + return infos; } +void +gossip_telepathy_group_info_list_free (GList *infos) +{ + GList *l; + + for (l = infos; l; l = l->next) { + GossipTpGroupInfo *info; + + info = l->data; + + g_free (info->message); + g_slice_free (GossipTpGroupInfo, info); + } + g_list_free (infos); +} + + static void telepathy_group_destroy_cb (DBusGProxy *proxy, GossipTelepathyGroup *group) diff --git a/libempathy/gossip-telepathy-group.h b/libempathy/gossip-telepathy-group.h index 9c61bdbc4..17b96de2e 100644 --- a/libempathy/gossip-telepathy-group.h +++ b/libempathy/gossip-telepathy-group.h @@ -46,6 +46,13 @@ struct _GossipTelepathyGroupClass { GObjectClass parent_class; }; +typedef struct { + guint member; + guint actor; + guint reason; + gchar *message; +} GossipTpGroupInfo; + GType gossip_telepathy_group_get_type (void) G_GNUC_CONST; GossipTelepathyGroup *gossip_telepathy_group_new (TpChan *tp_chan, TpConn *tp_conn); @@ -66,8 +73,9 @@ void gossip_telepathy_group_get_all_members (GossipTelepathyGro GArray **members, GArray **local_pending, GArray **remote_pending); -GPtrArray * gossip_telepathy_group_get_local_pending_members_with_info +GList * gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup *group); +void gossip_telepathy_group_info_list_free (GList *infos); const gchar * gossip_telepathy_group_get_name (GossipTelepathyGroup *group); guint gossip_telepathy_group_get_self_handle (GossipTelepathyGroup *group); const gchar * gossip_telepathy_group_get_object_path (GossipTelepathyGroup *group); diff --git a/src/empathy-chat-main.c b/src/empathy-chat-main.c index 339c4d0fa..31918d32f 100644 --- a/src/empathy-chat-main.c +++ b/src/empathy-chat-main.c @@ -39,11 +39,10 @@ #include <libempathy/gossip-debug.h> #include <libempathy/gossip-utils.h> #include <libempathy/empathy-chandler.h> -#include <libempathy/empathy-contact-manager.h> -#include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-tp-chat.h> #include <libempathy/gossip-paths.h> #include <libempathy-gtk/gossip-private-chat.h> +#include <libempathy-gtk/gossip-group-chat.h> #define DEBUG_DOMAIN "ChatMain" @@ -115,8 +114,11 @@ new_channel_cb (EmpathyChandler *chandler, mc = gossip_mission_control_new (); account = mission_control_get_account_for_connection (mc, tp_conn, NULL); id = empathy_tp_chat_build_id (account, tp_chan); - chat = gossip_chat_window_find_chat_by_id (id); + + g_free (id); + g_object_unref (mc); + if (chat) { /* The chat already exists */ if (!gossip_chat_is_connected (chat)) { @@ -128,54 +130,32 @@ new_channel_cb (EmpathyChandler *chandler, g_object_unref (tp_chat); } gossip_chat_present (chat); + + g_object_unref (account); + return; } - else if (tp_chan->handle_type == TP_HANDLE_TYPE_CONTACT) { - EmpathyContactManager *manager; - EmpathyTpContactList *list; - GossipContact *contact; - GossipPrivateChat *chat; + if (tp_chan->handle_type == TP_HANDLE_TYPE_CONTACT) { /* We have a new private chat channel */ - manager = empathy_contact_manager_new (); - list = empathy_contact_manager_get_list (manager, account); - contact = empathy_tp_contact_list_get_from_handle (list, tp_chan->handle); - - chat = gossip_private_chat_new_with_channel (contact, tp_chan); - g_object_weak_ref (G_OBJECT (chat), - (GWeakNotify) chat_finalized_cb, - NULL); - - exit_timeout_stop (); - chat_count++; - - gossip_chat_present (GOSSIP_CHAT (chat)); - - g_object_unref (contact); - g_object_unref (chat); - g_object_unref (manager); + chat = GOSSIP_CHAT (gossip_private_chat_new (account, tp_chan)); } else if (tp_chan->handle_type == TP_HANDLE_TYPE_ROOM) { -#if 0 - GossipGroupChat *chat; - /* We have a new group chat channel */ - chat = gossip_group_chat_new (account, tp_chan); - g_object_weak_ref (G_OBJECT (chat), - (GWeakNotify) chat_finalized_cb, - NULL); + chat = GOSSIP_CHAT (gossip_group_chat_new (account, tp_chan)); + } - exit_timeout_stop (); - chat_count++; + g_object_weak_ref (G_OBJECT (chat), + (GWeakNotify) chat_finalized_cb, + NULL); - gossip_chat_present (GOSSIP_CHAT (chat)); + exit_timeout_stop (); + chat_count++; - g_object_unref (chat); -#endif - } + gossip_chat_present (GOSSIP_CHAT (chat)); - g_free (id); + g_object_unref (chat); g_object_unref (account); - g_object_unref (mc); + } int |