]> git.0d.be Git - empathy.git/blob - libempathy/empathy-tp-chatroom.c
Initial room list support. It does not works yet.
[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 "empathy-tp-chatroom.h"
26 #include "empathy-tp-contact-list.h"
27 #include "empathy-contact-list.h"
28 #include "empathy-contact-manager.h"
29 #include "empathy-tp-group.h"
30 #include "empathy-utils.h"
31 #include "empathy-debug.h"
32
33 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
34                        EMPATHY_TYPE_TP_CHATROOM, EmpathyTpChatroomPriv))
35
36 #define DEBUG_DOMAIN "TpChatroom"
37
38 struct _EmpathyTpChatroomPriv {
39         EmpathyContactManager *manager;
40         EmpathyTpContactList  *list;
41         EmpathyTpGroup        *group;
42
43         gboolean               is_invited;
44         EmpathyContact        *invitor;
45         gchar                 *invit_message;
46 };
47
48 static void            empathy_tp_chatroom_class_init (EmpathyTpChatroomClass  *klass);
49 static void            tp_chatroom_iface_init         (EmpathyContactListIface *iface);
50 static void            empathy_tp_chatroom_init       (EmpathyTpChatroom       *chatroom);
51 static void            tp_chatroom_finalize           (GObject                 *object);
52 static void            tp_chatroom_members_added_cb   (EmpathyTpGroup          *group,
53                                                        GArray                  *handles,
54                                                        guint                    actor_handle,
55                                                        guint                    reason,
56                                                        const gchar             *message,
57                                                        EmpathyTpChatroom       *list);
58 static void            tp_chatroom_members_removed_cb (EmpathyTpGroup          *group,
59                                                        GArray                  *handles,
60                                                        guint                    actor_handle,
61                                                        guint                    reason,
62                                                        const gchar             *message,
63                                                        EmpathyTpChatroom       *list);
64 static void            tp_chatroom_setup              (EmpathyContactList      *list);
65 static EmpathyContact * tp_chatroom_find               (EmpathyContactList      *list,
66                                                        const gchar             *id);
67 static void            tp_chatroom_add                (EmpathyContactList      *list,
68                                                        EmpathyContact           *contact,
69                                                        const gchar             *message);
70 static void            tp_chatroom_remove             (EmpathyContactList      *list,
71                                                        EmpathyContact           *contact,
72                                                        const gchar             *message);
73 static GList *         tp_chatroom_get_members        (EmpathyContactList      *list);
74
75 G_DEFINE_TYPE_WITH_CODE (EmpathyTpChatroom, empathy_tp_chatroom, EMPATHY_TYPE_TP_CHAT,
76                          G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
77                                                 tp_chatroom_iface_init));
78
79 static void
80 empathy_tp_chatroom_class_init (EmpathyTpChatroomClass *klass)
81 {
82         GObjectClass *object_class = G_OBJECT_CLASS (klass);
83
84         object_class->finalize = tp_chatroom_finalize;
85
86         g_type_class_add_private (object_class, sizeof (EmpathyTpChatroomPriv));
87 }
88
89 static void
90 tp_chatroom_iface_init (EmpathyContactListIface *iface)
91 {
92         iface->setup       = tp_chatroom_setup;
93         iface->find        = tp_chatroom_find;
94         iface->add         = tp_chatroom_add;
95         iface->remove      = tp_chatroom_remove;
96         iface->get_members = tp_chatroom_get_members;
97 }
98
99 static void
100 empathy_tp_chatroom_init (EmpathyTpChatroom *chatroom)
101 {
102 }
103
104 static void
105 tp_chatroom_finalize (GObject *object)
106 {
107         EmpathyTpChatroomPriv *priv;
108         EmpathyTpChatroom     *chatroom;
109
110         chatroom = EMPATHY_TP_CHATROOM (object);
111         priv = GET_PRIV (chatroom);
112
113         g_object_unref (priv->group);
114         g_object_unref (priv->manager);
115
116         if (priv->invitor) {
117                 g_object_unref (priv->invitor);
118         }
119
120         g_free (priv->invit_message);
121
122         G_OBJECT_CLASS (empathy_tp_chatroom_parent_class)->finalize (object);
123 }
124
125 EmpathyTpChatroom *
126 empathy_tp_chatroom_new (McAccount *account,
127                          TpChan    *tp_chan)
128 {
129         EmpathyTpChatroomPriv *priv;
130         EmpathyTpChatroom     *chatroom;
131         GList                 *members, *l;
132         guint                  self_handle;
133
134         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
135         g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
136
137         chatroom = g_object_new (EMPATHY_TYPE_TP_CHATROOM,
138                                  "account", account,
139                                  "tp-chan", tp_chan,
140                                  NULL);
141
142         priv = GET_PRIV (chatroom);
143
144         priv->manager = empathy_contact_manager_new ();
145         priv->list = empathy_contact_manager_get_list (priv->manager, account);
146         priv->group = empathy_tp_group_new (account, tp_chan);
147
148         g_signal_connect (priv->group, "members-added",
149                           G_CALLBACK (tp_chatroom_members_added_cb),
150                           chatroom);
151         g_signal_connect (priv->group, "members-removed",
152                           G_CALLBACK (tp_chatroom_members_removed_cb),
153                           chatroom);
154
155         /* Check if we are invited to join the chat */
156         self_handle = empathy_tp_group_get_self_handle (priv->group);
157         members = empathy_tp_group_get_local_pending_members_with_info (priv->group);
158         for (l = members; l; l = l->next) {
159                 EmpathyTpGroupInfo *info;
160
161                 info = l->data;
162
163                 if (info->member != self_handle) {
164                         continue;
165                 }
166
167                 priv->invitor = empathy_tp_contact_list_get_from_handle (priv->list,
168                                                                          info->actor);
169                 priv->invit_message = g_strdup (info->message);
170                 priv->is_invited = TRUE;
171
172                 empathy_debug (DEBUG_DOMAIN, "We are invited to join by %s: %s",
173                               empathy_contact_get_name (priv->invitor),
174                               priv->invit_message);
175         }
176
177         empathy_tp_group_info_list_free (members);
178
179         return chatroom;
180 }
181
182 gboolean
183 empathy_tp_chatroom_get_invitation (EmpathyTpChatroom  *chatroom,
184                                     EmpathyContact     **contact,
185                                     const gchar       **message)
186 {
187         EmpathyTpChatroomPriv *priv;
188
189         g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom), FALSE);
190
191         priv = GET_PRIV (chatroom);
192
193         if (*contact) {
194                 *contact = priv->invitor;
195         }
196         if (*message) {
197                 *message = priv->invit_message;
198         }
199
200         return priv->is_invited;
201 }
202
203 void
204 empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom)
205 {
206         EmpathyTpChatroomPriv *priv;
207         guint                  self_handle;
208
209         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom));
210
211         priv = GET_PRIV (chatroom);
212
213         /* Clear invitation data */
214         priv->is_invited = FALSE;
215         if (priv->invitor) {
216                 g_object_unref (priv->invitor);
217                 priv->invitor = NULL;
218         }
219         g_free (priv->invit_message);
220         priv->invit_message = NULL;
221
222         /* Add ourself in the members of the room */
223         self_handle = empathy_tp_group_get_self_handle (priv->group);
224         empathy_tp_group_add_member (priv->group, self_handle,
225                                            "Just for fun");
226 }
227
228 void
229 empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom,
230                                const gchar       *topic)
231 {
232 }
233
234 static void
235 tp_chatroom_members_added_cb (EmpathyTpGroup    *group,
236                               GArray            *handles,
237                               guint              actor_handle,
238                               guint              reason,
239                               const gchar       *message,
240                               EmpathyTpChatroom *chatroom)
241 {
242         EmpathyTpChatroomPriv *priv;
243         GList                 *contacts, *l;
244
245         priv = GET_PRIV (chatroom);
246
247         contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
248         for (l = contacts; l; l = l->next) {
249                 EmpathyContact *contact;
250
251                 contact = l->data;
252
253                 g_signal_emit_by_name (chatroom, "contact-added", contact);
254
255                 g_object_unref (contact);
256         }
257         g_list_free (contacts);
258 }
259
260 static void
261 tp_chatroom_members_removed_cb (EmpathyTpGroup    *group,
262                                 GArray            *handles,
263                                 guint              actor_handle,
264                                 guint              reason,
265                                 const gchar       *message,
266                                 EmpathyTpChatroom *chatroom)
267 {
268         EmpathyTpChatroomPriv *priv;
269         GList                 *contacts, *l;
270
271         priv = GET_PRIV (chatroom);
272
273         contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
274         for (l = contacts; l; l = l->next) {
275                 EmpathyContact *contact;
276
277                 contact = l->data;
278
279                 g_signal_emit_by_name (chatroom, "contact-removed", contact);
280
281                 g_object_unref (contact);
282         }
283         g_list_free (contacts);
284 }
285
286 static void
287 tp_chatroom_setup (EmpathyContactList *list)
288 {
289         /* Nothing to do */
290 }
291
292 static EmpathyContact *
293 tp_chatroom_find (EmpathyContactList *list,
294                   const gchar        *id)
295 {
296         return NULL;
297 }
298
299 static void
300 tp_chatroom_add (EmpathyContactList *list,
301                  EmpathyContact     *contact,
302                  const gchar        *message)
303 {
304         EmpathyTpChatroomPriv *priv;
305
306         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (list));
307         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
308
309         priv = GET_PRIV (list);
310
311         empathy_tp_group_add_member (priv->group,
312                                      empathy_contact_get_handle (contact),
313                                      message);
314 }
315
316 static void
317 tp_chatroom_remove (EmpathyContactList *list,
318                     EmpathyContact     *contact,
319                     const gchar        *message)
320 {
321         EmpathyTpChatroomPriv *priv;
322
323         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (list));
324         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
325
326         priv = GET_PRIV (list);
327
328         empathy_tp_group_remove_member (priv->group,
329                                         empathy_contact_get_handle (contact),
330                                         message);
331 }
332
333 static GList *
334 tp_chatroom_get_members (EmpathyContactList *list)
335 {
336         EmpathyTpChatroomPriv *priv;
337         GArray                *members;
338         GList                 *contacts;
339
340         g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL);
341
342         priv = GET_PRIV (list);
343
344         members = empathy_tp_group_get_members (priv->group);
345         contacts = empathy_tp_contact_list_get_from_handles (priv->list, members);
346         g_array_free (members, TRUE);
347
348         return contacts;
349 }
350