mirror of https://github.com/djcb/mu.git
Merge pull request #1444 from JulienMasson/threads-sorting
mu: add an option to ignore leader when sorting childs of a thread
This commit is contained in:
commit
b77b536d81
|
@ -353,36 +353,8 @@ container_cmp (MuContainer *a, MuContainer *b, MuMsgFieldId mfid)
|
|||
return mu_msg_cmp (a->msg, b->msg, mfid);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
container_is_leaf (const MuContainer *c)
|
||||
{
|
||||
return c->child == NULL;
|
||||
}
|
||||
|
||||
static MuContainer*
|
||||
container_max (MuContainer *a, MuContainer *b, MuMsgFieldId mfid)
|
||||
{
|
||||
return container_cmp (a, b, mfid) > 0 ? a : b;
|
||||
}
|
||||
|
||||
static MuContainer*
|
||||
find_sorted_tree_leader (MuContainer *root, SortFuncData *order)
|
||||
{
|
||||
MuContainer *last_child;
|
||||
|
||||
if (container_is_leaf (root))
|
||||
return root;
|
||||
|
||||
if (!order->descending)
|
||||
last_child = root->child->last;
|
||||
else /* reversed order, first is last */
|
||||
last_child = root->child;
|
||||
|
||||
return container_max (root, last_child->leader, order->mfid);
|
||||
}
|
||||
|
||||
static int
|
||||
sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data)
|
||||
sort_func_root (MuContainer *a, MuContainer *b, SortFuncData *data)
|
||||
{
|
||||
if (data->descending)
|
||||
return container_cmp (b->leader, a->leader, data->mfid);
|
||||
|
@ -390,10 +362,56 @@ sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data)
|
|||
return container_cmp (a->leader, b->leader, data->mfid);
|
||||
}
|
||||
|
||||
static int
|
||||
sort_func_child (MuContainer *a, MuContainer *b, SortFuncData *data)
|
||||
{
|
||||
if (data->descending)
|
||||
return container_cmp (a, b, data->mfid);
|
||||
else
|
||||
return container_cmp (b, a, data->mfid);
|
||||
}
|
||||
|
||||
static MuContainer*
|
||||
container_sort_real (MuContainer *c, SortFuncData *sfdata)
|
||||
container_sort(MuContainer *c, GCompareDataFunc func, SortFuncData *sfdata)
|
||||
{
|
||||
GSList *lst;
|
||||
|
||||
lst = mu_container_to_list (c);
|
||||
lst = g_slist_sort_with_data (lst, func, sfdata);
|
||||
c = mu_container_from_list (lst);
|
||||
g_slist_free (lst);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static MuContainer*
|
||||
container_sort_child (MuContainer *c, SortFuncData *sfdata)
|
||||
{
|
||||
MuContainer *cur, *leader;
|
||||
|
||||
if (!c)
|
||||
return NULL;
|
||||
|
||||
/* find leader */
|
||||
leader = c->leader;
|
||||
for (cur = c; cur; cur = cur->next) {
|
||||
if (cur->child)
|
||||
cur->child = container_sort_child (cur->child, sfdata);
|
||||
if (container_cmp (cur->leader, leader, sfdata->mfid) > 0)
|
||||
leader = cur->leader;
|
||||
}
|
||||
|
||||
c = container_sort(c, (GCompareDataFunc)sort_func_child, sfdata);
|
||||
|
||||
/* set parent's leader to the one found */
|
||||
c->parent->leader = leader;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static MuContainer*
|
||||
container_sort_root (MuContainer *c, SortFuncData *sfdata)
|
||||
{
|
||||
MuContainer *cur;
|
||||
|
||||
if (!c)
|
||||
|
@ -401,19 +419,10 @@ container_sort_real (MuContainer *c, SortFuncData *sfdata)
|
|||
|
||||
for (cur = c; cur; cur = cur->next) {
|
||||
if (cur->child)
|
||||
cur->child = container_sort_real (cur->child, sfdata);
|
||||
cur->leader = find_sorted_tree_leader (cur, sfdata);
|
||||
cur->child = container_sort_child (cur->child, sfdata);
|
||||
}
|
||||
|
||||
/* sort siblings */
|
||||
lst = mu_container_to_list (c);
|
||||
lst = g_slist_sort_with_data(lst,
|
||||
(GCompareDataFunc)sort_func_wrapper,
|
||||
sfdata);
|
||||
c = mu_container_from_list (lst);
|
||||
g_slist_free (lst);
|
||||
|
||||
return c;
|
||||
return container_sort (c, (GCompareDataFunc)sort_func_root, sfdata);
|
||||
}
|
||||
|
||||
MuContainer*
|
||||
|
@ -429,7 +438,7 @@ mu_container_sort (MuContainer *c, MuMsgFieldId mfid, gboolean descending,
|
|||
g_return_val_if_fail (c, NULL);
|
||||
g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), NULL);
|
||||
|
||||
return container_sort_real (c, &sfdata);
|
||||
return container_sort_root (c, &sfdata);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -158,9 +158,9 @@ test_mu_threads_01 (void)
|
|||
|
||||
const tinfo items [] = {
|
||||
{"0", "root0@msg.id", "root0"},
|
||||
{"0:0", "child0.0@msg.id", "Re: child 0.0"},
|
||||
{"0:1", "child0.1@msg.id", "Re: child 0.1"},
|
||||
{"0:1:0", "child0.1.0@msg.id", "Re: child 0.1.0"},
|
||||
{"0:0", "child0.1@msg.id", "Re: child 0.1"},
|
||||
{"0:0:0", "child0.1.0@msg.id", "Re: child 0.1.0"},
|
||||
{"0:1", "child0.0@msg.id", "Re: child 0.0"},
|
||||
{"1", "root1@msg.id", "root1"},
|
||||
{"2", "root2@msg.id", "root2"},
|
||||
/* next one's been promoted 2.0.0 => 2.0 */
|
||||
|
@ -169,8 +169,8 @@ test_mu_threads_01 (void)
|
|||
{"3", "child3.0.0.0.0@msg.id", "Re: child 3.0.0.0"},
|
||||
|
||||
/* two children of absent root 4.0 */
|
||||
{"4:0", "child4.0@msg.id", "Re: child 4.0"},
|
||||
{"4:1", "child4.1@msg.id", "Re: child 4.1"}
|
||||
{"4:0", "child4.1@msg.id", "Re: child 4.1"},
|
||||
{"4:1", "child4.0@msg.id", "Re: child 4.0"}
|
||||
};
|
||||
|
||||
xpath = fill_database (MU_TESTMAILDIR3);
|
||||
|
@ -308,13 +308,13 @@ test_mu_threads_sort_2nd_child_promotes_thread (void)
|
|||
{ "0", "A@msg.id", "A"},
|
||||
{ "1", "D@msg.id", "D"},
|
||||
{ "2", "B@msg.id", "B"},
|
||||
{ "2:0", "C@msg.id", "C"},
|
||||
{ "2:1", "E@msg.id", "E"},
|
||||
{ "2:0", "E@msg.id", "E"},
|
||||
{ "2:1", "C@msg.id", "C"},
|
||||
};
|
||||
const tinfo expected_desc [] = {
|
||||
{ "0", "B@msg.id", "B"},
|
||||
{ "0:0", "E@msg.id", "E"},
|
||||
{ "0:1", "C@msg.id", "C"},
|
||||
{ "0:0", "C@msg.id", "C"},
|
||||
{ "0:1", "E@msg.id", "E"},
|
||||
{ "1", "D@msg.id", "D"},
|
||||
{ "2", "A@msg.id", "A"},
|
||||
};
|
||||
|
@ -334,12 +334,12 @@ test_mu_threads_sort_orphan_promotes_thread (void)
|
|||
const tinfo expected_asc [] = {
|
||||
{ "0", "A@msg.id", "A"},
|
||||
{ "1", "D@msg.id", "D"},
|
||||
{ "2:0", "C@msg.id", "C"},
|
||||
{ "2:1", "E@msg.id", "E"},
|
||||
{ "2:0", "E@msg.id", "E"},
|
||||
{ "2:1", "C@msg.id", "C"},
|
||||
};
|
||||
const tinfo expected_desc [] = {
|
||||
{ "0:0", "E@msg.id", "E"},
|
||||
{ "0:1", "C@msg.id", "C"},
|
||||
{ "0:0", "C@msg.id", "C"},
|
||||
{ "0:1", "E@msg.id", "E"},
|
||||
{ "1", "D@msg.id", "D"},
|
||||
{ "2", "A@msg.id", "A"},
|
||||
};
|
||||
|
@ -357,16 +357,16 @@ test_mu_threads_sort_child_does_not_promote_thread (void)
|
|||
const char *query = "maildir:/sort/child-does-not-promote-thread";
|
||||
|
||||
const tinfo expected_asc [] = {
|
||||
{ "0", "X@msg.id", "X"},
|
||||
{ "1", "Y@msg.id", "Y"},
|
||||
{ "1:0", "A@msg.id", "A"},
|
||||
{ "0", "Y@msg.id", "Y"},
|
||||
{ "0:0", "A@msg.id", "A"},
|
||||
{ "1", "X@msg.id", "X"},
|
||||
{ "2", "Z@msg.id", "Z"},
|
||||
};
|
||||
const tinfo expected_desc [] = {
|
||||
{ "0", "Z@msg.id", "Z"},
|
||||
{ "1", "Y@msg.id", "Y"},
|
||||
{ "1:0", "A@msg.id", "A"},
|
||||
{ "2", "X@msg.id", "X"},
|
||||
{ "1", "X@msg.id", "X"},
|
||||
{ "2", "Y@msg.id", "Y"},
|
||||
{ "2:0", "A@msg.id", "A"},
|
||||
};
|
||||
|
||||
check_sort_by_subject_asc (query, expected_asc,
|
||||
|
@ -409,19 +409,19 @@ test_mu_threads_sort_granchild_promotes_only_subthread (void)
|
|||
const tinfo expected_asc [] = {
|
||||
{ "0", "A@msg.id", "A"},
|
||||
{ "1", "B@msg.id", "B"},
|
||||
{ "1:0", "C@msg.id", "C"},
|
||||
{ "1:1", "E@msg.id", "E"},
|
||||
{ "1:2", "D@msg.id", "D"},
|
||||
{ "1:2:0", "F@msg.id", "F"},
|
||||
{ "1:0", "E@msg.id", "E"},
|
||||
{ "1:1", "D@msg.id", "D"},
|
||||
{ "1:1:0", "F@msg.id", "F"},
|
||||
{ "1:2", "C@msg.id", "C"},
|
||||
{ "2", "G@msg.id", "G"},
|
||||
};
|
||||
const tinfo expected_desc [] = {
|
||||
{ "0", "G@msg.id", "G"},
|
||||
{ "1", "B@msg.id", "B"},
|
||||
{ "1:0", "D@msg.id", "D"},
|
||||
{ "1:0:0", "F@msg.id", "F"},
|
||||
{ "1:1", "E@msg.id", "E"},
|
||||
{ "1:2", "C@msg.id", "C"},
|
||||
{ "1:0", "C@msg.id", "C"},
|
||||
{ "1:1", "D@msg.id", "D"},
|
||||
{ "1:1:0", "F@msg.id", "F"},
|
||||
{ "1:2", "E@msg.id", "E"},
|
||||
{ "2", "A@msg.id", "A"},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue