NeoMutt  2022-04-29-215-gc12b98
Teaching an old dog new tricks
DOXYGEN
mview.c File Reference

The "currently-open" mailbox. More...

#include "config.h"
#include <string.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "mview.h"
#include "imap/lib.h"
#include "ncrypt/lib.h"
#include "pattern/lib.h"
#include "mutt_header.h"
#include "mutt_thread.h"
#include "mx.h"
#include "score.h"
#include "sort.h"
+ Include dependency graph for mview.c:

Go to the source code of this file.

Functions

void mview_free (struct MailboxView **ptr)
 Free a MailboxView. More...
 
struct MailboxViewmview_new (struct Mailbox *m)
 Create a new MailboxView. More...
 
static void ctx_cleanup (struct MailboxView *mv)
 Release memory and initialize a MailboxView. More...
 
void mview_update (struct MailboxView *mv)
 Update the MailboxView's message counts. More...
 
static void update_tables (struct MailboxView *mv)
 Update a MailboxView's internal tables. More...
 
int mview_mailbox_observer (struct NotifyCallback *nc)
 Notification that a Mailbox has changed - Implements observer_t -. More...
 
bool message_is_tagged (struct Email *e)
 Is a message in the index tagged (and within limit) More...
 
int el_add_tagged (struct EmailList *el, struct MailboxView *mv, struct Email *e, bool use_tagged)
 Get a list of the tagged Emails. More...
 
struct Emailmutt_get_virt_email (struct Mailbox *m, int vnum)
 Get a virtual Email. More...
 
bool mview_has_limit (const struct MailboxView *mv)
 Is a limit active? More...
 
struct Mailboxmview_mailbox (struct MailboxView *mv)
 Wrapper to get the mailbox in a MailboxView, or NULL. More...
 

Detailed Description

The "currently-open" mailbox.

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

Function Documentation

◆ mview_free()

void mview_free ( struct MailboxView **  ptr)

Free a MailboxView.

Parameters
[out]ptrMailboxView to free

Definition at line 49 of file mview.c.

50{
51 if (!ptr || !*ptr)
52 return;
53
54 struct MailboxView *mv = *ptr;
55
56 struct EventMview ev_m = { mv };
57 mutt_debug(LL_NOTIFY, "NT_MVIEW_DELETE: %p\n", mv);
59
60 if (mv->mailbox)
62
65 FREE(&mv->pattern);
67
68 FREE(&mv);
69 *ptr = NULL;
70}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
int mview_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
Definition: mview.c:313
@ LL_NOTIFY
Log of notifications.
Definition: logging.h:45
#define FREE(x)
Definition: memory.h:43
bool notify_observer_remove(struct Notify *notify, const observer_t callback, const void *global_data)
Remove an observer from an object.
Definition: notify.c:228
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:73
void mutt_thread_ctx_free(struct ThreadsContext **tctx)
Finalize a threading context.
Definition: mutt_thread.c:365
@ NT_MVIEW_DELETE
The Mview is about to be destroyed.
Definition: mview.h:61
@ NT_MVIEW
MailboxView has changed, NotifyMview, EventMview.
Definition: notify_type.h:50
An Event that happened to an MailboxView.
Definition: mview.h:69
struct MailboxView * mv
The MailboxView this Event relates to.
Definition: mview.h:70
The "current" mailbox.
Definition: mview.h:38
struct Notify * notify
Notifications: NotifyMview, EventMview.
Definition: mview.h:50
struct PatternList * limit_pattern
Compiled limit pattern.
Definition: mview.h:41
struct ThreadsContext * threads
Threads context.
Definition: mview.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition: mview.h:49
char * pattern
Limit pattern string.
Definition: mview.h:40
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
Definition: mailbox.h:144
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mview_new()

struct MailboxView * mview_new ( struct Mailbox m)

Create a new MailboxView.

Parameters
mMailbox
Return values
ptrNew MailboxView

Definition at line 77 of file mview.c.

78{
79 if (!m)
80 return NULL;
81
82 struct MailboxView *mv = mutt_mem_calloc(1, sizeof(struct MailboxView));
83
84 mv->notify = notify_new();
86 struct EventMview ev_m = { mv };
87 mutt_debug(LL_NOTIFY, "NT_MVIEW_ADD: %p\n", mv);
89 // If the Mailbox is closed, mv->mailbox must be set to NULL
91
92 mv->mailbox = m;
94 mv->msg_in_pager = -1;
95 mv->collapsed = false;
97
98 return mv;
99}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:60
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:93
struct ThreadsContext * mutt_thread_ctx_init(struct Mailbox *m)
Initialize a threading context.
Definition: mutt_thread.c:352
void mview_update(struct MailboxView *mv)
Update the MailboxView's message counts.
Definition: mview.c:125
@ NT_MVIEW_ADD
The Mview has been opened.
Definition: mview.h:60
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
bool collapsed
Are all threads collapsed?
Definition: mview.h:47
int msg_in_pager
Message currently shown in the pager.
Definition: mview.h:43
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ctx_cleanup()

static void ctx_cleanup ( struct MailboxView mv)
static

Release memory and initialize a MailboxView.

Parameters
mvMailboxView to cleanup

Definition at line 105 of file mview.c.

106{
107 FREE(&mv->pattern);
109 if (mv->mailbox)
111
112 struct Notify *notify = mv->notify;
113 struct Mailbox *m = mv->mailbox;
114 memset(mv, 0, sizeof(struct MailboxView));
115 mv->notify = notify;
116 mv->mailbox = m;
117}
A mailbox.
Definition: mailbox.h:79
Notification API.
Definition: notify.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mview_update()

void mview_update ( struct MailboxView mv)

Update the MailboxView's message counts.

Parameters
mvMailbox View

this routine is called to update the counts in the MailboxView structure

Definition at line 125 of file mview.c.

126{
127 if (!mv || !mv->mailbox)
128 return;
129
130 struct Mailbox *m = mv->mailbox;
131
134
135 /* reset counters */
136 m->msg_unread = 0;
137 m->msg_flagged = 0;
138 m->msg_new = 0;
139 m->msg_deleted = 0;
140 m->msg_tagged = 0;
141 m->vcount = 0;
142 m->changed = false;
143
145
146 const bool c_score = cs_subset_bool(NeoMutt->sub, "score");
147 struct Email *e = NULL;
148 for (int msgno = 0; msgno < m->msg_count; msgno++)
149 {
150 e = m->emails[msgno];
151 if (!e)
152 continue;
153
154 if (WithCrypto)
155 {
156 /* NOTE: this _must_ be done before the check for mailcap! */
157 e->security = crypt_query(e->body);
158 }
159
160 if (mview_has_limit(mv))
161 {
162 e->vnum = -1;
163 }
164 else
165 {
166 m->v2r[m->vcount] = msgno;
167 e->vnum = m->vcount++;
168 }
169 e->msgno = msgno;
170
171 if (e->env->supersedes)
172 {
173 struct Email *e2 = NULL;
174
175 if (!m->id_hash)
177
178 e2 = mutt_hash_find(m->id_hash, e->env->supersedes);
179 if (e2)
180 {
181 e2->superseded = true;
182 if (c_score)
183 mutt_score_message(mv->mailbox, e2, true);
184 }
185 }
186
187 /* add this message to the hash tables */
188 if (m->id_hash && e->env->message_id)
190 if (m->subj_hash && e->env->real_subj)
193
194 if (c_score)
195 mutt_score_message(mv->mailbox, e, false);
196
197 if (e->changed)
198 m->changed = true;
199 if (e->flagged)
200 m->msg_flagged++;
201 if (e->deleted)
202 m->msg_deleted++;
203 if (e->tagged)
204 m->msg_tagged++;
205 if (!e->read)
206 {
207 m->msg_unread++;
208 if (!e->old)
209 m->msg_new++;
210 }
211 }
212
213 /* rethread from scratch */
214 mutt_sort_headers(mv->mailbox, mv->threads, true, &mv->vsize);
215}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:675
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
void mutt_label_hash_add(struct Mailbox *m, struct Email *e)
Add a message's labels to the Hash Table.
Definition: mutt_header.c:383
void mutt_clear_threads(struct ThreadsContext *tctx)
Clear the threading of message in a mailbox.
Definition: mutt_thread.c:708
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1651
bool mview_has_limit(const struct MailboxView *mv)
Is a limit active?
Definition: mview.c:435
#define WithCrypto
Definition: lib.h:116
void mutt_score_message(struct Mailbox *m, struct Email *e, bool upd_mbox)
Apply scoring to an email.
Definition: score.c:159
void mutt_sort_headers(struct Mailbox *m, struct ThreadsContext *threads, bool init, off_t *vsize)
Sort emails by their headers.
Definition: sort.c:356
The envelope/body of an email.
Definition: email.h:37
bool read
Email is read.
Definition: email.h:48
struct Envelope * env
Envelope information.
Definition: email.h:66
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
struct Body * body
List of MIME parts.
Definition: email.h:67
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
int vnum
Virtual message number.
Definition: email.h:114
int msgno
Number displayed to the user.
Definition: email.h:111
bool deleted
Email is deleted.
Definition: email.h:76
bool tagged
Email is tagged.
Definition: email.h:107
bool superseded
Got superseded?
Definition: email.h:50
char * supersedes
Supersedes header.
Definition: envelope.h:74
char * message_id
Message ID.
Definition: envelope.h:73
char * real_subj
Offset of the real subject.
Definition: envelope.h:71
off_t vsize
Size (in bytes) of the messages shown.
Definition: mview.h:39
int vcount
The number of virtual messages.
Definition: mailbox.h:99
bool changed
Mailbox has been modified.
Definition: mailbox.h:110
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:98
int msg_new
Number of new messages.
Definition: mailbox.h:92
int msg_count
Total number of messages.
Definition: mailbox.h:88
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:124
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
struct HashTable * id_hash
Hash Table by msg id.
Definition: mailbox.h:123
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:93
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:90
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:94
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_tables()

static void update_tables ( struct MailboxView mv)
static

Update a MailboxView's internal tables.

Parameters
mvMailbox

Definition at line 221 of file mview.c.

222{
223 if (!mv || !mv->mailbox)
224 return;
225
226 struct Mailbox *m = mv->mailbox;
227
228 int i, j, padding;
229
230 /* update memory to reflect the new state of the mailbox */
231 m->vcount = 0;
232 mv->vsize = 0;
233 m->msg_tagged = 0;
234 m->msg_deleted = 0;
235 m->msg_new = 0;
236 m->msg_unread = 0;
237 m->changed = false;
238 m->msg_flagged = 0;
239 padding = mx_msg_padding_size(m);
240 for (i = 0, j = 0; i < m->msg_count; i++)
241 {
242 if (!m->emails[i])
243 break;
244 const bool c_maildir_trash = cs_subset_bool(NeoMutt->sub, "maildir_trash");
245 if (!m->emails[i]->quasi_deleted &&
246 (!m->emails[i]->deleted || ((m->type == MUTT_MAILDIR) && c_maildir_trash)))
247 {
248 if (i != j)
249 {
250 m->emails[j] = m->emails[i];
251 m->emails[i] = NULL;
252 }
253 m->emails[j]->msgno = j;
254 if (m->emails[j]->vnum != -1)
255 {
256 m->v2r[m->vcount] = j;
257 m->emails[j]->vnum = m->vcount++;
258 struct Body *b = m->emails[j]->body;
259 mv->vsize += b->length + b->offset - b->hdr_offset + padding;
260 }
261
262 m->emails[j]->changed = false;
263 m->emails[j]->env->changed = false;
264
265 if ((m->type == MUTT_MAILDIR) && c_maildir_trash)
266 {
267 if (m->emails[j]->deleted)
268 m->msg_deleted++;
269 }
270
271 if (m->emails[j]->tagged)
272 m->msg_tagged++;
273 if (m->emails[j]->flagged)
274 m->msg_flagged++;
275 if (!m->emails[j]->read)
276 {
277 m->msg_unread++;
278 if (!m->emails[j]->old)
279 m->msg_new++;
280 }
281
282 j++;
283 }
284 else
285 {
286 if ((m->type == MUTT_NOTMUCH) || (m->type == MUTT_MH) ||
287 (m->type == MUTT_MAILDIR) || (m->type == MUTT_IMAP))
288 {
289 mailbox_size_sub(m, m->emails[i]);
290 }
291 /* remove message from the hash tables */
292 if (m->subj_hash && m->emails[i]->env->real_subj)
294 if (m->id_hash && m->emails[i]->env->message_id)
297
298#ifdef USE_IMAP
299 if (m->type == MUTT_IMAP)
301#endif
302
303 mailbox_gc_add(m->emails[i]);
304 m->emails[i] = NULL;
305 }
306 }
307 m->msg_count = j;
308}
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
void imap_notify_delete_email(struct Mailbox *m, struct Email *e)
Inform IMAP that an Email has been deleted.
Definition: imap.c:654
void mailbox_size_sub(struct Mailbox *m, const struct Email *e)
Subtract an email's size from the total size of a Mailbox.
Definition: mailbox.c:247
void mailbox_gc_add(struct Email *e)
Add an Email to the garbage-collection set.
Definition: mailbox.c:282
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
@ MUTT_MH
'MH' Mailbox type
Definition: mailbox.h:47
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition: mailbox.h:48
void mutt_label_hash_remove(struct Mailbox *m, struct Email *e)
Remove a message's labels from the Hash Table.
Definition: mutt_header.c:396
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
Definition: mx.c:1549
The body of an email.
Definition: body.h:36
LOFF_T offset
offset where the actual data begins
Definition: body.h:52
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:80
bool quasi_deleted
Deleted from neomutt, but not modified on disk.
Definition: email.h:103
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:92
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ message_is_tagged()

bool message_is_tagged ( struct Email e)

Is a message in the index tagged (and within limit)

Parameters
eEmail
Return values
trueThe message is both tagged and within limit

If a limit is in effect, the message must be visible within it.

Definition at line 352 of file mview.c.

353{
354 return e->visible && e->tagged;
355}
bool visible
Is this message part of the view?
Definition: email.h:121
+ Here is the caller graph for this function:

◆ el_add_tagged()

int el_add_tagged ( struct EmailList *  el,
struct MailboxView mv,
struct Email e,
bool  use_tagged 
)

Get a list of the tagged Emails.

Parameters
elEmpty EmailList to populate
mvCurrent Mailbox
eCurrent Email
use_taggedUse tagged Emails
Return values
numNumber of selected emails
-1Error

Definition at line 366 of file mview.c.

367{
368 int count = 0;
369
370 if (use_tagged)
371 {
372 if (!mv || !mv->mailbox || !mv->mailbox->emails)
373 return -1;
374
375 struct Mailbox *m = mv->mailbox;
376 for (int i = 0; i < m->msg_count; i++)
377 {
378 e = m->emails[i];
379 if (!e)
380 break;
381 if (!message_is_tagged(e))
382 continue;
383
384 struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
385 en->email = e;
386 STAILQ_INSERT_TAIL(el, en, entries);
387 count++;
388 }
389 }
390 else
391 {
392 if (!e)
393 return -1;
394
395 struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
396 en->email = e;
397 STAILQ_INSERT_TAIL(el, en, entries);
398 count = 1;
399 }
400
401 return count;
402}
bool message_is_tagged(struct Email *e)
Is a message in the index tagged (and within limit)
Definition: mview.c:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
List of Emails.
Definition: email.h:131
struct Email * email
Email in the list.
Definition: email.h:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_virt_email()

struct Email * mutt_get_virt_email ( struct Mailbox m,
int  vnum 
)

Get a virtual Email.

Parameters
mMailbox
vnumVirtual index number
Return values
ptrEmail
NULLNo Email selected, or bad index values

This safely gets the result of the following:

  • mailbox->emails[mailbox->v2r[vnum]]

Definition at line 414 of file mview.c.

415{
416 if (!m || !m->emails || !m->v2r)
417 return NULL;
418
419 if ((vnum < 0) || (vnum >= m->vcount))
420 return NULL;
421
422 int inum = m->v2r[vnum];
423 if ((inum < 0) || (inum >= m->msg_count))
424 return NULL;
425
426 return m->emails[inum];
427}
+ Here is the caller graph for this function:

◆ mview_has_limit()

bool mview_has_limit ( const struct MailboxView mv)

Is a limit active?

Parameters
mvMailboxView
Return values
trueA limit is active
falseNo limit is active

Definition at line 435 of file mview.c.

436{
437 return mv && mv->pattern;
438}
+ Here is the caller graph for this function:

◆ mview_mailbox()

struct Mailbox * mview_mailbox ( struct MailboxView mv)

Wrapper to get the mailbox in a MailboxView, or NULL.

Parameters
mvMailboxView
Return values
ptrThe mailbox in the MailboxView
NULLMailboxView is NULL or doesn't have a mailbox

Definition at line 446 of file mview.c.

447{
448 return mv ? mv->mailbox : NULL;
449}
+ Here is the caller graph for this function: