diff --git a/src/client/ui/main-window.vala b/src/client/ui/main-window.vala index fee64804..abccf574 100644 --- a/src/client/ui/main-window.vala +++ b/src/client/ui/main-window.vala @@ -214,7 +214,7 @@ public class MainWindow : Gtk.Window { yield current_folder.open_async(true); - current_folder.lazy_list_email_async(1, 1000, Geary.Email.Field.ENVELOPE, + current_folder.lazy_list_email_async(1, 1000, MessageListStore.REQUIRED_FIELDS, on_list_email_ready); } diff --git a/src/client/ui/message-list-store.vala b/src/client/ui/message-list-store.vala index 3a69a73f..94f3c422 100644 --- a/src/client/ui/message-list-store.vala +++ b/src/client/ui/message-list-store.vala @@ -5,6 +5,9 @@ */ public class MessageListStore : Gtk.TreeStore { + public const Geary.Email.Field REQUIRED_FIELDS = + Geary.Email.Field.ENVELOPE | Geary.Email.Field.PROPERTIES; + public enum Column { DATE, FROM, @@ -56,17 +59,28 @@ public class MessageListStore : Gtk.TreeStore { set_sort_column_id(TreeSortable.DEFAULT_SORT_COLUMN_ID, Gtk.SortType.DESCENDING); } - // The Email should've been fetched with Geary.Email.Field.ENVELOPE, at least. + // The Email should've been fetched with REQUIRED_FIELDS. public void append_envelope(Geary.Email envelope) { assert(envelope.fields.fulfills(Geary.Email.Field.ENVELOPE)); Gtk.TreeIter iter; append(out iter, null); + string? pre = null;; + string? post = null; + if (envelope.properties != null) { + pre = envelope.properties.is_unread() ? "" : null; + post = envelope.properties.is_unread() ? "" : null; + } + + string date = to_markup(Date.pretty_print(envelope.date.value), pre, post); + string from = to_markup(envelope.from[0].get_short_address(), pre, post); + string subject = to_markup(envelope.subject.value, pre, post); + set(iter, - Column.DATE, Date.pretty_print(envelope.date.value), - Column.FROM, envelope.from[0].get_short_address(), - Column.SUBJECT, envelope.subject.value, + Column.DATE, date, + Column.FROM, from, + Column.SUBJECT, subject, Column.MESSAGE_OBJECT, envelope ); } @@ -96,5 +110,13 @@ public class MessageListStore : Gtk.TreeStore { // stabilize sort by using the mail's position, which is always unique in a folder return aenvelope.location.position - benvelope.location.position; } + + private static string to_markup(string str, string? pre = null, string? post = null) { + return "%s%s%s".printf( + (pre != null) ? pre : "", + Markup.escape_text(str), + (post != null) ? post : "" + ); + } } diff --git a/src/client/ui/message-list-view.vala b/src/client/ui/message-list-view.vala index de4aa7fb..a1bf0e40 100644 --- a/src/client/ui/message-list-view.vala +++ b/src/client/ui/message-list-view.vala @@ -13,10 +13,10 @@ public class MessageListView : Gtk.TreeView { Gtk.CellRendererText date_renderer = new Gtk.CellRendererText(); date_renderer.xalign = 1.0f; append_column(create_column(MessageListStore.Column.FROM, new Gtk.CellRendererText(), - "text", 200)); + "markup", 200)); append_column(create_column(MessageListStore.Column.SUBJECT, new Gtk.CellRendererText(), - "text", 400)); - append_column(create_column(MessageListStore.Column.DATE, date_renderer, "text", 100)); + "markup", 400)); + append_column(create_column(MessageListStore.Column.DATE, date_renderer, "markup", 100)); get_selection().changed.connect(on_selection_changed); } diff --git a/src/engine/api/geary-email-properties.vala b/src/engine/api/geary-email-properties.vala index 18aefa44..7d38939d 100644 --- a/src/engine/api/geary-email-properties.vala +++ b/src/engine/api/geary-email-properties.vala @@ -5,5 +5,9 @@ */ public abstract class Geary.EmailProperties : Object { + public EmailProperties() { + } + + public abstract bool is_unread(); } diff --git a/src/engine/imap/api/imap-email-properties.vala b/src/engine/imap/api/imap-email-properties.vala index 48559b21..38a7cb76 100644 --- a/src/engine/imap/api/imap-email-properties.vala +++ b/src/engine/imap/api/imap-email-properties.vala @@ -10,5 +10,9 @@ public class Geary.Imap.EmailProperties : Geary.EmailProperties { public EmailProperties(MessageFlags flags) { this.flags = flags; } + + public override bool is_unread() { + return !flags.contains(MessageFlag.SEEN); + } }