1 /**
2  * @file
3  * Create/manipulate threading in emails
4  *
5  * @authors
6  * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef MUTT_MUTT_THREAD_H
24 #define MUTT_MUTT_THREAD_H
25 
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <sys/types.h>
29 #include "config/lib.h"
30 
31 struct Buffer;
32 struct Email;
33 struct EmailList;
34 struct Mailbox;
35 struct ThreadsContext;
36 
37 /**
38  * enum TreeChar - Tree characters for menus
39  *
40  * @sa linearize_tree(), print_enriched_string()
41  */
42 enum TreeChar
43 {
44   MUTT_TREE_LLCORNER = 1, ///< Lower left corner
45   MUTT_TREE_ULCORNER,     ///< Upper left corner
46   MUTT_TREE_LTEE,         ///< Left T-piece
47   MUTT_TREE_HLINE,        ///< Horizontal line
48   MUTT_TREE_VLINE,        ///< Vertical line
49   MUTT_TREE_SPACE,        ///< Blank space
50   MUTT_TREE_RARROW,       ///< Right arrow
51   MUTT_TREE_STAR,         ///< Star character (for threads)
52   MUTT_TREE_HIDDEN,       ///< Ampersand character (for threads)
53   MUTT_TREE_EQUALS,       ///< Equals (for threads)
54   MUTT_TREE_TTEE,         ///< Top T-piece
55   MUTT_TREE_BTEE,         ///< Bottom T-piece
56   MUTT_TREE_MISSING,      ///< Question mark
57   MUTT_TREE_MAX,
58 
59   MUTT_SPECIAL_INDEX = MUTT_TREE_MAX, ///< Colour indicator
60 };
61 
62 typedef uint8_t MuttThreadFlags;         ///< Flags, e.g. #MUTT_THREAD_COLLAPSE
63 #define MUTT_THREAD_NO_FLAGS          0  ///< No flags are set
64 #define MUTT_THREAD_COLLAPSE    (1 << 0) ///< Collapse an email thread
65 #define MUTT_THREAD_UNCOLLAPSE  (1 << 1) ///< Uncollapse an email thread
66 #define MUTT_THREAD_UNREAD      (1 << 2) ///< Count unread emails in a thread
67 #define MUTT_THREAD_NEXT_UNREAD (1 << 3) ///< Find the next unread email
68 #define MUTT_THREAD_FLAGGED     (1 << 4) ///< Count flagged emails in a thread
69 
70 /**
71  * enum MessageInThread - Flags for mutt_messages_in_thread()
72  */
73 enum MessageInThread
74 {
75   MIT_NUM_MESSAGES, ///< How many messages are in the thread
76   MIT_POSITION,     ///< Our position in the thread
77 };
78 
79 /**
80  * enum UseThreads - Which threading style is active, $use_threads
81  */
82 enum UseThreads
83 {
84   UT_UNSET,     ///< Not yet set by user, stick to legacy semantics
85   UT_FLAT,      ///< Unthreaded
86   UT_THREADS,   ///< Normal threading (root above subthreads)
87   UT_REVERSE,   ///< Reverse threading (subthreads above root)
88 };
89 
90 extern struct EnumDef UseThreadsTypeDef;
91 
92 int mutt_traverse_thread(struct Email *e, MuttThreadFlags flag);
93 #define mutt_collapse_thread(e)         mutt_traverse_thread(e, MUTT_THREAD_COLLAPSE)
94 #define mutt_uncollapse_thread(e)       mutt_traverse_thread(e, MUTT_THREAD_UNCOLLAPSE)
95 #define mutt_thread_contains_unread(e)  mutt_traverse_thread(e, MUTT_THREAD_UNREAD)
96 #define mutt_thread_contains_flagged(e) mutt_traverse_thread(e, MUTT_THREAD_FLAGGED)
97 #define mutt_thread_next_unread(e)      mutt_traverse_thread(e, MUTT_THREAD_NEXT_UNREAD)
98 
99 enum UseThreads mutt_thread_style(void);
100 #define mutt_using_threads() (mutt_thread_style() > UT_FLAT)
101 const char *get_use_threads_str(enum UseThreads value);
102 int sort_validator(const struct ConfigSet *cs, const struct ConfigDef *cdef,
103                    intptr_t value, struct Buffer *err);
104 
105 int mutt_aside_thread(struct Email *e, bool forwards, bool subthreads);
106 #define mutt_next_thread(e)        mutt_aside_thread(e, true,  false)
107 #define mutt_previous_thread(e)    mutt_aside_thread(e, false, false)
108 #define mutt_next_subthread(e)     mutt_aside_thread(e, true,  true)
109 #define mutt_previous_subthread(e) mutt_aside_thread(e, false, true)
110 
111 struct ThreadsContext *mutt_thread_ctx_init          (struct Mailbox *m);
112 void                   mutt_thread_ctx_free          (struct ThreadsContext **tctx);
113 void                   mutt_thread_collapse_collapsed(struct ThreadsContext *tctx);
114 void                   mutt_thread_collapse          (struct ThreadsContext *tctx, bool collapse);
115 bool                   mutt_thread_can_collapse      (struct Email *e);
116 
117 void                   mutt_clear_threads     (struct ThreadsContext *tctx);
118 void                   mutt_draw_tree         (struct ThreadsContext *tctx);
119 bool                   mutt_link_threads      (struct Email *parent, struct EmailList *children, struct Mailbox *m);
120 struct HashTable *     mutt_make_id_hash      (struct Mailbox *m);
121 int                    mutt_messages_in_thread(struct Mailbox *m, struct Email *e, enum MessageInThread mit);
122 int                    mutt_parent_message    (struct Email *e, bool find_root);
123 off_t                  mutt_set_vnum          (struct Mailbox *m);
124 void                   mutt_sort_threads      (struct ThreadsContext *tctx, bool init);
125 
126 #endif /* MUTT_MUTT_THREAD_H */
127