1 /*
2 * Project : tin - a Usenet reader
3 * Module : options_menu.c
4 * Author : Michael Bienia <michael@vorlon.ping.de>
5 * Created : 2004-09-05
6 * Updated : 2020-06-10
7 * Notes : Split from config.c
8 *
9 * Copyright (c) 2004-2021 Michael Bienia <michael@vorlon.ping.de>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * 3. Neither the name of the copyright holder nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40
41 #ifndef TIN_H
42 # include "tin.h"
43 #endif /* !TIN_H */
44 #ifndef TINCFG_H
45 # include "tincfg.h"
46 #endif /* !TINCFG_H */
47 #ifndef TCURSES_H
48 # include "tcurses.h"
49 #endif /* !TCURSES_H */
50
51
52 #define option_lines_per_page (cLINES - INDEX_TOP - 3)
53
54 #define UPDATE_INT_ATTRIBUTES(option) do { \
55 scopes[0].attribute->option = tinrc.option; \
56 changed |= MISC_OPTS; \
57 } while (0)
58
59 #define CAO(A, O) A ## O
60 #define SET_NUM_ATTRIBUTE(option) do { \
61 curr_scope->attribute->option = CAO(tinrc.attrib_, option); \
62 curr_scope->state->option = TRUE; \
63 changed |= MISC_OPTS; \
64 } while (0)
65 #define SET_STRING_ATTRIBUTE(opt) do { \
66 if (!strlen(CAO(tinrc.attrib_, opt))) { \
67 reset_state(option); \
68 redraw_screen(option); \
69 } else { \
70 FreeIfNeeded(curr_scope->attribute->opt); \
71 curr_scope->state->opt = TRUE; \
72 curr_scope->attribute->opt = my_strdup(CAO(tinrc.attrib_, opt)); \
73 } \
74 changed |= MISC_OPTS; \
75 } while (0)
76
77 static enum option_enum first_option_on_screen, last_option_on_screen, last_opt;
78
79 /*
80 * local prototypes
81 */
82 static enum option_enum get_first_opt(void);
83 static enum option_enum move_cursor(enum option_enum cur_option, t_bool down);
84 static enum option_enum next_option(enum option_enum option, t_bool incl_titles);
85 static enum option_enum opt_scroll_down(enum option_enum option);
86 static enum option_enum opt_scroll_up(enum option_enum option);
87 static enum option_enum prev_option(enum option_enum option, t_bool incl_titles);
88 static enum option_enum set_option_num(int num);
89 static int add_new_scope(void);
90 static int find_scope(const char *scope);
91 static int get_option_num(enum option_enum option);
92 static int move_scope(int curr_pos);
93 static t_bool check_state(enum option_enum option);
94 static t_bool delete_scope(int curr_pos);
95 static t_bool option_is_title(enum option_enum option);
96 static t_bool option_on_page(enum option_enum option);
97 static t_bool rename_scope(struct t_scope *scope);
98 static t_bool scope_is_empty(void);
99 static t_function option_left(void);
100 static t_function option_right(void);
101 static t_function scope_left(void);
102 static t_function scope_right(void);
103 static void build_scope_line(int i);
104 static void do_delete_scope(int curr_pos);
105 static void do_move_scope(int from, int to);
106 static void draw_scope_arrow(void);
107 static void free_scopes_and_attributes(void);
108 static void highlight_option(enum option_enum option);
109 static void initialize_attributes(void);
110 static void print_any_option(enum option_enum option);
111 static void redraw_screen(enum option_enum option);
112 static void repaint_option(enum option_enum option);
113 static void reset_state(enum option_enum option);
114 static void scope_page(enum context level);
115 static void set_first_option_on_screen(enum option_enum last_option);
116 static void set_last_opt(void);
117 static void set_last_option_on_screen(enum option_enum first_option);
118 static void show_config_page(void);
119 static void show_scope_page(void);
120 static void unhighlight_option(enum option_enum option);
121 #ifdef USE_CURSES
122 static void do_scroll(int jump);
123 #endif /* USE_CURSES */
124
125 static t_menu scopemenu = { 0, 0, 0, show_scope_page, draw_scope_arrow, build_scope_line };
126 static struct t_scope *curr_scope = NULL;
127
128 /*
129 * returns the row on the screen of an option
130 * note: option should be on this page
131 */
132 int
option_row(enum option_enum option)133 option_row(
134 enum option_enum option)
135 {
136 int i = 0;
137 enum option_enum j = first_option_on_screen;
138
139 while (j < option) {
140 if (option_is_visible(j))
141 i++;
142 j++;
143 }
144
145 return INDEX_TOP + i;
146 }
147
148
149 /*
150 * returns the number of an option
151 */
152 static int
get_option_num(enum option_enum option)153 get_option_num(
154 enum option_enum option)
155 {
156 enum option_enum i;
157 int result = 0;
158
159 for (i = 0; i < option && result < (int) last_opt; i = next_option(i, FALSE))
160 result++;
161
162 return result;
163 }
164
165
166 /*
167 * returns the option with the given number
168 */
169 static enum option_enum
set_option_num(int num)170 set_option_num(
171 int num)
172 {
173 enum option_enum result = 0;
174
175 while (num > 0 && result < last_opt) {
176 result = next_option(result, FALSE);
177 num--;
178 }
179 return result;
180 }
181
182
183 /*
184 * returns TRUE if an option is visible in the menu
185 */
186 t_bool
option_is_visible(enum option_enum option)187 option_is_visible(
188 enum option_enum option)
189 {
190 switch (option) {
191 #ifdef HAVE_COLOR
192 case OPT_COL_BACK:
193 case OPT_COL_FROM:
194 case OPT_COL_HEAD:
195 case OPT_COL_HELP:
196 case OPT_COL_INVERS_BG:
197 case OPT_COL_INVERS_FG:
198 case OPT_COL_MESSAGE:
199 case OPT_COL_MINIHELP:
200 case OPT_COL_NEWSHEADERS:
201 case OPT_COL_NORMAL:
202 case OPT_COL_QUOTE:
203 case OPT_COL_QUOTE2:
204 case OPT_COL_QUOTE3:
205 case OPT_COL_EXTQUOTE:
206 case OPT_COL_RESPONSE:
207 case OPT_COL_SIGNATURE:
208 case OPT_COL_SUBJECT:
209 case OPT_COL_TEXT:
210 case OPT_COL_TITLE:
211 case OPT_COL_URLS:
212 case OPT_QUOTE_REGEX:
213 case OPT_QUOTE_REGEX2:
214 case OPT_QUOTE_REGEX3:
215 case OPT_EXTQUOTE_HANDLING:
216 return curr_scope ? FALSE : tinrc.use_color;
217
218 case OPT_COL_MARKSTAR:
219 case OPT_COL_MARKDASH:
220 case OPT_COL_MARKSLASH:
221 case OPT_COL_MARKSTROKE:
222 return curr_scope ? FALSE : (tinrc.word_highlight && tinrc.use_color);
223
224 case OPT_COL_VERBATIM:
225 return curr_scope ? FALSE : (tinrc.verbatim_handling && tinrc.use_color);
226
227 case OPT_EXTQUOTE_REGEX:
228 return curr_scope ? FALSE : (tinrc.extquote_handling && tinrc.use_color);
229 #endif /* HAVE_COLOR */
230
231 case OPT_WORD_H_DISPLAY_MARKS:
232 case OPT_SLASHES_REGEX:
233 case OPT_STARS_REGEX:
234 case OPT_STROKES_REGEX:
235 case OPT_UNDERSCORES_REGEX:
236 return curr_scope ? FALSE : tinrc.word_highlight;
237
238 case OPT_MONO_MARKSTAR:
239 case OPT_MONO_MARKDASH:
240 case OPT_MONO_MARKSLASH:
241 case OPT_MONO_MARKSTROKE:
242 #ifdef HAVE_COLOR
243 return curr_scope ? FALSE : (tinrc.word_highlight && !tinrc.use_color);
244 #else
245 return curr_scope ? FALSE : tinrc.word_highlight;
246 #endif /* HAVE_COLOR */
247
248 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
249 case OPT_UTF8_GRAPHICS:
250 return curr_scope ? FALSE : IS_LOCAL_CHARSET("UTF-8");
251 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
252
253 case OPT_VERBATIM_BEGIN_REGEX:
254 case OPT_VERBATIM_END_REGEX:
255 return curr_scope ? FALSE : tinrc.verbatim_handling;
256
257 #ifndef USE_CURSES
258 case OPT_STRIP_BLANKS:
259 #endif /* !USE_CURSES */
260 case OPT_GETART_LIMIT_OPTIONS:
261 return curr_scope ? FALSE : TRUE;
262
263 #ifdef HAVE_COLOR
264 case OPT_COLOR_OPTIONS:
265 return curr_scope ? tinrc.use_color : TRUE;
266 #endif /* HAVE_COLOR */
267
268 case OPT_DISPLAY_OPTIONS:
269 case OPT_FILTERING_OPTIONS:
270 case OPT_SAVING_OPTIONS:
271 case OPT_POSTING_OPTIONS:
272 case OPT_EXPERT_OPTIONS:
273 return TRUE;
274
275 case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
276 case OPT_ATTRIB_ADVERTISING:
277 case OPT_ATTRIB_ALTERNATIVE_HANDLING:
278 case OPT_ATTRIB_ASK_FOR_METAMAIL:
279 case OPT_ATTRIB_AUTO_CC_BCC:
280 case OPT_ATTRIB_AUTO_LIST_THREAD:
281 case OPT_ATTRIB_AUTO_SAVE:
282 case OPT_ATTRIB_AUTO_SELECT:
283 case OPT_ATTRIB_BATCH_SAVE:
284 case OPT_ATTRIB_DATE_FORMAT:
285 case OPT_ATTRIB_DELETE_TMP_FILES:
286 case OPT_ATTRIB_EDITOR_FORMAT:
287 case OPT_ATTRIB_FCC:
288 case OPT_ATTRIB_FOLLOWUP_TO:
289 case OPT_ATTRIB_FROM:
290 case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
291 case OPT_ATTRIB_GROUP_FORMAT:
292 #ifdef HAVE_ISPELL
293 case OPT_ATTRIB_ISPELL:
294 #endif /* HAVE_ISPELL */
295 case OPT_ATTRIB_MAILDIR:
296 case OPT_ATTRIB_MAIL_8BIT_HEADER:
297 case OPT_ATTRIB_MAIL_MIME_ENCODING:
298 case OPT_ATTRIB_MAILING_LIST:
299 case OPT_ATTRIB_MARK_IGNORE_TAGS:
300 case OPT_ATTRIB_MARK_SAVED_READ:
301 case OPT_ATTRIB_MIME_FORWARD:
302 case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
303 case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
304 case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
305 case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
306 case OPT_ATTRIB_ORGANIZATION:
307 case OPT_ATTRIB_POST_8BIT_HEADER:
308 case OPT_ATTRIB_POST_MIME_ENCODING:
309 case OPT_ATTRIB_POST_PROCESS_VIEW:
310 case OPT_ATTRIB_POS_FIRST_UNREAD:
311 case OPT_ATTRIB_QUICK_KILL_HEADER:
312 case OPT_ATTRIB_QUICK_KILL_SCOPE:
313 case OPT_ATTRIB_QUICK_KILL_EXPIRE:
314 case OPT_ATTRIB_QUICK_KILL_CASE:
315 case OPT_ATTRIB_QUICK_SELECT_HEADER:
316 case OPT_ATTRIB_QUICK_SELECT_SCOPE:
317 case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
318 case OPT_ATTRIB_QUICK_SELECT_CASE:
319 #ifndef DISABLE_PRINTING
320 case OPT_ATTRIB_PRINT_HEADER:
321 #endif /* !DISABLE_PRINTING */
322 case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
323 case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
324 case OPT_ATTRIB_QUOTE_CHARS:
325 case OPT_ATTRIB_SAVEDIR:
326 case OPT_ATTRIB_SAVEFILE:
327 case OPT_ATTRIB_SHOW_AUTHOR:
328 case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
329 case OPT_ATTRIB_SHOW_SIGNATURES:
330 case OPT_ATTRIB_SIGDASHES:
331 case OPT_ATTRIB_SIGFILE:
332 case OPT_ATTRIB_SIGNATURE_REPOST:
333 case OPT_ATTRIB_START_EDITOR_OFFSET:
334 case OPT_ATTRIB_THREAD_ARTICLES:
335 case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
336 case OPT_ATTRIB_THREAD_FORMAT:
337 case OPT_ATTRIB_THREAD_PERC:
338 case OPT_ATTRIB_TRIM_ARTICLE_BODY:
339 case OPT_ATTRIB_TEX2ISO_CONV:
340 case OPT_ATTRIB_SORT_THREADS_TYPE:
341 #ifdef CHARSET_CONVERSION
342 case OPT_ATTRIB_MM_NETWORK_CHARSET:
343 case OPT_ATTRIB_UNDECLARED_CHARSET:
344 #endif /* CHARSET_CONVERSION */
345 case OPT_ATTRIB_VERBATIM_HANDLING:
346 case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
347 case OPT_ATTRIB_SORT_ARTICLE_TYPE:
348 case OPT_ATTRIB_POST_PROCESS_TYPE:
349 case OPT_ATTRIB_X_BODY:
350 case OPT_ATTRIB_X_COMMENT_TO:
351 case OPT_ATTRIB_X_HEADERS:
352 return curr_scope ? TRUE : FALSE;
353
354 #ifdef HAVE_COLOR
355 case OPT_ATTRIB_EXTQUOTE_HANDLING:
356 return curr_scope ? tinrc.use_color : FALSE;
357 #endif /* HAVE_COLOR */
358
359 default:
360 return curr_scope ? FALSE : TRUE;
361 }
362 }
363
364
365 /*
366 * returns TRUE if option is OPT_TITLE else FALSE
367 */
368 static t_bool
option_is_title(enum option_enum option)369 option_is_title(
370 enum option_enum option)
371 {
372 return option_table[option].var_type == OPT_TITLE;
373 }
374
375
376 /*
377 * returns TRUE if option is on the current page else FALSE
378 */
379 static t_bool
option_on_page(enum option_enum option)380 option_on_page(
381 enum option_enum option)
382 {
383 return ((option >= first_option_on_screen) && (option <= last_option_on_screen));
384 }
385
386
387 char *
fmt_option_prompt(char * dst,size_t len,t_bool editing,enum option_enum option)388 fmt_option_prompt(
389 char *dst,
390 size_t len,
391 t_bool editing,
392 enum option_enum option)
393 {
394 char *buf;
395 size_t option_width = MAX(35, cCOLS / 2 - 9);
396 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
397 wchar_t *wbuf, *wbuf2;
398
399 /* convert the option text to wchar_t */
400 wbuf = char2wchar_t(_(option_table[option].txt->opt));
401 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
402
403 if (!option_is_title(option)) {
404 char flag;
405 int num = get_option_num(option);
406
407 flag = (curr_scope && check_state(option)) ? '+' : ' ';
408 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
409 if (wbuf != NULL) {
410 wbuf2 = wstrunc(wbuf, option_width);
411 if ((buf = wchar_t2char(wbuf2)) == NULL) {
412 /* conversion failed, truncate original string */
413 buf = strunc(_(option_table[option].txt->opt), option_width);
414 snprintf(dst, len, "%s %c%3d %-*.*s: ", editing ? "->" : " ", flag, num, (int) option_width, (int) option_width, buf);
415 } else
416 snprintf(dst, len, "%s %c%3d %-*.*s: ", editing ? "->" : " ", flag, num,
417 (int) (strlen(buf) + option_width - wcswidth(wbuf2, option_width + 1)),
418 (int) (strlen(buf) + option_width - wcswidth(wbuf2, option_width + 1)), buf);
419 free(wbuf2);
420 } else
421 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
422 {
423 /* truncate original string */
424 buf = strunc(_(option_table[option].txt->opt), option_width);
425 snprintf(dst, len, "%s %c%3d %-*.*s: ", editing ? "->" : " ", flag, num, (int) option_width, (int) option_width, buf);
426 }
427 } else {
428 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
429 if (wbuf != NULL) {
430 wbuf2 = wstrunc(wbuf, cCOLS - 3);
431 if ((buf = wchar_t2char(wbuf2)) == NULL) /* conversion failed, truncate original string */
432 buf = strunc(_(option_table[option].txt->opt), cCOLS - 3);
433 free(wbuf2);
434 } else
435 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
436 buf = strunc(_(option_table[option].txt->opt), cCOLS - 3); /* truncate original string */
437 snprintf(dst, len, " %s", buf);
438 }
439
440 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
441 FreeIfNeeded(wbuf);
442 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
443 FreeIfNeeded(buf);
444 return dst;
445 }
446
447
448 static void
print_any_option(enum option_enum option)449 print_any_option(
450 enum option_enum option)
451 {
452 constext **list;
453 char temp[LEN], *ptr, *ptr2;
454 int row = option_row(option);
455 size_t len = sizeof(temp) - 1;
456 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) && defined(USE_CURSES)
457 char *buf;
458 #endif /* MULTIBYTE_ABLE && !NO_LOCALE && USE_CURSES */
459
460 MoveCursor(row, 0);
461
462 ptr = fmt_option_prompt(temp, len, FALSE, option);
463 ptr += strlen(temp);
464 len -= strlen(temp);
465
466 switch (option_table[option].var_type) {
467 case OPT_ON_OFF:
468 /* %-3s to match the length of OFF */
469 snprintf(ptr, len, "%-3s", print_boolean(*OPT_ON_OFF_list[option_table[option].var_index]));
470 break;
471
472 case OPT_LIST:
473 list = option_table[option].opt_list;
474 ptr2 = my_strdup(list[*(option_table[option].variable) + ((strcasecmp(_(list[0]), _(txt_default)) == 0) ? 1 : 0)]);
475 strncpy(ptr, _(ptr2), len);
476 free(ptr2);
477 break;
478
479 case OPT_STRING:
480 strncpy(ptr, OPT_STRING_list[option_table[option].var_index], len);
481 break;
482
483 case OPT_NUM:
484 snprintf(ptr, len, "%d", *(option_table[option].variable));
485 break;
486
487 case OPT_CHAR:
488 snprintf(ptr, len, "%c", *OPT_CHAR_list[option_table[option].var_index]);
489 break;
490
491 default:
492 break;
493 }
494 #ifdef USE_CURSES
495 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
496 if ((buf = spart(temp, cCOLS - 1, FALSE)) != NULL) {
497 my_printf("%s", buf);
498 free(buf);
499 } else
500 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
501 my_printf("%.*s", cCOLS - 1, temp);
502 {
503 int y, x;
504
505 getyx(stdscr, y, x);
506 if (x < cCOLS)
507 clrtoeol();
508 }
509 #else
510 my_printf("%.*s", cCOLS - 1, temp);
511 /* draw_arrow_mark() will read this back for repainting */
512 if (tinrc.strip_blanks)
513 strncpy(screen[row - INDEX_TOP].col, temp, cCOLS - 1);
514 else
515 snprintf(screen[row - INDEX_TOP].col, cCOLS, "%-*s", cCOLS - 1, temp);
516 #endif /* USE_CURSES */
517 }
518
519
520 static void
repaint_option(enum option_enum option)521 repaint_option(
522 enum option_enum option)
523 {
524 if (option_on_page(option))
525 print_any_option(option);
526 }
527
528
529 #ifdef USE_CURSES
530 static void
do_scroll(int jump)531 do_scroll(
532 int jump)
533 {
534 scrollok(stdscr, TRUE);
535 MoveCursor(INDEX_TOP, 0);
536 SetScrollRegion(INDEX_TOP, INDEX_TOP + option_lines_per_page - 1);
537 ScrollScreen(jump);
538 SetScrollRegion(0, LINES - 1);
539 scrollok(stdscr, FALSE);
540 }
541 #endif /* USE_CURSES */
542
543
544 /*
545 * returns the option after moving 'move' positions up or down
546 * updates also first_option_on_screen and last_option_on screen accordingly
547 */
548 static enum option_enum
move_cursor(enum option_enum cur_option,t_bool down)549 move_cursor(
550 enum option_enum cur_option,
551 t_bool down)
552 {
553 enum option_enum old_option = cur_option;
554
555 if (down) { /* move down */
556 do {
557 cur_option = next_option(cur_option, TRUE);
558 if (cur_option > last_option_on_screen) {
559 /* move the markers one option down */
560 last_option_on_screen = cur_option;
561 first_option_on_screen = next_option(first_option_on_screen, TRUE);
562 #ifdef USE_CURSES
563 do_scroll(1);
564 print_any_option(cur_option);
565 #else
566 show_config_page();
567 #endif /* USE_CURSES */
568 } else if (cur_option < first_option_on_screen) {
569 /* wrap around: set to begin of option list */
570 first_option_on_screen = cur_option;
571 set_last_option_on_screen(cur_option);
572 show_config_page();
573 }
574 } while (option_is_title(cur_option) && old_option != cur_option);
575 } else { /* move up */
576 do {
577 cur_option = prev_option(cur_option, TRUE);
578 if (cur_option < first_option_on_screen) {
579 /* move the markers one option up */
580 first_option_on_screen = cur_option;
581 set_last_option_on_screen(cur_option);
582 #ifdef USE_CURSES
583 do_scroll(-1);
584 print_any_option(cur_option);
585 #else
586 show_config_page();
587 #endif /* USE_CURSES */
588 } else if (cur_option > last_option_on_screen) {
589 /* wrap around: set to end of option list */
590 last_option_on_screen = cur_option;
591 set_first_option_on_screen(cur_option);
592 show_config_page();
593 }
594 } while (option_is_title(cur_option) && old_option != cur_option);
595 }
596 return cur_option;
597 }
598
599
600 /*
601 * scroll the screen one line down
602 * the selected option is only moved if it is scrolled off the screen
603 */
604 static enum option_enum
opt_scroll_down(enum option_enum option)605 opt_scroll_down(
606 enum option_enum option)
607 {
608 if (last_option_on_screen < last_opt) {
609 first_option_on_screen = next_option(first_option_on_screen, TRUE);
610 set_last_option_on_screen(first_option_on_screen);
611 #ifdef USE_CURSES
612 do_scroll(1);
613 print_any_option(last_option_on_screen);
614 stow_cursor();
615 #else
616 show_config_page();
617 #endif /* USE_CURSES */
618 if (option < first_option_on_screen) {
619 option = first_option_on_screen;
620 if (option_is_title(option))
621 option = next_option(option, FALSE);
622 #ifdef USE_CURSES
623 highlight_option(option);
624 #endif /* USE_CURSES */
625 }
626 #ifndef USE_CURSES
627 /* in the !USE_CURSES case we must always highlight the option */
628 highlight_option(option);
629 #endif /* !USE_CURSES */
630 }
631 return option;
632 }
633
634
635 /*
636 * scroll the screen one line up
637 * the selected option is only moved if it is scrolled off the screen
638 */
639 static enum option_enum
opt_scroll_up(enum option_enum option)640 opt_scroll_up(
641 enum option_enum option)
642 {
643 if (first_option_on_screen > 0) {
644 first_option_on_screen = prev_option(first_option_on_screen, TRUE);
645 set_last_option_on_screen(first_option_on_screen);
646 #ifdef USE_CURSES
647 do_scroll(-1);
648 print_any_option(first_option_on_screen);
649 stow_cursor();
650 #else
651 show_config_page();
652 #endif /* USE_CURSES */
653 if (option > last_option_on_screen) {
654 option = last_option_on_screen;
655 if (option_is_title(option))
656 option = prev_option(option, FALSE);
657 #ifdef USE_CURSES
658 highlight_option(option);
659 #endif /* USE_CURSES */
660 }
661 #ifndef USE_CURSES
662 /* in the !USE_CURSES case we must always highlight the option */
663 highlight_option(option);
664 #endif /* !USE_CURSES */
665 }
666 return option;
667 }
668
669
670 /*
671 * returns the next visible option
672 * if 'incl_titles' is TRUE titles are also returned else they are skipped
673 */
674 static enum option_enum
next_option(enum option_enum option,t_bool incl_titles)675 next_option(
676 enum option_enum option,
677 t_bool incl_titles)
678 {
679 do {
680 option++;
681 if (option > last_opt)
682 option = 0;
683 } while (!(option_is_visible(option) && (incl_titles || !option_is_title(option))));
684
685 return option;
686 }
687
688
689 /*
690 * returns the previous visible option
691 * if 'incl_titles' is TRUE titles are also returned else they are skipped
692 */
693 static enum option_enum
prev_option(enum option_enum option,t_bool incl_titles)694 prev_option(
695 enum option_enum option,
696 t_bool incl_titles)
697 {
698 do {
699 if (option == 0)
700 option = last_opt;
701 else
702 option--;
703 } while (!(option_is_visible(option) && (incl_titles || !option_is_title(option))));
704
705 return option;
706 }
707
708
709 /*
710 * set first_option_on_screen in such way that 'last_option' will be
711 * the last option on the screen
712 */
713 static void
set_first_option_on_screen(enum option_enum last_option)714 set_first_option_on_screen(
715 enum option_enum last_option)
716 {
717 int i;
718
719 first_option_on_screen = last_option;
720 for (i = 1; i < option_lines_per_page && first_option_on_screen > 0; i++)
721 first_option_on_screen = prev_option(first_option_on_screen, TRUE);
722
723 /*
724 * make sure that the first page is used completely
725 */
726 if (first_option_on_screen == 0)
727 set_last_option_on_screen(0);
728 }
729
730
731 /*
732 * set last_option_on_screen in such way that 'first_option' will be
733 * the first option on the screen
734 */
735 static void
set_last_option_on_screen(enum option_enum first_option)736 set_last_option_on_screen(
737 enum option_enum first_option)
738 {
739 int i;
740
741 last_option_on_screen = first_option;
742 /*
743 * on last page, there need not be option_lines_per_page options
744 */
745 for (i = 1; i < option_lines_per_page && last_option_on_screen < last_opt; i++)
746 last_option_on_screen = next_option(last_option_on_screen, TRUE);
747 }
748
749
750 static void
highlight_option(enum option_enum option)751 highlight_option(
752 enum option_enum option)
753 {
754 refresh_config_page(option); /* to keep refresh_config_page():last_option up-to-date */
755 draw_arrow_mark(option_row(option));
756 info_message("%s", _(option_table[option].txt->opt));
757 }
758
759
760 static void
unhighlight_option(enum option_enum option)761 unhighlight_option(
762 enum option_enum option)
763 {
764 /* Astonishing hack */
765 t_menu *savemenu = currmenu;
766 t_menu cfgmenu = { 0, 1, 0, NULL, NULL, NULL };
767
768 currmenu = &cfgmenu;
769 currmenu->curr = option_row(option) - INDEX_TOP;
770 erase_arrow();
771 currmenu = savemenu;
772 clear_message();
773 }
774
775
776 /*
777 * Refresh the config page which holds the actual option. If act_option is
778 * smaller zero fall back on the last given option (first option if there was
779 * no last option) and refresh the screen.
780 */
781 void
refresh_config_page(enum option_enum act_option)782 refresh_config_page(
783 enum option_enum act_option)
784 {
785 static enum option_enum last_option = 0;
786 /* t_bool force_redraw = FALSE; */
787
788 if (act_option == SIGNAL_HANDLER) { /* called by signal handler */
789 /* force_redraw = TRUE; */
790 act_option = last_option;
791 set_last_option_on_screen(first_option_on_screen); /* terminal size may have changed */
792 if (!option_on_page(last_option)) {
793 last_option_on_screen = last_option;
794 set_first_option_on_screen(last_option);
795 }
796 redraw_screen(last_option);
797 }
798 last_option = act_option;
799 }
800
801
802 static void
redraw_screen(enum option_enum option)803 redraw_screen(
804 enum option_enum option)
805 {
806 show_config_page();
807 highlight_option(option);
808 }
809
810
811 /*
812 * show_menu_help
813 */
814 void
show_menu_help(const char * help_message)815 show_menu_help(
816 const char *help_message)
817 {
818 MoveCursor(cLINES - 2, 0);
819 CleartoEOLN();
820 center_line(cLINES - 2, FALSE, _(help_message));
821 }
822
823
824 /*
825 * display current configuration page
826 */
827 static void
show_config_page(void)828 show_config_page(
829 void)
830 {
831 enum option_enum i;
832
833 signal_context = curr_scope ? cAttrib : cConfig;
834 mark_offset = 0;
835
836 ClearScreen();
837 center_line(0, TRUE, curr_scope ? curr_scope->scope : _(txt_options_menu));
838
839 for (i = first_option_on_screen; i <= last_option_on_screen; i++) {
840 while (!option_is_visible(i))
841 i++;
842 if (i > last_opt)
843 break;
844 print_any_option(i);
845 }
846
847 show_menu_help(txt_select_config_file_option);
848 my_flush();
849 stow_cursor();
850 }
851
852
853 /*
854 * Check if score_kill is <= score_limit_kill and if score_select >= score_limit_select
855 */
856 void
check_score_defaults(void)857 check_score_defaults(
858 void)
859 {
860 if (tinrc.score_kill > tinrc.score_limit_kill)
861 tinrc.score_kill = tinrc.score_limit_kill;
862
863 if (tinrc.score_select < tinrc.score_limit_select)
864 tinrc.score_select = tinrc.score_limit_select;
865 }
866
867
868 static t_function
option_left(void)869 option_left(
870 void)
871 {
872 return GLOBAL_QUIT;
873 }
874
875
876 static t_function
option_right(void)877 option_right(
878 void)
879 {
880 return CONFIG_SELECT;
881 }
882
883
884 /*
885 * set last_opt to the last visible option
886 */
887 static void
set_last_opt(void)888 set_last_opt(
889 void)
890 {
891 enum option_enum i;
892
893 for (i = 0; i <= LAST_OPT; i++) {
894 if (option_is_visible(i))
895 last_opt = i;
896 }
897 }
898
899
900 /*
901 * returns the first visible option
902 */
903 static enum option_enum
get_first_opt(void)904 get_first_opt(
905 void)
906 {
907 enum option_enum i;
908
909 for (i = 0; i <= last_opt; i++) {
910 if (option_is_visible(i) && !option_is_title(i))
911 break;
912 }
913 return i;
914 }
915
916
917 /*
918 * options menu so that the user can dynamically change parameters
919 */
920 void
config_page(const char * grpname,enum context level)921 config_page(
922 const char *grpname,
923 enum context level)
924 {
925 char key[MAXKEYLEN];
926 enum option_enum option, old_option;
927 enum {
928 NOT_CHANGED = 0,
929 MISC_OPTS = 1 << 0,
930 DISPLAY_OPTS = 1 << 1,
931 SCORE_OPTS = 1 << 2,
932 SHOW_AUTHOR = 1 << 3,
933 SHOW_ONLY_UNREAD = 1 << 4,
934 SORT_OPTS = 1 << 5,
935 THREAD_ARTS = 1 << 6,
936 THREAD_SCORE = 1 << 7
937 } changed = NOT_CHANGED;
938 int i, scope_idx = 0;
939 t_bool change_option = FALSE;
940 t_function func;
941 #ifdef CHARSET_CONVERSION
942 t_bool is_7bit;
943 #endif /* CHARSET_CONVERSION */
944 unsigned old_show_author = 0, old_show_unread = 0, old_thread_arts = 0;
945
946 if (curr_scope)
947 initialize_attributes();
948 if (grpname && curr_group) {
949 /*
950 * These things can be toggled by the user,
951 * keep a copy of the current value to restore
952 * the state if necessary
953 */
954 old_show_author = curr_group->attribute->show_author;
955 old_show_unread = curr_group->attribute->show_only_unread_arts;
956 old_thread_arts = curr_group->attribute->thread_articles;
957 }
958 set_last_opt();
959 option = get_first_opt();
960 first_option_on_screen = 0;
961 set_last_option_on_screen(0);
962
963 redraw_screen(option);
964 set_xclick_off();
965
966 forever {
967 switch ((func = handle_keypad(option_left, option_right, NULL, option_menu_keys))) {
968 case GLOBAL_QUIT:
969 if (grpname) {
970 if (curr_scope && scope_is_empty()) {
971 /*
972 * Called via TAB from Config 'M'enu and all attributes
973 * have default values -> delete scope
974 */
975 do_delete_scope(scope_idx);
976 curr_scope = NULL;
977 }
978 if (changed) {
979 /*
980 * At least one option or attribute has changed,
981 * write config files
982 */
983 write_config_file(local_config_file);
984 write_attributes_file(local_attributes_file);
985 }
986 }
987 /* FALLTHROUGH */
988 case CONFIG_NO_SAVE:
989 if (grpname && curr_scope) {
990 /*
991 * Called via TAB from Config 'M'enu,
992 * delete scope if all attributes have default values
993 */
994 if (scope_is_empty())
995 do_delete_scope(scope_idx);
996 curr_scope = NULL;
997 }
998 assign_attributes_to_groups();
999 if (grpname && curr_group) {
1000 /*
1001 * These things can be toggled by the user,
1002 * restore the cached state if no changes were made
1003 */
1004 if (!(changed & SHOW_AUTHOR))
1005 curr_group->attribute->show_author = old_show_author;
1006 if (!(changed & SHOW_ONLY_UNREAD))
1007 curr_group->attribute->show_only_unread_arts = old_show_unread;
1008 if (!(changed & THREAD_ARTS))
1009 curr_group->attribute->thread_articles = old_thread_arts;
1010
1011 if (changed) {
1012 t_bool filtered = FALSE;
1013 t_bool old_keep_in_base = TRUE;
1014
1015 /*
1016 * recook if an article is open
1017 */
1018 if (changed & DISPLAY_OPTS) {
1019 if (pgart.raw)
1020 resize_article(TRUE, &pgart);
1021 }
1022 /*
1023 * Clear art->keep_in_base if switching to !show_only_unread_arts
1024 */
1025 if ((changed & SHOW_ONLY_UNREAD) && !curr_group->attribute->show_only_unread_arts) {
1026 for_each_art(i)
1027 arts[i].keep_in_base = FALSE;
1028 }
1029
1030 if (changed & SCORE_OPTS) {
1031 unfilter_articles(curr_group);
1032 read_filter_file(filter_file);
1033 filtered = filter_articles(curr_group);
1034 }
1035 /*
1036 * If the sorting/threading strategy of threads or filter options have
1037 * changed, fix things so that resorting will occur
1038 *
1039 * If show_only_unread_arts or the scoring of a thread has changed,
1040 * resort base[] (find_base() is called inside make_threads() too, so
1041 * do this only if make_threads() was not called before)
1042 *
1043 * If we were called from page level, keep the current article in
1044 * base[]. This prevents that find_base() removes the current article
1045 * after switching to show_only_unread.
1046 */
1047 if (level == cPage) {
1048 old_keep_in_base = arts[this_resp].keep_in_base;
1049 arts[this_resp].keep_in_base = TRUE;
1050 }
1051 if (changed & (THREAD_ARTS | SORT_OPTS))
1052 make_threads(curr_group, TRUE);
1053 else if (filtered)
1054 make_threads(curr_group, FALSE);
1055 else if (changed & (SHOW_ONLY_UNREAD | THREAD_SCORE))
1056 find_base(curr_group);
1057
1058 if (level == cPage)
1059 arts[this_resp].keep_in_base = old_keep_in_base;
1060 }
1061 }
1062 clear_note_area();
1063 return;
1064
1065 case GLOBAL_BUGREPORT:
1066 bug_report();
1067 redraw_screen(option);
1068 break;
1069
1070 case GLOBAL_HELP:
1071 if (curr_scope)
1072 show_help_page(ATTRIB_LEVEL, _(txt_attrib_menu_com));
1073 else
1074 show_help_page(CONFIG_LEVEL, _(txt_options_menu_com));
1075 redraw_screen(option);
1076 break;
1077
1078 case GLOBAL_LINE_UP:
1079 unhighlight_option(option);
1080 option = move_cursor(option, FALSE);
1081 highlight_option(option);
1082 break;
1083
1084 case GLOBAL_LINE_DOWN:
1085 unhighlight_option(option);
1086 option = move_cursor(option, TRUE);
1087 highlight_option(option);
1088 break;
1089
1090 case GLOBAL_FIRST_PAGE:
1091 unhighlight_option(option);
1092 option = get_first_opt();
1093 first_option_on_screen = 0;
1094 set_last_option_on_screen(0);
1095 redraw_screen(option);
1096 /* highlight_option(option); is already done by redraw_screen() */
1097 break;
1098
1099 case GLOBAL_LAST_PAGE:
1100 unhighlight_option(option);
1101 option = last_opt;
1102 last_option_on_screen = last_opt;
1103 set_first_option_on_screen(last_opt);
1104 redraw_screen(option);
1105 /* highlight_option(option); is already done by redraw_screen() */
1106 break;
1107
1108 case GLOBAL_PAGE_UP:
1109 unhighlight_option(option);
1110 if (option != first_option_on_screen && !(option_is_title(first_option_on_screen) && option == next_option(first_option_on_screen, FALSE))) {
1111 option = first_option_on_screen;
1112 if (option_is_title(option))
1113 option = next_option(option, FALSE);
1114 highlight_option(option);
1115 break;
1116 } else if (tinrc.scroll_lines == -2 && first_option_on_screen != 0) {
1117 i = option_lines_per_page / 2;
1118
1119 for (; i > 0; i--) {
1120 last_option_on_screen = prev_option(last_option_on_screen, TRUE);
1121 if (last_option_on_screen == last_opt) /* end on wrap around */
1122 break;
1123 }
1124 } else
1125 last_option_on_screen = prev_option(first_option_on_screen, TRUE);
1126
1127 set_first_option_on_screen(last_option_on_screen);
1128 if (last_option_on_screen == last_opt)
1129 option = last_option_on_screen;
1130 else
1131 option = first_option_on_screen;
1132 if (option_is_title(option))
1133 option = next_option(option, FALSE);
1134 redraw_screen(option);
1135 /* highlight_option(option); is already done by redraw_screen() */
1136 break;
1137
1138 case GLOBAL_PAGE_DOWN:
1139 unhighlight_option(option);
1140 if (option == last_opt) {
1141 /* wrap around */
1142 first_option_on_screen = 0;
1143 option = 0;
1144 } else {
1145 enum option_enum old_first = first_option_on_screen;
1146
1147 if (tinrc.scroll_lines == -2) {
1148 i = option_lines_per_page / 2;
1149
1150 for (; i > 0; i--) {
1151 first_option_on_screen = next_option(first_option_on_screen, TRUE);
1152 if (first_option_on_screen == 0) /* end on wrap_around */
1153 break;
1154 }
1155 } else
1156 first_option_on_screen = next_option(last_option_on_screen, TRUE);
1157
1158 if (first_option_on_screen == 0) {
1159 first_option_on_screen = old_first;
1160 option = last_opt;
1161 highlight_option(option);
1162 break;
1163 } else
1164 option = first_option_on_screen;
1165 }
1166
1167 set_last_option_on_screen(first_option_on_screen);
1168 if (option_is_title(option))
1169 option = next_option(option, FALSE);
1170 redraw_screen(option);
1171 /* highlight_option(option); is already done by redraw_screen() */
1172 break;
1173
1174 case GLOBAL_SCROLL_UP:
1175 option = opt_scroll_up(option);
1176 break;
1177
1178 case GLOBAL_SCROLL_DOWN:
1179 option = opt_scroll_down(option);
1180 break;
1181
1182 case DIGIT_1:
1183 case DIGIT_2:
1184 case DIGIT_3:
1185 case DIGIT_4:
1186 case DIGIT_5:
1187 case DIGIT_6:
1188 case DIGIT_7:
1189 case DIGIT_8:
1190 case DIGIT_9:
1191 unhighlight_option(option);
1192 option = set_option_num(prompt_num(func_to_key(func, option_menu_keys), _(txt_enter_option_num)));
1193 if (!option_on_page(option)) {
1194 first_option_on_screen = option;
1195 set_last_option_on_screen(option);
1196 redraw_screen(option);
1197 } else
1198 highlight_option(option);
1199 break;
1200
1201 #ifndef NO_SHELL_ESCAPE
1202 case GLOBAL_SHELL_ESCAPE:
1203 shell_escape();
1204 redraw_screen(option);
1205 break;
1206 #endif /* !NO_SHELL_ESCAPE */
1207
1208 case GLOBAL_SEARCH_SUBJECT_FORWARD:
1209 case GLOBAL_SEARCH_SUBJECT_BACKWARD:
1210 case GLOBAL_SEARCH_REPEAT:
1211 if (func == GLOBAL_SEARCH_REPEAT && last_search != GLOBAL_SEARCH_SUBJECT_FORWARD && last_search != GLOBAL_SEARCH_SUBJECT_BACKWARD)
1212 info_message(_(txt_no_prev_search));
1213 else {
1214 old_option = option;
1215 option = search_config((func == GLOBAL_SEARCH_SUBJECT_FORWARD), (func == GLOBAL_SEARCH_REPEAT), option, last_opt);
1216 if (option != old_option) {
1217 unhighlight_option(old_option);
1218 if (!option_on_page(option)) {
1219 first_option_on_screen = option;
1220 set_last_option_on_screen(option);
1221 redraw_screen(option);
1222 } else
1223 highlight_option(option);
1224 }
1225 }
1226 break;
1227
1228 case CONFIG_SCOPE_MENU:
1229 if (!curr_scope) {
1230 scope_page(level);
1231 set_last_opt();
1232 option = get_first_opt();
1233 first_option_on_screen = 0;
1234 set_last_option_on_screen(0);
1235 redraw_screen(option);
1236 }
1237 break;
1238
1239 case CONFIG_RESET_ATTRIB:
1240 if (curr_scope) {
1241 if (curr_scope->global)
1242 info_message(_(txt_scope_operation_not_allowed));
1243 else if (check_state(option)) {
1244 reset_state(option);
1245 changed |= MISC_OPTS;
1246 redraw_screen(option);
1247 }
1248 }
1249 break;
1250
1251 case CONFIG_SELECT:
1252 if (curr_scope && curr_scope->global)
1253 info_message(_(txt_scope_operation_not_allowed));
1254 else
1255 change_option = TRUE;
1256 break;
1257
1258 case CONFIG_TOGGLE_ATTRIB:
1259 if (grpname) {
1260 if (curr_scope) {
1261 if (scope_is_empty()) {
1262 do_delete_scope(scope_idx);
1263 scope_idx = 0;
1264 }
1265 curr_scope = NULL;
1266 } else {
1267 if (!(scope_idx = find_scope(grpname)))
1268 scope_idx = add_scope(grpname);
1269 if (scope_idx) {
1270 curr_scope = &scopes[scope_idx];
1271 initialize_attributes();
1272 }
1273 }
1274 set_last_opt();
1275 option = get_first_opt();
1276 first_option_on_screen = 0;
1277 set_last_option_on_screen(0);
1278 redraw_screen(option);
1279 }
1280 break;
1281
1282 case GLOBAL_REDRAW_SCREEN:
1283 my_retouch();
1284 set_xclick_off();
1285 set_last_option_on_screen(first_option_on_screen);
1286 redraw_screen(option);
1287 break;
1288
1289 case GLOBAL_VERSION:
1290 info_message(cvers);
1291 break;
1292
1293 default:
1294 info_message(_(txt_bad_command), printascii(key, func_to_key(GLOBAL_HELP, option_menu_keys)));
1295 break;
1296 } /* switch (ch) */
1297
1298 if (change_option) {
1299 switch (option_table[option].var_type) {
1300 case OPT_ON_OFF:
1301 switch (option) {
1302 case OPT_ABBREVIATE_GROUPNAME:
1303 case OPT_AUTO_RECONNECT:
1304 case OPT_CACHE_OVERVIEW_FILES:
1305 case OPT_CATCHUP_READ_GROUPS:
1306 case OPT_FORCE_SCREEN_REDRAW:
1307 case OPT_KEEP_DEAD_ARTICLES:
1308 case OPT_SHOW_ONLY_UNREAD_GROUPS:
1309 case OPT_STRIP_NEWSRC:
1310 #if defined(HAVE_ICONV_OPEN_TRANSLIT) && defined(CHARSET_CONVERSION)
1311 case OPT_TRANSLIT:
1312 #endif /* HAVE_ICONV_OPEN_TRANSLIT && CHARSET_CONVERSION */
1313 case OPT_UNLINK_ARTICLE:
1314 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
1315 case OPT_UTF8_GRAPHICS:
1316 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
1317 case OPT_URL_HIGHLIGHT:
1318 #ifdef HAVE_KEYPAD
1319 case OPT_USE_KEYPAD:
1320 #endif /* HAVE_KEYPAD */
1321 case OPT_USE_MOUSE:
1322 if (prompt_option_on_off(option))
1323 changed |= MISC_OPTS;
1324 break;
1325
1326 case OPT_ADD_POSTED_TO_FILTER:
1327 if (prompt_option_on_off(option))
1328 UPDATE_INT_ATTRIBUTES(add_posted_to_filter);
1329 break;
1330
1331 case OPT_ADVERTISING:
1332 if (prompt_option_on_off(option))
1333 UPDATE_INT_ATTRIBUTES(advertising);
1334 break;
1335
1336 case OPT_ALTERNATIVE_HANDLING:
1337 if (prompt_option_on_off(option))
1338 UPDATE_INT_ATTRIBUTES(alternative_handling);
1339 break;
1340
1341 case OPT_ASK_FOR_METAMAIL:
1342 if (prompt_option_on_off(option))
1343 UPDATE_INT_ATTRIBUTES(ask_for_metamail);
1344 break;
1345
1346 case OPT_AUTO_LIST_THREAD:
1347 if (prompt_option_on_off(option))
1348 UPDATE_INT_ATTRIBUTES(auto_list_thread);
1349 break;
1350
1351 case OPT_AUTO_SAVE:
1352 if (prompt_option_on_off(option))
1353 UPDATE_INT_ATTRIBUTES(auto_save);
1354 break;
1355
1356 case OPT_BATCH_SAVE:
1357 if (prompt_option_on_off(option))
1358 UPDATE_INT_ATTRIBUTES(batch_save);
1359 break;
1360
1361 #ifdef HAVE_COLOR
1362 case OPT_EXTQUOTE_HANDLING:
1363 /*
1364 * option toggles visibility of other
1365 * options -> needs redraw_screen()
1366 */
1367 if (prompt_option_on_off(option)) {
1368 UPDATE_INT_ATTRIBUTES(extquote_handling);
1369 set_last_option_on_screen(first_option_on_screen);
1370 redraw_screen(option);
1371 changed |= DISPLAY_OPTS;
1372 }
1373 break;
1374 #endif /* HAVE_COLOR */
1375
1376 case OPT_GROUP_CATCHUP_ON_EXIT:
1377 if (prompt_option_on_off(option))
1378 UPDATE_INT_ATTRIBUTES(group_catchup_on_exit);
1379 break;
1380
1381 case OPT_MARK_IGNORE_TAGS:
1382 if (prompt_option_on_off(option))
1383 UPDATE_INT_ATTRIBUTES(mark_ignore_tags);
1384 break;
1385
1386 case OPT_MARK_SAVED_READ:
1387 if (prompt_option_on_off(option))
1388 UPDATE_INT_ATTRIBUTES(mark_saved_read);
1389 break;
1390
1391 case OPT_POST_PROCESS_VIEW:
1392 if (prompt_option_on_off(option))
1393 UPDATE_INT_ATTRIBUTES(post_process_view);
1394 break;
1395
1396 case OPT_POS_FIRST_UNREAD:
1397 if (prompt_option_on_off(option))
1398 UPDATE_INT_ATTRIBUTES(pos_first_unread);
1399 break;
1400
1401 #ifndef DISABLE_PRINTING
1402 case OPT_PRINT_HEADER:
1403 if (prompt_option_on_off(option))
1404 UPDATE_INT_ATTRIBUTES(print_header);
1405 break;
1406 #endif /* !DISABLE_PRINTING */
1407
1408 case OPT_PROCESS_ONLY_UNREAD:
1409 if (prompt_option_on_off(option))
1410 UPDATE_INT_ATTRIBUTES(process_only_unread);
1411 break;
1412
1413 case OPT_PROMPT_FOLLOWUPTO:
1414 if (prompt_option_on_off(option))
1415 UPDATE_INT_ATTRIBUTES(prompt_followupto);
1416 break;
1417
1418 case OPT_SHOW_SIGNATURES:
1419 if (prompt_option_on_off(option))
1420 UPDATE_INT_ATTRIBUTES(show_signatures);
1421 break;
1422
1423 case OPT_SIGDASHES:
1424 if (prompt_option_on_off(option))
1425 UPDATE_INT_ATTRIBUTES(sigdashes);
1426 break;
1427
1428 case OPT_SIGNATURE_REPOST:
1429 if (prompt_option_on_off(option))
1430 UPDATE_INT_ATTRIBUTES(signature_repost);
1431 break;
1432
1433 case OPT_START_EDITOR_OFFSET:
1434 if (prompt_option_on_off(option))
1435 UPDATE_INT_ATTRIBUTES(start_editor_offset);
1436 break;
1437
1438 #ifndef USE_CURSES
1439 case OPT_STRIP_BLANKS:
1440 if (prompt_option_on_off(option)) {
1441 redraw_screen(option);
1442 changed |= MISC_OPTS;
1443 }
1444 break;
1445 #endif /* !USE_CURSES */
1446
1447 case OPT_TEX2ISO_CONV:
1448 if (prompt_option_on_off(option))
1449 UPDATE_INT_ATTRIBUTES(tex2iso_conv);
1450 break;
1451
1452 case OPT_THREAD_CATCHUP_ON_EXIT:
1453 if (prompt_option_on_off(option))
1454 UPDATE_INT_ATTRIBUTES(thread_catchup_on_exit);
1455 break;
1456
1457 case OPT_WRAP_ON_NEXT_UNREAD:
1458 if (prompt_option_on_off(option))
1459 UPDATE_INT_ATTRIBUTES(wrap_on_next_unread);
1460 break;
1461
1462 case OPT_VERBATIM_HANDLING:
1463 /*
1464 * option toggles visibility of other
1465 * options -> needs redraw_screen()
1466 */
1467 if (prompt_option_on_off(option)) {
1468 UPDATE_INT_ATTRIBUTES(verbatim_handling);
1469 set_last_option_on_screen(first_option_on_screen);
1470 redraw_screen(option);
1471 }
1472 break;
1473
1474 /* show mini help menu */
1475 case OPT_BEGINNER_LEVEL:
1476 if (prompt_option_on_off(option)) {
1477 set_noteslines(cLINES);
1478 changed |= MISC_OPTS;
1479 }
1480 break;
1481
1482 /* show all arts or just new/unread arts */
1483 case OPT_SHOW_ONLY_UNREAD_ARTS:
1484 if (prompt_option_on_off(option)) {
1485 UPDATE_INT_ATTRIBUTES(show_only_unread_arts);
1486 changed |= SHOW_ONLY_UNREAD;
1487 }
1488 break;
1489
1490 /* draw -> / highlighted bar */
1491 case OPT_DRAW_ARROW:
1492 if (prompt_option_on_off(option)) {
1493 unhighlight_option(option);
1494 if (!tinrc.draw_arrow && !tinrc.inverse_okay) {
1495 tinrc.inverse_okay = TRUE;
1496 repaint_option(OPT_INVERSE_OKAY);
1497 center_line(0, TRUE, _(txt_options_menu));
1498 }
1499 changed |= MISC_OPTS;
1500 }
1501 break;
1502
1503 /* draw inversed screen header lines */
1504 /* draw inversed group/article/option line if draw_arrow is OFF */
1505 case OPT_INVERSE_OKAY:
1506 if (prompt_option_on_off(option)) {
1507 unhighlight_option(option);
1508 if (!tinrc.draw_arrow && !tinrc.inverse_okay) {
1509 tinrc.draw_arrow = TRUE; /* we don't want to navigate blindly */
1510 repaint_option(OPT_DRAW_ARROW);
1511 }
1512 center_line(0, TRUE, _(txt_options_menu));
1513 changed |= MISC_OPTS;
1514 }
1515 break;
1516
1517 case OPT_MAIL_8BIT_HEADER:
1518 if (prompt_option_on_off(option)) {
1519 if (tinrc.mail_mime_encoding != MIME_ENCODING_8BIT) {
1520 tinrc.mail_8bit_header = FALSE;
1521 print_any_option(OPT_MAIL_8BIT_HEADER);
1522 }
1523 UPDATE_INT_ATTRIBUTES(mail_8bit_header);
1524 }
1525 break;
1526
1527 case OPT_POST_8BIT_HEADER:
1528 if (prompt_option_on_off(option)) {
1529 /* if post_mime_encoding != 8bit, post_8bit_header is disabled */
1530 if (tinrc.post_mime_encoding != MIME_ENCODING_8BIT) {
1531 tinrc.post_8bit_header = FALSE;
1532 print_any_option(OPT_POST_8BIT_HEADER);
1533 }
1534 UPDATE_INT_ATTRIBUTES(post_8bit_header);
1535 }
1536 break;
1537
1538 /* show newsgroup description text next to newsgroups */
1539 case OPT_SHOW_DESCRIPTION:
1540 if (prompt_option_on_off(option)) {
1541 show_description = tinrc.show_description;
1542 if (show_description) /* force reread of newgroups file */
1543 read_descriptions(FALSE);
1544 changed |= MISC_OPTS;
1545 }
1546 break;
1547
1548 #ifdef HAVE_COLOR
1549 /* use ANSI color */
1550 case OPT_USE_COLOR:
1551 if (prompt_option_on_off(option)) {
1552 # ifdef USE_CURSES
1553 if (!has_colors())
1554 use_color = FALSE;
1555 else
1556 # endif /* USE_CURSES */
1557 use_color = tinrc.use_color;
1558 set_last_option_on_screen(first_option_on_screen);
1559 redraw_screen(option);
1560 changed |= MISC_OPTS;
1561 }
1562 break;
1563 #endif /* HAVE_COLOR */
1564
1565 #ifdef XFACE_ABLE
1566 /* use slrnface */
1567 case OPT_USE_SLRNFACE:
1568 if (prompt_option_on_off(option)) {
1569 if (!tinrc.use_slrnface)
1570 slrnface_stop();
1571 else
1572 slrnface_start();
1573 changed |= MISC_OPTS;
1574 }
1575 break;
1576 #endif /* XFACE_ABLE */
1577
1578 /* word_highlight */
1579 case OPT_WORD_HIGHLIGHT:
1580 if (prompt_option_on_off(option)) {
1581 word_highlight = tinrc.word_highlight;
1582 set_last_option_on_screen(first_option_on_screen);
1583 redraw_screen(option);
1584 changed |= MISC_OPTS;
1585 }
1586 break;
1587
1588 #if defined(HAVE_LIBICUUC) && defined(MULTIBYTE_ABLE) && defined(HAVE_UNICODE_UBIDI_H) && !defined(NO_LOCALE)
1589 case OPT_RENDER_BIDI:
1590 if (prompt_option_on_off(option))
1591 changed |= MISC_OPTS;
1592 break;
1593 #endif /* HAVE_LIBICUUC && MULTIBYTE_ABLE && HAVE_UNICODE_UBIDI_H && !NO_LOCALE */
1594
1595 case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
1596 if (prompt_option_on_off(option))
1597 SET_NUM_ATTRIBUTE(add_posted_to_filter);
1598 break;
1599
1600 case OPT_ATTRIB_ADVERTISING:
1601 if (prompt_option_on_off(option))
1602 SET_NUM_ATTRIBUTE(advertising);
1603 break;
1604
1605 case OPT_ATTRIB_ALTERNATIVE_HANDLING:
1606 if (prompt_option_on_off(option))
1607 SET_NUM_ATTRIBUTE(alternative_handling);
1608 break;
1609
1610 case OPT_ATTRIB_ASK_FOR_METAMAIL:
1611 if (prompt_option_on_off(option))
1612 SET_NUM_ATTRIBUTE(ask_for_metamail);
1613 break;
1614
1615 case OPT_ATTRIB_AUTO_LIST_THREAD:
1616 if (prompt_option_on_off(option))
1617 SET_NUM_ATTRIBUTE(auto_list_thread);
1618 break;
1619
1620 case OPT_ATTRIB_AUTO_SAVE:
1621 if (prompt_option_on_off(option))
1622 SET_NUM_ATTRIBUTE(auto_save);
1623 break;
1624
1625 case OPT_ATTRIB_AUTO_SELECT:
1626 if (prompt_option_on_off(option))
1627 SET_NUM_ATTRIBUTE(auto_select);
1628 break;
1629
1630 case OPT_ATTRIB_BATCH_SAVE:
1631 if (prompt_option_on_off(option))
1632 SET_NUM_ATTRIBUTE(batch_save);
1633 break;
1634
1635 case OPT_ATTRIB_DELETE_TMP_FILES:
1636 if (prompt_option_on_off(option))
1637 SET_NUM_ATTRIBUTE(delete_tmp_files);
1638 break;
1639
1640 #ifdef HAVE_COLOR
1641 case OPT_ATTRIB_EXTQUOTE_HANDLING:
1642 if (prompt_option_on_off(option))
1643 SET_NUM_ATTRIBUTE(extquote_handling);
1644 break;
1645 #endif /* HAVE_COLOR */
1646
1647 case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
1648 if (prompt_option_on_off(option))
1649 SET_NUM_ATTRIBUTE(group_catchup_on_exit);
1650 break;
1651
1652 case OPT_ATTRIB_MAIL_8BIT_HEADER:
1653 if (prompt_option_on_off(option))
1654 SET_NUM_ATTRIBUTE(mail_8bit_header);
1655 break;
1656
1657 case OPT_ATTRIB_MARK_IGNORE_TAGS:
1658 if (prompt_option_on_off(option))
1659 SET_NUM_ATTRIBUTE(mark_ignore_tags);
1660 break;
1661
1662 case OPT_ATTRIB_MARK_SAVED_READ:
1663 if (prompt_option_on_off(option))
1664 SET_NUM_ATTRIBUTE(mark_saved_read);
1665 break;
1666
1667 case OPT_ATTRIB_MIME_FORWARD:
1668 if (prompt_option_on_off(option))
1669 SET_NUM_ATTRIBUTE(mime_forward);
1670 break;
1671
1672 case OPT_ATTRIB_POST_8BIT_HEADER:
1673 if (prompt_option_on_off(option))
1674 SET_NUM_ATTRIBUTE(post_8bit_header);
1675 break;
1676
1677 case OPT_ATTRIB_POST_PROCESS_VIEW:
1678 if (prompt_option_on_off(option))
1679 SET_NUM_ATTRIBUTE(post_process_view);
1680 break;
1681
1682 case OPT_ATTRIB_POS_FIRST_UNREAD:
1683 if (prompt_option_on_off(option))
1684 SET_NUM_ATTRIBUTE(pos_first_unread);
1685 break;
1686
1687 #ifndef DISABLE_PRINTING
1688 case OPT_ATTRIB_PRINT_HEADER:
1689 if (prompt_option_on_off(option))
1690 SET_NUM_ATTRIBUTE(print_header);
1691 break;
1692 #endif /* !DISABLE_PRINTING */
1693
1694 case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
1695 if (prompt_option_on_off(option))
1696 SET_NUM_ATTRIBUTE(process_only_unread);
1697 break;
1698
1699 case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
1700 if (prompt_option_on_off(option))
1701 SET_NUM_ATTRIBUTE(prompt_followupto);
1702 break;
1703
1704 case OPT_ATTRIB_QUICK_KILL_CASE:
1705 if (prompt_option_on_off(option))
1706 SET_NUM_ATTRIBUTE(quick_kill_case);
1707 break;
1708
1709 case OPT_ATTRIB_QUICK_KILL_EXPIRE:
1710 if (prompt_option_on_off(option))
1711 SET_NUM_ATTRIBUTE(quick_kill_expire);
1712 break;
1713
1714 case OPT_ATTRIB_QUICK_SELECT_CASE:
1715 if (prompt_option_on_off(option))
1716 SET_NUM_ATTRIBUTE(quick_select_case);
1717 break;
1718
1719 case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
1720 if (prompt_option_on_off(option))
1721 SET_NUM_ATTRIBUTE(quick_select_expire);
1722 break;
1723
1724 case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
1725 if (prompt_option_on_off(option)) {
1726 SET_NUM_ATTRIBUTE(show_only_unread_arts);
1727 changed |= SHOW_ONLY_UNREAD;
1728 }
1729 break;
1730
1731 case OPT_ATTRIB_SHOW_SIGNATURES:
1732 if (prompt_option_on_off(option))
1733 SET_NUM_ATTRIBUTE(show_signatures);
1734 break;
1735
1736 case OPT_ATTRIB_SIGDASHES:
1737 if (prompt_option_on_off(option))
1738 SET_NUM_ATTRIBUTE(sigdashes);
1739 break;
1740
1741 case OPT_ATTRIB_SIGNATURE_REPOST:
1742 if (prompt_option_on_off(option))
1743 SET_NUM_ATTRIBUTE(signature_repost);
1744 break;
1745
1746 case OPT_ATTRIB_START_EDITOR_OFFSET:
1747 if (prompt_option_on_off(option))
1748 SET_NUM_ATTRIBUTE(start_editor_offset);
1749 break;
1750
1751 case OPT_ATTRIB_TEX2ISO_CONV:
1752 if (prompt_option_on_off(option))
1753 SET_NUM_ATTRIBUTE(tex2iso_conv);
1754 break;
1755
1756 case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
1757 if (prompt_option_on_off(option))
1758 SET_NUM_ATTRIBUTE(thread_catchup_on_exit);
1759 break;
1760
1761 case OPT_ATTRIB_VERBATIM_HANDLING:
1762 if (prompt_option_on_off(option))
1763 SET_NUM_ATTRIBUTE(verbatim_handling);
1764 break;
1765
1766 case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
1767 if (prompt_option_on_off(option))
1768 SET_NUM_ATTRIBUTE(wrap_on_next_unread);
1769 break;
1770
1771 case OPT_ATTRIB_X_COMMENT_TO:
1772 if (prompt_option_on_off(option))
1773 SET_NUM_ATTRIBUTE(x_comment_to);
1774 break;
1775
1776 default:
1777 break;
1778 } /* switch (option) */
1779 break;
1780
1781 case OPT_LIST:
1782 switch (option) {
1783 #ifdef USE_CANLOCK
1784 case OPT_CANCEL_LOCK_ALGO:
1785 #endif /* USE_CANLOCK */
1786 #ifdef HAVE_COLOR
1787 case OPT_COL_FROM:
1788 case OPT_COL_HEAD:
1789 case OPT_COL_HELP:
1790 case OPT_COL_INVERS_BG:
1791 case OPT_COL_INVERS_FG:
1792 case OPT_COL_MESSAGE:
1793 case OPT_COL_MINIHELP:
1794 case OPT_COL_NEWSHEADERS:
1795 case OPT_COL_QUOTE:
1796 case OPT_COL_QUOTE2:
1797 case OPT_COL_QUOTE3:
1798 case OPT_COL_EXTQUOTE:
1799 case OPT_COL_RESPONSE:
1800 case OPT_COL_SIGNATURE:
1801 case OPT_COL_SUBJECT:
1802 case OPT_COL_TEXT:
1803 case OPT_COL_TITLE:
1804 case OPT_COL_MARKSTAR:
1805 case OPT_COL_MARKDASH:
1806 case OPT_COL_MARKSLASH:
1807 case OPT_COL_MARKSTROKE:
1808 case OPT_COL_URLS:
1809 case OPT_COL_VERBATIM:
1810 #endif /* HAVE_COLOR */
1811 case OPT_CONFIRM_CHOICE:
1812 case OPT_GOTO_NEXT_UNREAD:
1813 case OPT_HIDE_UUE:
1814 case OPT_INTERACTIVE_MAILER:
1815 case OPT_KILL_LEVEL:
1816 case OPT_MAILBOX_FORMAT:
1817 case OPT_MONO_MARKDASH:
1818 case OPT_MONO_MARKSLASH:
1819 case OPT_MONO_MARKSTAR:
1820 case OPT_MONO_MARKSTROKE:
1821 #ifdef HAVE_UNICODE_NORMALIZATION
1822 case OPT_NORMALIZATION_FORM:
1823 #endif /* HAVE_UNICODE_NORMALIZATION */
1824 case OPT_QUOTE_STYLE:
1825 case OPT_STRIP_BOGUS:
1826 case OPT_WILDCARD:
1827 case OPT_WORD_H_DISPLAY_MARKS:
1828 #ifdef USE_HEAPSORT
1829 case OPT_SORT_FUNCTION:
1830 #endif /* USE_HEAPSORT */
1831 if (prompt_option_list(option))
1832 changed |= MISC_OPTS;
1833 break;
1834
1835 #ifdef HAVE_COLOR
1836 case OPT_COL_BACK:
1837 case OPT_COL_NORMAL:
1838 if (prompt_option_list(option)) {
1839 redraw_screen(option);
1840 changed |= MISC_OPTS;
1841 }
1842 break;
1843 #endif /* HAVE_COLOR */
1844
1845 case OPT_AUTO_CC_BCC:
1846 if (prompt_option_list(option))
1847 UPDATE_INT_ATTRIBUTES(auto_cc_bcc);
1848 break;
1849
1850 case OPT_THREAD_ARTICLES:
1851 if (prompt_option_list(option)) {
1852 UPDATE_INT_ATTRIBUTES(thread_articles);
1853 changed |= THREAD_ARTS;
1854 }
1855 break;
1856
1857 case OPT_SORT_ARTICLE_TYPE:
1858 if (prompt_option_list(option)) {
1859 UPDATE_INT_ATTRIBUTES(sort_article_type);
1860 changed |= SORT_OPTS;
1861 }
1862 break;
1863
1864 case OPT_SORT_THREADS_TYPE:
1865 if (prompt_option_list(option)) {
1866 UPDATE_INT_ATTRIBUTES(sort_threads_type);
1867 changed |= SORT_OPTS;
1868 }
1869 break;
1870
1871 case OPT_THREAD_SCORE:
1872 if (prompt_option_list(option))
1873 changed |= THREAD_SCORE;
1874 break;
1875
1876 case OPT_TRIM_ARTICLE_BODY:
1877 if (prompt_option_list(option))
1878 UPDATE_INT_ATTRIBUTES(trim_article_body);
1879 break;
1880
1881 case OPT_POST_PROCESS_TYPE:
1882 if (prompt_option_list(option))
1883 UPDATE_INT_ATTRIBUTES(post_process_type);
1884 break;
1885
1886 case OPT_SHOW_AUTHOR:
1887 if (prompt_option_list(option)) {
1888 UPDATE_INT_ATTRIBUTES(show_author);
1889 changed |= SHOW_AUTHOR;
1890 }
1891 break;
1892
1893 case OPT_MAIL_MIME_ENCODING:
1894 if (prompt_option_list(option)) {
1895 #ifdef CHARSET_CONVERSION
1896 /*
1897 * check if we have selected a !7bit encoding but a 7bit network charset
1898 * or a !8bit encoding but a 8bit network charset, update encoding if needed
1899 */
1900 is_7bit = FALSE;
1901 for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
1902 if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
1903 is_7bit = TRUE;
1904 break;
1905 }
1906 }
1907 if (is_7bit) {
1908 if (tinrc.mail_mime_encoding != MIME_ENCODING_7BIT) {
1909 tinrc.mail_mime_encoding = MIME_ENCODING_7BIT;
1910 repaint_option(OPT_MAIL_MIME_ENCODING);
1911 }
1912 } else {
1913 if (tinrc.mail_mime_encoding == MIME_ENCODING_7BIT) {
1914 tinrc.mail_mime_encoding = MIME_ENCODING_QP;
1915 repaint_option(OPT_MAIL_MIME_ENCODING);
1916 }
1917 }
1918 #endif /* CHARSET_CONVERSION */
1919 UPDATE_INT_ATTRIBUTES(mail_mime_encoding);
1920 /* do not use 8 bit headers if mime encoding is not 8bit */
1921 if (tinrc.mail_mime_encoding != MIME_ENCODING_8BIT) {
1922 tinrc.mail_8bit_header = FALSE;
1923 repaint_option(OPT_MAIL_8BIT_HEADER);
1924 UPDATE_INT_ATTRIBUTES(mail_8bit_header);
1925 }
1926 }
1927 break;
1928
1929 case OPT_POST_MIME_ENCODING:
1930 if (prompt_option_list(option)) {
1931 #ifdef CHARSET_CONVERSION
1932 /*
1933 * check if we have selected a !7bit encoding but a 7bit network charset
1934 * or a !8bit encoding but a 8bit network charset, update encoding if needed
1935 */
1936 is_7bit = FALSE;
1937 for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
1938 if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
1939 is_7bit = TRUE;
1940 break;
1941 }
1942 }
1943 if (is_7bit) {
1944 if (tinrc.post_mime_encoding != MIME_ENCODING_7BIT) {
1945 tinrc.post_mime_encoding = MIME_ENCODING_7BIT;
1946 repaint_option(OPT_POST_MIME_ENCODING);
1947 }
1948 } else {
1949 if (tinrc.post_mime_encoding == MIME_ENCODING_7BIT) {
1950 tinrc.post_mime_encoding = MIME_ENCODING_8BIT;
1951 repaint_option(OPT_POST_MIME_ENCODING);
1952 }
1953 }
1954 #endif /* CHARSET_CONVERSION */
1955 UPDATE_INT_ATTRIBUTES(post_mime_encoding);
1956 /* do not use 8 bit headers if mime encoding is not 8bit */
1957 if (tinrc.post_mime_encoding != MIME_ENCODING_8BIT) {
1958 tinrc.post_8bit_header = FALSE;
1959 repaint_option(OPT_POST_8BIT_HEADER);
1960 UPDATE_INT_ATTRIBUTES(post_8bit_header);
1961 }
1962 }
1963 break;
1964
1965 #ifdef CHARSET_CONVERSION
1966 case OPT_MM_NETWORK_CHARSET:
1967 if (prompt_option_list(option)) {
1968 /*
1969 * check if we have selected a 7bit charset but a !7bit encoding
1970 * or a 8bit charset but a !8bit encoding, update encoding if needed
1971 *
1972 * if (mail|post)_mime_encoding != 8bit, disable (mail|post)_8bit_header
1973 */
1974 is_7bit = FALSE;
1975 UPDATE_INT_ATTRIBUTES(mm_network_charset);
1976 for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
1977 if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
1978 is_7bit = TRUE;
1979 break;
1980 }
1981 }
1982 if (is_7bit) {
1983 if (tinrc.mail_mime_encoding != MIME_ENCODING_7BIT) {
1984 tinrc.mail_mime_encoding = MIME_ENCODING_7BIT;
1985 tinrc.mail_8bit_header = FALSE;
1986 repaint_option(OPT_MAIL_MIME_ENCODING);
1987 repaint_option(OPT_MAIL_8BIT_HEADER);
1988 UPDATE_INT_ATTRIBUTES(mail_mime_encoding);
1989 UPDATE_INT_ATTRIBUTES(mail_8bit_header);
1990 }
1991 if (tinrc.post_mime_encoding != MIME_ENCODING_7BIT) {
1992 tinrc.post_mime_encoding = MIME_ENCODING_7BIT;
1993 tinrc.post_8bit_header = FALSE;
1994 repaint_option(OPT_POST_MIME_ENCODING);
1995 repaint_option(OPT_POST_8BIT_HEADER);
1996 UPDATE_INT_ATTRIBUTES(post_mime_encoding);
1997 UPDATE_INT_ATTRIBUTES(post_8bit_header);
1998 }
1999 } else {
2000 if (tinrc.mail_mime_encoding == MIME_ENCODING_7BIT) {
2001 tinrc.mail_mime_encoding = MIME_ENCODING_QP;
2002 repaint_option(OPT_MAIL_MIME_ENCODING);
2003 UPDATE_INT_ATTRIBUTES(mail_mime_encoding);
2004 }
2005 if (tinrc.post_mime_encoding == MIME_ENCODING_7BIT) {
2006 tinrc.post_mime_encoding = MIME_ENCODING_8BIT;
2007 repaint_option(OPT_POST_MIME_ENCODING);
2008 UPDATE_INT_ATTRIBUTES(post_mime_encoding);
2009 }
2010 }
2011 }
2012 break;
2013 #endif /* CHARSET_CONVERSION */
2014
2015 case OPT_ATTRIB_AUTO_CC_BCC:
2016 if (prompt_option_list(option))
2017 SET_NUM_ATTRIBUTE(auto_cc_bcc);
2018 break;
2019
2020 case OPT_ATTRIB_MAIL_MIME_ENCODING:
2021 if (prompt_option_list(option))
2022 SET_NUM_ATTRIBUTE(mail_mime_encoding);
2023 break;
2024
2025 #ifdef CHARSET_CONVERSION
2026 case OPT_ATTRIB_MM_NETWORK_CHARSET:
2027 if (prompt_option_list(option))
2028 SET_NUM_ATTRIBUTE(mm_network_charset);
2029 break;
2030 #endif /* CHARSET_CONVERSION */
2031
2032 case OPT_ATTRIB_POST_MIME_ENCODING:
2033 if (prompt_option_list(option))
2034 SET_NUM_ATTRIBUTE(post_mime_encoding);
2035 break;
2036
2037 case OPT_ATTRIB_POST_PROCESS_TYPE:
2038 if (prompt_option_list(option))
2039 SET_NUM_ATTRIBUTE(post_process_type);
2040 break;
2041
2042 case OPT_ATTRIB_QUICK_KILL_HEADER:
2043 if (prompt_option_list(option))
2044 SET_NUM_ATTRIBUTE(quick_kill_header);
2045 break;
2046
2047 case OPT_ATTRIB_QUICK_SELECT_HEADER:
2048 if (prompt_option_list(option))
2049 SET_NUM_ATTRIBUTE(quick_select_header);
2050 break;
2051
2052 case OPT_ATTRIB_SHOW_AUTHOR:
2053 if (prompt_option_list(option)) {
2054 SET_NUM_ATTRIBUTE(show_author);
2055 changed |= SHOW_AUTHOR;
2056 }
2057 break;
2058
2059 case OPT_ATTRIB_SORT_ARTICLE_TYPE:
2060 if (prompt_option_list(option)) {
2061 SET_NUM_ATTRIBUTE(sort_article_type);
2062 changed |= SORT_OPTS;
2063 }
2064 break;
2065
2066 case OPT_ATTRIB_SORT_THREADS_TYPE:
2067 if (prompt_option_list(option)) {
2068 SET_NUM_ATTRIBUTE(sort_threads_type);
2069 changed |= SORT_OPTS;
2070 }
2071 break;
2072
2073 case OPT_ATTRIB_THREAD_ARTICLES:
2074 if (prompt_option_list(option)) {
2075 SET_NUM_ATTRIBUTE(thread_articles);
2076 changed |= THREAD_ARTS;
2077 }
2078 break;
2079
2080 case OPT_ATTRIB_TRIM_ARTICLE_BODY:
2081 if (prompt_option_list(option))
2082 SET_NUM_ATTRIBUTE(trim_article_body);
2083 break;
2084
2085 default:
2086 break;
2087 } /* switch (option) */
2088 break;
2089
2090 case OPT_STRING:
2091 switch (option) {
2092 case OPT_INEWS_PROG:
2093 case OPT_MAILDIR:
2094 case OPT_MAILER_FORMAT:
2095 case OPT_MAIL_ADDRESS:
2096 case OPT_MAIL_QUOTE_FORMAT:
2097 case OPT_METAMAIL_PROG:
2098 case OPT_NEWS_QUOTE_FORMAT:
2099 case OPT_SAVEDIR:
2100 case OPT_SIGFILE:
2101 #ifndef DISABLE_PRINTING
2102 case OPT_PRINTER:
2103 #endif /* !DISABLE_PRINTING */
2104 case OPT_QUOTE_CHARS:
2105 case OPT_SPAMTRAP_WARNING_ADDRESSES:
2106 case OPT_URL_HANDLER:
2107 case OPT_XPOST_QUOTE_FORMAT:
2108 if (prompt_option_string(option))
2109 changed |= MISC_OPTS;
2110 break;
2111
2112 case OPT_EDITOR_FORMAT:
2113 if (prompt_option_string(option)) {
2114 if (!strlen(tinrc.editor_format))
2115 STRCPY(tinrc.editor_format, TIN_EDITOR_FMT_ON);
2116 changed |= MISC_OPTS;
2117 }
2118 break;
2119
2120 case OPT_GROUP_FORMAT:
2121 if (prompt_option_string(option)) {
2122 if (!strlen(tinrc.group_format))
2123 STRCPY(tinrc.group_format, DEFAULT_GROUP_FORMAT);
2124 changed |= MISC_OPTS;
2125 }
2126 break;
2127
2128 case OPT_ATTRIB_GROUP_FORMAT:
2129 if (prompt_option_string(option))
2130 SET_STRING_ATTRIBUTE(group_format);
2131 break;
2132
2133 #ifndef CHARSET_CONVERSION
2134 case OPT_MM_CHARSET:
2135 if (prompt_option_string(option)) {
2136 /*
2137 * No charset conversion available, assume local charset
2138 * to be network charset.
2139 */
2140 STRCPY(tinrc.mm_local_charset, tinrc.mm_charset);
2141 changed |= MISC_OPTS;
2142 }
2143 break;
2144 #else
2145 # ifdef NO_LOCALE
2146 case OPT_MM_LOCAL_CHARSET:
2147 if (prompt_option_string(option))
2148 /* no locales -> can't guess local charset */
2149 changed |= MISC_OPTS;
2150 break;
2151
2152 # endif /* NO_LOCALE */
2153 #endif /* !CHARSET_CONVERSION */
2154
2155 case OPT_NEWS_HEADERS_TO_DISPLAY:
2156 if (prompt_option_string(option)) {
2157 build_news_headers_array(scopes[0].attribute, TRUE);
2158 changed |= MISC_OPTS;
2159 }
2160 break;
2161
2162 case OPT_NEWS_HEADERS_TO_NOT_DISPLAY:
2163 if (prompt_option_string(option)) {
2164 build_news_headers_array(scopes[0].attribute, FALSE);
2165 changed |= MISC_OPTS;
2166 }
2167 break;
2168
2169 case OPT_POSTED_ARTICLES_FILE:
2170 if (prompt_option_string(option)) /* no expansion here, will be done in post_loop() */
2171 changed |= MISC_OPTS;
2172 break;
2173
2174 #ifdef HAVE_COLOR
2175 case OPT_QUOTE_REGEX:
2176 if (prompt_option_string(option)) {
2177 FreeIfNeeded(quote_regex.re);
2178 FreeIfNeeded(quote_regex.extra);
2179 if (!strlen(tinrc.quote_regex))
2180 STRCPY(tinrc.quote_regex, DEFAULT_QUOTE_REGEX);
2181 compile_regex(tinrc.quote_regex, "e_regex, PCRE_CASELESS);
2182 changed |= DISPLAY_OPTS;
2183 }
2184 break;
2185
2186 case OPT_QUOTE_REGEX2:
2187 if (prompt_option_string(option)) {
2188 FreeIfNeeded(quote_regex2.re);
2189 FreeIfNeeded(quote_regex2.extra);
2190 if (!strlen(tinrc.quote_regex2))
2191 STRCPY(tinrc.quote_regex2, DEFAULT_QUOTE_REGEX2);
2192 compile_regex(tinrc.quote_regex2, "e_regex2, PCRE_CASELESS);
2193 changed |= DISPLAY_OPTS;
2194 }
2195 break;
2196
2197 case OPT_QUOTE_REGEX3:
2198 if (prompt_option_string(option)) {
2199 FreeIfNeeded(quote_regex3.re);
2200 FreeIfNeeded(quote_regex3.extra);
2201 if (!strlen(tinrc.quote_regex3))
2202 STRCPY(tinrc.quote_regex3, DEFAULT_QUOTE_REGEX3);
2203 compile_regex(tinrc.quote_regex3, "e_regex3, PCRE_CASELESS);
2204 changed |= DISPLAY_OPTS;
2205 }
2206 break;
2207
2208 case OPT_EXTQUOTE_REGEX:
2209 if (prompt_option_string(option)) {
2210 FreeIfNeeded(extquote_regex.re);
2211 FreeIfNeeded(extquote_regex.extra);
2212 if (!strlen(tinrc.extquote_regex))
2213 STRCPY(tinrc.extquote_regex, DEFAULT_EXTQUOTE_REGEX);
2214 compile_regex(tinrc.extquote_regex, &extquote_regex, PCRE_CASELESS);
2215 changed |= DISPLAY_OPTS;
2216 }
2217 break;
2218 #endif /* HAVE_COLOR */
2219
2220 case OPT_SELECT_FORMAT:
2221 if (prompt_option_string(option)) {
2222 if (!strlen(tinrc.select_format))
2223 STRCPY(tinrc.select_format, DEFAULT_SELECT_FORMAT);
2224 changed |= MISC_OPTS;
2225 }
2226 break;
2227
2228 case OPT_SLASHES_REGEX:
2229 if (prompt_option_string(option)) {
2230 FreeIfNeeded(slashes_regex.re);
2231 FreeIfNeeded(slashes_regex.extra);
2232 if (!strlen(tinrc.slashes_regex))
2233 STRCPY(tinrc.slashes_regex, DEFAULT_SLASHES_REGEX);
2234 compile_regex(tinrc.slashes_regex, &slashes_regex, PCRE_CASELESS);
2235 changed |= DISPLAY_OPTS;
2236 }
2237 break;
2238
2239 case OPT_STARS_REGEX:
2240 if (prompt_option_string(option)) {
2241 FreeIfNeeded(stars_regex.re);
2242 FreeIfNeeded(stars_regex.extra);
2243 if (!strlen(tinrc.stars_regex))
2244 STRCPY(tinrc.stars_regex, DEFAULT_STARS_REGEX);
2245 compile_regex(tinrc.stars_regex, &stars_regex, PCRE_CASELESS);
2246 changed |= DISPLAY_OPTS;
2247 }
2248 break;
2249
2250 case OPT_STROKES_REGEX:
2251 if (prompt_option_string(option)) {
2252 FreeIfNeeded(strokes_regex.re);
2253 FreeIfNeeded(strokes_regex.extra);
2254 if (!strlen(tinrc.strokes_regex))
2255 STRCPY(tinrc.strokes_regex, DEFAULT_STROKES_REGEX);
2256 compile_regex(tinrc.strokes_regex, &strokes_regex, PCRE_CASELESS);
2257 changed |= DISPLAY_OPTS;
2258 }
2259 break;
2260
2261 case OPT_UNDERSCORES_REGEX:
2262 if (prompt_option_string(option)) {
2263 FreeIfNeeded(underscores_regex.re);
2264 FreeIfNeeded(underscores_regex.extra);
2265 if (!strlen(tinrc.underscores_regex))
2266 STRCPY(tinrc.underscores_regex, DEFAULT_UNDERSCORES_REGEX);
2267 compile_regex(tinrc.underscores_regex, &underscores_regex, PCRE_CASELESS);
2268 changed |= DISPLAY_OPTS;
2269 }
2270 break;
2271
2272 case OPT_STRIP_RE_REGEX:
2273 if (prompt_option_string(option)) {
2274 FreeIfNeeded(strip_re_regex.re);
2275 FreeIfNeeded(strip_re_regex.extra);
2276 if (!strlen(tinrc.strip_re_regex))
2277 STRCPY(tinrc.strip_re_regex, DEFAULT_STRIP_RE_REGEX);
2278 compile_regex(tinrc.strip_re_regex, &strip_re_regex, PCRE_ANCHORED);
2279 changed |= MISC_OPTS;
2280 }
2281 break;
2282
2283 case OPT_STRIP_WAS_REGEX:
2284 if (prompt_option_string(option)) {
2285 FreeIfNeeded(strip_was_regex.re);
2286 FreeIfNeeded(strip_was_regex.extra);
2287 if (!strlen(tinrc.strip_was_regex)) {
2288 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
2289 if (IS_LOCAL_CHARSET("UTF-8") && utf8_pcre())
2290 STRCPY(tinrc.strip_was_regex, DEFAULT_U8_STRIP_WAS_REGEX);
2291 else
2292 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
2293 STRCPY(tinrc.strip_was_regex, DEFAULT_STRIP_WAS_REGEX);
2294 }
2295 compile_regex(tinrc.strip_was_regex, &strip_was_regex, 0);
2296 changed |= MISC_OPTS;
2297 }
2298 break;
2299
2300 case OPT_THREAD_FORMAT:
2301 if (prompt_option_string(option)) {
2302 if (!strlen(tinrc.thread_format))
2303 STRCPY(tinrc.thread_format, DEFAULT_THREAD_FORMAT);
2304 changed |= MISC_OPTS;
2305 }
2306 break;
2307
2308 case OPT_ATTRIB_THREAD_FORMAT:
2309 if (prompt_option_string(option))
2310 SET_STRING_ATTRIBUTE(thread_format);
2311 break;
2312
2313 case OPT_VERBATIM_BEGIN_REGEX:
2314 if (prompt_option_string(option)) {
2315 FreeIfNeeded(verbatim_begin_regex.re);
2316 FreeIfNeeded(verbatim_begin_regex.extra);
2317 if (!strlen(tinrc.verbatim_begin_regex))
2318 STRCPY(tinrc.verbatim_begin_regex, DEFAULT_VERBATIM_BEGIN_REGEX);
2319 compile_regex(tinrc.verbatim_begin_regex, &verbatim_begin_regex, PCRE_ANCHORED);
2320 changed |= DISPLAY_OPTS;
2321 }
2322 break;
2323
2324 case OPT_VERBATIM_END_REGEX:
2325 if (prompt_option_string(option)) {
2326 FreeIfNeeded(verbatim_end_regex.re);
2327 FreeIfNeeded(verbatim_end_regex.extra);
2328 if (!strlen(tinrc.verbatim_end_regex))
2329 STRCPY(tinrc.verbatim_end_regex, DEFAULT_VERBATIM_END_REGEX);
2330 compile_regex(tinrc.verbatim_end_regex, &verbatim_end_regex, PCRE_ANCHORED);
2331 changed |= DISPLAY_OPTS;
2332 }
2333 break;
2334
2335 case OPT_DATE_FORMAT:
2336 if (prompt_option_string(option)) {
2337 if (!strlen(tinrc.date_format))
2338 STRCPY(tinrc.date_format, DEFAULT_DATE_FORMAT);
2339 changed |= MISC_OPTS;
2340 }
2341 break;
2342
2343 case OPT_ATTRIB_DATE_FORMAT:
2344 if (prompt_option_string(option))
2345 SET_STRING_ATTRIBUTE(date_format);
2346 break;
2347
2348 case OPT_ATTRIB_EDITOR_FORMAT:
2349 if (prompt_option_string(option))
2350 SET_STRING_ATTRIBUTE(editor_format);
2351 break;
2352
2353 case OPT_ATTRIB_FCC:
2354 if (prompt_option_string(option))
2355 SET_STRING_ATTRIBUTE(fcc);
2356 break;
2357
2358 case OPT_ATTRIB_FOLLOWUP_TO:
2359 if (prompt_option_string(option))
2360 SET_STRING_ATTRIBUTE(followup_to);
2361 break;
2362
2363 case OPT_ATTRIB_FROM:
2364 if (prompt_option_string(option))
2365 SET_STRING_ATTRIBUTE(from);
2366 break;
2367
2368 #ifdef HAVE_ISPELL
2369 case OPT_ATTRIB_ISPELL:
2370 if (prompt_option_string(option))
2371 SET_STRING_ATTRIBUTE(ispell);
2372 break;
2373 #endif /* HAVE_ISPELL */
2374
2375 case OPT_ATTRIB_MAILDIR:
2376 if (prompt_option_string(option))
2377 SET_STRING_ATTRIBUTE(maildir);
2378 break;
2379
2380 case OPT_ATTRIB_MAILING_LIST:
2381 if (prompt_option_string(option))
2382 SET_STRING_ATTRIBUTE(mailing_list);
2383 break;
2384
2385 case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
2386 if (prompt_option_string(option))
2387 SET_STRING_ATTRIBUTE(mime_types_to_save);
2388 break;
2389
2390 case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
2391 if (prompt_option_string(option)) {
2392 SET_STRING_ATTRIBUTE(news_headers_to_display);
2393 build_news_headers_array(curr_scope->attribute, TRUE);
2394 changed |= DISPLAY_OPTS;
2395 }
2396 break;
2397
2398 case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
2399 if (prompt_option_string(option)) {
2400 SET_STRING_ATTRIBUTE(news_headers_to_not_display);
2401 build_news_headers_array(curr_scope->attribute, FALSE);
2402 changed |= DISPLAY_OPTS;
2403 }
2404 break;
2405
2406 case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
2407 if (prompt_option_string(option))
2408 SET_STRING_ATTRIBUTE(news_quote_format);
2409 break;
2410
2411 case OPT_ATTRIB_ORGANIZATION:
2412 if (prompt_option_string(option))
2413 SET_STRING_ATTRIBUTE(organization);
2414 break;
2415
2416 case OPT_ATTRIB_QUICK_KILL_SCOPE:
2417 if (prompt_option_string(option))
2418 SET_STRING_ATTRIBUTE(quick_kill_scope);
2419 break;
2420
2421 case OPT_ATTRIB_QUICK_SELECT_SCOPE:
2422 if (prompt_option_string(option))
2423 SET_STRING_ATTRIBUTE(quick_select_scope);
2424 break;
2425
2426 case OPT_ATTRIB_QUOTE_CHARS:
2427 if (prompt_option_string(option))
2428 SET_STRING_ATTRIBUTE(quote_chars);
2429 break;
2430
2431 case OPT_ATTRIB_SAVEDIR:
2432 if (prompt_option_string(option))
2433 SET_STRING_ATTRIBUTE(savedir);
2434 break;
2435
2436 case OPT_ATTRIB_SAVEFILE:
2437 if (prompt_option_string(option))
2438 SET_STRING_ATTRIBUTE(savefile);
2439 break;
2440
2441 case OPT_ATTRIB_SIGFILE:
2442 if (prompt_option_string(option))
2443 SET_STRING_ATTRIBUTE(sigfile);
2444 break;
2445
2446 #ifdef CHARSET_CONVERSION
2447 case OPT_ATTRIB_UNDECLARED_CHARSET:
2448 if (prompt_option_string(option))
2449 SET_STRING_ATTRIBUTE(undeclared_charset);
2450 break;
2451
2452 #endif /* CHARSET_CONVERSION */
2453 case OPT_ATTRIB_X_BODY:
2454 if (prompt_option_string(option))
2455 SET_STRING_ATTRIBUTE(x_body);
2456 break;
2457
2458 case OPT_ATTRIB_X_HEADERS:
2459 if (prompt_option_string(option))
2460 SET_STRING_ATTRIBUTE(x_headers);
2461 break;
2462
2463 default:
2464 break;
2465 } /* switch (option) */
2466
2467 break;
2468
2469 case OPT_NUM:
2470 switch (option) {
2471 case OPT_GETART_LIMIT:
2472 case OPT_SCROLL_LINES:
2473 if (prompt_option_num(option))
2474 changed |= MISC_OPTS;
2475 break;
2476
2477 #if defined(HAVE_ALARM) && defined(SIGALRM)
2478 case OPT_NNTP_READ_TIMEOUT_SECS:
2479 if (prompt_option_num(option)) {
2480 if (tinrc.nntp_read_timeout_secs < 0)
2481 tinrc.nntp_read_timeout_secs = 0;
2482 changed |= MISC_OPTS;
2483 }
2484 break;
2485 #endif /* HAVE_ALARM && SIGALRM */
2486
2487 case OPT_REREAD_ACTIVE_FILE_SECS:
2488 if (prompt_option_num(option)) {
2489 if (tinrc.reread_active_file_secs < 0)
2490 tinrc.reread_active_file_secs = 0;
2491 changed |= MISC_OPTS;
2492 }
2493 break;
2494
2495 case OPT_RECENT_TIME:
2496 if (prompt_option_num(option)) {
2497 if (tinrc.recent_time < 0)
2498 tinrc.recent_time = 0;
2499 changed |= MISC_OPTS;
2500 }
2501 break;
2502
2503 case OPT_FILTER_DAYS:
2504 if (prompt_option_num(option)) {
2505 if (tinrc.filter_days <= 0)
2506 tinrc.filter_days = 1;
2507 changed |= MISC_OPTS;
2508 }
2509 break;
2510
2511 case OPT_SCORE_LIMIT_KILL:
2512 case OPT_SCORE_KILL:
2513 case OPT_SCORE_LIMIT_SELECT:
2514 case OPT_SCORE_SELECT:
2515 if (prompt_option_num(option)) {
2516 check_score_defaults();
2517 redraw_screen(option);
2518 changed |= SCORE_OPTS;
2519 }
2520 break;
2521
2522 case OPT_THREAD_PERC:
2523 if (prompt_option_num(option)) {
2524 if (tinrc.thread_perc < 0 || tinrc.thread_perc > 100)
2525 tinrc.thread_perc = THREAD_PERC_DEFAULT;
2526 UPDATE_INT_ATTRIBUTES(thread_perc);
2527 }
2528 break;
2529
2530 case OPT_WRAP_COLUMN:
2531 if (prompt_option_num(option))
2532 changed |= DISPLAY_OPTS;
2533 break;
2534
2535 case OPT_ATTRIB_THREAD_PERC:
2536 if (prompt_option_num(option))
2537 SET_NUM_ATTRIBUTE(thread_perc);
2538 break;
2539
2540 default:
2541 break;
2542 } /* switch (option) */
2543 break;
2544
2545 case OPT_CHAR:
2546 switch (option) {
2547 /*
2548 * TODO: do DASH_TO_SPACE/SPACE_TO_DASH conversion here?
2549 */
2550 case OPT_ART_MARKED_DELETED:
2551 case OPT_ART_MARKED_INRANGE:
2552 case OPT_ART_MARKED_RETURN:
2553 case OPT_ART_MARKED_SELECTED:
2554 case OPT_ART_MARKED_RECENT:
2555 case OPT_ART_MARKED_UNREAD:
2556 case OPT_ART_MARKED_READ:
2557 case OPT_ART_MARKED_KILLED:
2558 case OPT_ART_MARKED_READ_SELECTED:
2559 if (prompt_option_char(option))
2560 changed |= MISC_OPTS;
2561 break;
2562
2563 default:
2564 break;
2565 } /* switch (option) */
2566 break;
2567
2568 default:
2569 break;
2570 } /* switch (option_table[option].var_type) */
2571 change_option = FALSE;
2572 show_menu_help(txt_select_config_file_option);
2573 repaint_option(option);
2574 highlight_option(option);
2575 } /* if (change_option) */
2576 } /* forever */
2577 /* NOTREACHED */
2578 return;
2579 }
2580
2581
2582 /*
2583 * scopes and attributes menu
2584 */
2585
2586 static t_function
scope_left(void)2587 scope_left(
2588 void)
2589 {
2590 return GLOBAL_QUIT;
2591 }
2592
2593
2594 static t_function
scope_right(void)2595 scope_right(
2596 void)
2597 {
2598 return SCOPE_SELECT;
2599 }
2600
2601
2602 static void
show_scope_page(void)2603 show_scope_page(
2604 void)
2605 {
2606 int i;
2607
2608 signal_context = cScope;
2609 currmenu = &scopemenu;
2610 mark_offset = 0;
2611
2612 if (scopemenu.curr < 0)
2613 scopemenu.curr = 0;
2614
2615 scopemenu.max = num_scope - 1;
2616
2617 ClearScreen();
2618 set_first_screen_item();
2619 center_line(0, TRUE, _(txt_scopes_menu));
2620
2621 for (i = scopemenu.first; i < scopemenu.first + NOTESLINES && i < scopemenu.max; ++i)
2622 build_scope_line(i);
2623
2624 show_mini_help(SCOPE_LEVEL);
2625
2626 if (scopemenu.max <= 0) {
2627 info_message(_(txt_no_scopes));
2628 return;
2629 }
2630
2631 draw_scope_arrow();
2632 }
2633
2634
2635 static void
scope_page(enum context level)2636 scope_page(
2637 enum context level)
2638 {
2639 char key[MAXKEYLEN];
2640 int i;
2641 t_bool changed = FALSE;
2642 t_function func;
2643 t_menu *oldmenu = NULL;
2644
2645 if (currmenu)
2646 oldmenu = currmenu;
2647 scopemenu.curr = 0;
2648 clear_note_area();
2649 show_scope_page();
2650 set_xclick_off();
2651
2652 forever {
2653 switch ((func = handle_keypad(scope_left, scope_right, NULL, scope_keys))) {
2654 case GLOBAL_QUIT:
2655 if (changed)
2656 write_attributes_file(local_attributes_file);
2657 clear_note_area();
2658 if (oldmenu)
2659 currmenu = oldmenu;
2660 return;
2661
2662 case DIGIT_1:
2663 case DIGIT_2:
2664 case DIGIT_3:
2665 case DIGIT_4:
2666 case DIGIT_5:
2667 case DIGIT_6:
2668 case DIGIT_7:
2669 case DIGIT_8:
2670 case DIGIT_9:
2671 if (scopemenu.max)
2672 prompt_item_num(func_to_key(func, scope_keys), _(txt_scope_select));
2673 break;
2674
2675 #ifndef NO_SHELL_ESCAPE
2676 case GLOBAL_SHELL_ESCAPE:
2677 do_shell_escape();
2678 break;
2679 #endif /* !NO_SHELL_ESCAPE */
2680
2681 case GLOBAL_HELP:
2682 show_help_page(SCOPE_LEVEL, _(txt_scopes_menu_com));
2683 show_scope_page();
2684 break;
2685
2686 case GLOBAL_FIRST_PAGE:
2687 top_of_list();
2688 break;
2689
2690 case GLOBAL_LAST_PAGE:
2691 end_of_list();
2692 break;
2693
2694 case GLOBAL_REDRAW_SCREEN:
2695 my_retouch();
2696 set_xclick_off();
2697 show_scope_page();
2698 break;
2699
2700 case GLOBAL_LINE_DOWN:
2701 move_down();
2702 break;
2703
2704 case GLOBAL_LINE_UP:
2705 move_up();
2706 break;
2707
2708 case GLOBAL_PAGE_DOWN:
2709 page_down();
2710 break;
2711
2712 case GLOBAL_PAGE_UP:
2713 page_up();
2714 break;
2715
2716 case GLOBAL_SCROLL_DOWN:
2717 scroll_down();
2718 break;
2719
2720 case GLOBAL_SCROLL_UP:
2721 scroll_up();
2722 break;
2723
2724 case GLOBAL_TOGGLE_HELP_DISPLAY:
2725 toggle_mini_help(SCOPE_LEVEL);
2726 show_scope_page();
2727 break;
2728
2729 case SCOPE_ADD:
2730 if ((i = add_new_scope())) {
2731 changed = TRUE;
2732 scopemenu.curr = i;
2733 show_scope_page();
2734 }
2735 break;
2736
2737 case SCOPE_DELETE:
2738 if (scopemenu.max) {
2739 if (scopes[scopemenu.curr + 1].global)
2740 info_message(_(txt_scope_operation_not_allowed));
2741 else if (delete_scope(scopemenu.curr + 1)) {
2742 changed = TRUE;
2743 show_scope_page();
2744 }
2745 }
2746 break;
2747
2748 case SCOPE_EDIT_ATTRIBUTES_FILE:
2749 if (changed)
2750 write_attributes_file(local_attributes_file);
2751 if (!invoke_editor(local_attributes_file, attrib_file_offset, NULL))
2752 break;
2753 free_scopes_and_attributes();
2754 read_attributes_file(FALSE);
2755 assign_attributes_to_groups();
2756 changed = FALSE;
2757 scopemenu.curr = 0;
2758 show_scope_page();
2759 break;
2760
2761 case SCOPE_MOVE:
2762 if (scopemenu.max > 1) {
2763 if (scopes[scopemenu.curr + 1].global)
2764 info_message(_(txt_scope_operation_not_allowed));
2765 else if ((i = move_scope(scopemenu.curr + 1))) {
2766 changed = TRUE;
2767 scopemenu.curr = i - 1;
2768 show_scope_page();
2769 }
2770 }
2771 break;
2772
2773 case SCOPE_RENAME:
2774 if (scopemenu.max) {
2775 if (scopes[scopemenu.curr + 1].global)
2776 info_message(_(txt_scope_operation_not_allowed));
2777 else if (rename_scope(&scopes[scopemenu.curr + 1])) {
2778 changed = TRUE;
2779 show_scope_page();
2780 }
2781 }
2782 break;
2783
2784 case SCOPE_SELECT:
2785 if (scopemenu.max) {
2786 curr_scope = &scopes[scopemenu.curr + 1];
2787 config_page(NULL, level);
2788 if (!curr_scope->global && scope_is_empty())
2789 do_delete_scope(scopemenu.curr + 1);
2790 curr_scope = NULL;
2791 changed = TRUE;
2792 show_scope_page();
2793 }
2794 break;
2795
2796 default:
2797 info_message(_(txt_bad_command), printascii(key, func_to_key(GLOBAL_HELP, scope_keys)));
2798 break;
2799 }
2800 }
2801 }
2802
2803
2804 static void
draw_scope_arrow(void)2805 draw_scope_arrow(
2806 void)
2807 {
2808 draw_arrow_mark(INDEX_TOP + scopemenu.curr - scopemenu.first);
2809 if (scopemenu.curr == scopemenu.max - 1)
2810 info_message(_(txt_end_of_scopes));
2811 }
2812
2813
2814 static void
build_scope_line(int i)2815 build_scope_line(
2816 int i)
2817 {
2818 char *sptr;
2819 int len = cCOLS - 11;
2820
2821 #ifdef USE_CURSES
2822 /*
2823 * Allocate line buffer
2824 * make it the same size like in !USE_CURSES case to simplify some code
2825 */
2826 sptr = my_malloc(cCOLS + 2);
2827 #else
2828 sptr = screen[INDEX2SNUM(i)].col;
2829 #endif /* USE_CURSES */
2830
2831 snprintf(sptr, cCOLS, " %c %s %-*.*s%s", (scopes[i + 1].global ? '!' : ' '), tin_ltoa(i + 1, 4), len, len, scopes[i + 1].scope, cCRLF);
2832
2833 #ifndef USE_CURSES
2834 if (tinrc.strip_blanks)
2835 strcat(strip_line(sptr), cCRLF);
2836 #endif /* !USE_CURSES */
2837
2838 WriteLine(INDEX2LNUM(i), sptr);
2839
2840 #ifdef USE_CURSES
2841 free(sptr);
2842 #endif /* USE_CURSES */
2843 }
2844
2845
2846 /*
2847 * add a new scope and return the index
2848 */
2849 static int
add_new_scope(void)2850 add_new_scope(
2851 void)
2852 {
2853 char buf[LEN];
2854 int new_pos = 0;
2855
2856 if (prompt_default_string(_(txt_scope_enter), buf, sizeof(buf), (char *) NULL, HIST_OTHER))
2857 new_pos = add_scope(buf);
2858
2859 return new_pos;
2860 }
2861
2862
2863 /*
2864 * returns TRUE if the given scope was deleted
2865 */
2866 static t_bool
delete_scope(int curr_pos)2867 delete_scope(
2868 int curr_pos)
2869 {
2870 if (prompt_yn(_(txt_scope_delete), FALSE) == 1) {
2871 do_delete_scope(curr_pos);
2872 return TRUE;
2873 }
2874
2875 return FALSE;
2876 }
2877
2878
2879 static void
do_delete_scope(int curr_pos)2880 do_delete_scope(
2881 int curr_pos)
2882 {
2883 do_move_scope(curr_pos, num_scope - 1);
2884 free_scope(--num_scope);
2885 }
2886
2887
2888 /*
2889 * returns TRUE if scope was renamed
2890 */
2891 static t_bool
rename_scope(struct t_scope * scope)2892 rename_scope(
2893 struct t_scope *scope)
2894 {
2895 char buf[LEN];
2896
2897 if (prompt_default_string(_(txt_scope_rename), buf, sizeof(buf), scope->scope, HIST_OTHER)) {
2898 if (buf[0] == '\0')
2899 return FALSE;
2900 FreeIfNeeded(scope->scope);
2901 scope->scope = my_strdup(buf);
2902 return TRUE;
2903 }
2904
2905 return FALSE;
2906 }
2907
2908
2909 /*
2910 * look if an entry with the given scope exists and return the index
2911 */
2912 static int
find_scope(const char * scope)2913 find_scope(
2914 const char *scope)
2915 {
2916 int i;
2917
2918 if (!scope || !*scope)
2919 return 0;
2920
2921 for (i = 1; i < num_scope; i++) {
2922 if (!scopes[i].global && strcasecmp(scope, scopes[i].scope) == 0)
2923 return i;
2924 }
2925
2926 return 0;
2927 }
2928
2929
2930 /*
2931 * returns the new position of the moved scope or 0 if repositioning
2932 * is not possible
2933 */
2934 static int
move_scope(int curr_pos)2935 move_scope(
2936 int curr_pos)
2937 {
2938 char *p;
2939 int new_pos;
2940
2941 clear_message();
2942 if ((p = tin_getline(_(txt_scope_new_position), 1, NULL, 0, FALSE, HIST_OTHER)) != NULL)
2943 new_pos = atoi(p);
2944 else
2945 new_pos = curr_pos;
2946 clear_message();
2947
2948 if (new_pos == curr_pos || new_pos == 0)
2949 return 0;
2950
2951 if (new_pos >= num_scope)
2952 new_pos = num_scope - 1;
2953
2954 if (scopes[new_pos].global) {
2955 info_message(_(txt_scope_new_position_is_global));
2956 return 0;
2957 }
2958
2959 do_move_scope(curr_pos, new_pos);
2960
2961 return new_pos;
2962 }
2963
2964
2965 /*
2966 * repositions a scope into scopes[]
2967 */
2968 static void
do_move_scope(int from,int to)2969 do_move_scope(
2970 int from,
2971 int to)
2972 {
2973 struct t_scope tmp;
2974
2975 if (from == to)
2976 return;
2977
2978 tmp = scopes[from];
2979
2980 if (from > to) {
2981 while (from-- > to)
2982 scopes[from + 1] = scopes[from];
2983 } else {
2984 while (from++ < to)
2985 scopes[from - 1] = scopes[from];
2986 }
2987 scopes[to] = tmp;
2988 }
2989
2990
2991 /*
2992 * free all group->attribute arrays and all scopes which are
2993 * not marked as global
2994 */
2995 static void
free_scopes_and_attributes(void)2996 free_scopes_and_attributes(
2997 void)
2998 {
2999 int i;
3000
3001 for_each_group(i) {
3002 if (active[i].attribute && !active[i].attribute->global) {
3003 free(active[i].attribute);
3004 active[i].attribute = (struct t_attribute *) 0;
3005 }
3006 }
3007
3008 while (num_scope > 1 && !scopes[num_scope - 1].global)
3009 free_scope(--num_scope);
3010 }
3011
3012
3013 /*
3014 * returns TRUE if no attribute in curr_scope has state == TRUE
3015 */
3016 static t_bool
scope_is_empty(void)3017 scope_is_empty(
3018 void)
3019 {
3020 enum option_enum i;
3021
3022 for (i = 0; i <= last_opt; i++) {
3023 if (option_is_visible(i) && !option_is_title(i) && check_state(i))
3024 return FALSE;
3025 }
3026
3027 return TRUE;
3028 }
3029
3030
3031 /*
3032 * returns the state of the given attribute
3033 */
3034 static t_bool
check_state(enum option_enum option)3035 check_state(
3036 enum option_enum option)
3037 {
3038 switch (option) {
3039 case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
3040 return curr_scope->state->add_posted_to_filter;
3041 case OPT_ATTRIB_ADVERTISING:
3042 return curr_scope->state->advertising;
3043 case OPT_ATTRIB_ALTERNATIVE_HANDLING:
3044 return curr_scope->state->alternative_handling;
3045 case OPT_ATTRIB_ASK_FOR_METAMAIL:
3046 return curr_scope->state->ask_for_metamail;
3047 case OPT_ATTRIB_AUTO_CC_BCC:
3048 return curr_scope->state->auto_cc_bcc;
3049 case OPT_ATTRIB_AUTO_LIST_THREAD:
3050 return curr_scope->state->auto_list_thread;
3051 case OPT_ATTRIB_AUTO_SAVE:
3052 return curr_scope->state->auto_save;
3053 case OPT_ATTRIB_AUTO_SELECT:
3054 return curr_scope->state->auto_select;
3055 case OPT_ATTRIB_BATCH_SAVE:
3056 return curr_scope->state->batch_save;
3057 case OPT_ATTRIB_DATE_FORMAT:
3058 return curr_scope->state->date_format;
3059 case OPT_ATTRIB_DELETE_TMP_FILES:
3060 return curr_scope->state->delete_tmp_files;
3061 case OPT_ATTRIB_EDITOR_FORMAT:
3062 return curr_scope->state->editor_format;
3063 #ifdef HAVE_COLOR
3064 case OPT_ATTRIB_EXTQUOTE_HANDLING:
3065 return curr_scope->state->extquote_handling;
3066 #endif /* HAVE_COLOR */
3067 case OPT_ATTRIB_FCC:
3068 return curr_scope->state->fcc;
3069 case OPT_ATTRIB_FOLLOWUP_TO:
3070 return curr_scope->state->followup_to;
3071 case OPT_ATTRIB_FROM:
3072 return curr_scope->state->from;
3073 case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
3074 return curr_scope->state->group_catchup_on_exit;
3075 case OPT_ATTRIB_GROUP_FORMAT:
3076 return curr_scope->state->group_format;
3077 #ifdef HAVE_ISPELL
3078 case OPT_ATTRIB_ISPELL:
3079 return curr_scope->state->ispell;
3080 #endif /* HAVE_ISPELL */
3081 case OPT_ATTRIB_MAILDIR:
3082 return curr_scope->state->maildir;
3083 case OPT_ATTRIB_MAIL_8BIT_HEADER:
3084 return curr_scope->state->mail_8bit_header;
3085 case OPT_ATTRIB_MAIL_MIME_ENCODING:
3086 return curr_scope->state->mail_mime_encoding;
3087 case OPT_ATTRIB_MAILING_LIST:
3088 return curr_scope->state->mailing_list;
3089 case OPT_ATTRIB_MARK_IGNORE_TAGS:
3090 return curr_scope->state->mark_ignore_tags;
3091 case OPT_ATTRIB_MARK_SAVED_READ:
3092 return curr_scope->state->mark_saved_read;
3093 case OPT_ATTRIB_MIME_FORWARD:
3094 return curr_scope->state->mime_forward;
3095 case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
3096 return curr_scope->state->mime_types_to_save;
3097 case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
3098 return curr_scope->state->news_headers_to_display;
3099 case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
3100 return curr_scope->state->news_headers_to_not_display;
3101 case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
3102 return curr_scope->state->news_quote_format;
3103 case OPT_ATTRIB_ORGANIZATION:
3104 return curr_scope->state->organization;
3105 case OPT_ATTRIB_POST_8BIT_HEADER:
3106 return curr_scope->state->post_8bit_header;
3107 case OPT_ATTRIB_POST_MIME_ENCODING:
3108 return curr_scope->state->post_mime_encoding;
3109 case OPT_ATTRIB_POST_PROCESS_VIEW:
3110 return curr_scope->state->post_process_view;
3111 case OPT_ATTRIB_POS_FIRST_UNREAD:
3112 return curr_scope->state->pos_first_unread;
3113 #ifndef DISABLE_PRINTING
3114 case OPT_ATTRIB_PRINT_HEADER:
3115 return curr_scope->state->print_header;
3116 #endif /* !DISABLE_PRINTING */
3117 case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
3118 return curr_scope->state->process_only_unread;
3119 case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
3120 return curr_scope->state->prompt_followupto;
3121 case OPT_ATTRIB_QUICK_KILL_SCOPE:
3122 return curr_scope->state->quick_kill_scope;
3123 case OPT_ATTRIB_QUICK_KILL_HEADER:
3124 return curr_scope->state->quick_kill_header;
3125 case OPT_ATTRIB_QUICK_KILL_CASE:
3126 return curr_scope->state->quick_kill_case;
3127 case OPT_ATTRIB_QUICK_KILL_EXPIRE:
3128 return curr_scope->state->quick_kill_expire;
3129 case OPT_ATTRIB_QUICK_SELECT_SCOPE:
3130 return curr_scope->state->quick_select_scope;
3131 case OPT_ATTRIB_QUICK_SELECT_HEADER:
3132 return curr_scope->state->quick_select_header;
3133 case OPT_ATTRIB_QUICK_SELECT_CASE:
3134 return curr_scope->state->quick_select_case;
3135 case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
3136 return curr_scope->state->quick_select_expire;
3137 case OPT_ATTRIB_QUOTE_CHARS:
3138 return curr_scope->state->quote_chars;
3139 case OPT_ATTRIB_SAVEDIR:
3140 return curr_scope->state->savedir;
3141 case OPT_ATTRIB_SAVEFILE:
3142 return curr_scope->state->savefile;
3143 case OPT_ATTRIB_SHOW_AUTHOR:
3144 return curr_scope->state->show_author;
3145 case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
3146 return curr_scope->state->show_only_unread_arts;
3147 case OPT_ATTRIB_SHOW_SIGNATURES:
3148 return curr_scope->state->show_signatures;
3149 case OPT_ATTRIB_SIGDASHES:
3150 return curr_scope->state->sigdashes;
3151 case OPT_ATTRIB_SIGFILE:
3152 return curr_scope->state->sigfile;
3153 case OPT_ATTRIB_SIGNATURE_REPOST:
3154 return curr_scope->state->signature_repost;
3155 case OPT_ATTRIB_START_EDITOR_OFFSET:
3156 return curr_scope->state->start_editor_offset;
3157 case OPT_ATTRIB_THREAD_ARTICLES:
3158 return curr_scope->state->thread_articles;
3159 case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
3160 return curr_scope->state->thread_catchup_on_exit;
3161 case OPT_ATTRIB_THREAD_FORMAT:
3162 return curr_scope->state->thread_format;
3163 case OPT_ATTRIB_THREAD_PERC:
3164 return curr_scope->state->thread_perc;
3165 case OPT_ATTRIB_TRIM_ARTICLE_BODY:
3166 return curr_scope->state->trim_article_body;
3167 case OPT_ATTRIB_TEX2ISO_CONV:
3168 return curr_scope->state->tex2iso_conv;
3169 case OPT_ATTRIB_SORT_THREADS_TYPE:
3170 return curr_scope->state->sort_threads_type;
3171 #ifdef CHARSET_CONVERSION
3172 case OPT_ATTRIB_MM_NETWORK_CHARSET:
3173 return curr_scope->state->mm_network_charset;
3174 case OPT_ATTRIB_UNDECLARED_CHARSET:
3175 return curr_scope->state->undeclared_charset;
3176 #endif /* CHARSET_CONVERSION */
3177 case OPT_ATTRIB_VERBATIM_HANDLING:
3178 return curr_scope->state->verbatim_handling;
3179 case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
3180 return curr_scope->state->wrap_on_next_unread;
3181 case OPT_ATTRIB_SORT_ARTICLE_TYPE:
3182 return curr_scope->state->sort_article_type;
3183 case OPT_ATTRIB_POST_PROCESS_TYPE:
3184 return curr_scope->state->post_process_type;
3185 case OPT_ATTRIB_X_BODY:
3186 return curr_scope->state->x_body;
3187 case OPT_ATTRIB_X_COMMENT_TO:
3188 return curr_scope->state->x_comment_to;
3189 case OPT_ATTRIB_X_HEADERS:
3190 return curr_scope->state->x_headers;
3191
3192 default:
3193 return FALSE;
3194 }
3195 }
3196
3197
3198 /*
3199 * set the state of the given attribute to FALSE and the corresponding
3200 * tinrc.attrib_* to a default value
3201 */
3202 static void
reset_state(enum option_enum option)3203 reset_state(
3204 enum option_enum option)
3205 {
3206 struct t_scope *default_scope = &scopes[0];
3207
3208 switch (option) {
3209 case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
3210 curr_scope->state->add_posted_to_filter = FALSE;
3211 tinrc.attrib_add_posted_to_filter = default_scope->attribute->add_posted_to_filter;
3212 break;
3213 case OPT_ATTRIB_ADVERTISING:
3214 curr_scope->state->advertising = FALSE;
3215 tinrc.attrib_advertising = default_scope->attribute->advertising;
3216 break;
3217 case OPT_ATTRIB_ALTERNATIVE_HANDLING:
3218 curr_scope->state->alternative_handling = FALSE;
3219 tinrc.attrib_alternative_handling = default_scope->attribute->alternative_handling;
3220 break;
3221 case OPT_ATTRIB_ASK_FOR_METAMAIL:
3222 curr_scope->state->ask_for_metamail = FALSE;
3223 tinrc.attrib_ask_for_metamail = default_scope->attribute->ask_for_metamail;
3224 break;
3225 case OPT_ATTRIB_AUTO_CC_BCC:
3226 curr_scope->state->auto_cc_bcc = FALSE;
3227 tinrc.attrib_auto_cc_bcc = default_scope->attribute->auto_cc_bcc;
3228 break;
3229 case OPT_ATTRIB_AUTO_LIST_THREAD:
3230 curr_scope->state->auto_list_thread = FALSE;
3231 tinrc.attrib_auto_list_thread = default_scope->attribute->auto_list_thread;
3232 break;
3233 case OPT_ATTRIB_AUTO_SAVE:
3234 curr_scope->state->auto_save = FALSE;
3235 tinrc.attrib_auto_save = default_scope->attribute->auto_save;
3236 break;
3237 case OPT_ATTRIB_AUTO_SELECT:
3238 curr_scope->state->auto_select = FALSE;
3239 tinrc.attrib_auto_select = default_scope->attribute->auto_select;
3240 break;
3241 case OPT_ATTRIB_BATCH_SAVE:
3242 curr_scope->state->batch_save = FALSE;
3243 tinrc.attrib_batch_save = default_scope->attribute->batch_save;
3244 break;
3245 case OPT_ATTRIB_DATE_FORMAT:
3246 FreeAndNull(curr_scope->attribute->date_format);
3247 curr_scope->state->date_format = FALSE;
3248 snprintf(tinrc.attrib_date_format, sizeof(tinrc.attrib_date_format), "%s", BlankIfNull(default_scope->attribute->date_format));
3249 break;
3250 case OPT_ATTRIB_DELETE_TMP_FILES:
3251 curr_scope->state->delete_tmp_files = FALSE;
3252 tinrc.attrib_delete_tmp_files = default_scope->attribute->delete_tmp_files;
3253 break;
3254 case OPT_ATTRIB_EDITOR_FORMAT:
3255 FreeAndNull(curr_scope->attribute->editor_format);
3256 curr_scope->state->editor_format = FALSE;
3257 snprintf(tinrc.attrib_editor_format, sizeof(tinrc.attrib_editor_format), "%s", BlankIfNull(default_scope->attribute->editor_format));
3258 break;
3259 #ifdef HAVE_COLOR
3260 case OPT_ATTRIB_EXTQUOTE_HANDLING:
3261 curr_scope->state->extquote_handling = FALSE;
3262 tinrc.attrib_extquote_handling = default_scope->attribute->extquote_handling;
3263 break;
3264 #endif /* HAVE_COLOR */
3265 case OPT_ATTRIB_FCC:
3266 FreeAndNull(curr_scope->attribute->fcc);
3267 curr_scope->state->fcc = FALSE;
3268 snprintf(tinrc.attrib_fcc, sizeof(tinrc.attrib_fcc), "%s", BlankIfNull(default_scope->attribute->fcc));
3269 break;
3270 case OPT_ATTRIB_FOLLOWUP_TO:
3271 FreeAndNull(curr_scope->attribute->followup_to);
3272 curr_scope->state->followup_to = FALSE;
3273 snprintf(tinrc.attrib_followup_to, sizeof(tinrc.attrib_followup_to), "%s", BlankIfNull(default_scope->attribute->followup_to));
3274 break;
3275 case OPT_ATTRIB_FROM:
3276 FreeAndNull(curr_scope->attribute->from);
3277 curr_scope->state->from = FALSE;
3278 snprintf(tinrc.attrib_from, sizeof(tinrc.attrib_from), "%s", BlankIfNull(default_scope->attribute->from));
3279 break;
3280 case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
3281 curr_scope->state->group_catchup_on_exit = FALSE;
3282 tinrc.attrib_group_catchup_on_exit = default_scope->attribute->group_catchup_on_exit;
3283 break;
3284 case OPT_ATTRIB_GROUP_FORMAT:
3285 FreeAndNull(curr_scope->attribute->group_format);
3286 curr_scope->state->group_format = FALSE;
3287 snprintf(tinrc.attrib_group_format, sizeof(tinrc.attrib_group_format), "%s", BlankIfNull(default_scope->attribute->group_format));
3288 break;
3289 #ifdef HAVE_ISPELL
3290 case OPT_ATTRIB_ISPELL:
3291 FreeAndNull(curr_scope->attribute->ispell);
3292 curr_scope->state->ispell = FALSE;
3293 snprintf(tinrc.attrib_ispell, sizeof(tinrc.attrib_ispell), "%s", BlankIfNull(default_scope->attribute->ispell));
3294 break;
3295 #endif /* HAVE_ISPELL */
3296 case OPT_ATTRIB_MAILDIR:
3297 FreeAndNull(curr_scope->attribute->maildir);
3298 curr_scope->state->maildir = FALSE;
3299 snprintf(tinrc.attrib_maildir, sizeof(tinrc.attrib_maildir), "%s", BlankIfNull(default_scope->attribute->maildir));
3300 break;
3301 case OPT_ATTRIB_MAIL_8BIT_HEADER:
3302 curr_scope->state->mail_8bit_header = FALSE;
3303 tinrc.attrib_mail_8bit_header = default_scope->attribute->mail_8bit_header;
3304 break;
3305 case OPT_ATTRIB_MAIL_MIME_ENCODING:
3306 curr_scope->state->mail_mime_encoding = FALSE;
3307 tinrc.attrib_mail_mime_encoding = default_scope->attribute->mail_mime_encoding;
3308 break;
3309 case OPT_ATTRIB_MAILING_LIST:
3310 FreeAndNull(curr_scope->attribute->mailing_list);
3311 curr_scope->state->mailing_list = FALSE;
3312 snprintf(tinrc.attrib_mailing_list, sizeof(tinrc.attrib_mailing_list), "%s", BlankIfNull(default_scope->attribute->mailing_list));
3313 break;
3314 case OPT_ATTRIB_MARK_IGNORE_TAGS:
3315 curr_scope->state->mark_ignore_tags = FALSE;
3316 tinrc.attrib_mark_ignore_tags = default_scope->attribute->mark_ignore_tags;
3317 break;
3318 case OPT_ATTRIB_MARK_SAVED_READ:
3319 curr_scope->state->mark_saved_read = FALSE;
3320 tinrc.attrib_mark_saved_read = default_scope->attribute->mark_saved_read;
3321 break;
3322 case OPT_ATTRIB_MIME_FORWARD:
3323 curr_scope->state->mime_forward = FALSE;
3324 tinrc.attrib_mime_forward = default_scope->attribute->mime_forward;
3325 break;
3326 case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
3327 FreeAndNull(curr_scope->attribute->mime_types_to_save);
3328 curr_scope->state->mime_types_to_save = FALSE;
3329 snprintf(tinrc.attrib_mime_types_to_save, sizeof(tinrc.attrib_mime_types_to_save), "%s", BlankIfNull(default_scope->attribute->mime_types_to_save));
3330 break;
3331 case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
3332 FreeAndNull(curr_scope->attribute->news_headers_to_display);
3333 build_news_headers_array(curr_scope->attribute, TRUE);
3334 curr_scope->state->news_headers_to_display = FALSE;
3335 snprintf(tinrc.attrib_news_headers_to_display, sizeof(tinrc.attrib_news_headers_to_display), "%s", BlankIfNull(default_scope->attribute->news_headers_to_display));
3336 break;
3337 case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
3338 FreeAndNull(curr_scope->attribute->news_headers_to_not_display);
3339 build_news_headers_array(curr_scope->attribute, FALSE);
3340 curr_scope->state->news_headers_to_not_display = FALSE;
3341 snprintf(tinrc.attrib_news_headers_to_not_display, sizeof(tinrc.attrib_news_headers_to_not_display), "%s", BlankIfNull(default_scope->attribute->news_headers_to_not_display));
3342 break;
3343 case OPT_ATTRIB_QUICK_KILL_SCOPE:
3344 FreeAndNull(curr_scope->attribute->quick_kill_scope);
3345 curr_scope->state->quick_kill_scope = FALSE;
3346 snprintf(tinrc.attrib_quick_kill_scope, sizeof(tinrc.attrib_quick_kill_scope), "%s", BlankIfNull(default_scope->attribute->quick_kill_scope));
3347 break;
3348 case OPT_ATTRIB_QUICK_KILL_HEADER:
3349 curr_scope->state->quick_kill_header = FALSE;
3350 tinrc.attrib_quick_kill_header = default_scope->attribute->quick_kill_header;
3351 break;
3352 case OPT_ATTRIB_QUICK_KILL_CASE:
3353 curr_scope->state->quick_kill_case = FALSE;
3354 tinrc.attrib_quick_kill_case = default_scope->attribute->quick_kill_case;
3355 break;
3356 case OPT_ATTRIB_QUICK_KILL_EXPIRE:
3357 curr_scope->state->quick_kill_expire = FALSE;
3358 tinrc.attrib_quick_kill_expire = default_scope->attribute->quick_kill_expire;
3359 break;
3360 case OPT_ATTRIB_QUICK_SELECT_SCOPE:
3361 FreeAndNull(curr_scope->attribute->quick_select_scope);
3362 curr_scope->state->quick_select_scope = FALSE;
3363 snprintf(tinrc.attrib_quick_select_scope, sizeof(tinrc.attrib_quick_select_scope), "%s", BlankIfNull(default_scope->attribute->quick_select_scope));
3364 break;
3365 case OPT_ATTRIB_QUICK_SELECT_HEADER:
3366 curr_scope->state->quick_select_header = FALSE;
3367 tinrc.attrib_quick_select_header = default_scope->attribute->quick_select_header;
3368 break;
3369 case OPT_ATTRIB_QUICK_SELECT_CASE:
3370 curr_scope->state->quick_select_case = FALSE;
3371 tinrc.attrib_quick_select_case = default_scope->attribute->quick_select_case;
3372 break;
3373 case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
3374 curr_scope->state->quick_select_expire = FALSE;
3375 tinrc.attrib_quick_select_expire = default_scope->attribute->quick_select_expire;
3376 break;
3377 case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
3378 FreeAndNull(curr_scope->attribute->news_quote_format);
3379 curr_scope->state->news_quote_format = FALSE;
3380 snprintf(tinrc.attrib_news_quote_format, sizeof(tinrc.attrib_news_quote_format), "%s", BlankIfNull(default_scope->attribute->news_quote_format));
3381 break;
3382 case OPT_ATTRIB_ORGANIZATION:
3383 FreeAndNull(curr_scope->attribute->organization);
3384 curr_scope->state->organization = FALSE;
3385 snprintf(tinrc.attrib_organization, sizeof(tinrc.attrib_organization), "%s", BlankIfNull(default_scope->attribute->organization));
3386 break;
3387 case OPT_ATTRIB_POST_8BIT_HEADER:
3388 curr_scope->state->post_8bit_header = FALSE;
3389 tinrc.attrib_post_8bit_header = default_scope->attribute->post_8bit_header;
3390 break;
3391 case OPT_ATTRIB_POST_MIME_ENCODING:
3392 curr_scope->state->post_mime_encoding = FALSE;
3393 tinrc.attrib_post_mime_encoding = default_scope->attribute->post_mime_encoding;
3394 break;
3395 case OPT_ATTRIB_POST_PROCESS_VIEW:
3396 curr_scope->state->post_process_view = FALSE;
3397 tinrc.attrib_post_process_view = default_scope->attribute->post_process_view;
3398 break;
3399 case OPT_ATTRIB_POS_FIRST_UNREAD:
3400 curr_scope->state->pos_first_unread = FALSE;
3401 tinrc.attrib_pos_first_unread = default_scope->attribute->pos_first_unread;
3402 break;
3403 #ifndef DISABLE_PRINTING
3404 case OPT_ATTRIB_PRINT_HEADER:
3405 curr_scope->state->print_header = FALSE;
3406 tinrc.attrib_print_header = default_scope->attribute->print_header;
3407 break;
3408 #endif /* !DISABLE_PRINTING */
3409 case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
3410 curr_scope->state->process_only_unread = FALSE;
3411 tinrc.attrib_process_only_unread = default_scope->attribute->process_only_unread;
3412 break;
3413 case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
3414 curr_scope->state->prompt_followupto = FALSE;
3415 tinrc.attrib_prompt_followupto = default_scope->attribute->prompt_followupto;
3416 break;
3417 case OPT_ATTRIB_QUOTE_CHARS:
3418 FreeAndNull(curr_scope->attribute->quote_chars);
3419 curr_scope->state->quote_chars = FALSE;
3420 snprintf(tinrc.attrib_quote_chars, sizeof(tinrc.attrib_quote_chars), "%s", BlankIfNull(default_scope->attribute->quote_chars));
3421 break;
3422 case OPT_ATTRIB_SAVEDIR:
3423 FreeAndNull(curr_scope->attribute->savedir);
3424 curr_scope->state->savedir = FALSE;
3425 snprintf(tinrc.attrib_savedir, sizeof(tinrc.attrib_savedir), "%s", BlankIfNull(default_scope->attribute->savedir));
3426 break;
3427 case OPT_ATTRIB_SAVEFILE:
3428 FreeAndNull(curr_scope->attribute->savefile);
3429 curr_scope->state->savefile = FALSE;
3430 snprintf(tinrc.attrib_savefile, sizeof(tinrc.attrib_savefile), "%s", BlankIfNull(default_scope->attribute->savefile));
3431 break;
3432 case OPT_ATTRIB_SHOW_AUTHOR:
3433 curr_scope->state->show_author = FALSE;
3434 tinrc.attrib_show_author = default_scope->attribute->show_author;
3435 break;
3436 case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
3437 curr_scope->state->show_only_unread_arts = FALSE;
3438 tinrc.attrib_show_only_unread_arts = default_scope->attribute->show_only_unread_arts;
3439 break;
3440 case OPT_ATTRIB_SHOW_SIGNATURES:
3441 curr_scope->state->show_signatures = FALSE;
3442 tinrc.attrib_show_signatures = default_scope->attribute->show_signatures;
3443 break;
3444 case OPT_ATTRIB_SIGDASHES:
3445 curr_scope->state->sigdashes = FALSE;
3446 tinrc.attrib_sigdashes = default_scope->attribute->sigdashes;
3447 break;
3448 case OPT_ATTRIB_SIGFILE:
3449 FreeAndNull(curr_scope->attribute->sigfile);
3450 curr_scope->state->sigfile = FALSE;
3451 snprintf(tinrc.attrib_sigfile, sizeof(tinrc.attrib_sigfile), "%s", BlankIfNull(default_scope->attribute->sigfile));
3452 break;
3453 case OPT_ATTRIB_SIGNATURE_REPOST:
3454 curr_scope->state->signature_repost = FALSE;
3455 tinrc.attrib_signature_repost = default_scope->attribute->signature_repost;
3456 break;
3457 case OPT_ATTRIB_START_EDITOR_OFFSET:
3458 curr_scope->state->start_editor_offset = FALSE;
3459 tinrc.attrib_start_editor_offset = default_scope->attribute->start_editor_offset;
3460 break;
3461 case OPT_ATTRIB_THREAD_ARTICLES:
3462 curr_scope->state->thread_articles = FALSE;
3463 tinrc.attrib_thread_articles = default_scope->attribute->thread_articles;
3464 break;
3465 case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
3466 curr_scope->state->thread_catchup_on_exit = FALSE;
3467 tinrc.attrib_thread_catchup_on_exit = default_scope->attribute->thread_catchup_on_exit;
3468 break;
3469 case OPT_ATTRIB_THREAD_FORMAT:
3470 FreeAndNull(curr_scope->attribute->thread_format);
3471 curr_scope->state->thread_format = FALSE;
3472 snprintf(tinrc.attrib_thread_format, sizeof(tinrc.attrib_thread_format), "%s", BlankIfNull(default_scope->attribute->thread_format));
3473 break;
3474 case OPT_ATTRIB_THREAD_PERC:
3475 curr_scope->state->thread_perc = FALSE;
3476 tinrc.attrib_thread_perc = default_scope->attribute->thread_perc;
3477 break;
3478 case OPT_ATTRIB_TRIM_ARTICLE_BODY:
3479 curr_scope->state->trim_article_body = FALSE;
3480 tinrc.attrib_trim_article_body = default_scope->attribute->trim_article_body;
3481 break;
3482 case OPT_ATTRIB_TEX2ISO_CONV:
3483 curr_scope->state->tex2iso_conv = FALSE;
3484 tinrc.attrib_tex2iso_conv = default_scope->attribute->tex2iso_conv;
3485 break;
3486 case OPT_ATTRIB_SORT_THREADS_TYPE:
3487 curr_scope->state->sort_threads_type = FALSE;
3488 tinrc.attrib_sort_threads_type = default_scope->attribute->sort_threads_type;
3489 break;
3490 #ifdef CHARSET_CONVERSION
3491 case OPT_ATTRIB_MM_NETWORK_CHARSET:
3492 curr_scope->state->mm_network_charset = FALSE;
3493 tinrc.attrib_mm_network_charset = default_scope->attribute->mm_network_charset;
3494 break;
3495 case OPT_ATTRIB_UNDECLARED_CHARSET:
3496 FreeAndNull(curr_scope->attribute->undeclared_charset);
3497 curr_scope->state->undeclared_charset = FALSE;
3498 snprintf(tinrc.attrib_undeclared_charset, sizeof(tinrc.attrib_undeclared_charset), "%s", BlankIfNull(default_scope->attribute->undeclared_charset));
3499 break;
3500 #endif /* CHARSET_CONVERSION */
3501 case OPT_ATTRIB_VERBATIM_HANDLING:
3502 curr_scope->state->verbatim_handling = FALSE;
3503 tinrc.attrib_verbatim_handling = default_scope->attribute->verbatim_handling;
3504 break;
3505 case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
3506 curr_scope->state->wrap_on_next_unread = FALSE;
3507 tinrc.attrib_wrap_on_next_unread = default_scope->attribute->wrap_on_next_unread;
3508 break;
3509 case OPT_ATTRIB_SORT_ARTICLE_TYPE:
3510 curr_scope->state->sort_article_type = FALSE;
3511 tinrc.attrib_sort_article_type = default_scope->attribute->sort_article_type;
3512 break;
3513 case OPT_ATTRIB_POST_PROCESS_TYPE:
3514 curr_scope->state->post_process_type = FALSE;
3515 tinrc.attrib_post_process_type = default_scope->attribute->post_process_type;
3516 break;
3517 case OPT_ATTRIB_X_BODY:
3518 FreeAndNull(curr_scope->attribute->x_body);
3519 curr_scope->state->x_body = FALSE;
3520 snprintf(tinrc.attrib_x_body, sizeof(tinrc.attrib_x_body), "%s", BlankIfNull(default_scope->attribute->x_body));
3521 break;
3522 case OPT_ATTRIB_X_COMMENT_TO:
3523 curr_scope->state->x_comment_to = FALSE;
3524 tinrc.attrib_x_comment_to = default_scope->attribute->x_comment_to;
3525 break;
3526 case OPT_ATTRIB_X_HEADERS:
3527 FreeAndNull(curr_scope->attribute->x_headers);
3528 curr_scope->state->x_headers = FALSE;
3529 snprintf(tinrc.attrib_x_headers, sizeof(tinrc.attrib_x_headers), "%s", BlankIfNull(default_scope->attribute->x_headers));
3530 break;
3531
3532 default:
3533 break;
3534 }
3535 }
3536
3537
3538 #define INITIALIZE_STRING_ATTRIBUTE(option) do { \
3539 if (curr_scope->state->option) \
3540 snprintf(CAO(tinrc.attrib_, option), sizeof(CAO(tinrc.attrib_, option)), "%s", curr_scope->attribute->option); \
3541 else \
3542 snprintf(CAO(tinrc.attrib_, option), sizeof(CAO(tinrc.attrib_, option)), "%s", BlankIfNull(default_scope->attribute->option)); \
3543 } while (0)
3544 #define INITIALIZE_NUM_ATTRIBUTE(option) do { \
3545 if (curr_scope->state->option) \
3546 CAO(tinrc.attrib_, option) = curr_scope->attribute->option; \
3547 else \
3548 CAO(tinrc.attrib_, option) = default_scope->attribute->option; \
3549 } while (0)
3550
3551 static void
initialize_attributes(void)3552 initialize_attributes(
3553 void)
3554 {
3555 struct t_scope *default_scope = &scopes[0];
3556
3557 INITIALIZE_NUM_ATTRIBUTE(add_posted_to_filter);
3558 INITIALIZE_NUM_ATTRIBUTE(advertising);
3559 INITIALIZE_NUM_ATTRIBUTE(alternative_handling);
3560 INITIALIZE_NUM_ATTRIBUTE(ask_for_metamail);
3561 INITIALIZE_NUM_ATTRIBUTE(auto_cc_bcc);
3562 INITIALIZE_NUM_ATTRIBUTE(auto_list_thread);
3563 INITIALIZE_NUM_ATTRIBUTE(auto_save);
3564 INITIALIZE_NUM_ATTRIBUTE(auto_select);
3565 INITIALIZE_NUM_ATTRIBUTE(batch_save);
3566 INITIALIZE_NUM_ATTRIBUTE(delete_tmp_files);
3567 #ifdef HAVE_COLOR
3568 INITIALIZE_NUM_ATTRIBUTE(extquote_handling);
3569 #endif /* HAVE_COLOR */
3570 INITIALIZE_NUM_ATTRIBUTE(group_catchup_on_exit);
3571 INITIALIZE_NUM_ATTRIBUTE(mail_8bit_header);
3572 INITIALIZE_NUM_ATTRIBUTE(mail_mime_encoding);
3573 INITIALIZE_NUM_ATTRIBUTE(mark_ignore_tags);
3574 INITIALIZE_NUM_ATTRIBUTE(mark_saved_read);
3575 INITIALIZE_NUM_ATTRIBUTE(mime_forward);
3576 INITIALIZE_NUM_ATTRIBUTE(pos_first_unread);
3577 INITIALIZE_NUM_ATTRIBUTE(post_8bit_header);
3578 INITIALIZE_NUM_ATTRIBUTE(post_mime_encoding);
3579 INITIALIZE_NUM_ATTRIBUTE(post_process_view);
3580 #ifndef DISABLE_PRINTING
3581 INITIALIZE_NUM_ATTRIBUTE(print_header);
3582 #endif /* !DISABLE_PRINTING */
3583 INITIALIZE_NUM_ATTRIBUTE(process_only_unread);
3584 INITIALIZE_NUM_ATTRIBUTE(prompt_followupto);
3585 INITIALIZE_NUM_ATTRIBUTE(quick_kill_header);
3586 INITIALIZE_NUM_ATTRIBUTE(quick_kill_case);
3587 INITIALIZE_NUM_ATTRIBUTE(quick_kill_expire);
3588 INITIALIZE_NUM_ATTRIBUTE(quick_select_header);
3589 INITIALIZE_NUM_ATTRIBUTE(quick_select_case);
3590 INITIALIZE_NUM_ATTRIBUTE(quick_select_expire);
3591 INITIALIZE_NUM_ATTRIBUTE(show_author);
3592 INITIALIZE_NUM_ATTRIBUTE(show_only_unread_arts);
3593 INITIALIZE_NUM_ATTRIBUTE(show_signatures);
3594 INITIALIZE_NUM_ATTRIBUTE(sigdashes);
3595 INITIALIZE_NUM_ATTRIBUTE(signature_repost);
3596 INITIALIZE_NUM_ATTRIBUTE(start_editor_offset);
3597 INITIALIZE_NUM_ATTRIBUTE(thread_articles);
3598 INITIALIZE_NUM_ATTRIBUTE(thread_catchup_on_exit);
3599 INITIALIZE_NUM_ATTRIBUTE(thread_perc);
3600 INITIALIZE_NUM_ATTRIBUTE(trim_article_body);
3601 INITIALIZE_NUM_ATTRIBUTE(tex2iso_conv);
3602 INITIALIZE_NUM_ATTRIBUTE(verbatim_handling);
3603 INITIALIZE_NUM_ATTRIBUTE(wrap_on_next_unread);
3604 INITIALIZE_NUM_ATTRIBUTE(sort_article_type);
3605 INITIALIZE_NUM_ATTRIBUTE(sort_threads_type);
3606 INITIALIZE_NUM_ATTRIBUTE(post_process_type);
3607 INITIALIZE_NUM_ATTRIBUTE(x_comment_to);
3608 INITIALIZE_STRING_ATTRIBUTE(date_format);
3609 INITIALIZE_STRING_ATTRIBUTE(editor_format);
3610 INITIALIZE_STRING_ATTRIBUTE(fcc);
3611 INITIALIZE_STRING_ATTRIBUTE(followup_to);
3612 INITIALIZE_STRING_ATTRIBUTE(from);
3613 INITIALIZE_STRING_ATTRIBUTE(group_format);
3614 #ifdef HAVE_ISPELL
3615 INITIALIZE_STRING_ATTRIBUTE(ispell);
3616 #endif /* HAVE_ISPELL */
3617 INITIALIZE_STRING_ATTRIBUTE(maildir);
3618 INITIALIZE_STRING_ATTRIBUTE(mailing_list);
3619 INITIALIZE_STRING_ATTRIBUTE(mime_types_to_save);
3620 INITIALIZE_STRING_ATTRIBUTE(news_headers_to_display);
3621 INITIALIZE_STRING_ATTRIBUTE(news_headers_to_not_display);
3622 INITIALIZE_STRING_ATTRIBUTE(news_quote_format);
3623 INITIALIZE_STRING_ATTRIBUTE(organization);
3624 INITIALIZE_STRING_ATTRIBUTE(quick_kill_scope);
3625 INITIALIZE_STRING_ATTRIBUTE(quick_select_scope);
3626 INITIALIZE_STRING_ATTRIBUTE(quote_chars);
3627 INITIALIZE_STRING_ATTRIBUTE(savedir);
3628 INITIALIZE_STRING_ATTRIBUTE(savefile);
3629 INITIALIZE_STRING_ATTRIBUTE(sigfile);
3630 INITIALIZE_STRING_ATTRIBUTE(thread_format);
3631 #ifdef CHARSET_CONVERSION
3632 INITIALIZE_NUM_ATTRIBUTE(mm_network_charset);
3633 INITIALIZE_STRING_ATTRIBUTE(undeclared_charset);
3634 #endif /* CHARSET_CONVERSION */
3635 INITIALIZE_STRING_ATTRIBUTE(x_body);
3636 INITIALIZE_STRING_ATTRIBUTE(x_headers);
3637 }
3638