NeoMutt  2024-02-01-35-geee02f
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
flags.c File Reference

Manipulate the flags in an email header. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "color/lib.h"
#include "index/lib.h"
#include "key/lib.h"
#include "mutt_thread.h"
#include "protos.h"
+ Include dependency graph for flags.c:

Go to the source code of this file.

Functions

void mutt_set_flag (struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
 Set a flag on an email.
 
void mutt_emails_set_flag (struct Mailbox *m, struct EmailArray *ea, enum MessageType flag, bool bf)
 Set flag on messages.
 
int mutt_thread_set_flag (struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool subthread)
 Set a flag on an entire thread.
 
int mw_change_flag (struct Mailbox *m, struct EmailArray *ea, bool bf)
 Change the flag on a Message -.
 

Detailed Description

Manipulate the flags in an email header.

Authors
  • Michael R. Elkins
  • Richard Russon
  • Fabrice Bellet
  • Mehdi Abaakouk
  • Pietro Cerutti

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 flags.c.

Function Documentation

◆ mutt_set_flag()

void mutt_set_flag ( struct Mailbox m,
struct Email e,
enum MessageType  flag,
bool  bf,
bool  upd_mbox 
)

Set a flag on an email.

Parameters
mMailbox
eEmail
flagFlag to set, e.g. MUTT_DELETE
bftrue: set the flag; false: clear the flag
upd_mboxtrue: update the Mailbox

Definition at line 57 of file flags.c.

59{
60 if (!m || !e)
61 return;
62
63 bool changed = e->changed;
64 int deleted = m->msg_deleted;
65 int tagged = m->msg_tagged;
66 int flagged = m->msg_flagged;
67 int update = false;
68
69 if (m->readonly && (flag != MUTT_TAG))
70 return; /* don't modify anything if we are read-only */
71
72 switch (flag)
73 {
74 case MUTT_DELETE:
75 {
76 if (!(m->rights & MUTT_ACL_DELETE))
77 return;
78
79 if (bf)
80 {
81 const bool c_flag_safe = cs_subset_bool(NeoMutt->sub, "flag_safe");
82 if (!e->deleted && !m->readonly && (!e->flagged || !c_flag_safe))
83 {
84 e->deleted = true;
85 update = true;
86 if (upd_mbox)
87 m->msg_deleted++;
88 /* deleted messages aren't treated as changed elsewhere so that the
89 * purge-on-sync option works correctly. This isn't applicable here */
90 if (m->type == MUTT_IMAP)
91 {
92 e->changed = true;
93 if (upd_mbox)
94 m->changed = true;
95 }
96 }
97 }
98 else if (e->deleted)
99 {
100 e->deleted = false;
101 update = true;
102 if (upd_mbox)
103 m->msg_deleted--;
104 /* see my comment above */
105 if (m->type == MUTT_IMAP)
106 {
107 e->changed = true;
108 if (upd_mbox)
109 m->changed = true;
110 }
111 /* If the user undeletes a message which is marked as
112 * "trash" in the maildir folder on disk, the folder has
113 * been changed, and is marked accordingly. However, we do
114 * _not_ mark the message itself changed, because trashing
115 * is checked in specific code in the maildir folder
116 * driver. */
117 if ((m->type == MUTT_MAILDIR) && upd_mbox && e->trash)
118 m->changed = true;
119 }
120 break;
121 }
122 case MUTT_PURGE:
123 {
124 if (!(m->rights & MUTT_ACL_DELETE))
125 return;
126
127 if (bf)
128 {
129 if (!e->purge && !m->readonly)
130 e->purge = true;
131 }
132 else if (e->purge)
133 {
134 e->purge = false;
135 }
136 break;
137 }
138 case MUTT_NEW:
139 {
140 if (!(m->rights & MUTT_ACL_SEEN))
141 return;
142
143 if (bf)
144 {
145 if (e->read || e->old)
146 {
147 update = true;
148 e->old = false;
149 if (upd_mbox)
150 m->msg_new++;
151 if (e->read)
152 {
153 e->read = false;
154 if (upd_mbox)
155 m->msg_unread++;
156 }
157 e->changed = true;
158 if (upd_mbox)
159 m->changed = true;
160 }
161 }
162 else if (!e->read)
163 {
164 update = true;
165 if (!e->old)
166 if (upd_mbox)
167 m->msg_new--;
168 e->read = true;
169 if (upd_mbox)
170 m->msg_unread--;
171 e->changed = true;
172 if (upd_mbox)
173 m->changed = true;
174 }
175 break;
176 }
177 case MUTT_OLD:
178 {
179 if (!(m->rights & MUTT_ACL_SEEN))
180 return;
181
182 if (bf)
183 {
184 if (!e->old)
185 {
186 update = true;
187 e->old = true;
188 if (!e->read)
189 if (upd_mbox)
190 m->msg_new--;
191 e->changed = true;
192 if (upd_mbox)
193 m->changed = true;
194 }
195 }
196 else if (e->old)
197 {
198 update = true;
199 e->old = false;
200 if (!e->read)
201 if (upd_mbox)
202 m->msg_new++;
203 e->changed = true;
204 if (upd_mbox)
205 m->changed = true;
206 }
207 break;
208 }
209 case MUTT_READ:
210 {
211 if (!(m->rights & MUTT_ACL_SEEN))
212 return;
213
214 if (bf)
215 {
216 if (!e->read)
217 {
218 update = true;
219 e->read = true;
220 if (upd_mbox)
221 m->msg_unread--;
222 if (!e->old)
223 if (upd_mbox)
224 m->msg_new--;
225 e->changed = true;
226 if (upd_mbox)
227 m->changed = true;
228 }
229 }
230 else if (e->read)
231 {
232 update = true;
233 e->read = false;
234 if (upd_mbox)
235 m->msg_unread++;
236 if (!e->old)
237 if (upd_mbox)
238 m->msg_new++;
239 e->changed = true;
240 if (upd_mbox)
241 m->changed = true;
242 }
243 break;
244 }
245 case MUTT_REPLIED:
246 {
247 if (!(m->rights & MUTT_ACL_WRITE))
248 return;
249
250 if (bf)
251 {
252 if (!e->replied)
253 {
254 update = true;
255 e->replied = true;
256 if (!e->read)
257 {
258 e->read = true;
259 if (upd_mbox)
260 m->msg_unread--;
261 if (!e->old)
262 if (upd_mbox)
263 m->msg_new--;
264 }
265 e->changed = true;
266 if (upd_mbox)
267 m->changed = true;
268 }
269 }
270 else if (e->replied)
271 {
272 update = true;
273 e->replied = false;
274 e->changed = true;
275 if (upd_mbox)
276 m->changed = true;
277 }
278 break;
279 }
280 case MUTT_FLAG:
281 {
282 if (!(m->rights & MUTT_ACL_WRITE))
283 return;
284
285 if (bf)
286 {
287 if (!e->flagged)
288 {
289 update = true;
290 e->flagged = bf;
291 if (upd_mbox)
292 m->msg_flagged++;
293 e->changed = true;
294 if (upd_mbox)
295 m->changed = true;
296 }
297 }
298 else if (e->flagged)
299 {
300 update = true;
301 e->flagged = false;
302 if (upd_mbox)
303 m->msg_flagged--;
304 e->changed = true;
305 if (upd_mbox)
306 m->changed = true;
307 }
308 break;
309 }
310 case MUTT_TAG:
311 {
312 if (bf)
313 {
314 if (!e->tagged)
315 {
316 update = true;
317 e->tagged = true;
318 if (upd_mbox)
319 m->msg_tagged++;
320 }
321 }
322 else if (e->tagged)
323 {
324 update = true;
325 e->tagged = false;
326 if (upd_mbox)
327 m->msg_tagged--;
328 }
329 break;
330 }
331 default:
332 {
333 break;
334 }
335 }
336
337 if (update)
338 {
340 struct EventMailbox ev_m = { m };
342 }
343
344 /* if the message status has changed, we need to invalidate the cached
345 * search results so that any future search will match the current status
346 * of this message and not what it was at the time it was last searched. */
347 if (e->searched && ((changed != e->changed) || (deleted != m->msg_deleted) ||
348 (tagged != m->msg_tagged) || (flagged != m->msg_flagged)))
349 {
350 e->searched = false;
351 }
352}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
@ NT_MAILBOX_CHANGE
Mailbox has been changed.
Definition: mailbox.h:173
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:63
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:71
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition: mailbox.h:48
#define MUTT_ACL_SEEN
Change the 'seen' status of a message.
Definition: mailbox.h:70
void mutt_set_header_color(struct Mailbox *m, struct Email *e)
Select a colour for a message.
Definition: dlg_index.c:1366
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:173
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:73
@ MUTT_OLD
Old messages.
Definition: mutt.h:71
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition: mutt.h:77
@ MUTT_TAG
Tagged messages.
Definition: mutt.h:80
@ MUTT_FLAG
Flagged messages.
Definition: mutt.h:79
@ MUTT_DELETE
Messages to be deleted.
Definition: mutt.h:75
@ MUTT_NEW
New messages.
Definition: mutt.h:70
@ MUTT_REPLIED
Messages that have been replied to.
Definition: mutt.h:72
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
bool searched
Email has been searched.
Definition: email.h:108
bool read
Email is read.
Definition: email.h:50
bool purge
Skip trash folder when deleting.
Definition: email.h:79
bool old
Email is seen, but unread.
Definition: email.h:49
bool changed
Email has been edited.
Definition: email.h:77
bool flagged
Marked important?
Definition: email.h:47
bool replied
Email has been replied to.
Definition: email.h:51
bool deleted
Email is deleted.
Definition: email.h:78
bool trash
Message is marked as trashed on disk (used by the maildir_trash option)
Definition: email.h:53
bool tagged
Email is tagged.
Definition: email.h:110
An Event that happened to a Mailbox.
Definition: mailbox.h:187
bool changed
Mailbox has been modified.
Definition: mailbox.h:110
int msg_new
Number of new messages.
Definition: mailbox.h:92
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:119
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
Definition: mailbox.h:145
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:93
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:90
bool readonly
Don't allow changes to the mailbox.
Definition: mailbox.h:116
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:94
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_emails_set_flag()

void mutt_emails_set_flag ( struct Mailbox m,
struct EmailArray *  ea,
enum MessageType  flag,
bool  bf 
)

Set flag on messages.

Parameters
mMailbox
eaArray of Emails to flag
flagFlag to set, e.g. MUTT_DELETE
bftrue: set the flag; false: clear the flag

Definition at line 361 of file flags.c.

363{
364 if (!m || !ea || ARRAY_EMPTY(ea))
365 return;
366
367 struct Email **ep = NULL;
368 ARRAY_FOREACH(ep, ea)
369 {
370 struct Email *e = *ep;
371 mutt_set_flag(m, e, flag, bf, true);
372 }
373}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:212
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:74
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
Definition: flags.c:57
The envelope/body of an email.
Definition: email.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_thread_set_flag()

int mutt_thread_set_flag ( struct Mailbox m,
struct Email e,
enum MessageType  flag,
bool  bf,
bool  subthread 
)

Set a flag on an entire thread.

Parameters
mMailbox
eEmail
flagFlag to set, e.g. MUTT_DELETE
bftrue: set the flag; false: clear the flag
subthreadIf true apply to all of the thread
Return values
0Success
-1Failure

Definition at line 385 of file flags.c.

387{
388 struct MuttThread *start = NULL;
389 struct MuttThread *cur = e->thread;
390
391 if (!mutt_using_threads())
392 {
393 mutt_error(_("Threading is not enabled"));
394 return -1;
395 }
396
397 if (!subthread)
398 while (cur->parent)
399 cur = cur->parent;
400
401 start = cur;
402
403 if (cur->message && (cur != e->thread))
404 mutt_set_flag(m, cur->message, flag, bf, true);
405
406 cur = cur->child;
407 if (!cur)
408 goto done;
409
410 while (true)
411 {
412 if (cur->message && (cur != e->thread))
413 mutt_set_flag(m, cur->message, flag, bf, true);
414
415 if (cur->child)
416 {
417 cur = cur->child;
418 }
419 else if (cur->next)
420 {
421 cur = cur->next;
422 }
423 else
424 {
425 while (!cur->next)
426 {
427 cur = cur->parent;
428 if (cur == start)
429 goto done;
430 }
431 cur = cur->next;
432 }
433 }
434done:
435 cur = e->thread;
436 if (cur->message)
437 mutt_set_flag(m, cur->message, flag, bf, true);
438 return 0;
439}
#define mutt_error(...)
Definition: logging2.h:92
#define _(a)
Definition: message.h:28
#define mutt_using_threads()
Definition: mutt_thread.h:114
struct MuttThread * thread
Thread of Emails.
Definition: email.h:122
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function: