]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-tp-chat.c
Merge call branch from Elliot Fairweather with cleanups from Xavier Claessens.
[empathy.git] / libempathy / empathy-tp-chat.c
index 691d7a2f14c7dfab6447abd21661fd8616c25be5..5e166cac9d33163e74719e73ed99babab46d10e0 100644 (file)
@@ -2,20 +2,19 @@
 /*
  * Copyright (C) 2007 Collabora Ltd.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  * 
  * Authors: Xavier Claessens <xclaesse@gmail.com>
  */
@@ -31,8 +30,7 @@
 #include <libtelepathy/tp-props-iface.h>
 
 #include "empathy-tp-chat.h"
-#include "empathy-contact-manager.h"
-#include "empathy-tp-contact-list.h"
+#include "empathy-contact-factory.h"
 #include "empathy-marshal.h"
 #include "empathy-debug.h"
 #include "empathy-time.h"
@@ -44,8 +42,8 @@
 #define DEBUG_DOMAIN "TpChat"
 
 struct _EmpathyTpChatPriv {
-       EmpathyTpContactList  *list;
-       EmpathyContactManager *manager;
+       EmpathyContactFactory *factory;
+       EmpathyContact        *user;
        McAccount             *account;
        gchar                 *id;
        MissionControl        *mc;
@@ -57,58 +55,58 @@ struct _EmpathyTpChatPriv {
        DBusGProxy            *chat_state_iface;
 };
 
-static void             empathy_tp_chat_class_init    (EmpathyTpChatClass        *klass);
-static void             empathy_tp_chat_init          (EmpathyTpChat             *chat);
-static void             tp_chat_finalize              (GObject                   *object);
-static GObject *        tp_chat_constructor           (GType                      type,
-                                                      guint                      n_props,
-                                                      GObjectConstructParam     *props);
-static void             tp_chat_get_property          (GObject                   *object,
-                                                      guint                      param_id,
-                                                      GValue                    *value,
-                                                      GParamSpec                *pspec);
-static void             tp_chat_set_property          (GObject                   *object,
-                                                      guint                      param_id,
-                                                      const GValue              *value,
-                                                      GParamSpec                *pspec);
-static void             tp_chat_destroy_cb            (TpChan                    *text_chan,
-                                                      EmpathyTpChat             *chat);
-static void             tp_chat_closed_cb             (TpChan                    *text_chan,
-                                                      EmpathyTpChat             *chat);
-static void             tp_chat_received_cb           (DBusGProxy                *text_iface,
-                                                      guint                      message_id,
-                                                      guint                      timestamp,
-                                                      guint                      from_handle,
-                                                      guint                      message_type,
-                                                      guint                      message_flags,
-                                                      gchar                     *message_body,
-                                                      EmpathyTpChat             *chat);
-static void             tp_chat_sent_cb               (DBusGProxy                *text_iface,
-                                                      guint                      timestamp,
-                                                      guint                      message_type,
-                                                      gchar                     *message_body,
-                                                      EmpathyTpChat             *chat);
-static void             tp_chat_send_error_cb         (DBusGProxy                *text_iface,
-                                                      guint                      error_code,
-                                                      guint                      timestamp,
-                                                      guint                      message_type,
-                                                      gchar                     *message_body,
-                                                      EmpathyTpChat             *chat);
-static void             tp_chat_state_changed_cb      (DBusGProxy                *chat_state_iface,
-                                                      guint                      handle,
-                                                      TelepathyChannelChatState  state,
-                                                      EmpathyTpChat             *chat);
-static EmpathyMessage * tp_chat_build_message         (EmpathyTpChat             *chat,
-                                                      guint                      type,
-                                                      guint                      timestamp,
-                                                      guint                      from_handle,
-                                                      const gchar               *message_body);
-static void             tp_chat_properties_ready_cb   (TpPropsIface              *props_iface,
-                                                      EmpathyTpChat             *chat);
-static void             tp_chat_properties_changed_cb (TpPropsIface              *props_iface,
-                                                      guint                      prop_id,
-                                                      TpPropsChanged             flag,
-                                                      EmpathyTpChat             *chat);
+static void             empathy_tp_chat_class_init    (EmpathyTpChatClass    *klass);
+static void             empathy_tp_chat_init          (EmpathyTpChat         *chat);
+static void             tp_chat_finalize              (GObject               *object);
+static GObject *        tp_chat_constructor           (GType                  type,
+                                                      guint                  n_props,
+                                                      GObjectConstructParam *props);
+static void             tp_chat_get_property          (GObject               *object,
+                                                      guint                  param_id,
+                                                      GValue                *value,
+                                                      GParamSpec            *pspec);
+static void             tp_chat_set_property          (GObject               *object,
+                                                      guint                  param_id,
+                                                      const GValue          *value,
+                                                      GParamSpec            *pspec);
+static void             tp_chat_destroy_cb            (TpChan                *text_chan,
+                                                      EmpathyTpChat         *chat);
+static void             tp_chat_closed_cb             (TpChan                *text_chan,
+                                                      EmpathyTpChat         *chat);
+static void             tp_chat_received_cb           (DBusGProxy            *text_iface,
+                                                      guint                  message_id,
+                                                      guint                  timestamp,
+                                                      guint                  from_handle,
+                                                      guint                  message_type,
+                                                      guint                  message_flags,
+                                                      gchar                 *message_body,
+                                                      EmpathyTpChat         *chat);
+static void             tp_chat_sent_cb               (DBusGProxy            *text_iface,
+                                                      guint                  timestamp,
+                                                      guint                  message_type,
+                                                      gchar                 *message_body,
+                                                      EmpathyTpChat         *chat);
+static void             tp_chat_send_error_cb         (DBusGProxy            *text_iface,
+                                                      guint                  error_code,
+                                                      guint                  timestamp,
+                                                      guint                  message_type,
+                                                      gchar                 *message_body,
+                                                      EmpathyTpChat         *chat);
+static void             tp_chat_state_changed_cb      (DBusGProxy            *chat_state_iface,
+                                                      guint                  handle,
+                                                      TpChannelChatState     state,
+                                                      EmpathyTpChat         *chat);
+static EmpathyMessage * tp_chat_build_message         (EmpathyTpChat         *chat,
+                                                      guint                  type,
+                                                      guint                  timestamp,
+                                                      guint                  from_handle,
+                                                      const gchar           *message_body);
+static void             tp_chat_properties_ready_cb   (TpPropsIface          *props_iface,
+                                                      EmpathyTpChat         *chat);
+static void             tp_chat_properties_changed_cb (TpPropsIface          *props_iface,
+                                                      guint                  prop_id,
+                                                      TpPropsChanged         flag,
+                                                      EmpathyTpChat         *chat);
 enum {
        PROP_0,
        PROP_ACCOUNT,
@@ -304,7 +302,7 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass)
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__OBJECT_UINT,
+                             _empathy_marshal_VOID__OBJECT_UINT,
                              G_TYPE_NONE,
                              2, EMPATHY_TYPE_MESSAGE, G_TYPE_UINT);
 
@@ -314,7 +312,7 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass)
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__OBJECT_UINT,
+                             _empathy_marshal_VOID__OBJECT_UINT,
                              G_TYPE_NONE,
                              2, EMPATHY_TYPE_CONTACT, G_TYPE_UINT);
 
@@ -347,10 +345,31 @@ tp_chat_finalize (GObject *object)
        chat = EMPATHY_TP_CHAT (object);
        priv = GET_PRIV (chat);
 
+       if (priv->text_iface) {
+               dbus_g_proxy_disconnect_signal (priv->text_iface, "Received",
+                                               G_CALLBACK (tp_chat_received_cb),
+                                               chat);
+               dbus_g_proxy_disconnect_signal (priv->text_iface, "Sent",
+                                               G_CALLBACK (tp_chat_sent_cb),
+                                               chat);
+               dbus_g_proxy_disconnect_signal (priv->text_iface, "SendError",
+                                               G_CALLBACK (tp_chat_send_error_cb),
+                                               chat);
+       }
+
+       if (priv->chat_state_iface) {
+               dbus_g_proxy_disconnect_signal (priv->chat_state_iface, "ChatStateChanged",
+                                               G_CALLBACK (tp_chat_state_changed_cb),
+                                               chat);
+       }
+
        if (priv->tp_chan) {
                g_signal_handlers_disconnect_by_func (priv->tp_chan,
                                                      tp_chat_destroy_cb,
                                                      object);
+               dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->tp_chan), "Closed",
+                                               G_CALLBACK (tp_chat_closed_cb),
+                                               chat);
                if (priv->acknowledge) {
                        empathy_debug (DEBUG_DOMAIN, "Closing channel...");
                        if (!tp_chan_close (DBUS_G_PROXY (priv->tp_chan), &error)) {
@@ -363,11 +382,11 @@ tp_chat_finalize (GObject *object)
                g_object_unref (priv->tp_chan);
        }
 
-       if (priv->manager) {
-               g_object_unref (priv->manager);
+       if (priv->factory) {
+               g_object_unref (priv->factory);
        }
-       if (priv->list) {
-               g_object_unref (priv->list);
+       if (priv->user) {
+               g_object_unref (priv->user);
        }
        if (priv->account) {
                g_object_unref (priv->account);
@@ -392,17 +411,16 @@ tp_chat_constructor (GType                  type,
 
        priv = GET_PRIV (chat);
 
-       priv->manager = empathy_contact_manager_new ();
-       priv->list = empathy_contact_manager_get_list (priv->manager, priv->account);
+       priv->factory = empathy_contact_factory_new ();
+       priv->user = empathy_contact_factory_get_user (priv->factory, priv->account);
        priv->mc = empathy_mission_control_new ();
-       g_object_ref (priv->list);
 
        priv->text_iface = tp_chan_get_interface (priv->tp_chan,
-                                                 TELEPATHY_CHAN_IFACE_TEXT_QUARK);
+                                                 TP_IFACE_QUARK_CHANNEL_TYPE_TEXT);
        priv->chat_state_iface = tp_chan_get_interface (priv->tp_chan,
-                                                       TELEPATHY_CHAN_IFACE_CHAT_STATE_QUARK);
+                                                       TP_IFACE_QUARK_CHANNEL_INTERFACE_CHAT_STATE);
        priv->props_iface = tp_chan_get_interface (priv->tp_chan,
-                                                  TELEPATHY_PROPS_IFACE_QUARK);
+                                                  TP_IFACE_QUARK_PROPERTIES_INTERFACE);
 
        g_signal_connect (priv->tp_chan, "destroy",
                          G_CALLBACK (tp_chat_destroy_cb),
@@ -560,7 +578,7 @@ empathy_tp_chat_new_with_contact (EmpathyContact *contact)
        account = empathy_contact_get_account (contact);
 
        if (mission_control_get_connection_status (mc, account, NULL) != 0) {
-               /* The account is not connected, nothing to do. */
+               /* The account is not connected. */
                return NULL;
        }
 
@@ -624,6 +642,18 @@ empathy_tp_chat_get_channel (EmpathyTpChat *chat)
        return priv->tp_chan;
 }
 
+McAccount *
+empathy_tp_chat_get_account (EmpathyTpChat *chat)
+{
+       EmpathyTpChatPriv *priv;
+
+       g_return_val_if_fail (EMPATHY_IS_TP_CHAT (chat), NULL);
+
+       priv = GET_PRIV (chat);
+
+       return priv->account;
+}
+
 GList *
 empathy_tp_chat_get_pendings (EmpathyTpChat *chat)
 {
@@ -681,6 +711,7 @@ empathy_tp_chat_get_pendings (EmpathyTpChat *chat)
 
                g_value_array_free (message_struct);
        }
+       messages = g_list_reverse (messages);
 
        g_ptr_array_free (messages_list, TRUE);
 
@@ -717,8 +748,8 @@ empathy_tp_chat_send (EmpathyTpChat *chat,
 }
 
 void
-empathy_tp_chat_set_state (EmpathyTpChat             *chat,
-                          TelepathyChannelChatState  state)
+empathy_tp_chat_set_state (EmpathyTpChat      *chat,
+                          TpChannelChatState  state)
 {
        EmpathyTpChatPriv *priv;
        GError            *error = NULL;
@@ -749,12 +780,10 @@ empathy_tp_chat_get_id (EmpathyTpChat *chat)
 
        priv = GET_PRIV (chat);
 
-       if (priv->id) {
-               return priv->id;
+       if (!priv->id) {
+               priv->id = empathy_inspect_channel (priv->account, priv->tp_chan);
        }
 
-       priv->id = empathy_inspect_channel (priv->account, priv->tp_chan);
-
        return priv->id;
 }
 
@@ -874,17 +903,19 @@ tp_chat_send_error_cb (DBusGProxy    *text_iface,
 }
 
 static void
-tp_chat_state_changed_cb (DBusGProxy                *chat_state_iface,
-                         guint                      handle,
-                         TelepathyChannelChatState  state,
-                         EmpathyTpChat             *chat)
+tp_chat_state_changed_cb (DBusGProxy         *chat_state_iface,
+                         guint               handle,
+                         TpChannelChatState  state,
+                         EmpathyTpChat      *chat)
 {
        EmpathyTpChatPriv *priv;
        EmpathyContact     *contact;
 
        priv = GET_PRIV (chat);
 
-       contact = empathy_tp_contact_list_get_from_handle (priv->list, handle);
+       contact = empathy_contact_factory_get_from_handle (priv->factory,
+                                                          priv->account,
+                                                          handle);
 
        empathy_debug (DEBUG_DOMAIN, "Chat state changed for %s (%d): %d",
                      empathy_contact_get_name (contact),
@@ -905,23 +936,22 @@ tp_chat_build_message (EmpathyTpChat *chat,
        EmpathyTpChatPriv *priv;
        EmpathyMessage    *message;
        EmpathyContact    *sender;
-       EmpathyContact    *receiver;
 
        priv = GET_PRIV (chat);
 
-       receiver = empathy_tp_contact_list_get_user (priv->list);
        if (from_handle == 0) {
-               sender = g_object_ref (receiver);
+               sender = g_object_ref (priv->user);
        } else {
-               sender = empathy_tp_contact_list_get_from_handle (priv->list,
+               sender = empathy_contact_factory_get_from_handle (priv->factory,
+                                                                 priv->account,
                                                                  from_handle);
        }
 
        message = empathy_message_new (message_body);
        empathy_message_set_type (message, type);
        empathy_message_set_sender (message, sender);
-       empathy_message_set_receiver (message, receiver);
-       empathy_message_set_timestamp (message, (EmpathyTime) timestamp);
+       empathy_message_set_receiver (message, priv->user);
+       empathy_message_set_timestamp (message, timestamp);
 
        g_object_unref (sender);