NeoMutt  2022-04-29-81-g9c5a59
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:40
bool notify_observer_remove(struct Notify *notify, observer_t callback, 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:145
+ 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
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:60
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
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 
133  mutt_hash_free(&m->id_hash);
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)
176  m->id_hash = mutt_make_id_hash(m);
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)
192  mutt_label_hash_add(m, e);
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 }
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
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_label_hash_add(struct Mailbox *m, struct Email *e)
Add a message's labels to the Hash Table.
Definition: mutt_header.c:382
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:433
#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:111
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:125
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
struct HashTable * id_hash
Hash Table by msg id.
Definition: mailbox.h:124
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)
293  mutt_hash_delete(m->subj_hash, m->emails[i]->env->real_subj, m->emails[i]);
294  if (m->id_hash && m->emails[i]->env->message_id)
295  mutt_hash_delete(m->id_hash, m->emails[i]->env->message_id, m->emails[i]);
296  mutt_label_hash_remove(m, m->emails[i]);
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:395
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 350 of file mview.c.

351 {
352  return e->visible && e->tagged;
353 }
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 364 of file mview.c.

365 {
366  int count = 0;
367 
368  if (use_tagged)
369  {
370  if (!mv || !mv->mailbox || !mv->mailbox->emails)
371  return -1;
372 
373  struct Mailbox *m = mv->mailbox;
374  for (int i = 0; i < m->msg_count; i++)
375  {
376  e = m->emails[i];
377  if (!e)
378  break;
379  if (!message_is_tagged(e))
380  continue;
381 
382  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
383  en->email = e;
384  STAILQ_INSERT_TAIL(el, en, entries);
385  count++;
386  }
387  }
388  else
389  {
390  if (!e)
391  return -1;
392 
393  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
394  en->email = e;
395  STAILQ_INSERT_TAIL(el, en, entries);
396  count = 1;
397  }
398 
399  return count;
400 }
bool message_is_tagged(struct Email *e)
Is a message in the index tagged (and within limit)
Definition: mview.c:350
#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 412 of file mview.c.

413 {
414  if (!m || !m->emails || !m->v2r)
415  return NULL;
416 
417  if ((vnum < 0) || (vnum >= m->vcount))
418  return NULL;
419 
420  int inum = m->v2r[vnum];
421  if ((inum < 0) || (inum >= m->msg_count))
422  return NULL;
423 
424  return m->emails[inum];
425 }
+ 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 433 of file mview.c.

434 {
435  return mv && mv->pattern;
436 }
+ 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 444 of file mview.c.

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