]> git.0d.be Git - empathy.git/blob - libempathy/empathy-tp-chatroom.c
Implementing basic chatroom support. Actually it works only if we get
[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 "gossip-telepathy-group.h"
32 #include "gossip-utils.h"
33 #include "gossip-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         GossipTelepathyGroup  *group;
44
45         gboolean               is_invited;
46         GossipContact         *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   (GossipTelepathyGroup    *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 (GossipTelepathyGroup    *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 GossipContact * tp_chatroom_find               (EmpathyContactList      *list,
68                                                        const gchar             *id);
69 static void            tp_chatroom_add                (EmpathyContactList      *list,
70                                                        GossipContact           *contact,
71                                                        const gchar             *message);
72 static void            tp_chatroom_remove             (EmpathyContactList      *list,
73                                                        GossipContact           *contact,
74                                                        const gchar             *message);
75 static GList *         tp_chatroom_get_contacts       (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_contacts = tp_chatroom_get_contacts;
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 = gossip_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 = gossip_telepathy_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 = gossip_telepathy_group_get_self_handle (priv->group);
163         members = gossip_telepathy_group_get_local_pending_members_with_info (priv->group);
164         for (l = members; l; l = l->next) {
165                 GossipTpGroupInfo *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                 gossip_debug (DEBUG_DOMAIN, "We are invited to join by %s: %s",
179                               gossip_contact_get_name (priv->invitor),
180                               priv->invit_message);
181         }
182
183         gossip_telepathy_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                                     GossipContact     **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 = gossip_telepathy_group_get_self_handle (priv->group);
232         gossip_telepathy_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 (GossipTelepathyGroup *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         g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom));
254
255         priv = GET_PRIV (chatroom);
256
257         contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
258         for (l = contacts; l; l = l->next) {
259                 GossipContact *contact;
260
261                 contact = l->data;
262
263                 g_signal_emit_by_name (chatroom, "contact-added", contact);
264
265                 g_object_unref (contact);
266         }
267         g_list_free (contacts);
268 }
269
270 static void
271 tp_chatroom_members_removed_cb (GossipTelepathyGroup *group,
272                                 GArray               *handles,
273                                 guint                 actor_handle,
274                                 guint                 reason,
275                                 const gchar          *message,
276                                 EmpathyTpChatroom    *chatroom)
277 {
278 }
279
280 static void
281 tp_chatroom_setup (EmpathyContactList *list)
282 {
283         /* Nothing to do */
284 }
285
286 static GossipContact *
287 tp_chatroom_find (EmpathyContactList *list,
288                   const gchar        *id)
289 {
290         return NULL;
291 }
292
293 static void
294 tp_chatroom_add (EmpathyContactList *list,
295                  GossipContact      *contact,
296                  const gchar        *message)
297 {
298 }
299
300 static void
301 tp_chatroom_remove (EmpathyContactList *list,
302                     GossipContact      *contact,
303                     const gchar        *message)
304 {
305 }
306
307 static GList *
308 tp_chatroom_get_contacts (EmpathyContactList *list)
309 {
310         EmpathyTpChatroomPriv *priv;
311         GArray                *members;
312         GList                 *contacts;
313
314         g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL);
315
316         priv = GET_PRIV (list);
317
318         members = gossip_telepathy_group_get_members (priv->group);
319         contacts = empathy_tp_contact_list_get_from_handles (priv->list, members);
320         g_array_free (members, TRUE);
321
322         return contacts;
323 }
324