[empathy: 2/7] individual-widget: show a "on a phone" label in the individual view



commit c391eb0efd50b519218c317d0c14e34954a45f9a
Author: Jonny Lamb <jonny lamb collabora co uk>
Date:   Thu Sep 30 18:24:10 2010 +0100

    individual-widget: show a "on a phone" label in the individual view
    
    Also refactor having a TpContact in the EmpathyIndividualViewPriv
    struct, so that contact info and client types info use the same
    TpContact.
    
    Signed-off-by: Jonny Lamb <jonnylamb gnome org>

 libempathy-gtk/empathy-individual-view.c    |    3 +-
 libempathy-gtk/empathy-individual-widget.c  |  157 +++++++++++++++++++--------
 libempathy-gtk/empathy-individual-widget.h  |    1 +
 libempathy-gtk/empathy-individual-widget.ui |   29 +++++
 4 files changed, 146 insertions(+), 44 deletions(-)
---
diff --git a/libempathy-gtk/empathy-individual-view.c b/libempathy-gtk/empathy-individual-view.c
index 94e60a4..4fef0d7 100644
--- a/libempathy-gtk/empathy-individual-view.c
+++ b/libempathy-gtk/empathy-individual-view.c
@@ -214,7 +214,8 @@ individual_view_query_tooltip_cb (EmpathyIndividualView *view,
     {
       priv->tooltip_widget = empathy_individual_widget_new (individual,
           EMPATHY_INDIVIDUAL_WIDGET_FOR_TOOLTIP |
-          EMPATHY_INDIVIDUAL_WIDGET_SHOW_LOCATION);
+          EMPATHY_INDIVIDUAL_WIDGET_SHOW_LOCATION |
+          EMPATHY_INDIVIDUAL_WIDGET_SHOW_CLIENT_TYPES);
       gtk_container_set_border_width (GTK_CONTAINER (priv->tooltip_widget), 8);
       g_object_ref (priv->tooltip_widget);
       g_signal_connect (priv->tooltip_widget, "destroy",
diff --git a/libempathy-gtk/empathy-individual-widget.c b/libempathy-gtk/empathy-individual-widget.c
index 5f180c0..72acfd8 100644
--- a/libempathy-gtk/empathy-individual-widget.c
+++ b/libempathy-gtk/empathy-individual-widget.c
@@ -78,7 +78,7 @@ typedef struct {
   EmpathyIndividualWidgetFlags flags;
 
   /* weak pointer to the contact whose contact details we're displaying */
-  TpContact *contact_info_contact;
+  TpContact *contact;
 
   /* unowned Persona (borrowed from priv->individual) -> GtkTable child */
   GHashTable *persona_tables;
@@ -106,6 +106,9 @@ typedef struct {
   /* Groups */
   GtkWidget *groups_widget;
 
+  /* Client types */
+  GtkWidget *hbox_client_types;
+
   /* Details */
   GtkWidget *vbox_details;
   GtkWidget *table_details;
@@ -122,6 +125,9 @@ enum {
   PROP_FLAGS
 };
 
+static void client_types_update (EmpathyIndividualWidget *self);
+static void remove_weak_contact (EmpathyIndividualWidget *self);
+
 static void
 details_set_up (EmpathyIndividualWidget *self)
 {
@@ -193,6 +199,47 @@ contact_info_field_cmp (TpContactInfoField *field1,
   return contact_info_field_name_cmp (field1->field_name, field2->field_name);
 }
 
+static void
+update_weak_contact (EmpathyIndividualWidget *self)
+{
+  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
+  TpContact *tp_contact = NULL;
+
+  remove_weak_contact (self);
+
+  if (priv->individual != NULL)
+    {
+      /* FIXME: We take the most available TpContact we find and only
+       * use its details. It would be a lot better if we would get the
+       * details for every TpContact in the Individual and merge them
+       * all, but that requires vCard support in libfolks for it to
+       * not be hideously complex.  (bgo#627399) */
+      GList *personas, *l;
+      FolksPresenceType presence_type = FOLKS_PRESENCE_TYPE_UNSET;
+
+      personas = folks_individual_get_personas (priv->individual);
+      for (l = personas; l != NULL; l = l->next)
+        {
+          FolksPresence *presence = FOLKS_PRESENCE (l->data);
+
+          if (folks_presence_typecmp (folks_presence_get_presence_type (presence),
+                  presence_type) > 0
+              && TPF_IS_PERSONA (presence))
+            {
+              presence_type = folks_presence_get_presence_type (presence);
+              tp_contact = tpf_persona_get_contact (TPF_PERSONA (l->data));
+            }
+        }
+    }
+
+  if (tp_contact != NULL)
+    {
+      priv->contact = tp_contact;
+      g_object_add_weak_pointer (G_OBJECT (tp_contact),
+          (gpointer *) &priv->contact);
+    }
+}
+
 typedef struct {
   EmpathyIndividualWidget *widget; /* weak */
   TpContact *contact; /* owned */
@@ -324,18 +371,6 @@ details_request_cb (TpContact *contact,
 
       tp_clear_object (&priv->details_cancellable);
 
-      /* We need a (weak) pointer to the contact so that we can disconnect the
-       * signal handler on deconstruction. */
-      if (priv->contact_info_contact != NULL)
-        {
-          g_object_remove_weak_pointer (G_OBJECT (priv->contact_info_contact),
-            (gpointer *) &priv->contact_info_contact);
-        }
-
-      priv->contact_info_contact = contact;
-      g_object_add_weak_pointer (G_OBJECT (contact),
-          (gpointer *) &priv->contact_info_contact);
-
       g_signal_connect (contact, "notify::contact-info",
           (GCallback) details_notify_cb, self);
     }
@@ -387,28 +422,10 @@ details_update (EmpathyIndividualWidget *self)
 
   gtk_widget_hide (priv->vbox_details);
 
-  if (priv->individual != NULL)
-    {
-      /* FIXME: We take the first TpContact we find and only use its details.
-       * It would be a lot better if we would get the details for every
-       * TpContact in the Individual and merge them all, but that requires
-       * vCard support in libfolks for it to not be hideously complex.
-       * (bgo#627399) */
-      GList *personas, *l;
-
-      personas = folks_individual_get_personas (priv->individual);
-      for (l = personas; l != NULL; l = l->next)
-        {
-          if (TPF_IS_PERSONA (l->data))
-            {
-              tp_contact = tpf_persona_get_contact (TPF_PERSONA (l->data));
-              if (tp_contact != NULL)
-                break;
-            }
-        }
-    }
+  if (priv->contact == NULL)
+    update_weak_contact (self);
 
-  if (tp_contact != NULL)
+  if (priv->contact != NULL)
     {
       GQuark features[] = { TP_CONNECTION_FEATURE_CONTACT_INFO, 0 };
       TpConnection *connection;
@@ -417,7 +434,7 @@ details_update (EmpathyIndividualWidget *self)
       data = g_slice_new (DetailsData);
       data->widget = self;
       g_object_add_weak_pointer (G_OBJECT (self), (gpointer *) &data->widget);
-      data->contact = g_object_ref (tp_contact);
+      data->contact = g_object_ref (priv->contact);
 
       /* First, make sure the CONTACT_INFO feature is ready on the connection */
       connection = tp_contact_get_connection (tp_contact);
@@ -785,6 +802,64 @@ location_update (EmpathyIndividualWidget *self)
     gtk_widget_show (priv->vbox_location);
 }
 
+static void
+client_types_notify_cb (TpContact *contact,
+    GParamSpec *pspec,
+    EmpathyIndividualWidget *self)
+{
+  client_types_update (self);
+}
+
+static void
+client_types_update (EmpathyIndividualWidget *self)
+{
+  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
+  const gchar * const *types;
+
+  if (!(priv->flags & EMPATHY_INDIVIDUAL_WIDGET_SHOW_CLIENT_TYPES) ||
+      priv->individual == NULL)
+    {
+      gtk_widget_hide (priv->hbox_client_types);
+      return;
+    }
+
+  if (priv->contact == NULL)
+    update_weak_contact (self);
+
+  /* let's try that again... */
+  if (priv->contact == NULL)
+    return;
+
+  types = tp_contact_get_client_types (priv->contact);
+
+  if (types != NULL
+      && g_strv_length ((gchar **) types) > 0
+      && !tp_strdiff (types[0], "phone"))
+    {
+      gtk_widget_show (priv->hbox_client_types);
+    }
+  else
+    {
+      gtk_widget_hide (priv->hbox_client_types);
+    }
+
+  g_signal_connect (priv->contact, "notify::client-types",
+      (GCallback) client_types_notify_cb, self);
+}
+
+static void
+remove_weak_contact (EmpathyIndividualWidget *self)
+{
+  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
+
+  if (priv->contact == NULL)
+    return;
+
+  g_object_remove_weak_pointer (G_OBJECT (priv->contact),
+      (gpointer *) &priv->contact);
+  priv->contact = NULL;
+}
+
 static EmpathyAvatar *
 persona_dup_avatar (FolksPersona *persona)
 {
@@ -1741,14 +1816,8 @@ remove_individual (EmpathyIndividualWidget *self)
         remove_persona (self, FOLKS_PERSONA (l->data));
       individual_table_destroy (self);
 
-      if (priv->contact_info_contact != NULL)
-        {
-          g_signal_handlers_disconnect_by_func (priv->contact_info_contact,
-              details_notify_cb, self);
-          g_object_remove_weak_pointer (G_OBJECT (priv->contact_info_contact),
-              (gpointer *) &priv->contact_info_contact);
-          priv->contact_info_contact = NULL;
-        }
+      if (priv->contact != NULL)
+        remove_weak_contact (self);
 
       tp_clear_object (&priv->individual);
     }
@@ -1847,6 +1916,7 @@ empathy_individual_widget_init (EmpathyIndividualWidget *self)
       "vbox_details", &priv->vbox_details,
       "table_details", &priv->table_details,
       "hbox_details_requested", &priv->hbox_details_requested,
+      "hbox_client_types", &priv->hbox_client_types,
       NULL);
   g_free (filename);
 
@@ -2080,4 +2150,5 @@ empathy_individual_widget_set_individual (EmpathyIndividualWidget *self,
   groups_update (self);
   details_update (self);
   location_update (self);
+  client_types_update (self);
 }
diff --git a/libempathy-gtk/empathy-individual-widget.h b/libempathy-gtk/empathy-individual-widget.h
index a968d14..24a7f3d 100644
--- a/libempathy-gtk/empathy-individual-widget.h
+++ b/libempathy-gtk/empathy-individual-widget.h
@@ -63,6 +63,7 @@ typedef enum
   EMPATHY_INDIVIDUAL_WIDGET_SHOW_LOCATION  = 1 << 4,
   EMPATHY_INDIVIDUAL_WIDGET_SHOW_DETAILS = 1 << 5,
   EMPATHY_INDIVIDUAL_WIDGET_SHOW_PERSONAS = 1 << 6,
+  EMPATHY_INDIVIDUAL_WIDGET_SHOW_CLIENT_TYPES = 1 << 7,
 } EmpathyIndividualWidgetFlags;
 
 #define EMPATHY_TYPE_INDIVIDUAL_WIDGET (empathy_individual_widget_get_type ())
diff --git a/libempathy-gtk/empathy-individual-widget.ui b/libempathy-gtk/empathy-individual-widget.ui
index 5fb3823..dcfc83a 100644
--- a/libempathy-gtk/empathy-individual-widget.ui
+++ b/libempathy-gtk/empathy-individual-widget.ui
@@ -88,6 +88,35 @@
       </packing>
     </child>
     <child>
+      <object class="GtkHBox" id="hbox_client_types">
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkImage" id="image_phone">
+            <property name="visible">True</property>
+            <property name="icon_name">phone</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Online from a phone or mobile device</property>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
       <object class="EmpathyGroupsWidget" id="groups_widget"/>
       <packing>
         <property name="position">2</property>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]