[Users] [PATCH 1/2] Allow sorting by thread number in addition to thread date

Alexander Lyons Harkness me at bearbin.net
Sun Aug 25 17:53:29 CEST 2019


This allows effectively sorting by received-date of the last
message in each thread. Sorting by date leads to unexpected
behaviour sometimes, as some messages' Date headers are missing
or incorrect.

Signed-off-by: Alexander Lyons Harkness <me at bearbin.net>
---
This patch adds new UI without translations - do these need to be
added or not?

 src/folder.c          |  2 ++
 src/folder.h          |  3 ++-
 src/mainwindow.c      |  4 ++++
 src/prefs_summaries.c |  1 +
 src/procmsg.h         |  1 +
 src/summaryview.c     | 41 ++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/src/folder.c b/src/folder.c
index b9a9c99f8..642eeb872 100644
--- a/src/folder.c
+++ b/src/folder.c
@@ -632,6 +632,8 @@ void folder_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag)
 				item->sort_key = SORT_BY_TAGS;
 			else if (!strcmp(attr->value, "thread_date"))
 				item->sort_key = SORT_BY_THREAD_DATE;
+			else if (!strcmp(attr->value, "thread_number"))
+				item->sort_key = SORT_BY_THREAD_NUMBER;
 		} else if (!strcmp(attr->name, "sort_type")) {
 			if (!strcmp(attr->value, "ascending"))
 				item->sort_type = SORT_ASCENDING;
diff --git a/src/folder.h b/src/folder.h
index 7013a7c33..67db4c35c 100644
--- a/src/folder.h
+++ b/src/folder.h
@@ -82,7 +82,8 @@ typedef enum
 	SORT_BY_TO,
 	SORT_BY_LOCKED,
 	SORT_BY_TAGS,
-	SORT_BY_THREAD_DATE
+	SORT_BY_THREAD_DATE,
+	SORT_BY_THREAD_NUMBER,
 } FolderSortKey;
 
 typedef enum
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 60fa66d29..8bac1471f 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -864,6 +864,7 @@ static GtkRadioActionEntry mainwin_layout_radio_entries[] = { /* set_layout_cb *
 #endif
 static GtkRadioActionEntry mainwin_sort_radio_entries[] = { /* sort_summary_cb */
 	{"View/Sort/Number",                     NULL, N_("By _number"), NULL, NULL, SORT_BY_NUMBER }, /* radio SORT_BY_NUMBER */
+	{"View/Sort/ThreadNumber",               NULL, N_("By thread number"), NULL, NULL, SORT_BY_THREAD_NUMBER }, /* radio SORT_BY_THREAD_NUMBER */
 	{"View/Sort/Size",                       NULL, N_("By s_ize"), NULL, NULL, SORT_BY_SIZE }, /* radio SORT_BY_SIZE */
 	{"View/Sort/Date",                       NULL, N_("By _date"), NULL, NULL, SORT_BY_DATE }, /* radio SORT_BY_DATE */
 	{"View/Sort/ThreadDate",                 NULL, N_("By thread date"), NULL, NULL, SORT_BY_THREAD_DATE }, /* radio SORT_BY_THREAD_DATE */
@@ -1584,6 +1585,7 @@ MainWindow *main_window_create()
 
 	MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "Sort", "View/Sort", GTK_UI_MANAGER_MENU)
 	MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Sort", "Number", "View/Sort/Number", GTK_UI_MANAGER_MENUITEM)
+	MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Sort", "ThreadNumber", "View/Sort/ThreadNumber", GTK_UI_MANAGER_MENUITEM)
 	MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Sort", "Size", "View/Sort/Size", GTK_UI_MANAGER_MENUITEM)
 	MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Sort", "Date", "View/Sort/Date", GTK_UI_MANAGER_MENUITEM)
 	MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Sort", "ThreadDate", "View/Sort/ThreadDate", GTK_UI_MANAGER_MENUITEM)
@@ -3296,6 +3298,8 @@ do { \
 	switch (summaryview->sort_key) {
 	case SORT_BY_NUMBER:
 		menu_path = "Menu/View/Sort/Number"; break;
+	case SORT_BY_THREAD_NUMBER:
+		menu_path = "Menu/View/Sort/ThreadNumber"; break;
 	case SORT_BY_SIZE:
 		menu_path = "Menu/View/Sort/Size"; break;
 	case SORT_BY_DATE:
diff --git a/src/prefs_summaries.c b/src/prefs_summaries.c
index cb2a5d81b..e88a3f52d 100644
--- a/src/prefs_summaries.c
+++ b/src/prefs_summaries.c
@@ -609,6 +609,7 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
 	gtk_widget_show(optmenu_sort_key);
 
 	COMBOBOX_ADD(menu, _("Number"), SORT_BY_NUMBER);
+	COMBOBOX_ADD(menu, _("Thread number"), SORT_BY_THREAD_NUMBER);
 	COMBOBOX_ADD(menu, _("Size"), SORT_BY_SIZE);
 	COMBOBOX_ADD(menu, _("Date"), SORT_BY_DATE);
 	COMBOBOX_ADD(menu, _("Thread date"), SORT_BY_THREAD_DATE);
diff --git a/src/procmsg.h b/src/procmsg.h
index 1dda93dd8..14ed1cfe3 100644
--- a/src/procmsg.h
+++ b/src/procmsg.h
@@ -193,6 +193,7 @@ struct _MsgInfo
 	time_t mtime;
 	time_t date_t;
 	time_t thread_date;
+	guint thread_msgnum;
 
 	MsgFlags flags;
 
diff --git a/src/summaryview.c b/src/summaryview.c
index 96016b9d0..37142d86b 100644
--- a/src/summaryview.c
+++ b/src/summaryview.c
@@ -361,6 +361,9 @@ static gint summary_cmp_by_mime		(GtkCMCList		*clist,
 static gint summary_cmp_by_num		(GtkCMCList		*clist,
 					 gconstpointer		 ptr1,
 					 gconstpointer		 ptr2);
+static gint summary_cmp_by_thread_num   (GtkCMCList             *clist,
+					 gconstpointer           ptr1,
+					 gconstpointer           ptr2);
 static gint summary_cmp_by_size		(GtkCMCList		*clist,
 					 gconstpointer		 ptr1,
 					 gconstpointer		 ptr2);
@@ -3063,6 +3066,9 @@ void summary_sort(SummaryView *summaryview,
 	case SORT_BY_NUMBER:
 		cmp_func = (GtkCMCListCompareFunc)summary_cmp_by_num;
 		break;
+	case SORT_BY_THREAD_NUMBER:
+		cmp_func = (GtkCMCListCompareFunc)summary_cmp_by_thread_num;
+		break;
 	case SORT_BY_SIZE:
 		cmp_func = (GtkCMCListCompareFunc)summary_cmp_by_size;
 		break;
@@ -3146,20 +3152,36 @@ static gboolean summary_update_thread_age(GNode *node, gpointer data)
 		*most_recent = msginfo->date_t;
 	}
 	return FALSE;
+}
+
+static gboolean summary_update_thread_number(GNode *node, gpointer data)
+{
+	MsgInfo *msginfo = node->data;
+	guint *most_recent = (guint *)data;
+
+	if (msginfo->msgnum > *most_recent) {
+		*most_recent = msginfo->msgnum;
+	}
+	return FALSE;
 }	
 
 static void summary_find_thread_age(GNode *gnode)
 {
 	MsgInfo *msginfo = (MsgInfo *)gnode->data;
 	time_t most_recent;
+	guint most_recent_num;
 
 	if (!msginfo)
 		return;
-	most_recent = msginfo->thread_date = msginfo->date_t;
 
+	most_recent = msginfo->thread_date = msginfo->date_t;
 	g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, summary_update_thread_age, &most_recent);
 
+	most_recent_num = msginfo->thread_msgnum = msginfo->msgnum;
+	g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, summary_update_thread_number, &most_recent_num);
+
 	msginfo->thread_date = most_recent;
+	msginfo->thread_msgnum = most_recent_num;
 }
 
 static gboolean summary_update_is_read(GNode *node, gpointer data)
@@ -7780,6 +7802,23 @@ static gint summary_cmp_by_subject(GtkCMCList *clist,
 	return (res != 0)? res: summary_cmp_by_date(clist, ptr1, ptr2);
 }
 
+static gint summary_cmp_by_thread_num(GtkCMCList *clist,
+				      gconstpointer ptr1,
+				      gconstpointer ptr2)
+{
+	MsgInfo *msginfo1 = ((GtkCMCListRow *)ptr1)->data;
+	MsgInfo *msginfo2 = ((GtkCMCListRow *)ptr2)->data;
+	gint res;
+	if (!msginfo1 || !msginfo2)
+		return -1;
+
+	res = (msginfo1->thread_msgnum - msginfo2->thread_msgnum);
+
+	if (!msginfo1->thread_msgnum || !msginfo2->thread_msgnum)
+		res = summary_cmp_by_num(clist, ptr1, ptr2);
+	return res;
+}
+
 static gint summary_cmp_by_thread_date(GtkCMCList *clist,
 				   gconstpointer ptr1,
 				   gconstpointer ptr2)
-- 
2.23.0.rc1



More information about the Users mailing list