diff options
Diffstat (limited to 'libempathy-gtk')
-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 |
6 files changed, 908 insertions, 16 deletions
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 |