NeoMutt  2025-12-11-177-g48e272
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
preview.c File Reference

Compose message preview. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include "private.h"
#include "mutt/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "color/lib.h"
#include "key/lib.h"
+ Include dependency graph for preview.c:

Go to the source code of this file.

Data Structures

struct  PreviewWindowData
 Data to fill the Preview Window. More...
 
struct  PreviewFunction
 A message preview function. More...
 

Typedefs

typedef int(* preview_function_t) (struct PreviewWindowData *wdata, const struct KeyEvent *event)
 

Functions

static void preview_wdata_free (struct MuttWindow *win, void **ptr)
 Free the Preview Data - Implements MuttWindow::wdata_free() -.
 
static struct PreviewWindowDatapreview_wdata_new (void)
 Create new Preview Data.
 
static void draw_preview (struct MuttWindow *win, struct PreviewWindowData *wdata)
 Write the message preview to the compose window.
 
static int preview_color_observer (struct NotifyCallback *nc)
 Notification that a Color has changed - Implements observer_t -.
 
static int preview_email_observer (struct NotifyCallback *nc)
 Notification that the Email has changed - Implements observer_t -.
 
static int preview_window_observer (struct NotifyCallback *nc)
 Notification that a Window has changed - Implements observer_t -.
 
static int preview_repaint (struct MuttWindow *win)
 Repaint the Window - Implements MuttWindow::repaint() -.
 
static int preview_recalc (struct MuttWindow *win)
 Recalculate the Window data - Implements MuttWindow::recalc() -.
 
struct MuttWindowpreview_window_new (struct Email *e, struct MuttWindow *bar)
 Create the preview window.
 
static int preview_page_up (struct PreviewWindowData *wdata, const struct KeyEvent *event)
 Show the previous page of the message - Implements preview_function_t -.
 
static int preview_page_down (struct PreviewWindowData *wdata, const struct KeyEvent *event)
 Show the previous page of the message - Implements preview_function_t -.
 
int preview_function_dispatcher (struct MuttWindow *win, const struct KeyEvent *event)
 Perform a preview function - Implements function_dispatcher_t -.
 

Variables

const long MAX_PREVIEW_BODY_SIZE = 1024 * 1024 * 5
 
static const struct PreviewFunction PreviewFunctions []
 All the functions that the preview window supports.
 

Detailed Description

Compose message preview.

Authors
  • Dennis Schön

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

Typedef Documentation

◆ preview_function_t

typedef int(* preview_function_t) (struct PreviewWindowData *wdata, const struct KeyEvent *event)

Definition at line 99 of file preview.c.

Function Documentation

◆ preview_wdata_new()

static struct PreviewWindowData * preview_wdata_new ( void )
static

Create new Preview Data.

Return values
ptrNew Preview Data

Definition at line 126 of file preview.c.

127{
128 struct PreviewWindowData *wdata = mutt_mem_calloc(1, sizeof(struct PreviewWindowData));
129
130 return wdata;
131}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition memory.c:76
Data to fill the Preview Window.
Definition preview.c:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_preview()

static void draw_preview ( struct MuttWindow * win,
struct PreviewWindowData * wdata )
static

Write the message preview to the compose window.

Parameters
winWindow to draw on
wdataPreview Window data

Definition at line 138 of file preview.c.

139{
140 struct Email *e = wdata->email;
141
142 // Reset preview window and status bar.
144 sbar_set_title(wdata->bar, _("-- Preview"));
145
146 // Check for valid content type and disposition
147 if ((e->body->disposition != DISP_INLINE) || (e->body->type != TYPE_TEXT))
148 {
149 mutt_error(_("Only inline attachments with content-type text/* can be previewed"));
150 return;
151 }
152
153 // Ensure file isn't to too large.
154 long file_size = mutt_file_get_size(e->body->filename);
155 if (file_size > MAX_PREVIEW_BODY_SIZE)
156 {
157 mutt_error(_("Email too large to preview"));
158 return;
159 }
160
161 FILE *fp = mutt_file_fopen(e->body->filename, "r");
162 if (!fp)
163 {
164 mutt_perror("%s", e->body->filename);
165 return;
166 }
167
168 wdata->more_content = false;
169
170 int content_lines = 0; // number of (wrapped) content lines
171 int row = 0; // window row to print
172 char *line = NULL;
173 size_t line_len = 0;
174 while ((line = mutt_file_read_line(line, &line_len, fp, NULL, MUTT_RL_NO_FLAGS)))
175 {
176 size_t pos = 0;
177 bool text_left = true;
178 while (text_left)
179 {
180 /* Text wrapping loop
181 *
182 * Note: We need to do the text wrapping also for text outside the visible
183 * area to ensure the scrolling works correctly.
184 */
185
186 content_lines++;
187
188 line = mutt_str_expand_tabs(line, &line_len, 8);
189
190 // Check how much of the string fits into the window width.
191 size_t width = 0;
192 size_t bytes = mutt_wstr_trunc(&line[pos], line_len - pos, win->state.cols, &width);
193
194 // If it doesn't fill the full width we're done wrapping.
195 if ((win->state.cols - width) > 0)
196 text_left = false;
197
198 // Only move the cursor and print if this line is currently visible.
199 if ((content_lines >= wdata->scroll_offset) && (row < win->state.rows))
200 {
201 int rc = mutt_window_move(win, row, 0);
202 if (rc == ERR)
203 mutt_warning(_("Failed to move cursor!"));
204
205 mutt_paddstr(win, win->state.cols, &line[pos]);
206
207 row++;
208 }
209
210 // Advance position in string.
211 pos += bytes;
212 }
213 }
214
215 FREE(&line);
216 mutt_file_fclose(&fp);
217
218 // Show the scroll percentage in the status bar
219 if ((content_lines != 0) && (content_lines > win->state.rows))
220 {
221 char title[256] = { 0 };
222 double percent = 100.0;
223 if ((wdata->scroll_offset + row) < content_lines)
224 percent = 100.0 / content_lines * (wdata->scroll_offset + row);
225
226 // TODO: having the percentage right-aligned would be nice
227 snprintf(title, sizeof(title), _("-- Preview (%.0f%%)"), percent);
228 sbar_set_title(wdata->bar, title);
229
230 if (content_lines > (wdata->scroll_offset + row))
231 wdata->more_content = true;
232 }
233}
size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
Work out how to truncate a widechar string.
Definition curs_lib.c:384
void mutt_paddstr(struct MuttWindow *win, int n, const char *s)
Display a string on screen, padded if necessary.
Definition curs_lib.c:342
char * mutt_str_expand_tabs(char *str, size_t *len, int tabwidth)
Convert tabs to spaces in a string.
Definition curs_lib.c:591
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition file.c:686
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition file.c:1413
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition file.h:40
#define mutt_warning(...)
Definition logging2.h:92
#define mutt_error(...)
Definition logging2.h:94
#define mutt_perror(...)
Definition logging2.h:95
#define FREE(x)
Definition memory.h:63
@ TYPE_TEXT
Type: 'text/*'.
Definition mime.h:38
@ DISP_INLINE
Content is inline.
Definition mime.h:62
#define _(a)
Definition message.h:28
void mutt_window_clear(struct MuttWindow *win)
Clear a Window.
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
const long MAX_PREVIEW_BODY_SIZE
Definition preview.c:72
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition sbar.c:227
unsigned int disposition
content-disposition, ContentDisposition
Definition body.h:42
unsigned int type
content-type primary type, ContentType
Definition body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
The envelope/body of an email.
Definition email.h:39
struct Body * body
List of MIME parts.
Definition email.h:69
struct WindowState state
Current state of the Window.
struct MuttWindow * bar
Status bar above the preview window.
Definition preview.c:82
int scroll_offset
Scroll offset.
Definition preview.c:80
struct Email * email
Email being composed.
Definition preview.c:79
bool more_content
Is there more content to scroll down to?
Definition preview.c:83
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition mutt_window.h:61
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition mutt_window.h:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ preview_window_new()

struct MuttWindow * preview_window_new ( struct Email * e,
struct MuttWindow * bar )

Create the preview window.

Parameters
eEmail
barPreview Bar

Definition at line 346 of file preview.c.

347{
351
355
356 struct PreviewWindowData *wdata = preview_wdata_new();
357 wdata->email = e;
358 wdata->scroll_offset = 0;
359 wdata->win = win;
360 wdata->bar = bar;
361
362 win->wdata = wdata;
366
367 return win;
368}
void mutt_color_observer_add(observer_t callback, void *global_data)
Add an observer.
Definition notify.c:61
static int preview_email_observer(struct NotifyCallback *nc)
Notification that the Email has changed - Implements observer_t -.
Definition preview.c:269
static int preview_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition preview.c:286
static int preview_color_observer(struct NotifyCallback *nc)
Notification that a Color has changed - Implements observer_t -.
Definition preview.c:238
static int preview_recalc(struct MuttWindow *win)
Recalculate the Window data - Implements MuttWindow::recalc() -.
Definition preview.c:331
static int preview_repaint(struct MuttWindow *win)
Repaint the Window - Implements MuttWindow::repaint() -.
Definition preview.c:319
static void preview_wdata_free(struct MuttWindow *win, void **ptr)
Free the Preview Data - Implements MuttWindow::wdata_free() -.
Definition preview.c:114
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:191
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
@ 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:39
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition mutt_window.h:53
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition mutt_window.h:49
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition notify_type.h:57
@ NT_ALL
Register for all notifications.
Definition notify_type.h:35
static struct PreviewWindowData * preview_wdata_new(void)
Create new Preview Data.
Definition preview.c:126
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition email.h:73
int(* repaint)(struct MuttWindow *win)
void * wdata
Private data.
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
int(* recalc)(struct MuttWindow *win)
void(* wdata_free)(struct MuttWindow *win, void **ptr)
struct MuttWindow * win
Window holding the message preview.
Definition preview.c:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ MAX_PREVIEW_BODY_SIZE

const long MAX_PREVIEW_BODY_SIZE = 1024 * 1024 * 5

Definition at line 72 of file preview.c.

◆ PreviewFunctions

const struct PreviewFunction PreviewFunctions[]
static
Initial value:
= {
{ OP_PREVIEW_PAGE_DOWN, preview_page_down },
{ OP_PREVIEW_PAGE_UP, preview_page_up },
{ 0, NULL },
}
static int preview_page_down(struct PreviewWindowData *wdata, const struct KeyEvent *event)
Show the previous page of the message - Implements preview_function_t -.
Definition preview.c:387
static int preview_page_up(struct PreviewWindowData *wdata, const struct KeyEvent *event)
Show the previous page of the message - Implements preview_function_t -.
Definition preview.c:373

All the functions that the preview window supports.

Definition at line 401 of file preview.c.

401 {
402 // clang-format off
403 { OP_PREVIEW_PAGE_DOWN, preview_page_down },
404 { OP_PREVIEW_PAGE_UP, preview_page_up },
405 { 0, NULL },
406 // clang-format on
407};