NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
thread.h File Reference

Create/manipulate threading in emails. More...

#include <stdbool.h>
+ Include dependency graph for thread.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  MuttThread
 An Email conversation. More...
 

Functions

void clean_references (struct MuttThread *brk, struct MuttThread *cur)
 Update email references for a broken Thread.
 
struct Emailfind_virtual (struct MuttThread *cur, bool reverse)
 Find an email with a Virtual message number.
 
void insert_message (struct MuttThread **add, struct MuttThread *parent, struct MuttThread *cur)
 Insert a message into a thread.
 
bool is_descendant (const struct MuttThread *a, const struct MuttThread *b)
 Is one thread a descendant of another.
 
void mutt_break_thread (struct Email *e)
 Break the email Thread.
 
void unlink_message (struct MuttThread **old, struct MuttThread *cur)
 Break the message out of the thread.
 

Detailed Description

Create/manipulate threading in emails.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file thread.h.

Function Documentation

◆ clean_references()

void clean_references ( struct MuttThread brk,
struct MuttThread cur 
)

Update email references for a broken Thread.

Parameters
brkBroken thread
curCurrent thread

Definition at line 174 of file thread.c.

175{
176 struct ListNode *ref = NULL;
177 bool done = false;
178
179 for (; cur; cur = cur->next, done = false)
180 {
181 /* parse subthread recursively */
182 clean_references(brk, cur->child);
183
184 if (!cur->message)
185 break; /* skip pseudo-message */
186
187 /* Looking for the first bad reference according to the new threading.
188 * Optimal since NeoMutt stores the references in reverse order, and the
189 * first loop should match immediately for mails respecting RFC2822. */
190 for (struct MuttThread *p = brk; !done && p; p = p->parent)
191 {
192 for (ref = STAILQ_FIRST(&cur->message->env->references);
193 p->message && ref; ref = STAILQ_NEXT(ref, entries))
194 {
195 if (mutt_istr_equal(ref->data, p->message->env->message_id))
196 {
197 done = true;
198 break;
199 }
200 }
201 }
202
203 if (done)
204 {
205 struct Email *e = cur->message;
206
207 /* clearing the References: header from obsolete Message-ID(s) */
208 struct ListNode *np = NULL;
209 while ((np = STAILQ_NEXT(ref, entries)))
210 {
211 STAILQ_REMOVE_AFTER(&cur->message->env->references, ref, entries);
212 FREE(&np->data);
213 FREE(&np);
214 }
215
216 e->changed = true;
218 }
219 }
220}
#define MUTT_ENV_CHANGED_REFS
References changed to break thread.
Definition: envelope.h:35
#define FREE(x)
Definition: memory.h:45
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_REMOVE_AFTER(head, elm, field)
Definition: queue.h:416
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
The envelope/body of an email.
Definition: email.h:37
struct Envelope * env
Envelope information.
Definition: email.h:66
bool changed
Email has been edited.
Definition: email.h:75
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:92
struct ListHead references
message references (in reverse order)
Definition: envelope.h:85
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
An Email conversation.
Definition: thread.h:34
struct MuttThread * parent
Parent of this Thread.
Definition: thread.h:44
struct MuttThread * child
Child of this Thread.
Definition: thread.h:45
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
struct MuttThread * next
Next sibling Thread.
Definition: thread.h:46
void clean_references(struct MuttThread *brk, struct MuttThread *cur)
Update email references for a broken Thread.
Definition: thread.c:174
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_virtual()

struct Email * find_virtual ( struct MuttThread cur,
bool  reverse 
)

Find an email with a Virtual message number.

Parameters
curThread to search
reverseIf true, reverse the direction of the search
Return values
ptrMatching Email

Definition at line 121 of file thread.c.

122{
123 if (!cur)
124 return NULL;
125
126 struct MuttThread *top = NULL;
127
128 if (cur->message && (cur->message->vnum >= 0))
129 return cur->message;
130
131 top = cur;
132 cur = cur->child;
133 if (!cur)
134 return NULL;
135
136 while (reverse && cur->next)
137 cur = cur->next;
138
139 while (true)
140 {
141 if (cur->message && (cur->message->vnum >= 0))
142 return cur->message;
143
144 if (cur->child)
145 {
146 cur = cur->child;
147
148 while (reverse && cur->next)
149 cur = cur->next;
150 }
151 else if (reverse ? cur->prev : cur->next)
152 {
153 cur = reverse ? cur->prev : cur->next;
154 }
155 else
156 {
157 while (!(reverse ? cur->prev : cur->next))
158 {
159 cur = cur->parent;
160 if (cur == top)
161 return NULL;
162 }
163 cur = reverse ? cur->prev : cur->next;
164 }
165 /* not reached */
166 }
167}
int vnum
Virtual message number.
Definition: email.h:113
struct MuttThread * prev
Previous sibling Thread.
Definition: thread.h:47
+ Here is the caller graph for this function:

◆ insert_message()

void insert_message ( struct MuttThread **  add,
struct MuttThread parent,
struct MuttThread cur 
)

Insert a message into a thread.

Parameters
[in,out]addNew thread to add
[in]parentParent of new thread
[in]curCurrent thread to add after

add cur as a prior sibling of *add, with parent parent

Definition at line 101 of file thread.c.

102{
103 if (!cur || !add)
104 return;
105
106 if (*add)
107 (*add)->prev = cur;
108
109 cur->parent = parent;
110 cur->next = *add;
111 cur->prev = NULL;
112 *add = cur;
113}
+ Here is the caller graph for this function:

◆ is_descendant()

bool is_descendant ( const struct MuttThread a,
const struct MuttThread b 
)

Is one thread a descendant of another.

Parameters
aParent thread
bChild thread
Return values
trueb is a descendent of a (child, grandchild, etc)

Definition at line 43 of file thread.c.

44{
45 while (a)
46 {
47 if (a == b)
48 return true;
49 a = a->parent;
50 }
51 return false;
52}
+ Here is the caller graph for this function:

◆ mutt_break_thread()

void mutt_break_thread ( struct Email e)

Break the email Thread.

Parameters
eEmail to break at

Definition at line 226 of file thread.c.

227{
228 if (!e)
229 return;
230
233 e->changed = true;
235
237}
#define MUTT_ENV_CHANGED_IRT
In-Reply-To changed to link/break threads.
Definition: envelope.h:34
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
struct MuttThread * thread
Thread of Emails.
Definition: email.h:118
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unlink_message()

void unlink_message ( struct MuttThread **  old,
struct MuttThread cur 
)

Break the message out of the thread.

Parameters
[in,out]oldRoot of thread
[in]curChild thread to separate

Remove cur and its descendants from their current location. Also make sure ancestors of cur no longer are sorted by the fact that cur is their descendant.

Definition at line 63 of file thread.c.

64{
65 if (!old || !cur)
66 return;
67
68 struct MuttThread *tmp = NULL;
69
70 if (cur->prev)
71 cur->prev->next = cur->next;
72 else
73 *old = cur->next;
74
75 if (cur->next)
76 cur->next->prev = cur->prev;
77
78 if (cur->sort_thread_key)
79 {
80 for (tmp = cur->parent;
81 tmp && (tmp->sort_thread_key == cur->sort_thread_key); tmp = tmp->parent)
82 {
83 tmp->sort_thread_key = NULL;
84 }
85 }
86 if (cur->sort_aux_key)
87 {
88 for (tmp = cur->parent; tmp && (tmp->sort_aux_key == cur->sort_aux_key); tmp = tmp->parent)
89 tmp->sort_aux_key = NULL;
90 }
91}
struct Email * sort_aux_key
Email that controls how subthread siblings sort.
Definition: thread.h:51
struct Email * sort_thread_key
Email that controls how top thread sorts.
Definition: thread.h:50
+ Here is the caller graph for this function: