148 if (!c_hide_thread_subject)
157 for (tmp = tree->
prev; tmp; tmp = tmp->
prev)
203 while (!
tree->message)
206 *array =
tree->message;
207 array += reverse ? -1 : 1;
252 int hide_top_missing = c_hide_top_missing && !c_hide_missing;
255 int hide_top_limited = c_hide_top_limited && !c_hide_limited;
265 if (depth > *max_depth)
277 for (tmp = tree; tmp; tmp = tmp->
parent)
294 tree->
deep = !c_hide_limited;
300 tree->
deep = !c_hide_missing;
315 while (tree && !tree->
prev)
327 if (hide_top_limited || hide_top_missing)
333 ((tree->
message && hide_top_limited) || (!tree->
message && hide_top_missing)))
343 while (tree && !tree->
next)
373 (*tctx)->mailbox = NULL;
392 char *pfx = NULL, *mypfx = NULL, *arrow = NULL, *myarrow = NULL, *new_tree = NULL;
397 int depth = 0, start_depth = 0, max_depth = 0, width = c_narrow_tree ? 1 : 2;
411 myarrow = arrow + (depth - start_depth - ((start_depth != 0) ? 0 : 1)) * width;
414 if (start_depth == depth)
430 myarrow[width + 1] = 0;
434 strncpy(new_tree, pfx, (
size_t) width * (start_depth - 1));
436 (1 + depth - start_depth) * width + 2);
440 mutt_str_copy(new_tree, arrow, ((
size_t) depth * width) + 2);
445 if (tree->
child && (depth != 0))
447 mypfx = pfx + (depth - 1) * width;
477 if (tree == nextdisp)
484 if (start_depth == depth)
491 if (tree == nextdisp)
503 }
while (!tree->
deep);
536 if ((*dateptr == 0) || (thisdate < *dateptr))
557 while (!cur->
next && (cur != start))
594 tmp = ((
struct Email *) he->
data)->thread;
600 (!last || (c_thread_received ?
654 struct MuttThread *tmp = NULL, *cur = NULL, *
parent = NULL, *curchild = NULL,
667 cur->fake_thread =
true;
687 for (curchild = tmp->
child; curchild;)
689 nextchild = curchild->next;
690 if (curchild->fake_thread)
695 curchild = nextchild;
699 while (!tmp->
next && (tmp != cur))
776 struct MuttThread **array = NULL, *top = NULL, *tmp = NULL;
777 struct Email *sort_aux_key = NULL, *oldsort_aux_key = NULL;
778 struct Email *oldsort_thread_key = NULL;
780 bool sort_top =
false;
858 array[i - 1]->
prev = NULL;
867 array[i - 1]->
prev = array[i];
868 array[i]->
next = array[i - 1];
906 if ((c_sort_aux & ~
SORT_REVERSE) == (c_sort & ~SORT_REVERSE))
1018 struct Email *e = NULL;
1019 int i, using_refs = 0;
1020 struct MuttThread *thread = NULL, *tnew = NULL, *tmp = NULL;
1042 for (thread = tctx->
tree; thread; thread = thread->
next)
1063 if (thread && !thread->
message)
1071 for (tmp = (thread->
child ? thread->
child : thread); tmp != thread;)
1073 while (!tmp->message)
1075 tmp->check_subject =
true;
1076 while (!tmp->next && (tmp != thread))
1098 }
while (thread != &top && !thread->
child && !thread->
message);
1103 tnew = (c_duplicate_threads ? thread : NULL);
1113 if (tnew->duplicate_thread)
1114 tnew = tnew->parent;
1129 for (tnew = thread->
child; tnew;)
1132 if (tnew->fake_thread)
1136 tnew->fake_thread =
false;
1161 if (using_refs == 0)
1175 else if (using_refs == 1)
1207 if (tnew->duplicate_thread)
1208 tnew = tnew->parent;
1231 for (thread = top.
child; thread; thread = thread->
next)
1240 if (!c_strict_threads)
1268 struct Email *e_tmp = NULL;
1335 struct Email *e_parent = NULL;
1366 mutt_error(
_(
"Root message is not visible in this limited view"));
1368 mutt_error(
_(
"Parent message is not visible in this limited view"));
1371 return e_parent->
vnum;
1415 struct MuttThread *thread = NULL, *top = NULL;
1416 struct Email *e_root = NULL;
1419 int num_hidden = 0, new_mail = 0, old_mail = 0;
1421 int min_unread_msgno = INT_MAX, min_unread = e_cur->
vnum;
1434 final = e_cur->
vnum;
1442 minmsgno = e_cur->
msgno;
1450 if (e_cur->
msgno < min_unread_msgno)
1452 min_unread = e_cur->
vnum;
1453 min_unread_msgno = e_cur->
msgno;
1467 if (e_cur->
vnum != -1)
1471 final = e_root->
vnum;
1484 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1501 if (!e_root && e_cur->
visible)
1505 final = e_root->
vnum;
1511 minmsgno = e_cur->
msgno;
1512 final = e_cur->
vnum;
1517 if (e_cur != e_root)
1533 if (e_cur->
msgno < min_unread_msgno)
1535 min_unread = e_cur->
vnum;
1536 min_unread_msgno = e_cur->
msgno;
1608 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1637 while (threads[0]->
parent)
1638 threads[0] = threads[0]->
parent;
1642 for (
int i = 0; i < (((mit ==
MIT_POSITION) || !threads[1]) ? 1 : 2); i++)
1645 threads[i] = threads[i]->
child;
1695 if (child == parent)
1716 if (!parent || !children || !m)
1738 while ((thread = top))
1741 thread = thread->
child;
1759 while ((thread = top))
1762 thread = thread->
child;
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Convenience wrapper for the config headers.
#define CSR_ERR_INVALID
Value hasn't been set.
#define CSR_SUCCESS
Action completed successfully.
Convenience wrapper for the core headers.
Structs that make up an email.
#define MUTT_ENV_CHANGED_IRT
In-Reply-To changed to link/break threads.
bool OptSortSubthreads
(pseudo) used when $sort_aux changes
int sort_validator(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Validate values of "sort" - Implements ConfigDef::validator() -.
void thread_hash_destructor(int type, void *obj, intptr_t data)
Hash Destructor callback - Implements hash_hdata_free_t -.
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
struct HashElem * mutt_hash_find_bucket(const struct HashTable *table, const char *strkey)
Find the HashElem in a Hash Table element using a key.
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
#define MUTT_HASH_NO_FLAGS
No flags are set.
#define MUTT_HASH_ALLOW_DUPS
allow duplicate keys to be inserted
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
void mutt_list_clear(struct ListHead *h)
Free a list, but NOT its strings.
struct ListNode * mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s)
Insert a string after a given ListNode.
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Convenience wrapper for the library headers.
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
char * mutt_str_dup(const char *str)
Copy a string, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Many unsorted constants and some structs.
@ MUTT_TAG
Tagged messages.
static void linearize_tree(struct ThreadsContext *tctx)
Flatten an email thread.
static void calculate_visibility(struct MuttThread *tree, int *max_depth)
Are tree nodes visible.
void mutt_clear_threads(struct ThreadsContext *tctx)
Clear the threading of message in a mailbox.
int mutt_traverse_thread(struct Email *e_cur, MuttThreadFlags flag)
Recurse through an email thread, matching messages.
void mutt_thread_ctx_free(struct ThreadsContext **tctx)
Finalize a threading context.
static void mutt_sort_subthreads(struct ThreadsContext *tctx, bool init)
Sort the children of a thread.
void mutt_thread_collapse(struct ThreadsContext *tctx, bool collapse)
Toggle collapse.
void mutt_thread_collapse_collapsed(struct ThreadsContext *tctx)
Re-collapse threads marked as collapsed.
static const struct Mapping UseThreadsMethods[]
Choices for '$use_threads' for the index.
void mutt_draw_tree(struct ThreadsContext *tctx)
Draw a tree of threaded emails.
int mutt_messages_in_thread(struct Mailbox *m, struct Email *e, enum MessageInThread mit)
Count the messages in a thread.
static void make_subject_list(struct ListHead *subjects, struct MuttThread *cur, time_t *dateptr)
Create a sorted list of all subjects in a thread.
const char * get_use_threads_str(enum UseThreads value)
Convert UseThreads enum to string.
static int compare_threads(const void *a, const void *b, void *arg)
qsort_r() function for comparing email threads
enum UseThreads mutt_thread_style(void)
Which threading style is active?
static void pseudo_threads(struct ThreadsContext *tctx)
Thread messages by subject.
static struct HashTable * make_subj_hash(struct Mailbox *m)
Create a Hash Table for the email subjects.
bool mutt_link_threads(struct Email *parent, struct EmailList *children, struct Mailbox *m)
Forcibly link threads together.
void mutt_sort_threads(struct ThreadsContext *tctx, bool init)
Sort email threads.
static bool need_display_subject(struct Email *e)
Determines whether to display a message's subject.
struct EnumDef UseThreadsTypeDef
off_t mutt_set_vnum(struct Mailbox *m)
Set the virtual index number of all the messages in a mailbox.
int mutt_aside_thread(struct Email *e, bool forwards, bool subthreads)
Find the next/previous (sub)thread.
bool mutt_thread_can_collapse(struct Email *e)
Check whether a thread can be collapsed.
static struct MuttThread * find_subject(struct Mailbox *m, struct MuttThread *cur)
Find the best possible match for a parent based on subject.
int mutt_parent_message(struct Email *e, bool find_root)
Find the parent of a message.
static void check_subjects(struct Mailbox *m, bool init)
Find out which emails' subjects differ from their parent's.
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
static bool link_threads(struct Email *parent, struct Email *child, struct Mailbox *m)
Forcibly link messages together.
struct ThreadsContext * mutt_thread_ctx_init(struct Mailbox *m)
Initialize a threading context.
static bool is_visible(struct Email *e)
Is the message visible?
Create/manipulate threading in emails.
#define MUTT_THREAD_UNREAD
Count unread emails in a thread.
uint8_t MuttThreadFlags
Flags, e.g. MUTT_THREAD_COLLAPSE.
#define mutt_thread_contains_flagged(e)
UseThreads
Which threading style is active, $use_threads.
@ UT_UNSET
Not yet set by user, stick to legacy semantics.
@ UT_THREADS
Normal threading (root above subthreads)
@ UT_REVERSE
Reverse threading (subthreads above root)
#define mutt_using_threads()
#define mutt_uncollapse_thread(e)
MessageInThread
Flags for mutt_messages_in_thread()
@ MIT_POSITION
Our position in the thread.
#define MUTT_THREAD_UNCOLLAPSE
Uncollapse an email thread.
#define MUTT_THREAD_NEXT_UNREAD
Find the next unread email.
#define mutt_thread_contains_unread(e)
#define MUTT_THREAD_COLLAPSE
Collapse an email thread.
#define mutt_collapse_thread(e)
#define MUTT_THREAD_FLAGGED
Count flagged emails in a thread.
TreeChar
Tree characters for menus.
@ MUTT_TREE_LLCORNER
Lower left corner.
@ MUTT_TREE_RARROW
Right arrow.
@ MUTT_TREE_ULCORNER
Upper left corner.
@ MUTT_TREE_EQUALS
Equals (for threads)
@ MUTT_TREE_HIDDEN
Ampersand character (for threads)
@ MUTT_TREE_STAR
Star character (for threads)
@ MUTT_TREE_LTEE
Left T-piece.
@ MUTT_TREE_VLINE
Vertical line.
@ MUTT_TREE_MISSING
Question mark.
@ MUTT_TREE_TTEE
Top T-piece.
@ MUTT_TREE_HLINE
Horizontal line.
@ MUTT_TREE_SPACE
Blank space.
@ MUTT_TREE_BTEE
Bottom T-piece.
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
enum MailboxType mx_type(struct Mailbox *m)
Return the type of the Mailbox.
Prototypes for many functions.
#define mutt_set_flag(m, e, flag, bf)
void mutt_qsort_r(void *base, size_t nmemb, size_t size, qsort_r_compar_t compar, void *arg)
Sort an array, where the comparator has access to opaque data rather than requiring global variables.
#define STAILQ_HEAD_INITIALIZER(head)
#define STAILQ_FIRST(head)
#define STAILQ_FOREACH(var, head, field)
#define STAILQ_EMPTY(head)
#define STAILQ_NEXT(elm, field)
#define SORT_MASK
Mask for the sort id.
#define SORT_LAST
Sort thread by last-X, e.g. received date.
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
@ SORT_THREADS
Sort by email threads.
#define SORT_REVERSE
Reverse the order of the sort.
int mutt_compare_emails(const struct Email *a, const struct Email *b, enum MailboxType type, short sort, short sort_aux)
Compare two emails using up to two sort methods.
Assorted sorting methods.
LOFF_T offset
offset where the actual data begins
LOFF_T length
length (in bytes) of attachment
long hdr_offset
Offset in stream where the headers begin.
String manipulation buffer.
const char * name
User-visible name.
Container for lots of config items.
struct Email * email
Email in the list.
The envelope/body of an email.
bool display_subject
Used for threading.
bool visible
Is this message part of the view?
struct Envelope * env
Envelope information.
bool collapsed
Is this message part of a collapsed thread?
struct Body * body
List of MIME parts.
bool subject_changed
Used for threading.
char * tree
Character string to print thread tree.
bool old
Email is seen, but unread.
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
struct AttrColor * attr_color
Color-pair to use when displaying in the index.
bool changed
Email has been edited.
bool flagged
Marked important?
bool threaded
Used for threading.
time_t date_sent
Time when the message was sent (UTC)
int vnum
Virtual message number.
int msgno
Number displayed to the user.
time_t received
Time when the message was placed in the mailbox.
struct MuttThread * thread
Thread of Emails.
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
char * message_id
Message ID.
struct ListHead references
message references (in reverse order)
struct ListHead in_reply_to
in-reply-to header content
char * subject
Email's subject.
char * real_subj
Offset of the real subject.
The item stored in a Hash Table.
struct HashElem * next
Linked List.
void * data
User-supplied data.
int vcount
The number of virtual messages.
int * v2r
Mapping from virtual to real msgno.
int msg_count
Total number of messages.
struct HashTable * subj_hash
Hash Table by subject.
struct Email ** emails
Array of Emails.
Mapping between user-readable string and a constant.
bool sort_children
Sort the children.
bool visible
Is this Thread visible?
struct MuttThread * parent
Parent of this Thread.
struct Email * sort_aux_key
Email that controls how subthread siblings sort.
struct MuttThread * prev
Previous sibling Thread.
bool fake_thread
Emails grouped by Subject.
struct MuttThread * child
Child of this Thread.
struct Email * message
Email this Thread refers to.
bool deep
Is the Thread deeply nested?
unsigned int subtree_visible
Is this Thread subtree visible?
bool duplicate_thread
Duplicated Email in Thread.
bool next_subtree_visible
Is the next Thread subtree visible?
bool check_subject
Should the Subject be checked?
struct Email * sort_thread_key
Email that controls how top thread sorts.
struct MuttThread * next
Next sibling Thread.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
The "current" threading state.
struct MuttThread * tree
Top of thread tree.
struct HashTable * hash
Hash table for threads.
short c_sort_aux
Last sort_aux method.
short c_sort
Last sort method.
struct Mailbox * mailbox
Current mailbox.
void unlink_message(struct MuttThread **old, struct MuttThread *cur)
Break the message out of the thread.
bool is_descendant(struct MuttThread *a, const struct MuttThread *b)
Is one thread a descendant of another.
void insert_message(struct MuttThread **add, struct MuttThread *parent, struct MuttThread *cur)
Insert a message into a thread.
void mutt_break_thread(struct Email *e)
Break the email Thread.
struct Email * find_virtual(struct MuttThread *cur, bool reverse)
Find an email with a Virtual message number.