]> git.0d.be Git - empathy.git/blob - libempathy/empathy-tp-chatroom.c
Rename all filenames starting with "gossip" by "empathy", change namespace
[empathy.git] / libempathy / empathy-tp-chatroom.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007 Collabora Ltd.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  * 
20  * Authors: Xavier Claessens <xclaesse@gmail.com>
21  */
22
23 #include <config.h>
24
25 #include <libmissioncontrol/mission-control.h>
26
27 #include "empathy-tp-chatroom.h"
28 #include "empathy-tp-contact-list.h"
29 #include "empathy-contact-list.h"
30 #include "empathy-contact-manager.h"
31 #include "empathy-tp-group.h"
32 #include "empathy-utils.h"
33 #include "empathy-debug.h"
34
35 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
36                        EMPATHY_TYPE_TP_CHATROOM, EmpathyTpChatroomPriv))
37
38 #define DEBUG_DOMAIN "TpChatroom"
39
40 struct _EmpathyTpChatroomPriv {
41         EmpathyContactManager *manager;
42         EmpathyTpContactList  *list;
43         EmpathyTpGroup        *group;
44
45         gboolean               is_invited;
46         EmpathyContact        *invitor;
47         gchar                 *invit_message;
48 };
49
50 static void            empathy_tp_chatroom_class_init (EmpathyTpChatroomClass  *klass);
51 static void            tp_chatroom_iface_init         (EmpathyContactListIface *iface);
52 static void            empathy_tp_chatroom_init       (EmpathyTpChatroom       *chatroom);
53 static void            tp_chatroom_finalize           (GObject                 *object);
54 static void            tp_chatroom_members_added_cb   (EmpathyTpGroup          *group,
55                                                        GArray                  *handles,
56                                                        guint                    actor_handle,
57                                                        guint                    reason,
58                                                        const gchar             *message,
59                                                        EmpathyTpChatroom       *list);
60 static void            tp_chatroom_members_removed_cb (EmpathyTpGroup          *group,
61                                                        GArray                  *handles,
62                                                        guint                    actor_handle,
63                                                        guint                    reason,
64                                                        const gchar             *message,
65                                                        EmpathyTpChatroom       *list);
66 static void            tp_chatroom_setup              (EmpathyContactList      *list);
67 static EmpathyContact * tp_chatroom_find               (EmpathyContactList      *list,
68                                                        const gchar             *id);
69 static void            tp_chatroom_add                (EmpathyContactList      *list,
70                                                        EmpathyContact           *contact,
71                                                        const gchar             *message);
72 static void            tp_chatroom_remove             (EmpathyContactList      *list,
73                                                        EmpathyContact           *contact,
74                                                        const gchar             *message);
75 static GList *         tp_chatroom_get_members        (EmpathyContactList      *list);
76
77 G_DEFINE_TYPE_WITH_CODE (EmpathyTpChatroom, empathy_tp_chatroom, EMPATHY_TYPE_TP_CHAT,
78                          G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
79                                                 tp_chatroom_iface_init));
80
81 static void
82 empathy_tp_chatroom_class_init (EmpathyTpChatroomClass *klass)
83 {
84         GObjectClass *object_class = G_OBJECT_CLASS (klass);
85
86         object_class->finalize = tp_chatroom_finalize;
87
88         g_type_class_add_private (object_class, sizeof (EmpathyTpChatroomPriv));
89 }
90
91 static void
92 tp_chatroom_iface_init (EmpathyContactListIface *iface)
93 {
94         iface->setup       = tp_chatroom_setup;
95         iface->find        = tp_chatroom_find;
96         iface->add         = tp_chatroom_add;
97         iface->remove      = tp_chatroom_remove;
98         iface->get_members = tp_chatroom_get_members;
99 }
100
101 static void
102 empathy_tp_chatroom_init (EmpathyTpChatroom *chatroom)
103 {
104 }
105
106 static void
107 tp_chatroom_finalize (GObject *object)
108 {
109         EmpathyTpChatroomPriv *priv;
110         EmpathyTpChatroom     *chatroom;
111
112         chatroom = EMPATHY_TP_CHATROOM (object);
113         priv = GET_PRIV (chatroom);
114
115         g_object_unref (priv->group);
116         g_object_unref (priv->manager);
117
118         if (priv->invitor) {
119                 g_object_unref (priv->invitor);
120         }
121
122         g_free (priv->invit_message);
123
124         G_OBJECT_CLASS (empathy_tp_chatroom_parent_class)->finalize (object);
125 }
126
127 EmpathyTpChatroom *
128 empathy_tp_chatroom_new (McAccount *account,
129                          TpChan    *tp_chan)
130 {
131         EmpathyTpChatroomPriv *priv;
132         EmpathyTpChatroom     *chatroom;
133         TpConn                *tp_conn;
134         MissionControl        *mc;
135         GList                 *members, *l;
136         guint                  self_handle;
137
138         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
139         g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
140
141         chatroom = g_object_new (EMPATHY_TYPE_TP_CHATROOM,
142                                  "account", account,
143                                  "tp-chan", tp_chan,
144                                  NULL);
145
146         priv = GET_PRIV (chatroom);
147
148         mc = empathy_mission_control_new ();
149         tp_conn = mission_control_get_connection (mc, account, NULL);
150         priv->manager = empathy_contact_manager_new ();
151         priv->list = empathy_contact_manager_get_list (priv->manager, account);
152         priv->group = empathy_tp_group_new (tp_chan, tp_conn);
153
154         g_signal_connect (priv->group, "members-added",
155                           G_CALLBACK (tp_chatroom_members_added_cb),
156                           chatroom);
157         g_signal_connect (priv->group, "members-removed",
158                           G_CALLBACK (tp_chatroom_members_removed_cb),
159                           chatroom);
160
161         /* Check if we are invited to join the chat */
162         self_handle = empathy_tp_group_get_self_handle (priv->group);
163         members = empathy_tp_group_get_local_pending_members_with_info (priv->group);
164         for (l = members; l; l = l->next) {
165                 EmpathyTpGroupInfo *info;
166
167                 info = l->data;
168
169                 if (info->member != self_handle) {
170                         continue;
171                 }
172
173                 priv->invitor = empathy_tp_contact_list_get_from_handle (priv->list,
174                                                                          info->actor);
175                 priv->invit_message = g_strdup (info->message);
176                 priv->is_invited = TRUE;
177
178                 empathy_debug (DEBUG_DOMAIN, "We are invited to join by %s: %s",
179                               empathy_contact_get_name (priv->invitor),
180                               priv->invit_message);
181         }
182
183         empathy_tp_group_info_list_free (members);
184         g_object_unref (mc);
185         g_object_unref (tp_conn);
186
187         return chatroom;
188 }
189
190 gboolean
191 empathy_tp_chatroom_get_invitation (EmpathyTpChatroom  *chatroom,
192                                     EmpathyContact     **contact,
193                                     const gchar       **message)
194 {
195         EmpathyTpChatroomPriv *priv;
196
197         g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom), FALSE);
198
199         priv = GET_PRIV (chatroom);
200
201         if (*contact) {
202                 *contact = priv->invitor;
203         }
204         if (*message) {
205                 *message = priv->invit_message;
206         }
207
208         return priv->is_invited;
209 }
210
211 void
212 empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom)
213 {
214         EmpathyTpChatroomPriv *priv;
215         guint                  self_handle;
216
217         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom));
218
219         priv = GET_PRIV (chatroom);
220
221         /* Clear invitation data */
222         priv->is_invited = FALSE;
223         if (priv->invitor) {
224                 g_object_unref (priv->invitor);
225                 priv->invitor = NULL;
226         }
227         g_free (priv->invit_message);
228         priv->invit_message = NULL;
229
230         /* Add ourself in the members of the room */
231         self_handle = empathy_tp_group_get_self_handle (priv->group);
232         empathy_tp_group_add_member (priv->group, self_handle,
233                                            "Just for fun");
234 }
235
236 void
237 empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom,
238                                const gchar       *topic)
239 {
240 }
241
242 static void
243 tp_chatroom_members_added_cb (EmpathyTpGroup    *group,
244                               GArray            *handles,
245                               guint              actor_handle,
246                               guint              reason,
247                               const gchar       *message,
248                               EmpathyTpChatroom *chatroom)
249 {
250         EmpathyTpChatroomPriv *priv;
251         GList                 *contacts, *l;
252
253         priv = GET_PRIV (chatroom);
254
255         contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
256         for (l = contacts; l; l = l->next) {
257                 EmpathyContact *contact;
258
259                 contact = l->data;
260
261                 g_signal_emit_by_name (chatroom, "contact-added", contact);
262
263                 g_object_unref (contact);
264         }
265         g_list_free (contacts);
266 }
267
268 static void
269 tp_chatroom_members_removed_cb (EmpathyTpGroup    *group,
270                                 GArray            *handles,
271                                 guint              actor_handle,
272                                 guint              reason,
273                                 const gchar       *message,
274                                 EmpathyTpChatroom *chatroom)
275 {
276         EmpathyTpChatroomPriv *priv;
277         GList                 *contacts, *l;
278
279         priv = GET_PRIV (chatroom);
280
281         contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
282         for (l = contacts; l; l = l->next) {
283                 EmpathyContact *contact;
284
285                 contact = l->data;
286
287                 g_signal_emit_by_name (chatroom, "contact-removed", contact);
288
289                 g_object_unref (contact);
290         }
291         g_list_free (contacts);
292 }
293
294 static void
295 tp_chatroom_setup (EmpathyContactList *list)
296 {
297         /* Nothing to do */
298 }
299
300 static EmpathyContact *
301 tp_chatroom_find (EmpathyContactList *list,
302                   const gchar        *id)
303 {
304         return NULL;
305 }
306
307 static void
308 tp_chatroom_add (EmpathyContactList *list,
309                  EmpathyContact     *contact,
310                  const gchar        *message)
311 {
312         EmpathyTpChatroomPriv *priv;
313
314         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (list));
315         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
316
317         priv = GET_PRIV (list);
318
319         empathy_tp_group_add_member (priv->group,
320                                      empathy_contact_get_handle (contact),
321                                      message);
322 }
323
324 static void
325 tp_chatroom_remove (EmpathyContactList *list,
326                     EmpathyContact     *contact,
327                     const gchar        *message)
328 {
329         EmpathyTpChatroomPriv *priv;
330
331         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (list));
332         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
333
334         priv = GET_PRIV (list);
335
336         empathy_tp_group_remove_member (priv->group,
337                                         empathy_contact_get_handle (contact),
338                                         message);
339 }
340
341 static GList *
342 tp_chatroom_get_members (EmpathyContactList *list)
343 {
344         EmpathyTpChatroomPriv *priv;
345         GArray                *members;
346         GList                 *contacts;
347
348         g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL);
349
350         priv = GET_PRIV (list);
351
352         members = empathy_tp_group_get_members (priv->group);
353         contacts = empathy_tp_contact_list_get_from_handles (priv->list, members);
354         g_array_free (members, TRUE);
355
356         return contacts;
357 }
358