]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-tp-roomlist.c
Merge branch 'master' into tp-tube
[empathy.git] / libempathy / empathy-tp-roomlist.c
index 4193685dc994236cb9dc9094f63e4087bb126326..fc2526fd0d6a422875517df13859423b8573aa2f 100644 (file)
 
 #include <telepathy-glib/channel.h>
 #include <telepathy-glib/dbus.h>
+#include <telepathy-glib/util.h>
 
 #include <libmissioncontrol/mission-control.h>
 
 #include "empathy-tp-roomlist.h"
 #include "empathy-chatroom.h"
 #include "empathy-utils.h"
-#include "empathy-debug.h"
-
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-                      EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistPriv))
 
-#define DEBUG_DOMAIN "TpRoomlist"
+#define DEBUG_FLAG EMPATHY_DEBUG_TP
+#include "empathy-debug.h"
 
-struct _EmpathyTpRoomlistPriv {
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpRoomlist)
+typedef struct {
        TpConnection *connection;
        TpChannel    *channel;
        McAccount    *account;
        gboolean      is_listing;
-};
-
-static void empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass);
-static void empathy_tp_roomlist_init       (EmpathyTpRoomlist      *chat);
+} EmpathyTpRoomlistPriv;
 
 enum {
        NEW_ROOM,
@@ -72,11 +68,45 @@ tp_roomlist_listing_cb (TpChannel *channel,
 {
        EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
 
-       empathy_debug (DEBUG_DOMAIN, "Listing: %s", listing ? "Yes" : "No");
+       DEBUG ("Listing: %s", listing ? "Yes" : "No");
        priv->is_listing = listing;
        g_object_notify (list, "is-listing");
 }
 
+static void
+tp_roomlist_chatrooms_free (gpointer data)
+{
+       GSList *chatrooms = data;
+
+       g_slist_foreach (chatrooms, (GFunc) g_object_unref, NULL);
+       g_slist_free (chatrooms);
+}
+
+static void
+tp_roomlist_inspect_handles_cb (TpConnection *connection,
+                               const gchar **names,
+                               const GError *error,
+                               gpointer      user_data,
+                               GObject      *list)
+{
+       GSList *chatrooms = user_data;
+
+       if (error != NULL) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
+
+       while (*names != NULL) {
+               EmpathyChatroom *chatroom = chatrooms->data;
+
+               empathy_chatroom_set_room (chatroom, *names);
+               g_signal_emit (list, signals[NEW_ROOM], 0, chatroom);
+
+               names++;
+               chatrooms = chatrooms->next;
+       }
+}
+
 static void
 tp_roomlist_got_rooms_cb (TpChannel       *channel,
                          const GPtrArray *rooms,
@@ -84,49 +114,96 @@ tp_roomlist_got_rooms_cb (TpChannel       *channel,
                          GObject         *list)
 {
        EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
+       EmpathyChatroom       *chatroom;
        guint                  i;
-       const gchar          **names;
-       gchar                **room_ids;
-       GArray                *handles;
+       GArray                *handles = NULL;
+       GSList                *chatrooms = NULL;
 
-       names = g_new0 (const gchar*, rooms->len + 1);
-       handles = g_array_sized_new (FALSE, FALSE, sizeof (guint), rooms->len);
        for (i = 0; i < rooms->len; i++) {
                const GValue *room_name_value;
+               const GValue *handle_name_value;
+               const GValue *room_members_value;
+               const GValue *room_subject_value;
+               const GValue *room_invite_value;
+               const GValue *room_password_value;
                GValueArray  *room_struct;
                guint         handle;
+               const gchar  *channel_type;
                GHashTable   *info;
 
                /* Get information */
                room_struct = g_ptr_array_index (rooms, i);
                handle = g_value_get_uint (g_value_array_get_nth (room_struct, 0));
+               channel_type = g_value_get_string (g_value_array_get_nth (room_struct, 1));
                info = g_value_get_boxed (g_value_array_get_nth (room_struct, 2));
                room_name_value = g_hash_table_lookup (info, "name");
-
-               names[i] = g_value_get_string (room_name_value);
-               g_array_append_val (handles, handle);
-       }
-               
-       tp_cli_connection_run_inspect_handles (priv->connection, -1,
-                                              TP_HANDLE_TYPE_ROOM,
-                                              handles,
-                                              &room_ids,
-                                              NULL, NULL);
-       for (i = 0; i < handles->len; i++) {
-               EmpathyChatroom *chatroom;
-
-               chatroom = empathy_chatroom_new_full (priv->account,
-                                                     room_ids[i],
-                                                     names[i],
-                                                     FALSE);
-               g_signal_emit (list, signals[NEW_ROOM], 0, chatroom);
-               g_object_unref (chatroom);
-               g_free (room_ids[i]);
+               handle_name_value = g_hash_table_lookup (info, "handle-name");
+               room_subject_value = g_hash_table_lookup (info, "subject");
+               room_members_value = g_hash_table_lookup (info, "members");
+               room_invite_value = g_hash_table_lookup (info, "invite-only");
+               room_password_value = g_hash_table_lookup (info, "password");
+
+               if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)) {
+                       continue;
+               }
+
+               chatroom = empathy_chatroom_new (priv->account);
+
+               if (room_name_value != NULL) {
+                       empathy_chatroom_set_name (chatroom,
+                                                  g_value_get_string (room_name_value));
+               }
+
+               if (room_members_value != NULL) {
+                       empathy_chatroom_set_members_count (chatroom,
+                                                  g_value_get_uint (room_members_value));
+               }
+
+               if (room_subject_value != NULL) {
+                       empathy_chatroom_set_subject (chatroom,
+                                                  g_value_get_string (room_subject_value));
+               }
+
+               if (room_invite_value != NULL) {
+                       empathy_chatroom_set_invite_only (chatroom,
+                                                  g_value_get_boolean (room_invite_value));
+               }
+
+               if (room_password_value != NULL) {
+                       empathy_chatroom_set_need_password (chatroom,
+                                                  g_value_get_boolean (room_password_value));
+               }
+
+               if (handle_name_value != NULL) {
+                       empathy_chatroom_set_room (chatroom,
+                                                  g_value_get_string (handle_name_value));
+
+                       /* We have the room ID, we can directly emit it */
+                       g_signal_emit (list, signals[NEW_ROOM], 0, chatroom);
+                       g_object_unref (chatroom);
+               } else {
+                       /* We don't have the room ID, we'll inspect all handles
+                        * at once and then emit rooms */
+                       if (handles == NULL) {
+                               handles = g_array_new (FALSE, FALSE, sizeof (guint));
+                       }
+
+                       g_array_append_val (handles, handle);
+                       chatrooms = g_slist_prepend (chatrooms, chatroom);
+               }
        }
 
-       g_free (names);
-       g_free (room_ids);
-       g_array_free (handles, TRUE);
+       if (handles != NULL) {
+               chatrooms = g_slist_reverse (chatrooms);
+               tp_cli_connection_call_inspect_handles (priv->connection, -1,
+                                                      TP_HANDLE_TYPE_ROOM,
+                                                      handles,
+                                                      tp_roomlist_inspect_handles_cb,
+                                                      chatrooms,
+                                                      tp_roomlist_chatrooms_free,
+                                                      list);
+               g_array_free (handles, TRUE);
+       }
 }
 
 static void
@@ -139,8 +216,7 @@ tp_roomlist_get_listing_rooms_cb (TpChannel    *channel,
        EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error geting listing rooms: %s",
-                              error->message);
+               DEBUG ("Error geting listing rooms: %s", error->message);
                return;
        }
 
@@ -155,7 +231,7 @@ tp_roomlist_invalidated_cb (TpChannel         *channel,
                            gchar             *message,
                            EmpathyTpRoomlist *list)
 {
-       empathy_debug (DEBUG_DOMAIN, "Channel invalidated: %s", message);
+       DEBUG ("Channel invalidated: %s", message);
        g_signal_emit (list, signals[DESTROY], 0);
 }
 
@@ -169,8 +245,7 @@ tp_roomlist_request_channel_cb (TpConnection *connection,
        EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
 
        if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error requesting channel: %s",
-                              error->message);
+               DEBUG ("Error requesting channel: %s", error->message);
                return;
        }
 
@@ -207,7 +282,7 @@ tp_roomlist_finalize (GObject *object)
        EmpathyTpRoomlistPriv *priv = GET_PRIV (object);
 
        if (priv->channel) {
-               empathy_debug (DEBUG_DOMAIN, "Closing channel...");
+               DEBUG ("Closing channel...");
                g_signal_handlers_disconnect_by_func (priv->channel,
                                                      tp_roomlist_invalidated_cb,
                                                      object);
@@ -232,7 +307,7 @@ tp_roomlist_constructed (GObject *list)
        EmpathyTpRoomlistPriv *priv = GET_PRIV (list);
        MissionControl        *mc;
 
-       mc = empathy_mission_control_new ();
+       mc = empathy_mission_control_dup_singleton ();
        priv->account = mission_control_get_account_for_tpconnection (mc,
                                                                      priv->connection,
                                                                      NULL);
@@ -339,6 +414,10 @@ empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass)
 static void
 empathy_tp_roomlist_init (EmpathyTpRoomlist *list)
 {
+       EmpathyTpRoomlistPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (list,
+               EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistPriv);
+
+       list->priv = priv;
 }
 
 EmpathyTpRoomlist *
@@ -350,7 +429,7 @@ empathy_tp_roomlist_new (McAccount *account)
 
        g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
 
-       mc = empathy_mission_control_new ();
+       mc = empathy_mission_control_dup_singleton ();
        connection = mission_control_get_tpconnection (mc, account, NULL);
 
        list = g_object_new (EMPATHY_TYPE_TP_ROOMLIST,
@@ -382,8 +461,7 @@ empathy_tp_roomlist_start (EmpathyTpRoomlist *list)
        g_return_if_fail (TP_IS_CHANNEL (priv->channel));
 
        tp_cli_channel_type_room_list_call_list_rooms (priv->channel, -1,
-                                                      NULL, NULL, NULL,
-                                                      G_OBJECT (list));
+                                                      NULL, NULL, NULL, NULL);
 }
 
 void
@@ -395,7 +473,6 @@ empathy_tp_roomlist_stop (EmpathyTpRoomlist *list)
        g_return_if_fail (TP_IS_CHANNEL (priv->channel));
 
        tp_cli_channel_type_room_list_call_stop_listing (priv->channel, -1,
-                                                        NULL, NULL, NULL,
-                                                        G_OBJECT (list));
+                                                        NULL, NULL, NULL, NULL);
 }