NeoMutt  2021-10-29-220-g2b1eec
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

GUI display a file/email/help in a viewport with paging. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "menu/lib.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PagerData
 Data to be displayed by PagerView. More...
 
struct  PagerView
 Paged view into some data. More...
 

Macros

#define MUTT_PAGER_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_SHOWFLAT   (1 << 0)
 Show characters (used for displaying help) More...
 
#define MUTT_SHOWCOLOR   (1 << 1)
 Show characters in color otherwise don't show characters. More...
 
#define MUTT_HIDE   (1 << 2)
 Don't show quoted text. More...
 
#define MUTT_SEARCH   (1 << 3)
 Resolve search patterns. More...
 
#define MUTT_TYPES   (1 << 4)
 Compute line's type. More...
 
#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)
 
#define MUTT_PAGER_NSKIP   (1 << 5)
 Preserve whitespace with smartwrap. More...
 
#define MUTT_PAGER_MARKER   (1 << 6)
 Use markers if option is set. More...
 
#define MUTT_PAGER_RETWINCH   (1 << 7)
 Need reformatting on SIGWINCH. More...
 
#define MUTT_PAGER_ATTACHMENT   (1 << 8)
 Attachments may exist. More...
 
#define MUTT_PAGER_NOWRAP   (1 << 9)
 Format for term width, ignore $wrap. More...
 
#define MUTT_PAGER_LOGS   (1 << 10)
 Logview mode. More...
 
#define MUTT_PAGER_BOTTOM   (1 << 11)
 Start at the bottom. More...
 
#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)
 
#define MUTT_DISPLAYFLAGS   (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)
 
#define NT_PAGER_NO_FLAGS   0
 No flags are set. More...
 
#define NT_PAGER_DELETE   (1 << 0)
 Pager Private Data is about to be freed. More...
 
#define NT_PAGER_VIEW   (1 << 1)
 Pager View has changed. More...
 

Typedefs

typedef uint16_t PagerFlags
 Flags for mutt_pager(), e.g. MUTT_SHOWFLAT. More...
 
typedef uint8_t NotifyPager
 Flags, e.g. NT_PAGER_DELETE. More...
 

Enumerations

enum  PagerMode {
  PAGER_MODE_UNKNOWN = 0 , PAGER_MODE_EMAIL , PAGER_MODE_ATTACH , PAGER_MODE_ATTACH_E ,
  PAGER_MODE_HELP , PAGER_MODE_OTHER , PAGER_MODE_MAX
}
 Determine the behaviour of the Pager. More...
 

Functions

int mutt_pager (struct PagerView *pview)
 Display an email, attachment, or help, in a window. More...
 
int mutt_do_pager (struct PagerView *pview, struct Email *e)
 Display some page-able text to the user (help or attachment) More...
 
void mutt_buffer_strip_formatting (struct Buffer *dest, const char *src, bool strip_markers)
 Removes ANSI and backspace formatting. More...
 
struct MuttWindowppanel_new (bool status_on_top, struct IndexSharedData *shared)
 Create the Windows for the Pager panel. More...
 
struct MuttWindowpager_window_new (struct IndexSharedData *shared, struct PagerPrivateData *priv)
 Create a new Pager Window (list of Emails) More...
 
int mutt_display_message (struct MuttWindow *win_index, struct MuttWindow *win_pager, struct MuttWindow *win_pbar, struct Mailbox *m, struct Email *e)
 Display a message in the pager. More...
 
int external_pager (struct Mailbox *m, struct Email *e, const char *command)
 Display a message in an external program. More...
 
void pager_queue_redraw (struct PagerPrivateData *priv, MenuRedrawFlags redraw)
 Queue a request for a redraw. More...
 
void mutt_clear_pager_position (void)
 Reset the pager's viewing position. More...
 

Variables

int braille_row
 
int braille_col
 

Detailed Description

GUI display a file/email/help in a viewport with paging.

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 lib.h.

Macro Definition Documentation

◆ MUTT_PAGER_NO_FLAGS

#define MUTT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 59 of file lib.h.

◆ MUTT_SHOWFLAT

#define MUTT_SHOWFLAT   (1 << 0)

Show characters (used for displaying help)

Definition at line 60 of file lib.h.

◆ MUTT_SHOWCOLOR

#define MUTT_SHOWCOLOR   (1 << 1)

Show characters in color otherwise don't show characters.

Definition at line 61 of file lib.h.

◆ MUTT_HIDE

#define MUTT_HIDE   (1 << 2)

Don't show quoted text.

Definition at line 62 of file lib.h.

◆ MUTT_SEARCH

#define MUTT_SEARCH   (1 << 3)

Resolve search patterns.

Definition at line 63 of file lib.h.

◆ MUTT_TYPES

#define MUTT_TYPES   (1 << 4)

Compute line's type.

Definition at line 64 of file lib.h.

◆ MUTT_SHOW

#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)

Definition at line 65 of file lib.h.

◆ MUTT_PAGER_NSKIP

#define MUTT_PAGER_NSKIP   (1 << 5)

Preserve whitespace with smartwrap.

Definition at line 68 of file lib.h.

◆ MUTT_PAGER_MARKER

#define MUTT_PAGER_MARKER   (1 << 6)

Use markers if option is set.

Definition at line 69 of file lib.h.

◆ MUTT_PAGER_RETWINCH

#define MUTT_PAGER_RETWINCH   (1 << 7)

Need reformatting on SIGWINCH.

Definition at line 70 of file lib.h.

◆ MUTT_PAGER_ATTACHMENT

#define MUTT_PAGER_ATTACHMENT   (1 << 8)

Attachments may exist.

Definition at line 71 of file lib.h.

◆ MUTT_PAGER_NOWRAP

#define MUTT_PAGER_NOWRAP   (1 << 9)

Format for term width, ignore $wrap.

Definition at line 72 of file lib.h.

◆ MUTT_PAGER_LOGS

#define MUTT_PAGER_LOGS   (1 << 10)

Logview mode.

Definition at line 73 of file lib.h.

◆ MUTT_PAGER_BOTTOM

#define MUTT_PAGER_BOTTOM   (1 << 11)

Start at the bottom.

Definition at line 74 of file lib.h.

◆ MUTT_PAGER_MESSAGE

#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)

Definition at line 75 of file lib.h.

◆ MUTT_DISPLAYFLAGS

#define MUTT_DISPLAYFLAGS   (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)

Definition at line 77 of file lib.h.

◆ NT_PAGER_NO_FLAGS

#define NT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 172 of file lib.h.

◆ NT_PAGER_DELETE

#define NT_PAGER_DELETE   (1 << 0)

Pager Private Data is about to be freed.

Definition at line 173 of file lib.h.

◆ NT_PAGER_VIEW

#define NT_PAGER_VIEW   (1 << 1)

Pager View has changed.

Definition at line 174 of file lib.h.

Typedef Documentation

◆ PagerFlags

typedef uint16_t PagerFlags

Flags for mutt_pager(), e.g. MUTT_SHOWFLAT.

Definition at line 58 of file lib.h.

◆ NotifyPager

typedef uint8_t NotifyPager

Flags, e.g. NT_PAGER_DELETE.

Definition at line 171 of file lib.h.

Enumeration Type Documentation

◆ PagerMode

enum PagerMode

Determine the behaviour of the Pager.

Enumerator
PAGER_MODE_UNKNOWN 

A default and invalid mode, should never be used.

PAGER_MODE_EMAIL 

Pager is invoked via 1st path. The mime part is selected automatically.

PAGER_MODE_ATTACH 

Pager is invoked via 2nd path. A user-selected attachment (mime part or a nested email) will be shown.

PAGER_MODE_ATTACH_E 

A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message.

PAGER_MODE_HELP 

Pager is invoked via 3rd path to show help.

PAGER_MODE_OTHER 

Pager is invoked via 3rd path. Non-email content is likely to be shown.

PAGER_MODE_MAX 

Another invalid mode, should never be used.

Definition at line 132 of file lib.h.

133 {
134  PAGER_MODE_UNKNOWN = 0,
135 
141 
143 };
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:140
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition: lib.h:139
@ PAGER_MODE_ATTACH
Pager is invoked via 2nd path. A user-selected attachment (mime part or a nested email) will be shown...
Definition: lib.h:137
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition: lib.h:136
@ PAGER_MODE_ATTACH_E
A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message.
Definition: lib.h:138
@ PAGER_MODE_UNKNOWN
A default and invalid mode, should never be used.
Definition: lib.h:134
@ PAGER_MODE_MAX
Another invalid mode, should never be used.
Definition: lib.h:142

Function Documentation

◆ mutt_pager()

int mutt_pager ( struct PagerView pview)

Display an email, attachment, or help, in a window.

Parameters
pviewPager view settings
Return values
0Success
-1Error

This pager is actually not so simple as it once was. But it will be again. Currently it operates in 3 modes:

  • viewing messages. (PAGER_MODE_EMAIL)
  • viewing attachments. (PAGER_MODE_ATTACH)
  • viewing other stuff (e.g. help). (PAGER_MODE_OTHER) These can be distinguished by PagerMode in PagerView. Data is not yet polymorphic and is fused into a single struct (PagerData). Different elements of PagerData are expected to be present depending on the mode:
  • PAGER_MODE_EMAIL expects data->email and not expects data->body
  • PAGER_MODE_ATTACH expects data->email and data->body special sub-case of this mode is viewing attached email message it is recognized by presence of data->fp and data->body->email
  • PAGER_MODE_OTHER does not expect data->email or data->body

Definition at line 466 of file dlg_pager.c.

467 {
468  //===========================================================================
469  // ACT 1 - Ensure sanity of the caller and determine the mode
470  //===========================================================================
471  assert(pview);
472  assert((pview->mode > PAGER_MODE_UNKNOWN) && (pview->mode < PAGER_MODE_MAX));
473  assert(pview->pdata); // view can't exist in a vacuum
474  assert(pview->win_pager);
475  assert(pview->win_pbar);
476 
477  struct MuttWindow *dlg = dialog_find(pview->win_pager);
478  struct IndexSharedData *shared = dlg->wdata;
479 
480  switch (pview->mode)
481  {
482  case PAGER_MODE_EMAIL:
483  // This case was previously identified by IsEmail macro
484  // we expect data to contain email and not contain body
485  // We also expect email to always belong to some mailbox
486  assert(shared->ctx);
487  assert(shared->mailbox);
488  assert(shared->email);
489  assert(!pview->pdata->body);
490  break;
491 
492  case PAGER_MODE_ATTACH:
493  // this case was previously identified by IsAttach and IsMsgAttach
494  // macros, we expect data to contain:
495  // - body (viewing regular attachment)
496  // - fp and body->email in special case of viewing an attached email.
497  assert(pview->pdata->body);
498  if (pview->pdata->fp && pview->pdata->body->email)
499  {
500  // Special case: attachment is a full-blown email message.
501  // Yes, emails can contain other emails.
502  pview->mode = PAGER_MODE_ATTACH_E;
503  }
504  break;
505 
506  case PAGER_MODE_HELP:
507  case PAGER_MODE_OTHER:
508  assert(!shared->ctx);
509  assert(!shared->email);
510  assert(!pview->pdata->body);
511  break;
512 
513  case PAGER_MODE_UNKNOWN:
514  case PAGER_MODE_MAX:
515  default:
516  // Unexpected mode. Catch fire and explode.
517  // This *should* happen if mode is PAGER_MODE_ATTACH_E, since
518  // we do not expect any caller to pass it to us.
519  assert(false);
520  break;
521  }
522 
523  //===========================================================================
524  // ACT 2 - Declare, initialize local variables, read config, etc.
525  //===========================================================================
526 
527  //---------- reading config values needed now--------------------------------
528  const short c_pager_index_lines =
529  cs_subset_number(NeoMutt->sub, "pager_index_lines");
530 
531  //---------- local variables ------------------------------------------------
532  int op = 0;
533  enum MailboxType mailbox_type = shared->mailbox ? shared->mailbox->type : MUTT_UNKNOWN;
534  struct PagerPrivateData *priv = pview->win_pager->parent->wdata;
535  priv->rc = -1;
536  priv->searchctx = 0;
537  priv->first = true;
538  priv->wrapped = false;
539  priv->delay_read_timestamp = 0;
540 
541  {
542  // Wipe any previous state info
543  struct Menu *menu = priv->menu;
544  struct Notify *notify = priv->notify;
545  int rc = priv->rc;
546  memset(priv, 0, sizeof(*priv));
547  priv->rc = rc;
548  priv->menu = menu;
549  priv->notify = notify;
550  priv->win_pbar = pview->win_pbar;
551  }
552 
553  //---------- setup flags ----------------------------------------------------
554  if (!(pview->flags & MUTT_SHOWCOLOR))
555  pview->flags |= MUTT_SHOWFLAT;
556 
557  if ((pview->mode == PAGER_MODE_EMAIL) && !shared->email->read)
558  {
559  shared->ctx->msg_in_pager = shared->email->msgno;
560  priv->win_pbar->actions |= WA_RECALC;
561  const short c_pager_read_delay =
562  cs_subset_number(NeoMutt->sub, "pager_read_delay");
563  if (c_pager_read_delay == 0)
564  {
565  mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true);
566  }
567  else
568  {
569  priv->delay_read_timestamp = mutt_date_epoch_ms() + (1000 * c_pager_read_delay);
570  }
571  }
572  //---------- setup help menu ------------------------------------------------
573  pview->win_pager->help_data = pager_resolve_help_mapping(pview->mode, mailbox_type);
574  pview->win_pager->help_menu = MENU_PAGER;
575 
576  //---------- initialize redraw pdata -----------------------------------------
578  priv->pview = pview;
579  priv->index_size = c_pager_index_lines;
580  priv->indicator = priv->index_size / 3;
581  priv->lines_max = LINES; // number of lines on screen, from curses
582  priv->lines = mutt_mem_calloc(priv->lines_max, sizeof(struct Line));
583  priv->fp = fopen(pview->pdata->fname, "r");
584  priv->has_types =
585  ((pview->mode == PAGER_MODE_EMAIL) || (pview->flags & MUTT_SHOWCOLOR)) ?
586  MUTT_TYPES :
587  0; // main message or rfc822 attachment
588 
589  for (size_t i = 0; i < priv->lines_max; i++)
590  {
591  priv->lines[i].cid = -1;
592  priv->lines[i].search_arr_size = -1;
593  priv->lines[i].syntax = mutt_mem_malloc(sizeof(struct TextSyntax));
594  (priv->lines[i].syntax)[0].first = -1;
595  (priv->lines[i].syntax)[0].last = -1;
596  }
597 
598  // ---------- try to open the pdata file -------------------------------------
599  if (!priv->fp)
600  {
601  mutt_perror(pview->pdata->fname);
602  return -1;
603  }
604 
605  if (stat(pview->pdata->fname, &priv->st) != 0)
606  {
607  mutt_perror(pview->pdata->fname);
608  mutt_file_fclose(&priv->fp);
609  return -1;
610  }
611  unlink(pview->pdata->fname);
612 
613  //---------- restore global state if needed ---------------------------------
614  while ((pview->mode == PAGER_MODE_EMAIL) && (OldEmail == shared->email) && // are we "resuming" to the same Email?
615  (TopLine != priv->top_line) && // is saved offset different?
616  (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1)))
617  {
619  pager_custom_redraw(priv);
620  // trick user, as if nothing happened
621  // scroll down to previously saved offset
622  priv->top_line = ((TopLine - priv->top_line) > priv->win_height) ?
623  priv->top_line + priv->win_height :
624  TopLine;
625  }
626 
627  TopLine = 0;
628  OldEmail = NULL;
629 
630  //---------- show windows, set focus and visibility --------------------------
631  squash_index_panel(dlg, shared, priv, c_pager_index_lines);
632  window_set_focus(pview->win_pager);
633 
634  //---------- jump to the bottom if requested ------------------------------
635  if (pview->flags & MUTT_PAGER_BOTTOM)
636  {
637  jump_to_bottom(priv, pview);
638  }
639 
640  //-------------------------------------------------------------------------
641  // ACT 3: Read user input and decide what to do with it
642  // ...but also do a whole lot of other things.
643  //-------------------------------------------------------------------------
644  while (op != -1)
645  {
647  {
648  mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true);
649  }
651 
653  pager_custom_redraw(priv);
654  notify_send(priv->notify, NT_PAGER, NT_PAGER_VIEW, priv);
655  window_redraw(NULL);
656 
657  const bool c_braille_friendly =
658  cs_subset_bool(NeoMutt->sub, "braille_friendly");
659  if (c_braille_friendly)
660  {
661  if (braille_row != -1)
662  {
664  braille_row = -1;
665  }
666  }
667  else
668  mutt_window_move(priv->pview->win_pbar, priv->pview->win_pager->state.cols - 1, 0);
669 
670  // force redraw of the screen at every iteration of the event loop
671  mutt_refresh();
672 
673  //-------------------------------------------------------------------------
674  // Check if information in the status bar needs an update
675  // This is done because pager is a single-threaded application, which
676  // tries to emulate concurrency.
677  //-------------------------------------------------------------------------
678  bool do_new_mail = false;
679  if (shared->mailbox && !OptAttachMsg)
680  {
681  int oldcount = shared->mailbox->msg_count;
682  /* check for new mail */
683  enum MxStatus check = mx_mbox_check(shared->mailbox);
684  if (check == MX_STATUS_ERROR)
685  {
686  if (!shared->mailbox || mutt_buffer_is_empty(&shared->mailbox->pathbuf))
687  {
688  /* fatal error occurred */
690  break;
691  }
692  }
693  else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
694  (check == MX_STATUS_FLAGS))
695  {
696  /* notify user of newly arrived mail */
697  if (check == MX_STATUS_NEW_MAIL)
698  {
699  for (size_t i = oldcount; i < shared->mailbox->msg_count; i++)
700  {
701  struct Email *e = shared->mailbox->emails[i];
702 
703  if (e && !e->read)
704  {
705  mutt_message(_("New mail in this mailbox"));
706  do_new_mail = true;
707  break;
708  }
709  }
710  }
711 
712  if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
713  {
714  if (priv->menu && shared->mailbox)
715  {
716  /* After the mailbox has been updated, selection might be invalid */
717  int index = menu_get_index(priv->menu);
718  menu_set_index(priv->menu, MIN(index, MAX(shared->mailbox->msg_count - 1, 0)));
719  index = menu_get_index(priv->menu);
720  struct Email *e = mutt_get_virt_email(shared->mailbox, index);
721  if (!e)
722  continue;
723 
724  bool verbose = shared->mailbox->verbose;
725  shared->mailbox->verbose = false;
726  mutt_update_index(priv->menu, shared->ctx, check, oldcount, shared);
727  shared->mailbox->verbose = verbose;
728 
729  priv->menu->max = shared->mailbox->vcount;
730 
731  /* If these header pointers don't match, then our email may have
732  * been deleted. Make the pointer safe, then leave the pager.
733  * This have a unpleasant behaviour to close the pager even the
734  * deleted message is not the opened one, but at least it's safe. */
735  e = mutt_get_virt_email(shared->mailbox, index);
736  if (shared->email != e)
737  {
738  shared->email = e;
739  break;
740  }
741  }
742 
744  OptSearchInvalid = true;
745  }
746  }
747 
748  if (mutt_mailbox_notify(shared->mailbox) || do_new_mail)
749  {
750  const bool c_beep_new = cs_subset_bool(NeoMutt->sub, "beep_new");
751  if (c_beep_new)
752  mutt_beep(true);
753  const char *const c_new_mail_command =
754  cs_subset_string(NeoMutt->sub, "new_mail_command");
755  if (c_new_mail_command)
756  {
757  char cmd[1024];
758  menu_status_line(cmd, sizeof(cmd), shared, priv->menu, sizeof(cmd),
759  NONULL(c_new_mail_command));
760  if (mutt_system(cmd) != 0)
761  mutt_error(_("Error running \"%s\""), cmd);
762  }
763  }
764  }
765  //-------------------------------------------------------------------------
766 
767  if (SigWinch)
768  {
769  SigWinch = false;
771  clearok(stdscr, true); /* force complete redraw */
773 
775  if (pview->flags & MUTT_PAGER_RETWINCH)
776  {
777  /* Store current position. */
778  priv->win_height = -1;
779  for (size_t i = 0; i <= priv->top_line; i++)
780  if (!priv->lines[i].cont_line)
781  priv->win_height++;
782 
783  Resize = mutt_mem_malloc(sizeof(struct Resize));
784 
785  Resize->line = priv->win_height;
787  Resize->search_back = priv->search_back;
788 
789  op = -1;
790  priv->rc = OP_REFORMAT_WINCH;
791  }
792  else
793  {
794  /* note: mutt_resize_screen() -> mutt_window_reflow() sets
795  * MENU_REDRAW_FULL and MENU_REDRAW_FLOW */
796  op = 0;
797  }
798  continue;
799  }
800  //-------------------------------------------------------------------------
801  // Finally, read user's key press
802  //-------------------------------------------------------------------------
803  // km_dokey() reads not only user's key strokes, but also a MacroBuffer
804  // MacroBuffer may contain OP codes of the operations.
805  // MacroBuffer is global
806  // OP codes inserted into the MacroBuffer by various functions.
807  // One of such functions is `mutt_enter_command()`
808  // Some OP codes are not handled by pager, they cause pager to quit returning
809  // OP code to index. Index handles the operation and then restarts pager
810  op = km_dokey(MENU_PAGER);
811 
812  if (op >= 0)
813  {
815  mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", OpStrings[op][0], op);
816  }
818 
819  if (op < 0)
820  {
821  op = 0;
823  continue;
824  }
825 
826  priv->rc = op;
827 
828  if (op == OP_NULL)
829  {
831  continue;
832  }
833 
834  int rc = pager_function_dispatcher(priv->pview->win_pager, op);
835  if (rc == IR_DONE)
836  break;
837  if (rc == IR_UNKNOWN)
838  break;
839  }
840  //-------------------------------------------------------------------------
841  // END OF ACT 3: Read user input loop - while (op != -1)
842  //-------------------------------------------------------------------------
843 
845  {
846  mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true);
847  }
848  mutt_file_fclose(&priv->fp);
849  if (pview->mode == PAGER_MODE_EMAIL)
850  {
851  shared->ctx->msg_in_pager = -1;
852  priv->win_pbar->actions |= WA_RECALC;
853  switch (priv->rc)
854  {
855  case -1:
856  case OP_DISPLAY_HEADERS:
858  break;
859  default:
860  TopLine = priv->top_line;
861  OldEmail = shared->email;
862  break;
863  }
864  }
865 
867 
868  for (size_t i = 0; i < priv->lines_max; i++)
869  {
870  FREE(&(priv->lines[i].syntax));
871  if (priv->search_compiled && priv->lines[i].search)
872  FREE(&(priv->lines[i].search));
873  }
874  if (priv->search_compiled)
875  {
876  regfree(&priv->search_re);
877  priv->search_compiled = false;
878  }
879  FREE(&priv->lines);
880 
881  expand_index_panel(dlg, priv);
882 
883  return (priv->rc != -1) ? priv->rc : 0;
884 }
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:412
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:114
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:104
uint64_t mutt_date_epoch_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:436
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition: dialog.c:83
void mutt_update_index(struct Menu *menu, struct Context *ctx, enum MxStatus check, int oldcount, struct IndexSharedData *shared)
Update the index.
Definition: dlg_index.c:537
static void expand_index_panel(struct MuttWindow *dlg, struct PagerPrivateData *priv)
Restore the Index Panel.
Definition: dlg_pager.c:427
void mutt_clear_pager_position(void)
Reset the pager's viewing position.
Definition: dlg_pager.c:143
static const struct Mapping * pager_resolve_help_mapping(enum PagerMode mode, enum MailboxType type)
Determine help mapping based on pager mode and mailbox type.
Definition: dlg_pager.c:348
int braille_col
Definition: dlg_pager.c:83
static void pager_custom_redraw(struct PagerPrivateData *priv)
Redraw the pager window.
Definition: dlg_pager.c:164
static struct Email * OldEmail
Definition: dlg_pager.c:80
static void squash_index_panel(struct MuttWindow *dlg, struct IndexSharedData *shared, struct PagerPrivateData *priv, int pil)
Shrink or hide the Index Panel.
Definition: dlg_pager.c:402
static bool check_read_delay(uint64_t *timestamp)
Is it time to mark the message read?
Definition: dlg_pager.c:385
void pager_queue_redraw(struct PagerPrivateData *priv, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition: dlg_pager.c:154
int braille_row
Definition: dlg_pager.c:82
static int TopLine
Definition: dlg_pager.c:79
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
#define mutt_perror(...)
Definition: logging.h:88
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_timeout_hook(void)
Execute any timeout hooks.
Definition: hook.c:830
@ IR_DONE
Exit the Index.
Definition: functions.h:37
@ IR_UNKNOWN
Unknown key.
Definition: functions.h:35
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:627
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1132
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
MailboxType
Supported mailbox formats.
Definition: mailbox.h:44
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:47
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:40
#define MIN(a, b)
Definition: memory.h:31
#define MAX(a, b)
Definition: memory.h:30
#define MENU_REDRAW_FULL
Redraw everything.
Definition: lib.h:55
#define MENU_REDRAW_FLOW
Used by pager to reflow text.
Definition: lib.h:57
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition: menu.c:624
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition: menu.c:638
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:240
#define _(a)
Definition: message.h:28
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
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:92
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:63
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
Definition: resize.c:73
@ MUTT_CURSOR_INVISIBLE
Hide the cursor.
Definition: mutt_curses.h:54
@ MUTT_CURSOR_VISIBLE
Display a normal cursor.
Definition: mutt_curses.h:55
SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:72
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there's new mail.
Definition: mutt_mailbox.c:236
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:603
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:292
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:651
#define WA_RECALC
Recalculate the contents of the Window.
Definition: mutt_window.h:110
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition: mutt_window.h:48
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition: mx.c:1125
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
Definition: mxapi.h:76
@ MX_STATUS_ERROR
An error occurred.
Definition: mxapi.h:77
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition: mxapi.h:82
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mxapi.h:81
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mxapi.h:79
@ NT_PAGER
Pager data has changed, NotifyPager, PagerPrivateData.
Definition: notify_type.h:50
const char * OpStrings[][2]
Definition: opcodes.c:34
bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:37
bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:57
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition: functions.c:194
int pager_function_dispatcher(struct MuttWindow *win_pager, int op)
Perform a Pager function.
Definition: functions.c:1967
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: lib.h:70
#define NT_PAGER_VIEW
Pager View has changed.
Definition: lib.h:174
#define MUTT_TYPES
Compute line's type.
Definition: lib.h:64
#define MUTT_SHOWCOLOR
Show characters in color otherwise don't show characters.
Definition: lib.h:61
#define MUTT_PAGER_BOTTOM
Start at the bottom.
Definition: lib.h:74
#define MUTT_SHOWFLAT
Show characters (used for displaying help)
Definition: lib.h:60
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
void qstyle_free_tree(struct QuoteStyle **quote_list)
Free an entire tree of QuoteStyle.
Definition: quoted.c:149
void menu_status_line(char *buf, size_t buflen, struct IndexSharedData *shared, struct Menu *menu, int cols, const char *fmt)
Create the status line.
Definition: status.c:445
#define NONULL(x)
Definition: string2.h:37
struct Email * email
header information for message/rfc822
Definition: body.h:72
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:43
The envelope/body of an email.
Definition: email.h:37
bool read
Email is read.
Definition: email.h:48
int msgno
Number displayed to the user.
Definition: email.h:111
int index
The absolute (unsorted) message number.
Definition: email.h:110
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct Context * ctx
Current Mailbox view.
Definition: shared_data.h:39
struct Email * email
Currently selected Email.
Definition: shared_data.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
A line of text in the pager.
Definition: display.h:71
short search_arr_size
Number of items in search array.
Definition: display.h:80
struct TextSyntax * search
Array of search text in the line.
Definition: display.h:81
bool cont_line
Continuation of a previous line (wrapped by NeoMutt)
Definition: display.h:74
short cid
Default line colour, e.g. MT_COLOR_QUOTED.
Definition: display.h:73
LOFF_T offset
Offset into Email file (PagerPrivateData->fp)
Definition: display.h:72
struct TextSyntax * syntax
Array of coloured text in the line.
Definition: display.h:78
int vcount
The number of virtual messages.
Definition: mailbox.h:102
int msg_count
Total number of messages.
Definition: mailbox.h:91
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:83
bool verbose
Display status messages?
Definition: mailbox.h:118
Definition: lib.h:69
int max
Number of entries in the menu.
Definition: lib.h:71
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:142
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:141
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:135
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:132
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Definition: mutt_window.h:131
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Notification API.
Definition: notify.c:51
const char * fname
Name of the file to read.
Definition: lib.h:153
FILE * fp
Source stream.
Definition: lib.h:151
struct Body * body
Current attachment.
Definition: lib.h:150
Private state data for the Pager.
Definition: private_data.h:41
int rc
Return code from functions.
Definition: private_data.h:77
int cur_line
Current line (last line visible on screen)
Definition: private_data.h:53
bool wrapped
Has the search/next wrapped around?
Definition: private_data.h:80
int lines_max
Capacity of lines array (total entries)
Definition: private_data.h:52
int index_size
Size of the mini-index Window $pager_index_lines
Definition: private_data.h:70
uint64_t delay_read_timestamp
Time that email was first shown.
Definition: private_data.h:81
struct MuttWindow * win_pbar
Pager Bar.
Definition: private_data.h:43
struct Line * lines
Array of text lines in pager.
Definition: private_data.h:50
int has_types
Set to MUTT_TYPES for PAGER_MODE_EMAIL or MUTT_SHOWCOLOR.
Definition: private_data.h:58
struct Notify * notify
Notifications: NotifyPager, PagerPrivateData.
Definition: private_data.h:75
struct Menu * menu
Pager Menu.
Definition: private_data.h:42
int top_line
First visible line on screen.
Definition: private_data.h:57
struct stat st
Stats about Email file.
Definition: private_data.h:47
bool first
First time flag for toggle-new.
Definition: private_data.h:79
bool search_back
Search backwards.
Definition: private_data.h:68
struct QuoteStyle * quote_list
Tree of quoting levels.
Definition: private_data.h:60
struct PagerView * pview
Object to view in the pager.
Definition: private_data.h:44
int searchctx
Space to show around search matches.
Definition: private_data.h:78
int indicator
Preferred position of the indicator line in the mini-index Window.
Definition: private_data.h:71
regex_t search_re
Compiled search string.
Definition: private_data.h:67
int win_height
Number of lines in the Window.
Definition: private_data.h:56
FILE * fp
File containing decrypted/decoded/weeded Email.
Definition: private_data.h:46
bool search_compiled
Search regex is in use.
Definition: private_data.h:66
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:161
enum PagerMode mode
Pager mode.
Definition: lib.h:162
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:163
struct MuttWindow * win_pbar
Pager Bar Window.
Definition: lib.h:167
struct MuttWindow * win_pager
Pager Window.
Definition: lib.h:168
Keep track of screen resizing.
Definition: dlg_pager.c:72
bool search_compiled
Definition: dlg_pager.c:74
bool search_back
Definition: dlg_pager.c:75
int line
Definition: dlg_pager.c:73
Highlighting for a piece of text.
Definition: display.h:50
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_do_pager()

int mutt_do_pager ( struct PagerView pview,
struct Email e 
)

Display some page-able text to the user (help or attachment)

Parameters
pviewPagerView to construct Pager object
eEmail to use
Return values
0Success
-1Error

Definition at line 120 of file do_pager.c.

121 {
122  assert(pview);
123  assert(pview->pdata);
124  assert(pview->pdata->fname);
125  assert((pview->mode == PAGER_MODE_ATTACH) ||
126  (pview->mode == PAGER_MODE_HELP) || (pview->mode == PAGER_MODE_OTHER));
127 
128  struct MuttWindow *dlg =
131 
132  struct IndexSharedData *shared = index_shared_data_new();
133  shared->email = e;
134 
135  notify_set_parent(shared->notify, dlg->notify);
136 
137  dlg->wdata = shared;
139 
140  const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
141  struct MuttWindow *panel_pager = ppanel_new(c_status_on_top, shared);
142  dlg->focus = panel_pager;
143  mutt_window_add_child(dlg, panel_pager);
144 
147  dialog_push(dlg);
148 
149  pview->win_index = NULL;
150  pview->win_pbar = window_find_child(panel_pager, WT_STATUS_BAR);
151  pview->win_pager = window_find_child(panel_pager, WT_CUSTOM);
152 
153  int rc;
154 
155  const char *const c_pager = cs_subset_string(NeoMutt->sub, "pager");
156  if (!c_pager || mutt_str_equal(c_pager, "builtin"))
157  {
158  rc = mutt_pager(pview);
159  }
160  else
161  {
162  struct Buffer *cmd = mutt_buffer_pool_get();
163 
164  mutt_endwin();
165  mutt_buffer_file_expand_fmt_quote(cmd, c_pager, pview->pdata->fname);
166  if (mutt_system(mutt_buffer_string(cmd)) == -1)
167  {
168  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
169  rc = -1;
170  }
171  else
172  rc = 0;
173  mutt_file_unlink(pview->pdata->fname);
175  }
176 
177  dialog_pop();
178  mutt_window_free(&dlg);
179  return rc;
180 }
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:394
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:103
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:137
int mutt_pager(struct PagerView *pview)
Display an email, attachment, or help, in a window.
Definition: dlg_pager.c:466
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
void mutt_buffer_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1463
static int dopager_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: do_pager.c:75
static int dopager_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: do_pager.c:93
void index_shared_data_free(struct MuttWindow *win, void **ptr)
Free Shared Index Data - Implements MuttWindow::wdata_free() -.
Definition: shared_data.c:269
struct IndexSharedData * index_shared_data_new(void)
Create new Index Data.
Definition: shared_data.c:296
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
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:715
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:200
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:438
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:180
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:521
@ WT_CUSTOM
Window with a custom drawing function.
Definition: mutt_window.h:95
@ WT_STATUS_BAR
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
@ WT_DLG_DO_PAGER
Pager Dialog, mutt_do_pager()
Definition: mutt_window.h:84
@ 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
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
struct MuttWindow * ppanel_new(bool status_on_top, struct IndexSharedData *shared)
Create the Windows for the Pager panel.
Definition: ppanel.c:119
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
String manipulation buffer.
Definition: buffer.h:34
struct Notify * notify
Notifications: NotifyIndex, IndexSharedData.
Definition: shared_data.h:44
struct MuttWindow * focus
Focused Window.
Definition: mutt_window.h:140
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:160
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
struct MuttWindow * win_index
Index Window.
Definition: lib.h:166
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_strip_formatting()

void mutt_buffer_strip_formatting ( struct Buffer dest,
const char *  src,
bool  strip_markers 
)

Removes ANSI and backspace formatting.

Parameters
destBuffer for the result
srcString to strip
strip_markersRemove

Removes ANSI and backspace formatting, and optionally markers. This is separated out so that it can be used both by the pager and the autoview handler.

This logic is pulled from the pager fill_buffer() function, for use in stripping reply-quoted autoview output of ansi sequences.

Definition at line 740 of file display.c.

741 {
742  const char *s = src;
743 
744  mutt_buffer_reset(dest);
745 
746  if (!s)
747  return;
748 
749  while (s[0] != '\0')
750  {
751  if ((s[0] == '\010') && (s > src))
752  {
753  if (s[1] == '_') /* underline */
754  s += 2;
755  else if (s[1] && mutt_buffer_len(dest)) /* bold or overstrike */
756  {
757  dest->dptr--;
758  mutt_buffer_addch(dest, s[1]);
759  s += 2;
760  }
761  else /* ^H */
762  mutt_buffer_addch(dest, *s++);
763  }
764  else if ((s[0] == '\033') && (s[1] == '[') && is_ansi(s + 2))
765  {
766  while (*s++ != 'm')
767  ; /* skip ANSI sequence */
768  }
769  else if (strip_markers && (s[0] == '\033') && (s[1] == ']') &&
771  {
772  mutt_debug(LL_DEBUG2, "Seen attachment marker\n");
773  while (*s++ != '\a')
774  ; /* skip pseudo-ANSI sequence */
775  }
776  else
777  mutt_buffer_addch(dest, *s++);
778  }
779 }
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
static int check_protected_header_marker(const char *p)
Check that the unique marker is present.
Definition: display.c:298
static int check_attachment_marker(const char *p)
Check that the unique marker is present.
Definition: display.c:288
static bool is_ansi(const char *str)
Is this an ANSI escape sequence?
Definition: display.c:635
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
char * dptr
Current read/write position.
Definition: buffer.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ppanel_new()

struct MuttWindow* ppanel_new ( bool  status_on_top,
struct IndexSharedData shared 
)

Create the Windows for the Pager panel.

Parameters
status_on_toptrue, if the Pager bar should be on top
sharedShared Index data
Return values
ptrNew Pager Panel

Definition at line 119 of file ppanel.c.

120 {
121  struct MuttWindow *panel_pager =
124  panel_pager->state.visible = false; // The Pager and Pager Bar are initially hidden
125 
126  struct PagerPrivateData *priv = pager_private_data_new();
127  panel_pager->wdata = priv;
128  panel_pager->wdata_free = pager_private_data_free;
129 
130  struct MuttWindow *win_pager = pager_window_new(shared, priv);
131  panel_pager->focus = win_pager;
132 
133  struct MuttWindow *win_pbar = pbar_new(shared, priv);
134  if (status_on_top)
135  {
136  mutt_window_add_child(panel_pager, win_pbar);
137  mutt_window_add_child(panel_pager, win_pager);
138  }
139  else
140  {
141  mutt_window_add_child(panel_pager, win_pager);
142  mutt_window_add_child(panel_pager, win_pbar);
143  }
144 
146  notify_observer_add(panel_pager->notify, NT_WINDOW, ppanel_window_observer, panel_pager);
147 
148  return panel_pager;
149 }
static int ppanel_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: ppanel.c:73
static int ppanel_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: ppanel.c:93
@ WT_PAGER
A panel containing the Pager Window.
Definition: mutt_window.h:100
struct MuttWindow * pager_window_new(struct IndexSharedData *shared, struct PagerPrivateData *priv)
Create a new Pager Window (list of Emails)
Definition: pager.c:239
struct PagerPrivateData * pager_private_data_new(void)
Create new Pager Data.
Definition: private_data.c:57
void pager_private_data_free(struct MuttWindow *win, void **ptr)
Free Pager Data.
Definition: private_data.c:39
struct MuttWindow * pbar_new(struct IndexSharedData *shared, struct PagerPrivateData *priv)
Create the Pager Bar.
Definition: pbar.c:336
bool visible
Window is visible.
Definition: mutt_window.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pager_window_new()

struct MuttWindow* pager_window_new ( struct IndexSharedData shared,
struct PagerPrivateData priv 
)

Create a new Pager Window (list of Emails)

Parameters
sharedShared Index Data
privPrivate Pager Data
Return values
ptrNew Window

Definition at line 239 of file pager.c.

241 {
242  struct MuttWindow *win =
245  win->wdata = priv;
246 
252 
253  return win;
254 }
static int pager_pager_observer(struct NotifyCallback *nc)
Notification that the Pager has changed - Implements observer_t -.
Definition: pager.c:191
static int pager_color_observer(struct NotifyCallback *nc)
Notification that a Color has changed - Implements observer_t -.
Definition: pager.c:122
static int pager_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: pager.c:134
static int pager_index_observer(struct NotifyCallback *nc)
Notification that the Index has changed - Implements observer_t -.
Definition: pager.c:154
static int pager_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: pager.c:203
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:39
@ NT_INDEX
Index data has changed, NotifyIndex, IndexSharedData.
Definition: notify_type.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_display_message()

int mutt_display_message ( struct MuttWindow win_index,
struct MuttWindow win_pager,
struct MuttWindow win_pbar,
struct Mailbox m,
struct Email e 
)

Display a message in the pager.

Parameters
win_indexIndex Window
win_pagerPager Window
win_pbarPager Bar Window
mMailbox
eEmail to display
Return values
0Success
-1Error

Definition at line 410 of file message.c.

412 {
413  struct Message *msg = mx_msg_open(m, e->msgno);
414  if (!msg)
415  return -1;
416 
417  struct Buffer *tempfile = mutt_buffer_pool_get();
418 
420 
421  // win_pager might not be visible and have a size yet, so use win_index
422  int rc = email_to_file(msg, tempfile, m, e, NULL, win_index->state.cols, &cmflags);
423  if (rc < 0)
424  goto cleanup;
425 
426  notify_crypto(e, msg, cmflags);
427 
428  /* Invoke the builtin pager */
429  struct PagerData pdata = { 0 };
430  struct PagerView pview = { &pdata };
431 
432  pdata.fp = msg->fp;
433  pdata.fname = mutt_buffer_string(tempfile);
434 
435  pview.mode = PAGER_MODE_EMAIL;
436  pview.banner = NULL;
437  pview.flags = MUTT_PAGER_MESSAGE | (e->body->nowrap ? MUTT_PAGER_NOWRAP : 0);
438  pview.win_index = win_index;
439  pview.win_pbar = win_pbar;
440  pview.win_pager = win_pager;
441  rc = mutt_pager(&pview);
442 
443 cleanup:
444  mx_msg_close(m, &msg);
445  mutt_buffer_pool_release(&tempfile);
446  return rc;
447 }
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:32
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:39
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1192
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1146
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:72
#define MUTT_PAGER_MESSAGE
Definition: lib.h:75
static int email_to_file(struct Message *msg, struct Buffer *tempfile, struct Mailbox *m, struct Email *e, const char *header, int wrap_len, CopyMessageFlags *cmflags)
Decrypt, decode and weed an Email into a file.
Definition: message.c:178
static void notify_crypto(struct Email *e, struct Message *msg, CopyMessageFlags cmflags)
Notify the user about the crypto status of the Email.
Definition: message.c:372
bool nowrap
Do not wrap the output in the pager.
Definition: body.h:88
struct Body * body
List of MIME parts.
Definition: email.h:67
A local copy of an email.
Definition: mxapi.h:42
FILE * fp
pointer to the message data
Definition: mxapi.h:43
Data to be displayed by PagerView.
Definition: lib.h:149
Paged view into some data.
Definition: lib.h:160
const char * banner
Title to display in status bar.
Definition: lib.h:164
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ external_pager()

int external_pager ( struct Mailbox m,
struct Email e,
const char *  command 
)

Display a message in an external program.

Parameters
mMailbox
eEmail to display
commandExternal command to run
Return values
0Success
-1Error

Definition at line 317 of file message.c.

318 {
319  struct Message *msg = mx_msg_open(m, e->msgno);
320  if (!msg)
321  return -1;
322 
323  char buf[1024] = { 0 };
324  const char *const c_pager_format =
325  cs_subset_string(NeoMutt->sub, "pager_format");
326  const int screen_width = RootWindow->state.cols;
327  mutt_make_string(buf, sizeof(buf), screen_width, NONULL(c_pager_format), m,
329 
330  struct Buffer *tempfile = mutt_buffer_pool_get();
331 
333  int rc = email_to_file(msg, tempfile, m, e, buf, screen_width, &cmflags);
334  if (rc < 0)
335  goto cleanup;
336 
337  mutt_endwin();
338 
339  struct Buffer *cmd = mutt_buffer_pool_get();
340  mutt_buffer_printf(cmd, "%s %s", command, mutt_buffer_string(tempfile));
341  int r = mutt_system(mutt_buffer_string(cmd));
342  if (r == -1)
343  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
344  unlink(mutt_buffer_string(tempfile));
346 
347  if (!OptNoCurses)
348  keypad(stdscr, true);
349  if (r != -1)
350  mutt_set_flag(m, e, MUTT_READ, true);
351  const bool c_prompt_after = cs_subset_bool(NeoMutt->sub, "prompt_after");
352  if ((r != -1) && c_prompt_after)
353  {
354  mutt_unget_event(mutt_any_key_to_continue(_("Command: ")), 0);
355  rc = km_dokey(MENU_PAGER);
356  }
357  else
358  rc = 0;
359 
360 cleanup:
361  mx_msg_close(m, &msg);
362  mutt_buffer_pool_release(&tempfile);
363  return rc;
364 }
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:560
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:427
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1410
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53
static const char * ExtPagerProgress
Definition: message.c:60
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: rootwin.c:103
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pager_queue_redraw()

void pager_queue_redraw ( struct PagerPrivateData priv,
MenuRedrawFlags  redraw 
)

Queue a request for a redraw.

Parameters
privPrivate Pager data
redrawItem to redraw, e.g. MENU_REDRAW_FULL

Definition at line 154 of file dlg_pager.c.

155 {
156  priv->redraw |= redraw;
157  // win_pager->actions |= WA_RECALC;
158 }
MenuRedrawFlags redraw
When to redraw the screen.
Definition: private_data.h:74
+ Here is the caller graph for this function:

◆ mutt_clear_pager_position()

void mutt_clear_pager_position ( void  )

Reset the pager's viewing position.

Definition at line 143 of file dlg_pager.c.

144 {
145  TopLine = 0;
146  OldEmail = NULL;
147 }
+ Here is the caller graph for this function:

Variable Documentation

◆ braille_row

int braille_row
extern

Definition at line 82 of file dlg_pager.c.

◆ braille_col

int braille_col
extern

Definition at line 83 of file dlg_pager.c.