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>
29 #include <libmissioncontrol/mission-control.h>
31 #include "empathy-tp-roomlist.h"
32 #include "empathy-chatroom.h"
33 #include "empathy-utils.h"
34 #include "empathy-debug.h"
36 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
37 EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistPriv))
39 #define DEBUG_DOMAIN "TpRoomlist"
41 struct _EmpathyTpRoomlistPriv {
42 TpConnection *connection;
48 static void empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass);
49 static void empathy_tp_roomlist_init (EmpathyTpRoomlist *chat);
63 static guint signals[LAST_SIGNAL];
65 G_DEFINE_TYPE (EmpathyTpRoomlist, empathy_tp_roomlist, G_TYPE_OBJECT);
68 tp_roomlist_listing_cb (TpChannel *channel,
73 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
75 empathy_debug (DEBUG_DOMAIN, "Listing: %s", listing ? "Yes" : "No");
76 priv->is_listing = listing;
77 g_object_notify (list, "is-listing");
81 tp_roomlist_got_rooms_cb (TpChannel *channel,
82 const GPtrArray *rooms,
86 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
92 names = g_new0 (const gchar*, rooms->len + 1);
93 handles = g_array_sized_new (FALSE, FALSE, sizeof (guint), rooms->len);
94 for (i = 0; i < rooms->len; i++) {
95 const GValue *room_name_value;
96 GValueArray *room_struct;
100 /* Get information */
101 room_struct = g_ptr_array_index (rooms, i);
102 handle = g_value_get_uint (g_value_array_get_nth (room_struct, 0));
103 info = g_value_get_boxed (g_value_array_get_nth (room_struct, 2));
104 room_name_value = g_hash_table_lookup (info, "name");
106 names[i] = g_value_get_string (room_name_value);
107 g_array_append_val (handles, handle);
110 tp_cli_connection_run_inspect_handles (priv->connection, -1,
115 for (i = 0; i < handles->len; i++) {
116 EmpathyChatroom *chatroom;
118 chatroom = empathy_chatroom_new_full (priv->account,
122 g_signal_emit (list, signals[NEW_ROOM], 0, chatroom);
123 g_object_unref (chatroom);
124 g_free (room_ids[i]);
129 g_array_free (handles, TRUE);
133 tp_roomlist_get_listing_rooms_cb (TpChannel *channel,
139 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
142 empathy_debug (DEBUG_DOMAIN, "Error geting listing rooms: %s",
147 priv->is_listing = is_listing;
148 g_object_notify (list, "is-listing");
152 tp_roomlist_invalidated_cb (TpChannel *channel,
156 EmpathyTpRoomlist *list)
158 empathy_debug (DEBUG_DOMAIN, "Channel invalidated: %s", message);
159 g_signal_emit (list, signals[DESTROY], 0);
163 tp_roomlist_request_channel_cb (TpConnection *connection,
164 const gchar *object_path,
169 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
172 empathy_debug (DEBUG_DOMAIN, "Error requesting channel: %s",
177 priv->channel = tp_channel_new (priv->connection, object_path,
178 TP_IFACE_CHANNEL_TYPE_ROOM_LIST,
181 tp_channel_run_until_ready (priv->channel, NULL, NULL);
183 g_signal_connect (priv->channel, "invalidated",
184 G_CALLBACK (tp_roomlist_invalidated_cb),
187 tp_cli_channel_type_room_list_connect_to_listing_rooms (priv->channel,
188 tp_roomlist_listing_cb,
192 tp_cli_channel_type_room_list_connect_to_got_rooms (priv->channel,
193 tp_roomlist_got_rooms_cb,
198 tp_cli_channel_type_room_list_call_get_listing_rooms (priv->channel, -1,
199 tp_roomlist_get_listing_rooms_cb,
205 tp_roomlist_finalize (GObject *object)
207 EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
210 empathy_debug (DEBUG_DOMAIN, "Closing channel...");
211 g_signal_handlers_disconnect_by_func (priv->channel,
212 tp_roomlist_invalidated_cb,
214 tp_cli_channel_call_close (priv->channel, -1,
215 NULL, NULL, NULL, NULL);
216 g_object_unref (priv->channel);
220 g_object_unref (priv->account);
222 if (priv->connection) {
223 g_object_unref (priv->connection);
226 G_OBJECT_CLASS (empathy_tp_roomlist_parent_class)->finalize (object);
230 tp_roomlist_constructed (GObject *list)
232 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
235 mc = empathy_mission_control_new ();
236 priv->account = mission_control_get_account_for_tpconnection (mc,
241 tp_cli_connection_call_request_channel (priv->connection, -1,
242 TP_IFACE_CHANNEL_TYPE_ROOM_LIST,
246 tp_roomlist_request_channel_cb,
252 tp_roomlist_get_property (GObject *object,
257 EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
260 case PROP_CONNECTION:
261 g_value_set_object (value, priv->connection);
263 case PROP_IS_LISTING:
264 g_value_set_boolean (value, priv->is_listing);
267 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
273 tp_roomlist_set_property (GObject *object,
278 EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
281 case PROP_CONNECTION:
282 priv->connection = g_object_ref (g_value_get_object (value));
285 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
291 empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass)
293 GObjectClass *object_class = G_OBJECT_CLASS (klass);
295 object_class->finalize = tp_roomlist_finalize;
296 object_class->constructed = tp_roomlist_constructed;
297 object_class->get_property = tp_roomlist_get_property;
298 object_class->set_property = tp_roomlist_set_property;
300 g_object_class_install_property (object_class,
302 g_param_spec_object ("connection",
304 "The connection on which it lists rooms",
307 G_PARAM_CONSTRUCT_ONLY));
308 g_object_class_install_property (object_class,
310 g_param_spec_boolean ("is-listing",
312 "Are we listing rooms",
317 g_signal_new ("new-room",
318 G_TYPE_FROM_CLASS (klass),
322 g_cclosure_marshal_VOID__OBJECT,
324 1, EMPATHY_TYPE_CHATROOM);
327 g_signal_new ("destroy",
328 G_TYPE_FROM_CLASS (klass),
332 g_cclosure_marshal_VOID__VOID,
336 g_type_class_add_private (object_class, sizeof (EmpathyTpRoomlistPriv));
340 empathy_tp_roomlist_init (EmpathyTpRoomlist *list)
345 empathy_tp_roomlist_new (McAccount *account)
347 EmpathyTpRoomlist *list;
349 TpConnection *connection;
351 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
353 mc = empathy_mission_control_new ();
354 connection = mission_control_get_tpconnection (mc, account, NULL);
356 list = g_object_new (EMPATHY_TYPE_TP_ROOMLIST,
357 "connection", connection,
361 g_object_unref (connection);
367 empathy_tp_roomlist_is_listing (EmpathyTpRoomlist *list)
369 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
371 g_return_val_if_fail (EMPATHY_IS_TP_ROOMLIST (list), FALSE);
373 return priv->is_listing;
377 empathy_tp_roomlist_start (EmpathyTpRoomlist *list)
379 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
381 g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list));
382 g_return_if_fail (TP_IS_CHANNEL (priv->channel));
384 tp_cli_channel_type_room_list_call_list_rooms (priv->channel, -1,
390 empathy_tp_roomlist_stop (EmpathyTpRoomlist *list)
392 EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
394 g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list));
395 g_return_if_fail (TP_IS_CHANNEL (priv->channel));
397 tp_cli_channel_type_room_list_call_stop_listing (priv->channel, -1,