X-Git-Url: https://git.0d.be/?p=empathy.git;a=blobdiff_plain;f=libempathy-gtk%2Fempathy-roster-contact.c;h=d98ca13fca064cc8c6810687e1d3d6d9cd5bd08a;hp=22b360075671217efaeb4b6b9c2d4cbb392503c7;hb=HEAD;hpb=6338748568d1a37c423568e91e60eb838188a3c2 diff --git a/libempathy-gtk/empathy-roster-contact.c b/libempathy-gtk/empathy-roster-contact.c index 22b36007..d98ca13f 100644 --- a/libempathy-gtk/empathy-roster-contact.c +++ b/libempathy-gtk/empathy-roster-contact.c @@ -3,11 +3,12 @@ #include #include +#include #include "empathy-ui-utils.h" #include "empathy-utils.h" -G_DEFINE_TYPE (EmpathyRosterContact, empathy_roster_contact, GTK_TYPE_ALIGNMENT) +G_DEFINE_TYPE (EmpathyRosterContact, empathy_roster_contact, GTK_TYPE_LIST_BOX_ROW) #define AVATAR_SIZE 48 @@ -17,6 +18,7 @@ enum PROP_GROUP, PROP_ONLINE, PROP_ALIAS, + PROP_MOST_RECENT_EVENT, N_PROPS }; @@ -32,12 +34,17 @@ static guint signals[LAST_SIGNAL]; struct _EmpathyRosterContactPriv { FolksIndividual *individual; + EmpathyContact *contact; gchar *group; + TplLogManager *log_manager; + TplEvent *most_recent_event; + GtkWidget *avatar; GtkWidget *first_line_alig; GtkWidget *alias; GtkWidget *presence_msg; + GtkWidget *most_recent_msg; GtkWidget *presence_icon; GtkWidget *phone_icon; @@ -76,6 +83,9 @@ empathy_roster_contact_get_property (GObject *object, case PROP_ALIAS: g_value_set_string (value, get_alias (self)); break; + case PROP_MOST_RECENT_EVENT: + g_value_set_object (value, self->priv->most_recent_event); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -106,6 +116,24 @@ empathy_roster_contact_set_property (GObject *object, } } +gint64 +empathy_roster_contact_get_most_recent_timestamp (EmpathyRosterContact *contact) +{ + if (contact->priv->most_recent_event) { + return tpl_event_get_timestamp (contact->priv->most_recent_event); + } + return 0; +} + +static const gchar* +get_most_recent_message (EmpathyRosterContact *contact) +{ + if (contact->priv->most_recent_event) { + return tpl_text_event_get_message (TPL_TEXT_EVENT(contact->priv->most_recent_event)); + } + return NULL; +} + static void avatar_loaded_cb (GObject *source, GAsyncResult *result, @@ -124,7 +152,7 @@ avatar_loaded_cb (GObject *source, if (pixbuf == NULL) { - pixbuf = empathy_pixbuf_from_icon_name_sized ( + pixbuf = tpaw_pixbuf_from_icon_name_sized ( TPAW_IMAGE_AVATAR_DEFAULT, AVATAR_SIZE); } @@ -137,6 +165,29 @@ out: tp_weak_ref_destroy (wr); } +static void +update_most_recent_msg (EmpathyRosterContact *self) +{ + const gchar* msg = get_most_recent_message (self); + + if (tp_str_empty (msg)) + { + gtk_alignment_set (GTK_ALIGNMENT (self->priv->first_line_alig), + 0, 0.5, 1, 1); + gtk_widget_hide (self->priv->most_recent_msg); + } + else + { + gchar *tmp = g_strdup (msg); + if (strchr(tmp, '\n')) strchr(tmp, '\n')[0] = 0; + gtk_label_set_text (GTK_LABEL (self->priv->most_recent_msg), tmp); + gtk_alignment_set (GTK_ALIGNMENT (self->priv->first_line_alig), + 0, 0.75, 1, 1); + gtk_misc_set_alignment (GTK_MISC (self->priv->most_recent_msg), 0, 0.25); + g_free (tmp); + } +} + static void update_avatar (EmpathyRosterContact *self) { @@ -290,10 +341,36 @@ presence_status_changed_cb (FolksIndividual *individual, update_online (self); } +static void +get_filtered_events (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + EmpathyRosterContact *contact = EMPATHY_ROSTER_CONTACT (user_data); + GError *error; + GList *events; + + error = NULL; + if (!tpl_log_manager_get_filtered_events_finish (contact->priv->log_manager, res, &events, &error)) + { + g_warning ("Unable to get events: %s", error->message); + g_error_free (error); + goto out; + } + + if (events) { + contact->priv->most_recent_event = TPL_EVENT (events->data); + g_object_notify (G_OBJECT (contact), "most-recent-event"); + update_most_recent_msg (contact); + } + + out: + return; +} + static void empathy_roster_contact_constructed (GObject *object) { EmpathyRosterContact *self = EMPATHY_ROSTER_CONTACT (object); + TplEntity *tpl_entity; void (*chain_up) (GObject *) = ((GObjectClass *) empathy_roster_contact_parent_class)->constructed; @@ -302,6 +379,26 @@ empathy_roster_contact_constructed (GObject *object) g_assert (FOLKS_IS_INDIVIDUAL (self->priv->individual)); + self->priv->contact = empathy_contact_dup_best_for_action ( + self->priv->individual, + EMPATHY_ACTION_CHAT); + + self->priv->log_manager = tpl_log_manager_dup_singleton (); + + tpl_entity = tpl_entity_new_from_tp_contact ( + empathy_contact_get_tp_contact (self->priv->contact), + TPL_ENTITY_CONTACT); + tpl_log_manager_get_filtered_events_async( + self->priv->log_manager, + empathy_contact_get_account (self->priv->contact), + tpl_entity, + TPL_EVENT_MASK_TEXT, + 1, + NULL, + NULL, + get_filtered_events, + object); + tp_g_signal_connect_object (self->priv->individual, "notify::avatar", G_CALLBACK (avatar_changed_cb), self, 0); tp_g_signal_connect_object (self->priv->individual, "notify::alias", @@ -342,6 +439,7 @@ empathy_roster_contact_finalize (GObject *object) g_free (self->priv->group); g_free (self->priv->event_icon); + g_object_unref (self->priv->log_manager); if (chain_up != NULL) chain_up (object); @@ -384,18 +482,28 @@ empathy_roster_contact_class_init ( G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (oclass, PROP_ALIAS, spec); + spec = g_param_spec_object ("most-recent-event", "Most recent event", + "Most recent event", + TPL_TYPE_EVENT, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_MOST_RECENT_EVENT, spec); + g_type_class_add_private (klass, sizeof (EmpathyRosterContactPriv)); } static void empathy_roster_contact_init (EmpathyRosterContact *self) { - GtkWidget *main_box, *box, *first_line_box; + GtkWidget *alig, *main_box, *box, *first_line_box; GtkStyleContext *context; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_ROSTER_CONTACT, EmpathyRosterContactPriv); + alig = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alig); + gtk_alignment_set_padding (GTK_ALIGNMENT (alig), 4, 4, 4, 12); + main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); /* Avatar */ @@ -440,12 +548,24 @@ empathy_roster_contact_init (EmpathyRosterContact *self) self->priv->presence_msg = gtk_label_new (NULL); gtk_label_set_ellipsize (GTK_LABEL (self->priv->presence_msg), PANGO_ELLIPSIZE_END); + /* gtk_box_pack_start (GTK_BOX (box), self->priv->presence_msg, TRUE, TRUE, 0); gtk_widget_show (self->priv->presence_msg); + */ context = gtk_widget_get_style_context (self->priv->presence_msg); gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL); + /* Most recent message */ + self->priv->most_recent_msg = gtk_label_new (NULL); + gtk_label_set_ellipsize (GTK_LABEL (self->priv->most_recent_msg), + PANGO_ELLIPSIZE_END); + gtk_box_pack_start (GTK_BOX (box), self->priv->most_recent_msg, TRUE, TRUE, 0); + gtk_widget_show (self->priv->most_recent_msg); + + context = gtk_widget_get_style_context (self->priv->most_recent_msg); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL); + /* Presence icon */ self->priv->presence_icon = gtk_image_new (); @@ -453,7 +573,8 @@ empathy_roster_contact_init (EmpathyRosterContact *self) FALSE, FALSE, 0); gtk_widget_show (self->priv->presence_icon); - gtk_container_add (GTK_CONTAINER (self), main_box); + gtk_container_add (GTK_CONTAINER (self), alig); + gtk_container_add (GTK_CONTAINER (alig), main_box); gtk_widget_show (main_box); } @@ -466,10 +587,6 @@ empathy_roster_contact_new (FolksIndividual *individual, return g_object_new (EMPATHY_TYPE_ROSTER_CONTACT, "individual", individual, "group", group, - "bottom-padding", 4, - "top-padding", 4, - "left-padding", 4, - "right-padding", 12, NULL); } @@ -479,6 +596,12 @@ empathy_roster_contact_get_individual (EmpathyRosterContact *self) return self->priv->individual; } +EmpathyContact * +empathy_roster_contact_get_contact (EmpathyRosterContact *self) +{ + return self->priv->contact; +} + gboolean empathy_roster_contact_is_online (EmpathyRosterContact *self) {