]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-contact-monitor.c
add myself to AUTHORS
[empathy.git] / libempathy / empathy-contact-monitor.c
index e48f0865555f3ceed8ea20bfc9d7d983c7adcdf5..f41b8bd5c11df45b9188c1ead1596ce5d3b22d31 100644 (file)
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 /*
  * Copyright (C) 2008 Collabora Ltd.
  *
  * 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: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
  */
 
-#include <glib-object.h>
+#include "config.h"
 
-#include <libmissioncontrol/mc-enum-types.h>
+#include <glib-object.h>
 
 #include "empathy-contact-monitor.h"
 #include "empathy-contact-list.h"
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyContactMonitor)
 
 typedef struct {
-  EmpathyContactList *proxy;
-  GPtrArray *contacts;
+  EmpathyContactList *iface;
+  GList *contacts;
+
+  gboolean dispose_run;
 } EmpathyContactMonitorPriv;
 
 enum {
@@ -50,188 +51,18 @@ enum {
 
 enum {
   PROP_0,
-  PROP_PROXY
+  PROP_IFACE
 };
 
-static void  contact_remove_foreach (EmpathyContact *contact,
-                                     EmpathyContactMonitor *monitor);
-static void  cl_members_changed_cb  (EmpathyContactList    *cl,
-                                     EmpathyContact        *contact,
-                                     EmpathyContact        *actor,
-                                     guint                  reason,
-                                     gchar                 *message,
-                                     gboolean               is_member,
-                                     EmpathyContactMonitor *monitor);
-
 static guint signals[LAST_SIGNAL];
 
 G_DEFINE_TYPE (EmpathyContactMonitor, empathy_contact_monitor, G_TYPE_OBJECT);
 
-static void
-do_set_property (GObject      *object,
-                 guint         param_id,
-                 const GValue *value,
-                 GParamSpec   *pspec)
-{
-  switch (param_id) {
-    case PROP_PROXY:
-      empathy_contact_monitor_set_proxy
-        (EMPATHY_CONTACT_MONITOR (object),
-         g_value_get_object (value));
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-      break;
-  };
-}
-
-static void
-do_get_property (GObject    *object,
-                 guint       param_id,
-                 GValue     *value,
-                 GParamSpec *pspec)
-{
-  EmpathyContactMonitorPriv *priv = GET_PRIV (object);
-
-  switch (param_id) {
-    case PROP_PROXY:
-      g_value_set_object (value, priv->proxy);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-      break;
-  };
-}
-
-static void
-do_finalize (GObject *obj)
-{
-  EmpathyContactMonitorPriv *priv;
-
-  priv = GET_PRIV (obj);
-
-  if (priv->contacts) {
-    g_ptr_array_foreach (priv->contacts,
-                         (GFunc) contact_remove_foreach, obj);
-    g_ptr_array_free (priv->contacts, TRUE);
-    priv->contacts = NULL;
-  }
-
-  if (priv->proxy) {
-    g_signal_handlers_disconnect_by_func (priv->proxy,
-                                          cl_members_changed_cb, obj);
-  }
-
-  G_OBJECT_CLASS (empathy_contact_monitor_parent_class)->finalize (obj);
-}
-
-static void
-empathy_contact_monitor_class_init (EmpathyContactMonitorClass *klass)
-{
-  GObjectClass *oclass = G_OBJECT_CLASS (klass);
-
-  oclass->finalize = do_finalize;
-  oclass->get_property = do_get_property;
-  oclass->set_property = do_set_property;
-
-  g_object_class_install_property (oclass,
-                                   PROP_PROXY,
-                                   g_param_spec_object ("proxy",
-                                                        "Monitor's proxy",
-                                                        "The contact list associated we're monitoring",
-                                                        EMPATHY_TYPE_CONTACT_LIST,
-                                                        G_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT_ONLY |
-                                                        G_PARAM_STATIC_STRINGS));
-
-  signals[CONTACT_ADDED] =
-    g_signal_new ("contact-added",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE,
-                  1, EMPATHY_TYPE_CONTACT);
-  signals[CONTACT_AVATAR_CHANGED] =
-    g_signal_new ("contact-avatar-changed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE,
-                  1, EMPATHY_TYPE_CONTACT);
-  signals[CONTACT_CAPABILITIES_CHANGED] =
-    g_signal_new ("contact-capabilities-changed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE,
-                  1, EMPATHY_TYPE_CONTACT);
-  signals[CONTACT_NAME_CHANGED] =
-    g_signal_new ("contact-name-changed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  _empathy_marshal_VOID__OBJECT_STRING,
-                  G_TYPE_NONE,
-                  2, EMPATHY_TYPE_CONTACT,
-                  G_TYPE_STRING);
-  signals[CONTACT_PRESENCE_CHANGED] =
-    g_signal_new ("contact-presence-changed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  _empathy_marshal_VOID__OBJECT_ENUM_ENUM,
-                  G_TYPE_NONE,
-                  3, EMPATHY_TYPE_CONTACT,
-                  MC_TYPE_PRESENCE,
-                  MC_TYPE_PRESENCE);
-  signals[CONTACT_PRESENCE_MESSAGE_CHANGED] =
-    g_signal_new ("contact-presence-message-changed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  _empathy_marshal_VOID__OBJECT_STRING,
-                  G_TYPE_NONE,
-                  2, EMPATHY_TYPE_CONTACT,
-                  G_TYPE_STRING);
-  signals[CONTACT_REMOVED] =
-    g_signal_new ("contact-removed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE,
-                  1, EMPATHY_TYPE_CONTACT);
-
-  g_type_class_add_private (klass, sizeof (EmpathyContactMonitorPriv));
-}
-
-static void
-empathy_contact_monitor_init (EmpathyContactMonitor *self)
-{
-  EmpathyContactMonitorPriv *priv =
-    G_TYPE_INSTANCE_GET_PRIVATE (self,
-                                 EMPATHY_TYPE_CONTACT_MONITOR, EmpathyContactMonitorPriv);
-
-  self->priv = priv;
-  priv->contacts = NULL;
-  priv->proxy = NULL;
-}
-
 static void
 contact_monitor_presence_changed_cb (EmpathyContact *contact,
-                                     McPresence current_presence,
-                                     McPresence previous_presence,
-                                     EmpathyContactMonitor *self)
+    TpConnectionPresenceType current_presence,
+    TpConnectionPresenceType previous_presence,
+    EmpathyContactMonitor *self)
 {
   g_signal_emit (self, signals[CONTACT_PRESENCE_CHANGED], 0, contact,
                  current_presence, previous_presence);
@@ -268,8 +99,7 @@ contact_monitor_avatar_changed_cb (EmpathyContact *contact,
                                    GParamSpec *pspec,
                                    EmpathyContactMonitor *self)
 {
-  /* don't emit a pixbuf in the signal, as we don't know how large
-   * a client would like it to be.
+  /* don't emit a pixbuf in the signal, as we don't depend on GTK+ here
    */
 
   g_signal_emit (self, signals[CONTACT_AVATAR_CHANGED], 0, contact);
@@ -305,7 +135,7 @@ contact_add (EmpathyContactMonitor *monitor,
                     G_CALLBACK (contact_monitor_capabilities_changed_cb),
                     monitor);
 
-  g_ptr_array_add (priv->contacts, g_object_ref (contact));
+  priv->contacts = g_list_prepend (priv->contacts, g_object_ref (contact));
 
   g_signal_emit (monitor, signals[CONTACT_ADDED], 0, contact);
 }
@@ -332,7 +162,7 @@ contact_remove (EmpathyContactMonitor *monitor,
                                         G_CALLBACK (contact_monitor_capabilities_changed_cb),
                                         monitor);
 
-  g_ptr_array_remove (priv->contacts, contact);
+  priv->contacts = g_list_remove (priv->contacts, contact);
 
   g_signal_emit (monitor, signals[CONTACT_REMOVED], 0, contact);
 
@@ -355,49 +185,233 @@ cl_members_changed_cb (EmpathyContactList    *cl,
                        gboolean               is_member,
                        EmpathyContactMonitor *monitor)
 {
-  if (is_member) {
+  if (is_member)
     contact_add (monitor, contact);
-  } else {
+  else
     contact_remove (monitor, contact);
-  }
+}
+
+static void
+do_set_property (GObject      *object,
+                 guint         param_id,
+                 const GValue *value,
+                 GParamSpec   *pspec)
+{
+  switch (param_id)
+    {
+      case PROP_IFACE:
+        empathy_contact_monitor_set_iface (EMPATHY_CONTACT_MONITOR (object),
+                                           g_value_get_object (value));
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        break;
+    };
+}
+
+static void
+do_get_property (GObject    *object,
+                 guint       param_id,
+                 GValue     *value,
+                 GParamSpec *pspec)
+{
+  EmpathyContactMonitorPriv *priv = GET_PRIV (object);
+
+  switch (param_id)
+    {
+      case PROP_IFACE:
+        g_value_set_object (value, priv->iface);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        break;
+    };
+}
+
+static void
+do_finalize (GObject *obj)
+{
+  EmpathyContactMonitorPriv *priv;
+
+  priv = GET_PRIV (obj);
+
+  if (priv->contacts)
+    {
+      g_list_free (priv->contacts);
+      priv->contacts = NULL;
+    }
+
+  if (priv->iface)
+    g_signal_handlers_disconnect_by_func (priv->iface,
+                                          cl_members_changed_cb, obj);
+
+  G_OBJECT_CLASS (empathy_contact_monitor_parent_class)->finalize (obj);
+}
+
+static void
+do_dispose (GObject *obj)
+{
+  EmpathyContactMonitorPriv *priv;
+
+  priv = GET_PRIV (obj);
+
+  if (priv->dispose_run)
+    return;
+
+  priv->dispose_run = TRUE;
+
+  if (priv->contacts)
+    g_list_foreach (priv->contacts,
+                    (GFunc) contact_remove_foreach, obj);
+
+  if (priv->iface)
+    g_signal_handlers_disconnect_by_func (priv->iface,
+                                          cl_members_changed_cb, obj);
+
+  G_OBJECT_CLASS (empathy_contact_monitor_parent_class)->dispose (obj);
+}
+
+static void
+empathy_contact_monitor_class_init (EmpathyContactMonitorClass *klass)
+{
+  GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+  oclass->finalize = do_finalize;
+  oclass->dispose = do_dispose;
+  oclass->get_property = do_get_property;
+  oclass->set_property = do_set_property;
+
+  g_object_class_install_property (oclass,
+                                   PROP_IFACE,
+                                   g_param_spec_object ("iface",
+                                                        "Monitor's iface",
+                                                        "The contact list we're monitoring",
+                                                        EMPATHY_TYPE_CONTACT_LIST,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_STRINGS));
+
+  signals[CONTACT_ADDED] =
+    g_signal_new ("contact-added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1, EMPATHY_TYPE_CONTACT);
+  signals[CONTACT_AVATAR_CHANGED] =
+    g_signal_new ("contact-avatar-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1, EMPATHY_TYPE_CONTACT);
+  signals[CONTACT_CAPABILITIES_CHANGED] =
+    g_signal_new ("contact-capabilities-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1, EMPATHY_TYPE_CONTACT);
+  signals[CONTACT_NAME_CHANGED] =
+    g_signal_new ("contact-name-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  _empathy_marshal_VOID__OBJECT_STRING,
+                  G_TYPE_NONE,
+                  2, EMPATHY_TYPE_CONTACT,
+                  G_TYPE_STRING);
+  signals[CONTACT_PRESENCE_CHANGED] =
+    g_signal_new ("contact-presence-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  _empathy_marshal_VOID__OBJECT_UINT_UINT,
+                  G_TYPE_NONE,
+                  3, EMPATHY_TYPE_CONTACT,
+                  G_TYPE_UINT,
+                  G_TYPE_UINT);
+  signals[CONTACT_PRESENCE_MESSAGE_CHANGED] =
+    g_signal_new ("contact-presence-message-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  _empathy_marshal_VOID__OBJECT_STRING,
+                  G_TYPE_NONE,
+                  2, EMPATHY_TYPE_CONTACT,
+                  G_TYPE_STRING);
+  signals[CONTACT_REMOVED] =
+    g_signal_new ("contact-removed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1, EMPATHY_TYPE_CONTACT);
+
+  g_type_class_add_private (klass, sizeof (EmpathyContactMonitorPriv));
+}
+
+static void
+empathy_contact_monitor_init (EmpathyContactMonitor *self)
+{
+  EmpathyContactMonitorPriv *priv =
+      G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_CONTACT_MONITOR,
+                                   EmpathyContactMonitorPriv);
+
+  self->priv = priv;
+  priv->contacts = NULL;
+  priv->iface = NULL;
+  priv->dispose_run = FALSE;
 }
 
 /* public methods */
 
 void
-empathy_contact_monitor_set_proxy (EmpathyContactMonitor *self,
-                                   EmpathyContactList *proxy)
+empathy_contact_monitor_set_iface (EmpathyContactMonitor *self,
+                                   EmpathyContactList *iface)
 {
   EmpathyContactMonitorPriv *priv;
 
-  g_assert (EMPATHY_IS_CONTACT_MONITOR (self));
-  g_assert (EMPATHY_IS_CONTACT_LIST (proxy));
+  g_return_if_fail (EMPATHY_IS_CONTACT_MONITOR (self));
+  g_return_if_fail (EMPATHY_IS_CONTACT_LIST (iface));
 
   priv = GET_PRIV (self);
 
-  if (priv->contacts != NULL) {
-    g_ptr_array_foreach (priv->contacts,
-                         (GFunc) contact_remove_foreach, self);
-    g_ptr_array_free (priv->contacts, TRUE);
-    priv->contacts = NULL;
-  }
+  if (priv->contacts != NULL)
+    {
+      g_list_foreach (priv->contacts,
+                      (GFunc) contact_remove_foreach, self);
+      g_list_free (priv->contacts);
+      priv->contacts = NULL;
+    }
 
-  priv->proxy = proxy;
-  priv->contacts = g_ptr_array_new ();
+  priv->iface = iface;
 
-  g_signal_connect (proxy, "members-changed",
+  g_signal_connect (iface, "members-changed",
                     G_CALLBACK (cl_members_changed_cb), self);
 }
 
 EmpathyContactMonitor *
-empathy_contact_monitor_new_for_proxy (EmpathyContactList *proxy)
+empathy_contact_monitor_new_for_iface (EmpathyContactList *iface)
 {
   EmpathyContactMonitor *retval;
 
-  g_assert (EMPATHY_IS_CONTACT_LIST (proxy));
+  g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (iface), NULL);
 
   retval = g_object_new (EMPATHY_TYPE_CONTACT_MONITOR,
-                         "proxy", proxy, NULL);
+                         "iface", iface, NULL);
 
   return retval;
 }
+