[telepathy-doc/master] Move Statuses loading into PresenceChooser

Danielle Madeley danielle.madeley at collabora.co.uk
Wed Nov 4 22:26:28 PST 2009


---
 docs/examples/gtk_presence_app/presence-chooser.c |  216 ++++++++++++++++++---
 docs/examples/gtk_presence_app/presence-chooser.h |    6 +-
 docs/examples/gtk_presence_app/presence-widget.c  |   94 ++--------
 3 files changed, 200 insertions(+), 116 deletions(-)

diff --git a/docs/examples/gtk_presence_app/presence-chooser.c b/docs/examples/gtk_presence_app/presence-chooser.c
index df618f1..d03af4c 100644
--- a/docs/examples/gtk_presence_app/presence-chooser.c
+++ b/docs/examples/gtk_presence_app/presence-chooser.c
@@ -7,6 +7,10 @@
  *    Danielle Madeley <danielle.madeley at collabora.co.uk>
  */
 
+#include <telepathy-glib/enums.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/interfaces.h>
+
 #include "presence-chooser.h"
 
 #define GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_PRESENCE_CHOOSER, PresenceChooserPrivate))
@@ -19,9 +23,16 @@ extern const char *presence_icons[];
 typedef struct _PresenceChooserPrivate PresenceChooserPrivate;
 struct _PresenceChooserPrivate
 {
+  TpAccount *account;
   GtkListStore *store;
 };
 
+enum /* properties */
+{
+  PROP_0,
+  PROP_ACCOUNT
+};
+
 enum /* columns */
 {
   ICON_NAME,
@@ -33,47 +44,48 @@ enum /* columns */
 };
 
 static void
-presence_chooser_class_init (PresenceChooserClass *class)
+presence_chooser_get_property (GObject    *self,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  PresenceChooserPrivate *priv = GET_PRIVATE (self);
 
-  g_type_class_add_private (gobject_class, sizeof (PresenceChooserPrivate));
+  switch (prop_id)
+    {
+      case PROP_ACCOUNT:
+        g_value_set_object (value, priv->account);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
+        break;
+    }
 }
 
 static void
-presence_chooser_init (PresenceChooser *self)
+presence_chooser_set_property (GObject      *self,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
 {
   PresenceChooserPrivate *priv = GET_PRIVATE (self);
 
-  priv->store = gtk_list_store_new (N_COLUMNS,
-      G_TYPE_STRING,  /* ICON_NAME */
-      G_TYPE_UINT,    /* PRESENCE_TYPE */
-      G_TYPE_STRING,  /* STATUS */
-      G_TYPE_BOOLEAN, /* CAN_HAVE_MESSAGE */
-      G_TYPE_STRING   /* STATUS_MESSAGE */
-    );
-
-  gtk_combo_box_set_model (GTK_COMBO_BOX (self), GTK_TREE_MODEL (priv->store));
-
-  gtk_cell_layout_clear (GTK_CELL_LAYOUT (self));
-
-  GtkCellRenderer *renderer;
-  renderer = gtk_cell_renderer_pixbuf_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, FALSE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
-      "icon-name", ICON_NAME,
-      NULL);
+  switch (prop_id)
+    {
+      case PROP_ACCOUNT:
+        priv->account = g_value_dup_object (value);
+        break;
 
-  renderer = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, TRUE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
-      "text", STATUS_MESSAGE,
-      NULL);
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
+        break;
+    }
 }
 
-void
+static void
 presence_chooser_set_statuses (PresenceChooser *self,
-                               GHashTable *statuses)
+                               GHashTable      *statuses)
 {
   g_return_if_fail (IS_PRESENCE_CHOOSER (self));
   g_return_if_fail (statuses != NULL);
@@ -109,8 +121,150 @@ presence_chooser_set_statuses (PresenceChooser *self,
     }
 }
 
+static void
+_get_property_statuses (TpProxy      *conn,
+                        const GValue *value,
+                        const GError *error,
+                        gpointer      user_data,
+                        GObject      *self)
+{
+  if (error != NULL)
+    {
+      g_warning ("%s", error->message);
+      return;
+    }
+
+  g_return_if_fail (G_VALUE_HOLDS (value, TP_HASH_TYPE_SIMPLE_STATUS_SPEC_MAP));
+
+  GHashTable *statuses = g_value_get_boxed (value);
+  presence_chooser_set_statuses (PRESENCE_CHOOSER (self), statuses);
+}
+
+static void
+_connection_ready (TpConnection *conn,
+                   const GError *error,
+                   gpointer      self)
+{
+  if (error != NULL)
+    {
+      g_warning ("%s", error->message);
+      return;
+    }
+
+  if (tp_proxy_has_interface (conn,
+        TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE))
+    {
+      /* request the Statuses property */
+      tp_cli_dbus_properties_call_get (conn, -1,
+          TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
+          "Statuses",
+          _get_property_statuses,
+          NULL, NULL, G_OBJECT (self));
+    }
+}
+
+static void
+_status_changed (PresenceChooser *self,
+                 guint            old_status,
+                 guint            new_status,
+                 guint            reason,
+                 TpAccount       *account)
+{
+  TpConnection *conn = tp_account_get_connection (account);
+
+  if (conn == NULL) return;
+  else if (new_status == TP_CONNECTION_STATUS_CONNECTED ||
+           new_status == TP_CONNECTION_STATUS_DISCONNECTED)
+    {
+      tp_connection_call_when_ready (conn, _connection_ready, self);
+    }
+}
+
+static void
+presence_chooser_constructed (GObject *self)
+{
+  PresenceChooserPrivate *priv = GET_PRIVATE (self);
+
+  g_signal_connect_swapped (priv->account, "status-changed",
+      G_CALLBACK (_status_changed), self);
+
+  _status_changed (PRESENCE_CHOOSER (self), 0,
+      tp_account_get_connection_status (priv->account),
+      0, priv->account);
+}
+
+static void
+presence_chooser_dispose (GObject *self)
+{
+  PresenceChooserPrivate *priv = GET_PRIVATE (self);
+
+  if (priv->account != NULL)
+    {
+      g_object_unref (priv->account);
+      priv->account = NULL;
+    }
+
+  G_OBJECT_CLASS (presence_chooser_parent_class)->dispose (self);
+}
+
+static void
+presence_chooser_class_init (PresenceChooserClass *class)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+  gobject_class->get_property = presence_chooser_get_property;
+  gobject_class->set_property = presence_chooser_set_property;
+  gobject_class->constructed  = presence_chooser_constructed;
+  gobject_class->dispose      = presence_chooser_dispose;
+
+  g_object_class_install_property (gobject_class,
+      PROP_ACCOUNT,
+      g_param_spec_object ("account",
+                           "account",
+                           "Telepathy Account",
+                           TP_TYPE_ACCOUNT,
+                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_type_class_add_private (gobject_class, sizeof (PresenceChooserPrivate));
+}
+
+static void
+presence_chooser_init (PresenceChooser *self)
+{
+  PresenceChooserPrivate *priv = GET_PRIVATE (self);
+
+  priv->store = gtk_list_store_new (N_COLUMNS,
+      G_TYPE_STRING,  /* ICON_NAME */
+      G_TYPE_UINT,    /* PRESENCE_TYPE */
+      G_TYPE_STRING,  /* STATUS */
+      G_TYPE_BOOLEAN, /* CAN_HAVE_MESSAGE */
+      G_TYPE_STRING   /* STATUS_MESSAGE */
+    );
+
+  gtk_combo_box_set_model (GTK_COMBO_BOX (self), GTK_TREE_MODEL (priv->store));
+
+  gtk_cell_layout_clear (GTK_CELL_LAYOUT (self));
+
+  GtkCellRenderer *renderer;
+  renderer = gtk_cell_renderer_pixbuf_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, FALSE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
+      "icon-name", ICON_NAME,
+      NULL);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
+      "text", STATUS_MESSAGE,
+      NULL);
+}
+
 GtkWidget *
-presence_chooser_new (void)
+presence_chooser_new (TpAccount *account)
 {
-  return g_object_new (TYPE_PRESENCE_CHOOSER, NULL);
+  g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL);
+
+  return g_object_new (TYPE_PRESENCE_CHOOSER,
+      "account", account,
+      NULL);
 }
diff --git a/docs/examples/gtk_presence_app/presence-chooser.h b/docs/examples/gtk_presence_app/presence-chooser.h
index ffc17c0..0899ee5 100644
--- a/docs/examples/gtk_presence_app/presence-chooser.h
+++ b/docs/examples/gtk_presence_app/presence-chooser.h
@@ -12,6 +12,8 @@
 
 #include <gtk/gtk.h>
 
+#include <telepathy-glib/account.h>
+
 G_BEGIN_DECLS
 
 #define TYPE_PRESENCE_CHOOSER	(presence_chooser_get_type ())
@@ -35,9 +37,7 @@ struct _PresenceChooserClass
 };
 
 GType presence_chooser_get_type (void);
-void presence_chooser_set_statuses (PresenceChooser *self,
-                                    GHashTable *statuses);
-GtkWidget *presence_chooser_new (void);
+GtkWidget *presence_chooser_new (TpAccount *account);
 
 G_END_DECLS
 
diff --git a/docs/examples/gtk_presence_app/presence-widget.c b/docs/examples/gtk_presence_app/presence-widget.c
index 719ed43..8736fc3 100644
--- a/docs/examples/gtk_presence_app/presence-widget.c
+++ b/docs/examples/gtk_presence_app/presence-widget.c
@@ -23,7 +23,6 @@ typedef struct _PresenceWidgetPrivate PresenceWidgetPrivate;
 struct _PresenceWidgetPrivate
 {
   TpAccount *account;
-  GHashTable *statuses;
 
   GtkWidget *enabled_check;
   GtkWidget *status_icon;
@@ -148,74 +147,6 @@ _notify_status_message (PresenceWidget *self,
 }
 
 static void
-_get_property_statuses (TpProxy      *conn,
-                        const GValue *value,
-                        const GError *error,
-                        gpointer      user_data,
-                        GObject      *self)
-{
-  PresenceWidgetPrivate *priv = GET_PRIVATE (self);
-
-  if (error != NULL)
-    {
-      g_warning ("%s", error->message);
-      return;
-    }
-
-  g_return_if_fail (G_VALUE_HOLDS (value, TP_HASH_TYPE_SIMPLE_STATUS_SPEC_MAP));
-
-  if (priv->statuses != NULL) g_hash_table_unref (priv->statuses);
-  priv->statuses = g_hash_table_ref (g_value_get_boxed (value));
-
-  // FIXME: do I need to hold onto this?
-  presence_chooser_set_statuses (PRESENCE_CHOOSER (priv->chooser),
-                                 priv->statuses);
-}
-
-static void
-_connection_ready (TpConnection *conn,
-                   const GError *error,
-                   gpointer      user_data)
-{
-  PresenceWidget *self = PRESENCE_WIDGET (user_data);
-  PresenceWidgetPrivate *priv = GET_PRIVATE (self);
-
-  if (error != NULL)
-    {
-      g_warning ("%s", error->message);
-      return;
-    }
-
-  if (tp_proxy_has_interface (conn,
-        TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE))
-    {
-      /* request the Statuses property */
-      tp_cli_dbus_properties_call_get (conn, -1,
-          TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
-          "Statuses",
-          _get_property_statuses,
-          NULL, NULL, G_OBJECT (self));
-    }
-}
-
-static void
-_status_changed (PresenceWidget *self,
-                 guint           old_status,
-                 guint           new_status,
-                 guint           reason,
-                 TpAccount      *account)
-{
-  TpConnection *conn = tp_account_get_connection (account);
-
-  if (conn == NULL) return;
-  else if (new_status == TP_CONNECTION_STATUS_CONNECTED ||
-           new_status == TP_CONNECTION_STATUS_DISCONNECTED)
-    {
-      tp_connection_call_when_ready (conn, _connection_ready, self);
-    }
-}
-
-static void
 _account_removed (PresenceWidget *self,
                   TpAccount      *account)
 {
@@ -228,6 +159,13 @@ presence_widget_constructed (GObject *self)
 {
   PresenceWidgetPrivate *priv = GET_PRIVATE (self);
 
+  priv->chooser = presence_chooser_new (priv->account);
+  gtk_table_attach (GTK_TABLE (gtk_bin_get_child (GTK_BIN (self))),
+      priv->chooser,
+      0, 2, 1, 2,
+      GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (priv->chooser);
+
   g_signal_connect_swapped (priv->account, "notify::enabled",
       G_CALLBACK (_notify_enabled), self);
   g_signal_connect_swapped (priv->account, "notify::display-name",
@@ -237,8 +175,6 @@ presence_widget_constructed (GObject *self)
   g_signal_connect_swapped (priv->account, "notify::status-message",
       G_CALLBACK (_notify_status_message), self);
 
-  g_signal_connect_swapped (priv->account, "status-changed",
-      G_CALLBACK (_status_changed), self);
   g_signal_connect_swapped (priv->account, "removed",
       G_CALLBACK (_account_removed), self);
 
@@ -246,10 +182,6 @@ presence_widget_constructed (GObject *self)
   _notify_display_name (PRESENCE_WIDGET (self), NULL, priv->account);
   _notify_presence (PRESENCE_WIDGET (self), NULL, priv->account);
   _notify_status_message (PRESENCE_WIDGET (self), NULL, priv->account);
-
-  _status_changed (PRESENCE_WIDGET (self), 0,
-      tp_account_get_connection_status (priv->account),
-      0, priv->account);
 }
 
 static void
@@ -257,8 +189,11 @@ presence_widget_dispose (GObject *self)
 {
   PresenceWidgetPrivate *priv = GET_PRIVATE (self);
 
-  g_object_unref (priv->account);
-  priv->account = NULL;
+  if (priv->account != NULL)
+    {
+      g_object_unref (priv->account);
+      priv->account = NULL;
+    }
 
   G_OBJECT_CLASS (presence_widget_parent_class)->dispose (self);
 }
@@ -324,11 +259,6 @@ presence_widget_init (PresenceWidget *self)
       1, 2, 0, 1,
       GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
 
-  priv->chooser = presence_chooser_new ();
-  gtk_table_attach (GTK_TABLE (table), priv->chooser,
-      0, 2, 1, 2,
-      GTK_FILL, GTK_FILL, 0, 0);
-
   gtk_widget_show (priv->enabled_check);
   gtk_widget_show_all (table);
 }
-- 
1.5.6.5




More information about the telepathy-commits mailing list