1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007-2008 Collabora Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Authors: Xavier Claessens <xclaesse@gmail.com>
26 #include <telepathy-glib/channel.h>
27 #include <telepathy-glib/dbus.h>
28 #include <telepathy-glib/util.h>
30 #include <libmissioncontrol/mission-control.h>
32 #include "empathy-tp-roomlist.h"
33 #include "empathy-chatroom.h"
34 #include "empathy-utils.h"
36 #define DEBUG_FLAG EMPATHY_DEBUG_TP
37 #include "empathy-debug.h"
39 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpRoomlist)
41 TpConnection *connection;
45 } EmpathyTpRoomlistPriv;
59 static guint signals[LAST_SIGNAL];
61 G_DEFINE_TYPE (EmpathyTpRoomlist, empathy_tp_roomlist, G_TYPE_OBJECT);
64 tp_roomlist_listing_cb (TpChannel *channel,
69 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
71 DEBUG ("Listing: %s", listing ? "Yes" : "No");
72 priv->is_listing = listing;
73 g_object_notify (list, "is-listing");
77 tp_roomlist_chatrooms_free (gpointer data)
79 GSList *chatrooms = data;
81 g_slist_foreach (chatrooms, (GFunc) g_object_unref, NULL);
82 g_slist_free (chatrooms);
86 tp_roomlist_inspect_handles_cb (TpConnection *connection,
92 GSList *chatrooms = user_data;
95 DEBUG ("Error: %s", error->message);
99 while (*names != NULL) {
100 EmpathyChatroom *chatroom = chatrooms->data;
102 empathy_chatroom_set_room (chatroom, *names);
103 g_signal_emit (list, signals[NEW_ROOM], 0, chatroom);
106 chatrooms = chatrooms->next;
111 tp_roomlist_got_rooms_cb (TpChannel *channel,
112 const GPtrArray *rooms,
116 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
117 EmpathyChatroom *chatroom;
119 GArray *handles = NULL;
120 GSList *chatrooms = NULL;
122 for (i = 0; i < rooms->len; i++) {
123 const GValue *room_name_value;
124 const GValue *handle_name_value;
125 const GValue *room_members_value;
126 const GValue *room_subject_value;
127 const GValue *room_invite_value;
128 const GValue *room_password_value;
129 GValueArray *room_struct;
131 const gchar *channel_type;
134 /* Get information */
135 room_struct = g_ptr_array_index (rooms, i);
136 handle = g_value_get_uint (g_value_array_get_nth (room_struct, 0));
137 channel_type = g_value_get_string (g_value_array_get_nth (room_struct, 1));
138 info = g_value_get_boxed (g_value_array_get_nth (room_struct, 2));
139 room_name_value = g_hash_table_lookup (info, "name");
140 handle_name_value = g_hash_table_lookup (info, "handle-name");
141 room_subject_value = g_hash_table_lookup (info, "subject");
142 room_members_value = g_hash_table_lookup (info, "members");
143 room_invite_value = g_hash_table_lookup (info, "invite-only");
144 room_password_value = g_hash_table_lookup (info, "password");
146 if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)) {
150 chatroom = empathy_chatroom_new (priv->account);
152 if (room_name_value != NULL) {
153 empathy_chatroom_set_name (chatroom,
154 g_value_get_string (room_name_value));
157 if (room_members_value != NULL) {
158 empathy_chatroom_set_members_count (chatroom,
159 g_value_get_uint (room_members_value));
162 if (room_subject_value != NULL) {
163 empathy_chatroom_set_subject (chatroom,
164 g_value_get_string (room_subject_value));
167 if (room_invite_value != NULL) {
168 empathy_chatroom_set_invite_only (chatroom,
169 g_value_get_boolean (room_invite_value));
172 if (room_password_value != NULL) {
173 empathy_chatroom_set_need_password (chatroom,
174 g_value_get_boolean (room_password_value));
177 if (handle_name_value != NULL) {
178 empathy_chatroom_set_room (chatroom,
179 g_value_get_string (handle_name_value));
181 /* We have the room ID, we can directly emit it */
182 g_signal_emit (list, signals[NEW_ROOM], 0, chatroom);
183 g_object_unref (chatroom);
185 /* We don't have the room ID, we'll inspect all handles
186 * at once and then emit rooms */
187 if (handles == NULL) {
188 handles = g_array_new (FALSE, FALSE, sizeof (guint));
191 g_array_append_val (handles, handle);
192 chatrooms = g_slist_prepend (chatrooms, chatroom);
196 if (handles != NULL) {
197 chatrooms = g_slist_reverse (chatrooms);
198 tp_cli_connection_call_inspect_handles (priv->connection, -1,
201 tp_roomlist_inspect_handles_cb,
203 tp_roomlist_chatrooms_free,
205 g_array_free (handles, TRUE);
210 tp_roomlist_get_listing_rooms_cb (TpChannel *channel,
216 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
219 DEBUG ("Error geting listing rooms: %s", error->message);
223 priv->is_listing = is_listing;
224 g_object_notify (list, "is-listing");
228 tp_roomlist_invalidated_cb (TpChannel *channel,
232 EmpathyTpRoomlist *list)
234 DEBUG ("Channel invalidated: %s", message);
235 g_signal_emit (list, signals[DESTROY], 0);
239 tp_roomlist_request_channel_cb (TpConnection *connection,
240 const gchar *object_path,
245 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
248 DEBUG ("Error requesting channel: %s", error->message);
252 priv->channel = tp_channel_new (priv->connection, object_path,
253 TP_IFACE_CHANNEL_TYPE_ROOM_LIST,
256 tp_channel_run_until_ready (priv->channel, NULL, NULL);
258 g_signal_connect (priv->channel, "invalidated",
259 G_CALLBACK (tp_roomlist_invalidated_cb),
262 tp_cli_channel_type_room_list_connect_to_listing_rooms (priv->channel,
263 tp_roomlist_listing_cb,
267 tp_cli_channel_type_room_list_connect_to_got_rooms (priv->channel,
268 tp_roomlist_got_rooms_cb,
273 tp_cli_channel_type_room_list_call_get_listing_rooms (priv->channel, -1,
274 tp_roomlist_get_listing_rooms_cb,
280 tp_roomlist_finalize (GObject *object)
282 EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
285 DEBUG ("Closing channel...");
286 g_signal_handlers_disconnect_by_func (priv->channel,
287 tp_roomlist_invalidated_cb,
289 tp_cli_channel_call_close (priv->channel, -1,
290 NULL, NULL, NULL, NULL);
291 g_object_unref (priv->channel);
295 g_object_unref (priv->account);
297 if (priv->connection) {
298 g_object_unref (priv->connection);
301 G_OBJECT_CLASS (empathy_tp_roomlist_parent_class)->finalize (object);
305 tp_roomlist_constructed (GObject *list)
307 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
310 mc = empathy_mission_control_dup_singleton ();
311 priv->account = mission_control_get_account_for_tpconnection (mc,
316 tp_cli_connection_call_request_channel (priv->connection, -1,
317 TP_IFACE_CHANNEL_TYPE_ROOM_LIST,
321 tp_roomlist_request_channel_cb,
327 tp_roomlist_get_property (GObject *object,
332 EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
335 case PROP_CONNECTION:
336 g_value_set_object (value, priv->connection);
338 case PROP_IS_LISTING:
339 g_value_set_boolean (value, priv->is_listing);
342 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
348 tp_roomlist_set_property (GObject *object,
353 EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
356 case PROP_CONNECTION:
357 priv->connection = g_object_ref (g_value_get_object (value));
360 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
366 empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass)
368 GObjectClass *object_class = G_OBJECT_CLASS (klass);
370 object_class->finalize = tp_roomlist_finalize;
371 object_class->constructed = tp_roomlist_constructed;
372 object_class->get_property = tp_roomlist_get_property;
373 object_class->set_property = tp_roomlist_set_property;
375 g_object_class_install_property (object_class,
377 g_param_spec_object ("connection",
379 "The connection on which it lists rooms",
382 G_PARAM_CONSTRUCT_ONLY));
383 g_object_class_install_property (object_class,
385 g_param_spec_boolean ("is-listing",
387 "Are we listing rooms",
392 g_signal_new ("new-room",
393 G_TYPE_FROM_CLASS (klass),
397 g_cclosure_marshal_VOID__OBJECT,
399 1, EMPATHY_TYPE_CHATROOM);
402 g_signal_new ("destroy",
403 G_TYPE_FROM_CLASS (klass),
407 g_cclosure_marshal_VOID__VOID,
411 g_type_class_add_private (object_class, sizeof (EmpathyTpRoomlistPriv));
415 empathy_tp_roomlist_init (EmpathyTpRoomlist *list)
417 EmpathyTpRoomlistPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (list,
418 EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistPriv);
424 empathy_tp_roomlist_new (McAccount *account)
426 EmpathyTpRoomlist *list;
428 TpConnection *connection;
430 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
432 mc = empathy_mission_control_dup_singleton ();
433 connection = mission_control_get_tpconnection (mc, account, NULL);
435 list = g_object_new (EMPATHY_TYPE_TP_ROOMLIST,
436 "connection", connection,
440 g_object_unref (connection);
446 empathy_tp_roomlist_is_listing (EmpathyTpRoomlist *list)
448 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
450 g_return_val_if_fail (EMPATHY_IS_TP_ROOMLIST (list), FALSE);
452 return priv->is_listing;
456 empathy_tp_roomlist_start (EmpathyTpRoomlist *list)
458 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
460 g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list));
461 g_return_if_fail (TP_IS_CHANNEL (priv->channel));
463 tp_cli_channel_type_room_list_call_list_rooms (priv->channel, -1,
464 NULL, NULL, NULL, NULL);
468 empathy_tp_roomlist_stop (EmpathyTpRoomlist *list)
470 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
472 g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list));
473 g_return_if_fail (TP_IS_CHANNEL (priv->channel));
475 tp_cli_channel_type_room_list_call_stop_listing (priv->channel, -1,
476 NULL, NULL, NULL, NULL);