1 /**
2  * @file
3  * GUI display a file/email/help in a viewport with paging
4  *
5  * @authors
6  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /**
24  * @page lib_pager Pager
25  *
26  * Display contents of an email or help
27  *
28  * | File                 | Description                 |
29  * | :------------------- | :-------------------------- |
30  * | pager/config.c       | @subpage pager_config       |
31  * | pager/display.c      | @subpage pager_display      |
32  * | pager/dlg_pager.c    | @subpage pager_dialog       |
33  * | pager/do_pager.c     | @subpage pager_dopager      |
34  * | pager/functions.c    | @subpage pager_functions    |
35  * | pager/message.c      | @subpage pager_message      |
36  * | pager/pager.c        | @subpage pager_pager        |
37  * | pager/pbar.c         | @subpage pager_pbar         |
38  * | pager/ppanel.c       | @subpage pager_ppanel       |
39  * | pager/private_data.c | @subpage pager_private_data |
40  */
41 
42 #ifndef MUTT_PAGER_LIB_H
43 #define MUTT_PAGER_LIB_H
44 
45 #include "config.h"
46 #include <stdbool.h>
47 #include <stdint.h>
48 #include <stdio.h>
49 #include "menu/lib.h"
50 
51 struct Buffer;
52 struct Email;
53 struct IndexSharedData;
54 struct Mailbox;
55 struct MuttWindow;
56 struct PagerPrivateData;
57 
58 typedef uint16_t PagerFlags;              ///< Flags for mutt_pager(), e.g. #MUTT_SHOWFLAT
59 #define MUTT_PAGER_NO_FLAGS         0     ///< No flags are set
60 #define MUTT_SHOWFLAT         (1 << 0)    ///< Show characters (used for displaying help)
61 #define MUTT_SHOWCOLOR        (1 << 1)    ///< Show characters in color otherwise don't show characters
62 #define MUTT_HIDE             (1 << 2)    ///< Don't show quoted text
63 #define MUTT_SEARCH           (1 << 3)    ///< Resolve search patterns
64 #define MUTT_TYPES            (1 << 4)    ///< Compute line's type
65 #define MUTT_SHOW             (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)
66 
67 /* exported flags for mutt_(do_)?pager */
68 #define MUTT_PAGER_NSKIP      (1 << 5)    ///< Preserve whitespace with smartwrap
69 #define MUTT_PAGER_MARKER     (1 << 6)    ///< Use markers if option is set
70 #define MUTT_PAGER_RETWINCH   (1 << 7)    ///< Need reformatting on SIGWINCH
71 #define MUTT_PAGER_ATTACHMENT (1 << 8)    ///< Attachments may exist
72 #define MUTT_PAGER_NOWRAP     (1 << 9)    ///< Format for term width, ignore $wrap
73 #define MUTT_PAGER_LOGS       (1 << 10)   ///< Logview mode
74 #define MUTT_PAGER_BOTTOM     (1 << 11)   ///< Start at the bottom
75 #define MUTT_PAGER_MESSAGE    (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)
76 
77 #define MUTT_DISPLAYFLAGS (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)
78 
79 // Pager mode.
80 // There are 10 code paths that lead to mutt_pager() invocation:
81 //
82 // 1. mutt_index_menu -> mutt_display_message -> mutt_pager
83 //
84 //    This path always results in mailbox and email set,
85 //    the rest is unset - Body, fp.
86 //    This invocation can be identified by IsEmail macro.
87 //    The intent is to display an email message
88 //
89 // 2. mutt_view_attachment -> mutt_do_pager -> mutt_pager
90 //
91 //    this path always results in email, body, ctx set
92 //    this invocation can be identified by one of the two macros
93 //    - IsAttach (viewing a regular attachment)
94 //    - IsMsgAttach (viewing nested email)
95 //
96 //    IsMsgAttach has extra->body->email set
97 //    extra->email != extra->body->email
98 //    the former is the message that contains the latter message as attachment
99 //
100 //    NB. extra->email->body->email seems to be always NULL
101 //
102 // 3. The following 8 invocations are similar, because they all call
103 //    mutt_do_page with info = NULL
104 //
105 //    And so it results in mailbox, body, fp set to NULL.
106 //    The intent is to show user some text that is not
107 //    directly related to viewing emails,
108 //    e.g. help, log messages,gpg key selection etc.
109 //
110 //    No macro identifies these invocations
111 //
112 //    mutt_index_menu       -> mutt_do_pager -> mutt_pager
113 //    mutt_help             -> mutt_do_pager -> mutt_pager
114 //    icmd_bind             -> mutt_do_pager -> mutt_pager
115 //    icmd_set              -> mutt_do_pager -> mutt_pager
116 //    icmd_version          -> mutt_do_pager -> mutt_pager
117 //    dlg_select_pgp_key    -> mutt_do_pager -> mutt_pager
118 //    verify_key            -> mutt_do_pager -> mutt_pager
119 //    mutt_invoke_sendmail  -> mutt_do_pager -> mutt_pager
120 //
121 //
122 // - IsAttach(pager) (pager && (pager)->body)
123 // - IsMsgAttach(pager)
124 //   (pager && (pager)->fp && (pager)->body && (pager)->body->email)
125 // - IsEmail(pager) (pager && (pager)->email && !(pager)->body)
126 // See nice infographic here:
127 // https://gist.github.com/flatcap/044ecbd2498c65ea9a85099ef317509a
128 
129 /**
130  * enum PagerMode - Determine the behaviour of the Pager
131  */
132 enum PagerMode
133 {
134   PAGER_MODE_UNKNOWN = 0, ///< A default and invalid mode, should never be used
135 
136   PAGER_MODE_EMAIL,       ///< Pager is invoked via 1st path. The mime part is selected automatically
137   PAGER_MODE_ATTACH,      ///< Pager is invoked via 2nd path. A user-selected attachment (mime part or a nested email) will be shown
138   PAGER_MODE_ATTACH_E,    ///< A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message
139   PAGER_MODE_HELP,        ///< Pager is invoked via 3rd path to show help.
140   PAGER_MODE_OTHER,       ///< Pager is invoked via 3rd path. Non-email content is likely to be shown
141 
142   PAGER_MODE_MAX,         ///< Another invalid mode, should never be used
143 };
144 
145 /**
146  * struct PagerData - Data to be displayed by PagerView
147  */
148 struct PagerData
149 {
150   struct Body      *body;   ///< Current attachment
151   FILE             *fp;     ///< Source stream
152   struct AttachCtx *actx;   ///< Attachment information
153   const char       *fname;  ///< Name of the file to read
154 };
155 
156 /**
157  * struct PagerView - Paged view into some data
158  */
159 struct PagerView
160 {
161   struct PagerData *pdata; ///< Data that pager displays. NOTNULL
162   enum PagerMode mode;     ///< Pager mode
163   PagerFlags flags;        ///< Additional settings to tweak pager's function
164   const char *banner;      ///< Title to display in status bar
165 
166   struct MuttWindow *win_index; ///< Index Window
167   struct MuttWindow *win_pbar;  ///< Pager Bar Window
168   struct MuttWindow *win_pager; ///< Pager Window
169 };
170 
171 typedef uint8_t NotifyPager;         ///< Flags, e.g. #NT_PAGER_DELETE
172 #define NT_PAGER_NO_FLAGS        0   ///< No flags are set
173 #define NT_PAGER_DELETE    (1 << 0)  ///< Pager Private Data is about to be freed
174 #define NT_PAGER_VIEW      (1 << 1)  ///< Pager View has changed
175 
176 extern int braille_row;
177 extern int braille_col;
178 
179 int mutt_pager(struct PagerView *pview);
180 int mutt_do_pager(struct PagerView *pview, struct Email *e);
181 void mutt_buffer_strip_formatting(struct Buffer *dest, const char *src, bool strip_markers);
182 struct MuttWindow *ppanel_new(bool status_on_top, struct IndexSharedData *shared);
183 struct MuttWindow *pager_window_new(struct IndexSharedData *shared, struct PagerPrivateData *priv);
184 int mutt_display_message(struct MuttWindow *win_index, struct MuttWindow *win_pager, struct MuttWindow *win_pbar, struct Mailbox *m, struct Email *e);
185 int external_pager(struct Mailbox *m, struct Email *e, const char *command);
186 void pager_queue_redraw(struct PagerPrivateData *priv, MenuRedrawFlags redraw);
187 
188 void mutt_clear_pager_position(void);
189 
190 #endif /* MUTT_PAGER_LIB_H */
191