[balsa/thread-date] mailbox: Sort by thread date



commit 858d152051a129c7a7149b9201e708d0215f3083
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Sun Aug 5 11:02:23 2018 -0400

    mailbox: Sort by thread date
    
    The 'thread-date' of a message is the date of the most recent message in
    the thread that it heads. This commit changes 'sort by date' to 'sort by
    thread-date'.
    
    It does not change the displayed date of a message, which continues to
    be its real date. But an old thread with a recent reply is sorted by the
    date of the reply, thus avoiding the hiding of recent messages in old
    threads.

 libbalsa/mailbox.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++------
 libbalsa/mailbox.h |  1 +
 2 files changed, 58 insertions(+), 7 deletions(-)
---
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index f689d9c4a..ee4c2b4d2 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -3333,13 +3333,62 @@ mbox_compare_subject(LibBalsaMailboxIndexEntry * message_a,
     return g_ascii_strcasecmp(message_a->subject, message_b->subject);
 }
 
+/* Thread date stuff */
+
+typedef struct {
+    time_t           thread_date;
+    LibBalsaMailbox *mbox;
+} LibBalsaMailboxThreadDateInfo;
+
+static gboolean
+mbox_get_thread_date_traverse_func(GNode   *node,
+                                   gpointer data)
+{
+    LibBalsaMailboxThreadDateInfo *info = data;
+    guint msgno = GPOINTER_TO_UINT(node->data);
+    LibBalsaMailboxIndexEntry *message =
+        g_ptr_array_index(info->mbox->mindex, msgno - 1);
+
+    if (message != NULL) {
+        time_t msg_date = message->msg_date;
+
+        if (msg_date > info->thread_date)
+            info->thread_date = msg_date;
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static time_t
+mbox_get_thread_date(const SortTuple *tuple,
+                     LibBalsaMailbox *mbox)
+{
+    if (tuple->thread_date == 0) {
+        LibBalsaMailboxThreadDateInfo info = { 0, mbox };
+
+        g_node_traverse(tuple->node, G_IN_ORDER, G_TRAVERSE_ALL, -1,
+                        mbox_get_thread_date_traverse_func, &info);
+
+        /* Cast away the 'const' qualifier so that we can cache the
+         * thread date: */
+        ((SortTuple *) tuple)->thread_date = info.thread_date;
+    }
+
+    return tuple->thread_date;
+}
+
 static gint
-mbox_compare_date(LibBalsaMailboxIndexEntry * message_a,
-                  LibBalsaMailboxIndexEntry * message_b)
+mbox_compare_date(const SortTuple *a,
+                  const SortTuple *b,
+                  LibBalsaMailbox *mbox)
 {
-    return message_a->msg_date - message_b->msg_date;
+    return mbox_get_thread_date(a, mbox) - mbox_get_thread_date(b, mbox);
 }
 
+/* End of thread date stuff */
+
 static gint
 mbox_compare_size(LibBalsaMailboxIndexEntry * message_a,
                   LibBalsaMailboxIndexEntry * message_b)
@@ -3378,7 +3427,7 @@ mbox_compare_func(const SortTuple * a,
            retval = mbox_compare_subject(message_a, message_b);
            break;
        case LB_MAILBOX_SORT_DATE:
-           retval = mbox_compare_date(message_a, message_b);
+           retval = mbox_compare_date(a, b, mbox);
            break;
        case LB_MAILBOX_SORT_SIZE:
            retval = mbox_compare_size(message_a, message_b);
@@ -3397,9 +3446,9 @@ mbox_compare_func(const SortTuple * a,
             case LB_MAILBOX_SORT_SUBJECT:
                 retval = mbox_compare_subject(message_a, message_b);
                 break;
-            case LB_MAILBOX_SORT_DATE:
-                retval = mbox_compare_date(message_a, message_b);
-                break;
+           case LB_MAILBOX_SORT_DATE:
+               retval = mbox_compare_date(a, b, mbox);
+               break;
             case LB_MAILBOX_SORT_SIZE:
                 retval = mbox_compare_size(message_a, message_b);
                 break;
@@ -3468,6 +3517,7 @@ lbm_sort(LibBalsaMailbox * mbox, GNode * parent)
             /* We have the sort fields. */
             sort_tuple.offset = node_array->len;
             sort_tuple.node = tmp_node;
+            sort_tuple.thread_date = 0;
             g_array_append_val(sort_array, sort_tuple);
         }
         g_ptr_array_add(node_array, tmp_node);
diff --git a/libbalsa/mailbox.h b/libbalsa/mailbox.h
index 4bff62ef9..a966082b1 100644
--- a/libbalsa/mailbox.h
+++ b/libbalsa/mailbox.h
@@ -82,6 +82,7 @@ typedef struct _SortTuple SortTuple;
 struct _SortTuple {
     guint offset;
     GNode *node;
+    time_t thread_date;
 };
 
 typedef enum {


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