]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-private-chat.c
Rename all filenames starting with "gossip" by "empathy", change namespace
[empathy.git] / libempathy-gtk / empathy-private-chat.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2002-2007 Imendio AB
4  * Copyright (C) 2007 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Mikael Hallendal <micke@imendio.com>
22  *          Richard Hult <richard@imendio.com>
23  *          Martyn Russell <martyn@imendio.com>
24  *          Geert-Jan Van den Bogaerde <geertjan@gnome.org>
25  *          Xavier Claessens <xclaesse@gmail.com>
26  */
27
28 #include "config.h"
29
30 #include <string.h>
31
32 #include <gtk/gtk.h>
33 #include <glade/glade.h>
34 #include <glib/gi18n.h>
35
36 #include <libempathy/empathy-debug.h>
37 #include <libempathy/empathy-tp-chat.h>
38 #include <libempathy/empathy-tp-contact-list.h>
39 #include <libempathy/empathy-contact-manager.h>
40 //#include <libempathy/empathy-log.h>
41
42 #include "empathy-private-chat.h"
43 #include "empathy-chat-view.h"
44 #include "empathy-chat.h"
45 #include "empathy-preferences.h"
46 //#include "empathy-sound.h"
47 #include "empathy-images.h"
48 #include "empathy-ui-utils.h"
49
50 #define DEBUG_DOMAIN "PrivateChat"
51
52 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_PRIVATE_CHAT, EmpathyPrivateChatPriv))
53
54 struct _EmpathyPrivateChatPriv {   
55         EmpathyContact *contact;
56         gchar         *name;
57
58         gboolean       is_online;
59
60         GtkWidget     *widget;
61         GtkWidget     *text_view_sw;
62 };
63
64 static void           empathy_private_chat_class_init            (EmpathyPrivateChatClass *klass);
65 static void           empathy_private_chat_init                  (EmpathyPrivateChat      *chat);
66 static void           private_chat_finalize                     (GObject                *object);
67 static void           private_chat_create_ui                    (EmpathyPrivateChat      *chat);
68 static void           private_chat_contact_presence_updated_cb  (EmpathyContact          *contact,
69                                                                  GParamSpec             *param,
70                                                                  EmpathyPrivateChat      *chat);
71 static void           private_chat_contact_updated_cb           (EmpathyContact          *contact,
72                                                                  GParamSpec             *param,
73                                                                  EmpathyPrivateChat      *chat);
74 static void           private_chat_widget_destroy_cb            (GtkWidget              *widget,
75                                                                  EmpathyPrivateChat      *chat);
76 static const gchar *  private_chat_get_name                     (EmpathyChat             *chat);
77 static gchar *        private_chat_get_tooltip                  (EmpathyChat             *chat);
78 static const gchar *  private_chat_get_status_icon_name         (EmpathyChat             *chat);
79 static GtkWidget *    private_chat_get_widget                   (EmpathyChat             *chat);
80
81 G_DEFINE_TYPE (EmpathyPrivateChat, empathy_private_chat, EMPATHY_TYPE_CHAT);
82
83 static void
84 empathy_private_chat_class_init (EmpathyPrivateChatClass *klass)
85 {
86         GObjectClass    *object_class = G_OBJECT_CLASS (klass);
87         EmpathyChatClass *chat_class = EMPATHY_CHAT_CLASS (klass);
88
89         object_class->finalize = private_chat_finalize;
90
91         chat_class->get_name             = private_chat_get_name;
92         chat_class->get_tooltip          = private_chat_get_tooltip;
93         chat_class->get_status_icon_name = private_chat_get_status_icon_name;
94         chat_class->get_widget           = private_chat_get_widget;
95         chat_class->set_tp_chat          = NULL;
96
97         g_type_class_add_private (object_class, sizeof (EmpathyPrivateChatPriv));
98 }
99
100 static void
101 empathy_private_chat_init (EmpathyPrivateChat *chat)
102 {
103         EmpathyPrivateChatPriv *priv;
104
105         priv = GET_PRIV (chat);
106
107         priv->is_online = FALSE;
108
109         private_chat_create_ui (chat);
110 }
111
112 static void
113 private_chat_finalize (GObject *object)
114 {
115         EmpathyPrivateChat     *chat;
116         EmpathyPrivateChatPriv *priv;
117         
118         chat = EMPATHY_PRIVATE_CHAT (object);
119         priv = GET_PRIV (chat);
120
121         g_signal_handlers_disconnect_by_func (priv->contact,
122                                               private_chat_contact_updated_cb,
123                                               chat);
124         g_signal_handlers_disconnect_by_func (priv->contact,
125                                               private_chat_contact_presence_updated_cb,
126                                               chat);
127
128         if (priv->contact) {
129                 g_object_unref (priv->contact);
130         }
131
132         g_free (priv->name);
133
134         G_OBJECT_CLASS (empathy_private_chat_parent_class)->finalize (object);
135 }
136
137 static void
138 private_chat_create_ui (EmpathyPrivateChat *chat)
139 {
140         GladeXML              *glade;
141         EmpathyPrivateChatPriv *priv;
142         GtkWidget             *input_text_view_sw;
143
144         priv = GET_PRIV (chat);
145
146         glade = empathy_glade_get_file ("empathy-chat.glade",
147                                        "chat_widget",
148                                        NULL,
149                                       "chat_widget", &priv->widget,
150                                       "chat_view_sw", &priv->text_view_sw,
151                                       "input_text_view_sw", &input_text_view_sw,
152                                        NULL);
153
154         empathy_glade_connect (glade,
155                               chat,
156                               "chat_widget", "destroy", private_chat_widget_destroy_cb,
157                               NULL);
158
159         g_object_unref (glade);
160
161         g_object_set_data (G_OBJECT (priv->widget), "chat", g_object_ref (chat));
162
163         gtk_container_add (GTK_CONTAINER (priv->text_view_sw),
164                            GTK_WIDGET (EMPATHY_CHAT (chat)->view));
165         gtk_widget_show (GTK_WIDGET (EMPATHY_CHAT (chat)->view));
166
167         gtk_container_add (GTK_CONTAINER (input_text_view_sw),
168                            EMPATHY_CHAT (chat)->input_text_view);
169         gtk_widget_show (EMPATHY_CHAT (chat)->input_text_view);
170 }
171
172 static void
173 private_chat_contact_presence_updated_cb (EmpathyContact     *contact,
174                                           GParamSpec        *param,
175                                           EmpathyPrivateChat *chat)
176 {
177         EmpathyPrivateChatPriv *priv;
178
179         priv = GET_PRIV (chat);
180
181         empathy_debug (DEBUG_DOMAIN, "Presence update for contact: %s",
182                       empathy_contact_get_id (contact));
183
184         if (!empathy_contact_is_online (contact)) {
185                 if (priv->is_online) {
186                         gchar *msg;
187
188                         msg = g_strdup_printf (_("%s went offline"),
189                                                empathy_contact_get_name (priv->contact));
190                         empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, msg);
191                         g_free (msg);
192                 }
193
194                 priv->is_online = FALSE;
195
196                 g_signal_emit_by_name (chat, "composing", FALSE);
197
198         } else {
199                 if (!priv->is_online) {
200                         gchar *msg;
201
202                         msg = g_strdup_printf (_("%s has come online"),
203                                                empathy_contact_get_name (priv->contact));
204                         empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, msg);
205                         g_free (msg);
206                 }
207
208                 priv->is_online = TRUE;
209         }
210
211         g_signal_emit_by_name (chat, "status-changed");
212 }
213
214 static void
215 private_chat_contact_updated_cb (EmpathyContact     *contact,
216                                  GParamSpec        *param,
217                                  EmpathyPrivateChat *chat)
218 {
219         EmpathyPrivateChatPriv *priv;
220
221         priv = GET_PRIV (chat);
222
223         if (strcmp (priv->name, empathy_contact_get_name (contact)) != 0) {
224                 g_free (priv->name);
225                 priv->name = g_strdup (empathy_contact_get_name (contact));
226                 g_signal_emit_by_name (chat, "name-changed", priv->name);
227         }
228 }
229
230 static void
231 private_chat_widget_destroy_cb (GtkWidget         *widget,
232                                 EmpathyPrivateChat *chat)
233 {
234         empathy_debug (DEBUG_DOMAIN, "Destroyed");
235
236         g_object_unref (chat);
237 }
238
239 static const gchar *
240 private_chat_get_name (EmpathyChat *chat)
241 {
242         EmpathyPrivateChatPriv *priv;
243
244         g_return_val_if_fail (EMPATHY_IS_PRIVATE_CHAT (chat), NULL);
245
246         priv = GET_PRIV (chat);
247
248         return priv->name;
249 }
250
251 static gchar *
252 private_chat_get_tooltip (EmpathyChat *chat)
253 {
254         EmpathyPrivateChatPriv *priv;
255         const gchar           *status;
256
257         g_return_val_if_fail (EMPATHY_IS_PRIVATE_CHAT (chat), NULL);
258
259         priv = GET_PRIV (chat);
260
261         status = empathy_contact_get_status (priv->contact);
262
263         return g_strdup_printf ("%s\n%s",
264                                 empathy_contact_get_id (priv->contact),
265                                 status);
266 }
267
268 static const gchar *
269 private_chat_get_status_icon_name (EmpathyChat *chat)
270 {
271         EmpathyPrivateChatPriv *priv;
272
273         g_return_val_if_fail (EMPATHY_IS_PRIVATE_CHAT (chat), NULL);
274
275         priv = GET_PRIV (chat);
276
277         return empathy_icon_name_for_contact (priv->contact);
278 }
279
280 EmpathyContact *
281 empathy_private_chat_get_contact (EmpathyPrivateChat *chat)
282 {
283         EmpathyPrivateChatPriv *priv;
284
285         g_return_val_if_fail (EMPATHY_IS_PRIVATE_CHAT (chat), NULL);
286
287         priv = GET_PRIV (chat);
288
289         return priv->contact;
290 }
291
292 static GtkWidget *
293 private_chat_get_widget (EmpathyChat *chat)
294 {
295         EmpathyPrivateChatPriv *priv;
296
297         priv = GET_PRIV (chat);
298
299         return priv->widget;
300 }
301
302 static void
303 private_chat_setup (EmpathyPrivateChat *chat,
304                     EmpathyContact     *contact,
305                     EmpathyTpChat     *tp_chat)
306 {
307         EmpathyPrivateChatPriv *priv;
308
309         priv = GET_PRIV (chat);
310
311         EMPATHY_CHAT (chat)->account = g_object_ref (empathy_contact_get_account (contact));
312         priv->contact = g_object_ref (contact);
313         priv->name = g_strdup (empathy_contact_get_name (contact));
314
315         empathy_chat_set_tp_chat (EMPATHY_CHAT (chat), tp_chat);
316
317         g_signal_connect (priv->contact, 
318                           "notify::name",
319                           G_CALLBACK (private_chat_contact_updated_cb),
320                           chat);
321         g_signal_connect (priv->contact, 
322                           "notify::presence",
323                           G_CALLBACK (private_chat_contact_presence_updated_cb),
324                           chat);
325
326         priv->is_online = empathy_contact_is_online (priv->contact);
327 }
328
329 EmpathyPrivateChat *
330 empathy_private_chat_new (McAccount *account,
331                          TpChan    *tp_chan)
332 {
333         EmpathyPrivateChat     *chat;
334         EmpathyTpChat         *tp_chat;
335         EmpathyContactManager *manager;
336         EmpathyTpContactList  *list;
337         EmpathyContact         *contact;
338
339         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
340         g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
341
342         manager = empathy_contact_manager_new ();
343         list = empathy_contact_manager_get_list (manager, account);
344         contact = empathy_tp_contact_list_get_from_handle (list, tp_chan->handle);
345
346         chat = g_object_new (EMPATHY_TYPE_PRIVATE_CHAT, NULL);
347         tp_chat = empathy_tp_chat_new (account, tp_chan);
348
349         private_chat_setup (chat, contact, tp_chat);
350
351         g_object_unref (tp_chat);
352         g_object_unref (contact);
353         g_object_unref (manager);
354
355         return chat;
356 }
357
358 EmpathyPrivateChat *
359 empathy_private_chat_new_with_contact (EmpathyContact *contact)
360 {
361         EmpathyPrivateChat *chat;
362         EmpathyTpChat     *tp_chat;
363
364         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
365
366         chat = g_object_new (EMPATHY_TYPE_PRIVATE_CHAT, NULL);
367         tp_chat = empathy_tp_chat_new_with_contact (contact);
368
369         private_chat_setup (chat, contact, tp_chat);
370         g_object_unref (tp_chat);
371
372         return chat;
373 }
374