From f94018474b36d3870a25c19f0a90b473dfbbcf9c Mon Sep 17 00:00:00 2001 From: Jim Nelson Date: Fri, 24 Jun 2011 16:28:05 -0700 Subject: [PATCH] Sort folders in sidebar (case-insensitive): #3692 This is the first half of #3692, sorting the folders in the sidebar. Also, this patch ensures that messages are listed in chronologically descending order. (No option to change either sorts at this time.) --- src/client/ui/FolderListStore.vala | 19 +++++++++++++++++++ src/client/ui/MainWindow.vala | 2 +- src/client/ui/MessageListStore.vala | 21 +++++++++++++++++++-- src/engine/api/Email.vala | 10 +++++++++- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/client/ui/FolderListStore.vala b/src/client/ui/FolderListStore.vala index 8febb083..c0c7c20c 100644 --- a/src/client/ui/FolderListStore.vala +++ b/src/client/ui/FolderListStore.vala @@ -4,6 +4,13 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ +// These are defined here due to this bug: +// https://bugzilla.gnome.org/show_bug.cgi?id=653379 +public enum TreeSortable { + DEFAULT_SORT_COLUMN_ID = -1, + UNSORTED_SORT_COLUMN_ID = -2 +} + public class FolderListStore : Gtk.TreeStore { public enum Column { NAME, @@ -40,6 +47,8 @@ public class FolderListStore : Gtk.TreeStore { public FolderListStore() { set_column_types(Column.get_types()); + set_default_sort_func(sort_by_name); + set_sort_column_id(TreeSortable.DEFAULT_SORT_COLUMN_ID, Gtk.SortType.ASCENDING); } public void add_folder(Geary.Folder folder) { @@ -67,5 +76,15 @@ public class FolderListStore : Gtk.TreeStore { return folder; } + + private int sort_by_name(Gtk.TreeModel model, Gtk.TreeIter aiter, Gtk.TreeIter biter) { + string aname; + model.get(aiter, Column.NAME, out aname); + + string bname; + model.get(biter, Column.NAME, out bname); + + return strcmp(aname.down(), bname.down()); + } } diff --git a/src/client/ui/MainWindow.vala b/src/client/ui/MainWindow.vala index 7ca04086..a0610afa 100644 --- a/src/client/ui/MainWindow.vala +++ b/src/client/ui/MainWindow.vala @@ -31,7 +31,7 @@ public class MainWindow : Gtk.Window { public MainWindow() { title = GearyApplication.NAME; - set_default_size(800, 600); + set_default_size(862, 684); try { ui.add_ui_from_string(MAIN_MENU_XML, -1); diff --git a/src/client/ui/MessageListStore.vala b/src/client/ui/MessageListStore.vala index 970d67be..3a69a73f 100644 --- a/src/client/ui/MessageListStore.vala +++ b/src/client/ui/MessageListStore.vala @@ -52,12 +52,14 @@ public class MessageListStore : Gtk.TreeStore { public MessageListStore() { set_column_types(Column.get_types()); + set_default_sort_func(sort_by_date); + 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. - // - // TODO: Need to insert email's in their proper position, not merely append. public void append_envelope(Geary.Email envelope) { + assert(envelope.fields.fulfills(Geary.Email.Field.ENVELOPE)); + Gtk.TreeIter iter; append(out iter, null); @@ -79,5 +81,20 @@ public class MessageListStore : Gtk.TreeStore { return email; } + + private int sort_by_date(Gtk.TreeModel model, Gtk.TreeIter aiter, Gtk.TreeIter biter) { + Geary.Email aenvelope; + get(aiter, Column.MESSAGE_OBJECT, out aenvelope); + + Geary.Email benvelope; + get(biter, Column.MESSAGE_OBJECT, out benvelope); + + int diff = aenvelope.date.value.compare(benvelope.date.value); + if (diff != 0) + return diff; + + // stabilize sort by using the mail's position, which is always unique in a folder + return aenvelope.location.position - benvelope.location.position; + } } diff --git a/src/engine/api/Email.vala b/src/engine/api/Email.vala index 6a3f5780..67c3ca7d 100644 --- a/src/engine/api/Email.vala +++ b/src/engine/api/Email.vala @@ -32,10 +32,14 @@ public class Geary.Email : Object { }; } - public inline bool is_set(Field required_fields) { + public inline bool is_all_set(Field required_fields) { return (this & required_fields) == required_fields; } + public inline bool is_set(Field required_fields) { + return (this & required_fields) != 0; + } + public inline Field set(Field field) { return (this | field); } @@ -43,6 +47,10 @@ public class Geary.Email : Object { public inline Field clear(Field field) { return (this & ~(field)); } + + public inline bool fulfills(Field required_fields) { + return is_all_set(required_fields); + } } public Geary.EmailLocation location { get; private set; }