NeoMutt
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 "opcodes.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

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 54 of file flags.c.

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

364{
365 if (!m || !ea || ARRAY_EMPTY(ea))
366 return;
367
368 struct Email **ep = NULL;
369 ARRAY_FOREACH(ep, ea)
370 {
371 struct Email *e = *ep;
372 mutt_set_flag(m, e, flag, bf, true);
373 }
374}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:211
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:73
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:54
The envelope/body of an email.
Definition: email.h:37
+ 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 386 of file flags.c.

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