NeoMutt  2022-04-29-323-g5fcc6c
Teaching an old dog new tricks
DOXYGEN
window.c File Reference

Envelope Window. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include "private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "color/lib.h"
#include "ncrypt/lib.h"
#include "functions.h"
#include "options.h"
#include "wdata.h"
#include <libintl.h>
+ Include dependency graph for window.c:

Go to the source code of this file.

Macros

#define MAX_ADDR_ROWS   5
 Maximum number of rows to use for the To:, Cc:, Bcc: fields. More...
 
#define MAX_USER_HDR_ROWS   5
 Maximum number of rows to use for the Headers: field. More...
 

Functions

static void calc_header_width_padding (int idx, const char *header, bool calc_max)
 Calculate the width needed for the compose labels. More...
 
static void init_header_padding (void)
 Calculate how much padding the compose table will need. More...
 
static int calc_address (struct AddressList *al, struct ListHead *slist, short cols, short *srows)
 Calculate how many rows an AddressList will need. More...
 
static int calc_security (struct Email *e, short *rows, const struct ConfigSubset *sub)
 Calculate how many rows the security info will need. More...
 
static int calc_user_hdrs (const struct ListHead *hdrs)
 Calculate how many rows are needed for user-defined headers. More...
 
static int calc_envelope (struct MuttWindow *win, struct EnvelopeWindowData *wdata)
 Calculate how many rows the envelope will need. More...
 
static void draw_floating (struct MuttWindow *win, int col, int row, const char *text)
 Draw a floating label. More...
 
static void draw_header (struct MuttWindow *win, int row, enum HeaderField field)
 Draw an aligned label. More...
 
static void draw_header_content (struct MuttWindow *win, int row, enum HeaderField field, const char *content)
 Draw content on a separate line aligned to header prompt. More...
 
static int draw_crypt_lines (struct MuttWindow *win, struct EnvelopeWindowData *wdata, int row)
 Update the encryption info in the compose window. More...
 
static void draw_mix_line (struct ListHead *chain, struct MuttWindow *win, int row)
 Redraw the Mixmaster chain. More...
 
static int draw_envelope_addr (int field, struct AddressList *al, struct MuttWindow *win, int row, size_t max_lines)
 Write addresses to the compose window. More...
 
static int draw_envelope_user_hdrs (struct MuttWindow *win, struct EnvelopeWindowData *wdata, int row)
 Write user-defined headers to the compose window. More...
 
static void draw_envelope (struct MuttWindow *win, struct EnvelopeWindowData *wdata)
 Write the email headers to the compose window. More...
 
static int env_recalc (struct MuttWindow *win)
 Recalculate the Window data - Implements MuttWindow::recalc() -. More...
 
static int env_repaint (struct MuttWindow *win)
 Repaint the Window - Implements MuttWindow::repaint() -. More...
 
static int env_color_observer (struct NotifyCallback *nc)
 Notification that a Color has changed - Implements observer_t -. More...
 
static int env_config_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has changed - Implements observer_t -. More...
 
static int env_email_observer (struct NotifyCallback *nc)
 Notification that the Email has changed - Implements observer_t -. More...
 
static int env_header_observer (struct NotifyCallback *nc)
 Notification that a User Header has changed - Implements observer_t -. More...
 
static int env_window_observer (struct NotifyCallback *nc)
 Notification that a Window has changed - Implements observer_t -. More...
 
struct MuttWindowenv_window_new (struct Email *e, struct Buffer *fcc, struct ConfigSubset *sub)
 Create the Envelope Window. More...
 

Variables

int HeaderPadding [HDR_ATTACH_TITLE] = { 0 }
 
int MaxHeaderWidth = 0
 
const char *const Prompts []
 
static const char *const AutocryptRecUiFlags []
 

Detailed Description

Envelope Window.

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

Macro Definition Documentation

◆ MAX_ADDR_ROWS

#define MAX_ADDR_ROWS   5

Maximum number of rows to use for the To:, Cc:, Bcc: fields.

Definition at line 81 of file window.c.

◆ MAX_USER_HDR_ROWS

#define MAX_USER_HDR_ROWS   5

Maximum number of rows to use for the Headers: field.

Definition at line 84 of file window.c.

Function Documentation

◆ calc_header_width_padding()

static void calc_header_width_padding ( int  idx,
const char *  header,
bool  calc_max 
)
static

Calculate the width needed for the compose labels.

Parameters
idxStore the result at this index of HeaderPadding
headerHeader string
calc_maxIf true, calculate the maximum width

Definition at line 162 of file window.c.

163{
164 int width;
165
166 HeaderPadding[idx] = mutt_str_len(header);
167 width = mutt_strwidth(header);
168 if (calc_max && (MaxHeaderWidth < width))
169 MaxHeaderWidth = width;
170 HeaderPadding[idx] -= width;
171}
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:907
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: window.c:86
int MaxHeaderWidth
Definition: window.c:87
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:567
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_header_padding()

static void init_header_padding ( void  )
static

Calculate how much padding the compose table will need.

The padding needed for each header is strlen() + max_width - strwidth().

calc_header_width_padding sets each entry in HeaderPadding to strlen - width. Then, afterwards, we go through and add max_width to each entry.

Definition at line 181 of file window.c.

182{
183 static bool done = false;
184
185 if (done)
186 return;
187 done = true;
188
189 for (int i = 0; i < HDR_ATTACH_TITLE; i++)
190 {
191 if (i == HDR_CRYPTINFO)
192 continue;
193 calc_header_width_padding(i, _(Prompts[i]), true);
194 }
195
196 /* Don't include "Sign as: " in the MaxHeaderWidth calculation. It
197 * doesn't show up by default, and so can make the indentation of
198 * the other fields look funny. */
200
201 for (int i = 0; i < HDR_ATTACH_TITLE; i++)
202 {
204 if (HeaderPadding[i] < 0)
205 HeaderPadding[i] = 0;
206 }
207}
@ HDR_ATTACH_TITLE
The "-- Attachments" line.
Definition: private.h:56
@ HDR_CRYPTINFO
"Sign as:" field (encryption/signing info)
Definition: private.h:46
const char *const Prompts[]
Definition: window.c:89
static void calc_header_width_padding(int idx, const char *header, bool calc_max)
Calculate the width needed for the compose labels.
Definition: window.c:162
#define _(a)
Definition: message.h:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_address()

static int calc_address ( struct AddressList *  al,
struct ListHead *  slist,
short  cols,
short *  srows 
)
static

Calculate how many rows an AddressList will need.

Parameters
[in]alAddress List
[out]slistString list
[in]colsScreen columns available
[out]srowsRows needed
Return values
numRows needed
Note
Number of rows is capped at MAX_ADDR_ROWS

Definition at line 219 of file window.c.

221{
222 mutt_list_free(slist);
223 mutt_addrlist_write_list(al, slist);
224
225 int rows = 1;
226 int addr_len;
227 int width_left = cols;
228 struct ListNode *next = NULL;
229 struct ListNode *np = NULL;
230 STAILQ_FOREACH(np, slist, entries)
231 {
232 next = STAILQ_NEXT(np, entries);
233 addr_len = mutt_strwidth(np->data);
234 if (next)
235 addr_len += 2; // ", "
236
237 try_again:
238 if (addr_len >= width_left)
239 {
240 if (width_left == cols)
241 break;
242
243 rows++;
244 width_left = cols;
245 goto try_again;
246 }
247
248 if (addr_len < width_left)
249 width_left -= addr_len;
250 }
251
252 *srows = MIN(rows, MAX_ADDR_ROWS);
253 return *srows;
254}
size_t mutt_addrlist_write_list(const struct AddressList *al, struct ListHead *list)
Write Addresses to a List.
Definition: address.c:1201
#define MAX_ADDR_ROWS
Maximum number of rows to use for the To:, Cc:, Bcc: fields.
Definition: window.c:81
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
#define MIN(a, b)
Definition: memory.h:31
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_security()

static int calc_security ( struct Email e,
short *  rows,
const struct ConfigSubset sub 
)
static

Calculate how many rows the security info will need.

Parameters
eEmail
rowsRows needed
subConfigSubset
Return values
numRows needed

Definition at line 263 of file window.c.

264{
266 *rows = 0; // Neither PGP nor SMIME are built into NeoMutt
267 else if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) != 0)
268 *rows = 2; // 'Security:' and 'Sign as:'
269 else
270 *rows = 1; // Just 'Security:'
271
272#ifdef USE_AUTOCRYPT
273 const bool c_autocrypt = cs_subset_bool(sub, "autocrypt");
274 if (c_autocrypt)
275 *rows += 1;
276#endif
277
278 return *rows;
279}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define WithCrypto
Definition: lib.h:116
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_user_hdrs()

static int calc_user_hdrs ( const struct ListHead *  hdrs)
static

Calculate how many rows are needed for user-defined headers.

Parameters
hdrsHeader List
Return values
numRows needed, limited to MAX_USER_HDR_ROWS

Definition at line 286 of file window.c.

287{
288 int rows = 0; /* Don't print at all if no custom headers*/
289 struct ListNode *np = NULL;
290 STAILQ_FOREACH(np, hdrs, entries)
291 {
292 if (rows == MAX_USER_HDR_ROWS)
293 break;
294 rows++;
295 }
296 return rows;
297}
#define MAX_USER_HDR_ROWS
Maximum number of rows to use for the Headers: field.
Definition: window.c:84
+ Here is the caller graph for this function:

◆ calc_envelope()

static int calc_envelope ( struct MuttWindow win,
struct EnvelopeWindowData wdata 
)
static

Calculate how many rows the envelope will need.

Parameters
winWindow to draw on
wdataEnvelope Window data
Return values
numRows needed

Definition at line 305 of file window.c.

306{
307 int rows = 4; // 'From:', 'Subject:', 'Reply-To:', 'Fcc:'
308#ifdef MIXMASTER
309 rows++;
310#endif
311
312 struct Email *e = wdata->email;
313 struct Envelope *env = e->env;
314 const int cols = win->state.cols - MaxHeaderWidth;
315
316#ifdef USE_NNTP
317 if (wdata->is_news)
318 {
319 rows += 2; // 'Newsgroups:' and 'Followup-To:'
320 const bool c_x_comment_to = cs_subset_bool(wdata->sub, "x_comment_to");
321 if (c_x_comment_to)
322 rows++;
323 }
324 else
325#endif
326 {
327 rows += calc_address(&env->to, &wdata->to_list, cols, &wdata->to_rows);
328 rows += calc_address(&env->cc, &wdata->cc_list, cols, &wdata->cc_rows);
329 rows += calc_address(&env->bcc, &wdata->bcc_list, cols, &wdata->bcc_rows);
330 }
331 rows += calc_security(e, &wdata->sec_rows, wdata->sub);
332 const bool c_compose_show_user_headers = cs_subset_bool(wdata->sub, "compose_show_user_headers");
333 if (c_compose_show_user_headers)
334 rows += calc_user_hdrs(&env->userhdrs);
335
336 return rows;
337}
static int calc_address(struct AddressList *al, struct ListHead *slist, short cols, short *srows)
Calculate how many rows an AddressList will need.
Definition: window.c:219
static int calc_user_hdrs(const struct ListHead *hdrs)
Calculate how many rows are needed for user-defined headers.
Definition: window.c:286
static int calc_security(struct Email *e, short *rows, const struct ConfigSubset *sub)
Calculate how many rows the security info will need.
Definition: window.c:263
The envelope/body of an email.
Definition: email.h:37
struct Envelope * env
Envelope information.
Definition: email.h:66
struct ListHead cc_list
'Cc:' list of addresses
Definition: wdata.h:45
bool is_news
Email is a news article.
Definition: wdata.h:54
struct ListHead bcc_list
'Bcc:' list of addresses
Definition: wdata.h:46
struct Email * email
Email being composed.
Definition: wdata.h:41
short sec_rows
Number of rows used by the security fields.
Definition: wdata.h:51
short cc_rows
Number of rows used by the 'Cc:' field.
Definition: wdata.h:49
struct ConfigSubset * sub
Inherited config items.
Definition: wdata.h:40
struct ListHead to_list
'To:' list of addresses
Definition: wdata.h:44
short to_rows
Number of rows used by the 'To:' field.
Definition: wdata.h:48
short bcc_rows
Number of rows used by the 'Bcc:' field.
Definition: wdata.h:50
The header of an Email.
Definition: envelope.h:57
struct ListHead userhdrs
user defined headers
Definition: envelope.h:87
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_floating()

static void draw_floating ( struct MuttWindow win,
int  col,
int  row,
const char *  text 
)
static

Draw a floating label.

Parameters
winWindow to draw on
colColumn to draw at
rowRow to draw at
textText to display

Definition at line 346 of file window.c.

347{
349 mutt_window_mvprintw(win, col, row, "%s", text);
351}
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:57
@ MT_COLOR_COMPOSE_HEADER
Header labels, e.g. From:
Definition: color.h:44
struct AttrColor * mutt_curses_set_normal_backed_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:65
struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:81
int mutt_window_mvprintw(struct MuttWindow *win, int col, int row, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:322
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_header()

static void draw_header ( struct MuttWindow win,
int  row,
enum HeaderField  field 
)
static

Draw an aligned label.

Parameters
winWindow to draw on
rowRow to draw at
fieldField to display, e.g. HDR_FROM

Definition at line 359 of file window.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_header_content()

static void draw_header_content ( struct MuttWindow win,
int  row,
enum HeaderField  field,
const char *  content 
)
static

Draw content on a separate line aligned to header prompt.

Parameters
winWindow to draw on
rowRow to draw at
fieldField to display, e.g. HDR_FROM
contentText to display

Content will be truncated if it is wider than the window.

Definition at line 375 of file window.c.

377{
378 mutt_window_move(win, HeaderPadding[field], row);
379 mutt_paddstr(win, win->state.cols - HeaderPadding[field], content);
380}
void mutt_paddstr(struct MuttWindow *win, int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:816
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:293
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_crypt_lines()

static int draw_crypt_lines ( struct MuttWindow win,
struct EnvelopeWindowData wdata,
int  row 
)
static

Update the encryption info in the compose window.

Parameters
winWindow to draw on
wdataEnvelope Window data
rowWindow row to start drawing
Return values
numNumber of lines used

Definition at line 389 of file window.c.

390{
391 struct Email *e = wdata->email;
392
393 draw_header(win, row++, HDR_CRYPT);
394
396 return 0;
397
398 // We'll probably need two lines for 'Security:' and 'Sign as:'
399 int used = 2;
400 if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) == (SEC_ENCRYPT | SEC_SIGN))
401 {
403 mutt_window_addstr(win, _("Sign, Encrypt"));
404 }
405 else if (e->security & SEC_ENCRYPT)
406 {
408 mutt_window_addstr(win, _("Encrypt"));
409 }
410 else if (e->security & SEC_SIGN)
411 {
413 mutt_window_addstr(win, _("Sign"));
414 }
415 else
416 {
417 /* L10N: This refers to the encryption of the email, e.g. "Security: None" */
419 mutt_window_addstr(win, _("None"));
420 used = 1; // 'Sign as:' won't be needed
421 }
423
424 if ((e->security & (SEC_ENCRYPT | SEC_SIGN)))
425 {
426 if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
427 {
428 if ((e->security & SEC_INLINE))
429 mutt_window_addstr(win, _(" (inline PGP)"));
430 else
431 mutt_window_addstr(win, _(" (PGP/MIME)"));
432 }
433 else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
434 mutt_window_addstr(win, _(" (S/MIME)"));
435 }
436
437 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(wdata->sub, "crypt_opportunistic_encrypt");
438 if (c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT))
439 mutt_window_addstr(win, _(" (OppEnc mode)"));
440
442
443 if (((WithCrypto & APPLICATION_PGP) != 0) &&
444 (e->security & APPLICATION_PGP) && (e->security & SEC_SIGN))
445 {
446 draw_header(win, row++, HDR_CRYPTINFO);
447 const char *const c_pgp_sign_as = cs_subset_string(wdata->sub, "pgp_sign_as");
448 mutt_window_printf(win, "%s", c_pgp_sign_as ? c_pgp_sign_as : _("<default>"));
449 }
450
451 if (((WithCrypto & APPLICATION_SMIME) != 0) &&
453 {
454 draw_header(win, row++, HDR_CRYPTINFO);
455 const char *const c_smime_sign_as = cs_subset_string(wdata->sub, "smime_sign_as");
456 mutt_window_printf(win, "%s", c_smime_sign_as ? c_smime_sign_as : _("<default>"));
457 }
458
459 const char *const c_smime_encrypt_with = cs_subset_string(wdata->sub, "smime_encrypt_with");
460 if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME) &&
461 (e->security & SEC_ENCRYPT) && c_smime_encrypt_with)
462 {
463 draw_floating(win, 40, row - 1, _("Encrypt with: "));
464 mutt_window_printf(win, "%s", NONULL(c_smime_encrypt_with));
465 }
466
467#ifdef USE_AUTOCRYPT
468 const bool c_autocrypt = cs_subset_bool(wdata->sub, "autocrypt");
469 if (c_autocrypt)
470 {
471 draw_header(win, row, HDR_AUTOCRYPT);
472 if (e->security & SEC_AUTOCRYPT)
473 {
475 mutt_window_addstr(win, _("Encrypt"));
476 }
477 else
478 {
480 mutt_window_addstr(win, _("Off"));
481 }
482
483 /* L10N: The autocrypt compose menu Recommendation field.
484 Displays the output of the recommendation engine
485 (Off, No, Discouraged, Available, Yes) */
486 draw_floating(win, 40, row, _("Recommendation: "));
488
489 used++;
490 }
491#endif
492 return used;
493}
@ MT_COLOR_COMPOSE_SECURITY_ENCRYPT
Mail will be encrypted.
Definition: color.h:46
@ MT_COLOR_COMPOSE_SECURITY_NONE
Mail will not be encrypted or signed.
Definition: color.h:47
@ MT_COLOR_COMPOSE_SECURITY_BOTH
Mail will be encrypted and signed.
Definition: color.h:45
@ MT_COLOR_COMPOSE_SECURITY_SIGN
Mail will be signed.
Definition: color.h:48
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
@ HDR_AUTOCRYPT
"Autocrypt:" and "Recommendation:" fields
Definition: private.h:48
@ HDR_CRYPT
"Security:" field (encryption/signing info)
Definition: private.h:45
static const char *const AutocryptRecUiFlags[]
Definition: window.c:132
static void draw_header(struct MuttWindow *win, int row, enum HeaderField field)
Draw an aligned label.
Definition: window.c:359
static void draw_floating(struct MuttWindow *win, int col, int row, const char *text)
Draw a floating label.
Definition: window.c:346
int mutt_window_printf(struct MuttWindow *win, const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:424
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:409
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:242
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:85
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:87
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:86
#define NONULL(x)
Definition: string2.h:37
enum AutocryptRec autocrypt_rec
Autocrypt recommendation.
Definition: wdata.h:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_mix_line()

static void draw_mix_line ( struct ListHead *  chain,
struct MuttWindow win,
int  row 
)
static

Redraw the Mixmaster chain.

Parameters
chainList of chain links
winWindow to draw on
rowWindow row to start drawing

Definition at line 502 of file window.c.

503{
504 char *t = NULL;
505
506 draw_header(win, row, HDR_MIX);
507
508 if (STAILQ_EMPTY(chain))
509 {
510 mutt_window_addstr(win, _("<no chain defined>"));
512 return;
513 }
514
515 int c = 12;
516 struct ListNode *np = NULL;
517 STAILQ_FOREACH(np, chain, entries)
518 {
519 t = np->data;
520 if (t && (t[0] == '0') && (t[1] == '\0'))
521 t = "<random>";
522
523 if (c + mutt_str_len(t) + 2 >= win->state.cols)
524 break;
525
526 mutt_window_addstr(win, NONULL(t));
527 if (STAILQ_NEXT(np, entries))
528 mutt_window_addstr(win, ", ");
529
530 c += mutt_str_len(t) + 2;
531 }
532}
@ HDR_MIX
"Mix:" field (Mixmaster chain)
Definition: private.h:43
#define STAILQ_EMPTY(head)
Definition: queue.h:348
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_envelope_addr()

static int draw_envelope_addr ( int  field,
struct AddressList *  al,
struct MuttWindow win,
int  row,
size_t  max_lines 
)
static

Write addresses to the compose window.

Parameters
fieldField to display, e.g. HDR_FROM
alAddress list to write
winWindow
rowWindow row to start drawing
max_linesHow many lines may be used
Return values
numLines used

Definition at line 544 of file window.c.

546{
547 draw_header(win, row, field);
548
549 struct ListHead list = STAILQ_HEAD_INITIALIZER(list);
550 int count = mutt_addrlist_write_list(al, &list);
551
552 int lines_used = 1;
553 int width_left = win->state.cols - MaxHeaderWidth;
554 char more[32] = { 0 };
555 int more_len = 0;
556
557 char *sep = NULL;
558 struct ListNode *next = NULL;
559 struct ListNode *np = NULL;
560 STAILQ_FOREACH(np, &list, entries)
561 {
562 next = STAILQ_NEXT(np, entries);
563 int addr_len = mutt_strwidth(np->data);
564 if (next)
565 {
566 sep = ", ";
567 addr_len += 2;
568 }
569 else
570 {
571 sep = "";
572 }
573
574 count--;
575 try_again:
576 more_len = snprintf(more, sizeof(more),
577 ngettext("(+%d more)", "(+%d more)", count), count);
578 mutt_debug(LL_DEBUG3, "text: '%s' len: %d\n", more, more_len);
579
580 int reserve = ((count > 0) && (lines_used == max_lines)) ? more_len : 0;
581 mutt_debug(LL_DEBUG3, "processing: %s (al:%d, wl:%d, r:%d, lu:%d)\n",
582 np->data, addr_len, width_left, reserve, lines_used);
583 if (addr_len >= (width_left - reserve))
584 {
585 mutt_debug(LL_DEBUG3, "not enough space\n");
586 if (lines_used == max_lines)
587 {
588 mutt_debug(LL_DEBUG3, "no more lines\n");
589 mutt_debug(LL_DEBUG3, "truncating: %s\n", np->data);
590 mutt_paddstr(win, width_left, np->data);
591 break;
592 }
593
594 if (width_left == (win->state.cols - MaxHeaderWidth))
595 {
596 mutt_debug(LL_DEBUG3, "couldn't print: %s\n", np->data);
597 mutt_paddstr(win, width_left, np->data);
598 break;
599 }
600
601 mutt_debug(LL_DEBUG3, "start a new line\n");
603 row++;
604 lines_used++;
605 width_left = win->state.cols - MaxHeaderWidth;
607 goto try_again;
608 }
609
610 if (addr_len < width_left)
611 {
612 mutt_debug(LL_DEBUG3, "space for: %s\n", np->data);
613 mutt_window_addstr(win, np->data);
614 mutt_window_addstr(win, sep);
615 width_left -= addr_len;
616 }
617 mutt_debug(LL_DEBUG3, "%d addresses remaining\n", count);
618 mutt_debug(LL_DEBUG3, "%ld lines remaining\n", max_lines - lines_used);
619 }
620 mutt_list_free(&list);
621
622 if (count > 0)
623 {
624 mutt_window_move(win, win->state.cols - more_len, row);
626 mutt_window_addstr(win, more);
628 mutt_debug(LL_DEBUG3, "%d more (len %d)\n", count, more_len);
629 }
630 else
631 {
633 }
634
635 for (int i = lines_used; i < max_lines; i++)
636 {
637 mutt_window_move(win, 0, row + i);
639 }
640
641 mutt_debug(LL_DEBUG3, "used %d lines\n", lines_used);
642 return lines_used;
643}
@ MT_COLOR_BOLD
Bold text.
Definition: color.h:43
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_envelope_user_hdrs()

static int draw_envelope_user_hdrs ( struct MuttWindow win,
struct EnvelopeWindowData wdata,
int  row 
)
static

Write user-defined headers to the compose window.

Parameters
winWindow to draw on
wdataEnvelope Window data
rowWindow row to start drawing from
Return values
numRows used

Definition at line 652 of file window.c.

654{
655 const char *overflow_text = "...";
656 int rows_used = 0;
657
658 struct ListNode *first = STAILQ_FIRST(&wdata->email->env->userhdrs);
659 if (!first)
660 return rows_used;
661
662 /* Draw first entry on same line as prompt */
664 mutt_paddstr(win,
667 first->data);
668 rows_used++;
669
670 /* Draw any following entries on their own line */
671 struct ListNode *np = STAILQ_NEXT(first, entries);
672 if (!np)
673 return rows_used;
674
675 STAILQ_FOREACH_FROM(np, &wdata->email->env->userhdrs, entries)
676 {
677 if ((rows_used == (MAX_USER_HDR_ROWS - 1)) && STAILQ_NEXT(np, entries))
678 {
679 draw_header_content(win, row + rows_used, HDR_CUSTOM_HEADERS, overflow_text);
680 rows_used++;
681 break;
682 }
683 draw_header_content(win, row + rows_used, HDR_CUSTOM_HEADERS, np->data);
684 rows_used++;
685 }
686 return rows_used;
687}
@ HDR_CUSTOM_HEADERS
"Headers:" field
Definition: private.h:55
static void draw_header_content(struct MuttWindow *win, int row, enum HeaderField field, const char *content)
Draw content on a separate line aligned to header prompt.
Definition: window.c:375
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_FOREACH_FROM(var, head, field)
Definition: queue.h:357
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_envelope()

static void draw_envelope ( struct MuttWindow win,
struct EnvelopeWindowData wdata 
)
static

Write the email headers to the compose window.

Parameters
winWindow to draw on
wdataEnvelope Window data

Definition at line 694 of file window.c.

695{
696 struct Email *e = wdata->email;
697 const char *fcc = mutt_buffer_string(wdata->fcc);
698 const int cols = win->state.cols - MaxHeaderWidth;
699
701 int row = draw_envelope_addr(HDR_FROM, &e->env->from, win, 0, 1);
702
703#ifdef USE_NNTP
704 if (wdata->is_news)
705 {
706 draw_header(win, row++, HDR_NEWSGROUPS);
707 mutt_paddstr(win, cols, NONULL(e->env->newsgroups));
708
709 draw_header(win, row++, HDR_FOLLOWUPTO);
710 mutt_paddstr(win, cols, NONULL(e->env->followup_to));
711
712 const bool c_x_comment_to = cs_subset_bool(wdata->sub, "x_comment_to");
713 if (c_x_comment_to)
714 {
715 draw_header(win, row++, HDR_XCOMMENTTO);
716 mutt_paddstr(win, cols, NONULL(e->env->x_comment_to));
717 }
718 }
719 else
720#endif
721 {
722 row += draw_envelope_addr(HDR_TO, &e->env->to, win, row, wdata->to_rows);
723 row += draw_envelope_addr(HDR_CC, &e->env->cc, win, row, wdata->cc_rows);
724 row += draw_envelope_addr(HDR_BCC, &e->env->bcc, win, row, wdata->bcc_rows);
725 }
726
727 draw_header(win, row++, HDR_SUBJECT);
728 mutt_paddstr(win, cols, NONULL(e->env->subject));
729
730 row += draw_envelope_addr(HDR_REPLYTO, &e->env->reply_to, win, row, 1);
731
732 draw_header(win, row++, HDR_FCC);
733 mutt_paddstr(win, cols, fcc);
734
735 if (WithCrypto)
736 row += draw_crypt_lines(win, wdata, row);
737
738#ifdef MIXMASTER
739 draw_mix_line(&e->chain, win, row++);
740#endif
741 const bool c_compose_show_user_headers = cs_subset_bool(wdata->sub, "compose_show_user_headers");
742 if (c_compose_show_user_headers)
743 row += draw_envelope_user_hdrs(win, wdata, row);
744
746}
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
@ HDR_SUBJECT
"Subject:" field
Definition: private.h:39
@ HDR_REPLYTO
"Reply-To:" field
Definition: private.h:40
@ HDR_FCC
"Fcc:" (save folder) field
Definition: private.h:41
@ HDR_CC
"Cc:" field
Definition: private.h:37
@ HDR_TO
"To:" field
Definition: private.h:36
@ HDR_BCC
"Bcc:" field
Definition: private.h:38
@ HDR_FOLLOWUPTO
"Followup-To:" field
Definition: private.h:52
@ HDR_XCOMMENTTO
"X-Comment-To:" field
Definition: private.h:53
@ HDR_NEWSGROUPS
"Newsgroups:" field
Definition: private.h:51
@ HDR_FROM
"From:" field
Definition: private.h:35
static int draw_envelope_addr(int field, struct AddressList *al, struct MuttWindow *win, int row, size_t max_lines)
Write addresses to the compose window.
Definition: window.c:544
static void draw_mix_line(struct ListHead *chain, struct MuttWindow *win, int row)
Redraw the Mixmaster chain.
Definition: window.c:502
static int draw_envelope_user_hdrs(struct MuttWindow *win, struct EnvelopeWindowData *wdata, int row)
Write user-defined headers to the compose window.
Definition: window.c:652
static int draw_crypt_lines(struct MuttWindow *win, struct EnvelopeWindowData *wdata, int row)
Update the encryption info in the compose window.
Definition: window.c:389
void mutt_window_clear(struct MuttWindow *win)
Clear a Window.
Definition: mutt_window.c:695
struct ListHead chain
Mixmaster chain.
Definition: email.h:90
struct Buffer * fcc
Where the outgoing Email will be saved.
Definition: wdata.h:42
char * followup_to
List of 'followup-to' fields.
Definition: envelope.h:81
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:64
char * x_comment_to
List of 'X-comment-to' fields.
Definition: envelope.h:82
char * newsgroups
List of newsgroups.
Definition: envelope.h:79
char * subject
Email's subject.
Definition: envelope.h:70
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ env_window_new()

struct MuttWindow * env_window_new ( struct Email e,
struct Buffer fcc,
struct ConfigSubset sub 
)

Create the Envelope Window.

Parameters
eEmail
fccBuffer to save FCC
subConfigSubset
Return values
ptrNew Window

Definition at line 972 of file window.c.

973{
975
978 HDR_ATTACH_TITLE - 1);
979
985
986 struct EnvelopeWindowData *wdata = env_wdata_new();
987 wdata->fcc = fcc;
988 wdata->email = e;
989 wdata->sub = sub;
990 wdata->is_news = OptNewsSend;
991
992 win_env->wdata = wdata;
993 win_env->wdata_free = env_wdata_free;
994 win_env->recalc = env_recalc;
995 win_env->repaint = env_repaint;
996
997 return win_env;
998}
struct EnvelopeWindowData * env_wdata_new(void)
Create new Envelope Data.
Definition: wdata.c:55
static void init_header_padding(void)
Calculate how much padding the compose table will need.
Definition: window.c:181
static int env_email_observer(struct NotifyCallback *nc)
Notification that the Email has changed - Implements observer_t -.
Definition: window.c:870
static int env_color_observer(struct NotifyCallback *nc)
Notification that a Color has changed - Implements observer_t -.
Definition: window.c:784
static int env_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: window.c:933
static int env_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: window.c:820
static int env_header_observer(struct NotifyCallback *nc)
Notification that a User Header has changed - Implements observer_t -.
Definition: window.c:894
static int env_recalc(struct MuttWindow *win)
Recalculate the Window data - Implements MuttWindow::recalc() -.
Definition: window.c:751
static int env_repaint(struct MuttWindow *win)
Repaint the Window - Implements MuttWindow::repaint() -.
Definition: window.c:772
void env_wdata_free(struct MuttWindow *win, void **ptr)
Free the Envelope Data - Implements MuttWindow::wdata_free() -.
Definition: wdata.c:39
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 MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:181
@ WT_CUSTOM
Window with a custom drawing function.
Definition: mutt_window.h:95
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition: mutt_window.h:38
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:52
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition: mutt_window.h:47
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:55
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition: notify_type.h:47
@ NT_ALL
Register for all notifications.
Definition: notify_type.h:35
bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:51
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition: email.h:71
Data to fill the Envelope Window.
Definition: wdata.h:39
int(* repaint)(struct MuttWindow *win)
Definition: mutt_window.h:182
void * wdata
Private data.
Definition: mutt_window.h:145
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:171
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:160
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:

Variable Documentation

◆ HeaderPadding

int HeaderPadding[HDR_ATTACH_TITLE] = { 0 }

Definition at line 86 of file window.c.

◆ MaxHeaderWidth

int MaxHeaderWidth = 0

Definition at line 87 of file window.c.

◆ Prompts

const char* const Prompts[]

Definition at line 89 of file window.c.

◆ AutocryptRecUiFlags

const char* const AutocryptRecUiFlags[]
static
Initial value:
= {
N_("Off"),
N_("No"),
N_("Discouraged"),
N_("Available"),
N_("Yes"),
}
#define N_(a)
Definition: message.h:32

Definition at line 132 of file window.c.