BUFFER err, token;
char buffer[LONG_STRING], errbuf[SHORT_STRING];
int r;
- int old_strictthreads = option (OPTSTRICTTHREADS);
- int old_sortre = option (OPTSORTRE);
- int old_hidemissing = option (OPTHIDEMISSING);
- int old_threadreceived = option (OPTTHREADRECEIVED);
- int old_dupthreads = option (OPTDUPTHREADS);
buffer[0] = 0;
if (mutt_get_field (":", buffer, sizeof (buffer), M_COMMAND) != 0 || !buffer[0])
else
mutt_error ("%s", errbuf);
}
- if (option (OPTSTRICTTHREADS) != old_strictthreads ||
- option (OPTSORTRE) != old_sortre ||
- option (OPTHIDEMISSING) != old_hidemissing ||
- option (OPTTHREADRECEIVED) != old_threadreceived ||
- option (OPTDUPTHREADS) != old_dupthreads)
- set_option (OPTNEEDRESORT);
}
void mutt_display_address (ENVELOPE *env)
else
menu->current = 0;
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
- if (Sort & SORT_THREADS)
+ if ((Sort & SORT_MASK) == SORT_THREADS)
mutt_linearize_tree (Context, 0);
}
break;
set_option (OPTSORTSUBTHREADS);
if (p->flags & R_RESORT)
set_option (OPTNEEDRESORT);
+ if (p->flags & R_RESORT_INIT)
+ set_option (OPTRESORTINIT);
}
static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
set_option (OPTSORTSUBTHREADS);
if (MuttVars[idx].flags & R_RESORT)
set_option (OPTNEEDRESORT);
+ if (MuttVars[idx].flags & R_RESORT_INIT)
+ set_option (OPTRESORTINIT);
}
return (r);
}
#define R_PAGER (1<<1)
#define R_RESORT (1<<2) /* resort the mailbox */
#define R_RESORT_SUB (1<<3) /* resort subthreads */
+#define R_RESORT_INIT (1<<4) /* resort from scratch */
#define R_BOTH (R_INDEX | R_PAGER)
#define R_RESORT_BOTH (R_RESORT | R_RESORT_SUB)
** .pp
** Example: set dsn_return=hdrs
*/
- { "duplicate_threads", DT_BOOL, R_NONE, OPTDUPTHREADS, 1 },
+ { "duplicate_threads", DT_BOOL, R_RESORT|R_RESORT_INIT|R_INDEX, OPTDUPTHREADS, 1 },
/*
** .pp
** This variable controls whether mutt, when sorting by threads, threads
** affect the generation of Message-IDs, and it will not lead to the
** cut-off of first-level domains.
*/
- { "hide_missing", DT_BOOL, R_NONE, OPTHIDEMISSING, 1 },
+ { "hide_missing", DT_BOOL, R_RESORT|R_INDEX, OPTHIDEMISSING, 1 },
/*
** .pp
** When set, mutt will not indicate the presence of missing messages
** You may optionally use the reverse- prefix to specify reverse sorting
** order (example: set sort_browser=reverse-date).
*/
- { "sort_re", DT_BOOL, R_INDEX|R_RESORT_BOTH, OPTSORTRE, 1 },
+ { "sort_re", DT_BOOL, R_INDEX|R_RESORT|R_RESORT_INIT, OPTSORTRE, 1 },
/*
** .pp
** This variable is only useful when sorting by threads with
** Setting this variable causes the ``status bar'' to be displayed on
** the first line of the screen rather than near the bottom.
*/
- { "strict_threads", DT_BOOL, R_RESORT|R_INDEX, OPTSTRICTTHREADS, 0 },
+ { "strict_threads", DT_BOOL, R_RESORT|R_RESORT_INIT|R_INDEX, OPTSTRICTTHREADS, 0 },
/*
** .pp
** If set, threading will only make use of the ``In-Reply-To'' and
** .pp
** Note that $$indent_string is ignored when this option is set.
*/
- { "thread_received", DT_BOOL, R_NONE, OPTTHREADRECEIVED, 0 },
+ { "thread_received", DT_BOOL, R_RESORT|R_RESORT_INIT|R_INDEX, OPTTHREADRECEIVED, 0 },
/*
** .pp
** When set, mutt uses the date received rather than the date sent
OPTSIGNALSBLOCKED, /* (pseudo) using by mutt_block_signals () */
OPTSYSSIGNALSBLOCKED, /* (pseudo) using by mutt_block_signals_system () */
OPTNEEDRESORT, /* (pseudo) used to force a re-sort */
+ OPTRESORTINIT, /* (pseudo) used to force the next resort to be from scratch */
OPTVIEWATTACH, /* (pseudo) signals that we are viewing attachments */
OPTFORCEREDRAWINDEX, /* (pseudo) used to force a redraw in the main index */
OPTFORCEREDRAWPAGER, /* (pseudo) used to force a redraw in the pager */
Sort = i;
unset_option (OPTSORTSUBTHREADS);
}
+ if (option (OPTRESORTINIT))
+ {
+ unset_option (OPTRESORTINIT);
+ init = 1;
+ }
mutt_sort_threads (ctx, init);
}
else if ((sortfunc = mutt_get_sort_func (Sort)) == NULL ||
THREAD *mutt_sort_subthreads (THREAD *thread, int init)
{
- THREAD **array, *sort_key, *top;
+ THREAD **array, *sort_key, *top, *tmp;
HEADER *oldsort_key;
int i, array_size, sort_top = 0;
{
if (init || !thread->sort_key)
{
+ thread->sort_key = NULL;
+
if (thread->parent)
thread->parent->sort_children = 1;
else
if (thread->parent)
{
- if (!thread->parent->sort_key || thread->parent->sort_children)
+ tmp = thread;
+ thread = thread->parent;
+
+ if (!thread->sort_key || thread->sort_children)
{
/* make sort_key the first or last sibling, as appropriate */
- sort_key = (!(Sort & SORT_LAST) ^ !(Sort & SORT_REVERSE)) ? thread->parent->child : thread;
- thread->parent->sort_children = 0;
- }
- else
- sort_key = NULL;
+ sort_key = (!(Sort & SORT_LAST) ^ !(Sort & SORT_REVERSE)) ? thread->child : tmp;
- thread = thread->parent;
+ /* we just sorted its children */
+ thread->sort_children = 0;
- if (sort_key)
- {
oldsort_key = thread->sort_key;
+ thread->sort_key = thread->message;
+
if (Sort & SORT_LAST)
{
if (!thread->sort_key
> 0))
thread->sort_key = sort_key->sort_key;
}
- else if (!thread->sort_key || !thread->message)
+ else if (!thread->sort_key)
thread->sort_key = sort_key->sort_key;
/* if its sort_key has changed, we need to resort it and siblings */
}
}
+static void check_subjects (CONTEXT *ctx, int init)
+{
+ HEADER *cur;
+ THREAD *tmp;
+ int i;
+
+ for (i = 0; i < ctx->msgcount; i++)
+ {
+ cur = ctx->hdrs[i];
+ if (cur->thread->check_subject)
+ cur->thread->check_subject = 0;
+ else if (!init)
+ continue;
+
+ /* figure out which messages have subjects different than their parents' */
+ tmp = cur->thread->parent;
+ while (tmp && !tmp->message)
+ {
+ tmp = tmp->parent;
+ }
+
+ if (!tmp)
+ cur->subject_changed = 1;
+ else if (cur->env->real_subj && tmp->message->env->real_subj)
+ cur->subject_changed = mutt_strcmp (cur->env->real_subj,
+ tmp->message->env->real_subj) ? 1 : 0;
+ else
+ cur->subject_changed = (cur->env->real_subj
+ || tmp->message->env->real_subj) ? 1 : 0;
+ }
+}
+
void mutt_sort_threads (CONTEXT *ctx, int init)
{
HEADER *cur;
if (!cur->thread)
{
- thread = (((!init || option (OPTDUPTHREADS)) && cur->env->message_id)
- ? hash_find (ctx->thread_hash, cur->env->message_id) : NULL);
-
- new = (option (OPTDUPTHREADS) ? thread : NULL);
+ if ((!init || option (OPTDUPTHREADS)) && cur->env->message_id)
+ thread = hash_find (ctx->thread_hash, cur->env->message_id);
+ else
+ thread = NULL;
if (thread && !thread->message)
{
unlink_message (&tmp->child, thread);
thread->parent = NULL;
thread->sort_key = NULL;
+ thread->fake_thread = 0;
thread = tmp;
} while (thread != &top && !thread->child && !thread->message);
}
}
else
{
+ new = (option (OPTDUPTHREADS) ? thread : NULL);
+
thread = safe_calloc (1, sizeof (THREAD));
thread->message = cur;
thread->check_subject = 1;
hash_insert (ctx->thread_hash,
cur->env->message_id ? cur->env->message_id : "",
thread, 1);
- }
- if (new && new->message)
- {
- if (new->duplicate_thread)
- new = new->parent;
+ if (new)
+ {
+ if (new->duplicate_thread)
+ new = new->parent;
+
+ thread = cur->thread;
- insert_message (&new->child, new, thread);
- thread->duplicate_thread = 1;
- thread->message->threaded = 1;
+ insert_message (&new->child, new, thread);
+ thread->duplicate_thread = 1;
+ thread->message->threaded = 1;
+ }
}
}
else
}
ctx->tree = top.child;
- for (i = 0; i < ctx->msgcount; i++)
- {
- cur = ctx->hdrs[i];
- if (cur->thread->check_subject)
- cur->thread->check_subject = 0;
- else if (!init)
- continue;
-
- /* figure out which messages have subjects different than their parents' */
- tmp = cur->thread->parent;
- while (tmp && !tmp->message)
- {
- tmp = tmp->parent;
- }
-
- if (!tmp)
- cur->subject_changed = 1;
- else if (cur->env->real_subj && tmp->message->env->real_subj)
- cur->subject_changed = mutt_strcmp (cur->env->real_subj,
- tmp->message->env->real_subj) ? 1 : 0;
- else
- cur->subject_changed = (cur->env->real_subj
- || tmp->message->env->real_subj) ? 1 : 0;
- }
+ check_subjects (ctx, init);
if (!option (OPTSTRICTTHREADS))
pseudo_threads (ctx);