aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-individual-view.c3
-rw-r--r--libempathy-gtk/empathy-individual-widget.c157
-rw-r--r--libempathy-gtk/empathy-individual-widget.h1
-rw-r--r--libempathy-gtk/empathy-individual-widget.ui29
4 files changed, 146 insertions, 44 deletions
diff --git a/libempathy-gtk/empathy-individual-view.c b/libempathy-gtk/empathy-individual-view.c
index 94e60a41c..4fef0d733 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 5f180c0dc..72acfd8a5 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 a968d14f3..24a7f3dc3 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 5fb382363..dcfc83a47 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>