Go to the documentation of this file.
98 for (tmp = tree->
prev; tmp; tmp = tmp->
prev)
143 while (!
tree->message)
146 *array =
tree->message;
197 if (depth > *max_depth)
209 for (tmp = tree; tmp; tmp = tmp->
parent)
245 while (tree && !tree->
prev)
257 if (hide_top_limited || hide_top_missing)
263 ((tree->
message && hide_top_limited) || (!tree->
message && hide_top_missing)))
273 while (tree && !tree->
next)
303 (*tctx)->mailbox = NULL;
322 char *pfx = NULL, *mypfx = NULL, *arrow = NULL, *myarrow = NULL, *new_tree = NULL;
325 int depth = 0, start_depth = 0, max_depth = 0, width =
C_NarrowTree ? 1 : 2;
339 myarrow = arrow + (depth - start_depth - ((start_depth != 0) ? 0 : 1)) * width;
340 if (start_depth == depth)
356 myarrow[width + 1] = 0;
360 strncpy(new_tree, pfx, (
size_t) width * (start_depth - 1));
362 (1 + depth - start_depth) * width + 2);
365 mutt_str_copy(new_tree, arrow, ((
size_t) depth * width) + 2);
369 if (tree->
child && (depth != 0))
371 mypfx = pfx + (depth - 1) * width;
401 if (tree == nextdisp)
408 if (start_depth == depth)
415 if (tree == nextdisp)
427 }
while (!tree->
deep);
459 if ((*dateptr == 0) || (thisdate < *dateptr))
479 while (!cur->
next && (cur != start))
515 tmp = ((
struct Email *) ptr->
data)->thread;
575 struct MuttThread *tmp = NULL, *cur = NULL, *
parent = NULL, *curchild = NULL,
588 cur->fake_thread =
true;
608 for (curchild = tmp->
child; curchild;)
610 nextchild = curchild->next;
611 if (curchild->fake_thread)
616 curchild = nextchild;
620 while (!tmp->
next && (tmp != cur))
666 static sort_t sort_func = NULL;
671 &(*((
struct MuttThread const *
const *) b))->sort_key);
678 return sort_func ? 1 : 0;
694 struct Email *oldsort_key = NULL;
695 int i, array_size, sort_top = 0;
757 array[i - 1]->
prev = NULL;
766 array[i - 1]->
prev = array[i];
767 array[i]->
next = array[i - 1];
877 struct Email *e = NULL;
878 int i, oldsort, using_refs = 0;
879 struct MuttThread *thread = NULL, *tnew = NULL, *tmp = NULL;
905 for (thread = tctx->
tree; thread; thread = thread->
next)
925 if (thread && !thread->
message)
933 for (tmp = (thread->
child ? thread->
child : thread); tmp != thread;)
935 while (!tmp->message)
937 tmp->check_subject =
true;
938 while (!tmp->next && (tmp != thread))
959 }
while (thread != &top && !thread->
child && !thread->
message);
974 if (tnew->duplicate_thread)
990 for (tnew = thread->
child; tnew;)
993 if (tnew->fake_thread)
997 tnew->fake_thread =
false;
1022 if (using_refs == 0)
1034 else if (using_refs == 1)
1062 if (tnew->duplicate_thread)
1063 tnew = tnew->parent;
1086 for (thread = top.
child; thread; thread = thread->
next)
1122 struct Email *e_tmp = NULL;
1188 struct Email *e_parent = NULL;
1219 mutt_error(
_(
"Root message is not visible in this limited view"));
1221 mutt_error(
_(
"Parent message is not visible in this limited view"));
1224 return e_parent->
vnum;
1268 struct MuttThread *thread = NULL, *top = NULL;
1269 struct Email *e_root = NULL;
1271 int num_hidden = 0, new_mail = 0, old_mail = 0;
1273 int min_unread_msgno = INT_MAX, min_unread = e_cur->
vnum;
1286 final = e_cur->
vnum;
1294 minmsgno = e_cur->
msgno;
1302 if (e_cur->
msgno < min_unread_msgno)
1304 min_unread = e_cur->
vnum;
1305 min_unread_msgno = e_cur->
msgno;
1319 if (e_cur->
vnum != -1)
1323 final = e_root->
vnum;
1336 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1353 if (!e_root && e_cur->
visible)
1357 final = e_root->
vnum;
1363 minmsgno = e_cur->
msgno;
1364 final = e_cur->
vnum;
1369 if (e_cur != e_root)
1385 if (e_cur->
msgno < min_unread_msgno)
1387 min_unread = e_cur->
vnum;
1388 min_unread_msgno = e_cur->
msgno;
1460 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1488 while (threads[0]->
parent)
1489 threads[0] = threads[0]->
parent;
1493 for (
int i = 0; i < (((mit ==
MIT_POSITION) || !threads[1]) ? 1 : 2); i++)
1496 threads[i] = threads[i]->
child;
1544 if (child == parent)
1565 if (!parent || !children || !m)
1587 while ((thread = top))
1590 thread = thread->
child;
1608 while ((thread = top))
1611 thread = thread->
child;
static void pseudo_threads(struct ThreadsContext *tctx)
Thread messages by subject.
long hdr_offset
Offset in stream where the headers begin.
static bool link_threads(struct Email *parent, struct Email *child, struct Mailbox *m)
Forcibly link messages together.
struct HashTable * subj_hash
Hash Table by subject.
time_t date_sent
Time when the message was sent (UTC)
int msgno
Number displayed to the user.
char * subject
Email's subject.
#define MUTT_THREAD_FLAGGED
Count flagged emails in a thread.
The "current" threading state.
bool subject_changed
Used for threading.
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
uint8_t MuttThreadFlags
Flags, e.g. MUTT_THREAD_COLLAPSE.
#define MUTT_ENV_CHANGED_IRT
In-Reply-To changed to link/break threads.
void insert_message(struct MuttThread **add, struct MuttThread *parent, struct MuttThread *cur)
Insert a message into a thread.
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
@ SORT_THREADS
Sort by email threads.
struct ListHead in_reply_to
in-reply-to header content
char * message_id
Message ID.
int * v2r
Mapping from virtual to real msgno.
struct ThreadsContext * mutt_thread_ctx_init(struct Mailbox *m)
Initialize a threading context.
#define MUTT_THREAD_NEXT_UNREAD
Find the next unread email.
struct Email ** emails
Array of Emails.
struct MuttThread * thread
Thread of Emails.
void thread_hash_destructor(int type, void *obj, intptr_t data)
Hash Destructor callback - Implements hash_hdata_free_t.
#define mutt_thread_contains_flagged(e)
LOFF_T offset
offset where the actual data begins
int mutt_parent_message(struct Email *e, bool find_root)
Find the parent of a message.
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
struct HashTable * hash
Hash table for threads.
int mutt_aside_thread(struct Email *e, bool forwards, bool subthreads)
Find the next/previous (sub)thread.
struct ListNode * mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s)
Insert a string after a given ListNode.
void * data
User-supplied data.
struct HashElem * next
Linked List.
@ MUTT_TREE_LLCORNER
Lower left corner.
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
struct Email * email
Email in the list.
bool is_descendant(struct MuttThread *a, struct MuttThread *b)
Is one thread a descendant of another.
bool C_NarrowTree
Config: Draw a narrower thread tree in the index.
int mutt_messages_in_thread(struct Mailbox *m, struct Email *e, enum MessageInThread mit)
Count the messages in a thread.
char * mutt_str_dup(const char *str)
Copy a string, safely.
#define SORT_REVERSE
Reverse the order of the sort.
#define STAILQ_FIRST(head)
void mutt_sort_subthreads(struct ThreadsContext *tctx, bool init)
Sort the children of a thread.
sort_t mutt_get_sort_func(enum SortType method)
Get the sort function for a given sort id.
void mutt_draw_tree(struct ThreadsContext *tctx)
Draw a tree of threaded emails.
#define SORT_MASK
Mask for the sort id.
bool C_CollapseFlagged
Config: Prevent the collapse of threads with flagged emails.
struct Email * find_virtual(struct MuttThread *cur, int reverse)
Find an email with a Virtual message number.
#define STAILQ_EMPTY(head)
#define SORT_LAST
Sort thread by last-X, e.g. received date.
static void check_subjects(struct Mailbox *m, bool init)
Find out which emails' subjects differ from their parent's.
int(* sort_t)(const void *a, const void *b)
Prototype for a function to compare two emails.
char * real_subj
Offset of the real subject.
@ MUTT_TREE_STAR
Star character (for threads)
#define STAILQ_FOREACH(var, head, field)
off_t mutt_set_vnum(struct Mailbox *m)
Set the virtual index number of all the messages in a mailbox.
int vcount
The number of virtual messages.
bool mutt_thread_can_collapse(struct Email *e)
Check whether a thread can be collapsed.
char * tree
Character string to print thread tree.
struct MuttThread * prev
Previous sibling Thread.
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
struct MuttThread * parent
Parent of this Thread.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
struct MuttThread * child
Child of this Thread.
#define MUTT_HASH_ALLOW_DUPS
allow duplicate keys to be inserted
bool next_subtree_visible
Is the next Thread subtree visible?
bool old
Email is seen, but unread.
time_t received
Time when the message was placed in the mailbox.
bool C_ThreadReceived
Config: Sort threaded messages by their received date.
void mutt_thread_ctx_free(struct ThreadsContext **tctx)
Finalize a threading context.
@ MUTT_TREE_MISSING
Question mark.
static void make_subject_list(struct ListHead *subjects, struct MuttThread *cur, time_t *dateptr)
Create a sorted list of all subjects in a thread.
@ MUTT_TREE_RARROW
Right arrow.
@ MUTT_TREE_HLINE
Horizontal line.
struct HashElem * mutt_hash_find_bucket(const struct HashTable *table, const char *strkey)
Find the HashElem in a Hash Table element using a key.
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
bool visible
Is this message part of the view?
static void calculate_visibility(struct MuttThread *tree, int *max_depth)
Are tree nodes visible.
bool fake_thread
Emails grouped by Subject.
int mutt_traverse_thread(struct Email *e_cur, MuttThreadFlags flag)
Recurse through an email thread, matching messages.
LOFF_T length
length (in bytes) of attachment
@ MUTT_TREE_BTEE
Bottom T-piece.
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
unsigned int subtree_visible
Is this Thread subtree visible?
struct Email * message
Email this Thread refers to.
int msg_count
Total number of messages.
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
bool duplicate_thread
Duplicated Email in Thread.
#define MUTT_THREAD_UNREAD
Count unread emails in a thread.
@ MUTT_TREE_ULCORNER
Upper left corner.
bool C_HideMissing
Config: Don't indicate missing messages, in the thread tree.
#define mutt_collapse_thread(e)
bool display_subject
Used for threading.
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
struct Envelope * env
Envelope information.
struct MuttThread * tree
Top of thread tree.
struct Mailbox * mailbox
Current mailbox.
static bool is_visible(struct Email *e)
Is the message visible?
void mutt_thread_collapse(struct ThreadsContext *tctx, bool collapse)
toggle collapse
bool flagged
Marked important?
bool collapsed
Is this message part of a collapsed thread?
static struct HashTable * make_subj_hash(struct Mailbox *m)
Create a Hash Table for the email subjects.
#define mutt_uncollapse_thread(e)
bool mutt_link_threads(struct Email *parent, struct EmailList *children, struct Mailbox *m)
Forcibly link threads together.
#define MUTT_THREAD_UNCOLLAPSE
Uncollapse an email thread.
#define STAILQ_HEAD_INITIALIZER(head)
struct Email * sort_key
Email that this Thread is sorted against.
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
#define MUTT_HASH_NO_FLAGS
No flags are set.
The item stored in a Hash Table.
@ MUTT_TREE_EQUALS
Equals (for threads)
@ MUTT_TREE_TTEE
Top T-piece.
WHERE short C_Sort
Config: Sort method for the index.
void mutt_sort_threads(struct ThreadsContext *tctx, bool init)
Sort email threads.
static void linearize_tree(struct ThreadsContext *tctx)
Flatten an email thread.
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
bool visible
Is this Thread visible?
bool C_DuplicateThreads
Config: Highlight messages with duplicated message IDs.
void mutt_thread_collapse_collapsed(struct ThreadsContext *tctx)
re-collapse threads marked as collapsed
bool C_HideThreadSubject
Config: Hide subjects that are similar to that of the parent message.
void mutt_list_clear(struct ListHead *h)
Free a list, but NOT its strings.
@ MUTT_TREE_LTEE
Left T-piece.
@ MUTT_TAG
Tagged messages.
bool C_SortRe
Config: Sort method for the sidebar.
bool sort_children
Sort the children.
@ MUTT_TREE_HIDDEN
Ampersand character (for threads)
@ MUTT_TREE_VLINE
Vertical line.
bool check_subject
Should the Subject be checked?
int vnum
Virtual message number.
static bool need_display_subject(struct Email *e)
Determines whether to display a message's subject.
void unlink_message(struct MuttThread **old, struct MuttThread *cur)
Break the message out of the thread.
bool C_CollapseUnread
Config: Prevent the collapse of threads with unread emails.
struct MuttThread * next
Next sibling Thread.
#define STAILQ_NEXT(elm, field)
bool C_HideTopLimited
Config: Don't indicate hidden top message, in the thread tree.
bool C_HideLimited
Config: Don't indicate hidden messages, in the thread tree.
void mutt_break_thread(struct Email *e)
Break the email Thread.
The envelope/body of an email.
bool threaded
Used for threading.
#define mutt_set_flag(m, e, flag, bf)
void mutt_clear_threads(struct ThreadsContext *tctx)
Clear the threading of message in a mailbox.
WHERE short C_SortAux
Config: Secondary sort method for the index.
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
static int compare_threads(const void *a, const void *b)
Sorting function for email threads.
struct ListHead references
message references (in reverse order)
#define MUTT_THREAD_COLLAPSE
Collapse an email thread.
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
static struct MuttThread * find_subject(struct Mailbox *m, struct MuttThread *cur)
Find the best possible match for a parent based on subject.
bool changed
Email has been edited.
TreeChar
Tree characters for menus.
bool deep
Is the Thread deeply nested?
int pair
Color-pair to use when displaying in the index.
#define mutt_thread_contains_unread(e)
struct Body * body
List of MIME parts.
bool C_HideTopMissing
Config: Don't indicate missing top message, in the thread tree.
@ MUTT_TREE_SPACE
Blank space.
bool C_StrictThreads
Config: Thread messages using 'In-Reply-To' and 'References' headers.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)