(panel_callback) [MSG_FOCUS]: remove self-draw here.
[midnight-commander.git] / src / filemanager / boxes.c
blob27992669062aad979624c73ea09d0e3a50b0efc2
1 /*
2 Some misc dialog boxes for the program.
4 Copyright (C) 1994-2024
5 Free Software Foundation, Inc.
7 Written by:
8 Miguel de Icaza, 1994, 1995
9 Jakub Jelinek, 1995
10 Andrew Borodin <aborodin@vmail.ru>, 2009-2022
12 This file is part of the Midnight Commander.
14 The Midnight Commander is free software: you can redistribute it
15 and/or modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation, either version 3 of the License,
17 or (at your option) any later version.
19 The Midnight Commander is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 /** \file boxes.c
29 * \brief Source: Some misc dialog boxes for the program
32 #include <config.h>
34 #include <ctype.h>
35 #include <signal.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
42 #include "lib/global.h"
44 #include "lib/tty/tty.h"
45 #include "lib/tty/color.h" /* tty_use_colors() */
46 #include "lib/tty/key.h" /* XCTRL and ALT macros */
47 #include "lib/skin.h" /* INPUT_COLOR */
48 #include "lib/mcconfig.h" /* Load/save user formats */
49 #include "lib/strutil.h"
51 #include "lib/vfs/vfs.h"
52 #ifdef ENABLE_VFS_FTP
53 #include "src/vfs/ftpfs/ftpfs.h"
54 #endif /* ENABLE_VFS_FTP */
56 #include "lib/util.h" /* Q_() */
57 #include "lib/widget.h"
59 #include "src/setup.h"
60 #include "src/history.h" /* MC_HISTORY_ESC_TIMEOUT */
61 #include "src/execute.h" /* pause_after_run */
62 #ifdef ENABLE_BACKGROUND
63 #include "src/background.h" /* task_list */
64 #endif
66 #ifdef HAVE_CHARSET
67 #include "lib/charsets.h"
68 #include "src/selcodepage.h"
69 #endif
71 #include "command.h" /* For cmdline */
72 #include "dir.h"
73 #include "tree.h"
74 #include "layout.h" /* for get_nth_panel_name proto */
75 #include "filemanager.h"
77 #include "boxes.h"
79 /*** global variables ****************************************************************************/
81 /*** file scope macro definitions ****************************************************************/
83 #ifdef ENABLE_BACKGROUND
84 #define B_STOP (B_USER+1)
85 #define B_RESUME (B_USER+2)
86 #define B_KILL (B_USER+3)
87 #endif /* ENABLE_BACKGROUND */
89 /*** file scope type declarations ****************************************************************/
91 /*** forward declarations (file scope functions) *************************************************/
93 /*** file scope variables ************************************************************************/
95 static unsigned long configure_old_esc_mode_id, configure_time_out_id;
97 /* Index in list_formats[] for "brief" */
98 static const int panel_list_brief_idx = 1;
99 /* Index in list_formats[] for "user defined" */
100 static const int panel_list_user_idx = 3;
102 static char **status_format;
103 static unsigned long panel_list_formats_id, panel_user_format_id, panel_brief_cols_id;
104 static unsigned long user_mini_status_id, mini_user_format_id;
106 #ifdef HAVE_CHARSET
107 static int new_display_codepage;
108 #endif /* HAVE_CHARSET */
110 #if defined(ENABLE_VFS) && defined(ENABLE_VFS_FTP)
111 static unsigned long ftpfs_always_use_proxy_id, ftpfs_proxy_host_id;
112 #endif /* ENABLE_VFS && ENABLE_VFS_FTP */
114 static GPtrArray *skin_names;
115 static gchar *current_skin_name;
117 #ifdef ENABLE_BACKGROUND
118 static WListbox *bg_list = NULL;
119 #endif /* ENABLE_BACKGROUND */
121 static unsigned long shadows_id;
123 /* --------------------------------------------------------------------------------------------- */
124 /*** file scope functions ************************************************************************/
125 /* --------------------------------------------------------------------------------------------- */
127 static cb_ret_t
128 configure_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
130 switch (msg)
132 case MSG_NOTIFY:
133 /* message from "Single press" checkbutton */
134 if (sender != NULL && sender->id == configure_old_esc_mode_id)
136 const gboolean not_single = !CHECK (sender)->state;
137 Widget *ww;
139 /* input line */
140 ww = widget_find_by_id (w, configure_time_out_id);
141 widget_disable (ww, not_single);
143 return MSG_HANDLED;
145 return MSG_NOT_HANDLED;
147 default:
148 return dlg_default_callback (w, sender, msg, parm, data);
152 /* --------------------------------------------------------------------------------------------- */
154 static void
155 skin_apply (const gchar *skin_override)
157 GError *mcerror = NULL;
159 mc_skin_deinit ();
160 mc_skin_init (skin_override, &mcerror);
161 mc_fhl_free (&mc_filehighlight);
162 mc_filehighlight = mc_fhl_new (TRUE);
163 dlg_set_default_colors ();
164 input_set_default_colors ();
165 if (mc_global.mc_run_mode == MC_RUN_FULL)
166 command_set_default_colors ();
167 panel_deinit ();
168 panel_init ();
169 repaint_screen ();
171 mc_error_message (&mcerror, NULL);
174 /* --------------------------------------------------------------------------------------------- */
176 static const gchar *
177 skin_name_to_label (const gchar *name)
179 if (strcmp (name, "default") == 0)
180 return _("< Default >");
181 return name;
184 /* --------------------------------------------------------------------------------------------- */
186 static cb_ret_t
187 skin_dlg_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
189 switch (msg)
191 case MSG_RESIZE:
193 WDialog *d = DIALOG (w);
194 const WRect *wd = &WIDGET (d->data.p)->rect;
195 WRect r = w->rect;
197 r.y = wd->y + (wd->lines - r.lines) / 2;
198 r.x = wd->x + wd->cols / 2;
200 return dlg_default_callback (w, NULL, MSG_RESIZE, 0, &r);
203 default:
204 return dlg_default_callback (w, sender, msg, parm, data);
208 /* --------------------------------------------------------------------------------------------- */
210 static int
211 sel_skin_button (WButton *button, int action)
213 int result;
214 WListbox *skin_list;
215 WDialog *skin_dlg;
216 const gchar *skin_name;
217 unsigned int i;
218 unsigned int pos = 1;
220 (void) action;
222 skin_dlg =
223 dlg_create (TRUE, 0, 0, 13, 24, WPOS_KEEP_DEFAULT, TRUE, dialog_colors, skin_dlg_callback,
224 NULL, "[Appearance]", _("Skins"));
225 /* use Appearance dialog for positioning */
226 skin_dlg->data.p = WIDGET (button)->owner;
228 /* set dialog location before all */
229 send_message (skin_dlg, NULL, MSG_RESIZE, 0, NULL);
231 skin_list = listbox_new (1, 1, 11, 22, FALSE, NULL);
232 skin_name = "default";
233 listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
234 (void *) skin_name, FALSE);
236 if (strcmp (skin_name, current_skin_name) == 0)
237 listbox_set_current (skin_list, 0);
239 for (i = 0; i < skin_names->len; i++)
241 skin_name = g_ptr_array_index (skin_names, i);
242 if (strcmp (skin_name, "default") != 0)
244 listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
245 (void *) skin_name, FALSE);
246 if (strcmp (skin_name, current_skin_name) == 0)
247 listbox_set_current (skin_list, pos);
248 pos++;
252 /* make list stick to all sides of dialog, effectively make it be resized with dialog */
253 group_add_widget_autopos (GROUP (skin_dlg), skin_list, WPOS_KEEP_ALL, NULL);
255 result = dlg_run (skin_dlg);
256 if (result == B_ENTER)
258 gchar *skin_label;
260 listbox_get_current (skin_list, &skin_label, (void **) &skin_name);
261 g_free (current_skin_name);
262 current_skin_name = g_strdup (skin_name);
263 skin_apply (skin_name);
265 button_set_text (button, str_fit_to_term (skin_label, 20, J_LEFT_FIT));
267 widget_destroy (WIDGET (skin_dlg));
269 return 0;
272 /* --------------------------------------------------------------------------------------------- */
274 static cb_ret_t
275 appearance_box_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
277 switch (msg)
279 case MSG_INIT:
280 #ifdef ENABLE_SHADOWS
281 if (!tty_use_colors ())
282 #endif
284 Widget *shadow;
286 shadow = widget_find_by_id (w, shadows_id);
287 CHECK (shadow)->state = FALSE;
288 widget_disable (shadow, TRUE);
290 return MSG_HANDLED;
292 case MSG_NOTIFY:
293 if (sender != NULL && sender->id == shadows_id)
295 mc_global.tty.shadows = CHECK (sender)->state;
296 repaint_screen ();
297 return MSG_HANDLED;
299 return MSG_NOT_HANDLED;
301 default:
302 return dlg_default_callback (w, sender, msg, parm, data);
306 /* --------------------------------------------------------------------------------------------- */
308 static cb_ret_t
309 panel_listing_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
311 switch (msg)
313 case MSG_NOTIFY:
314 if (sender != NULL && sender->id == panel_list_formats_id)
316 WCheck *ch;
317 WInput *in1, *in2, *in3;
319 in1 = INPUT (widget_find_by_id (w, panel_user_format_id));
320 in2 = INPUT (widget_find_by_id (w, panel_brief_cols_id));
321 ch = CHECK (widget_find_by_id (w, user_mini_status_id));
322 in3 = INPUT (widget_find_by_id (w, mini_user_format_id));
324 if (!ch->state)
325 input_assign_text (in3, status_format[RADIO (sender)->sel]);
326 input_update (in1, FALSE);
327 input_update (in2, FALSE);
328 input_update (in3, FALSE);
329 widget_disable (WIDGET (in1), RADIO (sender)->sel != panel_list_user_idx);
330 widget_disable (WIDGET (in2), RADIO (sender)->sel != panel_list_brief_idx);
331 return MSG_HANDLED;
334 if (sender != NULL && sender->id == user_mini_status_id)
336 WInput *in;
338 in = INPUT (widget_find_by_id (w, mini_user_format_id));
340 if (CHECK (sender)->state)
342 widget_disable (WIDGET (in), FALSE);
343 input_assign_text (in, status_format[3]);
345 else
347 WRadio *r;
349 r = RADIO (widget_find_by_id (w, panel_list_formats_id));
350 widget_disable (WIDGET (in), TRUE);
351 input_assign_text (in, status_format[r->sel]);
353 /* input_update (in, FALSE); */
354 return MSG_HANDLED;
357 return MSG_NOT_HANDLED;
359 default:
360 return dlg_default_callback (w, sender, msg, parm, data);
364 /* --------------------------------------------------------------------------------------------- */
366 #ifdef HAVE_CHARSET
367 static int
368 sel_charset_button (WButton *button, int action)
370 int new_dcp;
372 (void) action;
374 new_dcp = select_charset (-1, -1, new_display_codepage, TRUE);
376 if (new_dcp != SELECT_CHARSET_CANCEL)
378 const char *cpname;
380 new_display_codepage = new_dcp;
381 cpname = (new_display_codepage == SELECT_CHARSET_OTHER_8BIT) ?
382 _("Other 8 bit") :
383 ((codepage_desc *) g_ptr_array_index (codepages, new_display_codepage))->name;
384 if (cpname != NULL)
385 mc_global.utf8_display = str_isutf8 (cpname);
386 else
387 cpname = _("7-bit ASCII"); /* FIXME */
389 button_set_text (button, cpname);
390 widget_draw (WIDGET (WIDGET (button)->owner));
393 return 0;
395 #endif /* HAVE_CHARSET */
397 /* --------------------------------------------------------------------------------------------- */
399 static cb_ret_t
400 tree_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
402 WDialog *h = DIALOG (w);
404 switch (msg)
406 case MSG_RESIZE:
408 WRect r = w->rect;
409 Widget *bar;
411 r.lines = LINES - 9;
412 r.cols = COLS - 20;
413 dlg_default_callback (w, NULL, MSG_RESIZE, 0, &r);
415 bar = WIDGET (buttonbar_find (h));
416 bar->rect.x = 0;
417 bar->rect.y = LINES - 1;
418 return MSG_HANDLED;
421 case MSG_ACTION:
422 return send_message (find_tree (h), NULL, MSG_ACTION, parm, NULL);
424 default:
425 return dlg_default_callback (w, sender, msg, parm, data);
429 /* --------------------------------------------------------------------------------------------- */
431 #if defined(ENABLE_VFS) && defined (ENABLE_VFS_FTP)
432 static cb_ret_t
433 confvfs_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
435 switch (msg)
437 case MSG_NOTIFY:
438 /* message from "Always use ftp proxy" checkbutton */
439 if (sender != NULL && sender->id == ftpfs_always_use_proxy_id)
441 const gboolean not_use = !CHECK (sender)->state;
442 Widget *wi;
444 /* input */
445 wi = widget_find_by_id (w, ftpfs_proxy_host_id);
446 widget_disable (wi, not_use);
447 return MSG_HANDLED;
449 return MSG_NOT_HANDLED;
451 default:
452 return dlg_default_callback (w, sender, msg, parm, data);
455 #endif /* ENABLE_VFS && ENABLE_VFS_FTP */
457 /* --------------------------------------------------------------------------------------------- */
459 #ifdef ENABLE_BACKGROUND
460 static void
461 jobs_fill_listbox (WListbox *list)
463 static const char *state_str[2] = { "", "" };
464 TaskList *tl;
466 if (state_str[0][0] == '\0')
468 state_str[0] = _("Running");
469 state_str[1] = _("Stopped");
472 for (tl = task_list; tl != NULL; tl = tl->next)
474 char *s;
476 s = g_strconcat (state_str[tl->state], " ", tl->info, (char *) NULL);
477 listbox_add_item_take (list, LISTBOX_APPEND_AT_END, 0, s, (void *) tl, FALSE);
481 /* --------------------------------------------------------------------------------------------- */
483 static int
484 task_cb (WButton *button, int action)
486 TaskList *tl;
487 int sig = 0;
489 (void) button;
491 if (bg_list->list == NULL)
492 return 0;
494 /* Get this instance information */
495 listbox_get_current (bg_list, NULL, (void **) &tl);
497 #ifdef SIGTSTP
498 if (action == B_STOP)
500 sig = SIGSTOP;
501 tl->state = Task_Stopped;
503 else if (action == B_RESUME)
505 sig = SIGCONT;
506 tl->state = Task_Running;
508 else
509 #endif
510 if (action == B_KILL)
511 sig = SIGKILL;
513 if (sig == SIGKILL)
514 unregister_task_running (tl->pid, tl->fd);
516 kill (tl->pid, sig);
517 listbox_remove_list (bg_list);
518 jobs_fill_listbox (bg_list);
520 /* This can be optimized to just redraw this widget :-) */
521 widget_draw (WIDGET (WIDGET (button)->owner));
523 return 0;
525 #endif /* ENABLE_BACKGROUND */
527 /* --------------------------------------------------------------------------------------------- */
528 /*** public functions ****************************************************************************/
529 /* --------------------------------------------------------------------------------------------- */
531 void
532 configure_box (void)
534 const char *pause_options[] = {
535 N_("&Never"),
536 N_("On dum&b terminals"),
537 N_("Alwa&ys")
540 int pause_options_num;
542 pause_options_num = G_N_ELEMENTS (pause_options);
545 char time_out[BUF_TINY] = "";
546 char *time_out_new;
548 quick_widget_t quick_widgets[] = {
549 /* *INDENT-OFF* */
550 QUICK_START_COLUMNS,
551 QUICK_START_GROUPBOX (N_("File operations")),
552 QUICK_CHECKBOX (N_("&Verbose operation"), &verbose, NULL),
553 QUICK_CHECKBOX (N_("Compute tota&ls"), &file_op_compute_totals, NULL),
554 QUICK_CHECKBOX (N_("Classic pro&gressbar"), &classic_progressbar, NULL),
555 QUICK_CHECKBOX (N_("Mkdi&r autoname"), &auto_fill_mkdir_name, NULL),
556 QUICK_CHECKBOX (N_("&Preallocate space"), &mc_global.vfs.preallocate_space,
557 NULL),
558 QUICK_STOP_GROUPBOX,
559 QUICK_START_GROUPBOX (N_("Esc key mode")),
560 QUICK_CHECKBOX (N_("S&ingle press"), &old_esc_mode, &configure_old_esc_mode_id),
561 QUICK_LABELED_INPUT (N_("Timeout:"), input_label_left,
562 (const char *) time_out, MC_HISTORY_ESC_TIMEOUT,
563 &time_out_new, &configure_time_out_id, FALSE, FALSE,
564 INPUT_COMPLETE_NONE),
565 QUICK_STOP_GROUPBOX,
566 QUICK_START_GROUPBOX (N_("Pause after run")),
567 QUICK_RADIO (pause_options_num, pause_options, &pause_after_run, NULL),
568 QUICK_STOP_GROUPBOX,
569 QUICK_NEXT_COLUMN,
570 QUICK_START_GROUPBOX (N_("Other options")),
571 QUICK_CHECKBOX (N_("Use internal edi&t"), &use_internal_edit, NULL),
572 QUICK_CHECKBOX (N_("Use internal vie&w"), &use_internal_view, NULL),
573 QUICK_CHECKBOX (N_("A&sk new file name"),
574 &editor_ask_filename_before_edit, NULL),
575 QUICK_CHECKBOX (N_("Auto m&enus"), &auto_menu, NULL),
576 QUICK_CHECKBOX (N_("&Drop down menus"), &drop_menus, NULL),
577 QUICK_CHECKBOX (N_("S&hell patterns"), &easy_patterns, NULL),
578 QUICK_CHECKBOX (N_("Co&mplete: show all"),
579 &mc_global.widget.show_all_if_ambiguous, NULL),
580 QUICK_CHECKBOX (N_("Rotating d&ash"), &nice_rotating_dash, NULL),
581 QUICK_CHECKBOX (N_("Cd follows lin&ks"), &mc_global.vfs.cd_symlinks, NULL),
582 QUICK_CHECKBOX (N_("Sa&fe delete"), &safe_delete, NULL),
583 QUICK_CHECKBOX (N_("Safe overwrite"), &safe_overwrite, NULL), /* w/o hotkey */
584 QUICK_CHECKBOX (N_("A&uto save setup"), &auto_save_setup, NULL),
585 QUICK_SEPARATOR (FALSE),
586 QUICK_SEPARATOR (FALSE),
587 QUICK_STOP_GROUPBOX,
588 QUICK_STOP_COLUMNS,
589 QUICK_BUTTONS_OK_CANCEL,
590 QUICK_END
591 /* *INDENT-ON* */
594 WRect r = { -1, -1, 0, 60 };
596 quick_dialog_t qdlg = {
597 r, N_("Configure options"), "[Configuration]",
598 quick_widgets, configure_callback, NULL
601 g_snprintf (time_out, sizeof (time_out), "%d", old_esc_mode_timeout);
603 #ifndef USE_INTERNAL_EDIT
604 quick_widgets[17].state = WST_DISABLED;
605 #endif
607 if (!old_esc_mode)
608 quick_widgets[10].state = quick_widgets[11].state = WST_DISABLED;
610 #ifndef HAVE_POSIX_FALLOCATE
611 mc_global.vfs.preallocate_space = FALSE;
612 quick_widgets[7].state = WST_DISABLED;
613 #endif
615 if (quick_dialog (&qdlg) == B_ENTER)
617 if (time_out_new[0] == '\0')
618 old_esc_mode_timeout = 0;
619 else
620 old_esc_mode_timeout = atoi (time_out_new);
623 g_free (time_out_new);
627 /* --------------------------------------------------------------------------------------------- */
629 void
630 appearance_box (void)
632 gboolean shadows = mc_global.tty.shadows;
634 current_skin_name = g_strdup (mc_skin__default.name);
635 skin_names = mc_skin_list ();
638 quick_widget_t quick_widgets[] = {
639 /* *INDENT-OFF* */
640 QUICK_START_COLUMNS,
641 QUICK_LABEL (N_("Skin:"), NULL),
642 QUICK_NEXT_COLUMN,
643 QUICK_BUTTON (str_fit_to_term (skin_name_to_label (current_skin_name), 20, J_LEFT_FIT),
644 B_USER, sel_skin_button, NULL),
645 QUICK_STOP_COLUMNS,
646 QUICK_SEPARATOR (TRUE),
647 QUICK_CHECKBOX (N_("&Shadows"), &mc_global.tty.shadows, &shadows_id),
648 QUICK_BUTTONS_OK_CANCEL,
649 QUICK_END
650 /* *INDENT-ON* */
653 WRect r = { -1, -1, 0, 54 };
655 quick_dialog_t qdlg = {
656 r, N_("Appearance"), "[Appearance]",
657 quick_widgets, appearance_box_callback, NULL
660 if (quick_dialog (&qdlg) == B_ENTER)
661 mc_config_set_string (mc_global.main_config, CONFIG_APP_SECTION, "skin",
662 current_skin_name);
663 else
665 skin_apply (NULL);
666 mc_global.tty.shadows = shadows;
670 g_free (current_skin_name);
671 g_ptr_array_free (skin_names, TRUE);
674 /* --------------------------------------------------------------------------------------------- */
676 void
677 panel_options_box (void)
679 gboolean simple_swap;
681 simple_swap = mc_config_get_bool (mc_global.main_config, CONFIG_PANELS_SECTION,
682 "simple_swap", FALSE);
684 const char *qsearch_options[] = {
685 N_("Case &insensitive"),
686 N_("Cas&e sensitive"),
687 N_("Use panel sort mo&de")
690 quick_widget_t quick_widgets[] = {
691 /* *INDENT-OFF* */
692 QUICK_START_COLUMNS,
693 QUICK_START_GROUPBOX (N_("Main options")),
694 QUICK_CHECKBOX (N_("Show mi&ni-status"), &panels_options.show_mini_info, NULL),
695 QUICK_CHECKBOX (N_("Use SI si&ze units"), &panels_options.kilobyte_si, NULL),
696 QUICK_CHECKBOX (N_("Mi&x all files"), &panels_options.mix_all_files, NULL),
697 QUICK_CHECKBOX (N_("Show &backup files"), &panels_options.show_backups, NULL),
698 QUICK_CHECKBOX (N_("Show &hidden files"), &panels_options.show_dot_files, NULL),
699 QUICK_CHECKBOX (N_("&Fast dir reload"), &panels_options.fast_reload, NULL),
700 QUICK_CHECKBOX (N_("Ma&rk moves down"), &panels_options.mark_moves_down, NULL),
701 QUICK_CHECKBOX (N_("Re&verse files only"), &panels_options.reverse_files_only,
702 NULL),
703 QUICK_CHECKBOX (N_("Simple s&wap"), &simple_swap, NULL),
704 QUICK_CHECKBOX (N_("A&uto save panels setup"), &panels_options.auto_save_setup,
705 NULL),
706 QUICK_SEPARATOR (FALSE),
707 QUICK_SEPARATOR (FALSE),
708 QUICK_SEPARATOR (FALSE),
709 QUICK_STOP_GROUPBOX,
710 QUICK_NEXT_COLUMN,
711 QUICK_START_GROUPBOX (N_("Navigation")),
712 QUICK_CHECKBOX (N_("L&ynx-like motion"), &panels_options.navigate_with_arrows,
713 NULL),
714 QUICK_CHECKBOX (N_("Pa&ge scrolling"), &panels_options.scroll_pages, NULL),
715 QUICK_CHECKBOX (N_("Center &scrolling"), &panels_options.scroll_center, NULL),
716 QUICK_CHECKBOX (N_("&Mouse page scrolling"), &panels_options.mouse_move_pages,
717 NULL),
718 QUICK_STOP_GROUPBOX,
719 QUICK_START_GROUPBOX (N_("File highlight")),
720 QUICK_CHECKBOX (N_("File &types"), &panels_options.filetype_mode, NULL),
721 QUICK_CHECKBOX (N_("&Permissions"), &panels_options.permission_mode, NULL),
722 QUICK_STOP_GROUPBOX,
723 QUICK_START_GROUPBOX (N_("Quick search")),
724 QUICK_RADIO (QSEARCH_NUM, qsearch_options, (int *) &panels_options.qsearch_mode,
725 NULL),
726 QUICK_STOP_GROUPBOX,
727 QUICK_STOP_COLUMNS,
728 QUICK_BUTTONS_OK_CANCEL,
729 QUICK_END
730 /* *INDENT-ON* */
733 WRect r = { -1, -1, 0, 60 };
735 quick_dialog_t qdlg = {
736 r, N_("Panel options"), "[Panel options]",
737 quick_widgets, NULL, NULL
740 if (quick_dialog (&qdlg) != B_ENTER)
741 return;
744 mc_config_set_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", simple_swap);
746 if (!panels_options.fast_reload_msg_shown && panels_options.fast_reload)
748 message (D_NORMAL, _("Information"),
749 _("Using the fast reload option may not reflect the exact\n"
750 "directory contents. In this case you'll need to do a\n"
751 "manual reload of the directory. See the man page for\n" "the details."));
752 panels_options.fast_reload_msg_shown = TRUE;
755 update_panels (UP_RELOAD, UP_KEEPSEL);
758 /* --------------------------------------------------------------------------------------------- */
760 /* return list type */
762 panel_listing_box (WPanel *panel, int num, char **userp, char **minip, gboolean *use_msformat,
763 int *brief_cols)
765 int result = -1;
766 const char *p = NULL;
768 if (panel == NULL)
770 p = get_nth_panel_name (num);
771 panel = panel_empty_new (p);
775 gboolean user_mini_status;
776 char panel_brief_cols_in[BUF_TINY];
777 char *panel_brief_cols_out = NULL;
778 char *panel_user_format = NULL;
779 char *mini_user_format = NULL;
781 /* Controls whether the array strings have been translated */
782 const char *list_formats[LIST_FORMATS] = {
783 N_("&Full file list"),
784 N_("&Brief file list:"),
785 N_("&Long file list"),
786 N_("&User defined:")
789 quick_widget_t quick_widgets[] = {
790 /* *INDENT-OFF* */
791 QUICK_START_COLUMNS,
792 QUICK_RADIO (LIST_FORMATS, list_formats, &result, &panel_list_formats_id),
793 QUICK_NEXT_COLUMN,
794 QUICK_SEPARATOR (FALSE),
795 QUICK_LABELED_INPUT (_ ("columns"), input_label_right, panel_brief_cols_in,
796 "panel-brief-cols-input", &panel_brief_cols_out,
797 &panel_brief_cols_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
798 QUICK_STOP_COLUMNS,
799 QUICK_INPUT (panel->user_format, "user-fmt-input", &panel_user_format,
800 &panel_user_format_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
801 QUICK_SEPARATOR (TRUE),
802 QUICK_CHECKBOX (N_("User &mini status"), &user_mini_status, &user_mini_status_id),
803 QUICK_INPUT (panel->user_status_format[panel->list_format], "mini_input",
804 &mini_user_format, &mini_user_format_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
805 QUICK_BUTTONS_OK_CANCEL,
806 QUICK_END
807 /* *INDENT-ON* */
810 WRect r = { -1, -1, 0, 48 };
812 quick_dialog_t qdlg = {
813 r, N_("Listing format"), "[Listing Format...]",
814 quick_widgets, panel_listing_callback, NULL
817 user_mini_status = panel->user_mini_status;
818 result = panel->list_format;
819 status_format = panel->user_status_format;
821 g_snprintf (panel_brief_cols_in, sizeof (panel_brief_cols_in), "%d", panel->brief_cols);
823 if ((int) panel->list_format != panel_list_brief_idx)
824 quick_widgets[4].state = WST_DISABLED;
826 if ((int) panel->list_format != panel_list_user_idx)
827 quick_widgets[6].state = WST_DISABLED;
829 if (!user_mini_status)
830 quick_widgets[9].state = WST_DISABLED;
832 if (quick_dialog (&qdlg) == B_CANCEL)
833 result = -1;
834 else
836 int cols;
837 char *error = NULL;
839 *userp = panel_user_format;
840 *minip = mini_user_format;
841 *use_msformat = user_mini_status;
843 cols = strtol (panel_brief_cols_out, &error, 10);
844 if (*error == '\0')
845 *brief_cols = cols;
846 else
847 *brief_cols = panel->brief_cols;
849 g_free (panel_brief_cols_out);
853 if (p != NULL)
855 int i;
857 g_free (panel->user_format);
858 for (i = 0; i < LIST_FORMATS; i++)
859 g_free (panel->user_status_format[i]);
860 g_free (panel);
863 return result;
866 /* --------------------------------------------------------------------------------------------- */
868 const panel_field_t *
869 sort_box (dir_sort_options_t *op, const panel_field_t *sort_field)
871 char **sort_orders_names;
872 gsize i;
873 gsize sort_names_num = 0;
874 int sort_idx = 0;
875 const panel_field_t *result = NULL;
877 sort_orders_names = panel_get_sortable_fields (&sort_names_num);
879 for (i = 0; i < sort_names_num; i++)
880 if (strcmp (sort_orders_names[i], _(sort_field->title_hotkey)) == 0)
882 sort_idx = i;
883 break;
887 quick_widget_t quick_widgets[] = {
888 /* *INDENT-OFF* */
889 QUICK_START_COLUMNS,
890 QUICK_RADIO (sort_names_num, (const char **) sort_orders_names, &sort_idx, NULL),
891 QUICK_NEXT_COLUMN,
892 QUICK_CHECKBOX (N_("Executable &first"), &op->exec_first, NULL),
893 QUICK_CHECKBOX (N_("Cas&e sensitive"), &op->case_sensitive, NULL),
894 QUICK_CHECKBOX (N_("&Reverse"), &op->reverse, NULL),
895 QUICK_STOP_COLUMNS,
896 QUICK_BUTTONS_OK_CANCEL,
897 QUICK_END
898 /* *INDENT-ON* */
901 WRect r = { -1, -1, 0, 40 };
903 quick_dialog_t qdlg = {
904 r, N_("Sort order"), "[Sort Order...]",
905 quick_widgets, NULL, NULL
908 if (quick_dialog (&qdlg) != B_CANCEL)
909 result = panel_get_field_by_title_hotkey (sort_orders_names[sort_idx]);
911 if (result == NULL)
912 result = sort_field;
915 g_strfreev (sort_orders_names);
917 return result;
920 /* --------------------------------------------------------------------------------------------- */
922 void
923 confirm_box (void)
925 quick_widget_t quick_widgets[] = {
926 /* *INDENT-OFF* */
927 /* TRANSLATORS: no need to translate 'Confirmation', it's just a context prefix */
928 QUICK_CHECKBOX (Q_("Confirmation|&Delete"), &confirm_delete, NULL),
929 QUICK_CHECKBOX (Q_("Confirmation|O&verwrite"), &confirm_overwrite, NULL),
930 QUICK_CHECKBOX (Q_("Confirmation|&Execute"), &confirm_execute, NULL),
931 QUICK_CHECKBOX (Q_("Confirmation|E&xit"), &confirm_exit, NULL),
932 QUICK_CHECKBOX (Q_("Confirmation|Di&rectory hotlist delete"),
933 &confirm_directory_hotlist_delete, NULL),
934 QUICK_CHECKBOX (Q_("Confirmation|&History cleanup"),
935 &mc_global.widget.confirm_history_cleanup, NULL),
936 QUICK_BUTTONS_OK_CANCEL,
937 QUICK_END
938 /* *INDENT-ON* */
941 WRect r = { -1, -1, 0, 46 };
943 quick_dialog_t qdlg = {
944 r, N_("Confirmation"), "[Confirmation]",
945 quick_widgets, NULL, NULL
948 (void) quick_dialog (&qdlg);
951 /* --------------------------------------------------------------------------------------------- */
953 #ifndef HAVE_CHARSET
954 void
955 display_bits_box (void)
957 gboolean new_meta;
958 int current_mode;
960 const char *display_bits_str[] = {
961 N_("&UTF-8 output"),
962 N_("&Full 8 bits output"),
963 N_("&ISO 8859-1"),
964 N_("7 &bits")
967 quick_widget_t quick_widgets[] = {
968 /* *INDENT-OFF* */
969 QUICK_RADIO (4, display_bits_str, &current_mode, NULL),
970 QUICK_SEPARATOR (TRUE),
971 QUICK_CHECKBOX (N_("F&ull 8 bits input"), &new_meta, NULL),
972 QUICK_BUTTONS_OK_CANCEL,
973 QUICK_END
974 /* *INDENT-ON* */
977 WRect r = { -1, -1, 0, 46 };
979 quick_dialog_t qdlg = {
980 r, _("Display bits"), "[Display bits]",
981 quick_widgets, NULL, NULL
984 if (mc_global.full_eight_bits)
985 current_mode = 0;
986 else if (mc_global.eight_bit_clean)
987 current_mode = 1;
988 else
989 current_mode = 2;
991 new_meta = !use_8th_bit_as_meta;
993 if (quick_dialog (&qdlg) != B_CANCEL)
995 mc_global.eight_bit_clean = current_mode < 3;
996 mc_global.full_eight_bits = current_mode < 2;
997 #ifndef HAVE_SLANG
998 tty_display_8bit (mc_global.eight_bit_clean);
999 #else
1000 tty_display_8bit (mc_global.full_eight_bits);
1001 #endif
1002 use_8th_bit_as_meta = !new_meta;
1006 /* --------------------------------------------------------------------------------------------- */
1007 #else /* HAVE_CHARSET */
1009 void
1010 display_bits_box (void)
1012 const char *cpname;
1014 new_display_codepage = mc_global.display_codepage;
1016 cpname = (new_display_codepage < 0) ? _("Other 8 bit")
1017 : ((codepage_desc *) g_ptr_array_index (codepages, new_display_codepage))->name;
1020 gboolean new_meta;
1022 quick_widget_t quick_widgets[] = {
1023 /* *INDENT-OFF* */
1024 QUICK_START_COLUMNS,
1025 QUICK_LABEL (N_("Input / display codepage:"), NULL),
1026 QUICK_NEXT_COLUMN,
1027 QUICK_BUTTON (cpname, B_USER, sel_charset_button, NULL),
1028 QUICK_STOP_COLUMNS,
1029 QUICK_SEPARATOR (TRUE),
1030 QUICK_CHECKBOX (N_("F&ull 8 bits input"), &new_meta, NULL),
1031 QUICK_BUTTONS_OK_CANCEL,
1032 QUICK_END
1033 /* *INDENT-ON* */
1036 WRect r = { -1, -1, 0, 46 };
1038 quick_dialog_t qdlg = {
1039 r, N_("Display bits"), "[Display bits]",
1040 quick_widgets, NULL, NULL
1043 new_meta = !use_8th_bit_as_meta;
1044 application_keypad_mode ();
1046 if (quick_dialog (&qdlg) == B_ENTER)
1048 char *errmsg;
1050 mc_global.display_codepage = new_display_codepage;
1052 errmsg = init_translation_table (mc_global.source_codepage, mc_global.display_codepage);
1053 if (errmsg != NULL)
1055 message (D_ERROR, MSG_ERROR, "%s", errmsg);
1056 g_free (errmsg);
1059 #ifdef HAVE_SLANG
1060 tty_display_8bit (mc_global.display_codepage != 0 && mc_global.display_codepage != 1);
1061 #else
1062 tty_display_8bit (mc_global.display_codepage != 0);
1063 #endif
1064 use_8th_bit_as_meta = !new_meta;
1066 repaint_screen ();
1070 #endif /* HAVE_CHARSET */
1072 /* --------------------------------------------------------------------------------------------- */
1073 /** Show tree in a box, not on a panel */
1075 char *
1076 tree_box (const char *current_dir)
1078 WTree *mytree;
1079 WRect r;
1080 WDialog *dlg;
1081 WGroup *g;
1082 Widget *wd;
1083 char *val = NULL;
1084 WButtonBar *bar;
1086 (void) current_dir;
1088 /* Create the components */
1089 dlg = dlg_create (TRUE, 0, 0, LINES - 9, COLS - 20, WPOS_CENTER, FALSE, dialog_colors,
1090 tree_callback, NULL, "[Directory Tree]", _("Directory tree"));
1091 g = GROUP (dlg);
1092 wd = WIDGET (dlg);
1094 rect_init (&r, 2, 2, wd->rect.lines - 6, wd->rect.cols - 5);
1095 mytree = tree_new (&r, FALSE);
1096 group_add_widget_autopos (g, mytree, WPOS_KEEP_ALL, NULL);
1097 group_add_widget_autopos (g, hline_new (wd->rect.lines - 4, 1, -1), WPOS_KEEP_BOTTOM, NULL);
1098 bar = buttonbar_new ();
1099 group_add_widget (g, bar);
1100 /* restore ButtonBar coordinates after add_widget() */
1101 WIDGET (bar)->rect.x = 0;
1102 WIDGET (bar)->rect.y = LINES - 1;
1104 if (dlg_run (dlg) == B_ENTER)
1106 const vfs_path_t *selected_name;
1108 selected_name = tree_selected_name (mytree);
1109 val = g_strdup (vfs_path_as_str (selected_name));
1112 widget_destroy (wd);
1113 return val;
1116 /* --------------------------------------------------------------------------------------------- */
1118 #ifdef ENABLE_VFS
1119 void
1120 configure_vfs_box (void)
1122 char buffer2[BUF_TINY];
1123 #ifdef ENABLE_VFS_FTP
1124 char buffer3[BUF_TINY];
1126 g_snprintf (buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
1127 #endif
1129 g_snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
1132 char *ret_timeout;
1133 #ifdef ENABLE_VFS_FTP
1134 char *ret_passwd;
1135 char *ret_ftp_proxy;
1136 char *ret_directory_timeout;
1137 #endif /* ENABLE_VFS_FTP */
1139 quick_widget_t quick_widgets[] = {
1140 /* *INDENT-OFF* */
1141 QUICK_LABELED_INPUT (N_("Timeout for freeing VFSs (sec):"), input_label_left,
1142 buffer2, "input-timo-vfs", &ret_timeout, NULL, FALSE, FALSE,
1143 INPUT_COMPLETE_NONE),
1144 #ifdef ENABLE_VFS_FTP
1145 QUICK_SEPARATOR (TRUE),
1146 QUICK_LABELED_INPUT (N_("FTP anonymous password:"), input_label_left,
1147 ftpfs_anonymous_passwd, "input-passwd", &ret_passwd, NULL,
1148 FALSE, FALSE, INPUT_COMPLETE_NONE),
1149 QUICK_LABELED_INPUT (N_("FTP directory cache timeout (sec):"), input_label_left,
1150 buffer3, "input-timeout", &ret_directory_timeout, NULL,
1151 FALSE, FALSE, INPUT_COMPLETE_NONE),
1152 QUICK_CHECKBOX (N_("&Always use ftp proxy:"), &ftpfs_always_use_proxy,
1153 &ftpfs_always_use_proxy_id),
1154 QUICK_INPUT (ftpfs_proxy_host, "input-ftp-proxy", &ret_ftp_proxy,
1155 &ftpfs_proxy_host_id, FALSE, FALSE, INPUT_COMPLETE_HOSTNAMES),
1156 QUICK_CHECKBOX (N_("&Use ~/.netrc"), &ftpfs_use_netrc, NULL),
1157 QUICK_CHECKBOX (N_("Use &passive mode"), &ftpfs_use_passive_connections, NULL),
1158 QUICK_CHECKBOX (N_("Use passive mode over pro&xy"),
1159 &ftpfs_use_passive_connections_over_proxy, NULL),
1160 #endif /* ENABLE_VFS_FTP */
1161 QUICK_BUTTONS_OK_CANCEL,
1162 QUICK_END
1163 /* *INDENT-ON* */
1166 WRect r = { -1, -1, 0, 56 };
1168 quick_dialog_t qdlg = {
1169 r, N_("Virtual File System Setting"), "[Virtual FS]",
1170 quick_widgets,
1171 #ifdef ENABLE_VFS_FTP
1172 confvfs_callback,
1173 #else
1174 NULL,
1175 #endif
1176 NULL,
1179 #ifdef ENABLE_VFS_FTP
1180 if (!ftpfs_always_use_proxy)
1181 quick_widgets[5].state = WST_DISABLED;
1182 #endif
1184 if (quick_dialog (&qdlg) != B_CANCEL)
1186 /* cppcheck-suppress uninitvar */
1187 if (ret_timeout[0] == '\0')
1188 vfs_timeout = 0;
1189 else
1190 vfs_timeout = atoi (ret_timeout);
1191 g_free (ret_timeout);
1193 if (vfs_timeout < 0 || vfs_timeout > 10000)
1194 vfs_timeout = 10;
1195 #ifdef ENABLE_VFS_FTP
1196 g_free (ftpfs_anonymous_passwd);
1197 /* cppcheck-suppress uninitvar */
1198 ftpfs_anonymous_passwd = ret_passwd;
1199 g_free (ftpfs_proxy_host);
1200 /* cppcheck-suppress uninitvar */
1201 ftpfs_proxy_host = ret_ftp_proxy;
1202 /* cppcheck-suppress uninitvar */
1203 if (ret_directory_timeout[0] == '\0')
1204 ftpfs_directory_timeout = 0;
1205 else
1206 ftpfs_directory_timeout = atoi (ret_directory_timeout);
1207 g_free (ret_directory_timeout);
1208 #endif
1213 #endif /* ENABLE_VFS */
1215 /* --------------------------------------------------------------------------------------------- */
1217 char *
1218 cd_box (const WPanel *panel)
1220 const Widget *w = CONST_WIDGET (panel);
1221 char *my_str;
1223 quick_widget_t quick_widgets[] = {
1224 QUICK_LABELED_INPUT (N_("cd"), input_label_left, "", "input", &my_str, NULL, FALSE, TRUE,
1225 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD),
1226 QUICK_END
1229 WRect r = { w->rect.y + w->rect.lines - 6, w->rect.x, 0, w->rect.cols };
1231 quick_dialog_t qdlg = {
1232 r, N_("Quick cd"), "[Quick cd]",
1233 quick_widgets, NULL, NULL
1236 return (quick_dialog (&qdlg) != B_CANCEL) ? my_str : NULL;
1239 /* --------------------------------------------------------------------------------------------- */
1241 void
1242 symlink_box (const vfs_path_t *existing_vpath, const vfs_path_t *new_vpath,
1243 char **ret_existing, char **ret_new)
1245 quick_widget_t quick_widgets[] = {
1246 /* *INDENT-OFF* */
1247 QUICK_LABELED_INPUT (N_("Existing filename (filename symlink will point to):"),
1248 input_label_above, vfs_path_as_str (existing_vpath), "input-2",
1249 ret_existing, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
1250 QUICK_SEPARATOR (FALSE),
1251 QUICK_LABELED_INPUT (N_("Symbolic link filename:"), input_label_above,
1252 vfs_path_as_str (new_vpath), "input-1",
1253 ret_new, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
1254 QUICK_BUTTONS_OK_CANCEL,
1255 QUICK_END
1256 /* *INDENT-ON* */
1259 WRect r = { -1, -1, 0, 64 };
1261 quick_dialog_t qdlg = {
1262 r, N_("Symbolic link"), "[File Menu]",
1263 quick_widgets, NULL, NULL
1266 if (quick_dialog (&qdlg) == B_CANCEL)
1268 *ret_new = NULL;
1269 *ret_existing = NULL;
1273 /* --------------------------------------------------------------------------------------------- */
1275 #ifdef ENABLE_BACKGROUND
1276 void
1277 jobs_box (void)
1279 struct
1281 const char *name;
1282 int flags;
1283 int value;
1284 int len;
1285 bcback_fn callback;
1287 job_but[] = {
1288 /* *INDENT-OFF* */
1289 { N_("&Stop"), NORMAL_BUTTON, B_STOP, 0, task_cb },
1290 { N_("&Resume"), NORMAL_BUTTON, B_RESUME, 0, task_cb },
1291 { N_("&Kill"), NORMAL_BUTTON, B_KILL, 0, task_cb },
1292 { N_("&OK"), DEFPUSH_BUTTON, B_CANCEL, 0, NULL }
1293 /* *INDENT-ON* */
1296 size_t i;
1297 const size_t n_but = G_N_ELEMENTS (job_but);
1299 WDialog *jobs_dlg;
1300 WGroup *g;
1301 int cols = 60;
1302 int lines = 15;
1303 int x = 0;
1305 for (i = 0; i < n_but; i++)
1307 #ifdef ENABLE_NLS
1308 job_but[i].name = _(job_but[i].name);
1309 #endif /* ENABLE_NLS */
1311 job_but[i].len = str_term_width1 (job_but[i].name) + 3;
1312 if (job_but[i].flags == DEFPUSH_BUTTON)
1313 job_but[i].len += 2;
1314 x += job_but[i].len;
1317 x += (int) n_but - 1;
1318 cols = MAX (cols, x + 6);
1320 jobs_dlg = dlg_create (TRUE, 0, 0, lines, cols, WPOS_CENTER, FALSE, dialog_colors, NULL, NULL,
1321 "[Background jobs]", _("Background jobs"));
1322 g = GROUP (jobs_dlg);
1324 bg_list = listbox_new (2, 2, lines - 6, cols - 6, FALSE, NULL);
1325 jobs_fill_listbox (bg_list);
1326 group_add_widget (g, bg_list);
1328 group_add_widget (g, hline_new (lines - 4, -1, -1));
1330 x = (cols - x) / 2;
1331 for (i = 0; i < n_but; i++)
1333 group_add_widget (g, button_new (lines - 3, x, job_but[i].value, job_but[i].flags,
1334 job_but[i].name, job_but[i].callback));
1335 x += job_but[i].len + 1;
1338 (void) dlg_run (jobs_dlg);
1339 widget_destroy (WIDGET (jobs_dlg));
1341 #endif /* ENABLE_BACKGROUND */
1343 /* --------------------------------------------------------------------------------------------- */