110 buf_printf(err,
_(
"Cannot use 'last-' prefix with 'threads' for %s"), cdef->
name);
138 if (!c_hide_thread_subject)
147 for (tmp = tree->
prev; tmp; tmp = tmp->
prev)
193 while (!
tree->message)
196 *array =
tree->message;
197 array += reverse ? -1 : 1;
242 int hide_top_missing = c_hide_top_missing && !c_hide_missing;
245 int hide_top_limited = c_hide_top_limited && !c_hide_limited;
255 if (depth > *max_depth)
267 for (tmp = tree; tmp; tmp = tmp->
parent)
284 tree->
deep = !c_hide_limited;
290 tree->
deep = !c_hide_missing;
307 while (tree && !tree->
prev)
319 if (hide_top_limited || hide_top_missing)
325 ((tree->
message && hide_top_limited) || (!tree->
message && hide_top_missing)))
339 while (tree && !tree->
next)
393 char *pfx = NULL, *mypfx = NULL, *arrow = NULL, *myarrow = NULL, *new_tree = NULL;
398 int depth = 0, start_depth = 0, max_depth = 0, width = c_narrow_tree ? 1 : 2;
414 myarrow = arrow + (depth - start_depth - ((start_depth != 0) ? 0 : 1)) * width;
415 if (start_depth == depth)
431 myarrow[width + 1] = 0;
435 strncpy(new_tree, pfx, (
size_t) width * (start_depth - 1));
437 (1 + depth - start_depth) * width + 2);
441 mutt_str_copy(new_tree, arrow, ((
size_t) depth * width) + 2);
446 if (tree->
child && (depth != 0))
448 mypfx = pfx + (depth - 1) * width;
478 if (tree == nextdisp)
485 if (start_depth == depth)
492 if (tree == nextdisp)
504 }
while (!tree->
deep);
538 if ((*dateptr == 0) || (thisdate < *dateptr))
558 while (!cur->
next && (cur != start))
595 tmp = ((
struct Email *) he->
data)->thread;
601 (!last || (c_thread_received ?
655 struct MuttThread *tmp = NULL, *cur = NULL, *
parent = NULL, *curchild = NULL,
668 cur->fake_thread =
true;
688 for (curchild = tmp->
child; curchild;)
690 nextchild = curchild->next;
691 if (curchild->fake_thread)
696 curchild = nextchild;
700 while (!tmp->
next && (tmp != cur))
719 if (!tctx || !tctx->
tree)
781 struct MuttThread **array = NULL, *top = NULL, *tmp = NULL;
782 struct Email *sort_aux_key = NULL, *oldsort_aux_key = NULL;
783 struct Email *oldsort_thread_key = NULL;
785 bool sort_top =
false;
846 while (!thread->
next)
852 for (i = 0; thread; i++, thread = thread->
prev)
865 array[i - 1]->prev = NULL;
868 thread->parent->child = array[i - 1];
874 array[i - 1]->prev = array[i];
875 array[i]->next = array[i - 1];
915 if ((c_sort_aux & ~
SORT_REVERSE) == (c_sort & ~SORT_REVERSE))
935 for (tmp = thread->
child; tmp; tmp = tmp->
next)
967 thread = thread->
next;
1036 struct Email *e = NULL;
1037 int i, using_refs = 0;
1038 struct MuttThread *thread = NULL, *tnew = NULL, *tmp = NULL;
1060 for (thread = tctx->
tree; thread; thread = thread->
next)
1079 for (tnew = thread->
child; tnew;)
1082 if (tnew->fake_thread)
1086 tnew->fake_thread =
false;
1098 if (thread && !thread->
message)
1106 for (tmp = (thread->
child ? thread->
child : thread); tmp != thread;)
1108 while (!tmp->message)
1110 tmp->check_subject =
true;
1111 while (!tmp->next && (tmp != thread))
1133 }
while (thread != &top && !thread->
child && !thread->
message);
1138 tnew = (c_duplicate_threads ? thread : NULL);
1148 if (tnew->duplicate_thread)
1149 tnew = tnew->parent;
1179 if (using_refs == 0)
1193 else if (using_refs == 1)
1225 if (tnew->duplicate_thread)
1226 tnew = tnew->parent;
1249 for (thread = top.
child; thread; thread = thread->
next)
1258 if (!c_strict_threads)
1290 struct Email *e_tmp = NULL;
1357 struct Email *e_parent = NULL;
1388 mutt_error(
_(
"Root message is not visible in this limited view"));
1390 mutt_error(
_(
"Parent message is not visible in this limited view"));
1393 return e_parent->
vnum;
1437 struct MuttThread *thread = NULL, *top = NULL;
1438 struct Email *e_root = NULL;
1441 int num_hidden = 0, new_mail = 0, old_mail = 0;
1443 int min_unread_msgno = INT_MAX, min_unread = e_cur->
vnum;
1456 final = e_cur->
vnum;
1464 minmsgno = e_cur->
msgno;
1472 if (e_cur->
msgno < min_unread_msgno)
1474 min_unread = e_cur->
vnum;
1475 min_unread_msgno = e_cur->
msgno;
1489 if (e_cur->
vnum != -1)
1493 final = e_root->
vnum;
1506 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1523 if (!e_root && e_cur->
visible)
1527 final = e_root->
vnum;
1533 minmsgno = e_cur->
msgno;
1534 final = e_cur->
vnum;
1539 if (e_cur != e_root)
1555 if (e_cur->
msgno < min_unread_msgno)
1557 min_unread = e_cur->
vnum;
1558 min_unread_msgno = e_cur->
msgno;
1638 return (old_mail && new_mail) ? new_mail : (old_mail ? old_mail : new_mail);
1667 while (threads[0]->
parent)
1668 threads[0] = threads[0]->
parent;
1672 for (
int i = 0; i < (((mit ==
MIT_POSITION) || !threads[1]) ? 1 : 2); i++)
1675 threads[i] = threads[i]->
child;
1725 if (child == parent)
1746 if (!parent || !children || !m)
1751 struct Email **ep = NULL;
1754 struct Email *e = *ep;
1769 while ((thread = top))
1772 thread = thread->
child;
1790 while ((thread = top))
1793 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.
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 values of "sort" - Implements ConfigDef::validator() -.
static void thread_hash_destructor(int type, void *obj, intptr_t data)
Hash Destructor callback - 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.
MailboxType
Supported mailbox formats.
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.
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.
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.
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.