NeoMutt  2024-04-16-36-g75b6fb
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
win_chain.c
Go to the documentation of this file.
1
46#include "config.h"
47#include <stddef.h>
48#include <stdbool.h>
49#include <stdio.h>
50#include <string.h>
51#include "mutt/lib.h"
52#include "gui/lib.h"
53#include "win_chain.h"
54#include "color/lib.h"
55#include "chain_data.h"
56#include "remailer.h"
57
62static void cbar_update(struct ChainData *cd)
63{
64 char buf[1024] = { 0 };
65 snprintf(buf, sizeof(buf), _("-- Remailer chain [Length: %d]"), cd->chain_len);
66 sbar_set_title(cd->win_cbar, buf);
67}
68
77static int chain_add(struct ChainData *cd, const char *s, struct RemailerArray *ra)
78{
79 if (cd->chain_len >= MAX_MIXES)
80 return -1;
81
82 if (mutt_str_equal(s, "0") || mutt_istr_equal(s, "<random>"))
83 {
84 cd->chain[cd->chain_len++] = 0;
85 return 0;
86 }
87
88 struct Remailer **r = NULL;
89 ARRAY_FOREACH(r, ra)
90 {
91 if (mutt_istr_equal(s, (*r)->shortname))
92 {
93 cd->chain[cd->chain_len++] = ARRAY_FOREACH_IDX;
94 return 0;
95 }
96 }
97
98 /* replace unknown remailers by <random> */
99 cd->chain[cd->chain_len++] = 0;
100 return 0;
101}
102
106static int win_chain_recalc(struct MuttWindow *win)
107{
108 const int wrap_indent = 2;
109
110 if (!win || !win->wdata)
111 return 0;
112
113 struct ChainData *cd = win->wdata;
114 cbar_update(cd);
115
116 win->actions |= WA_REPAINT;
117 if (cd->chain_len == 0)
118 return 0;
119
120 short col = 0, row = 0;
121 for (int i = 0; i < cd->chain_len; i++)
122 {
123 short old_col = col;
124 int index = cd->chain[i];
125 struct Remailer **rp = ARRAY_GET(cd->ra, index);
126 col += strlen((*rp)->shortname) + 2;
127
128 if (col >= win->state.cols)
129 {
130 old_col = wrap_indent;
131 col = wrap_indent;
132 row++;
133 }
134
135 cd->coords[i].col = old_col;
136 cd->coords[i].row = row;
137 }
138
139 return 0;
140}
141
145static int win_chain_repaint(struct MuttWindow *win)
146{
147 for (int i = 0; i < win->state.rows; i++)
148 {
149 mutt_window_move(win, 0, i);
151 }
152
153 struct ChainData *cd = win->wdata;
154
155 if (cd->chain_len == 0)
156 return 0;
157
158 for (int i = 0; i < cd->chain_len; i++)
159 {
160 if (cd->coords[i].row < win->state.rows)
161 {
162 if (i == cd->sel)
164 else
166
167 int index = cd->chain[i];
168 struct Remailer **rp = ARRAY_GET(cd->ra, index);
169 mutt_window_mvaddstr(win, cd->coords[i].col, cd->coords[i].row, (*rp)->shortname);
171
172 if ((i + 1) < cd->chain_len)
173 mutt_window_addstr(win, ", ");
174 }
175 }
176 return 0;
177}
178
184struct MuttWindow *win_chain_new(struct MuttWindow *win_cbar)
185{
188
189 struct ChainData *cd = chain_data_new();
190 cd->win_cbar = win_cbar;
191
194 win->wdata = cd;
196 win->actions |= WA_RECALC;
197
198 return win;
199}
200
207void win_chain_init(struct MuttWindow *win, struct ListHead *chain, struct RemailerArray *ra)
208{
209 if (!win || !win->wdata)
210 return;
211
212 struct ChainData *cd = win->wdata;
213 cd->ra = ra;
214 cd->sel = 0;
215
216 struct ListNode *p = NULL;
217 STAILQ_FOREACH(p, chain, entries)
218 {
219 chain_add(cd, p->data, cd->ra);
220 }
221 if (cd->chain_len > 1)
222 cd->sel = cd->chain_len - 1;
223 win->actions |= WA_RECALC;
224}
225
233int win_chain_extract(struct MuttWindow *win, struct ListHead *chain)
234{
235 if (!win || !win->wdata)
236 return -1;
237
238 struct ChainData *cd = win->wdata;
239
240 if (cd->chain_len)
241 {
242 char *t = NULL;
243 for (int i = 0; i < cd->chain_len; i++)
244 {
245 const int j = cd->chain[i];
246 if (j != 0)
247 {
248 struct Remailer **rp = ARRAY_GET(cd->ra, j);
249 t = (*rp)->shortname;
250 }
251 else
252 {
253 t = "*";
254 }
255
257 }
258 }
259 return cd->chain_len;
260}
261
268{
269 if (!win || !win->wdata)
270 return 0;
271
272 struct ChainData *cd = win->wdata;
273
274 return cd->chain_len;
275}
276
282bool win_chain_next(struct MuttWindow *win)
283{
284 if (!win || !win->wdata)
285 return false;
286
287 struct ChainData *cd = win->wdata;
288
289 if (cd->chain_len && (cd->sel < (cd->chain_len - 1)))
290 {
291 cd->sel++;
292 }
293 else
294 {
295 mutt_error(_("You already have the last chain element selected"));
296 return false;
297 }
298
299 win->actions |= WA_REPAINT;
300 return true;
301}
302
308bool win_chain_prev(struct MuttWindow *win)
309{
310 if (!win || !win->wdata)
311 return false;
312
313 struct ChainData *cd = win->wdata;
314
315 if (cd->sel)
316 {
317 cd->sel--;
318 }
319 else
320 {
321 mutt_error(_("You already have the first chain element selected"));
322 return false;
323 }
324
325 win->actions |= WA_REPAINT;
326 return true;
327}
328
335bool win_chain_append(struct MuttWindow *win, struct Remailer *r)
336{
337 if (!win || !win->wdata || !r)
338 return false;
339
340 struct ChainData *cd = win->wdata;
341
342 if ((cd->chain_len < MAX_MIXES) && (cd->sel < cd->chain_len))
343 cd->sel++;
344
345 return win_chain_insert(win, r);
346}
347
354bool win_chain_insert(struct MuttWindow *win, struct Remailer *r)
355{
356 if (!win || !win->wdata || !r)
357 return false;
358
359 struct ChainData *cd = win->wdata;
360
361 if (cd->chain_len < MAX_MIXES)
362 {
363 cd->chain_len++;
364 for (int i = cd->chain_len - 1; i > cd->sel; i--)
365 cd->chain[i] = cd->chain[i - 1];
366
367 cd->chain[cd->sel] = r->num;
368 }
369 else
370 {
371 /* L10N The '%d' here hard-coded to 19 */
372 mutt_error(_("Mixmaster chains are limited to %d elements"), MAX_MIXES);
373 return false;
374 }
375
376 win->actions |= WA_RECALC;
377 return true;
378}
379
386{
387 if (!win || !win->wdata)
388 return false;
389
390 struct ChainData *cd = win->wdata;
391
392 if (cd->chain_len)
393 {
394 cd->chain_len--;
395
396 for (int i = cd->sel; i < cd->chain_len; i++)
397 cd->chain[i] = cd->chain[i + 1];
398
399 if ((cd->sel == cd->chain_len) && cd->sel)
400 cd->sel--;
401 }
402 else
403 {
404 mutt_error(_("The remailer chain is already empty"));
405 return false;
406 }
407
408 win->actions |= WA_RECALC;
409 return true;
410}
411
418{
419 if (!win || !win->wdata)
420 return false;
421
422 struct ChainData *cd = win->wdata;
423 if (cd->chain_len == 0)
424 return false;
425
426 int last_index = cd->chain[cd->chain_len - 1];
427 if (last_index != 0)
428 {
429 struct Remailer **rp = ARRAY_GET(cd->ra, last_index);
430 if ((*rp)->caps & MIX_CAP_MIDDLEMAN)
431 {
432 mutt_error(_("Error: %s can't be used as the final remailer of a chain"),
433 (*rp)->shortname);
434 return false;
435 }
436 }
437
438 return true;
439}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:212
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:109
struct ChainData * chain_data_new(void)
Create new Chain data.
Definition: chain_data.c:37
Mixmaster Chain Data.
#define MAX_MIXES
Mixmaster's maximum chain length. Don't change this.
Definition: chain_data.h:29
Color and attribute parsing.
@ MT_COLOR_INDICATOR
Selected item in list.
Definition: color.h:54
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:59
#define mutt_error(...)
Definition: logging2.h:92
static int win_chain_recalc(struct MuttWindow *win)
Recalculate the Chain list - Implements MuttWindow::recalc() -.
Definition: win_chain.c:106
static int win_chain_repaint(struct MuttWindow *win)
Repaint the Chain list - Implements MuttWindow::repaint() -.
Definition: win_chain.c:145
void chain_data_free(struct MuttWindow *win, void **ptr)
Free the Chain data - Implements MuttWindow::wdata_free() -.
Definition: chain_data.c:45
Convenience wrapper for the gui headers.
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:666
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:654
const struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:79
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:182
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:297
int mutt_window_mvaddstr(struct MuttWindow *win, int col, int row, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:311
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:416
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
#define WA_RECALC
Recalculate the contents of the Window.
Definition: mutt_window.h:110
@ 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 WA_REPAINT
Redraw the contents of the Window.
Definition: mutt_window.h:111
#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
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
Mixmaster Remailer.
#define MIX_CAP_MIDDLEMAN
Must be a middle-man (not at the end of a chain)
Definition: remailer.h:32
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:227
An ordered set of Remailer hosts.
Definition: chain_data.h:46
int chain_len
Length of chain.
Definition: chain_data.h:48
struct RemailerArray * ra
Array of all Remailer hosts.
Definition: chain_data.h:51
struct MuttWindow * win_cbar
Chain Bar (status window)
Definition: chain_data.h:52
int chain[MAX_MIXES]
Indexes of chain hosts.
Definition: chain_data.h:49
int sel
Current selection.
Definition: chain_data.h:47
struct Coord coords[MAX_MIXES]
Screen coordinates of each entry.
Definition: chain_data.h:50
short col
Column.
Definition: chain_data.h:37
short row
Row.
Definition: chain_data.h:36
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
int(* repaint)(struct MuttWindow *win)
Definition: mutt_window.h:187
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:173
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:159
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:132
A Mixmaster remailer.
Definition: remailer.h:40
int num
Index number.
Definition: remailer.h:41
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:61
bool win_chain_prev(struct MuttWindow *win)
Select the previous entry in the Chain list.
Definition: win_chain.c:308
static void cbar_update(struct ChainData *cd)
Update the Chain bar (status bar)
Definition: win_chain.c:62
int win_chain_extract(struct MuttWindow *win, struct ListHead *chain)
Extract the Chain list data.
Definition: win_chain.c:233
struct MuttWindow * win_chain_new(struct MuttWindow *win_cbar)
Create a new Chain list Window.
Definition: win_chain.c:184
bool win_chain_insert(struct MuttWindow *win, struct Remailer *r)
Add an item to the Chain, before the current item.
Definition: win_chain.c:354
bool win_chain_delete(struct MuttWindow *win)
Delete the current item from the Chain.
Definition: win_chain.c:385
bool win_chain_next(struct MuttWindow *win)
Select the next entry in the Chain list.
Definition: win_chain.c:282
void win_chain_init(struct MuttWindow *win, struct ListHead *chain, struct RemailerArray *ra)
Initialise the Chain list Window.
Definition: win_chain.c:207
bool win_chain_validate(struct MuttWindow *win)
Validate the Chain.
Definition: win_chain.c:417
static int chain_add(struct ChainData *cd, const char *s, struct RemailerArray *ra)
Add a host to the chain.
Definition: win_chain.c:77
bool win_chain_append(struct MuttWindow *win, struct Remailer *r)
Add an item to the Chain, after the current item.
Definition: win_chain.c:335
int win_chain_get_length(struct MuttWindow *win)
Get the number of Remailers in the Chain.
Definition: win_chain.c:267
Mixmaster Chain Window.