113 buf_printf(err,
_(
"Cannot use 'last-' prefix with 'threads' for %s"), cdef->
name);
141 if (!c_hide_thread_subject)
150 for (tmp = tree->
prev; tmp; tmp = tmp->
prev)
196 while (!
tree->message)
199 *array =
tree->message;
200 array += reverse ? -1 : 1;
245 int hide_top_missing = c_hide_top_missing && !c_hide_missing;
248 int hide_top_limited = c_hide_top_limited && !c_hide_limited;
258 if (depth > *max_depth)
270 for (tmp = tree; tmp; tmp = tmp->
parent)
287 tree->
deep = !c_hide_limited;
293 tree->
deep = !c_hide_missing;
310 while (tree && !tree->
prev)
322 if (hide_top_limited || hide_top_missing)
328 ((tree->
message && hide_top_limited) || (!tree->
message && hide_top_missing)))
342 while (tree && !tree->
next)
396 char *pfx = NULL, *mypfx = NULL, *arrow = NULL, *myarrow = NULL, *new_tree = NULL;
401 int depth = 0, start_depth = 0, max_depth = 0, width = c_narrow_tree ? 1 : 2;
417 myarrow = arrow + (depth - start_depth - ((start_depth != 0) ? 0 : 1)) * width;
418 if (start_depth == depth)
434 myarrow[width + 1] = 0;
438 strncpy(new_tree, pfx, (
size_t) width * (start_depth - 1));
440 (1 + depth - start_depth) * width + 2);
444 mutt_str_copy(new_tree, arrow, ((
size_t) depth * width) + 2);
449 if (tree->
child && (depth != 0))
451 mypfx = pfx + (depth - 1) * width;
481 if (tree == nextdisp)
488 if (start_depth == depth)
495 if (tree == nextdisp)
507 }
while (!tree->
deep);
541 if ((*dateptr == 0) || (thisdate < *dateptr))
561 while (!cur->
next && (cur != start))
598 tmp = ((
struct Email *) he->
data)->thread;
604 (!last || (c_thread_received ?
658 struct MuttThread *tmp = NULL, *cur = NULL, *
parent = NULL, *curchild = NULL,
671 cur->fake_thread =
true;
691 for (curchild = tmp->
child; curchild;)
693 nextchild = curchild->next;
694 if (curchild->fake_thread)
699 curchild = nextchild;
703 while (!tmp->
next && (tmp != cur))
722 if (!tctx || !tctx->
tree)
784 struct MuttThread **array = NULL, *top = NULL, *tmp = NULL;
785 struct Email *sort_aux_key = NULL, *oldsort_aux_key = NULL;
786 struct Email *oldsort_thread_key = NULL;
788 bool sort_top =
false;
849 while (!thread->
next)
855 for (i = 0; thread; i++, thread = thread->
prev)
871 array[i - 1]->prev = NULL;
874 thread->parent->child = array[i - 1];
880 array[i - 1]->prev = array[i];
881 array[i]->next = array[i - 1];
921 if ((c_sort_aux & ~
SORT_REVERSE) == (c_sort & ~SORT_REVERSE))
941 for (tmp = thread->
child; tmp; tmp = tmp->
next)
973 thread = thread->
next;
1042 struct Email *e = NULL;
1043 int i, using_refs = 0;
1044 struct MuttThread *thread = NULL, *tnew = NULL, *tmp = NULL;
1066 for (thread = tctx->
tree; thread; thread = thread->
next)
1085 for (tnew = thread->
child; tnew;)
1088 if (tnew->fake_thread)
1092 tnew->fake_thread =
false;
1104 if (thread && !thread->
message)
1112 for (tmp = (thread->
child ? thread->
child : thread); tmp != thread;)
1114 while (!tmp->message)
1116 tmp->check_subject =
true;
1117 while (!tmp->next && (tmp != thread))
1139 }
while (thread != &top && !thread->
child && !thread->
message);
1144 tnew = (c_duplicate_threads ? thread : NULL);
1154 if (tnew->duplicate_thread)
1155 tnew = tnew->parent;
1185 if (using_refs == 0)
1199 else if (using_refs == 1)
1231 if (tnew->duplicate_thread)
1232 tnew = tnew->parent;
1255 for (thread = top.
child; thread; thread = thread->
next)
1264 if (!c_strict_threads)
1296 struct Email *e_tmp = NULL;
1363 struct Email *e_parent = NULL;
1394 mutt_error(
_(
"Root message is not visible in this limited view"));
1396 mutt_error(
_(
"Parent message is not visible in this limited view"));
1399 return e_parent->
vnum;
1443 struct MuttThread *thread = NULL, *top = NULL;
1444 struct Email *e_root = NULL;
1447 int num_hidden = 0, new_mail = 0, old_mail = 0;
1449 int min_unread_msgno = INT_MAX, min_unread = e_cur->
vnum;
1462 final = e_cur->
vnum;
1470 minmsgno = e_cur->
msgno;
1478 if (e_cur->
msgno < min_unread_msgno)
1480 min_unread = e_cur->
vnum;
1481 min_unread_msgno = e_cur->
msgno;
1495 if (e_cur->
vnum != -1)
1499 final = e_root->
vnum;
1512 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1529 if (!e_root && e_cur->
visible)
1533 final = e_root->
vnum;
1539 minmsgno = e_cur->
msgno;
1540 final = e_cur->
vnum;
1545 if (e_cur != e_root)
1561 if (e_cur->
msgno < min_unread_msgno)
1563 min_unread = e_cur->
vnum;
1564 min_unread_msgno = e_cur->
msgno;
1644 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1673 while (threads[0]->
parent)
1674 threads[0] = threads[0]->
parent;
1678 for (
int i = 0; i < (((mit ==
MIT_POSITION) || !threads[1]) ? 1 : 2); i++)
1681 threads[i] = threads[i]->
child;
1731 if (child == parent)
1752 if (!parent || !children || !m)
1757 struct Email **ep = NULL;
1760 struct Email *e = *ep;
1775 while ((thread = top))
1778 thread = thread->
child;
1796 while ((thread = top))
1799 thread = thread->
child;
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
int buf_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.
MailboxType
Supported mailbox formats.
Structs that make up an email.
#define MUTT_ENV_CHANGED_IRT
In-Reply-To changed to link/break threads.
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
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 the "sort" config variable - Implements ConfigDef::validator() -.
static void thread_hash_destructor(int type, void *obj, intptr_t data)
Free our hash table data - Implements hash_hdata_free_t -.
static int compare_threads(const void *a, const void *b, void *sdata)
Helper to sort email threads - Implements sort_t -.
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 -.
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.
#define MUTT_MEM_CALLOC(n, type)
#define MUTT_MEM_REALLOC(pptr, n, type)
#define MUTT_MEM_MALLOC(n, type)
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.
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.
struct ThreadsContext * mutt_thread_ctx_init(struct MailboxView *mv)
Initialize a threading context.
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.
bool mutt_link_threads(struct Email *parent, struct EmailArray *children, struct Mailbox *m)
Forcibly link threads together.
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.
void mutt_thread_ctx_free(struct ThreadsContext **ptr)
Finalize a threading context.
const char * get_use_threads_str(enum UseThreads value)
Convert UseThreads enum to string.
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.
static void check_subjects(struct MailboxView *mv, bool init)
Find out which emails' subjects differ from their parent's.
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.
const struct EnumDef UseThreadsTypeDef
Data for the $use_threads enumeration.
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.
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.
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.
void mutt_qsort_r(void *base, size_t nmemb, size_t size, sort_t compar, void *sdata)
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.
SortType
Methods for sorting.
@ 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.
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.
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)
bool changed
Email has been edited.
bool flagged
Marked important?
bool threaded
Used for threading.
const struct AttrColor * attr_color
Color-pair to use when displaying in the index.
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.
char *const subject
Email's subject.
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 *const real_subj
Offset of the real subject.
The item stored in a Hash Table.
struct HashElem * next
Linked List.
void * data
User-supplied data.
struct Mailbox * mailbox
Current Mailbox.
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: "subject" -> Email.
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 MailboxView * mailbox_view
Current mailbox.
struct MuttThread * tree
Top of thread tree.
struct HashTable * hash
Hash Table: "message-id" -> MuttThread.
enum SortType c_sort_aux
Last sort_aux method.
enum SortType c_sort
Last sort method.
void unlink_message(struct MuttThread **old, struct MuttThread *cur)
Break the message out of the thread.
bool is_descendant(const 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.